summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Langley <agl@chromium.org>2016-01-13 15:00:54 -0800
committerAdam Langley <agl@chromium.org>2016-01-14 13:09:44 -0800
commit4139edb02e59e7ad48e0a8f4c02e45923bc8a344 (patch)
tree80b47f41b8e3971267452f49e48560c9c36434e2
parent55181dbbcdc86b9abed8bd900f1041344211663c (diff)
downloadexternal_boringssl-4139edb02e59e7ad48e0a8f4c02e45923bc8a344.zip
external_boringssl-4139edb02e59e7ad48e0a8f4c02e45923bc8a344.tar.gz
external_boringssl-4139edb02e59e7ad48e0a8f4c02e45923bc8a344.tar.bz2
external/boringssl: sync to 7b8b9c17
This includes the following changes from BoringSSL : 7b8b9c1 Include 'asm' in the name of X25519 asm sources. 3202750 Update the fuzz tests for the server. 6544426 Fix a ** 0 mod 1 = 0 for real this time. fe5f7c7 Only reserve EVP_MAX_MD_SIZE for the Finished, not twice of it. 0d56f88 Switch s to ssl everywhere. 974c7ba Route DHE through the SSL_ECDH abstraction as well. 4cc36ad Make it possible to tell what curve was used on the server. 4298d77 Implement draft-ietf-tls-curve25519-01 in C. c18ef75 Allocate a NID for X25519. 3a2a480 Remove long-dead comment. cba2b62 Implement draft-ietf-tls-curve25519-01 in Go. ab14563 Bundle a copy of golang.org/x/crypto/curve25519 for testing. a029ebc Switch the bundled poly1305 to relative imports. 64d9250 Completely remove P-224 from the TLS stack. 8c2b3bf Test all supported curves (including those off by default). fc82512 Convert ssl3_send_cert_verify to CBB. 5fb18c6 Make MSVC happy. 2a0b391 Rewrite ssl3_send_server_key_exchange to use CBB. d16bf34 Add a -lldb flag to runner.go. af21bcf Remove other unnecessary BN_CTX allocations. ae0eaaa Convert ssl3_send_client_key_exchange to CBB. 3ac4b3a Remove NO_ASM define that I accidently included in the previous commit. e6c5402 Don't build X25519 asm code when NO_ASM is set. 77a173e Add x86-64 assembly for X25519. c75c0ae Add #defines for ED25519 key and signature lengths. 48cce66 Tidy up ssl3_get_server_key_exchange slightly. c1cc858 Check for EC_KEY_set_public_key error. 4cc671c Add CBB_reserve and CBB_did_write. e13263d Resolve a few old TODOs. 841934f Remove stack macros for nonexistent types. 70ab223 Remove ASN1_R_MALLOC_FAILURE. b965c63 Reject calls to X509_verify_cert that have not been reinitialised 3f5b43d Simplify RSA key exchange padding check. 3ef6085 Refuse to parse RSA pubkeys with invalid exponents. afe57cb Add a tool to generate Ed25519 keys. 77c3c0b Enable Ed25519 when building with OPENSSL_SMALL. 9f897b2 Remove the stitched RC4-MD5 code and use the generic one. 1741a9d Save some mallocs in computing the MAC for e_tls.c. df57163 Add RC4-SHA1 and DES-EDE3-CBC-SHA1 to bssl speed. 13414b3 Implement draft-ietf-tls-chacha20-poly1305-04. 3748990 Implement draft-ietf-tls-chacha20-poly1305-04 in Go. 2089fdd Implement RFC 7539 in Go. 86e412d Add client cert support to bssl client. 23a681b Fix build. e320392 Rename the Go ChaCha20-Poly1305 implementation. 8ffab72 Point EVP_aead_chacha20_poly1305 at the standardized version. fef6fb5 Fix ChaCha20-Poly1305 tests. 60a08ac Remove unreachable code to duplicate DH keys. 4ec0cce Slightly tweak some array allocations. 2936170 Fix memory leak in DSA redo case. a01deee Make CBB_len relative to its argument. 77385bb Mark platform-specific HOST_[c2l|l2c] as (void). 6969971 Remove a dead prototype. 1b36716 Remove crypto/header_removed.h. 017231a Remove asm __asm__ define. 793c21e Make HOST_l2c return void. 0aff3ff Store the partial block as uint8_t, not uint32_t. 5a19d7d Use the straight-forward ROTATE macro. 78fefbf Reformat md32_common.h, part 2. fea1137 Reformat md32_common.h, part 1. 871fff0 *_Update of length zero is legal. d9f0671 Remove |need_record_splitting| from |SSL3_STATE|. cd48038 Remove unused fields from SSL3_STATE. 7fc0100 Slightly simplify SSL3_RECORD. ece5ba2 Reset ssl error codes. a41280d Pull ChangeCipherSpec into the handshake state machine. 8fd5c23 Simplify fragmented HelloRequest state. ef5dfd2 Add tests for malformed HelloRequests. 8411b24 Add tests for bad ChangeCipherSpecs. 502a843 Switch unrolled loop in BN_usub with memcpy. c3ae38b Remove DH EVP_PKEY hooks. 7100ee9 Chromium's update.sh is dead, long live update.py f28dd64 Fix flaky BadRSAClientKeyExchange-1 test. 4234885 Remove unused functions. 45dab25 Skip free callbacks on empty CRYPTO_EX_DATAs. 8a58933 Remove the CRYPTO_EX_new callback. 0abd6f2 Get struct timeval from sys/time.h. 1246670 Use UINT64_C in sha512.c table. 5ddffbb Make SSL_(CTX_)?set_tmp_ecdh call SSL_(CTX_)?set1_curves. 53e5c2c Remove SSL_(CTX_)?set_ecdh_callback. 756ad17 Initialize |one_index| in OAEP padding check. 1634a33 Convert rsa/padding.c to constant-time helpers. b36a395 Add slightly better RSA key exchange tests. 0bd71eb Remove weird ret negation logic. e9cddb8 Remove SSL_OP_LEGACY_SERVER_CONNECT. 3e052de Tighten SSL_OP_LEGACY_SERVER_CONNECT to align with RFC 5746. 03f0005 Remove SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER. ef5e515 Remove SSL_OP_TLS_D5_BUG. c100ef4 Limit depth of ASN1 parse printing. 2205093 Add a comment in SetTestState from bssl_shim. 6ae67df Don't leak Android hacks to other build platforms. a0ef7b0 Enforce that |EC_KEY| private key is in [0, group->order). 533a273 Add |EC_METHOD| method for verifying public key order. a3d9de0 Add |EC_GROUP_get0_order| to replace |EC_GROUP_get_order|. 8847856 Include <sys/time.h> in packeted_bio.h for 'timeval' dca63cf Don't abort in |init_once| if |fcntl| returns ENOSYS afd565f Add defines for SRTP profiles using GCM ciphers from RFC 7714. 902870e Gate SHA_CTX compatibility on !WINDOWS. 34aa55c Support the SHA_CTX hack without ANDROID. 6d9e5a7 Re-apply 75b833cc819a9d189adb0fdd56327bee600ff9e9 28243c0 Add PSS parameter check. e701f16 bn/asm/x86_64-mont5.pl: fix carry propagating bug (CVE-2015-3193). cb85298 Fix leak with ASN.1 combine. c4f25ce Work around yaSSL bug. c5eb467 Remove dead code in p256-x86_64. 758d127 Add get0 getters for EVP_PKEY. fde89b4 avoid clashes with libc's 'open' in e_chacha20poly1305.c 60a45aa Remove reference to removed |RSA_FLAG_NO_CONSTTIME| flag. 81edc9b Do away with BN_LLONG in favor of BN_ULLONG. e8fe07f Fix AES XTS mode key size. 93a5b44 Make CRYPTO_library_init use a CRYPTO_once_t. bf76218 Remove the |ri| field of |BN_MONT_CTX|. 596ab10 s/BN_BITS/BN_BITS2/ in |BN_mod_inverse_ex|; remove |BN_BITS| & |BN_MASK|. 7af36e1 Share common definitions of |TOBN| and |BIGNUM_STATIC|. ff2df33 Reformat the cipher suite table. 9f2e277 Remove strength_bits. d6e9eec Remove algo_strength. dcb6ef0 Remove algorithm_ssl. d28f59c Switch the keylog BIO to a callback. fba735c Register the *25519 tests as dependencies of all_tests. f3376ac Remove |EC_POINTs_mul| & simplify p256-x86_64. 301efc8 Fix error handling in |p256-x86_64|. e2136d9 Remove |EC_GROUP_precompute_mult| and |EC_KEY_precompute_mult|. 9b26297 Make |EC_GROUP_precompute_mult|/|EC_KEY_precompute_mult| no-ops. 5058d79 Remove p224-64 and p256-64 dead code for non-default generators. b1b6229 Add NEON implementation of curve25519. 9e65d48 Allow |CRYPTO_is_NEON_capable| to be known at compile time, if possible. 3ac32b1 Fix curve25519 code for MSVC. 4fb0dc4 Add X25519 and Ed25519 support. c324f17 Make sure pthread_once() succeeds. 9361243 Don't include <alloca.h>, it's no longer needed. b00061c Add SSL_CIPHER_is_AES[128|256]CBC. 3a59611 size_t SSL*_use_*_ASN1. b324159 Fix ssl3_send_server_key_exchange error path. f584a5a Reset epoch state in one place. 2077cf9 Use UINT64_C instead of OPENSSL_U64. af07365 Check for overflow when parsing a CBS with d2i_*. 780cd92 modes/asm/ghash-armv4.pl: extend Apple fix to all clang cases. f9c77de Drop CBB allocation failure test. a33915d Have |CBB_init| zero the |CBB| before any possible failures. c5c85de Make RAND_seed read a byte of random data. d9e2702 Don't encode or decode ∞. e7806fd Remove point-on-curve check from |ec_GFp_simple_oct2point|. 20c3731 Become partially -Wmissing-variable-declarations-clean. 7308aaa Remove `EC_GFp_simple_method` (dead code). f872951 Fix null pointer dereference when using "simple" EC. 8bde5d2 Remove the unused |Ni| member of |BN_MONT_CTX|. ce7ae6f Enable AVX code for SHA-*. 9f1f04f Remove nistz256 dead code for non-default generators. d7421eb Remove condition which always evaluates to true (size_t >= 0). d386394 Test for underflow before subtraction. ef14b2d Remove stl_compat.h. cd24a39 Limit DHE groups to 4096-bit. 99fdfb9 Move curve check out of tls12_check_peer_sigalg. Change-Id: Id2d7110569d250b1bae8f8ce7d4421a92f581a31
-rw-r--r--BORINGSSL_REVISION2
-rw-r--r--err_data.c1180
-rw-r--r--linux-arm/crypto/modes/ghash-armv4.S2
-rw-r--r--linux-x86/crypto/sha/sha1-586.S1176
-rw-r--r--linux-x86/crypto/sha/sha256-586.S1218
-rw-r--r--linux-x86_64/crypto/bn/x86_64-mont5.S9
-rw-r--r--linux-x86_64/crypto/ec/p256-x86_64-asm.S241
-rw-r--r--linux-x86_64/crypto/rc4/rc4-md5-x86_64.S1262
-rw-r--r--linux-x86_64/crypto/sha/sha1-x86_64.S1121
-rw-r--r--linux-x86_64/crypto/sha/sha256-x86_64.S1062
-rw-r--r--linux-x86_64/crypto/sha/sha512-x86_64.S2241
-rw-r--r--mac-x86/crypto/sha/sha1-586.S1174
-rw-r--r--mac-x86/crypto/sha/sha256-586.S1218
-rw-r--r--mac-x86_64/crypto/bn/x86_64-mont5.S9
-rw-r--r--mac-x86_64/crypto/ec/p256-x86_64-asm.S243
-rw-r--r--mac-x86_64/crypto/rc4/rc4-md5-x86_64.S1262
-rw-r--r--mac-x86_64/crypto/sha/sha1-x86_64.S1121
-rw-r--r--mac-x86_64/crypto/sha/sha256-x86_64.S1062
-rw-r--r--mac-x86_64/crypto/sha/sha512-x86_64.S2241
-rw-r--r--sources.mk8
-rw-r--r--src/crypto/CMakeLists.txt2
-rw-r--r--src/crypto/asn1/asn1_lib.c4
-rw-r--r--src/crypto/asn1/asn1_par.c9
-rw-r--r--src/crypto/asn1/tasn_dec.c6
-rw-r--r--src/crypto/asn1/tasn_prn.c2
-rw-r--r--src/crypto/bio/pair.c2
-rw-r--r--src/crypto/bn/add.c25
-rw-r--r--src/crypto/bn/asm/x86_64-mont5.pl22
-rw-r--r--src/crypto/bn/bn.c7
-rw-r--r--src/crypto/bn/bn_test.cc65
-rw-r--r--src/crypto/bn/convert.c6
-rw-r--r--src/crypto/bn/div.c12
-rw-r--r--src/crypto/bn/exponentiation.c33
-rw-r--r--src/crypto/bn/gcd.c2
-rw-r--r--src/crypto/bn/generic.c32
-rw-r--r--src/crypto/bn/internal.h43
-rw-r--r--src/crypto/bn/montgomery.c13
-rw-r--r--src/crypto/bytestring/bytestring_test.cc58
-rw-r--r--src/crypto/bytestring/cbb.c92
-rw-r--r--src/crypto/cipher/aead_test.cc59
-rw-r--r--src/crypto/cipher/cipher_test.cc26
-rw-r--r--src/crypto/cipher/e_aes.c2
-rw-r--r--src/crypto/cipher/e_chacha20poly1305.c44
-rw-r--r--src/crypto/cipher/e_rc4.c311
-rw-r--r--src/crypto/cipher/e_tls.c62
-rw-r--r--src/crypto/cipher/test/chacha20_poly1305_old_tests.txt106
-rw-r--r--src/crypto/cipher/test/chacha20_poly1305_tests.txt112
-rw-r--r--src/crypto/cpu-arm.c2
-rw-r--r--src/crypto/crypto.c18
-rw-r--r--src/crypto/curve25519/CMakeLists.txt47
-rw-r--r--src/crypto/curve25519/asm/x25519-asm-arm.S2118
-rw-r--r--src/crypto/curve25519/asm/x25519-asm-x86_64.S1931
-rw-r--r--src/crypto/curve25519/curve25519.c4898
-rw-r--r--src/crypto/curve25519/ed25519_test.cc63
-rw-r--r--src/crypto/curve25519/ed25519_tests.txt2577
-rw-r--r--src/crypto/curve25519/internal.h45
-rw-r--r--src/crypto/curve25519/x25519-x86_64.c225
-rw-r--r--src/crypto/curve25519/x25519_test.cc128
-rw-r--r--src/crypto/des/internal.h17
-rw-r--r--src/crypto/dh/dh.c19
-rw-r--r--src/crypto/dh/dh_test.cc13
-rw-r--r--src/crypto/dh/params.c251
-rw-r--r--src/crypto/digest/md32_common.h360
-rw-r--r--src/crypto/dsa/dsa.c23
-rw-r--r--src/crypto/ec/asm/p256-x86_64-asm.pl241
-rw-r--r--src/crypto/ec/ec.c65
-rw-r--r--src/crypto/ec/ec_asn1.c5
-rw-r--r--src/crypto/ec/ec_key.c95
-rw-r--r--src/crypto/ec/ec_montgomery.c58
-rw-r--r--src/crypto/ec/ec_test.cc3
-rw-r--r--src/crypto/ec/internal.h34
-rw-r--r--src/crypto/ec/oct.c38
-rw-r--r--src/crypto/ec/p224-64.c82
-rw-r--r--src/crypto/ec/p256-64.c89
-rw-r--r--src/crypto/ec/p256-x86_64.c485
-rw-r--r--src/crypto/ec/simple.c19
-rw-r--r--src/crypto/ec/wnaf.c453
-rw-r--r--src/crypto/ecdsa/ecdsa.c39
-rw-r--r--src/crypto/ecdsa/ecdsa_asn1.c12
-rw-r--r--src/crypto/ecdsa/ecdsa_test.cc53
-rw-r--r--src/crypto/err/asn1.errordata75
-rw-r--r--src/crypto/err/ssl.errordata319
-rw-r--r--src/crypto/evp/evp.c53
-rw-r--r--src/crypto/evp/evp_ctx.c3
-rw-r--r--src/crypto/evp/evp_extra_test.cc265
-rw-r--r--src/crypto/evp/evp_test.cc14
-rw-r--r--src/crypto/evp/internal.h7
-rw-r--r--src/crypto/evp/p_ec_asn1.c24
-rw-r--r--src/crypto/evp/p_rsa.c2
-rw-r--r--src/crypto/evp/p_rsa_asn1.c2
-rw-r--r--src/crypto/ex_data.c44
-rw-r--r--src/crypto/header_removed.h17
-rw-r--r--src/crypto/hmac/hmac.c2
-rw-r--r--src/crypto/hmac/hmac_test.cc25
-rw-r--r--src/crypto/internal.h22
-rw-r--r--src/crypto/md4/md4.c10
-rw-r--r--src/crypto/md5/md5.c10
-rw-r--r--src/crypto/modes/asm/ghash-armv4.pl2
-rw-r--r--src/crypto/modes/gcm.c13
-rw-r--r--src/crypto/obj/obj_dat.h9
-rw-r--r--src/crypto/obj/obj_mac.num1
-rw-r--r--src/crypto/obj/objects.txt3
-rw-r--r--src/crypto/pem/pem_all.c10
-rw-r--r--src/crypto/pem/pem_lib.c4
-rw-r--r--src/crypto/pem/pem_pkey.c6
-rw-r--r--src/crypto/pkcs8/pkcs8.c18
-rw-r--r--src/crypto/poly1305/poly1305_test.cc11
-rw-r--r--src/crypto/rand/rand.c7
-rw-r--r--src/crypto/rand/urandom.c14
-rw-r--r--src/crypto/rc4/CMakeLists.txt2
-rw-r--r--src/crypto/rc4/asm/rc4-md5-x86_64.pl632
-rw-r--r--src/crypto/rsa/padding.c191
-rw-r--r--src/crypto/rsa/rsa.c14
-rw-r--r--src/crypto/rsa/rsa_asn1.c8
-rw-r--r--src/crypto/rsa/rsa_impl.c2
-rw-r--r--src/crypto/rsa/rsa_test.cc44
-rw-r--r--src/crypto/sha/asm/sha1-586.pl4
-rw-r--r--src/crypto/sha/asm/sha1-x86_64.pl6
-rw-r--r--src/crypto/sha/asm/sha256-586.pl4
-rw-r--r--src/crypto/sha/asm/sha512-x86_64.pl6
-rw-r--r--src/crypto/sha/sha1.c11
-rw-r--r--src/crypto/sha/sha256.c8
-rw-r--r--src/crypto/sha/sha512.c166
-rw-r--r--src/crypto/test/file_test.cc2
-rw-r--r--src/crypto/test/scoped_types.h14
-rw-r--r--src/crypto/test/stl_compat.h144
-rw-r--r--src/crypto/thread_pthread.c7
-rw-r--r--src/crypto/x509/by_dir.c2
-rw-r--r--src/crypto/x509/by_file.c2
-rw-r--r--src/crypto/x509/pkcs7.c11
-rw-r--r--src/crypto/x509/x509_vfy.c40
-rw-r--r--src/crypto/x509/x509name.c12
-rw-r--r--src/crypto/x509/x_all.c50
-rw-r--r--src/crypto/x509/x_name.c2
-rw-r--r--src/crypto/x509/x_x509.c6
-rw-r--r--src/crypto/x509v3/ext_dat.h22
-rw-r--r--src/decrepit/cast/cast.c10
-rw-r--r--src/decrepit/cast/cast_tables.c3
-rw-r--r--src/decrepit/cast/internal.h81
-rw-r--r--src/decrepit/xts/xts.c84
-rw-r--r--src/include/openssl/aead.h24
-rw-r--r--src/include/openssl/asn1.h75
-rw-r--r--src/include/openssl/bn.h9
-rw-r--r--src/include/openssl/bytestring.h37
-rw-r--r--src/include/openssl/cpu.h18
-rw-r--r--src/include/openssl/curve25519.h92
-rw-r--r--src/include/openssl/dh.h2
-rw-r--r--src/include/openssl/dsa.h2
-rw-r--r--src/include/openssl/ec.h29
-rw-r--r--src/include/openssl/ec_key.h8
-rw-r--r--src/include/openssl/evp.h19
-rw-r--r--src/include/openssl/ex_data.h43
-rw-r--r--src/include/openssl/md4.h4
-rw-r--r--src/include/openssl/md5.h4
-rw-r--r--src/include/openssl/obj_mac.h4
-rw-r--r--src/include/openssl/pem.h4
-rw-r--r--src/include/openssl/rand.h3
-rw-r--r--src/include/openssl/rsa.h70
-rw-r--r--src/include/openssl/sha.h12
-rw-r--r--src/include/openssl/ssl.h525
-rw-r--r--src/include/openssl/ssl3.h2
-rw-r--r--src/include/openssl/stack.h3
-rw-r--r--src/include/openssl/stack_macros.h256
-rw-r--r--src/include/openssl/tls1.h27
-rw-r--r--src/include/openssl/x509.h4
-rw-r--r--src/include/openssl/x509_vfy.h2
-rw-r--r--src/ssl/CMakeLists.txt1
-rw-r--r--src/ssl/d1_both.c203
-rw-r--r--src/ssl/d1_clnt.c310
-rw-r--r--src/ssl/d1_lib.c119
-rw-r--r--src/ssl/d1_meth.c1
-rw-r--r--src/ssl/d1_pkt.c302
-rw-r--r--src/ssl/d1_srtp.c6
-rw-r--r--src/ssl/d1_srvr.c253
-rw-r--r--src/ssl/internal.h436
-rw-r--r--src/ssl/s3_both.c259
-rw-r--r--src/ssl/s3_clnt.c1355
-rw-r--r--src/ssl/s3_enc.c40
-rw-r--r--src/ssl/s3_lib.c116
-rw-r--r--src/ssl/s3_meth.c1
-rw-r--r--src/ssl/s3_pkt.c419
-rw-r--r--src/ssl/s3_srvr.c1417
-rw-r--r--src/ssl/ssl_aead_ctx.c68
-rw-r--r--src/ssl/ssl_asn1.c6
-rw-r--r--src/ssl/ssl_buffer.c10
-rw-r--r--src/ssl/ssl_cert.c19
-rw-r--r--src/ssl/ssl_cipher.c684
-rw-r--r--src/ssl/ssl_ecdh.c383
-rw-r--r--src/ssl/ssl_lib.c487
-rw-r--r--src/ssl/ssl_rsa.c89
-rw-r--r--src/ssl/ssl_session.c17
-rw-r--r--src/ssl/ssl_test.cc81
-rw-r--r--src/ssl/t1_enc.c197
-rw-r--r--src/ssl/t1_lib.c380
-rw-r--r--src/ssl/test/bssl_shim.cc83
-rw-r--r--src/ssl/test/packeted_bio.h2
-rw-r--r--src/ssl/test/runner/chacha20_poly1305.go128
-rw-r--r--src/ssl/test/runner/chacha20_poly1305_test.go83
-rw-r--r--src/ssl/test/runner/cipher_suites.go144
-rw-r--r--src/ssl/test/runner/common.go59
-rw-r--r--src/ssl/test/runner/conn.go22
-rw-r--r--src/ssl/test/runner/curve25519/const_amd64.s20
-rw-r--r--src/ssl/test/runner/curve25519/cswap_amd64.s88
-rw-r--r--src/ssl/test/runner/curve25519/curve25519.go841
-rw-r--r--src/ssl/test/runner/curve25519/curve25519_test.go29
-rw-r--r--src/ssl/test/runner/curve25519/doc.go23
-rw-r--r--src/ssl/test/runner/curve25519/freeze_amd64.s94
-rw-r--r--src/ssl/test/runner/curve25519/ladderstep_amd64.s1398
-rw-r--r--src/ssl/test/runner/curve25519/mont25519_amd64.go240
-rw-r--r--src/ssl/test/runner/curve25519/mul_amd64.s191
-rw-r--r--src/ssl/test/runner/curve25519/square_amd64.s153
-rw-r--r--src/ssl/test/runner/handshake_client.go10
-rw-r--r--src/ssl/test/runner/handshake_server.go8
-rw-r--r--src/ssl/test/runner/key_agreement.go207
-rw-r--r--src/ssl/test/runner/packet_adapter.go2
-rw-r--r--src/ssl/test/runner/poly1305/const_amd64.s45
-rw-r--r--src/ssl/test/runner/poly1305/poly1305.go32
-rw-r--r--src/ssl/test/runner/poly1305/poly1305_amd64.s497
-rw-r--r--src/ssl/test/runner/poly1305/poly1305_arm.s379
-rw-r--r--src/ssl/test/runner/poly1305/poly1305_test.go86
-rw-r--r--src/ssl/test/runner/poly1305/sum_amd64.go24
-rw-r--r--src/ssl/test/runner/poly1305/sum_arm.go24
-rw-r--r--src/ssl/test/runner/poly1305/sum_ref.go (renamed from src/ssl/test/runner/poly1305.go)25
-rw-r--r--src/ssl/test/runner/runner.go383
-rw-r--r--src/ssl/test/test_config.cc8
-rw-r--r--src/ssl/test/test_config.h7
-rw-r--r--src/ssl/tls_record.c39
-rw-r--r--src/tool/CMakeLists.txt1
-rw-r--r--src/tool/client.cc33
-rw-r--r--src/tool/generate_ed25519.cc67
-rw-r--r--src/tool/server.cc4
-rw-r--r--src/tool/speed.cc80
-rw-r--r--src/tool/tool.cc14
-rw-r--r--src/tool/transport_common.cc5
-rw-r--r--src/util/all_tests.json2
-rw-r--r--src/util/bot/update_clang.py2
-rw-r--r--src/util/doc.config1
-rw-r--r--src/util/generate_build_files.py7
-rw-r--r--win-x86/crypto/sha/sha1-586.asm1173
-rw-r--r--win-x86/crypto/sha/sha256-586.asm1218
-rw-r--r--win-x86_64/crypto/bn/x86_64-mont5.asm9
-rw-r--r--win-x86_64/crypto/ec/p256-x86_64-asm.asm285
-rw-r--r--win-x86_64/crypto/rc4/rc4-md5-x86_64.asm1372
-rw-r--r--win-x86_64/crypto/sha/sha1-x86_64.asm1152
-rw-r--r--win-x86_64/crypto/sha/sha256-x86_64.asm1088
-rw-r--r--win-x86_64/crypto/sha/sha512-x86_64.asm2301
246 files changed, 44966 insertions, 14256 deletions
diff --git a/BORINGSSL_REVISION b/BORINGSSL_REVISION
index a4cd7f9..6e9fe82 100644
--- a/BORINGSSL_REVISION
+++ b/BORINGSSL_REVISION
@@ -1 +1 @@
-7104cc96b752c45e02fd3f1728cf313263f04548
+7b8b9c17db93ea5287575b437c77fb36eeb81b31
diff --git a/err_data.c b/err_data.c
index 258a5c3..fe7979b 100644
--- a/err_data.c
+++ b/err_data.c
@@ -54,178 +54,178 @@ OPENSSL_COMPILE_ASSERT(ERR_LIB_USER == 32, library_values_changed_32);
OPENSSL_COMPILE_ASSERT(ERR_NUM_LIBS == 33, library_values_changed_num);
const uint32_t kOpenSSLReasonValues[] = {
- 0xc3207ba,
- 0xc3287d4,
- 0xc3307e3,
- 0xc3387f3,
- 0xc340802,
- 0xc34881b,
- 0xc350827,
- 0xc358844,
- 0xc360856,
- 0xc368864,
- 0xc370874,
- 0xc378881,
- 0xc380891,
- 0xc38889c,
- 0xc3908b2,
- 0xc3988c1,
- 0xc3a08d5,
- 0xc3a87c7,
+ 0xc3207ab,
+ 0xc3287c5,
+ 0xc3307d4,
+ 0xc3387e4,
+ 0xc3407f3,
+ 0xc34880c,
+ 0xc350818,
+ 0xc358835,
+ 0xc360847,
+ 0xc368855,
+ 0xc370865,
+ 0xc378872,
+ 0xc380882,
+ 0xc38888d,
+ 0xc3908a3,
+ 0xc3988b2,
+ 0xc3a08c6,
+ 0xc3a87b8,
0xc3b00b0,
- 0x10321478,
- 0x10329484,
- 0x1033149d,
- 0x103394b0,
- 0x10340de1,
- 0x103494cf,
- 0x103514e4,
- 0x10359516,
- 0x1036152f,
- 0x10369544,
- 0x10371562,
- 0x10379571,
- 0x1038158d,
- 0x103895a8,
- 0x103915b7,
- 0x103995d3,
- 0x103a15ee,
- 0x103a9605,
- 0x103b1616,
- 0x103b962a,
- 0x103c1649,
- 0x103c9658,
- 0x103d166f,
- 0x103d9682,
- 0x103e0b6c,
- 0x103e96b3,
- 0x103f16c6,
- 0x103f96e0,
- 0x104016f0,
- 0x10409704,
- 0x1041171a,
- 0x10419732,
- 0x10421747,
- 0x1042975b,
- 0x1043176d,
- 0x104385d0,
- 0x104408c1,
- 0x10449782,
- 0x10451799,
- 0x104597ae,
- 0x104617bc,
- 0x10469695,
- 0x104714f7,
- 0x104787c7,
+ 0x10321469,
+ 0x10329475,
+ 0x1033148e,
+ 0x103394a1,
+ 0x10340dd2,
+ 0x103494c0,
+ 0x103514d5,
+ 0x10359507,
+ 0x10361520,
+ 0x10369535,
+ 0x10371553,
+ 0x10379562,
+ 0x1038157e,
+ 0x10389599,
+ 0x103915a8,
+ 0x103995c4,
+ 0x103a15df,
+ 0x103a95f6,
+ 0x103b1607,
+ 0x103b961b,
+ 0x103c163a,
+ 0x103c9649,
+ 0x103d1660,
+ 0x103d9673,
+ 0x103e0b5d,
+ 0x103e96a4,
+ 0x103f16b7,
+ 0x103f96d1,
+ 0x104016e1,
+ 0x104096f5,
+ 0x1041170b,
+ 0x10419723,
+ 0x10421738,
+ 0x1042974c,
+ 0x1043175e,
+ 0x104385c1,
+ 0x104408b2,
+ 0x10449773,
+ 0x1045178a,
+ 0x1045979f,
+ 0x104617ad,
+ 0x10469686,
+ 0x104714e8,
+ 0x104787b8,
0x104800b0,
- 0x104894c3,
- 0x14320b4f,
- 0x14328b5d,
- 0x14330b6c,
- 0x14338b7e,
+ 0x104894b4,
+ 0x14320b40,
+ 0x14328b4e,
+ 0x14330b5d,
+ 0x14338b6f,
0x18320083,
- 0x18328e47,
- 0x18340e75,
- 0x18348e89,
- 0x18358ec0,
- 0x18368eed,
- 0x18370f00,
- 0x18378f14,
- 0x18380f38,
- 0x18388f46,
- 0x18390f5c,
- 0x18398f70,
- 0x183a0f80,
- 0x183b0f90,
- 0x183b8fa5,
- 0x183c8fd0,
- 0x183d0fe4,
- 0x183d8ff4,
- 0x183e0b9b,
- 0x183e9001,
- 0x183f1013,
- 0x183f901e,
- 0x1840102e,
- 0x1840903f,
- 0x18411050,
- 0x18419062,
- 0x1842108b,
- 0x184290bd,
- 0x184310cc,
- 0x18451135,
- 0x1845914b,
- 0x18461166,
- 0x18468ed8,
- 0x184709d9,
+ 0x18328e38,
+ 0x18340e66,
+ 0x18348e7a,
+ 0x18358eb1,
+ 0x18368ede,
+ 0x18370ef1,
+ 0x18378f05,
+ 0x18380f29,
+ 0x18388f37,
+ 0x18390f4d,
+ 0x18398f61,
+ 0x183a0f71,
+ 0x183b0f81,
+ 0x183b8f96,
+ 0x183c8fc1,
+ 0x183d0fd5,
+ 0x183d8fe5,
+ 0x183e0b8c,
+ 0x183e8ff2,
+ 0x183f1004,
+ 0x183f900f,
+ 0x1840101f,
+ 0x18409030,
+ 0x18411041,
+ 0x18419053,
+ 0x1842107c,
+ 0x184290ae,
+ 0x184310bd,
+ 0x18451126,
+ 0x1845913c,
+ 0x18461157,
+ 0x18468ec9,
+ 0x184709ca,
0x18478094,
- 0x18480fbc,
- 0x18489101,
- 0x18490e5d,
- 0x18498e9e,
- 0x184a119c,
- 0x184a9119,
- 0x184b10e0,
- 0x184b8e37,
- 0x184c10a4,
- 0x184c866b,
- 0x184d1181,
- 0x203211c3,
- 0x243211cf,
- 0x24328907,
- 0x243311e1,
- 0x243391ee,
- 0x243411fb,
- 0x2434920d,
- 0x2435121c,
- 0x24359239,
- 0x24361246,
- 0x24369254,
- 0x24371262,
- 0x24379270,
- 0x24381279,
- 0x24389286,
- 0x24391299,
- 0x28320b8f,
- 0x28328b9b,
- 0x28330b6c,
- 0x28338bae,
- 0x2c322bfd,
- 0x2c32ac0b,
- 0x2c332c1d,
- 0x2c33ac2f,
- 0x2c342c43,
- 0x2c34ac55,
- 0x2c352c70,
- 0x2c35ac82,
- 0x2c362c95,
+ 0x18480fad,
+ 0x184890f2,
+ 0x18490e4e,
+ 0x18498e8f,
+ 0x184a118d,
+ 0x184a910a,
+ 0x184b10d1,
+ 0x184b8e28,
+ 0x184c1095,
+ 0x184c865c,
+ 0x184d1172,
+ 0x203211b4,
+ 0x243211c0,
+ 0x243288f8,
+ 0x243311d2,
+ 0x243391df,
+ 0x243411ec,
+ 0x243491fe,
+ 0x2435120d,
+ 0x2435922a,
+ 0x24361237,
+ 0x24369245,
+ 0x24371253,
+ 0x24379261,
+ 0x2438126a,
+ 0x24389277,
+ 0x2439128a,
+ 0x28320b80,
+ 0x28328b8c,
+ 0x28330b5d,
+ 0x28338b9f,
+ 0x2c32280e,
+ 0x2c32a81c,
+ 0x2c33282e,
+ 0x2c33a840,
+ 0x2c342854,
+ 0x2c34a866,
+ 0x2c352881,
+ 0x2c35a893,
+ 0x2c3628a6,
0x2c3682f3,
- 0x2c372ca2,
- 0x2c37acb4,
- 0x2c382cc7,
- 0x2c38acd5,
- 0x2c392ce5,
- 0x2c39acf7,
- 0x2c3a2d0b,
- 0x2c3aad1c,
- 0x2c3b1359,
- 0x2c3bad2d,
- 0x2c3c2d41,
- 0x2c3cad57,
- 0x2c3d2d70,
- 0x2c3dad9e,
- 0x2c3e2dac,
- 0x2c3eadc4,
- 0x2c3f2ddc,
- 0x2c3fade9,
- 0x2c402e0c,
- 0x2c40ae2b,
- 0x2c4111c3,
- 0x2c41ae3c,
- 0x2c422e4f,
- 0x2c429135,
- 0x2c432e60,
- 0x2c4386a2,
- 0x2c442d8d,
+ 0x2c3728b3,
+ 0x2c37a8c5,
+ 0x2c3828d8,
+ 0x2c38a8e6,
+ 0x2c3928f6,
+ 0x2c39a908,
+ 0x2c3a291c,
+ 0x2c3aa92d,
+ 0x2c3b134a,
+ 0x2c3ba93e,
+ 0x2c3c2952,
+ 0x2c3ca968,
+ 0x2c3d2981,
+ 0x2c3da9af,
+ 0x2c3e29bd,
+ 0x2c3ea9d5,
+ 0x2c3f29ed,
+ 0x2c3fa9fa,
+ 0x2c402a1d,
+ 0x2c40aa3c,
+ 0x2c4111b4,
+ 0x2c41aa4d,
+ 0x2c422a60,
+ 0x2c429126,
+ 0x2c432a71,
+ 0x2c438693,
+ 0x2c44299e,
0x30320000,
0x30328015,
0x3033001f,
@@ -277,436 +277,398 @@ const uint32_t kOpenSSLReasonValues[] = {
0x304a03b4,
0x304a83c7,
0x304b03d2,
- 0x304b83e1,
- 0x304c03f2,
- 0x304c83fe,
- 0x304d0414,
- 0x304d8422,
- 0x304e0438,
- 0x304e844a,
- 0x304f045c,
- 0x304f846f,
- 0x30500482,
- 0x30508493,
- 0x305104a3,
- 0x305184bb,
- 0x305204d0,
- 0x305284e8,
- 0x305304fc,
- 0x30538514,
- 0x3054052d,
- 0x30548546,
- 0x30550563,
- 0x3055856e,
- 0x30560586,
- 0x30568596,
- 0x305705a7,
- 0x305785ba,
- 0x305805d0,
- 0x305885d9,
- 0x305905ee,
+ 0x304b83e3,
+ 0x304c03ef,
+ 0x304c8405,
+ 0x304d0413,
+ 0x304d8429,
+ 0x304e043b,
+ 0x304e844d,
+ 0x304f0460,
+ 0x304f8473,
+ 0x30500484,
+ 0x30508494,
+ 0x305104ac,
+ 0x305184c1,
+ 0x305204d9,
+ 0x305284ed,
+ 0x30530505,
+ 0x3053851e,
+ 0x30540537,
+ 0x30548554,
+ 0x3055055f,
+ 0x30558577,
+ 0x30560587,
+ 0x30568598,
+ 0x305705ab,
+ 0x305785c1,
+ 0x305805ca,
+ 0x305885df,
+ 0x305905f2,
0x30598601,
- 0x305a0610,
+ 0x305a0621,
0x305a8630,
- 0x305b063f,
- 0x305b864b,
- 0x305c066b,
- 0x305c8687,
- 0x305d0698,
- 0x305d86a2,
- 0x34320ac9,
- 0x34328add,
- 0x34330afa,
- 0x34338b0d,
- 0x34340b1c,
- 0x34348b39,
+ 0x305b063c,
+ 0x305b865c,
+ 0x305c0678,
+ 0x305c8689,
+ 0x305d0693,
+ 0x34320aba,
+ 0x34328ace,
+ 0x34330aeb,
+ 0x34338afe,
+ 0x34340b0d,
+ 0x34348b2a,
0x3c320083,
- 0x3c328bd8,
- 0x3c330bf1,
- 0x3c338c0c,
- 0x3c340c29,
- 0x3c348c44,
- 0x3c350c5f,
- 0x3c358c74,
- 0x3c360c8d,
- 0x3c368ca5,
- 0x3c370cb6,
- 0x3c378cc4,
- 0x3c380cd1,
- 0x3c388ce5,
- 0x3c390b9b,
- 0x3c398cf9,
- 0x3c3a0d0d,
- 0x3c3a8881,
- 0x3c3b0d1d,
- 0x3c3b8d38,
- 0x3c3c0d4a,
- 0x3c3c8d60,
- 0x3c3d0d6a,
- 0x3c3d8d7e,
- 0x3c3e0d8c,
- 0x3c3e8db1,
- 0x3c3f0bc4,
- 0x3c3f8d9a,
- 0x403217d3,
- 0x403297e9,
- 0x40331817,
- 0x40339821,
- 0x40341838,
- 0x40349856,
- 0x40351866,
- 0x40359878,
- 0x40361885,
- 0x40369891,
- 0x403718a6,
- 0x403798bb,
- 0x403818cd,
- 0x403898d8,
- 0x403918ea,
- 0x40398de1,
- 0x403a18fa,
- 0x403a990d,
- 0x403b192e,
- 0x403b993f,
- 0x403c194f,
- 0x403c8064,
- 0x403d195b,
- 0x403d9977,
- 0x403e198d,
- 0x403e999c,
- 0x403f19af,
- 0x403f99c9,
- 0x404019d7,
- 0x404099ec,
- 0x40411a00,
- 0x40419a1d,
- 0x40421a36,
- 0x40429a51,
- 0x40431a6a,
- 0x40439a7d,
- 0x40441a91,
- 0x40449aa9,
- 0x40451af4,
- 0x40459b02,
- 0x40461b20,
- 0x40468094,
- 0x40471b35,
- 0x40479b47,
- 0x40481b6b,
- 0x40489b8b,
- 0x40491b9f,
- 0x40499bb4,
- 0x404a1bcd,
- 0x404a9c07,
- 0x404b1c38,
- 0x404b9c6e,
- 0x404c1c89,
- 0x404c9ca3,
- 0x404d1cba,
- 0x404d9ce2,
- 0x404e1cf9,
- 0x404e9d15,
- 0x404f1d31,
- 0x404f9d52,
- 0x40501d74,
- 0x40509d90,
- 0x40511da4,
- 0x40519db1,
- 0x40521dc8,
- 0x40529dd8,
- 0x40531de8,
- 0x40539dfc,
- 0x40541e17,
- 0x40549e27,
- 0x40551e3e,
- 0x40559e4d,
- 0x40561e7a,
- 0x40569e92,
- 0x40571eae,
- 0x40579ec7,
- 0x40581eda,
- 0x40589eef,
- 0x40591f12,
- 0x40599f3d,
- 0x405a1f4a,
- 0x405a9f63,
- 0x405b1f7b,
- 0x405b9f8e,
- 0x405c1fa3,
- 0x405c9fb5,
- 0x405d1fca,
- 0x405d9fda,
- 0x405e1ff3,
- 0x405ea007,
- 0x405f2017,
- 0x405fa02f,
- 0x40602040,
- 0x4060a053,
- 0x40612064,
- 0x4061a082,
- 0x40622093,
- 0x4062a0a0,
- 0x406320b7,
- 0x4063a0f8,
- 0x4064210f,
- 0x4064a11c,
- 0x4065212a,
- 0x4065a14c,
- 0x40662174,
- 0x4066a189,
- 0x406721a0,
- 0x4067a1b1,
- 0x406821c2,
- 0x4068a1d3,
- 0x406921e8,
- 0x4069a1ff,
- 0x406a2210,
- 0x406aa229,
- 0x406b2244,
- 0x406ba25b,
- 0x406c22c8,
- 0x406ca2e9,
- 0x406d22fc,
- 0x406da31d,
- 0x406e2338,
- 0x406ea381,
- 0x406f23a2,
- 0x406fa3c8,
- 0x407023e8,
- 0x4070a404,
- 0x40712591,
- 0x4071a5b4,
- 0x407225ca,
- 0x4072a5e9,
- 0x40732601,
- 0x4073a621,
- 0x4074284b,
- 0x4074a870,
- 0x4075288b,
- 0x4075a8aa,
- 0x407628d9,
- 0x4076a901,
- 0x40772932,
- 0x4077a951,
- 0x4078298b,
- 0x4078a9a2,
- 0x407929b5,
- 0x4079a9d2,
- 0x407a0782,
- 0x407aa9e4,
- 0x407b29f7,
- 0x407baa10,
- 0x407c2a28,
- 0x407c90bd,
- 0x407d2a3c,
- 0x407daa56,
- 0x407e2a67,
- 0x407eaa7b,
- 0x407f2a89,
- 0x407faaa4,
- 0x40801286,
- 0x4080aac9,
- 0x40812aeb,
- 0x4081ab06,
- 0x40822b1b,
- 0x4082ab33,
- 0x40832b4b,
- 0x4083ab62,
- 0x40842b78,
- 0x4084ab84,
- 0x40852b97,
- 0x4085abac,
- 0x40862bbe,
- 0x4086abd3,
- 0x40872bdc,
- 0x40879cd0,
- 0x40880083,
- 0x4088a0d7,
- 0x40890a17,
- 0x4089a273,
- 0x408a1bf0,
- 0x408aa29d,
- 0x408b291a,
- 0x408ba976,
- 0x408c2353,
- 0x408c9c21,
- 0x408d1c56,
- 0x408d9e68,
- 0x408e1ab9,
- 0x408e9add,
- 0x408f1f20,
- 0x41f424bc,
- 0x41f9254e,
- 0x41fe2441,
- 0x41fea672,
- 0x41ff2763,
- 0x420324d5,
- 0x420824f7,
- 0x4208a533,
- 0x42092425,
- 0x4209a56d,
- 0x420a247c,
- 0x420aa45c,
- 0x420b249c,
- 0x420ba515,
- 0x420c277f,
- 0x420ca63f,
- 0x420d2659,
- 0x420da690,
- 0x421226aa,
- 0x42172746,
- 0x4217a6ec,
- 0x421c270e,
- 0x421f26c9,
- 0x42212796,
- 0x42262729,
- 0x422b282f,
- 0x422ba7f8,
- 0x422c2817,
- 0x422ca7d2,
- 0x422d27b1,
- 0x443206ad,
- 0x443286bc,
- 0x443306c8,
- 0x443386d6,
- 0x443406e9,
- 0x443486fa,
- 0x44350701,
- 0x4435870b,
- 0x4436071e,
- 0x44368734,
- 0x44370746,
- 0x44378753,
- 0x44380762,
- 0x4438876a,
- 0x44390782,
- 0x44398790,
- 0x443a07a3,
- 0x4c3212b0,
- 0x4c3292c0,
- 0x4c3312d3,
- 0x4c3392f3,
+ 0x3c328bc9,
+ 0x3c330be2,
+ 0x3c338bfd,
+ 0x3c340c1a,
+ 0x3c348c35,
+ 0x3c350c50,
+ 0x3c358c65,
+ 0x3c360c7e,
+ 0x3c368c96,
+ 0x3c370ca7,
+ 0x3c378cb5,
+ 0x3c380cc2,
+ 0x3c388cd6,
+ 0x3c390b8c,
+ 0x3c398cea,
+ 0x3c3a0cfe,
+ 0x3c3a8872,
+ 0x3c3b0d0e,
+ 0x3c3b8d29,
+ 0x3c3c0d3b,
+ 0x3c3c8d51,
+ 0x3c3d0d5b,
+ 0x3c3d8d6f,
+ 0x3c3e0d7d,
+ 0x3c3e8da2,
+ 0x3c3f0bb5,
+ 0x3c3f8d8b,
+ 0x403217c4,
+ 0x403297da,
+ 0x40331808,
+ 0x40339812,
+ 0x40341829,
+ 0x40349847,
+ 0x40351857,
+ 0x40359869,
+ 0x40361876,
+ 0x40369882,
+ 0x40371897,
+ 0x403798a9,
+ 0x403818b4,
+ 0x403898c6,
+ 0x40390dd2,
+ 0x403998d6,
+ 0x403a18e9,
+ 0x403a990a,
+ 0x403b191b,
+ 0x403b992b,
+ 0x403c0064,
+ 0x403c8083,
+ 0x403d1937,
+ 0x403d994d,
+ 0x403e195c,
+ 0x403e996f,
+ 0x403f1989,
+ 0x403f9997,
+ 0x404019ac,
+ 0x404099c0,
+ 0x404119dd,
+ 0x404199f8,
+ 0x40421a11,
+ 0x40429a24,
+ 0x40431a38,
+ 0x40439a50,
+ 0x40441a67,
+ 0x40448094,
+ 0x40451a7c,
+ 0x40459a8e,
+ 0x40461ab2,
+ 0x40469ad2,
+ 0x40471ae0,
+ 0x40479af4,
+ 0x40481b09,
+ 0x40489b22,
+ 0x40491b39,
+ 0x40499b53,
+ 0x404a1b6a,
+ 0x404a9b88,
+ 0x404b1ba0,
+ 0x404b9bb7,
+ 0x404c1bcd,
+ 0x404c9bdf,
+ 0x404d1c00,
+ 0x404d9c22,
+ 0x404e1c36,
+ 0x404e9c43,
+ 0x404f1c5a,
+ 0x404f9c6a,
+ 0x40501c7a,
+ 0x40509c8e,
+ 0x40511ca9,
+ 0x40519cb9,
+ 0x40521cd0,
+ 0x40529ce2,
+ 0x40531cfa,
+ 0x40539d0d,
+ 0x40541d22,
+ 0x40549d45,
+ 0x40551d53,
+ 0x40559d70,
+ 0x40561d7d,
+ 0x40569d96,
+ 0x40571dae,
+ 0x40579dc1,
+ 0x40581dd6,
+ 0x40589de8,
+ 0x40591df8,
+ 0x40599e11,
+ 0x405a1e25,
+ 0x405a9e35,
+ 0x405b1e4d,
+ 0x405b9e5e,
+ 0x405c1e71,
+ 0x405c9e82,
+ 0x405d1e8f,
+ 0x405d9ea6,
+ 0x405e1ec6,
+ 0x405e8a08,
+ 0x405f1ee7,
+ 0x405f9ef4,
+ 0x40601f02,
+ 0x40609f24,
+ 0x40611f4c,
+ 0x40619f61,
+ 0x40621f78,
+ 0x40629f89,
+ 0x40631f9a,
+ 0x40639faf,
+ 0x40641fc6,
+ 0x40649fd7,
+ 0x40651ff2,
+ 0x4065a009,
+ 0x40662021,
+ 0x4066a04b,
+ 0x40672076,
+ 0x4067a097,
+ 0x406820aa,
+ 0x4068a0cb,
+ 0x406920e6,
+ 0x4069a114,
+ 0x406a2135,
+ 0x406aa155,
+ 0x406b22dd,
+ 0x406ba300,
+ 0x406c2316,
+ 0x406ca542,
+ 0x406d2571,
+ 0x406da599,
+ 0x406e25b2,
+ 0x406ea5ca,
+ 0x406f25e9,
+ 0x406fa5fe,
+ 0x40702611,
+ 0x4070a62e,
+ 0x40710773,
+ 0x4071a640,
+ 0x40722653,
+ 0x4072a66c,
+ 0x40732684,
+ 0x407390ae,
+ 0x40742698,
+ 0x4074a6b2,
+ 0x407526c3,
+ 0x4075a6d7,
+ 0x407626e5,
+ 0x40769277,
+ 0x4077270a,
+ 0x4077a72c,
+ 0x40782747,
+ 0x4078a75c,
+ 0x40792773,
+ 0x4079a789,
+ 0x407a2795,
+ 0x407aa7a8,
+ 0x407b27bd,
+ 0x407ba7cf,
+ 0x407c27e4,
+ 0x407ca7ed,
+ 0x41f42208,
+ 0x41f9229a,
+ 0x41fe218d,
+ 0x41fea369,
+ 0x41ff245a,
+ 0x42032221,
+ 0x42082243,
+ 0x4208a27f,
+ 0x42092171,
+ 0x4209a2b9,
+ 0x420a21c8,
+ 0x420aa1a8,
+ 0x420b21e8,
+ 0x420ba261,
+ 0x420c2476,
+ 0x420ca336,
+ 0x420d2350,
+ 0x420da387,
+ 0x421223a1,
+ 0x4217243d,
+ 0x4217a3e3,
+ 0x421c2405,
+ 0x421f23c0,
+ 0x4221248d,
+ 0x42262420,
+ 0x422b2526,
+ 0x422ba4ef,
+ 0x422c250e,
+ 0x422ca4c9,
+ 0x422d24a8,
+ 0x4432069e,
+ 0x443286ad,
+ 0x443306b9,
+ 0x443386c7,
+ 0x443406da,
+ 0x443486eb,
+ 0x443506f2,
+ 0x443586fc,
+ 0x4436070f,
+ 0x44368725,
+ 0x44370737,
+ 0x44378744,
+ 0x44380753,
+ 0x4438875b,
+ 0x44390773,
+ 0x44398781,
+ 0x443a0794,
+ 0x4c3212a1,
+ 0x4c3292b1,
+ 0x4c3312c4,
+ 0x4c3392e4,
0x4c340094,
0x4c3480b0,
- 0x4c3512ff,
- 0x4c35930d,
- 0x4c361329,
- 0x4c36933c,
- 0x4c37134b,
- 0x4c379359,
- 0x4c38136e,
- 0x4c38937a,
- 0x4c39139a,
- 0x4c3993c4,
- 0x4c3a13dd,
- 0x4c3a93f6,
- 0x4c3b05d0,
- 0x4c3b940f,
- 0x4c3c1421,
- 0x4c3c9430,
- 0x4c3d10bd,
- 0x4c3d9449,
- 0x4c3e1456,
- 0x50322e72,
- 0x5032ae81,
- 0x50332e8c,
- 0x5033ae9c,
- 0x50342eb5,
- 0x5034aecf,
- 0x50352edd,
- 0x5035aef3,
- 0x50362f05,
- 0x5036af1b,
- 0x50372f34,
- 0x5037af47,
- 0x50382f5f,
- 0x5038af70,
- 0x50392f85,
- 0x5039af99,
- 0x503a2fb9,
- 0x503aafcf,
- 0x503b2fe7,
- 0x503baff9,
- 0x503c3015,
- 0x503cb02c,
- 0x503d3045,
- 0x503db05b,
- 0x503e3068,
- 0x503eb07e,
- 0x503f3090,
+ 0x4c3512f0,
+ 0x4c3592fe,
+ 0x4c36131a,
+ 0x4c36932d,
+ 0x4c37133c,
+ 0x4c37934a,
+ 0x4c38135f,
+ 0x4c38936b,
+ 0x4c39138b,
+ 0x4c3993b5,
+ 0x4c3a13ce,
+ 0x4c3a93e7,
+ 0x4c3b05c1,
+ 0x4c3b9400,
+ 0x4c3c1412,
+ 0x4c3c9421,
+ 0x4c3d10ae,
+ 0x4c3d943a,
+ 0x4c3e1447,
+ 0x50322a83,
+ 0x5032aa92,
+ 0x50332a9d,
+ 0x5033aaad,
+ 0x50342ac6,
+ 0x5034aae0,
+ 0x50352aee,
+ 0x5035ab04,
+ 0x50362b16,
+ 0x5036ab2c,
+ 0x50372b45,
+ 0x5037ab58,
+ 0x50382b70,
+ 0x5038ab81,
+ 0x50392b96,
+ 0x5039abaa,
+ 0x503a2bca,
+ 0x503aabe0,
+ 0x503b2bf8,
+ 0x503bac0a,
+ 0x503c2c26,
+ 0x503cac3d,
+ 0x503d2c56,
+ 0x503dac6c,
+ 0x503e2c79,
+ 0x503eac8f,
+ 0x503f2ca1,
0x503f8348,
- 0x504030a3,
- 0x5040b0b3,
- 0x504130cd,
- 0x5041b0dc,
- 0x504230f6,
- 0x5042b113,
- 0x50433123,
- 0x5043b133,
- 0x50443142,
- 0x50448414,
- 0x50453156,
- 0x5045b174,
- 0x50463187,
- 0x5046b19d,
- 0x504731af,
- 0x5047b1c4,
- 0x504831ea,
- 0x5048b1f8,
- 0x5049320b,
- 0x5049b220,
- 0x504a3236,
- 0x504ab246,
- 0x504b3266,
- 0x504bb279,
- 0x504c329c,
- 0x504cb2ca,
- 0x504d32dc,
- 0x504db2f9,
- 0x504e3314,
- 0x504eb330,
- 0x504f3342,
- 0x504fb359,
- 0x50503368,
- 0x50508687,
- 0x5051337b,
- 0x58320e1f,
- 0x68320de1,
- 0x68328b9b,
- 0x68330bae,
- 0x68338def,
- 0x68340dff,
+ 0x50402cb4,
+ 0x5040acc4,
+ 0x50412cde,
+ 0x5041aced,
+ 0x50422d07,
+ 0x5042ad24,
+ 0x50432d34,
+ 0x5043ad44,
+ 0x50442d53,
+ 0x50448405,
+ 0x50452d67,
+ 0x5045ad85,
+ 0x50462d98,
+ 0x5046adae,
+ 0x50472dc0,
+ 0x5047add5,
+ 0x50482dfb,
+ 0x5048ae09,
+ 0x50492e1c,
+ 0x5049ae31,
+ 0x504a2e47,
+ 0x504aae57,
+ 0x504b2e77,
+ 0x504bae8a,
+ 0x504c2ead,
+ 0x504caedb,
+ 0x504d2eed,
+ 0x504daf0a,
+ 0x504e2f25,
+ 0x504eaf41,
+ 0x504f2f53,
+ 0x504faf6a,
+ 0x50502f79,
+ 0x50508678,
+ 0x50512f8c,
+ 0x58320e10,
+ 0x68320dd2,
+ 0x68328b8c,
+ 0x68330b9f,
+ 0x68338de0,
+ 0x68340df0,
0x683480b0,
- 0x6c320dbd,
- 0x6c328b7e,
- 0x6c330dc8,
- 0x7432098d,
- 0x783208f2,
- 0x78328907,
- 0x78330913,
+ 0x6c320dae,
+ 0x6c328b6f,
+ 0x6c330db9,
+ 0x7432097e,
+ 0x783208e3,
+ 0x783288f8,
+ 0x78330904,
0x78338083,
- 0x78340922,
- 0x78348937,
- 0x78350956,
- 0x78358978,
- 0x7836098d,
- 0x783689a3,
- 0x783709b3,
- 0x783789c6,
- 0x783809d9,
- 0x783889eb,
- 0x783909f8,
- 0x78398a17,
- 0x783a0a2c,
- 0x783a8a3a,
- 0x783b0a44,
- 0x783b8a58,
- 0x783c0a6f,
- 0x783c8a84,
- 0x783d0a9b,
- 0x783d8ab0,
- 0x783e0a06,
- 0x7c3211b2,
+ 0x78340913,
+ 0x78348928,
+ 0x78350947,
+ 0x78358969,
+ 0x7836097e,
+ 0x78368994,
+ 0x783709a4,
+ 0x783789b7,
+ 0x783809ca,
+ 0x783889dc,
+ 0x783909e9,
+ 0x78398a08,
+ 0x783a0a1d,
+ 0x783a8a2b,
+ 0x783b0a35,
+ 0x783b8a49,
+ 0x783c0a60,
+ 0x783c8a75,
+ 0x783d0a8c,
+ 0x783d8aa1,
+ 0x783e09f7,
+ 0x7c3211a3,
};
const size_t kOpenSSLReasonValuesLen = sizeof(kOpenSSLReasonValues) / sizeof(kOpenSSLReasonValues[0]);
@@ -762,7 +724,6 @@ const char kOpenSSLReasonStringData[] =
"INVALID_UNIVERSALSTRING_LENGTH\0"
"INVALID_UTF8STRING\0"
"LIST_ERROR\0"
- "MALLOC_FAILURE\0"
"MISSING_ASN1_EOS\0"
"MISSING_EOC\0"
"MISSING_SECOND_NUMBER\0"
@@ -1030,7 +991,6 @@ const char kOpenSSLReasonStringData[] =
"BAD_DIGEST_LENGTH\0"
"BAD_ECC_CERT\0"
"BAD_ECPOINT\0"
- "BAD_HANDSHAKE_LENGTH\0"
"BAD_HANDSHAKE_RECORD\0"
"BAD_HELLO_REQUEST\0"
"BAD_LENGTH\0"
@@ -1041,7 +1001,6 @@ const char kOpenSSLReasonStringData[] =
"BAD_SSL_FILETYPE\0"
"BAD_WRITE_RETRY\0"
"BIO_NOT_SET\0"
- "CANNOT_SERIALIZE_PUBLIC_KEY\0"
"CA_DN_LENGTH_MISMATCH\0"
"CA_DN_TOO_LONG\0"
"CCS_RECEIVED_EARLY\0"
@@ -1050,41 +1009,30 @@ const char kOpenSSLReasonStringData[] =
"CERT_LENGTH_MISMATCH\0"
"CHANNEL_ID_NOT_P256\0"
"CHANNEL_ID_SIGNATURE_INVALID\0"
- "CIPHER_CODE_WRONG_LENGTH\0"
"CIPHER_OR_HASH_UNAVAILABLE\0"
"CLIENTHELLO_PARSE_FAILED\0"
"CLIENTHELLO_TLSEXT\0"
"CONNECTION_REJECTED\0"
"CONNECTION_TYPE_NOT_SET\0"
- "COOKIE_MISMATCH\0"
- "CUSTOM_EXTENSION_CONTENTS_TOO_LARGE\0"
"CUSTOM_EXTENSION_ERROR\0"
- "D2I_ECDSA_SIG\0"
- "DATA_BETWEEN_CCS_AND_FINISHED\0"
"DATA_LENGTH_TOO_LONG\0"
"DECRYPTION_FAILED\0"
"DECRYPTION_FAILED_OR_BAD_RECORD_MAC\0"
"DH_PUBLIC_VALUE_LENGTH_IS_WRONG\0"
+ "DH_P_TOO_LONG\0"
"DIGEST_CHECK_FAILED\0"
"DTLS_MESSAGE_TOO_BIG\0"
"ECC_CERT_NOT_FOR_SIGNING\0"
- "EMPTY_SRTP_PROTECTION_PROFILE_LIST\0"
"EMS_STATE_INCONSISTENT\0"
"ENCRYPTED_LENGTH_TOO_LONG\0"
"ERROR_ADDING_EXTENSION\0"
"ERROR_IN_RECEIVED_CIPHER_LIST\0"
"ERROR_PARSING_EXTENSION\0"
- "EVP_DIGESTSIGNFINAL_FAILED\0"
- "EVP_DIGESTSIGNINIT_FAILED\0"
"EXCESSIVE_MESSAGE_SIZE\0"
"EXTRA_DATA_IN_MESSAGE\0"
"FRAGMENT_MISMATCH\0"
- "GOT_A_FIN_BEFORE_A_CCS\0"
- "GOT_CHANNEL_ID_BEFORE_A_CCS\0"
- "GOT_NEXT_PROTO_BEFORE_A_CCS\0"
"GOT_NEXT_PROTO_WITHOUT_EXTENSION\0"
"HANDSHAKE_FAILURE_ON_CLIENT_HELLO\0"
- "HANDSHAKE_RECORD_BEFORE_CCS\0"
"HTTPS_PROXY_REQUEST\0"
"HTTP_REQUEST\0"
"INAPPROPRIATE_FALLBACK\0"
@@ -1094,12 +1042,8 @@ const char kOpenSSLReasonStringData[] =
"INVALID_TICKET_KEYS_LENGTH\0"
"LENGTH_MISMATCH\0"
"LIBRARY_HAS_NO_CIPHERS\0"
- "MISSING_DH_KEY\0"
- "MISSING_ECDSA_SIGNING_CERT\0"
"MISSING_EXTENSION\0"
"MISSING_RSA_CERTIFICATE\0"
- "MISSING_RSA_ENCRYPTING_CERT\0"
- "MISSING_RSA_SIGNING_CERT\0"
"MISSING_TMP_DH_KEY\0"
"MISSING_TMP_ECDH_KEY\0"
"MIXED_SPECIAL_OPERATOR_WITH_GROUPS\0"
@@ -1111,7 +1055,6 @@ const char kOpenSSLReasonStringData[] =
"NO_CERTIFICATE_SET\0"
"NO_CIPHERS_AVAILABLE\0"
"NO_CIPHERS_PASSED\0"
- "NO_CIPHERS_SPECIFIED\0"
"NO_CIPHER_MATCH\0"
"NO_COMPRESSION_SPECIFIED\0"
"NO_METHOD_SPECIFIED\0"
@@ -1120,13 +1063,10 @@ const char kOpenSSLReasonStringData[] =
"NO_RENEGOTIATION\0"
"NO_REQUIRED_DIGEST\0"
"NO_SHARED_CIPHER\0"
- "NO_SHARED_SIGATURE_ALGORITHMS\0"
- "NO_SRTP_PROFILES\0"
"NULL_SSL_CTX\0"
"NULL_SSL_METHOD_PASSED\0"
"OLD_SESSION_CIPHER_NOT_RETURNED\0"
"OLD_SESSION_VERSION_NOT_RETURNED\0"
- "PACKET_LENGTH_TOO_LONG\0"
"PARSE_TLSEXT\0"
"PATH_TOO_LONG\0"
"PEER_DID_NOT_RETURN_A_CERTIFICATE\0"
@@ -1135,11 +1075,9 @@ const char kOpenSSLReasonStringData[] =
"PSK_IDENTITY_NOT_FOUND\0"
"PSK_NO_CLIENT_CB\0"
"PSK_NO_SERVER_CB\0"
- "READ_BIO_NOT_SET\0"
"READ_TIMEOUT_EXPIRED\0"
"RECORD_LENGTH_MISMATCH\0"
"RECORD_TOO_LARGE\0"
- "RENEGOTIATE_EXT_TOO_LONG\0"
"RENEGOTIATION_ENCODING_ERR\0"
"RENEGOTIATION_MISMATCH\0"
"REQUIRED_CIPHER_MISSING\0"
@@ -1149,13 +1087,10 @@ const char kOpenSSLReasonStringData[] =
"SERVERHELLO_TLSEXT\0"
"SESSION_ID_CONTEXT_UNINITIALIZED\0"
"SESSION_MAY_NOT_BE_CREATED\0"
- "SIGNATURE_ALGORITHMS_ERROR\0"
"SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER\0"
"SRTP_COULD_NOT_ALLOCATE_PROFILES\0"
- "SRTP_PROTECTION_PROFILE_LIST_TOO_LONG\0"
"SRTP_UNKNOWN_PROTECTION_PROFILE\0"
"SSL3_EXT_INVALID_SERVERNAME\0"
- "SSL3_EXT_INVALID_SERVERNAME_TYPE\0"
"SSLV3_ALERT_BAD_CERTIFICATE\0"
"SSLV3_ALERT_BAD_RECORD_MAC\0"
"SSLV3_ALERT_CERTIFICATE_EXPIRED\0"
@@ -1170,10 +1105,7 @@ const char kOpenSSLReasonStringData[] =
"SSLV3_ALERT_UNSUPPORTED_CERTIFICATE\0"
"SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION\0"
"SSL_HANDSHAKE_FAILURE\0"
- "SSL_SESSION_ID_CALLBACK_FAILED\0"
- "SSL_SESSION_ID_CONFLICT\0"
"SSL_SESSION_ID_CONTEXT_TOO_LONG\0"
- "SSL_SESSION_ID_HAS_BAD_LENGTH\0"
"TLSV1_ALERT_ACCESS_DENIED\0"
"TLSV1_ALERT_DECODE_ERROR\0"
"TLSV1_ALERT_DECRYPTION_FAILED\0"
@@ -1192,17 +1124,12 @@ const char kOpenSSLReasonStringData[] =
"TLSV1_CERTIFICATE_UNOBTAINABLE\0"
"TLSV1_UNRECOGNIZED_NAME\0"
"TLSV1_UNSUPPORTED_EXTENSION\0"
- "TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER\0"
- "TLS_ILLEGAL_EXPORTER_LABEL\0"
- "TLS_INVALID_ECPOINTFORMAT_LIST\0"
"TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST\0"
"TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG\0"
"TOO_MANY_EMPTY_FRAGMENTS\0"
"TOO_MANY_WARNING_ALERTS\0"
"UNABLE_TO_FIND_ECDH_PARAMETERS\0"
- "UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS\0"
"UNEXPECTED_EXTENSION\0"
- "UNEXPECTED_GROUP_CLOSE\0"
"UNEXPECTED_MESSAGE\0"
"UNEXPECTED_OPERATOR_IN_GROUP\0"
"UNEXPECTED_RECORD\0"
@@ -1214,13 +1141,10 @@ const char kOpenSSLReasonStringData[] =
"UNKNOWN_PROTOCOL\0"
"UNKNOWN_SSL_VERSION\0"
"UNKNOWN_STATE\0"
- "UNPROCESSED_HANDSHAKE_DATA\0"
"UNSAFE_LEGACY_RENEGOTIATION_DISABLED\0"
"UNSUPPORTED_COMPRESSION_ALGORITHM\0"
"UNSUPPORTED_ELLIPTIC_CURVE\0"
"UNSUPPORTED_PROTOCOL\0"
- "UNSUPPORTED_SSL_VERSION\0"
- "USE_SRTP_NOT_NEGOTIATED\0"
"WRONG_CERTIFICATE_TYPE\0"
"WRONG_CIPHER_RETURNED\0"
"WRONG_CURVE\0"
diff --git a/linux-arm/crypto/modes/ghash-armv4.S b/linux-arm/crypto/modes/ghash-armv4.S
index 0a43989..d955d82 100644
--- a/linux-arm/crypto/modes/ghash-armv4.S
+++ b/linux-arm/crypto/modes/ghash-armv4.S
@@ -6,7 +6,7 @@
.text
.code 32
-#ifdef __APPLE__
+#ifdef __clang__
#define ldrplb ldrbpl
#define ldrneb ldrbne
#endif
diff --git a/linux-x86/crypto/sha/sha1-586.S b/linux-x86/crypto/sha/sha1-586.S
index dd86f31..58d0bc1 100644
--- a/linux-x86/crypto/sha/sha1-586.S
+++ b/linux-x86/crypto/sha/sha1-586.S
@@ -23,6 +23,11 @@ sha1_block_data_order:
movl 8(%esi),%ecx
testl $16777216,%eax
jz .L001x86
+ andl $268435456,%edx
+ andl $1073741824,%eax
+ orl %edx,%eax
+ cmpl $1342177280,%eax
+ je .Lavx_shortcut
jmp .Lssse3_shortcut
.align 16
.L001x86:
@@ -2611,6 +2616,1177 @@ _sha1_block_data_order_ssse3:
popl %ebp
ret
.size _sha1_block_data_order_ssse3,.-_sha1_block_data_order_ssse3
+.hidden _sha1_block_data_order_avx
+.type _sha1_block_data_order_avx,@function
+.align 16
+_sha1_block_data_order_avx:
+ pushl %ebp
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ call .L006pic_point
+.L006pic_point:
+ popl %ebp
+ leal .LK_XX_XX-.L006pic_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 .L007loop
+.align 16
+.L007loop:
+ 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 .L008done
+ 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 .L007loop
+.align 16
+.L008done:
+ 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
diff --git a/linux-x86/crypto/sha/sha256-586.S b/linux-x86/crypto/sha/sha256-586.S
index 196f7f9..38acbd8 100644
--- a/linux-x86/crypto/sha/sha256-586.S
+++ b/linux-x86/crypto/sha/sha256-586.S
@@ -40,12 +40,13 @@ sha256_block_data_order:
orl %ebx,%ecx
andl $1342177280,%ecx
cmpl $1342177280,%ecx
+ je .L004AVX
testl $512,%ebx
- jnz .L004SSSE3
+ jnz .L005SSSE3
.L003no_xmm:
subl %edi,%eax
cmpl $256,%eax
- jae .L005unrolled
+ jae .L006unrolled
jmp .L002loop
.align 16
.L002loop:
@@ -117,7 +118,7 @@ sha256_block_data_order:
movl %ecx,28(%esp)
movl %edi,32(%esp)
.align 16
-.L00600_15:
+.L00700_15:
movl %edx,%ecx
movl 24(%esp),%esi
rorl $14,%ecx
@@ -155,11 +156,11 @@ sha256_block_data_order:
addl $4,%ebp
addl %ebx,%eax
cmpl $3248222580,%esi
- jne .L00600_15
+ jne .L00700_15
movl 156(%esp),%ecx
- jmp .L00716_63
+ jmp .L00816_63
.align 16
-.L00716_63:
+.L00816_63:
movl %ecx,%ebx
movl 104(%esp),%esi
rorl $11,%ecx
@@ -214,7 +215,7 @@ sha256_block_data_order:
addl $4,%ebp
addl %ebx,%eax
cmpl $3329325298,%esi
- jne .L00716_63
+ jne .L00816_63
movl 356(%esp),%esi
movl 8(%esp),%ebx
movl 16(%esp),%ecx
@@ -258,7 +259,7 @@ sha256_block_data_order:
.byte 112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103
.byte 62,0
.align 16
-.L005unrolled:
+.L006unrolled:
leal -96(%esp),%esp
movl (%esi),%eax
movl 4(%esi),%ebp
@@ -275,9 +276,9 @@ sha256_block_data_order:
movl %ebx,20(%esp)
movl %ecx,24(%esp)
movl %esi,28(%esp)
- jmp .L008grand_loop
+ jmp .L009grand_loop
.align 16
-.L008grand_loop:
+.L009grand_loop:
movl (%edi),%ebx
movl 4(%edi),%ecx
bswap %ebx
@@ -3157,7 +3158,7 @@ sha256_block_data_order:
movl %ebx,24(%esp)
movl %ecx,28(%esp)
cmpl 104(%esp),%edi
- jb .L008grand_loop
+ jb .L009grand_loop
movl 108(%esp),%esp
popl %edi
popl %esi
@@ -3165,7 +3166,7 @@ sha256_block_data_order:
popl %ebp
ret
.align 32
-.L004SSSE3:
+.L005SSSE3:
leal -96(%esp),%esp
movl (%esi),%eax
movl 4(%esi),%ebx
@@ -3184,9 +3185,9 @@ sha256_block_data_order:
movl %ecx,24(%esp)
movl %esi,28(%esp)
movdqa 256(%ebp),%xmm7
- jmp .L009grand_ssse3
+ jmp .L010grand_ssse3
.align 16
-.L009grand_ssse3:
+.L010grand_ssse3:
movdqu (%edi),%xmm0
movdqu 16(%edi),%xmm1
movdqu 32(%edi),%xmm2
@@ -3209,9 +3210,9 @@ sha256_block_data_order:
paddd %xmm3,%xmm7
movdqa %xmm6,64(%esp)
movdqa %xmm7,80(%esp)
- jmp .L010ssse3_00_47
+ jmp .L011ssse3_00_47
.align 16
-.L010ssse3_00_47:
+.L011ssse3_00_47:
addl $64,%ebp
movl %edx,%ecx
movdqa %xmm1,%xmm4
@@ -3854,7 +3855,7 @@ sha256_block_data_order:
addl %ecx,%eax
movdqa %xmm6,80(%esp)
cmpl $66051,64(%ebp)
- jne .L010ssse3_00_47
+ jne .L011ssse3_00_47
movl %edx,%ecx
rorl $14,%edx
movl 20(%esp),%esi
@@ -4368,12 +4369,1193 @@ sha256_block_data_order:
movdqa 64(%ebp),%xmm7
subl $192,%ebp
cmpl 104(%esp),%edi
- jb .L009grand_ssse3
+ jb .L010grand_ssse3
movl 108(%esp),%esp
popl %edi
popl %esi
popl %ebx
popl %ebp
ret
+.align 32
+.L004AVX:
+ 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 .L012grand_avx
+.align 32
+.L012grand_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 .L013avx_00_47
+.align 16
+.L013avx_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 .L013avx_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 .L012grand_avx
+ 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
#endif
diff --git a/linux-x86_64/crypto/bn/x86_64-mont5.S b/linux-x86_64/crypto/bn/x86_64-mont5.S
index 02edc69..214064e 100644
--- a/linux-x86_64/crypto/bn/x86_64-mont5.S
+++ b/linux-x86_64/crypto/bn/x86_64-mont5.S
@@ -1561,6 +1561,15 @@ sqr8x_reduction:
.align 32
.L8x_tail_done:
addq (%rdx),%r8
+ adcq $0,%r9
+ adcq $0,%r10
+ adcq $0,%r11
+ adcq $0,%r12
+ adcq $0,%r13
+ adcq $0,%r14
+ adcq $0,%r15
+
+
xorq %rax,%rax
negq %rsi
diff --git a/linux-x86_64/crypto/ec/p256-x86_64-asm.S b/linux-x86_64/crypto/ec/p256-x86_64-asm.S
index db00544..2884c69 100644
--- a/linux-x86_64/crypto/ec/p256-x86_64-asm.S
+++ b/linux-x86_64/crypto/ec/p256-x86_64-asm.S
@@ -8,10 +8,6 @@
.Lpoly:
.quad 0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001
-
-.LRR:
-.quad 0x0000000000000003, 0xfffffffbffffffff, 0xfffffffffffffffe, 0x00000004fffffffd
-
.LOne:
.long 1,1,1,1,1,1,1,1
.LTwo:
@@ -21,8 +17,6 @@
.LONE_mont:
.quad 0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe
-.globl ecp_nistz256_mul_by_2
-.hidden ecp_nistz256_mul_by_2
.type ecp_nistz256_mul_by_2,@function
.align 64
ecp_nistz256_mul_by_2:
@@ -66,228 +60,6 @@ ecp_nistz256_mul_by_2:
-.globl ecp_nistz256_div_by_2
-.hidden ecp_nistz256_div_by_2
-.type ecp_nistz256_div_by_2,@function
-.align 32
-ecp_nistz256_div_by_2:
- pushq %r12
- pushq %r13
-
- 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)
-
- popq %r13
- popq %r12
- .byte 0xf3,0xc3
-.size ecp_nistz256_div_by_2,.-ecp_nistz256_div_by_2
-
-
-
-.globl ecp_nistz256_mul_by_3
-.hidden ecp_nistz256_mul_by_3
-.type ecp_nistz256_mul_by_3,@function
-.align 32
-ecp_nistz256_mul_by_3:
- pushq %r12
- pushq %r13
-
- 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
- testq %r13,%r13
-
- cmovzq %rax,%r8
- cmovzq %rdx,%r9
- cmovzq %rcx,%r10
- cmovzq %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
- 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)
-
- popq %r13
- popq %r12
- .byte 0xf3,0xc3
-.size ecp_nistz256_mul_by_3,.-ecp_nistz256_mul_by_3
-
-
-
-.globl ecp_nistz256_add
-.hidden ecp_nistz256_add
-.type ecp_nistz256_add,@function
-.align 32
-ecp_nistz256_add:
- pushq %r12
- pushq %r13
-
- 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
- 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)
-
- popq %r13
- popq %r12
- .byte 0xf3,0xc3
-.size ecp_nistz256_add,.-ecp_nistz256_add
-
-
-
-.globl ecp_nistz256_sub
-.hidden ecp_nistz256_sub
-.type ecp_nistz256_sub,@function
-.align 32
-ecp_nistz256_sub:
- pushq %r12
- pushq %r13
-
- 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)
-
- popq %r13
- popq %r12
- .byte 0xf3,0xc3
-.size ecp_nistz256_sub,.-ecp_nistz256_sub
-
-
-
.globl ecp_nistz256_neg
.hidden ecp_nistz256_neg
.type ecp_nistz256_neg,@function
@@ -336,19 +108,6 @@ ecp_nistz256_neg:
-.globl ecp_nistz256_to_mont
-.hidden ecp_nistz256_to_mont
-.type ecp_nistz256_to_mont,@function
-.align 32
-ecp_nistz256_to_mont:
- leaq .LRR(%rip),%rdx
- jmp .Lmul_mont
-.size ecp_nistz256_to_mont,.-ecp_nistz256_to_mont
-
-
-
-
-
.globl ecp_nistz256_mul_mont
diff --git a/linux-x86_64/crypto/rc4/rc4-md5-x86_64.S b/linux-x86_64/crypto/rc4/rc4-md5-x86_64.S
deleted file mode 100644
index 06c8d67..0000000
--- a/linux-x86_64/crypto/rc4/rc4-md5-x86_64.S
+++ /dev/null
@@ -1,1262 +0,0 @@
-#if defined(__x86_64__)
-.text
-.align 16
-
-.globl rc4_md5_enc
-.hidden rc4_md5_enc
-.type rc4_md5_enc,@function
-rc4_md5_enc:
- cmpq $0,%r9
- je .Labort
- pushq %rbx
- pushq %rbp
- pushq %r12
- pushq %r13
- pushq %r14
- pushq %r15
- subq $40,%rsp
-.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
- movq 48(%rsp),%r14
- movq 56(%rsp),%r13
- movq 64(%rsp),%r12
- movq 72(%rsp),%rbp
- movq 80(%rsp),%rbx
- leaq 88(%rsp),%rsp
-.Lepilogue:
-.Labort:
- .byte 0xf3,0xc3
-.size rc4_md5_enc,.-rc4_md5_enc
-#endif
diff --git a/linux-x86_64/crypto/sha/sha1-x86_64.S b/linux-x86_64/crypto/sha/sha1-x86_64.S
index 7668c2b..d830b53 100644
--- a/linux-x86_64/crypto/sha/sha1-x86_64.S
+++ b/linux-x86_64/crypto/sha/sha1-x86_64.S
@@ -13,6 +13,11 @@ sha1_block_data_order:
movl OPENSSL_ia32cap_P+8(%rip),%r10d
testl $512,%r8d
jz .Lialu
+ andl $268435456,%r8d
+ andl $1073741824,%r9d
+ orl %r9d,%r8d
+ cmpl $1342177280,%r8d
+ je _avx_shortcut
jmp _ssse3_shortcut
.align 16
@@ -2408,6 +2413,1122 @@ _ssse3_shortcut:
.Lepilogue_ssse3:
.byte 0xf3,0xc3
.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:
+ movq %rsp,%rax
+ pushq %rbx
+ pushq %rbp
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ leaq -64(%rsp),%rsp
+ vzeroupper
+ movq %rax,%r14
+ andq $-64,%rsp
+ movq %rdi,%r8
+ movq %rsi,%r9
+ movq %rdx,%r10
+
+ shlq $6,%r10
+ addq %r9,%r10
+ leaq K_XX_XX+64(%rip),%r11
+
+ 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(%r11),%xmm6
+ vmovdqa -64(%r11),%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(%r11),%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(%r11),%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(%r11),%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(%r11),%xmm6
+ vmovdqa -64(%r11),%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)
+ leaq (%r14),%rsi
+ movq -40(%rsi),%r14
+ movq -32(%rsi),%r13
+ movq -24(%rsi),%r12
+ movq -16(%rsi),%rbp
+ movq -8(%rsi),%rbx
+ leaq (%rsi),%rsp
+.Lepilogue_avx:
+ .byte 0xf3,0xc3
+.size sha1_block_data_order_avx,.-sha1_block_data_order_avx
.align 64
K_XX_XX:
.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999
diff --git a/linux-x86_64/crypto/sha/sha256-x86_64.S b/linux-x86_64/crypto/sha/sha256-x86_64.S
index f526de5..445b497 100644
--- a/linux-x86_64/crypto/sha/sha256-x86_64.S
+++ b/linux-x86_64/crypto/sha/sha256-x86_64.S
@@ -12,6 +12,11 @@ sha256_block_data_order:
movl 0(%r11),%r9d
movl 4(%r11),%r10d
movl 8(%r11),%r11d
+ andl $1073741824,%r9d
+ andl $268435968,%r10d
+ orl %r9d,%r10d
+ cmpl $1342177792,%r10d
+ je .Lavx_shortcut
testl $512,%r10d
jnz .Lssse3_shortcut
pushq %rbx
@@ -2841,4 +2846,1061 @@ sha256_block_data_order_ssse3:
.Lepilogue_ssse3:
.byte 0xf3,0xc3
.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:
+.Lavx_shortcut:
+ pushq %rbx
+ pushq %rbp
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ movq %rsp,%r11
+ 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 %r11,64+24(%rsp)
+.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 64+24(%rsp),%rsi
+ vzeroupper
+ movq (%rsi),%r15
+ movq 8(%rsi),%r14
+ movq 16(%rsi),%r13
+ movq 24(%rsi),%r12
+ movq 32(%rsi),%rbp
+ movq 40(%rsi),%rbx
+ leaq 48(%rsi),%rsp
+.Lepilogue_avx:
+ .byte 0xf3,0xc3
+.size sha256_block_data_order_avx,.-sha256_block_data_order_avx
#endif
diff --git a/linux-x86_64/crypto/sha/sha512-x86_64.S b/linux-x86_64/crypto/sha/sha512-x86_64.S
index ca3a3a1..d65743f 100644
--- a/linux-x86_64/crypto/sha/sha512-x86_64.S
+++ b/linux-x86_64/crypto/sha/sha512-x86_64.S
@@ -8,6 +8,17 @@
.type sha512_block_data_order,@function
.align 16
sha512_block_data_order:
+ 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 $1073741824,%r9d
+ andl $268435968,%r10d
+ orl %r9d,%r10d
+ cmpl $1342177792,%r10d
+ je .Lavx_shortcut
pushq %rbx
pushq %rbp
pushq %r12
@@ -1784,4 +1795,2234 @@ K512:
.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:
+.Lxop_shortcut:
+ pushq %rbx
+ pushq %rbp
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ movq %rsp,%r11
+ 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 %r11,128+24(%rsp)
+.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 128+24(%rsp),%rsi
+ vzeroupper
+ movq (%rsi),%r15
+ movq 8(%rsi),%r14
+ movq 16(%rsi),%r13
+ movq 24(%rsi),%r12
+ movq 32(%rsi),%rbp
+ movq 40(%rsi),%rbx
+ leaq 48(%rsi),%rsp
+.Lepilogue_xop:
+ .byte 0xf3,0xc3
+.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:
+.Lavx_shortcut:
+ pushq %rbx
+ pushq %rbp
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ movq %rsp,%r11
+ 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 %r11,128+24(%rsp)
+.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 128+24(%rsp),%rsi
+ vzeroupper
+ movq (%rsi),%r15
+ movq 8(%rsi),%r14
+ movq 16(%rsi),%r13
+ movq 24(%rsi),%r12
+ movq 32(%rsi),%rbp
+ movq 40(%rsi),%rbx
+ leaq 48(%rsi),%rsp
+.Lepilogue_avx:
+ .byte 0xf3,0xc3
+.size sha512_block_data_order_avx,.-sha512_block_data_order_avx
#endif
diff --git a/mac-x86/crypto/sha/sha1-586.S b/mac-x86/crypto/sha/sha1-586.S
index f880e7e..72a7205 100644
--- a/mac-x86/crypto/sha/sha1-586.S
+++ b/mac-x86/crypto/sha/sha1-586.S
@@ -22,6 +22,11 @@ L000pic_point:
movl 8(%esi),%ecx
testl $16777216,%eax
jz L001x86
+ andl $268435456,%edx
+ andl $1073741824,%eax
+ orl %edx,%eax
+ cmpl $1342177280,%eax
+ je Lavx_shortcut
jmp Lssse3_shortcut
.align 4,0x90
L001x86:
@@ -2607,6 +2612,1175 @@ L005done:
popl %ebx
popl %ebp
ret
+.private_extern __sha1_block_data_order_avx
+.align 4
+__sha1_block_data_order_avx:
+ pushl %ebp
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ call L006pic_point
+L006pic_point:
+ popl %ebp
+ leal LK_XX_XX-L006pic_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 L007loop
+.align 4,0x90
+L007loop:
+ 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 L008done
+ 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 L007loop
+.align 4,0x90
+L008done:
+ 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
.align 6,0x90
LK_XX_XX:
.long 1518500249,1518500249,1518500249,1518500249
diff --git a/mac-x86/crypto/sha/sha256-586.S b/mac-x86/crypto/sha/sha256-586.S
index 4615588..841854f 100644
--- a/mac-x86/crypto/sha/sha256-586.S
+++ b/mac-x86/crypto/sha/sha256-586.S
@@ -39,12 +39,13 @@ L000pic_point:
orl %ebx,%ecx
andl $1342177280,%ecx
cmpl $1342177280,%ecx
+ je L004AVX
testl $512,%ebx
- jnz L004SSSE3
+ jnz L005SSSE3
L003no_xmm:
subl %edi,%eax
cmpl $256,%eax
- jae L005unrolled
+ jae L006unrolled
jmp L002loop
.align 4,0x90
L002loop:
@@ -116,7 +117,7 @@ L002loop:
movl %ecx,28(%esp)
movl %edi,32(%esp)
.align 4,0x90
-L00600_15:
+L00700_15:
movl %edx,%ecx
movl 24(%esp),%esi
rorl $14,%ecx
@@ -154,11 +155,11 @@ L00600_15:
addl $4,%ebp
addl %ebx,%eax
cmpl $3248222580,%esi
- jne L00600_15
+ jne L00700_15
movl 156(%esp),%ecx
- jmp L00716_63
+ jmp L00816_63
.align 4,0x90
-L00716_63:
+L00816_63:
movl %ecx,%ebx
movl 104(%esp),%esi
rorl $11,%ecx
@@ -213,7 +214,7 @@ L00716_63:
addl $4,%ebp
addl %ebx,%eax
cmpl $3329325298,%esi
- jne L00716_63
+ jne L00816_63
movl 356(%esp),%esi
movl 8(%esp),%ebx
movl 16(%esp),%ecx
@@ -257,7 +258,7 @@ L001K256:
.byte 112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103
.byte 62,0
.align 4,0x90
-L005unrolled:
+L006unrolled:
leal -96(%esp),%esp
movl (%esi),%eax
movl 4(%esi),%ebp
@@ -274,9 +275,9 @@ L005unrolled:
movl %ebx,20(%esp)
movl %ecx,24(%esp)
movl %esi,28(%esp)
- jmp L008grand_loop
+ jmp L009grand_loop
.align 4,0x90
-L008grand_loop:
+L009grand_loop:
movl (%edi),%ebx
movl 4(%edi),%ecx
bswap %ebx
@@ -3156,7 +3157,7 @@ L008grand_loop:
movl %ebx,24(%esp)
movl %ecx,28(%esp)
cmpl 104(%esp),%edi
- jb L008grand_loop
+ jb L009grand_loop
movl 108(%esp),%esp
popl %edi
popl %esi
@@ -3164,7 +3165,7 @@ L008grand_loop:
popl %ebp
ret
.align 5,0x90
-L004SSSE3:
+L005SSSE3:
leal -96(%esp),%esp
movl (%esi),%eax
movl 4(%esi),%ebx
@@ -3183,9 +3184,9 @@ L004SSSE3:
movl %ecx,24(%esp)
movl %esi,28(%esp)
movdqa 256(%ebp),%xmm7
- jmp L009grand_ssse3
+ jmp L010grand_ssse3
.align 4,0x90
-L009grand_ssse3:
+L010grand_ssse3:
movdqu (%edi),%xmm0
movdqu 16(%edi),%xmm1
movdqu 32(%edi),%xmm2
@@ -3208,9 +3209,9 @@ L009grand_ssse3:
paddd %xmm3,%xmm7
movdqa %xmm6,64(%esp)
movdqa %xmm7,80(%esp)
- jmp L010ssse3_00_47
+ jmp L011ssse3_00_47
.align 4,0x90
-L010ssse3_00_47:
+L011ssse3_00_47:
addl $64,%ebp
movl %edx,%ecx
movdqa %xmm1,%xmm4
@@ -3853,7 +3854,7 @@ L010ssse3_00_47:
addl %ecx,%eax
movdqa %xmm6,80(%esp)
cmpl $66051,64(%ebp)
- jne L010ssse3_00_47
+ jne L011ssse3_00_47
movl %edx,%ecx
rorl $14,%edx
movl 20(%esp),%esi
@@ -4367,13 +4368,1194 @@ L010ssse3_00_47:
movdqa 64(%ebp),%xmm7
subl $192,%ebp
cmpl 104(%esp),%edi
- jb L009grand_ssse3
+ jb L010grand_ssse3
movl 108(%esp),%esp
popl %edi
popl %esi
popl %ebx
popl %ebp
ret
+.align 5,0x90
+L004AVX:
+ 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 L012grand_avx
+.align 5,0x90
+L012grand_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 L013avx_00_47
+.align 4,0x90
+L013avx_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 L013avx_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 L012grand_avx
+ movl 108(%esp),%esp
+ vzeroall
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
.section __IMPORT,__pointers,non_lazy_symbol_pointers
L_OPENSSL_ia32cap_P$non_lazy_ptr:
.indirect_symbol _OPENSSL_ia32cap_P
diff --git a/mac-x86_64/crypto/bn/x86_64-mont5.S b/mac-x86_64/crypto/bn/x86_64-mont5.S
index 2e8f469..461bfb2 100644
--- a/mac-x86_64/crypto/bn/x86_64-mont5.S
+++ b/mac-x86_64/crypto/bn/x86_64-mont5.S
@@ -1560,6 +1560,15 @@ L$8x_tail:
.p2align 5
L$8x_tail_done:
addq (%rdx),%r8
+ adcq $0,%r9
+ adcq $0,%r10
+ adcq $0,%r11
+ adcq $0,%r12
+ adcq $0,%r13
+ adcq $0,%r14
+ adcq $0,%r15
+
+
xorq %rax,%rax
negq %rsi
diff --git a/mac-x86_64/crypto/ec/p256-x86_64-asm.S b/mac-x86_64/crypto/ec/p256-x86_64-asm.S
index 43f7dff..bed1130 100644
--- a/mac-x86_64/crypto/ec/p256-x86_64-asm.S
+++ b/mac-x86_64/crypto/ec/p256-x86_64-asm.S
@@ -7,10 +7,6 @@
L$poly:
.quad 0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001
-
-L$RR:
-.quad 0x0000000000000003, 0xfffffffbffffffff, 0xfffffffffffffffe, 0x00000004fffffffd
-
L$One:
.long 1,1,1,1,1,1,1,1
L$Two:
@@ -20,11 +16,9 @@ L$Three:
L$ONE_mont:
.quad 0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe
-.globl _ecp_nistz256_mul_by_2
-.private_extern _ecp_nistz256_mul_by_2
.p2align 6
-_ecp_nistz256_mul_by_2:
+ecp_nistz256_mul_by_2:
pushq %r12
pushq %r13
@@ -65,228 +59,6 @@ _ecp_nistz256_mul_by_2:
-.globl _ecp_nistz256_div_by_2
-.private_extern _ecp_nistz256_div_by_2
-
-.p2align 5
-_ecp_nistz256_div_by_2:
- pushq %r12
- pushq %r13
-
- movq 0(%rsi),%r8
- movq 8(%rsi),%r9
- movq 16(%rsi),%r10
- movq %r8,%rax
- movq 24(%rsi),%r11
- leaq L$poly(%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)
-
- popq %r13
- popq %r12
- .byte 0xf3,0xc3
-
-
-
-
-.globl _ecp_nistz256_mul_by_3
-.private_extern _ecp_nistz256_mul_by_3
-
-.p2align 5
-_ecp_nistz256_mul_by_3:
- pushq %r12
- pushq %r13
-
- 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 L$poly+8(%rip),%r9
- sbbq $0,%r10
- movq %r11,%r12
- sbbq L$poly+24(%rip),%r11
- testq %r13,%r13
-
- cmovzq %rax,%r8
- cmovzq %rdx,%r9
- cmovzq %rcx,%r10
- cmovzq %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 L$poly+8(%rip),%r9
- sbbq $0,%r10
- movq %r11,%r12
- sbbq L$poly+24(%rip),%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)
-
- popq %r13
- popq %r12
- .byte 0xf3,0xc3
-
-
-
-
-.globl _ecp_nistz256_add
-.private_extern _ecp_nistz256_add
-
-.p2align 5
-_ecp_nistz256_add:
- pushq %r12
- pushq %r13
-
- movq 0(%rsi),%r8
- xorq %r13,%r13
- movq 8(%rsi),%r9
- movq 16(%rsi),%r10
- movq 24(%rsi),%r11
- leaq L$poly(%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
- 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)
-
- popq %r13
- popq %r12
- .byte 0xf3,0xc3
-
-
-
-
-.globl _ecp_nistz256_sub
-.private_extern _ecp_nistz256_sub
-
-.p2align 5
-_ecp_nistz256_sub:
- pushq %r12
- pushq %r13
-
- movq 0(%rsi),%r8
- xorq %r13,%r13
- movq 8(%rsi),%r9
- movq 16(%rsi),%r10
- movq 24(%rsi),%r11
- leaq L$poly(%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)
-
- popq %r13
- popq %r12
- .byte 0xf3,0xc3
-
-
-
-
.globl _ecp_nistz256_neg
.private_extern _ecp_nistz256_neg
@@ -335,19 +107,6 @@ _ecp_nistz256_neg:
-.globl _ecp_nistz256_to_mont
-.private_extern _ecp_nistz256_to_mont
-
-.p2align 5
-_ecp_nistz256_to_mont:
- leaq L$RR(%rip),%rdx
- jmp L$mul_mont
-
-
-
-
-
-
.globl _ecp_nistz256_mul_mont
diff --git a/mac-x86_64/crypto/rc4/rc4-md5-x86_64.S b/mac-x86_64/crypto/rc4/rc4-md5-x86_64.S
deleted file mode 100644
index 31ee7d2..0000000
--- a/mac-x86_64/crypto/rc4/rc4-md5-x86_64.S
+++ /dev/null
@@ -1,1262 +0,0 @@
-#if defined(__x86_64__)
-.text
-.p2align 4
-
-.globl _rc4_md5_enc
-.private_extern _rc4_md5_enc
-
-_rc4_md5_enc:
- cmpq $0,%r9
- je L$abort
- pushq %rbx
- pushq %rbp
- pushq %r12
- pushq %r13
- pushq %r14
- pushq %r15
- subq $40,%rsp
-L$body:
- 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 L$oop
-
-.p2align 4
-L$oop:
- 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 L$oop
-
- 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
- movq 48(%rsp),%r14
- movq 56(%rsp),%r13
- movq 64(%rsp),%r12
- movq 72(%rsp),%rbp
- movq 80(%rsp),%rbx
- leaq 88(%rsp),%rsp
-L$epilogue:
-L$abort:
- .byte 0xf3,0xc3
-
-#endif
diff --git a/mac-x86_64/crypto/sha/sha1-x86_64.S b/mac-x86_64/crypto/sha/sha1-x86_64.S
index 044dc5b..0509d45 100644
--- a/mac-x86_64/crypto/sha/sha1-x86_64.S
+++ b/mac-x86_64/crypto/sha/sha1-x86_64.S
@@ -12,6 +12,11 @@ _sha1_block_data_order:
movl _OPENSSL_ia32cap_P+8(%rip),%r10d
testl $512,%r8d
jz L$ialu
+ andl $268435456,%r8d
+ andl $1073741824,%r9d
+ orl %r9d,%r8d
+ cmpl $1342177280,%r8d
+ je _avx_shortcut
jmp _ssse3_shortcut
.p2align 4
@@ -2407,6 +2412,1122 @@ L$done_ssse3:
L$epilogue_ssse3:
.byte 0xf3,0xc3
+
+.p2align 4
+sha1_block_data_order_avx:
+_avx_shortcut:
+ movq %rsp,%rax
+ pushq %rbx
+ pushq %rbp
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ leaq -64(%rsp),%rsp
+ vzeroupper
+ movq %rax,%r14
+ andq $-64,%rsp
+ movq %rdi,%r8
+ movq %rsi,%r9
+ movq %rdx,%r10
+
+ shlq $6,%r10
+ addq %r9,%r10
+ leaq K_XX_XX+64(%rip),%r11
+
+ 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(%r11),%xmm6
+ vmovdqa -64(%r11),%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 L$oop_avx
+.p2align 4
+L$oop_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(%r11),%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(%r11),%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(%r11),%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 L$done_avx
+ vmovdqa 64(%r11),%xmm6
+ vmovdqa -64(%r11),%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 L$oop_avx
+
+.p2align 4
+L$done_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)
+ leaq (%r14),%rsi
+ movq -40(%rsi),%r14
+ movq -32(%rsi),%r13
+ movq -24(%rsi),%r12
+ movq -16(%rsi),%rbp
+ movq -8(%rsi),%rbx
+ leaq (%rsi),%rsp
+L$epilogue_avx:
+ .byte 0xf3,0xc3
+
.p2align 6
K_XX_XX:
.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999
diff --git a/mac-x86_64/crypto/sha/sha256-x86_64.S b/mac-x86_64/crypto/sha/sha256-x86_64.S
index da02d4c..0146ff5 100644
--- a/mac-x86_64/crypto/sha/sha256-x86_64.S
+++ b/mac-x86_64/crypto/sha/sha256-x86_64.S
@@ -11,6 +11,11 @@ _sha256_block_data_order:
movl 0(%r11),%r9d
movl 4(%r11),%r10d
movl 8(%r11),%r11d
+ andl $1073741824,%r9d
+ andl $268435968,%r10d
+ orl %r9d,%r10d
+ cmpl $1342177792,%r10d
+ je L$avx_shortcut
testl $512,%r10d
jnz L$ssse3_shortcut
pushq %rbx
@@ -2840,4 +2845,1061 @@ L$ssse3_00_47:
L$epilogue_ssse3:
.byte 0xf3,0xc3
+
+.p2align 6
+sha256_block_data_order_avx:
+L$avx_shortcut:
+ pushq %rbx
+ pushq %rbp
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ movq %rsp,%r11
+ 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 %r11,64+24(%rsp)
+L$prologue_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 L$loop_avx
+.p2align 4
+L$loop_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 L$avx_00_47
+
+.p2align 4
+L$avx_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 L$avx_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 L$loop_avx
+
+ movq 64+24(%rsp),%rsi
+ vzeroupper
+ movq (%rsi),%r15
+ movq 8(%rsi),%r14
+ movq 16(%rsi),%r13
+ movq 24(%rsi),%r12
+ movq 32(%rsi),%rbp
+ movq 40(%rsi),%rbx
+ leaq 48(%rsi),%rsp
+L$epilogue_avx:
+ .byte 0xf3,0xc3
+
#endif
diff --git a/mac-x86_64/crypto/sha/sha512-x86_64.S b/mac-x86_64/crypto/sha/sha512-x86_64.S
index 2f5d912..aeabd3f 100644
--- a/mac-x86_64/crypto/sha/sha512-x86_64.S
+++ b/mac-x86_64/crypto/sha/sha512-x86_64.S
@@ -7,6 +7,17 @@
.p2align 4
_sha512_block_data_order:
+ leaq _OPENSSL_ia32cap_P(%rip),%r11
+ movl 0(%r11),%r9d
+ movl 4(%r11),%r10d
+ movl 8(%r11),%r11d
+ testl $2048,%r10d
+ jnz L$xop_shortcut
+ andl $1073741824,%r9d
+ andl $268435968,%r10d
+ orl %r9d,%r10d
+ cmpl $1342177792,%r10d
+ je L$avx_shortcut
pushq %rbx
pushq %rbp
pushq %r12
@@ -1783,4 +1794,2234 @@ K512:
.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
+
+.p2align 6
+sha512_block_data_order_xop:
+L$xop_shortcut:
+ pushq %rbx
+ pushq %rbp
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ movq %rsp,%r11
+ 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 %r11,128+24(%rsp)
+L$prologue_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 L$loop_xop
+.p2align 4
+L$loop_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 L$xop_00_47
+
+.p2align 4
+L$xop_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 L$xop_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 L$loop_xop
+
+ movq 128+24(%rsp),%rsi
+ vzeroupper
+ movq (%rsi),%r15
+ movq 8(%rsi),%r14
+ movq 16(%rsi),%r13
+ movq 24(%rsi),%r12
+ movq 32(%rsi),%rbp
+ movq 40(%rsi),%rbx
+ leaq 48(%rsi),%rsp
+L$epilogue_xop:
+ .byte 0xf3,0xc3
+
+
+.p2align 6
+sha512_block_data_order_avx:
+L$avx_shortcut:
+ pushq %rbx
+ pushq %rbp
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ movq %rsp,%r11
+ 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 %r11,128+24(%rsp)
+L$prologue_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 L$loop_avx
+.p2align 4
+L$loop_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 L$avx_00_47
+
+.p2align 4
+L$avx_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 L$avx_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 L$loop_avx
+
+ movq 128+24(%rsp),%rsi
+ vzeroupper
+ movq (%rsi),%r15
+ movq 8(%rsi),%r14
+ movq 16(%rsi),%r13
+ movq 24(%rsi),%r12
+ movq 32(%rsi),%rbp
+ movq 40(%rsi),%rbx
+ leaq 48(%rsi),%rsp
+L$epilogue_avx:
+ .byte 0xf3,0xc3
+
#endif
diff --git a/sources.mk b/sources.mk
index 3674f3c..e82f3d5 100644
--- a/sources.mk
+++ b/sources.mk
@@ -109,6 +109,8 @@ crypto_sources := \
src/crypto/cpu-arm.c\
src/crypto/cpu-intel.c\
src/crypto/crypto.c\
+ src/crypto/curve25519/curve25519.c\
+ src/crypto/curve25519/x25519-x86_64.c\
src/crypto/des/des.c\
src/crypto/dh/check.c\
src/crypto/dh/dh.c\
@@ -302,6 +304,7 @@ ssl_sources := \
src/ssl/ssl_buffer.c\
src/ssl/ssl_cert.c\
src/ssl/ssl_cipher.c\
+ src/ssl/ssl_ecdh.c\
src/ssl/ssl_file.c\
src/ssl/ssl_lib.c\
src/ssl/ssl_rsa.c\
@@ -317,6 +320,7 @@ tool_sources := \
src/tool/client.cc\
src/tool/const.cc\
src/tool/digest.cc\
+ src/tool/generate_ed25519.cc\
src/tool/genrsa.cc\
src/tool/pkcs12.cc\
src/tool/rand.cc\
@@ -345,6 +349,7 @@ linux_arm_sources := \
linux-arm/crypto/sha/sha512-armv4.S\
src/crypto/chacha/chacha_vec_arm.S\
src/crypto/cpu-arm-asm.S\
+ src/crypto/curve25519/asm/x25519-asm-arm.S\
src/crypto/poly1305/poly1305_arm_asm.S\
linux_x86_sources := \
@@ -375,7 +380,6 @@ linux_x86_64_sources := \
linux-x86_64/crypto/modes/aesni-gcm-x86_64.S\
linux-x86_64/crypto/modes/ghash-x86_64.S\
linux-x86_64/crypto/rand/rdrand-x86_64.S\
- linux-x86_64/crypto/rc4/rc4-md5-x86_64.S\
linux-x86_64/crypto/rc4/rc4-x86_64.S\
linux-x86_64/crypto/sha/sha1-x86_64.S\
linux-x86_64/crypto/sha/sha256-x86_64.S\
@@ -409,7 +413,6 @@ mac_x86_64_sources := \
mac-x86_64/crypto/modes/aesni-gcm-x86_64.S\
mac-x86_64/crypto/modes/ghash-x86_64.S\
mac-x86_64/crypto/rand/rdrand-x86_64.S\
- mac-x86_64/crypto/rc4/rc4-md5-x86_64.S\
mac-x86_64/crypto/rc4/rc4-x86_64.S\
mac-x86_64/crypto/sha/sha1-x86_64.S\
mac-x86_64/crypto/sha/sha256-x86_64.S\
@@ -443,7 +446,6 @@ win_x86_64_sources := \
win-x86_64/crypto/modes/aesni-gcm-x86_64.asm\
win-x86_64/crypto/modes/ghash-x86_64.asm\
win-x86_64/crypto/rand/rdrand-x86_64.asm\
- win-x86_64/crypto/rc4/rc4-md5-x86_64.asm\
win-x86_64/crypto/rc4/rc4-x86_64.asm\
win-x86_64/crypto/sha/sha1-x86_64.asm\
win-x86_64/crypto/sha/sha256-x86_64.asm\
diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt
index 89f4ce5..6651f29 100644
--- a/src/crypto/CMakeLists.txt
+++ b/src/crypto/CMakeLists.txt
@@ -105,6 +105,7 @@ add_subdirectory(rc4)
add_subdirectory(conf)
add_subdirectory(chacha)
add_subdirectory(poly1305)
+add_subdirectory(curve25519)
# Level 1, depends only on 0.*
add_subdirectory(digest)
@@ -174,6 +175,7 @@ add_library(
$<TARGET_OBJECTS:conf>
$<TARGET_OBJECTS:chacha>
$<TARGET_OBJECTS:poly1305>
+ $<TARGET_OBJECTS:curve25519>
$<TARGET_OBJECTS:buf>
$<TARGET_OBJECTS:bn>
$<TARGET_OBJECTS:bio>
diff --git a/src/crypto/asn1/asn1_lib.c b/src/crypto/asn1/asn1_lib.c
index a109749..0f2ce50 100644
--- a/src/crypto/asn1/asn1_lib.c
+++ b/src/crypto/asn1/asn1_lib.c
@@ -64,10 +64,6 @@
#include <openssl/mem.h>
-/* Used in asn1_mac.h.
- * TODO(davidben): Remove this once asn1_mac.h is gone or trimmed. */
-OPENSSL_DECLARE_ERROR_REASON(ASN1, MALLOC_FAILURE);
-
/* Cross-module errors from crypto/x509/i2d_pr.c */
OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_PUBLIC_KEY_TYPE);
diff --git a/src/crypto/asn1/asn1_par.c b/src/crypto/asn1/asn1_par.c
index aff3e2b..e04aa1e 100644
--- a/src/crypto/asn1/asn1_par.c
+++ b/src/crypto/asn1/asn1_par.c
@@ -61,6 +61,8 @@
#include <openssl/mem.h>
+#define ASN1_PARSE_MAXDEPTH 128
+
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,
@@ -125,6 +127,13 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
#else
dump_indent = 6; /* Because we know BIO_dump_indent() */
#endif
+
+ if (depth > ASN1_PARSE_MAXDEPTH)
+ {
+ BIO_puts(bp, "BAD RECURSION DEPTH\n");
+ return 0;
+ }
+
p= *pp;
tot=p+length;
op=p-1;
diff --git a/src/crypto/asn1/tasn_dec.c b/src/crypto/asn1/tasn_dec.c
index d852ad7..7c81753 100644
--- a/src/crypto/asn1/tasn_dec.c
+++ b/src/crypto/asn1/tasn_dec.c
@@ -170,6 +170,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
int otag;
int ret = 0;
ASN1_VALUE **pchptr, *ptmpval;
+ int combine = aclass & ASN1_TFLG_COMBINE;
if (!pval)
return 0;
if (aux && aux->asn1_cb)
@@ -526,7 +527,8 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
auxerr:
OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
err:
- ASN1_item_ex_free(pval, it);
+ if (combine == 0)
+ ASN1_item_ex_free(pval, it);
if (errtt)
ERR_add_error_data(4, "Field=", errtt->field_name,
", Type=", it->sname);
@@ -742,7 +744,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
{
/* Nothing special */
ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
- -1, 0, opt, ctx);
+ -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx);
if (!ret)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
diff --git a/src/crypto/asn1/tasn_prn.c b/src/crypto/asn1/tasn_prn.c
index 6a097a1..a574055 100644
--- a/src/crypto/asn1/tasn_prn.c
+++ b/src/crypto/asn1/tasn_prn.c
@@ -72,7 +72,7 @@
/* ASN1_PCTX routines */
-ASN1_PCTX default_pctx =
+static ASN1_PCTX default_pctx =
{
ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */
0, /* nm_flags */
diff --git a/src/crypto/bio/pair.c b/src/crypto/bio/pair.c
index 6f78890..fba4be2 100644
--- a/src/crypto/bio/pair.c
+++ b/src/crypto/bio/pair.c
@@ -256,8 +256,8 @@ int BIO_zero_copy_get_read_buf_done(BIO* bio, size_t bytes_read) {
return 0;
}
+ assert(peer_b->len >= bytes_read);
peer_b->len -= bytes_read;
- assert(peer_b->len >= 0);
assert(peer_b->offset + bytes_read <= peer_b->size);
/* Move read offset. If zero_copy_write_lock == 1 we must advance the
diff --git a/src/crypto/bn/add.c b/src/crypto/bn/add.c
index a043d83..23f9f80 100644
--- a/src/crypto/bn/add.c
+++ b/src/crypto/bn/add.c
@@ -56,6 +56,8 @@
#include <openssl/bn.h>
+#include <string.h>
+
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -311,27 +313,8 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
}
}
- if (rp != ap) {
- for (;;) {
- if (!dif--) {
- break;
- }
- rp[0] = ap[0];
- if (!dif--) {
- break;
- }
- rp[1] = ap[1];
- if (!dif--) {
- break;
- }
- rp[2] = ap[2];
- if (!dif--) {
- break;
- }
- rp[3] = ap[3];
- rp += 4;
- ap += 4;
- }
+ if (dif > 0 && rp != ap) {
+ memcpy(rp, ap, sizeof(*rp) * dif);
}
r->top = max;
diff --git a/src/crypto/bn/asm/x86_64-mont5.pl b/src/crypto/bn/asm/x86_64-mont5.pl
index 38def07..3c5a8fc 100644
--- a/src/crypto/bn/asm/x86_64-mont5.pl
+++ b/src/crypto/bn/asm/x86_64-mont5.pl
@@ -1770,6 +1770,15 @@ sqr8x_reduction:
.align 32
.L8x_tail_done:
add (%rdx),%r8 # can this overflow?
+ adc \$0,%r9
+ adc \$0,%r10
+ adc \$0,%r11
+ adc \$0,%r12
+ adc \$0,%r13
+ adc \$0,%r14
+ adc \$0,%r15 # can't overflow, because we
+ # started with "overhung" part
+ # of multiplication
xor %rax,%rax
neg $carry
@@ -3116,6 +3125,15 @@ sqrx8x_reduction:
.align 32
.Lsqrx8x_tail_done:
add 24+8(%rsp),%r8 # can this overflow?
+ adc \$0,%r9
+ adc \$0,%r10
+ adc \$0,%r11
+ adc \$0,%r12
+ adc \$0,%r13
+ adc \$0,%r14
+ adc \$0,%r15 # can't overflow, because we
+ # started with "overhung" part
+ # of multiplication
mov $carry,%rax # xor %rax,%rax
sub 16+8(%rsp),$carry # mov 16(%rsp),%cf
@@ -3159,13 +3177,11 @@ my ($rptr,$nptr)=("%rdx","%rbp");
my @ri=map("%r$_",(10..13));
my @ni=map("%r$_",(14..15));
$code.=<<___;
- xor %rbx,%rbx
+ xor %ebx,%ebx
sub %r15,%rsi # compare top-most words
adc %rbx,%rbx
mov %rcx,%r10 # -$num
- .byte 0x67
or %rbx,%rax
- .byte 0x67
mov %rcx,%r9 # -$num
xor \$1,%rax
sar \$3+2,%rcx # cf=0
diff --git a/src/crypto/bn/bn.c b/src/crypto/bn/bn.c
index b342749..543c148 100644
--- a/src/crypto/bn/bn.c
+++ b/src/crypto/bn/bn.c
@@ -166,11 +166,10 @@ void BN_clear(BIGNUM *bn) {
}
const BIGNUM *BN_value_one(void) {
- static const BN_ULONG data_one = 1;
- static const BIGNUM const_one = {(BN_ULONG *)&data_one, 1, 1, 0,
- BN_FLG_STATIC_DATA};
+ static const BN_ULONG kOneLimbs[1] = { 1 };
+ static const BIGNUM kOne = STATIC_BIGNUM(kOneLimbs);
- return &const_one;
+ return &kOne;
}
void BN_with_flags(BIGNUM *out, const BIGNUM *in, int flags) {
diff --git a/src/crypto/bn/bn_test.cc b/src/crypto/bn/bn_test.cc
index 47093a7..e7e04f1 100644
--- a/src/crypto/bn/bn_test.cc
+++ b/src/crypto/bn/bn_test.cc
@@ -76,6 +76,8 @@
#include <stdio.h>
#include <string.h>
+#include <utility>
+
#include <openssl/bn.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
@@ -211,7 +213,7 @@ int main(int argc, char *argv[]) {
if (!sample) {
return 1;
}
- if (!test_lshift(bc_file.get(), ctx.get(), bssl::move(sample))) {
+ if (!test_lshift(bc_file.get(), ctx.get(), std::move(sample))) {
return 1;
}
flush_fp(bc_file.get());
@@ -328,6 +330,13 @@ int main(int argc, char *argv[]) {
return 0;
}
+static int HexToBIGNUM(ScopedBIGNUM *out, const char *in) {
+ BIGNUM *raw = NULL;
+ int ret = BN_hex2bn(&raw, in);
+ out->reset(raw);
+ return ret;
+}
+
static bool test_add(FILE *fp) {
ScopedBIGNUM a(BN_new());
ScopedBIGNUM b(BN_new());
@@ -1105,6 +1114,27 @@ static bool test_mod_exp(FILE *fp, BN_CTX *ctx) {
return false;
}
}
+
+ // Regression test for carry propagation bug in sqr8x_reduction.
+ if (!HexToBIGNUM(&a, "050505050505") ||
+ !HexToBIGNUM(&b, "02") ||
+ !HexToBIGNUM(
+ &c,
+ "4141414141414141414141274141414141414141414141414141414141414141"
+ "4141414141414141414141414141414141414141414141414141414141414141"
+ "4141414141414141414141800000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000001") ||
+ !BN_mod_exp(d.get(), a.get(), b.get(), c.get(), ctx) ||
+ !BN_mul(e.get(), a.get(), a.get(), ctx)) {
+ return false;
+ }
+ if (BN_cmp(d.get(), e.get()) != 0) {
+ fprintf(stderr, "BN_mod_exp and BN_mul produce different results!\n");
+ return false;
+ }
+
return true;
}
@@ -1286,23 +1316,23 @@ static bool test_exp(FILE *fp, BN_CTX *ctx) {
// test_exp_mod_zero tests that 1**0 mod 1 == 0.
static bool test_exp_mod_zero(void) {
- ScopedBIGNUM zero(BN_new());
- if (!zero) {
+ ScopedBIGNUM zero(BN_new()), a(BN_new()), r(BN_new());
+ if (!zero || !a || !r || !BN_rand(a.get(), 1024, 0, 0)) {
return false;
}
BN_zero(zero.get());
- ScopedBN_CTX ctx(BN_CTX_new());
- ScopedBIGNUM r(BN_new());
- if (!ctx || !r ||
- !BN_mod_exp(r.get(), BN_value_one(), zero.get(), BN_value_one(), ctx.get())) {
- return false;
- }
-
- if (!BN_is_zero(r.get())) {
- fprintf(stderr, "1**0 mod 1 = ");
- BN_print_fp(stderr, r.get());
- fprintf(stderr, ", should be 0\n");
+ if (!BN_mod_exp(r.get(), a.get(), zero.get(), BN_value_one(), nullptr) ||
+ !BN_is_zero(r.get()) ||
+ !BN_mod_exp_mont(r.get(), a.get(), zero.get(), BN_value_one(), nullptr,
+ nullptr) ||
+ !BN_is_zero(r.get()) ||
+ !BN_mod_exp_mont_consttime(r.get(), a.get(), zero.get(), BN_value_one(),
+ nullptr, nullptr) ||
+ !BN_is_zero(r.get()) ||
+ !BN_mod_exp_mont_word(r.get(), 42, zero.get(), BN_value_one(), nullptr,
+ nullptr) ||
+ !BN_is_zero(r.get())) {
return false;
}
@@ -1543,13 +1573,6 @@ static bool test_dec2bn(BN_CTX *ctx) {
return true;
}
-static int HexToBIGNUM(ScopedBIGNUM *out, const char *in) {
- BIGNUM *raw = NULL;
- int ret = BN_hex2bn(&raw, in);
- out->reset(raw);
- return ret;
-}
-
static bool test_hex2bn(BN_CTX *ctx) {
ScopedBIGNUM bn;
int ret = HexToBIGNUM(&bn, "0");
diff --git a/src/crypto/bn/convert.c b/src/crypto/bn/convert.c
index 0122709..1f7af64 100644
--- a/src/crypto/bn/convert.c
+++ b/src/crypto/bn/convert.c
@@ -63,6 +63,7 @@
#include <string.h>
#include <openssl/bio.h>
+#include <openssl/bytestring.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -195,6 +196,11 @@ int BN_bn2bin_padded(uint8_t *out, size_t len, const BIGNUM *in) {
return 1;
}
+int BN_bn2cbb_padded(CBB *out, size_t len, const BIGNUM *in) {
+ uint8_t *ptr;
+ return CBB_add_space(out, &ptr, len) && BN_bn2bin_padded(ptr, len, in);
+}
+
static const char hextable[] = "0123456789abcdef";
char *BN_bn2hex(const BIGNUM *bn) {
diff --git a/src/crypto/bn/div.c b/src/crypto/bn/div.c
index 779dda2..f9e144a 100644
--- a/src/crypto/bn/div.c
+++ b/src/crypto/bn/div.c
@@ -260,10 +260,10 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
q = BN_MASK2;
} else {
/* n0 < d0 */
-#ifdef BN_LLONG
+#ifdef BN_ULLONG
BN_ULLONG t2;
-#if defined(BN_LLONG) && !defined(div_asm)
+#if defined(BN_ULLONG) && !defined(div_asm)
q = (BN_ULONG)(((((BN_ULLONG)n0) << BN_BITS2) | n1) / d0);
#else
q = div_asm(n0, n1, d0);
@@ -288,7 +288,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
}
t2 -= d1;
}
-#else /* !BN_LLONG */
+#else /* !BN_ULLONG */
BN_ULONG t2l, t2h;
#if defined(div_asm)
@@ -331,7 +331,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
}
t2l -= d1;
}
-#endif /* !BN_LLONG */
+#endif /* !BN_ULLONG */
}
l0 = bn_mul_words(tmp->d, sdiv->d, div_n, q);
@@ -601,7 +601,7 @@ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) {
}
BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w) {
-#ifndef BN_LLONG
+#ifndef BN_ULLONG
BN_ULONG ret = 0;
#else
BN_ULLONG ret = 0;
@@ -614,7 +614,7 @@ BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w) {
w &= BN_MASK2;
for (i = a->top - 1; i >= 0; i--) {
-#ifndef BN_LLONG
+#ifndef BN_ULLONG
ret = ((ret << BN_BITS4) | ((a->d[i] >> BN_BITS4) & BN_MASK2l)) % w;
ret = ((ret << BN_BITS4) | (a->d[i] & BN_MASK2l)) % w;
#else
diff --git a/src/crypto/bn/exponentiation.c b/src/crypto/bn/exponentiation.c
index c580248..72a8db4 100644
--- a/src/crypto/bn/exponentiation.c
+++ b/src/crypto/bn/exponentiation.c
@@ -445,8 +445,12 @@ static int mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
bits = BN_num_bits(p);
if (bits == 0) {
- ret = BN_one(r);
- return ret;
+ /* x**0 mod 1 is still zero. */
+ if (BN_is_one(m)) {
+ BN_zero(r);
+ return 1;
+ }
+ return BN_one(r);
}
BN_CTX_start(ctx);
@@ -632,8 +636,12 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
}
bits = BN_num_bits(p);
if (bits == 0) {
- ret = BN_one(rr);
- return ret;
+ /* x**0 mod 1 is still zero. */
+ if (BN_is_one(m)) {
+ BN_zero(rr);
+ return 1;
+ }
+ return BN_one(rr);
}
BN_CTX_start(ctx);
@@ -875,8 +883,12 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
bits = BN_num_bits(p);
if (bits == 0) {
- ret = BN_one(rr);
- return ret;
+ /* x**0 mod 1 is still zero. */
+ if (BN_is_one(m)) {
+ BN_zero(rr);
+ return 1;
+ }
+ return BN_one(rr);
}
BN_CTX_start(ctx);
@@ -1230,17 +1242,14 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
if (bits == 0) {
/* x**0 mod 1 is still zero. */
if (BN_is_one(m)) {
- ret = 1;
BN_zero(rr);
- } else {
- ret = BN_one(rr);
+ return 1;
}
- return ret;
+ return BN_one(rr);
}
if (a == 0) {
BN_zero(rr);
- ret = 1;
- return ret;
+ return 1;
}
BN_CTX_start(ctx);
diff --git a/src/crypto/bn/gcd.c b/src/crypto/bn/gcd.c
index e106149..41ca6d2 100644
--- a/src/crypto/bn/gcd.c
+++ b/src/crypto/bn/gcd.c
@@ -279,7 +279,7 @@ BIGNUM *BN_mod_inverse_ex(BIGNUM *out, int *out_no_inverse, const BIGNUM *a,
* sign*Y*a == A (mod |n|).
*/
- if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048))) {
+ if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS2 <= 32 ? 450 : 2048))) {
/* Binary inversion algorithm; requires odd modulus.
* This is faster than the general algorithm if the modulus
* is sufficiently small (about 400 .. 500 bits on 32-bit
diff --git a/src/crypto/bn/generic.c b/src/crypto/bn/generic.c
index 7fd4819..7303ca5 100644
--- a/src/crypto/bn/generic.c
+++ b/src/crypto/bn/generic.c
@@ -69,13 +69,7 @@
(!defined(OPENSSL_X86_64) && !defined(OPENSSL_X86)) || \
(defined(OPENSSL_X86_64) && defined(OPENSSL_WINDOWS))
-#if defined(OPENSSL_WINDOWS)
-#define alloca _alloca
-#else
-#include <alloca.h>
-#endif
-
-#ifdef BN_LLONG
+#ifdef BN_ULLONG
#define mul_add(r, a, w, c) \
{ \
BN_ULLONG t; \
@@ -222,9 +216,9 @@
(c) = h & BN_MASK2; \
(r) = l & BN_MASK2; \
}
-#endif /* !BN_LLONG */
+#endif /* !BN_ULLONG */
-#if defined(BN_LLONG) || defined(BN_UMULT_HIGH)
+#if defined(BN_ULLONG) || defined(BN_UMULT_HIGH)
BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
BN_ULONG w) {
@@ -304,7 +298,7 @@ void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) {
}
}
-#else /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */
+#else /* !(defined(BN_ULLONG) || defined(BN_UMULT_HIGH)) */
BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
BN_ULONG w) {
@@ -390,9 +384,9 @@ void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) {
}
}
-#endif /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */
+#endif /* !(defined(BN_ULLONG) || defined(BN_UMULT_HIGH)) */
-#if defined(BN_LLONG)
+#if defined(BN_ULLONG)
BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) {
return (BN_ULONG)(((((BN_ULLONG)h) << BN_BITS2) | l) / (BN_ULLONG)d);
@@ -470,9 +464,9 @@ BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) {
return ret;
}
-#endif /* !defined(BN_LLONG) */
+#endif /* !defined(BN_ULLONG) */
-#ifdef BN_LLONG
+#ifdef BN_ULLONG
BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
int n) {
BN_ULLONG ll = 0;
@@ -512,7 +506,7 @@ BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
return (BN_ULONG)ll;
}
-#else /* !BN_LLONG */
+#else /* !BN_ULLONG */
BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
int n) {
@@ -569,7 +563,7 @@ BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
return (BN_ULONG)c;
}
-#endif /* !BN_LLONG */
+#endif /* !BN_ULLONG */
BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
int n) {
@@ -631,7 +625,7 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
/* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
-#ifdef BN_LLONG
+#ifdef BN_ULLONG
/* Keep in mind that additions to multiplication result can not overflow,
* because its high half cannot be all-ones. */
@@ -722,7 +716,7 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
-#else /* !BN_LLONG */
+#else /* !BN_ULLONG */
/* Keep in mind that additions to hi can not overflow, because
* the high word of a multiplication result cannot be all-ones. */
@@ -774,7 +768,7 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
} while (0)
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
-#endif /* !BN_LLONG */
+#endif /* !BN_ULLONG */
void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
BN_ULONG c1, c2, c3;
diff --git a/src/crypto/bn/internal.h b/src/crypto/bn/internal.h
index 0d0eb44..72ef4e9 100644
--- a/src/crypto/bn/internal.h
+++ b/src/crypto/bn/internal.h
@@ -144,44 +144,41 @@ BIGNUM *bn_expand(BIGNUM *bn, size_t bits);
#if !defined(_MSC_VER)
/* MSVC doesn't support two-word integers on 64-bit. */
-#define BN_LLONG __int128_t
#define BN_ULLONG __uint128_t
#endif
-#define BN_BITS 128
#define BN_BITS2 64
#define BN_BYTES 8
#define BN_BITS4 32
-#define BN_MASK (0xffffffffffffffffffffffffffffffffLL)
-#define BN_MASK2 (0xffffffffffffffffL)
-#define BN_MASK2l (0xffffffffL)
-#define BN_MASK2h (0xffffffff00000000L)
-#define BN_MASK2h1 (0xffffffff80000000L)
-#define BN_TBIT (0x8000000000000000L)
+#define BN_MASK2 (0xffffffffffffffffUL)
+#define BN_MASK2l (0xffffffffUL)
+#define BN_MASK2h (0xffffffff00000000UL)
+#define BN_MASK2h1 (0xffffffff80000000UL)
+#define BN_TBIT (0x8000000000000000UL)
#define BN_DEC_CONV (10000000000000000000UL)
#define BN_DEC_NUM 19
+#define TOBN(hi, lo) ((BN_ULONG)hi << 32 | lo)
#elif defined(OPENSSL_32_BIT)
-#define BN_LLONG int64_t
#define BN_ULLONG uint64_t
-#define BN_MASK (0xffffffffffffffffLL)
-#define BN_BITS 64
#define BN_BITS2 32
#define BN_BYTES 4
#define BN_BITS4 16
-#define BN_MASK2 (0xffffffffL)
-#define BN_MASK2l (0xffff)
-#define BN_MASK2h1 (0xffff8000L)
-#define BN_MASK2h (0xffff0000L)
-#define BN_TBIT (0x80000000L)
-#define BN_DEC_CONV (1000000000L)
+#define BN_MASK2 (0xffffffffUL)
+#define BN_MASK2l (0xffffUL)
+#define BN_MASK2h1 (0xffff8000UL)
+#define BN_MASK2h (0xffff0000UL)
+#define BN_TBIT (0x80000000UL)
+#define BN_DEC_CONV (1000000000UL)
#define BN_DEC_NUM 9
+#define TOBN(hi, lo) lo, hi
#else
#error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT"
#endif
+
/* Pentium pro 16,16,16,32,64 */
/* Alpha 16,16,16,16.64 */
#define BN_MULL_SIZE_NORMAL (16) /* 32 */
@@ -190,7 +187,13 @@ BIGNUM *bn_expand(BIGNUM *bn, size_t bits);
#define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL (32) /* 32 */
#define BN_MONT_CTX_SET_SIZE_WORD (64) /* 32 */
-#if defined(BN_LLONG)
+#define STATIC_BIGNUM(x) \
+ { \
+ (BN_ULONG *)x, sizeof(x) / sizeof(BN_ULONG), \
+ sizeof(x) / sizeof(BN_ULONG), 0, BN_FLG_STATIC_DATA \
+ }
+
+#if defined(BN_ULLONG)
#define Lw(t) (((BN_ULONG)(t))&BN_MASK2)
#define Hw(t) (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2)
#endif
@@ -220,7 +223,7 @@ int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl);
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);
-#if !defined(BN_LLONG)
+#if !defined(BN_ULLONG)
#define LBITS(a) ((a) & BN_MASK2l)
#define HBITS(a) (((a) >> BN_BITS4) & BN_MASK2l)
@@ -252,7 +255,7 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
(h) = ht; \
}
-#endif /* !defined(BN_LLONG) */
+#endif /* !defined(BN_ULLONG) */
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64)
# if defined(__GNUC__) && __GNUC__ >= 2
diff --git a/src/crypto/bn/montgomery.c b/src/crypto/bn/montgomery.c
index 11edcbf..18da0da 100644
--- a/src/crypto/bn/montgomery.c
+++ b/src/crypto/bn/montgomery.c
@@ -134,7 +134,6 @@ BN_MONT_CTX *BN_MONT_CTX_new(void) {
memset(ret, 0, sizeof(BN_MONT_CTX));
BN_init(&ret->RR);
BN_init(&ret->N);
- BN_init(&ret->Ni);
return ret;
}
@@ -146,7 +145,6 @@ void BN_MONT_CTX_free(BN_MONT_CTX *mont) {
BN_free(&mont->RR);
BN_free(&mont->N);
- BN_free(&mont->Ni);
OPENSSL_free(mont);
}
@@ -156,11 +154,9 @@ BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, const BN_MONT_CTX *from) {
}
if (!BN_copy(&to->RR, &from->RR) ||
- !BN_copy(&to->N, &from->N) ||
- !BN_copy(&to->Ni, &from->Ni)) {
+ !BN_copy(&to->N, &from->N)) {
return NULL;
}
- to->ri = from->ri;
to->n0[0] = from->n0[0];
to->n0[1] = from->n0[1];
return to;
@@ -193,8 +189,6 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) {
tmod.dmax = 2;
tmod.neg = 0;
- mont->ri = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2;
-
#if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2 <= 32)
/* Only certain BN_BITS2<=32 platforms actually make use of
* n0[1], and we could use the #else case (with a shorter R
@@ -278,9 +272,10 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) {
mont->n0[1] = 0;
#endif
- /* setup RR for conversions */
+ /* RR = (2^ri)^2 == 2^(ri*2) == 1 << (ri*2), which has its (ri*2)th bit set. */
+ int ri = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2;
BN_zero(&(mont->RR));
- if (!BN_set_bit(&(mont->RR), mont->ri * 2)) {
+ if (!BN_set_bit(&(mont->RR), ri * 2)) {
goto err;
}
if (!BN_mod(&(mont->RR), &(mont->RR), &(mont->N), ctx)) {
diff --git a/src/crypto/bytestring/bytestring_test.cc b/src/crypto/bytestring/bytestring_test.cc
index eae88d9..188c63d 100644
--- a/src/crypto/bytestring/bytestring_test.cc
+++ b/src/crypto/bytestring/bytestring_test.cc
@@ -12,6 +12,10 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+#if !defined(__STDC_CONSTANT_MACROS)
+#define __STDC_CONSTANT_MACROS
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -22,7 +26,6 @@
#include <openssl/bytestring.h>
#include "internal.h"
-#include "../internal.h"
#include "../test/scoped_types.h"
@@ -341,12 +344,14 @@ static bool TestCBBPrefixed() {
size_t buf_len;
CBB cbb, contents, inner_contents, inner_inner_contents;
- if (!CBB_init(&cbb, 0)) {
- return false;
- }
- if (!CBB_add_u8_length_prefixed(&cbb, &contents) ||
+ if (!CBB_init(&cbb, 0) ||
+ CBB_len(&cbb) != 0 ||
+ !CBB_add_u8_length_prefixed(&cbb, &contents) ||
!CBB_add_u8_length_prefixed(&cbb, &contents) ||
!CBB_add_u8(&contents, 1) ||
+ CBB_len(&contents) != 1 ||
+ !CBB_flush(&cbb) ||
+ CBB_len(&cbb) != 3 ||
!CBB_add_u16_length_prefixed(&cbb, &contents) ||
!CBB_add_u16(&contents, 0x203) ||
!CBB_add_u24_length_prefixed(&cbb, &contents) ||
@@ -483,7 +488,7 @@ static bool TestCBBASN1() {
return false;
}
if (!CBB_add_asn1(&cbb, &contents, 0x30) ||
- !CBB_add_bytes(&contents, bssl::vector_data(&test_data), 130) ||
+ !CBB_add_bytes(&contents, test_data.data(), 130) ||
!CBB_finish(&cbb, &buf, &buf_len)) {
CBB_cleanup(&cbb);
return false;
@@ -492,7 +497,7 @@ static bool TestCBBASN1() {
if (buf_len != 3 + 130 ||
memcmp(buf, "\x30\x81\x82", 3) != 0 ||
- memcmp(buf + 3, bssl::vector_data(&test_data), 130) != 0) {
+ memcmp(buf + 3, test_data.data(), 130) != 0) {
return false;
}
@@ -500,7 +505,7 @@ static bool TestCBBASN1() {
return false;
}
if (!CBB_add_asn1(&cbb, &contents, 0x30) ||
- !CBB_add_bytes(&contents, bssl::vector_data(&test_data), 1000) ||
+ !CBB_add_bytes(&contents, test_data.data(), 1000) ||
!CBB_finish(&cbb, &buf, &buf_len)) {
CBB_cleanup(&cbb);
return false;
@@ -509,7 +514,7 @@ static bool TestCBBASN1() {
if (buf_len != 4 + 1000 ||
memcmp(buf, "\x30\x82\x03\xe8", 4) != 0 ||
- memcmp(buf + 4, bssl::vector_data(&test_data), 1000)) {
+ memcmp(buf + 4, test_data.data(), 1000)) {
return false;
}
@@ -518,7 +523,7 @@ static bool TestCBBASN1() {
}
if (!CBB_add_asn1(&cbb, &contents, 0x30) ||
!CBB_add_asn1(&contents, &inner_contents, 0x30) ||
- !CBB_add_bytes(&inner_contents, bssl::vector_data(&test_data), 100000) ||
+ !CBB_add_bytes(&inner_contents, test_data.data(), 100000) ||
!CBB_finish(&cbb, &buf, &buf_len)) {
CBB_cleanup(&cbb);
return false;
@@ -527,7 +532,7 @@ static bool TestCBBASN1() {
if (buf_len != 5 + 5 + 100000 ||
memcmp(buf, "\x30\x83\x01\x86\xa5\x30\x83\x01\x86\xa0", 10) != 0 ||
- memcmp(buf + 10, bssl::vector_data(&test_data), 100000)) {
+ memcmp(buf + 10, test_data.data(), 100000)) {
return false;
}
@@ -627,9 +632,9 @@ static const ASN1Uint64Test kASN1Uint64Tests[] = {
{127, "\x02\x01\x7f", 3},
{128, "\x02\x02\x00\x80", 4},
{0xdeadbeef, "\x02\x05\x00\xde\xad\xbe\xef", 7},
- {OPENSSL_U64(0x0102030405060708),
+ {UINT64_C(0x0102030405060708),
"\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10},
- {OPENSSL_U64(0xffffffffffffffff),
+ {UINT64_C(0xffffffffffffffff),
"\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11},
};
@@ -698,12 +703,32 @@ static bool TestASN1Uint64() {
return true;
}
-static int TestZero() {
+static bool TestZero() {
CBB cbb;
CBB_zero(&cbb);
// Calling |CBB_cleanup| on a zero-state |CBB| must not crash.
CBB_cleanup(&cbb);
- return 1;
+ return true;
+}
+
+static bool TestCBBReserve() {
+ uint8_t buf[10];
+ uint8_t *ptr;
+ size_t len;
+ ScopedCBB cbb;
+ if (!CBB_init_fixed(cbb.get(), buf, sizeof(buf)) ||
+ // Too large.
+ CBB_reserve(cbb.get(), &ptr, 11) ||
+ // Successfully reserve the entire space.
+ !CBB_reserve(cbb.get(), &ptr, 10) ||
+ ptr != buf ||
+ // Advancing under the maximum bytes is legal.
+ !CBB_did_write(cbb.get(), 5) ||
+ !CBB_finish(cbb.get(), NULL, &len) ||
+ len != 5) {
+ return false;
+ }
+ return true;
}
int main(void) {
@@ -724,7 +749,8 @@ int main(void) {
!TestBerConvert() ||
!TestASN1Uint64() ||
!TestGetOptionalASN1Bool() ||
- !TestZero()) {
+ !TestZero() ||
+ !TestCBBReserve()) {
return 1;
}
diff --git a/src/crypto/bytestring/cbb.c b/src/crypto/bytestring/cbb.c
index 434ec13..8fc5187 100644
--- a/src/crypto/bytestring/cbb.c
+++ b/src/crypto/bytestring/cbb.c
@@ -25,6 +25,7 @@ void CBB_zero(CBB *cbb) {
}
static int cbb_init(CBB *cbb, uint8_t *buf, size_t cap) {
+ /* This assumes that |cbb| has already been zeroed. */
struct cbb_buffer_st *base;
base = OPENSSL_malloc(sizeof(struct cbb_buffer_st));
@@ -37,16 +38,15 @@ static int cbb_init(CBB *cbb, uint8_t *buf, size_t cap) {
base->cap = cap;
base->can_resize = 1;
- memset(cbb, 0, sizeof(CBB));
cbb->base = base;
cbb->is_top_level = 1;
return 1;
}
int CBB_init(CBB *cbb, size_t initial_capacity) {
- uint8_t *buf;
+ CBB_zero(cbb);
- buf = OPENSSL_malloc(initial_capacity);
+ uint8_t *buf = OPENSSL_malloc(initial_capacity);
if (initial_capacity > 0 && buf == NULL) {
return 0;
}
@@ -60,6 +60,8 @@ int CBB_init(CBB *cbb, size_t initial_capacity) {
}
int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len) {
+ CBB_zero(cbb);
+
if (!cbb_init(cbb, buf, len)) {
return 0;
}
@@ -82,8 +84,8 @@ void CBB_cleanup(CBB *cbb) {
cbb->base = NULL;
}
-static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out,
- size_t len) {
+static int cbb_buffer_reserve(struct cbb_buffer_st *base, uint8_t **out,
+ size_t len) {
size_t newlen;
if (base == NULL) {
@@ -119,7 +121,17 @@ static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out,
if (out) {
*out = base->buf + base->len;
}
- base->len = newlen;
+
+ return 1;
+}
+
+static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out,
+ size_t len) {
+ if (!cbb_buffer_reserve(base, out, len)) {
+ return 0;
+ }
+ /* This will not overflow or |cbb_buffer_reserve| would have failed. */
+ base->len += len;
return 1;
}
@@ -177,28 +189,28 @@ int CBB_flush(CBB *cbb) {
return 0;
}
- if (cbb->child == NULL || cbb->pending_len_len == 0) {
+ if (cbb->child == NULL || cbb->child->pending_len_len == 0) {
return 1;
}
- child_start = cbb->offset + cbb->pending_len_len;
+ child_start = cbb->child->offset + cbb->child->pending_len_len;
if (!CBB_flush(cbb->child) ||
- child_start < cbb->offset ||
+ child_start < cbb->child->offset ||
cbb->base->len < child_start) {
return 0;
}
len = cbb->base->len - child_start;
- if (cbb->pending_is_asn1) {
+ if (cbb->child->pending_is_asn1) {
/* For ASN.1 we assume that we'll only need a single byte for the length.
* If that turned out to be incorrect, we have to move the contents along
* in order to make space. */
size_t len_len;
uint8_t initial_length_byte;
- assert (cbb->pending_len_len == 1);
+ assert (cbb->child->pending_len_len == 1);
if (len > 0xfffffffe) {
/* Too large. */
@@ -230,12 +242,13 @@ int CBB_flush(CBB *cbb) {
memmove(cbb->base->buf + child_start + extra_bytes,
cbb->base->buf + child_start, len);
}
- cbb->base->buf[cbb->offset++] = initial_length_byte;
- cbb->pending_len_len = len_len - 1;
+ cbb->base->buf[cbb->child->offset++] = initial_length_byte;
+ cbb->child->pending_len_len = len_len - 1;
}
- for (i = cbb->pending_len_len - 1; i < cbb->pending_len_len; i--) {
- cbb->base->buf[cbb->offset + i] = len;
+ for (i = cbb->child->pending_len_len - 1; i < cbb->child->pending_len_len;
+ i--) {
+ cbb->base->buf[cbb->child->offset + i] = len;
len >>= 8;
}
if (len != 0) {
@@ -244,17 +257,20 @@ int CBB_flush(CBB *cbb) {
cbb->child->base = NULL;
cbb->child = NULL;
- cbb->pending_len_len = 0;
- cbb->pending_is_asn1 = 0;
- cbb->offset = 0;
return 1;
}
+const uint8_t *CBB_data(const CBB *cbb) {
+ assert(cbb->child == NULL);
+ return cbb->base->buf + cbb->offset + cbb->pending_len_len;
+}
+
size_t CBB_len(const CBB *cbb) {
assert(cbb->child == NULL);
+ assert(cbb->offset + cbb->pending_len_len <= cbb->base->len);
- return cbb->base->len;
+ return cbb->base->len - cbb->offset - cbb->pending_len_len;
}
static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents,
@@ -265,7 +281,7 @@ static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents,
return 0;
}
- cbb->offset = cbb->base->len;
+ size_t offset = cbb->base->len;
if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len)) {
return 0;
}
@@ -274,8 +290,9 @@ static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents,
memset(out_contents, 0, sizeof(CBB));
out_contents->base = cbb->base;
cbb->child = out_contents;
- cbb->pending_len_len = len_len;
- cbb->pending_is_asn1 = 0;
+ cbb->child->offset = offset;
+ cbb->child->pending_len_len = len_len;
+ cbb->child->pending_is_asn1 = 0;
return 1;
}
@@ -303,7 +320,7 @@ int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag) {
return 0;
}
- cbb->offset = cbb->base->len;
+ size_t offset = cbb->base->len;
if (!CBB_add_u8(cbb, 0)) {
return 0;
}
@@ -311,8 +328,9 @@ int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag) {
memset(out_contents, 0, sizeof(CBB));
out_contents->base = cbb->base;
cbb->child = out_contents;
- cbb->pending_len_len = 1;
- cbb->pending_is_asn1 = 1;
+ cbb->child->offset = offset;
+ cbb->child->pending_len_len = 1;
+ cbb->child->pending_is_asn1 = 1;
return 1;
}
@@ -336,6 +354,25 @@ int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len) {
return 1;
}
+int CBB_reserve(CBB *cbb, uint8_t **out_data, size_t len) {
+ if (!CBB_flush(cbb) ||
+ !cbb_buffer_reserve(cbb->base, out_data, len)) {
+ return 0;
+ }
+ return 1;
+}
+
+int CBB_did_write(CBB *cbb, size_t len) {
+ size_t newlen = cbb->base->len + len;
+ if (cbb->child != NULL ||
+ newlen < cbb->base->len ||
+ newlen > cbb->base->cap) {
+ return 0;
+ }
+ cbb->base->len = newlen;
+ return 1;
+}
+
int CBB_add_u8(CBB *cbb, uint8_t value) {
if (!CBB_flush(cbb)) {
return 0;
@@ -365,13 +402,10 @@ void CBB_discard_child(CBB *cbb) {
return;
}
- cbb->base->len = cbb->offset;
+ cbb->base->len = cbb->child->offset;
cbb->child->base = NULL;
cbb->child = NULL;
- cbb->pending_len_len = 0;
- cbb->pending_is_asn1 = 0;
- cbb->offset = 0;
}
int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) {
diff --git a/src/crypto/cipher/aead_test.cc b/src/crypto/cipher/aead_test.cc
index a4ddd3b..79d7110 100644
--- a/src/crypto/cipher/aead_test.cc
+++ b/src/crypto/cipher/aead_test.cc
@@ -23,7 +23,6 @@
#include "../test/file_test.h"
#include "../test/scoped_types.h"
-#include "../test/stl_compat.h"
// This program tests an AEAD against a series of test vectors from a file,
@@ -50,8 +49,7 @@ static bool TestAEAD(FileTest *t, void *arg) {
}
ScopedEVP_AEAD_CTX ctx;
- if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead,
- bssl::vector_data(&key), key.size(),
+ if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead, key.data(), key.size(),
tag.size(), evp_aead_seal)) {
t->PrintLine("Failed to init AEAD.");
return false;
@@ -60,10 +58,9 @@ static bool TestAEAD(FileTest *t, void *arg) {
std::vector<uint8_t> out(in.size() + EVP_AEAD_max_overhead(aead));
if (!t->HasAttribute("NO_SEAL")) {
size_t out_len;
- if (!EVP_AEAD_CTX_seal(ctx.get(), bssl::vector_data(&out), &out_len,
- out.size(), bssl::vector_data(&nonce), nonce.size(),
- bssl::vector_data(&in), in.size(),
- bssl::vector_data(&ad), ad.size())) {
+ if (!EVP_AEAD_CTX_seal(ctx.get(), out.data(), &out_len, out.size(),
+ nonce.data(), nonce.size(), in.data(), in.size(),
+ ad.data(), ad.size())) {
t->PrintLine("Failed to run AEAD.");
return false;
}
@@ -74,24 +71,21 @@ static bool TestAEAD(FileTest *t, void *arg) {
(unsigned)(ct.size() + tag.size()));
return false;
}
- if (!t->ExpectBytesEqual(bssl::vector_data(&ct), ct.size(),
- bssl::vector_data(&out), ct.size()) ||
- !t->ExpectBytesEqual(bssl::vector_data(&tag), tag.size(),
- bssl::vector_data(&out) + ct.size(), tag.size())) {
+ if (!t->ExpectBytesEqual(ct.data(), ct.size(), out.data(), ct.size()) ||
+ !t->ExpectBytesEqual(tag.data(), tag.size(), out.data() + ct.size(),
+ tag.size())) {
return false;
}
} else {
out.resize(ct.size() + tag.size());
- memcpy(bssl::vector_data(&out), bssl::vector_data(&ct), ct.size());
- memcpy(bssl::vector_data(&out) + ct.size(), bssl::vector_data(&tag),
- tag.size());
+ memcpy(out.data(), ct.data(), ct.size());
+ memcpy(out.data() + ct.size(), tag.data(), tag.size());
}
// The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
// reset after each operation.
ctx.Reset();
- if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead,
- bssl::vector_data(&key), key.size(),
+ if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead, key.data(), key.size(),
tag.size(), evp_aead_open)) {
t->PrintLine("Failed to init AEAD.");
return false;
@@ -99,11 +93,9 @@ static bool TestAEAD(FileTest *t, void *arg) {
std::vector<uint8_t> out2(out.size());
size_t out2_len;
- int ret = EVP_AEAD_CTX_open(ctx.get(),
- bssl::vector_data(&out2), &out2_len, out2.size(),
- bssl::vector_data(&nonce), nonce.size(),
- bssl::vector_data(&out), out.size(),
- bssl::vector_data(&ad), ad.size());
+ int ret = EVP_AEAD_CTX_open(ctx.get(), out2.data(), &out2_len, out2.size(),
+ nonce.data(), nonce.size(), out.data(),
+ out.size(), ad.data(), ad.size());
if (t->HasAttribute("FAILS")) {
if (ret) {
t->PrintLine("Decrypted bad data.");
@@ -118,16 +110,14 @@ static bool TestAEAD(FileTest *t, void *arg) {
return false;
}
out2.resize(out2_len);
- if (!t->ExpectBytesEqual(bssl::vector_data(&in), in.size(),
- bssl::vector_data(&out2), out2.size())) {
+ if (!t->ExpectBytesEqual(in.data(), in.size(), out2.data(), out2.size())) {
return false;
}
// The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
// reset after each operation.
ctx.Reset();
- if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead,
- bssl::vector_data(&key), key.size(),
+ if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead, key.data(), key.size(),
tag.size(), evp_aead_open)) {
t->PrintLine("Failed to init AEAD.");
return false;
@@ -136,10 +126,9 @@ static bool TestAEAD(FileTest *t, void *arg) {
// Garbage at the end isn't ignored.
out.push_back(0);
out2.resize(out.size());
- if (EVP_AEAD_CTX_open(ctx.get(), bssl::vector_data(&out2), &out2_len,
- out2.size(), bssl::vector_data(&nonce), nonce.size(),
- bssl::vector_data(&out), out.size(),
- bssl::vector_data(&ad), ad.size())) {
+ if (EVP_AEAD_CTX_open(ctx.get(), out2.data(), &out2_len, out2.size(),
+ nonce.data(), nonce.size(), out.data(), out.size(),
+ ad.data(), ad.size())) {
t->PrintLine("Decrypted bad data with trailing garbage.");
return false;
}
@@ -148,8 +137,7 @@ static bool TestAEAD(FileTest *t, void *arg) {
// The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
// reset after each operation.
ctx.Reset();
- if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead,
- bssl::vector_data(&key), key.size(),
+ if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead, key.data(), key.size(),
tag.size(), evp_aead_open)) {
t->PrintLine("Failed to init AEAD.");
return false;
@@ -159,10 +147,9 @@ static bool TestAEAD(FileTest *t, void *arg) {
out[0] ^= 0x80;
out.resize(out.size() - 1);
out2.resize(out.size());
- if (EVP_AEAD_CTX_open(ctx.get(), bssl::vector_data(&out2), &out2_len,
- out2.size(), bssl::vector_data(&nonce), nonce.size(),
- bssl::vector_data(&out), out.size(),
- bssl::vector_data(&ad), ad.size())) {
+ if (EVP_AEAD_CTX_open(ctx.get(), out2.data(), &out2_len, out2.size(),
+ nonce.data(), nonce.size(), out.data(), out.size(),
+ ad.data(), ad.size())) {
t->PrintLine("Decrypted bad data with corrupted byte.");
return false;
}
@@ -213,7 +200,7 @@ struct AEADName {
static const struct AEADName kAEADs[] = {
{ "aes-128-gcm", EVP_aead_aes_128_gcm },
{ "aes-256-gcm", EVP_aead_aes_256_gcm },
- { "chacha20-poly1305", EVP_aead_chacha20_poly1305_rfc7539 },
+ { "chacha20-poly1305", EVP_aead_chacha20_poly1305 },
{ "chacha20-poly1305-old", EVP_aead_chacha20_poly1305_old },
{ "rc4-md5-tls", EVP_aead_rc4_md5_tls },
{ "rc4-sha1-tls", EVP_aead_rc4_sha1_tls },
diff --git a/src/crypto/cipher/cipher_test.cc b/src/crypto/cipher/cipher_test.cc
index 5f04178..1cbfae9 100644
--- a/src/crypto/cipher/cipher_test.cc
+++ b/src/crypto/cipher/cipher_test.cc
@@ -63,7 +63,6 @@
#include "../test/file_test.h"
#include "../test/scoped_types.h"
-#include "../test/stl_compat.h"
static const EVP_CIPHER *GetCipher(const std::string &name) {
@@ -146,7 +145,7 @@ static bool TestOperation(FileTest *t,
}
if (is_aead && !encrypt &&
!EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_TAG, tag.size(),
- const_cast<uint8_t*>(bssl::vector_data(&tag)))) {
+ const_cast<uint8_t*>(tag.data()))) {
return false;
}
// The ciphers are run with no padding. For each of the ciphers we test, the
@@ -162,10 +161,10 @@ static bool TestOperation(FileTest *t,
// |EVP_CipherUpdate| calls when empty.
int unused, result_len1 = 0, result_len2;
if (!EVP_CIPHER_CTX_set_key_length(ctx.get(), key.size()) ||
- !EVP_CipherInit_ex(ctx.get(), nullptr, nullptr, bssl::vector_data(&key),
- bssl::vector_data(&iv), -1) ||
+ !EVP_CipherInit_ex(ctx.get(), nullptr, nullptr, key.data(), iv.data(),
+ -1) ||
(!aad.empty() &&
- !EVP_CipherUpdate(ctx.get(), nullptr, &unused, bssl::vector_data(&aad),
+ !EVP_CipherUpdate(ctx.get(), nullptr, &unused, aad.data(),
aad.size())) ||
!EVP_CIPHER_CTX_set_padding(ctx.get(), 0)) {
t->PrintLine("Operation failed.");
@@ -175,28 +174,27 @@ static bool TestOperation(FileTest *t,
for (size_t i = 0; i < in->size(); i++) {
uint8_t c = (*in)[i];
int len;
- if (!EVP_CipherUpdate(ctx.get(), bssl::vector_data(&result) + result_len1,
- &len, &c, 1)) {
+ if (!EVP_CipherUpdate(ctx.get(), result.data() + result_len1, &len, &c,
+ 1)) {
t->PrintLine("Operation failed.");
return false;
}
result_len1 += len;
}
} else if (!in->empty() &&
- !EVP_CipherUpdate(ctx.get(), bssl::vector_data(&result),
- &result_len1, bssl::vector_data(in),
- in->size())) {
+ !EVP_CipherUpdate(ctx.get(), result.data(), &result_len1,
+ in->data(), in->size())) {
t->PrintLine("Operation failed.");
return false;
}
- if (!EVP_CipherFinal_ex(ctx.get(), bssl::vector_data(&result) + result_len1,
+ if (!EVP_CipherFinal_ex(ctx.get(), result.data() + result_len1,
&result_len2)) {
t->PrintLine("Operation failed.");
return false;
}
result.resize(result_len1 + result_len2);
- if (!t->ExpectBytesEqual(bssl::vector_data(out), out->size(),
- bssl::vector_data(&result), result.size())) {
+ if (!t->ExpectBytesEqual(out->data(), out->size(), result.data(),
+ result.size())) {
return false;
}
if (encrypt && is_aead) {
@@ -207,7 +205,7 @@ static bool TestOperation(FileTest *t,
}
if (!EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, tag.size(),
rtag) ||
- !t->ExpectBytesEqual(bssl::vector_data(&tag), tag.size(), rtag,
+ !t->ExpectBytesEqual(tag.data(), tag.size(), rtag,
tag.size())) {
return false;
}
diff --git a/src/crypto/cipher/e_aes.c b/src/crypto/cipher/e_aes.c
index b46fed4..e5104b4 100644
--- a/src/crypto/cipher/e_aes.c
+++ b/src/crypto/cipher/e_aes.c
@@ -1652,7 +1652,7 @@ static int aead_aes_ctr_hmac_sha256_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
if (in_len + aes_ctx->tag_len < in_len ||
/* This input is so large it would overflow the 32-bit block counter. */
- in_len_64 >= (OPENSSL_U64(1) << 32) * AES_BLOCK_SIZE) {
+ in_len_64 >= (UINT64_C(1) << 32) * AES_BLOCK_SIZE) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
diff --git a/src/crypto/cipher/e_chacha20poly1305.c b/src/crypto/cipher/e_chacha20poly1305.c
index c3ba457..f384950 100644
--- a/src/crypto/cipher/e_chacha20poly1305.c
+++ b/src/crypto/cipher/e_chacha20poly1305.c
@@ -108,10 +108,11 @@ static void aead_poly1305(aead_poly1305_update update,
CRYPTO_poly1305_finish(&ctx, tag);
}
-static int seal(aead_poly1305_update poly1305_update, const EVP_AEAD_CTX *ctx,
- uint8_t *out, size_t *out_len, size_t max_out_len,
- const uint8_t nonce[12], const uint8_t *in, size_t in_len,
- const uint8_t *ad, size_t ad_len) {
+static int seal_impl(aead_poly1305_update poly1305_update,
+ const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
+ size_t max_out_len, const uint8_t nonce[12],
+ const uint8_t *in, size_t in_len, const uint8_t *ad,
+ size_t ad_len) {
const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
const uint64_t in_len_64 = in_len;
@@ -146,10 +147,11 @@ static int seal(aead_poly1305_update poly1305_update, const EVP_AEAD_CTX *ctx,
return 1;
}
-static int open(aead_poly1305_update poly1305_update, const EVP_AEAD_CTX *ctx,
- uint8_t *out, size_t *out_len, size_t max_out_len,
- const uint8_t nonce[12], const uint8_t *in, size_t in_len,
- const uint8_t *ad, size_t ad_len) {
+static int open_impl(aead_poly1305_update poly1305_update,
+ const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
+ size_t max_out_len, const uint8_t nonce[12],
+ const uint8_t *in, size_t in_len, const uint8_t *ad,
+ size_t ad_len) {
const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
size_t plaintext_len;
const uint64_t in_len_64 = in_len;
@@ -212,8 +214,8 @@ static int aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
return 0;
}
- return seal(poly1305_update, ctx, out, out_len, max_out_len, nonce, in,
- in_len, ad, ad_len);
+ return seal_impl(poly1305_update, ctx, out, out_len, max_out_len, nonce, in,
+ in_len, ad, ad_len);
}
static int aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
@@ -225,8 +227,8 @@ static int aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
return 0;
}
- return open(poly1305_update, ctx, out, out_len, max_out_len, nonce, in,
- in_len, ad, ad_len);
+ return open_impl(poly1305_update, ctx, out, out_len, max_out_len, nonce, in,
+ in_len, ad, ad_len);
}
static const EVP_AEAD aead_chacha20_poly1305 = {
@@ -243,10 +245,14 @@ static const EVP_AEAD aead_chacha20_poly1305 = {
NULL, /* get_iv */
};
-const EVP_AEAD *EVP_aead_chacha20_poly1305_rfc7539(void) {
+const EVP_AEAD *EVP_aead_chacha20_poly1305(void) {
return &aead_chacha20_poly1305;
}
+const EVP_AEAD *EVP_aead_chacha20_poly1305_rfc7539(void) {
+ return EVP_aead_chacha20_poly1305();
+}
+
static void poly1305_update_old(poly1305_state *ctx, const uint8_t *ad,
size_t ad_len, const uint8_t *ciphertext,
size_t ciphertext_len) {
@@ -267,8 +273,8 @@ static int aead_chacha20_poly1305_old_seal(
uint8_t nonce_96[12];
memset(nonce_96, 0, 4);
memcpy(nonce_96 + 4, nonce, 8);
- return seal(poly1305_update_old, ctx, out, out_len, max_out_len, nonce_96, in,
- in_len, ad, ad_len);
+ return seal_impl(poly1305_update_old, ctx, out, out_len, max_out_len,
+ nonce_96, in, in_len, ad, ad_len);
}
static int aead_chacha20_poly1305_old_open(
@@ -282,8 +288,8 @@ static int aead_chacha20_poly1305_old_open(
uint8_t nonce_96[12];
memset(nonce_96, 0, 4);
memcpy(nonce_96 + 4, nonce, 8);
- return open(poly1305_update_old, ctx, out, out_len, max_out_len, nonce_96, in,
- in_len, ad, ad_len);
+ return open_impl(poly1305_update_old, ctx, out, out_len, max_out_len,
+ nonce_96, in, in_len, ad, ad_len);
}
static const EVP_AEAD aead_chacha20_poly1305_old = {
@@ -303,7 +309,3 @@ static const EVP_AEAD aead_chacha20_poly1305_old = {
const EVP_AEAD *EVP_aead_chacha20_poly1305_old(void) {
return &aead_chacha20_poly1305_old;
}
-
-const EVP_AEAD *EVP_aead_chacha20_poly1305(void) {
- return &aead_chacha20_poly1305_old;
-}
diff --git a/src/crypto/cipher/e_rc4.c b/src/crypto/cipher/e_rc4.c
index 86d9395..3a2c166 100644
--- a/src/crypto/cipher/e_rc4.c
+++ b/src/crypto/cipher/e_rc4.c
@@ -54,21 +54,13 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
-#include <openssl/aead.h>
-
#include <assert.h>
#include <string.h>
#include <openssl/cipher.h>
-#include <openssl/cpu.h>
-#include <openssl/err.h>
-#include <openssl/md5.h>
-#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/rc4.h>
-#include "internal.h"
-
static int rc4_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
const uint8_t *iv, int enc) {
@@ -93,306 +85,3 @@ static const EVP_CIPHER rc4 = {
NULL /* cleanup */, NULL /* ctrl */, };
const EVP_CIPHER *EVP_rc4(void) { return &rc4; }
-
-
-struct aead_rc4_md5_tls_ctx {
- RC4_KEY rc4;
- MD5_CTX head, tail, md;
- size_t payload_length;
- unsigned char tag_len;
-};
-
-
-static int
-aead_rc4_md5_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len,
- size_t tag_len) {
- struct aead_rc4_md5_tls_ctx *rc4_ctx;
- size_t i;
- uint8_t hmac_key[MD5_CBLOCK];
-
- if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) {
- tag_len = MD5_DIGEST_LENGTH;
- }
-
- if (tag_len > MD5_DIGEST_LENGTH) {
- OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
- return 0;
- }
-
- /* The keys consists of |MD5_DIGEST_LENGTH| bytes of HMAC(MD5) key followed
- * by some number of bytes of RC4 key. */
- if (key_len <= MD5_DIGEST_LENGTH) {
- OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
- return 0;
- }
-
- rc4_ctx = OPENSSL_malloc(sizeof(struct aead_rc4_md5_tls_ctx));
- if (rc4_ctx == NULL) {
- OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- memset(rc4_ctx, 0, sizeof(struct aead_rc4_md5_tls_ctx));
-
- RC4_set_key(&rc4_ctx->rc4, key_len - MD5_DIGEST_LENGTH,
- key + MD5_DIGEST_LENGTH);
-
- memset(hmac_key, 0, sizeof(hmac_key));
- memcpy(hmac_key, key, MD5_DIGEST_LENGTH);
- for (i = 0; i < sizeof(hmac_key); i++) {
- hmac_key[i] ^= 0x36;
- }
- MD5_Init(&rc4_ctx->head);
- MD5_Update(&rc4_ctx->head, hmac_key, sizeof(hmac_key));
- for (i = 0; i < sizeof(hmac_key); i++) {
- hmac_key[i] ^= 0x36 ^ 0x5c;
- }
- MD5_Init(&rc4_ctx->tail);
- MD5_Update(&rc4_ctx->tail, hmac_key, sizeof(hmac_key));
-
- rc4_ctx->tag_len = tag_len;
- ctx->aead_state = rc4_ctx;
-
- return 1;
-}
-
-static void aead_rc4_md5_tls_cleanup(EVP_AEAD_CTX *ctx) {
- struct aead_rc4_md5_tls_ctx *rc4_ctx = ctx->aead_state;
- OPENSSL_cleanse(rc4_ctx, sizeof(struct aead_rc4_md5_tls_ctx));
- OPENSSL_free(rc4_ctx);
-}
-
-#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64)
-#define STITCHED_CALL
-
-/* rc4_md5_enc is defined in rc4_md5-x86_64.pl */
-void rc4_md5_enc(RC4_KEY *key, const void *in0, void *out, MD5_CTX *ctx,
- const void *inp, size_t blocks);
-#endif
-
-static int aead_rc4_md5_tls_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
- size_t *out_len, size_t max_out_len,
- const uint8_t *nonce, size_t nonce_len,
- const uint8_t *in, size_t in_len,
- const uint8_t *ad, size_t ad_len) {
- struct aead_rc4_md5_tls_ctx *rc4_ctx = ctx->aead_state;
- MD5_CTX md;
-#if defined(STITCHED_CALL)
- size_t rc4_off, md5_off, blocks;
-#else
- const size_t rc4_off = 0;
- const size_t md5_off = 0;
-#endif
- uint8_t digest[MD5_DIGEST_LENGTH];
-
- if (in_len + rc4_ctx->tag_len < in_len) {
- OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
- return 0;
- }
-
- if (nonce_len != 0) {
- OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_IV_TOO_LARGE);
- return 0;
- }
-
- if (max_out_len < in_len + rc4_ctx->tag_len) {
- OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
- return 0;
- }
-
- if (nonce_len != 0) {
- OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
- return 0;
- }
-
- memcpy(&md, &rc4_ctx->head, sizeof(MD5_CTX));
- /* The MAC's payload begins with the additional data. See
- * https://tools.ietf.org/html/rfc5246#section-6.2.3.1 */
- MD5_Update(&md, ad, ad_len);
-
- /* To allow for CBC mode which changes cipher length, |ad| doesn't include the
- * length for legacy ciphers. */
- uint8_t ad_extra[2];
- ad_extra[0] = (uint8_t)(in_len >> 8);
- ad_extra[1] = (uint8_t)(in_len & 0xff);
- MD5_Update(&md, ad_extra, sizeof(ad_extra));
-
-#if defined(STITCHED_CALL)
- /* 32 is $MOD from rc4_md5-x86_64.pl. */
- rc4_off = 32 - 1 - (rc4_ctx->rc4.x & (32 - 1));
- md5_off = MD5_CBLOCK - md.num;
- /* Ensure RC4 is behind MD5. */
- if (rc4_off > md5_off) {
- md5_off += MD5_CBLOCK;
- }
- assert(md5_off >= rc4_off);
-
- if (in_len > md5_off && (blocks = (in_len - md5_off) / MD5_CBLOCK) &&
- (OPENSSL_ia32cap_P[0] & (1 << 20)) == 0) {
- /* Process the initial portions of the plaintext normally. */
- MD5_Update(&md, in, md5_off);
- RC4(&rc4_ctx->rc4, rc4_off, in, out);
-
- /* Process the next |blocks| blocks of plaintext with stitched routines. */
- rc4_md5_enc(&rc4_ctx->rc4, in + rc4_off, out + rc4_off, &md, in + md5_off,
- blocks);
- blocks *= MD5_CBLOCK;
- rc4_off += blocks;
- md5_off += blocks;
- md.Nh += blocks >> 29;
- md.Nl += blocks <<= 3;
- if (md.Nl < (unsigned int)blocks) {
- md.Nh++;
- }
- } else {
- rc4_off = 0;
- md5_off = 0;
- }
-#endif
- /* Finish computing the MAC. */
- MD5_Update(&md, in + md5_off, in_len - md5_off);
- MD5_Final(digest, &md);
-
- memcpy(&md, &rc4_ctx->tail, sizeof(MD5_CTX));
- MD5_Update(&md, digest, sizeof(digest));
- if (rc4_ctx->tag_len == MD5_DIGEST_LENGTH) {
- MD5_Final(out + in_len, &md);
- } else {
- MD5_Final(digest, &md);
- memcpy(out + in_len, digest, rc4_ctx->tag_len);
- }
-
- /* Encrypt the remainder of the plaintext and the MAC. */
- RC4(&rc4_ctx->rc4, in_len - rc4_off, in + rc4_off, out + rc4_off);
- RC4(&rc4_ctx->rc4, MD5_DIGEST_LENGTH, out + in_len, out + in_len);
-
- *out_len = in_len + rc4_ctx->tag_len;
- return 1;
-}
-
-static int aead_rc4_md5_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
- size_t *out_len, size_t max_out_len,
- const uint8_t *nonce, size_t nonce_len,
- const uint8_t *in, size_t in_len,
- const uint8_t *ad, size_t ad_len) {
- struct aead_rc4_md5_tls_ctx *rc4_ctx = ctx->aead_state;
- MD5_CTX md;
- size_t plaintext_len;
-#if defined(STITCHED_CALL)
- unsigned int l;
- size_t rc4_off, md5_off, blocks;
- extern unsigned int OPENSSL_ia32cap_P[];
-#else
- const size_t rc4_off = 0;
- const size_t md5_off = 0;
-#endif
- uint8_t digest[MD5_DIGEST_LENGTH];
-
- if (in_len < rc4_ctx->tag_len) {
- OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
- return 0;
- }
-
- plaintext_len = in_len - rc4_ctx->tag_len;
-
- if (nonce_len != 0) {
- OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
- return 0;
- }
-
- if (max_out_len < in_len) {
- /* This requires that the caller provide space for the MAC, even though it
- * will always be removed on return. */
- OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
- return 0;
- }
-
- memcpy(&md, &rc4_ctx->head, sizeof(MD5_CTX));
- /* The MAC's payload begins with the additional data. See
- * https://tools.ietf.org/html/rfc5246#section-6.2.3.1 */
- MD5_Update(&md, ad, ad_len);
-
- /* To allow for CBC mode which changes cipher length, |ad| doesn't include the
- * length for legacy ciphers. */
- uint8_t ad_extra[2];
- ad_extra[0] = (uint8_t)(plaintext_len >> 8);
- ad_extra[1] = (uint8_t)(plaintext_len & 0xff);
- MD5_Update(&md, ad_extra, sizeof(ad_extra));
-
-#if defined(STITCHED_CALL)
- rc4_off = 32 - 1 - (rc4_ctx->rc4.x & (32 - 1));
- md5_off = MD5_CBLOCK - md.num;
- /* Ensure MD5 is a full block behind RC4 so it has plaintext to operate on in
- * both normal and stitched routines. */
- if (md5_off > rc4_off) {
- rc4_off += 2 * MD5_CBLOCK;
- } else {
- rc4_off += MD5_CBLOCK;
- }
-
- if (in_len > rc4_off && (blocks = (in_len - rc4_off) / MD5_CBLOCK) &&
- (OPENSSL_ia32cap_P[0] & (1 << 20)) == 0) {
- /* Decrypt the initial portion of the ciphertext and digest the plaintext
- * normally. */
- RC4(&rc4_ctx->rc4, rc4_off, in, out);
- MD5_Update(&md, out, md5_off);
-
- /* Decrypt and digest the next |blocks| blocks of ciphertext with the
- * stitched routines. */
- rc4_md5_enc(&rc4_ctx->rc4, in + rc4_off, out + rc4_off, &md, out + md5_off,
- blocks);
- blocks *= MD5_CBLOCK;
- rc4_off += blocks;
- md5_off += blocks;
- l = (md.Nl + (blocks << 3)) & 0xffffffffU;
- if (l < md.Nl) {
- md.Nh++;
- }
- md.Nl = l;
- md.Nh += blocks >> 29;
- } else {
- md5_off = 0;
- rc4_off = 0;
- }
-#endif
-
- /* Process the remainder of the input. */
- RC4(&rc4_ctx->rc4, in_len - rc4_off, in + rc4_off, out + rc4_off);
- MD5_Update(&md, out + md5_off, plaintext_len - md5_off);
- MD5_Final(digest, &md);
-
- /* Calculate HMAC and verify it */
- memcpy(&md, &rc4_ctx->tail, sizeof(MD5_CTX));
- MD5_Update(&md, digest, MD5_DIGEST_LENGTH);
- MD5_Final(digest, &md);
-
- if (CRYPTO_memcmp(out + plaintext_len, digest, rc4_ctx->tag_len)) {
- OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
- return 0;
- }
-
- *out_len = plaintext_len;
- return 1;
-}
-
-static int aead_rc4_md5_tls_get_rc4_state(const EVP_AEAD_CTX *ctx,
- const RC4_KEY **out_key) {
- struct aead_rc4_md5_tls_ctx *rc4_ctx = ctx->aead_state;
- *out_key = &rc4_ctx->rc4;
- return 1;
-}
-
-static const EVP_AEAD aead_rc4_md5_tls = {
- 16 + MD5_DIGEST_LENGTH, /* key len (RC4 + MD5) */
- 0, /* nonce len */
- MD5_DIGEST_LENGTH, /* overhead */
- MD5_DIGEST_LENGTH, /* max tag length */
- aead_rc4_md5_tls_init,
- NULL, /* init_with_direction */
- aead_rc4_md5_tls_cleanup,
- aead_rc4_md5_tls_seal,
- aead_rc4_md5_tls_open,
- aead_rc4_md5_tls_get_rc4_state,
- NULL, /* get_iv */
-};
-
-const EVP_AEAD *EVP_aead_rc4_md5_tls(void) { return &aead_rc4_md5_tls; }
diff --git a/src/crypto/cipher/e_tls.c b/src/crypto/cipher/e_tls.c
index d781da1..b87b0d6 100644
--- a/src/crypto/cipher/e_tls.c
+++ b/src/crypto/cipher/e_tls.c
@@ -20,6 +20,7 @@
#include <openssl/cipher.h>
#include <openssl/err.h>
#include <openssl/hmac.h>
+#include <openssl/md5.h>
#include <openssl/mem.h>
#include <openssl/sha.h>
#include <openssl/type_check.h>
@@ -111,7 +112,6 @@ static int aead_tls_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
/* Unlike a normal AEAD, a TLS AEAD may only be used in one direction. */
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION);
return 0;
-
}
if (in_len + EVP_AEAD_max_overhead(ctx->aead) < in_len ||
@@ -146,17 +146,13 @@ static int aead_tls_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
* in-place. */
uint8_t mac[EVP_MAX_MD_SIZE];
unsigned mac_len;
- HMAC_CTX hmac_ctx;
- HMAC_CTX_init(&hmac_ctx);
- if (!HMAC_CTX_copy_ex(&hmac_ctx, &tls_ctx->hmac_ctx) ||
- !HMAC_Update(&hmac_ctx, ad, ad_len) ||
- !HMAC_Update(&hmac_ctx, ad_extra, sizeof(ad_extra)) ||
- !HMAC_Update(&hmac_ctx, in, in_len) ||
- !HMAC_Final(&hmac_ctx, mac, &mac_len)) {
- HMAC_CTX_cleanup(&hmac_ctx);
+ if (!HMAC_Init_ex(&tls_ctx->hmac_ctx, NULL, 0, NULL, NULL) ||
+ !HMAC_Update(&tls_ctx->hmac_ctx, ad, ad_len) ||
+ !HMAC_Update(&tls_ctx->hmac_ctx, ad_extra, sizeof(ad_extra)) ||
+ !HMAC_Update(&tls_ctx->hmac_ctx, in, in_len) ||
+ !HMAC_Final(&tls_ctx->hmac_ctx, mac, &mac_len)) {
return 0;
}
- HMAC_CTX_cleanup(&hmac_ctx);
/* Configure the explicit IV. */
if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE &&
@@ -216,7 +212,6 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
/* Unlike a normal AEAD, a TLS AEAD may only be used in one direction. */
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION);
return 0;
-
}
if (in_len < HMAC_size(&tls_ctx->hmac_ctx)) {
@@ -324,18 +319,14 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
* implemented. */
assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) != EVP_CIPH_CBC_MODE);
- HMAC_CTX hmac_ctx;
- HMAC_CTX_init(&hmac_ctx);
unsigned mac_len_u;
- if (!HMAC_CTX_copy_ex(&hmac_ctx, &tls_ctx->hmac_ctx) ||
- !HMAC_Update(&hmac_ctx, ad_fixed, ad_len) ||
- !HMAC_Update(&hmac_ctx, out, data_len) ||
- !HMAC_Final(&hmac_ctx, mac, &mac_len_u)) {
- HMAC_CTX_cleanup(&hmac_ctx);
+ if (!HMAC_Init_ex(&tls_ctx->hmac_ctx, NULL, 0, NULL, NULL) ||
+ !HMAC_Update(&tls_ctx->hmac_ctx, ad_fixed, ad_len) ||
+ !HMAC_Update(&tls_ctx->hmac_ctx, out, data_len) ||
+ !HMAC_Final(&tls_ctx->hmac_ctx, mac, &mac_len_u)) {
return 0;
}
mac_len = mac_len_u;
- HMAC_CTX_cleanup(&hmac_ctx);
assert(mac_len == HMAC_size(&tls_ctx->hmac_ctx));
record_mac = &out[data_len];
@@ -359,6 +350,13 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
return 1;
}
+static int aead_rc4_md5_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
+ size_t key_len, size_t tag_len,
+ enum evp_aead_direction_t dir) {
+ return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_rc4(), EVP_md5(),
+ 0);
+}
+
static int aead_rc4_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
size_t key_len, size_t tag_len,
enum evp_aead_direction_t dir) {
@@ -433,8 +431,8 @@ static int aead_des_ede3_cbc_sha1_tls_implicit_iv_init(
EVP_sha1(), 1);
}
-static int aead_rc4_sha1_tls_get_rc4_state(const EVP_AEAD_CTX *ctx,
- const RC4_KEY **out_key) {
+static int aead_rc4_tls_get_rc4_state(const EVP_AEAD_CTX *ctx,
+ const RC4_KEY **out_key) {
const AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX*) ctx->aead_state;
if (EVP_CIPHER_CTX_cipher(&tls_ctx->cipher_ctx) != EVP_rc4()) {
return 0;
@@ -464,18 +462,32 @@ static int aead_null_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
EVP_sha1(), 1 /* implicit iv */);
}
+static const EVP_AEAD aead_rc4_md5_tls = {
+ MD5_DIGEST_LENGTH + 16, /* key len (MD5 + RC4) */
+ 0, /* nonce len */
+ MD5_DIGEST_LENGTH, /* overhead */
+ MD5_DIGEST_LENGTH, /* max tag length */
+ NULL, /* init */
+ aead_rc4_md5_tls_init,
+ aead_tls_cleanup,
+ aead_tls_seal,
+ aead_tls_open,
+ aead_rc4_tls_get_rc4_state, /* get_rc4_state */
+ NULL, /* get_iv */
+};
+
static const EVP_AEAD aead_rc4_sha1_tls = {
SHA_DIGEST_LENGTH + 16, /* key len (SHA1 + RC4) */
0, /* nonce len */
SHA_DIGEST_LENGTH, /* overhead */
SHA_DIGEST_LENGTH, /* max tag length */
- NULL, /* init */
+ NULL, /* init */
aead_rc4_sha1_tls_init,
aead_tls_cleanup,
aead_tls_seal,
aead_tls_open,
- aead_rc4_sha1_tls_get_rc4_state, /* get_rc4_state */
- NULL, /* get_iv */
+ aead_rc4_tls_get_rc4_state, /* get_rc4_state */
+ NULL, /* get_iv */
};
static const EVP_AEAD aead_aes_128_cbc_sha1_tls = {
@@ -618,6 +630,8 @@ static const EVP_AEAD aead_null_sha1_tls = {
NULL, /* get_iv */
};
+const EVP_AEAD *EVP_aead_rc4_md5_tls(void) { return &aead_rc4_md5_tls; }
+
const EVP_AEAD *EVP_aead_rc4_sha1_tls(void) { return &aead_rc4_sha1_tls; }
const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls(void) {
diff --git a/src/crypto/cipher/test/chacha20_poly1305_old_tests.txt b/src/crypto/cipher/test/chacha20_poly1305_old_tests.txt
index 55c506d..d40b21c 100644
--- a/src/crypto/cipher/test/chacha20_poly1305_old_tests.txt
+++ b/src/crypto/cipher/test/chacha20_poly1305_old_tests.txt
@@ -418,5 +418,107 @@ AD: fd6a3fdd879f8880843eac20ae01c1b9dc3487d270a806572088ef2ddc1f1e0de495e71d4813
CT: bd11ed07b7b4b30eeaf25d6a41a549cca0a5aee71f990ac566a37265d7af2ce3c03703427ee0b2755c2bdfc29f9d826aec6ee4ad28af48079ac23db16580b97424f3a4e35cc23625d39f95699d9ff5143e9a2bc26fcfee4f125f5aa2d968ccfc2faaf9db3c28850f6757f735cbc50c94c498bcde4f23bffafa8dd5f70d1a011e35eb26e905d4e68848fedebeb197be595c085ba33f11ba8398258445051751888e9bba111f800f31b37c447074ca6dce6d54b4dfad6cee5138643d4f6ac045e8047248924e88ea4294c7878bc22c9b41924ce301f22693c33733107bf1ba85e34806c5e4366ea66fc52a5f89dd9bf213239158b3d4d2600dde696c61d76c398b9bf10de9118e812e891c8f3355c0ecc6405f79bc32a58905e37888a1d8395fbedc3ac54eca569f
TAG: f7d3b58a34a86e99267e5db206f17bbe
-# BoringSSL has additional tests here for truncated tags. *ring* doesn't
-# support tag truncation, so those tests were removed.
+KEY: 3304e4917ad7777b86c26a636292c9cc4c10d32003c49e07209eb0ef8505031a
+NONCE: 4d572d116fbd8c4d
+IN: 2f242c2ba33790ecef862b0e077ff8b15eb9d10cf2ff621ed65902494431dcbd
+AD: e699bbf250cdd93d229d0740e433897e2d19132e2b722df8b69bb6a7c2cf3b93
+CT: fb81e30436e437c7f686f86b1b65c73549a9d09db810d320785c3634934150b3
+TAG: 8b
+
+KEY: ed6057bb163f1609ff28b938122f495e3d5ae4ec3dbd7456c9b5c82e28e952dc
+NONCE: e6ff6852f3a3afde
+IN: 3c50edc967eb0b3b2355f6400e0a036e796c8b7d72c5e583a86e820d53e76c43
+AD: 2441db55148e14e9e241d68296eb60d529408f0534143089671bce546db96d88
+CT: 6ecabccee31519374d4bed11296e7483d1cb759bea3f4446a96bda8b4ca6d7ac
+TAG: 355f
+
+KEY: 73568183c1f9725af30e0f2067606ce802c3fe3ab5cff8d02b3db8c35176ee0d
+NONCE: 0bc9e19321b3d00a
+IN: ec2590af5ccd226a32ff750c1b029c11e3dd76c469a5579da9418e4c3fdc0d41
+AD: df30160ae0cbf2cf8992221bd62dffe691dd602afa784ca691479e957af3acf1
+CT: 9e8d8ac30626f8b831448d6976933aa5bb8c6dbc794e1f4b7eeb0e4a59342c07
+TAG: 9fd36a
+
+KEY: 273bcb3f8c067da4ec3418799ad40e7e4aee74ad7e629499d646df4a7e585025
+NONCE: f60be3eb894b4030
+IN: 697498ba964d5ef401da4d94844fab1efc635e7157d0831a325bb5a4cf1fbd34
+AD: 9129715deab14f02c76ba8172571b1fa9d50365cd795bfccdfc28e7e7b4f66fc
+CT: bd4cd5af83be1c13933302675d9fcaf1c4cacdf269f6ff441d1ea2211c54e7ed
+TAG: 7ab12a37
+
+KEY: ad39610c2e6a6d0961207390e076e972c2edadca885c92965fa648b2ce34fdbf
+NONCE: a90db690bba83b78
+IN: 31c49e3cd3d80a82e6b90316dfb94b38b8a23042519bf40c8181fec873c99002
+AD: ddbd7d821d18d44c66295abf245b227b5cf4366811b7b34c07679600abdbfc29
+CT: 94628fc303a0546edd51e966f2bd87968f37800c607d5e5a91f727fc1fec406f
+TAG: c22ec4e4c8
+
+KEY: 29984954060ba06ece1bcfc0e50195f4632c6df48da1e02ae6c14f7065668971
+NONCE: cce53a25aeeaf747
+IN: b9b87433a9894f3c9ca8212623d62369a565a2edcddd276e07d611eda3597426
+AD: 19fa9aa59697559d8b46d9cd49c3b763c0b73b26b9e334a3eeac2c86fdbaca8d
+CT: b68c83397770c36f073710882fa86d43b0e54e8efef0ff75075604d0d7ec4e1b
+TAG: 40d4ab752f3d
+
+KEY: 5c3b838b84100b2a818c0842e9fe19a7c50cf5f3ea73364c816ef588e500ff3f
+NONCE: fdf6b0229e4bcc2a
+IN: 2ba91904c143be99297b39f52856904af41705c176c8c6554b6bc89bddffbcc1
+AD: 3539d9dd821f004f4ced1637071f4be6abd7fe98f017f0a8ce3f49dc8d496f46
+CT: ff9d6d924e737a1df8c2bd3047e40ab401f903aa0e5b51acb991bac38ac2cc4d
+TAG: 1bcaa415a6a3c7
+
+KEY: 6d65e627cab6d5eb1a088b25bd6c3a8a004a7a19cccae909d62fed3559c812f7
+NONCE: 7ff00a8798b792de
+IN: 6848ee4ac820291a2e1dc3baad97f1ad8b7160dfeaa1bc83b2700ae42b5a366b
+AD: d2437b1306bf0ea211449fac863ca0d1074d84caee9009c5d54b9e9bdc8de6b1
+CT: 2da0abe2a71e1c0b1ab309c160a8cebe45c6e16170aa5561806484ba2b5b9a9a
+TAG: 566003e1f78d2a90
+
+KEY: 63401046a96efbc8c6483a2c396b2a593d3fae0db565525b85999fae13a46b6a
+NONCE: 051393d775e635ee
+IN: 2b4b6477580382aae782f8b5772c0948a444d8d95caacd85c0856c7e4393fe09
+AD: 3d84d2e70e9c062d1f511eb685a9a90c8d5fa50eadf8455c7148666b3e7155e0
+CT: 880c1123e54fd8ffb3c293720dd174913572e619ef46504cdaa64fc451b0ec1c
+TAG: 339274339c88d50ac0
+
+KEY: 291fccfce0782f1787d62d4b9293d2ada4c04d37a8288ba9ba9aae0d31aad204
+NONCE: 7450bbd62e4aba7b
+IN: adc251e793181e5d4c4bd983b853eb13f2096ccb340996b6eca4cd2157efcec7
+AD: 4c598f6deedc8c1d97da33654763495cca3517430eec4edb006b10c95e031ae6
+CT: 28bda22e4922cd8ff6739cd8a6bdafce036d9c61a145a65ca1b86f6d4d3206a1
+TAG: d98fd43fe7ac74d4b016
+
+KEY: fa3a9674d4a0eb36b2f7547c956443d09e6b4e4acfc9deda838eb7ebdb999a8d
+NONCE: 0a2572592c3bbbf6
+IN: ae27f70fda9f5a5be0f704a27f0b8a9c04ce83d3c2e0d7ec152da25f473b0c8a
+AD: 6ee8705a9a3655d198497ad410da02005872ecbe397824851b80f4050bfdd311
+CT: f356cbd88e4e2aff62d91e3f914032085388955bbba995fde013758b8702e38f
+TAG: 00324c76fecd3f50e1e3b8
+
+KEY: 471ec87b992b104d369748d96856b5f66149cb45ca05c17f29d24eb9526fe6db
+NONCE: 23a2df9ed0b47439
+IN: 2b9452bca0f48e5519ec3d0736597608df6ad9ce799eba913cff71573d79c092
+AD: a56722ddfaee5f1b64398c225ee8bcdcfde5c2127101c363bfac52bc409c1082
+CT: 7bbc464aac5dd29c25262fe0b116c176d827c2cc8dd63428393b0a9110f3c194
+TAG: 2e87f4a6663a62e47c7e197f
+
+KEY: a29d1cfd4ccdc18803fbca9500f4bb29ce99cfcbf8acc41b8208dae4b7ee5d64
+NONCE: 634f99e88e237ef0
+IN: 09ee5982c5743f396d0c29c13e3fbb8fb89f61705da05466291e010effd51a5c
+AD: 564dddfcc3227b413244f1105b610f192decf15c4cfa067f4d7fcd6bd7af11b8
+CT: 32916b67a6f32733623344c98c49773f3e721dc2ded105fb245799525bc9c84c
+TAG: ff463c07e7ef831321d3fd775f
+
+KEY: 08ba23616d911188f91da063278bef1237dcbf17f52585e53c2c4b6cf3ac9f0d
+NONCE: 989ae593eddd3874
+IN: 749152c9478944c8271c0c11e07bc1c569eec01493e65b3b94842a1bf5d721f8
+AD: a12d1a45b7c9b91ab08751a70b753714052ad24e0b2619fe8c3be303c65f2dbc
+CT: 34c40538ee1d22ddf8ac290dd7d423dfc622b5cf8f3412a5343e277822aea713
+TAG: 014c7c678e0949e88071d1fe3531
+
+KEY: c2ba8bed8634156afc6bfe3754c91744d4131de39d059f3a866399f916553b5c
+NONCE: 80fbf7b433a4cd9c
+IN: 419be6623e7964f9f26068dd969e4a139617e67c5ffb269b3013c433fe771c77
+AD: 3937592db78a61ff469691b6800792019bc2b3d42512f23c1b1a66a8274495cb
+CT: 9d5bd1c7e766763eb00684c038043111d8c6390a8d6e17a15ef97c02ab16f09c
+TAG: a64d0eeb4a01481ec0cee8c1c357e3
diff --git a/src/crypto/cipher/test/chacha20_poly1305_tests.txt b/src/crypto/cipher/test/chacha20_poly1305_tests.txt
index a71ac14..103c196 100644
--- a/src/crypto/cipher/test/chacha20_poly1305_tests.txt
+++ b/src/crypto/cipher/test/chacha20_poly1305_tests.txt
@@ -47,8 +47,8 @@ AD: "123456789abcdef0"
CT: e275aeb341e1fc9a70c4fd4496fc7cdb
TAG: 41acd0560ea6843d3e5d4e5babf6e946
-# Test vectors from chacha20_poly1305_deprecated_tests.txt, modified for the
-# RFC 7539 AEAD construction.
+# Test vectors from chacha20_poly1305_old_tests.txt, modified for the RFC 7539
+# AEAD construction.
KEY: 9a97f65b9b4c721b960a672145fca8d4e32e67f9111ea979ce9c4826806aeee6
NONCE: 000000003de9c0da2bd7f91e
@@ -470,5 +470,109 @@ AD: fd6a3fdd879f8880843eac20ae01c1b9dc3487d270a806572088ef2ddc1f1e0de495e71d4813
CT: bd11ed07b7b4b30eeaf25d6a41a549cca0a5aee71f990ac566a37265d7af2ce3c03703427ee0b2755c2bdfc29f9d826aec6ee4ad28af48079ac23db16580b97424f3a4e35cc23625d39f95699d9ff5143e9a2bc26fcfee4f125f5aa2d968ccfc2faaf9db3c28850f6757f735cbc50c94c498bcde4f23bffafa8dd5f70d1a011e35eb26e905d4e68848fedebeb197be595c085ba33f11ba8398258445051751888e9bba111f800f31b37c447074ca6dce6d54b4dfad6cee5138643d4f6ac045e8047248924e88ea4294c7878bc22c9b41924ce301f22693c33733107bf1ba85e34806c5e4366ea66fc52a5f89dd9bf213239158b3d4d2600dde696c61d76c398b9bf10de9118e812e891c8f3355c0ecc6405f79bc32a58905e37888a1d8395fbedc3ac54eca569f
TAG: 296a397d280d026fc3627f4718971be9
-# BoringSSL has additional tests here for truncated tags. *ring* doesn't
-# support tag truncation, so those tests were removed.
+# Tag truncation tests.
+
+KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
+NONCE: 000000005d9856060c54ab06
+IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
+AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
+CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
+TAG: d3
+
+KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
+NONCE: 000000005d9856060c54ab06
+IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
+AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
+CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
+TAG: d3f7
+
+KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
+NONCE: 000000005d9856060c54ab06
+IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
+AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
+CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
+TAG: d3f7b9
+
+KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
+NONCE: 000000005d9856060c54ab06
+IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
+AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
+CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
+TAG: d3f7b9c2
+
+KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
+NONCE: 000000005d9856060c54ab06
+IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
+AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
+CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
+TAG: d3f7b9c295
+
+KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
+NONCE: 000000005d9856060c54ab06
+IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
+AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
+CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
+TAG: d3f7b9c295f3
+
+KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
+NONCE: 000000005d9856060c54ab06
+IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
+AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
+CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
+TAG: d3f7b9c295f374
+
+KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
+NONCE: 000000005d9856060c54ab06
+IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
+AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
+CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
+TAG: d3f7b9c295f37465
+
+KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
+NONCE: 000000005d9856060c54ab06
+IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
+AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
+CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
+TAG: d3f7b9c295f374651a
+
+KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
+NONCE: 000000005d9856060c54ab06
+IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
+AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
+CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
+TAG: d3f7b9c295f374651a84
+
+KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
+NONCE: 000000005d9856060c54ab06
+IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
+AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
+CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
+TAG: d3f7b9c295f374651a8413
+
+KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
+NONCE: 000000005d9856060c54ab06
+IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
+AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
+CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
+TAG: d3f7b9c295f374651a841386
+
+KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
+NONCE: 000000005d9856060c54ab06
+IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
+AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
+CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
+TAG: d3f7b9c295f374651a84138648
+
+KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
+NONCE: 000000005d9856060c54ab06
+IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
+AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
+CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
+TAG: d3f7b9c295f374651a84138648a5
+
+KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
+NONCE: 000000005d9856060c54ab06
+IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
+AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
+CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
+TAG: d3f7b9c295f374651a84138648a591
diff --git a/src/crypto/cpu-arm.c b/src/crypto/cpu-arm.c
index 14ad2ee..675d174 100644
--- a/src/crypto/cpu-arm.c
+++ b/src/crypto/cpu-arm.c
@@ -34,7 +34,7 @@ unsigned long getauxval(unsigned long type) __attribute__((weak));
extern uint32_t OPENSSL_armcap_P;
-char CRYPTO_is_NEON_capable(void) {
+char CRYPTO_is_NEON_capable_at_runtime(void) {
return (OPENSSL_armcap_P & ARMV7_NEON) != 0;
}
diff --git a/src/crypto/crypto.c b/src/crypto/crypto.c
index d70c8c7..ace1c82 100644
--- a/src/crypto/crypto.c
+++ b/src/crypto/crypto.c
@@ -14,6 +14,8 @@
#include <openssl/crypto.h>
+#include <openssl/cpu.h>
+
#include "internal.h"
@@ -86,22 +88,22 @@ uint32_t OPENSSL_armcap_P = ARMV7_NEON_FUNCTIONAL;
#endif
-#if defined(OPENSSL_WINDOWS)
+#if defined(OPENSSL_WINDOWS) && !defined(BORINGSSL_NO_STATIC_INITIALIZER)
#define OPENSSL_CDECL __cdecl
#else
#define OPENSSL_CDECL
#endif
-#if !defined(BORINGSSL_NO_STATIC_INITIALIZER)
-#if !defined(OPENSSL_WINDOWS)
-static void do_library_init(void) __attribute__ ((constructor));
-#else
+#if defined(BORINGSSL_NO_STATIC_INITIALIZER)
+static CRYPTO_once_t once = CRYPTO_ONCE_INIT;
+#elif defined(OPENSSL_WINDOWS)
#pragma section(".CRT$XCU", read)
static void __cdecl do_library_init(void);
__declspec(allocate(".CRT$XCU")) void(*library_init_constructor)(void) =
do_library_init;
+#else
+static void do_library_init(void) __attribute__ ((constructor));
#endif
-#endif /* !BORINGSSL_NO_STATIC_INITIALIZER */
/* do_library_init is the actual initialization function. If
* BORINGSSL_NO_STATIC_INITIALIZER isn't defined, this is set as a static
@@ -117,9 +119,9 @@ static void OPENSSL_CDECL do_library_init(void) {
void CRYPTO_library_init(void) {
/* TODO(davidben): It would be tidier if this build knob could be replaced
* with an internal lazy-init mechanism that would handle things correctly
- * in-library. */
+ * in-library. https://crbug.com/542879 */
#if defined(BORINGSSL_NO_STATIC_INITIALIZER)
- do_library_init();
+ CRYPTO_once(&once, do_library_init);
#endif
}
diff --git a/src/crypto/curve25519/CMakeLists.txt b/src/crypto/curve25519/CMakeLists.txt
new file mode 100644
index 0000000..a2ef3bb
--- /dev/null
+++ b/src/crypto/curve25519/CMakeLists.txt
@@ -0,0 +1,47 @@
+include_directories(../../include)
+
+if (${ARCH} STREQUAL "arm")
+ set(
+ CURVE25519_ARCH_SOURCES
+
+ asm/x25519-asm-arm.S
+ )
+endif()
+
+if (${ARCH} STREQUAL "x86_64")
+ set(
+ CURVE25519_ARCH_SOURCES
+
+ asm/x25519-asm-x86_64.S
+ )
+endif()
+
+add_library(
+ curve25519
+
+ OBJECT
+
+ curve25519.c
+ x25519-x86_64.c
+
+ ${CURVE25519_ARCH_SOURCES}
+)
+
+add_executable(
+ ed25519_test
+
+ ed25519_test.cc
+ $<TARGET_OBJECTS:test_support>
+)
+
+target_link_libraries(ed25519_test crypto)
+add_dependencies(all_tests ed25519_test)
+
+add_executable(
+ x25519_test
+
+ x25519_test.cc
+)
+
+target_link_libraries(x25519_test crypto)
+add_dependencies(all_tests x25519_test)
diff --git a/src/crypto/curve25519/asm/x25519-asm-arm.S b/src/crypto/curve25519/asm/x25519-asm-arm.S
new file mode 100644
index 0000000..60d08dd
--- /dev/null
+++ b/src/crypto/curve25519/asm/x25519-asm-arm.S
@@ -0,0 +1,2118 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+/* This file is taken from crypto_scalarmult/curve25519/neon2/scalarmult.s in
+ * SUPERCOP 20141124 (http://bench.cr.yp.to/supercop.html). That code is public
+ * domain licensed but the standard ISC license is included above to keep
+ * licensing simple. */
+
+.fpu neon
+.text
+.align 4
+
+.global x25519_NEON
+.hidden x25519_NEON
+.type x25519_NEON, %function
+x25519_NEON:
+vpush {q4,q5,q6,q7}
+mov r12,sp
+sub sp,sp,#736
+and sp,sp,#0xffffffe0
+strd r4,[sp,#0]
+strd r6,[sp,#8]
+strd r8,[sp,#16]
+strd r10,[sp,#24]
+str r12,[sp,#480]
+str r14,[sp,#484]
+mov r0,r0
+mov r1,r1
+mov r2,r2
+add r3,sp,#32
+ldr r4,=0
+ldr r5,=254
+vmov.i32 q0,#1
+vshr.u64 q1,q0,#7
+vshr.u64 q0,q0,#8
+vmov.i32 d4,#19
+vmov.i32 d5,#38
+add r6,sp,#512
+vst1.8 {d2-d3},[r6,: 128]
+add r6,sp,#528
+vst1.8 {d0-d1},[r6,: 128]
+add r6,sp,#544
+vst1.8 {d4-d5},[r6,: 128]
+add r6,r3,#0
+vmov.i32 q2,#0
+vst1.8 {d4-d5},[r6,: 128]!
+vst1.8 {d4-d5},[r6,: 128]!
+vst1.8 d4,[r6,: 64]
+add r6,r3,#0
+ldr r7,=960
+sub r7,r7,#2
+neg r7,r7
+sub r7,r7,r7,LSL #7
+str r7,[r6]
+add r6,sp,#704
+vld1.8 {d4-d5},[r1]!
+vld1.8 {d6-d7},[r1]
+vst1.8 {d4-d5},[r6,: 128]!
+vst1.8 {d6-d7},[r6,: 128]
+sub r1,r6,#16
+ldrb r6,[r1]
+and r6,r6,#248
+strb r6,[r1]
+ldrb r6,[r1,#31]
+and r6,r6,#127
+orr r6,r6,#64
+strb r6,[r1,#31]
+vmov.i64 q2,#0xffffffff
+vshr.u64 q3,q2,#7
+vshr.u64 q2,q2,#6
+vld1.8 {d8},[r2]
+vld1.8 {d10},[r2]
+add r2,r2,#6
+vld1.8 {d12},[r2]
+vld1.8 {d14},[r2]
+add r2,r2,#6
+vld1.8 {d16},[r2]
+add r2,r2,#4
+vld1.8 {d18},[r2]
+vld1.8 {d20},[r2]
+add r2,r2,#6
+vld1.8 {d22},[r2]
+add r2,r2,#2
+vld1.8 {d24},[r2]
+vld1.8 {d26},[r2]
+vshr.u64 q5,q5,#26
+vshr.u64 q6,q6,#3
+vshr.u64 q7,q7,#29
+vshr.u64 q8,q8,#6
+vshr.u64 q10,q10,#25
+vshr.u64 q11,q11,#3
+vshr.u64 q12,q12,#12
+vshr.u64 q13,q13,#38
+vand q4,q4,q2
+vand q6,q6,q2
+vand q8,q8,q2
+vand q10,q10,q2
+vand q2,q12,q2
+vand q5,q5,q3
+vand q7,q7,q3
+vand q9,q9,q3
+vand q11,q11,q3
+vand q3,q13,q3
+add r2,r3,#48
+vadd.i64 q12,q4,q1
+vadd.i64 q13,q10,q1
+vshr.s64 q12,q12,#26
+vshr.s64 q13,q13,#26
+vadd.i64 q5,q5,q12
+vshl.i64 q12,q12,#26
+vadd.i64 q14,q5,q0
+vadd.i64 q11,q11,q13
+vshl.i64 q13,q13,#26
+vadd.i64 q15,q11,q0
+vsub.i64 q4,q4,q12
+vshr.s64 q12,q14,#25
+vsub.i64 q10,q10,q13
+vshr.s64 q13,q15,#25
+vadd.i64 q6,q6,q12
+vshl.i64 q12,q12,#25
+vadd.i64 q14,q6,q1
+vadd.i64 q2,q2,q13
+vsub.i64 q5,q5,q12
+vshr.s64 q12,q14,#26
+vshl.i64 q13,q13,#25
+vadd.i64 q14,q2,q1
+vadd.i64 q7,q7,q12
+vshl.i64 q12,q12,#26
+vadd.i64 q15,q7,q0
+vsub.i64 q11,q11,q13
+vshr.s64 q13,q14,#26
+vsub.i64 q6,q6,q12
+vshr.s64 q12,q15,#25
+vadd.i64 q3,q3,q13
+vshl.i64 q13,q13,#26
+vadd.i64 q14,q3,q0
+vadd.i64 q8,q8,q12
+vshl.i64 q12,q12,#25
+vadd.i64 q15,q8,q1
+add r2,r2,#8
+vsub.i64 q2,q2,q13
+vshr.s64 q13,q14,#25
+vsub.i64 q7,q7,q12
+vshr.s64 q12,q15,#26
+vadd.i64 q14,q13,q13
+vadd.i64 q9,q9,q12
+vtrn.32 d12,d14
+vshl.i64 q12,q12,#26
+vtrn.32 d13,d15
+vadd.i64 q0,q9,q0
+vadd.i64 q4,q4,q14
+vst1.8 d12,[r2,: 64]!
+vshl.i64 q6,q13,#4
+vsub.i64 q7,q8,q12
+vshr.s64 q0,q0,#25
+vadd.i64 q4,q4,q6
+vadd.i64 q6,q10,q0
+vshl.i64 q0,q0,#25
+vadd.i64 q8,q6,q1
+vadd.i64 q4,q4,q13
+vshl.i64 q10,q13,#25
+vadd.i64 q1,q4,q1
+vsub.i64 q0,q9,q0
+vshr.s64 q8,q8,#26
+vsub.i64 q3,q3,q10
+vtrn.32 d14,d0
+vshr.s64 q1,q1,#26
+vtrn.32 d15,d1
+vadd.i64 q0,q11,q8
+vst1.8 d14,[r2,: 64]
+vshl.i64 q7,q8,#26
+vadd.i64 q5,q5,q1
+vtrn.32 d4,d6
+vshl.i64 q1,q1,#26
+vtrn.32 d5,d7
+vsub.i64 q3,q6,q7
+add r2,r2,#16
+vsub.i64 q1,q4,q1
+vst1.8 d4,[r2,: 64]
+vtrn.32 d6,d0
+vtrn.32 d7,d1
+sub r2,r2,#8
+vtrn.32 d2,d10
+vtrn.32 d3,d11
+vst1.8 d6,[r2,: 64]
+sub r2,r2,#24
+vst1.8 d2,[r2,: 64]
+add r2,r3,#96
+vmov.i32 q0,#0
+vmov.i64 d2,#0xff
+vmov.i64 d3,#0
+vshr.u32 q1,q1,#7
+vst1.8 {d2-d3},[r2,: 128]!
+vst1.8 {d0-d1},[r2,: 128]!
+vst1.8 d0,[r2,: 64]
+add r2,r3,#144
+vmov.i32 q0,#0
+vst1.8 {d0-d1},[r2,: 128]!
+vst1.8 {d0-d1},[r2,: 128]!
+vst1.8 d0,[r2,: 64]
+add r2,r3,#240
+vmov.i32 q0,#0
+vmov.i64 d2,#0xff
+vmov.i64 d3,#0
+vshr.u32 q1,q1,#7
+vst1.8 {d2-d3},[r2,: 128]!
+vst1.8 {d0-d1},[r2,: 128]!
+vst1.8 d0,[r2,: 64]
+add r2,r3,#48
+add r6,r3,#192
+vld1.8 {d0-d1},[r2,: 128]!
+vld1.8 {d2-d3},[r2,: 128]!
+vld1.8 {d4},[r2,: 64]
+vst1.8 {d0-d1},[r6,: 128]!
+vst1.8 {d2-d3},[r6,: 128]!
+vst1.8 d4,[r6,: 64]
+._mainloop:
+mov r2,r5,LSR #3
+and r6,r5,#7
+ldrb r2,[r1,r2]
+mov r2,r2,LSR r6
+and r2,r2,#1
+str r5,[sp,#488]
+eor r4,r4,r2
+str r2,[sp,#492]
+neg r2,r4
+add r4,r3,#96
+add r5,r3,#192
+add r6,r3,#144
+vld1.8 {d8-d9},[r4,: 128]!
+add r7,r3,#240
+vld1.8 {d10-d11},[r5,: 128]!
+veor q6,q4,q5
+vld1.8 {d14-d15},[r6,: 128]!
+vdup.i32 q8,r2
+vld1.8 {d18-d19},[r7,: 128]!
+veor q10,q7,q9
+vld1.8 {d22-d23},[r4,: 128]!
+vand q6,q6,q8
+vld1.8 {d24-d25},[r5,: 128]!
+vand q10,q10,q8
+vld1.8 {d26-d27},[r6,: 128]!
+veor q4,q4,q6
+vld1.8 {d28-d29},[r7,: 128]!
+veor q5,q5,q6
+vld1.8 {d0},[r4,: 64]
+veor q6,q7,q10
+vld1.8 {d2},[r5,: 64]
+veor q7,q9,q10
+vld1.8 {d4},[r6,: 64]
+veor q9,q11,q12
+vld1.8 {d6},[r7,: 64]
+veor q10,q0,q1
+sub r2,r4,#32
+vand q9,q9,q8
+sub r4,r5,#32
+vand q10,q10,q8
+sub r5,r6,#32
+veor q11,q11,q9
+sub r6,r7,#32
+veor q0,q0,q10
+veor q9,q12,q9
+veor q1,q1,q10
+veor q10,q13,q14
+veor q12,q2,q3
+vand q10,q10,q8
+vand q8,q12,q8
+veor q12,q13,q10
+veor q2,q2,q8
+veor q10,q14,q10
+veor q3,q3,q8
+vadd.i32 q8,q4,q6
+vsub.i32 q4,q4,q6
+vst1.8 {d16-d17},[r2,: 128]!
+vadd.i32 q6,q11,q12
+vst1.8 {d8-d9},[r5,: 128]!
+vsub.i32 q4,q11,q12
+vst1.8 {d12-d13},[r2,: 128]!
+vadd.i32 q6,q0,q2
+vst1.8 {d8-d9},[r5,: 128]!
+vsub.i32 q0,q0,q2
+vst1.8 d12,[r2,: 64]
+vadd.i32 q2,q5,q7
+vst1.8 d0,[r5,: 64]
+vsub.i32 q0,q5,q7
+vst1.8 {d4-d5},[r4,: 128]!
+vadd.i32 q2,q9,q10
+vst1.8 {d0-d1},[r6,: 128]!
+vsub.i32 q0,q9,q10
+vst1.8 {d4-d5},[r4,: 128]!
+vadd.i32 q2,q1,q3
+vst1.8 {d0-d1},[r6,: 128]!
+vsub.i32 q0,q1,q3
+vst1.8 d4,[r4,: 64]
+vst1.8 d0,[r6,: 64]
+add r2,sp,#544
+add r4,r3,#96
+add r5,r3,#144
+vld1.8 {d0-d1},[r2,: 128]
+vld1.8 {d2-d3},[r4,: 128]!
+vld1.8 {d4-d5},[r5,: 128]!
+vzip.i32 q1,q2
+vld1.8 {d6-d7},[r4,: 128]!
+vld1.8 {d8-d9},[r5,: 128]!
+vshl.i32 q5,q1,#1
+vzip.i32 q3,q4
+vshl.i32 q6,q2,#1
+vld1.8 {d14},[r4,: 64]
+vshl.i32 q8,q3,#1
+vld1.8 {d15},[r5,: 64]
+vshl.i32 q9,q4,#1
+vmul.i32 d21,d7,d1
+vtrn.32 d14,d15
+vmul.i32 q11,q4,q0
+vmul.i32 q0,q7,q0
+vmull.s32 q12,d2,d2
+vmlal.s32 q12,d11,d1
+vmlal.s32 q12,d12,d0
+vmlal.s32 q12,d13,d23
+vmlal.s32 q12,d16,d22
+vmlal.s32 q12,d7,d21
+vmull.s32 q10,d2,d11
+vmlal.s32 q10,d4,d1
+vmlal.s32 q10,d13,d0
+vmlal.s32 q10,d6,d23
+vmlal.s32 q10,d17,d22
+vmull.s32 q13,d10,d4
+vmlal.s32 q13,d11,d3
+vmlal.s32 q13,d13,d1
+vmlal.s32 q13,d16,d0
+vmlal.s32 q13,d17,d23
+vmlal.s32 q13,d8,d22
+vmull.s32 q1,d10,d5
+vmlal.s32 q1,d11,d4
+vmlal.s32 q1,d6,d1
+vmlal.s32 q1,d17,d0
+vmlal.s32 q1,d8,d23
+vmull.s32 q14,d10,d6
+vmlal.s32 q14,d11,d13
+vmlal.s32 q14,d4,d4
+vmlal.s32 q14,d17,d1
+vmlal.s32 q14,d18,d0
+vmlal.s32 q14,d9,d23
+vmull.s32 q11,d10,d7
+vmlal.s32 q11,d11,d6
+vmlal.s32 q11,d12,d5
+vmlal.s32 q11,d8,d1
+vmlal.s32 q11,d19,d0
+vmull.s32 q15,d10,d8
+vmlal.s32 q15,d11,d17
+vmlal.s32 q15,d12,d6
+vmlal.s32 q15,d13,d5
+vmlal.s32 q15,d19,d1
+vmlal.s32 q15,d14,d0
+vmull.s32 q2,d10,d9
+vmlal.s32 q2,d11,d8
+vmlal.s32 q2,d12,d7
+vmlal.s32 q2,d13,d6
+vmlal.s32 q2,d14,d1
+vmull.s32 q0,d15,d1
+vmlal.s32 q0,d10,d14
+vmlal.s32 q0,d11,d19
+vmlal.s32 q0,d12,d8
+vmlal.s32 q0,d13,d17
+vmlal.s32 q0,d6,d6
+add r2,sp,#512
+vld1.8 {d18-d19},[r2,: 128]
+vmull.s32 q3,d16,d7
+vmlal.s32 q3,d10,d15
+vmlal.s32 q3,d11,d14
+vmlal.s32 q3,d12,d9
+vmlal.s32 q3,d13,d8
+add r2,sp,#528
+vld1.8 {d8-d9},[r2,: 128]
+vadd.i64 q5,q12,q9
+vadd.i64 q6,q15,q9
+vshr.s64 q5,q5,#26
+vshr.s64 q6,q6,#26
+vadd.i64 q7,q10,q5
+vshl.i64 q5,q5,#26
+vadd.i64 q8,q7,q4
+vadd.i64 q2,q2,q6
+vshl.i64 q6,q6,#26
+vadd.i64 q10,q2,q4
+vsub.i64 q5,q12,q5
+vshr.s64 q8,q8,#25
+vsub.i64 q6,q15,q6
+vshr.s64 q10,q10,#25
+vadd.i64 q12,q13,q8
+vshl.i64 q8,q8,#25
+vadd.i64 q13,q12,q9
+vadd.i64 q0,q0,q10
+vsub.i64 q7,q7,q8
+vshr.s64 q8,q13,#26
+vshl.i64 q10,q10,#25
+vadd.i64 q13,q0,q9
+vadd.i64 q1,q1,q8
+vshl.i64 q8,q8,#26
+vadd.i64 q15,q1,q4
+vsub.i64 q2,q2,q10
+vshr.s64 q10,q13,#26
+vsub.i64 q8,q12,q8
+vshr.s64 q12,q15,#25
+vadd.i64 q3,q3,q10
+vshl.i64 q10,q10,#26
+vadd.i64 q13,q3,q4
+vadd.i64 q14,q14,q12
+add r2,r3,#288
+vshl.i64 q12,q12,#25
+add r4,r3,#336
+vadd.i64 q15,q14,q9
+add r2,r2,#8
+vsub.i64 q0,q0,q10
+add r4,r4,#8
+vshr.s64 q10,q13,#25
+vsub.i64 q1,q1,q12
+vshr.s64 q12,q15,#26
+vadd.i64 q13,q10,q10
+vadd.i64 q11,q11,q12
+vtrn.32 d16,d2
+vshl.i64 q12,q12,#26
+vtrn.32 d17,d3
+vadd.i64 q1,q11,q4
+vadd.i64 q4,q5,q13
+vst1.8 d16,[r2,: 64]!
+vshl.i64 q5,q10,#4
+vst1.8 d17,[r4,: 64]!
+vsub.i64 q8,q14,q12
+vshr.s64 q1,q1,#25
+vadd.i64 q4,q4,q5
+vadd.i64 q5,q6,q1
+vshl.i64 q1,q1,#25
+vadd.i64 q6,q5,q9
+vadd.i64 q4,q4,q10
+vshl.i64 q10,q10,#25
+vadd.i64 q9,q4,q9
+vsub.i64 q1,q11,q1
+vshr.s64 q6,q6,#26
+vsub.i64 q3,q3,q10
+vtrn.32 d16,d2
+vshr.s64 q9,q9,#26
+vtrn.32 d17,d3
+vadd.i64 q1,q2,q6
+vst1.8 d16,[r2,: 64]
+vshl.i64 q2,q6,#26
+vst1.8 d17,[r4,: 64]
+vadd.i64 q6,q7,q9
+vtrn.32 d0,d6
+vshl.i64 q7,q9,#26
+vtrn.32 d1,d7
+vsub.i64 q2,q5,q2
+add r2,r2,#16
+vsub.i64 q3,q4,q7
+vst1.8 d0,[r2,: 64]
+add r4,r4,#16
+vst1.8 d1,[r4,: 64]
+vtrn.32 d4,d2
+vtrn.32 d5,d3
+sub r2,r2,#8
+sub r4,r4,#8
+vtrn.32 d6,d12
+vtrn.32 d7,d13
+vst1.8 d4,[r2,: 64]
+vst1.8 d5,[r4,: 64]
+sub r2,r2,#24
+sub r4,r4,#24
+vst1.8 d6,[r2,: 64]
+vst1.8 d7,[r4,: 64]
+add r2,r3,#240
+add r4,r3,#96
+vld1.8 {d0-d1},[r4,: 128]!
+vld1.8 {d2-d3},[r4,: 128]!
+vld1.8 {d4},[r4,: 64]
+add r4,r3,#144
+vld1.8 {d6-d7},[r4,: 128]!
+vtrn.32 q0,q3
+vld1.8 {d8-d9},[r4,: 128]!
+vshl.i32 q5,q0,#4
+vtrn.32 q1,q4
+vshl.i32 q6,q3,#4
+vadd.i32 q5,q5,q0
+vadd.i32 q6,q6,q3
+vshl.i32 q7,q1,#4
+vld1.8 {d5},[r4,: 64]
+vshl.i32 q8,q4,#4
+vtrn.32 d4,d5
+vadd.i32 q7,q7,q1
+vadd.i32 q8,q8,q4
+vld1.8 {d18-d19},[r2,: 128]!
+vshl.i32 q10,q2,#4
+vld1.8 {d22-d23},[r2,: 128]!
+vadd.i32 q10,q10,q2
+vld1.8 {d24},[r2,: 64]
+vadd.i32 q5,q5,q0
+add r2,r3,#192
+vld1.8 {d26-d27},[r2,: 128]!
+vadd.i32 q6,q6,q3
+vld1.8 {d28-d29},[r2,: 128]!
+vadd.i32 q8,q8,q4
+vld1.8 {d25},[r2,: 64]
+vadd.i32 q10,q10,q2
+vtrn.32 q9,q13
+vadd.i32 q7,q7,q1
+vadd.i32 q5,q5,q0
+vtrn.32 q11,q14
+vadd.i32 q6,q6,q3
+add r2,sp,#560
+vadd.i32 q10,q10,q2
+vtrn.32 d24,d25
+vst1.8 {d12-d13},[r2,: 128]
+vshl.i32 q6,q13,#1
+add r2,sp,#576
+vst1.8 {d20-d21},[r2,: 128]
+vshl.i32 q10,q14,#1
+add r2,sp,#592
+vst1.8 {d12-d13},[r2,: 128]
+vshl.i32 q15,q12,#1
+vadd.i32 q8,q8,q4
+vext.32 d10,d31,d30,#0
+vadd.i32 q7,q7,q1
+add r2,sp,#608
+vst1.8 {d16-d17},[r2,: 128]
+vmull.s32 q8,d18,d5
+vmlal.s32 q8,d26,d4
+vmlal.s32 q8,d19,d9
+vmlal.s32 q8,d27,d3
+vmlal.s32 q8,d22,d8
+vmlal.s32 q8,d28,d2
+vmlal.s32 q8,d23,d7
+vmlal.s32 q8,d29,d1
+vmlal.s32 q8,d24,d6
+vmlal.s32 q8,d25,d0
+add r2,sp,#624
+vst1.8 {d14-d15},[r2,: 128]
+vmull.s32 q2,d18,d4
+vmlal.s32 q2,d12,d9
+vmlal.s32 q2,d13,d8
+vmlal.s32 q2,d19,d3
+vmlal.s32 q2,d22,d2
+vmlal.s32 q2,d23,d1
+vmlal.s32 q2,d24,d0
+add r2,sp,#640
+vst1.8 {d20-d21},[r2,: 128]
+vmull.s32 q7,d18,d9
+vmlal.s32 q7,d26,d3
+vmlal.s32 q7,d19,d8
+vmlal.s32 q7,d27,d2
+vmlal.s32 q7,d22,d7
+vmlal.s32 q7,d28,d1
+vmlal.s32 q7,d23,d6
+vmlal.s32 q7,d29,d0
+add r2,sp,#656
+vst1.8 {d10-d11},[r2,: 128]
+vmull.s32 q5,d18,d3
+vmlal.s32 q5,d19,d2
+vmlal.s32 q5,d22,d1
+vmlal.s32 q5,d23,d0
+vmlal.s32 q5,d12,d8
+add r2,sp,#672
+vst1.8 {d16-d17},[r2,: 128]
+vmull.s32 q4,d18,d8
+vmlal.s32 q4,d26,d2
+vmlal.s32 q4,d19,d7
+vmlal.s32 q4,d27,d1
+vmlal.s32 q4,d22,d6
+vmlal.s32 q4,d28,d0
+vmull.s32 q8,d18,d7
+vmlal.s32 q8,d26,d1
+vmlal.s32 q8,d19,d6
+vmlal.s32 q8,d27,d0
+add r2,sp,#576
+vld1.8 {d20-d21},[r2,: 128]
+vmlal.s32 q7,d24,d21
+vmlal.s32 q7,d25,d20
+vmlal.s32 q4,d23,d21
+vmlal.s32 q4,d29,d20
+vmlal.s32 q8,d22,d21
+vmlal.s32 q8,d28,d20
+vmlal.s32 q5,d24,d20
+add r2,sp,#576
+vst1.8 {d14-d15},[r2,: 128]
+vmull.s32 q7,d18,d6
+vmlal.s32 q7,d26,d0
+add r2,sp,#656
+vld1.8 {d30-d31},[r2,: 128]
+vmlal.s32 q2,d30,d21
+vmlal.s32 q7,d19,d21
+vmlal.s32 q7,d27,d20
+add r2,sp,#624
+vld1.8 {d26-d27},[r2,: 128]
+vmlal.s32 q4,d25,d27
+vmlal.s32 q8,d29,d27
+vmlal.s32 q8,d25,d26
+vmlal.s32 q7,d28,d27
+vmlal.s32 q7,d29,d26
+add r2,sp,#608
+vld1.8 {d28-d29},[r2,: 128]
+vmlal.s32 q4,d24,d29
+vmlal.s32 q8,d23,d29
+vmlal.s32 q8,d24,d28
+vmlal.s32 q7,d22,d29
+vmlal.s32 q7,d23,d28
+add r2,sp,#608
+vst1.8 {d8-d9},[r2,: 128]
+add r2,sp,#560
+vld1.8 {d8-d9},[r2,: 128]
+vmlal.s32 q7,d24,d9
+vmlal.s32 q7,d25,d31
+vmull.s32 q1,d18,d2
+vmlal.s32 q1,d19,d1
+vmlal.s32 q1,d22,d0
+vmlal.s32 q1,d24,d27
+vmlal.s32 q1,d23,d20
+vmlal.s32 q1,d12,d7
+vmlal.s32 q1,d13,d6
+vmull.s32 q6,d18,d1
+vmlal.s32 q6,d19,d0
+vmlal.s32 q6,d23,d27
+vmlal.s32 q6,d22,d20
+vmlal.s32 q6,d24,d26
+vmull.s32 q0,d18,d0
+vmlal.s32 q0,d22,d27
+vmlal.s32 q0,d23,d26
+vmlal.s32 q0,d24,d31
+vmlal.s32 q0,d19,d20
+add r2,sp,#640
+vld1.8 {d18-d19},[r2,: 128]
+vmlal.s32 q2,d18,d7
+vmlal.s32 q2,d19,d6
+vmlal.s32 q5,d18,d6
+vmlal.s32 q5,d19,d21
+vmlal.s32 q1,d18,d21
+vmlal.s32 q1,d19,d29
+vmlal.s32 q0,d18,d28
+vmlal.s32 q0,d19,d9
+vmlal.s32 q6,d18,d29
+vmlal.s32 q6,d19,d28
+add r2,sp,#592
+vld1.8 {d18-d19},[r2,: 128]
+add r2,sp,#512
+vld1.8 {d22-d23},[r2,: 128]
+vmlal.s32 q5,d19,d7
+vmlal.s32 q0,d18,d21
+vmlal.s32 q0,d19,d29
+vmlal.s32 q6,d18,d6
+add r2,sp,#528
+vld1.8 {d6-d7},[r2,: 128]
+vmlal.s32 q6,d19,d21
+add r2,sp,#576
+vld1.8 {d18-d19},[r2,: 128]
+vmlal.s32 q0,d30,d8
+add r2,sp,#672
+vld1.8 {d20-d21},[r2,: 128]
+vmlal.s32 q5,d30,d29
+add r2,sp,#608
+vld1.8 {d24-d25},[r2,: 128]
+vmlal.s32 q1,d30,d28
+vadd.i64 q13,q0,q11
+vadd.i64 q14,q5,q11
+vmlal.s32 q6,d30,d9
+vshr.s64 q4,q13,#26
+vshr.s64 q13,q14,#26
+vadd.i64 q7,q7,q4
+vshl.i64 q4,q4,#26
+vadd.i64 q14,q7,q3
+vadd.i64 q9,q9,q13
+vshl.i64 q13,q13,#26
+vadd.i64 q15,q9,q3
+vsub.i64 q0,q0,q4
+vshr.s64 q4,q14,#25
+vsub.i64 q5,q5,q13
+vshr.s64 q13,q15,#25
+vadd.i64 q6,q6,q4
+vshl.i64 q4,q4,#25
+vadd.i64 q14,q6,q11
+vadd.i64 q2,q2,q13
+vsub.i64 q4,q7,q4
+vshr.s64 q7,q14,#26
+vshl.i64 q13,q13,#25
+vadd.i64 q14,q2,q11
+vadd.i64 q8,q8,q7
+vshl.i64 q7,q7,#26
+vadd.i64 q15,q8,q3
+vsub.i64 q9,q9,q13
+vshr.s64 q13,q14,#26
+vsub.i64 q6,q6,q7
+vshr.s64 q7,q15,#25
+vadd.i64 q10,q10,q13
+vshl.i64 q13,q13,#26
+vadd.i64 q14,q10,q3
+vadd.i64 q1,q1,q7
+add r2,r3,#144
+vshl.i64 q7,q7,#25
+add r4,r3,#96
+vadd.i64 q15,q1,q11
+add r2,r2,#8
+vsub.i64 q2,q2,q13
+add r4,r4,#8
+vshr.s64 q13,q14,#25
+vsub.i64 q7,q8,q7
+vshr.s64 q8,q15,#26
+vadd.i64 q14,q13,q13
+vadd.i64 q12,q12,q8
+vtrn.32 d12,d14
+vshl.i64 q8,q8,#26
+vtrn.32 d13,d15
+vadd.i64 q3,q12,q3
+vadd.i64 q0,q0,q14
+vst1.8 d12,[r2,: 64]!
+vshl.i64 q7,q13,#4
+vst1.8 d13,[r4,: 64]!
+vsub.i64 q1,q1,q8
+vshr.s64 q3,q3,#25
+vadd.i64 q0,q0,q7
+vadd.i64 q5,q5,q3
+vshl.i64 q3,q3,#25
+vadd.i64 q6,q5,q11
+vadd.i64 q0,q0,q13
+vshl.i64 q7,q13,#25
+vadd.i64 q8,q0,q11
+vsub.i64 q3,q12,q3
+vshr.s64 q6,q6,#26
+vsub.i64 q7,q10,q7
+vtrn.32 d2,d6
+vshr.s64 q8,q8,#26
+vtrn.32 d3,d7
+vadd.i64 q3,q9,q6
+vst1.8 d2,[r2,: 64]
+vshl.i64 q6,q6,#26
+vst1.8 d3,[r4,: 64]
+vadd.i64 q1,q4,q8
+vtrn.32 d4,d14
+vshl.i64 q4,q8,#26
+vtrn.32 d5,d15
+vsub.i64 q5,q5,q6
+add r2,r2,#16
+vsub.i64 q0,q0,q4
+vst1.8 d4,[r2,: 64]
+add r4,r4,#16
+vst1.8 d5,[r4,: 64]
+vtrn.32 d10,d6
+vtrn.32 d11,d7
+sub r2,r2,#8
+sub r4,r4,#8
+vtrn.32 d0,d2
+vtrn.32 d1,d3
+vst1.8 d10,[r2,: 64]
+vst1.8 d11,[r4,: 64]
+sub r2,r2,#24
+sub r4,r4,#24
+vst1.8 d0,[r2,: 64]
+vst1.8 d1,[r4,: 64]
+add r2,r3,#288
+add r4,r3,#336
+vld1.8 {d0-d1},[r2,: 128]!
+vld1.8 {d2-d3},[r4,: 128]!
+vsub.i32 q0,q0,q1
+vld1.8 {d2-d3},[r2,: 128]!
+vld1.8 {d4-d5},[r4,: 128]!
+vsub.i32 q1,q1,q2
+add r5,r3,#240
+vld1.8 {d4},[r2,: 64]
+vld1.8 {d6},[r4,: 64]
+vsub.i32 q2,q2,q3
+vst1.8 {d0-d1},[r5,: 128]!
+vst1.8 {d2-d3},[r5,: 128]!
+vst1.8 d4,[r5,: 64]
+add r2,r3,#144
+add r4,r3,#96
+add r5,r3,#144
+add r6,r3,#192
+vld1.8 {d0-d1},[r2,: 128]!
+vld1.8 {d2-d3},[r4,: 128]!
+vsub.i32 q2,q0,q1
+vadd.i32 q0,q0,q1
+vld1.8 {d2-d3},[r2,: 128]!
+vld1.8 {d6-d7},[r4,: 128]!
+vsub.i32 q4,q1,q3
+vadd.i32 q1,q1,q3
+vld1.8 {d6},[r2,: 64]
+vld1.8 {d10},[r4,: 64]
+vsub.i32 q6,q3,q5
+vadd.i32 q3,q3,q5
+vst1.8 {d4-d5},[r5,: 128]!
+vst1.8 {d0-d1},[r6,: 128]!
+vst1.8 {d8-d9},[r5,: 128]!
+vst1.8 {d2-d3},[r6,: 128]!
+vst1.8 d12,[r5,: 64]
+vst1.8 d6,[r6,: 64]
+add r2,r3,#0
+add r4,r3,#240
+vld1.8 {d0-d1},[r4,: 128]!
+vld1.8 {d2-d3},[r4,: 128]!
+vld1.8 {d4},[r4,: 64]
+add r4,r3,#336
+vld1.8 {d6-d7},[r4,: 128]!
+vtrn.32 q0,q3
+vld1.8 {d8-d9},[r4,: 128]!
+vshl.i32 q5,q0,#4
+vtrn.32 q1,q4
+vshl.i32 q6,q3,#4
+vadd.i32 q5,q5,q0
+vadd.i32 q6,q6,q3
+vshl.i32 q7,q1,#4
+vld1.8 {d5},[r4,: 64]
+vshl.i32 q8,q4,#4
+vtrn.32 d4,d5
+vadd.i32 q7,q7,q1
+vadd.i32 q8,q8,q4
+vld1.8 {d18-d19},[r2,: 128]!
+vshl.i32 q10,q2,#4
+vld1.8 {d22-d23},[r2,: 128]!
+vadd.i32 q10,q10,q2
+vld1.8 {d24},[r2,: 64]
+vadd.i32 q5,q5,q0
+add r2,r3,#288
+vld1.8 {d26-d27},[r2,: 128]!
+vadd.i32 q6,q6,q3
+vld1.8 {d28-d29},[r2,: 128]!
+vadd.i32 q8,q8,q4
+vld1.8 {d25},[r2,: 64]
+vadd.i32 q10,q10,q2
+vtrn.32 q9,q13
+vadd.i32 q7,q7,q1
+vadd.i32 q5,q5,q0
+vtrn.32 q11,q14
+vadd.i32 q6,q6,q3
+add r2,sp,#560
+vadd.i32 q10,q10,q2
+vtrn.32 d24,d25
+vst1.8 {d12-d13},[r2,: 128]
+vshl.i32 q6,q13,#1
+add r2,sp,#576
+vst1.8 {d20-d21},[r2,: 128]
+vshl.i32 q10,q14,#1
+add r2,sp,#592
+vst1.8 {d12-d13},[r2,: 128]
+vshl.i32 q15,q12,#1
+vadd.i32 q8,q8,q4
+vext.32 d10,d31,d30,#0
+vadd.i32 q7,q7,q1
+add r2,sp,#608
+vst1.8 {d16-d17},[r2,: 128]
+vmull.s32 q8,d18,d5
+vmlal.s32 q8,d26,d4
+vmlal.s32 q8,d19,d9
+vmlal.s32 q8,d27,d3
+vmlal.s32 q8,d22,d8
+vmlal.s32 q8,d28,d2
+vmlal.s32 q8,d23,d7
+vmlal.s32 q8,d29,d1
+vmlal.s32 q8,d24,d6
+vmlal.s32 q8,d25,d0
+add r2,sp,#624
+vst1.8 {d14-d15},[r2,: 128]
+vmull.s32 q2,d18,d4
+vmlal.s32 q2,d12,d9
+vmlal.s32 q2,d13,d8
+vmlal.s32 q2,d19,d3
+vmlal.s32 q2,d22,d2
+vmlal.s32 q2,d23,d1
+vmlal.s32 q2,d24,d0
+add r2,sp,#640
+vst1.8 {d20-d21},[r2,: 128]
+vmull.s32 q7,d18,d9
+vmlal.s32 q7,d26,d3
+vmlal.s32 q7,d19,d8
+vmlal.s32 q7,d27,d2
+vmlal.s32 q7,d22,d7
+vmlal.s32 q7,d28,d1
+vmlal.s32 q7,d23,d6
+vmlal.s32 q7,d29,d0
+add r2,sp,#656
+vst1.8 {d10-d11},[r2,: 128]
+vmull.s32 q5,d18,d3
+vmlal.s32 q5,d19,d2
+vmlal.s32 q5,d22,d1
+vmlal.s32 q5,d23,d0
+vmlal.s32 q5,d12,d8
+add r2,sp,#672
+vst1.8 {d16-d17},[r2,: 128]
+vmull.s32 q4,d18,d8
+vmlal.s32 q4,d26,d2
+vmlal.s32 q4,d19,d7
+vmlal.s32 q4,d27,d1
+vmlal.s32 q4,d22,d6
+vmlal.s32 q4,d28,d0
+vmull.s32 q8,d18,d7
+vmlal.s32 q8,d26,d1
+vmlal.s32 q8,d19,d6
+vmlal.s32 q8,d27,d0
+add r2,sp,#576
+vld1.8 {d20-d21},[r2,: 128]
+vmlal.s32 q7,d24,d21
+vmlal.s32 q7,d25,d20
+vmlal.s32 q4,d23,d21
+vmlal.s32 q4,d29,d20
+vmlal.s32 q8,d22,d21
+vmlal.s32 q8,d28,d20
+vmlal.s32 q5,d24,d20
+add r2,sp,#576
+vst1.8 {d14-d15},[r2,: 128]
+vmull.s32 q7,d18,d6
+vmlal.s32 q7,d26,d0
+add r2,sp,#656
+vld1.8 {d30-d31},[r2,: 128]
+vmlal.s32 q2,d30,d21
+vmlal.s32 q7,d19,d21
+vmlal.s32 q7,d27,d20
+add r2,sp,#624
+vld1.8 {d26-d27},[r2,: 128]
+vmlal.s32 q4,d25,d27
+vmlal.s32 q8,d29,d27
+vmlal.s32 q8,d25,d26
+vmlal.s32 q7,d28,d27
+vmlal.s32 q7,d29,d26
+add r2,sp,#608
+vld1.8 {d28-d29},[r2,: 128]
+vmlal.s32 q4,d24,d29
+vmlal.s32 q8,d23,d29
+vmlal.s32 q8,d24,d28
+vmlal.s32 q7,d22,d29
+vmlal.s32 q7,d23,d28
+add r2,sp,#608
+vst1.8 {d8-d9},[r2,: 128]
+add r2,sp,#560
+vld1.8 {d8-d9},[r2,: 128]
+vmlal.s32 q7,d24,d9
+vmlal.s32 q7,d25,d31
+vmull.s32 q1,d18,d2
+vmlal.s32 q1,d19,d1
+vmlal.s32 q1,d22,d0
+vmlal.s32 q1,d24,d27
+vmlal.s32 q1,d23,d20
+vmlal.s32 q1,d12,d7
+vmlal.s32 q1,d13,d6
+vmull.s32 q6,d18,d1
+vmlal.s32 q6,d19,d0
+vmlal.s32 q6,d23,d27
+vmlal.s32 q6,d22,d20
+vmlal.s32 q6,d24,d26
+vmull.s32 q0,d18,d0
+vmlal.s32 q0,d22,d27
+vmlal.s32 q0,d23,d26
+vmlal.s32 q0,d24,d31
+vmlal.s32 q0,d19,d20
+add r2,sp,#640
+vld1.8 {d18-d19},[r2,: 128]
+vmlal.s32 q2,d18,d7
+vmlal.s32 q2,d19,d6
+vmlal.s32 q5,d18,d6
+vmlal.s32 q5,d19,d21
+vmlal.s32 q1,d18,d21
+vmlal.s32 q1,d19,d29
+vmlal.s32 q0,d18,d28
+vmlal.s32 q0,d19,d9
+vmlal.s32 q6,d18,d29
+vmlal.s32 q6,d19,d28
+add r2,sp,#592
+vld1.8 {d18-d19},[r2,: 128]
+add r2,sp,#512
+vld1.8 {d22-d23},[r2,: 128]
+vmlal.s32 q5,d19,d7
+vmlal.s32 q0,d18,d21
+vmlal.s32 q0,d19,d29
+vmlal.s32 q6,d18,d6
+add r2,sp,#528
+vld1.8 {d6-d7},[r2,: 128]
+vmlal.s32 q6,d19,d21
+add r2,sp,#576
+vld1.8 {d18-d19},[r2,: 128]
+vmlal.s32 q0,d30,d8
+add r2,sp,#672
+vld1.8 {d20-d21},[r2,: 128]
+vmlal.s32 q5,d30,d29
+add r2,sp,#608
+vld1.8 {d24-d25},[r2,: 128]
+vmlal.s32 q1,d30,d28
+vadd.i64 q13,q0,q11
+vadd.i64 q14,q5,q11
+vmlal.s32 q6,d30,d9
+vshr.s64 q4,q13,#26
+vshr.s64 q13,q14,#26
+vadd.i64 q7,q7,q4
+vshl.i64 q4,q4,#26
+vadd.i64 q14,q7,q3
+vadd.i64 q9,q9,q13
+vshl.i64 q13,q13,#26
+vadd.i64 q15,q9,q3
+vsub.i64 q0,q0,q4
+vshr.s64 q4,q14,#25
+vsub.i64 q5,q5,q13
+vshr.s64 q13,q15,#25
+vadd.i64 q6,q6,q4
+vshl.i64 q4,q4,#25
+vadd.i64 q14,q6,q11
+vadd.i64 q2,q2,q13
+vsub.i64 q4,q7,q4
+vshr.s64 q7,q14,#26
+vshl.i64 q13,q13,#25
+vadd.i64 q14,q2,q11
+vadd.i64 q8,q8,q7
+vshl.i64 q7,q7,#26
+vadd.i64 q15,q8,q3
+vsub.i64 q9,q9,q13
+vshr.s64 q13,q14,#26
+vsub.i64 q6,q6,q7
+vshr.s64 q7,q15,#25
+vadd.i64 q10,q10,q13
+vshl.i64 q13,q13,#26
+vadd.i64 q14,q10,q3
+vadd.i64 q1,q1,q7
+add r2,r3,#288
+vshl.i64 q7,q7,#25
+add r4,r3,#96
+vadd.i64 q15,q1,q11
+add r2,r2,#8
+vsub.i64 q2,q2,q13
+add r4,r4,#8
+vshr.s64 q13,q14,#25
+vsub.i64 q7,q8,q7
+vshr.s64 q8,q15,#26
+vadd.i64 q14,q13,q13
+vadd.i64 q12,q12,q8
+vtrn.32 d12,d14
+vshl.i64 q8,q8,#26
+vtrn.32 d13,d15
+vadd.i64 q3,q12,q3
+vadd.i64 q0,q0,q14
+vst1.8 d12,[r2,: 64]!
+vshl.i64 q7,q13,#4
+vst1.8 d13,[r4,: 64]!
+vsub.i64 q1,q1,q8
+vshr.s64 q3,q3,#25
+vadd.i64 q0,q0,q7
+vadd.i64 q5,q5,q3
+vshl.i64 q3,q3,#25
+vadd.i64 q6,q5,q11
+vadd.i64 q0,q0,q13
+vshl.i64 q7,q13,#25
+vadd.i64 q8,q0,q11
+vsub.i64 q3,q12,q3
+vshr.s64 q6,q6,#26
+vsub.i64 q7,q10,q7
+vtrn.32 d2,d6
+vshr.s64 q8,q8,#26
+vtrn.32 d3,d7
+vadd.i64 q3,q9,q6
+vst1.8 d2,[r2,: 64]
+vshl.i64 q6,q6,#26
+vst1.8 d3,[r4,: 64]
+vadd.i64 q1,q4,q8
+vtrn.32 d4,d14
+vshl.i64 q4,q8,#26
+vtrn.32 d5,d15
+vsub.i64 q5,q5,q6
+add r2,r2,#16
+vsub.i64 q0,q0,q4
+vst1.8 d4,[r2,: 64]
+add r4,r4,#16
+vst1.8 d5,[r4,: 64]
+vtrn.32 d10,d6
+vtrn.32 d11,d7
+sub r2,r2,#8
+sub r4,r4,#8
+vtrn.32 d0,d2
+vtrn.32 d1,d3
+vst1.8 d10,[r2,: 64]
+vst1.8 d11,[r4,: 64]
+sub r2,r2,#24
+sub r4,r4,#24
+vst1.8 d0,[r2,: 64]
+vst1.8 d1,[r4,: 64]
+add r2,sp,#544
+add r4,r3,#144
+add r5,r3,#192
+vld1.8 {d0-d1},[r2,: 128]
+vld1.8 {d2-d3},[r4,: 128]!
+vld1.8 {d4-d5},[r5,: 128]!
+vzip.i32 q1,q2
+vld1.8 {d6-d7},[r4,: 128]!
+vld1.8 {d8-d9},[r5,: 128]!
+vshl.i32 q5,q1,#1
+vzip.i32 q3,q4
+vshl.i32 q6,q2,#1
+vld1.8 {d14},[r4,: 64]
+vshl.i32 q8,q3,#1
+vld1.8 {d15},[r5,: 64]
+vshl.i32 q9,q4,#1
+vmul.i32 d21,d7,d1
+vtrn.32 d14,d15
+vmul.i32 q11,q4,q0
+vmul.i32 q0,q7,q0
+vmull.s32 q12,d2,d2
+vmlal.s32 q12,d11,d1
+vmlal.s32 q12,d12,d0
+vmlal.s32 q12,d13,d23
+vmlal.s32 q12,d16,d22
+vmlal.s32 q12,d7,d21
+vmull.s32 q10,d2,d11
+vmlal.s32 q10,d4,d1
+vmlal.s32 q10,d13,d0
+vmlal.s32 q10,d6,d23
+vmlal.s32 q10,d17,d22
+vmull.s32 q13,d10,d4
+vmlal.s32 q13,d11,d3
+vmlal.s32 q13,d13,d1
+vmlal.s32 q13,d16,d0
+vmlal.s32 q13,d17,d23
+vmlal.s32 q13,d8,d22
+vmull.s32 q1,d10,d5
+vmlal.s32 q1,d11,d4
+vmlal.s32 q1,d6,d1
+vmlal.s32 q1,d17,d0
+vmlal.s32 q1,d8,d23
+vmull.s32 q14,d10,d6
+vmlal.s32 q14,d11,d13
+vmlal.s32 q14,d4,d4
+vmlal.s32 q14,d17,d1
+vmlal.s32 q14,d18,d0
+vmlal.s32 q14,d9,d23
+vmull.s32 q11,d10,d7
+vmlal.s32 q11,d11,d6
+vmlal.s32 q11,d12,d5
+vmlal.s32 q11,d8,d1
+vmlal.s32 q11,d19,d0
+vmull.s32 q15,d10,d8
+vmlal.s32 q15,d11,d17
+vmlal.s32 q15,d12,d6
+vmlal.s32 q15,d13,d5
+vmlal.s32 q15,d19,d1
+vmlal.s32 q15,d14,d0
+vmull.s32 q2,d10,d9
+vmlal.s32 q2,d11,d8
+vmlal.s32 q2,d12,d7
+vmlal.s32 q2,d13,d6
+vmlal.s32 q2,d14,d1
+vmull.s32 q0,d15,d1
+vmlal.s32 q0,d10,d14
+vmlal.s32 q0,d11,d19
+vmlal.s32 q0,d12,d8
+vmlal.s32 q0,d13,d17
+vmlal.s32 q0,d6,d6
+add r2,sp,#512
+vld1.8 {d18-d19},[r2,: 128]
+vmull.s32 q3,d16,d7
+vmlal.s32 q3,d10,d15
+vmlal.s32 q3,d11,d14
+vmlal.s32 q3,d12,d9
+vmlal.s32 q3,d13,d8
+add r2,sp,#528
+vld1.8 {d8-d9},[r2,: 128]
+vadd.i64 q5,q12,q9
+vadd.i64 q6,q15,q9
+vshr.s64 q5,q5,#26
+vshr.s64 q6,q6,#26
+vadd.i64 q7,q10,q5
+vshl.i64 q5,q5,#26
+vadd.i64 q8,q7,q4
+vadd.i64 q2,q2,q6
+vshl.i64 q6,q6,#26
+vadd.i64 q10,q2,q4
+vsub.i64 q5,q12,q5
+vshr.s64 q8,q8,#25
+vsub.i64 q6,q15,q6
+vshr.s64 q10,q10,#25
+vadd.i64 q12,q13,q8
+vshl.i64 q8,q8,#25
+vadd.i64 q13,q12,q9
+vadd.i64 q0,q0,q10
+vsub.i64 q7,q7,q8
+vshr.s64 q8,q13,#26
+vshl.i64 q10,q10,#25
+vadd.i64 q13,q0,q9
+vadd.i64 q1,q1,q8
+vshl.i64 q8,q8,#26
+vadd.i64 q15,q1,q4
+vsub.i64 q2,q2,q10
+vshr.s64 q10,q13,#26
+vsub.i64 q8,q12,q8
+vshr.s64 q12,q15,#25
+vadd.i64 q3,q3,q10
+vshl.i64 q10,q10,#26
+vadd.i64 q13,q3,q4
+vadd.i64 q14,q14,q12
+add r2,r3,#144
+vshl.i64 q12,q12,#25
+add r4,r3,#192
+vadd.i64 q15,q14,q9
+add r2,r2,#8
+vsub.i64 q0,q0,q10
+add r4,r4,#8
+vshr.s64 q10,q13,#25
+vsub.i64 q1,q1,q12
+vshr.s64 q12,q15,#26
+vadd.i64 q13,q10,q10
+vadd.i64 q11,q11,q12
+vtrn.32 d16,d2
+vshl.i64 q12,q12,#26
+vtrn.32 d17,d3
+vadd.i64 q1,q11,q4
+vadd.i64 q4,q5,q13
+vst1.8 d16,[r2,: 64]!
+vshl.i64 q5,q10,#4
+vst1.8 d17,[r4,: 64]!
+vsub.i64 q8,q14,q12
+vshr.s64 q1,q1,#25
+vadd.i64 q4,q4,q5
+vadd.i64 q5,q6,q1
+vshl.i64 q1,q1,#25
+vadd.i64 q6,q5,q9
+vadd.i64 q4,q4,q10
+vshl.i64 q10,q10,#25
+vadd.i64 q9,q4,q9
+vsub.i64 q1,q11,q1
+vshr.s64 q6,q6,#26
+vsub.i64 q3,q3,q10
+vtrn.32 d16,d2
+vshr.s64 q9,q9,#26
+vtrn.32 d17,d3
+vadd.i64 q1,q2,q6
+vst1.8 d16,[r2,: 64]
+vshl.i64 q2,q6,#26
+vst1.8 d17,[r4,: 64]
+vadd.i64 q6,q7,q9
+vtrn.32 d0,d6
+vshl.i64 q7,q9,#26
+vtrn.32 d1,d7
+vsub.i64 q2,q5,q2
+add r2,r2,#16
+vsub.i64 q3,q4,q7
+vst1.8 d0,[r2,: 64]
+add r4,r4,#16
+vst1.8 d1,[r4,: 64]
+vtrn.32 d4,d2
+vtrn.32 d5,d3
+sub r2,r2,#8
+sub r4,r4,#8
+vtrn.32 d6,d12
+vtrn.32 d7,d13
+vst1.8 d4,[r2,: 64]
+vst1.8 d5,[r4,: 64]
+sub r2,r2,#24
+sub r4,r4,#24
+vst1.8 d6,[r2,: 64]
+vst1.8 d7,[r4,: 64]
+add r2,r3,#336
+add r4,r3,#288
+vld1.8 {d0-d1},[r2,: 128]!
+vld1.8 {d2-d3},[r4,: 128]!
+vadd.i32 q0,q0,q1
+vld1.8 {d2-d3},[r2,: 128]!
+vld1.8 {d4-d5},[r4,: 128]!
+vadd.i32 q1,q1,q2
+add r5,r3,#288
+vld1.8 {d4},[r2,: 64]
+vld1.8 {d6},[r4,: 64]
+vadd.i32 q2,q2,q3
+vst1.8 {d0-d1},[r5,: 128]!
+vst1.8 {d2-d3},[r5,: 128]!
+vst1.8 d4,[r5,: 64]
+add r2,r3,#48
+add r4,r3,#144
+vld1.8 {d0-d1},[r4,: 128]!
+vld1.8 {d2-d3},[r4,: 128]!
+vld1.8 {d4},[r4,: 64]
+add r4,r3,#288
+vld1.8 {d6-d7},[r4,: 128]!
+vtrn.32 q0,q3
+vld1.8 {d8-d9},[r4,: 128]!
+vshl.i32 q5,q0,#4
+vtrn.32 q1,q4
+vshl.i32 q6,q3,#4
+vadd.i32 q5,q5,q0
+vadd.i32 q6,q6,q3
+vshl.i32 q7,q1,#4
+vld1.8 {d5},[r4,: 64]
+vshl.i32 q8,q4,#4
+vtrn.32 d4,d5
+vadd.i32 q7,q7,q1
+vadd.i32 q8,q8,q4
+vld1.8 {d18-d19},[r2,: 128]!
+vshl.i32 q10,q2,#4
+vld1.8 {d22-d23},[r2,: 128]!
+vadd.i32 q10,q10,q2
+vld1.8 {d24},[r2,: 64]
+vadd.i32 q5,q5,q0
+add r2,r3,#240
+vld1.8 {d26-d27},[r2,: 128]!
+vadd.i32 q6,q6,q3
+vld1.8 {d28-d29},[r2,: 128]!
+vadd.i32 q8,q8,q4
+vld1.8 {d25},[r2,: 64]
+vadd.i32 q10,q10,q2
+vtrn.32 q9,q13
+vadd.i32 q7,q7,q1
+vadd.i32 q5,q5,q0
+vtrn.32 q11,q14
+vadd.i32 q6,q6,q3
+add r2,sp,#560
+vadd.i32 q10,q10,q2
+vtrn.32 d24,d25
+vst1.8 {d12-d13},[r2,: 128]
+vshl.i32 q6,q13,#1
+add r2,sp,#576
+vst1.8 {d20-d21},[r2,: 128]
+vshl.i32 q10,q14,#1
+add r2,sp,#592
+vst1.8 {d12-d13},[r2,: 128]
+vshl.i32 q15,q12,#1
+vadd.i32 q8,q8,q4
+vext.32 d10,d31,d30,#0
+vadd.i32 q7,q7,q1
+add r2,sp,#608
+vst1.8 {d16-d17},[r2,: 128]
+vmull.s32 q8,d18,d5
+vmlal.s32 q8,d26,d4
+vmlal.s32 q8,d19,d9
+vmlal.s32 q8,d27,d3
+vmlal.s32 q8,d22,d8
+vmlal.s32 q8,d28,d2
+vmlal.s32 q8,d23,d7
+vmlal.s32 q8,d29,d1
+vmlal.s32 q8,d24,d6
+vmlal.s32 q8,d25,d0
+add r2,sp,#624
+vst1.8 {d14-d15},[r2,: 128]
+vmull.s32 q2,d18,d4
+vmlal.s32 q2,d12,d9
+vmlal.s32 q2,d13,d8
+vmlal.s32 q2,d19,d3
+vmlal.s32 q2,d22,d2
+vmlal.s32 q2,d23,d1
+vmlal.s32 q2,d24,d0
+add r2,sp,#640
+vst1.8 {d20-d21},[r2,: 128]
+vmull.s32 q7,d18,d9
+vmlal.s32 q7,d26,d3
+vmlal.s32 q7,d19,d8
+vmlal.s32 q7,d27,d2
+vmlal.s32 q7,d22,d7
+vmlal.s32 q7,d28,d1
+vmlal.s32 q7,d23,d6
+vmlal.s32 q7,d29,d0
+add r2,sp,#656
+vst1.8 {d10-d11},[r2,: 128]
+vmull.s32 q5,d18,d3
+vmlal.s32 q5,d19,d2
+vmlal.s32 q5,d22,d1
+vmlal.s32 q5,d23,d0
+vmlal.s32 q5,d12,d8
+add r2,sp,#672
+vst1.8 {d16-d17},[r2,: 128]
+vmull.s32 q4,d18,d8
+vmlal.s32 q4,d26,d2
+vmlal.s32 q4,d19,d7
+vmlal.s32 q4,d27,d1
+vmlal.s32 q4,d22,d6
+vmlal.s32 q4,d28,d0
+vmull.s32 q8,d18,d7
+vmlal.s32 q8,d26,d1
+vmlal.s32 q8,d19,d6
+vmlal.s32 q8,d27,d0
+add r2,sp,#576
+vld1.8 {d20-d21},[r2,: 128]
+vmlal.s32 q7,d24,d21
+vmlal.s32 q7,d25,d20
+vmlal.s32 q4,d23,d21
+vmlal.s32 q4,d29,d20
+vmlal.s32 q8,d22,d21
+vmlal.s32 q8,d28,d20
+vmlal.s32 q5,d24,d20
+add r2,sp,#576
+vst1.8 {d14-d15},[r2,: 128]
+vmull.s32 q7,d18,d6
+vmlal.s32 q7,d26,d0
+add r2,sp,#656
+vld1.8 {d30-d31},[r2,: 128]
+vmlal.s32 q2,d30,d21
+vmlal.s32 q7,d19,d21
+vmlal.s32 q7,d27,d20
+add r2,sp,#624
+vld1.8 {d26-d27},[r2,: 128]
+vmlal.s32 q4,d25,d27
+vmlal.s32 q8,d29,d27
+vmlal.s32 q8,d25,d26
+vmlal.s32 q7,d28,d27
+vmlal.s32 q7,d29,d26
+add r2,sp,#608
+vld1.8 {d28-d29},[r2,: 128]
+vmlal.s32 q4,d24,d29
+vmlal.s32 q8,d23,d29
+vmlal.s32 q8,d24,d28
+vmlal.s32 q7,d22,d29
+vmlal.s32 q7,d23,d28
+add r2,sp,#608
+vst1.8 {d8-d9},[r2,: 128]
+add r2,sp,#560
+vld1.8 {d8-d9},[r2,: 128]
+vmlal.s32 q7,d24,d9
+vmlal.s32 q7,d25,d31
+vmull.s32 q1,d18,d2
+vmlal.s32 q1,d19,d1
+vmlal.s32 q1,d22,d0
+vmlal.s32 q1,d24,d27
+vmlal.s32 q1,d23,d20
+vmlal.s32 q1,d12,d7
+vmlal.s32 q1,d13,d6
+vmull.s32 q6,d18,d1
+vmlal.s32 q6,d19,d0
+vmlal.s32 q6,d23,d27
+vmlal.s32 q6,d22,d20
+vmlal.s32 q6,d24,d26
+vmull.s32 q0,d18,d0
+vmlal.s32 q0,d22,d27
+vmlal.s32 q0,d23,d26
+vmlal.s32 q0,d24,d31
+vmlal.s32 q0,d19,d20
+add r2,sp,#640
+vld1.8 {d18-d19},[r2,: 128]
+vmlal.s32 q2,d18,d7
+vmlal.s32 q2,d19,d6
+vmlal.s32 q5,d18,d6
+vmlal.s32 q5,d19,d21
+vmlal.s32 q1,d18,d21
+vmlal.s32 q1,d19,d29
+vmlal.s32 q0,d18,d28
+vmlal.s32 q0,d19,d9
+vmlal.s32 q6,d18,d29
+vmlal.s32 q6,d19,d28
+add r2,sp,#592
+vld1.8 {d18-d19},[r2,: 128]
+add r2,sp,#512
+vld1.8 {d22-d23},[r2,: 128]
+vmlal.s32 q5,d19,d7
+vmlal.s32 q0,d18,d21
+vmlal.s32 q0,d19,d29
+vmlal.s32 q6,d18,d6
+add r2,sp,#528
+vld1.8 {d6-d7},[r2,: 128]
+vmlal.s32 q6,d19,d21
+add r2,sp,#576
+vld1.8 {d18-d19},[r2,: 128]
+vmlal.s32 q0,d30,d8
+add r2,sp,#672
+vld1.8 {d20-d21},[r2,: 128]
+vmlal.s32 q5,d30,d29
+add r2,sp,#608
+vld1.8 {d24-d25},[r2,: 128]
+vmlal.s32 q1,d30,d28
+vadd.i64 q13,q0,q11
+vadd.i64 q14,q5,q11
+vmlal.s32 q6,d30,d9
+vshr.s64 q4,q13,#26
+vshr.s64 q13,q14,#26
+vadd.i64 q7,q7,q4
+vshl.i64 q4,q4,#26
+vadd.i64 q14,q7,q3
+vadd.i64 q9,q9,q13
+vshl.i64 q13,q13,#26
+vadd.i64 q15,q9,q3
+vsub.i64 q0,q0,q4
+vshr.s64 q4,q14,#25
+vsub.i64 q5,q5,q13
+vshr.s64 q13,q15,#25
+vadd.i64 q6,q6,q4
+vshl.i64 q4,q4,#25
+vadd.i64 q14,q6,q11
+vadd.i64 q2,q2,q13
+vsub.i64 q4,q7,q4
+vshr.s64 q7,q14,#26
+vshl.i64 q13,q13,#25
+vadd.i64 q14,q2,q11
+vadd.i64 q8,q8,q7
+vshl.i64 q7,q7,#26
+vadd.i64 q15,q8,q3
+vsub.i64 q9,q9,q13
+vshr.s64 q13,q14,#26
+vsub.i64 q6,q6,q7
+vshr.s64 q7,q15,#25
+vadd.i64 q10,q10,q13
+vshl.i64 q13,q13,#26
+vadd.i64 q14,q10,q3
+vadd.i64 q1,q1,q7
+add r2,r3,#240
+vshl.i64 q7,q7,#25
+add r4,r3,#144
+vadd.i64 q15,q1,q11
+add r2,r2,#8
+vsub.i64 q2,q2,q13
+add r4,r4,#8
+vshr.s64 q13,q14,#25
+vsub.i64 q7,q8,q7
+vshr.s64 q8,q15,#26
+vadd.i64 q14,q13,q13
+vadd.i64 q12,q12,q8
+vtrn.32 d12,d14
+vshl.i64 q8,q8,#26
+vtrn.32 d13,d15
+vadd.i64 q3,q12,q3
+vadd.i64 q0,q0,q14
+vst1.8 d12,[r2,: 64]!
+vshl.i64 q7,q13,#4
+vst1.8 d13,[r4,: 64]!
+vsub.i64 q1,q1,q8
+vshr.s64 q3,q3,#25
+vadd.i64 q0,q0,q7
+vadd.i64 q5,q5,q3
+vshl.i64 q3,q3,#25
+vadd.i64 q6,q5,q11
+vadd.i64 q0,q0,q13
+vshl.i64 q7,q13,#25
+vadd.i64 q8,q0,q11
+vsub.i64 q3,q12,q3
+vshr.s64 q6,q6,#26
+vsub.i64 q7,q10,q7
+vtrn.32 d2,d6
+vshr.s64 q8,q8,#26
+vtrn.32 d3,d7
+vadd.i64 q3,q9,q6
+vst1.8 d2,[r2,: 64]
+vshl.i64 q6,q6,#26
+vst1.8 d3,[r4,: 64]
+vadd.i64 q1,q4,q8
+vtrn.32 d4,d14
+vshl.i64 q4,q8,#26
+vtrn.32 d5,d15
+vsub.i64 q5,q5,q6
+add r2,r2,#16
+vsub.i64 q0,q0,q4
+vst1.8 d4,[r2,: 64]
+add r4,r4,#16
+vst1.8 d5,[r4,: 64]
+vtrn.32 d10,d6
+vtrn.32 d11,d7
+sub r2,r2,#8
+sub r4,r4,#8
+vtrn.32 d0,d2
+vtrn.32 d1,d3
+vst1.8 d10,[r2,: 64]
+vst1.8 d11,[r4,: 64]
+sub r2,r2,#24
+sub r4,r4,#24
+vst1.8 d0,[r2,: 64]
+vst1.8 d1,[r4,: 64]
+ldr r2,[sp,#488]
+ldr r4,[sp,#492]
+subs r5,r2,#1
+bge ._mainloop
+add r1,r3,#144
+add r2,r3,#336
+vld1.8 {d0-d1},[r1,: 128]!
+vld1.8 {d2-d3},[r1,: 128]!
+vld1.8 {d4},[r1,: 64]
+vst1.8 {d0-d1},[r2,: 128]!
+vst1.8 {d2-d3},[r2,: 128]!
+vst1.8 d4,[r2,: 64]
+ldr r1,=0
+._invertloop:
+add r2,r3,#144
+ldr r4,=0
+ldr r5,=2
+cmp r1,#1
+ldreq r5,=1
+addeq r2,r3,#336
+addeq r4,r3,#48
+cmp r1,#2
+ldreq r5,=1
+addeq r2,r3,#48
+cmp r1,#3
+ldreq r5,=5
+addeq r4,r3,#336
+cmp r1,#4
+ldreq r5,=10
+cmp r1,#5
+ldreq r5,=20
+cmp r1,#6
+ldreq r5,=10
+addeq r2,r3,#336
+addeq r4,r3,#336
+cmp r1,#7
+ldreq r5,=50
+cmp r1,#8
+ldreq r5,=100
+cmp r1,#9
+ldreq r5,=50
+addeq r2,r3,#336
+cmp r1,#10
+ldreq r5,=5
+addeq r2,r3,#48
+cmp r1,#11
+ldreq r5,=0
+addeq r2,r3,#96
+add r6,r3,#144
+add r7,r3,#288
+vld1.8 {d0-d1},[r6,: 128]!
+vld1.8 {d2-d3},[r6,: 128]!
+vld1.8 {d4},[r6,: 64]
+vst1.8 {d0-d1},[r7,: 128]!
+vst1.8 {d2-d3},[r7,: 128]!
+vst1.8 d4,[r7,: 64]
+cmp r5,#0
+beq ._skipsquaringloop
+._squaringloop:
+add r6,r3,#288
+add r7,r3,#288
+add r8,r3,#288
+vmov.i32 q0,#19
+vmov.i32 q1,#0
+vmov.i32 q2,#1
+vzip.i32 q1,q2
+vld1.8 {d4-d5},[r7,: 128]!
+vld1.8 {d6-d7},[r7,: 128]!
+vld1.8 {d9},[r7,: 64]
+vld1.8 {d10-d11},[r6,: 128]!
+add r7,sp,#416
+vld1.8 {d12-d13},[r6,: 128]!
+vmul.i32 q7,q2,q0
+vld1.8 {d8},[r6,: 64]
+vext.32 d17,d11,d10,#1
+vmul.i32 q9,q3,q0
+vext.32 d16,d10,d8,#1
+vshl.u32 q10,q5,q1
+vext.32 d22,d14,d4,#1
+vext.32 d24,d18,d6,#1
+vshl.u32 q13,q6,q1
+vshl.u32 d28,d8,d2
+vrev64.i32 d22,d22
+vmul.i32 d1,d9,d1
+vrev64.i32 d24,d24
+vext.32 d29,d8,d13,#1
+vext.32 d0,d1,d9,#1
+vrev64.i32 d0,d0
+vext.32 d2,d9,d1,#1
+vext.32 d23,d15,d5,#1
+vmull.s32 q4,d20,d4
+vrev64.i32 d23,d23
+vmlal.s32 q4,d21,d1
+vrev64.i32 d2,d2
+vmlal.s32 q4,d26,d19
+vext.32 d3,d5,d15,#1
+vmlal.s32 q4,d27,d18
+vrev64.i32 d3,d3
+vmlal.s32 q4,d28,d15
+vext.32 d14,d12,d11,#1
+vmull.s32 q5,d16,d23
+vext.32 d15,d13,d12,#1
+vmlal.s32 q5,d17,d4
+vst1.8 d8,[r7,: 64]!
+vmlal.s32 q5,d14,d1
+vext.32 d12,d9,d8,#0
+vmlal.s32 q5,d15,d19
+vmov.i64 d13,#0
+vmlal.s32 q5,d29,d18
+vext.32 d25,d19,d7,#1
+vmlal.s32 q6,d20,d5
+vrev64.i32 d25,d25
+vmlal.s32 q6,d21,d4
+vst1.8 d11,[r7,: 64]!
+vmlal.s32 q6,d26,d1
+vext.32 d9,d10,d10,#0
+vmlal.s32 q6,d27,d19
+vmov.i64 d8,#0
+vmlal.s32 q6,d28,d18
+vmlal.s32 q4,d16,d24
+vmlal.s32 q4,d17,d5
+vmlal.s32 q4,d14,d4
+vst1.8 d12,[r7,: 64]!
+vmlal.s32 q4,d15,d1
+vext.32 d10,d13,d12,#0
+vmlal.s32 q4,d29,d19
+vmov.i64 d11,#0
+vmlal.s32 q5,d20,d6
+vmlal.s32 q5,d21,d5
+vmlal.s32 q5,d26,d4
+vext.32 d13,d8,d8,#0
+vmlal.s32 q5,d27,d1
+vmov.i64 d12,#0
+vmlal.s32 q5,d28,d19
+vst1.8 d9,[r7,: 64]!
+vmlal.s32 q6,d16,d25
+vmlal.s32 q6,d17,d6
+vst1.8 d10,[r7,: 64]
+vmlal.s32 q6,d14,d5
+vext.32 d8,d11,d10,#0
+vmlal.s32 q6,d15,d4
+vmov.i64 d9,#0
+vmlal.s32 q6,d29,d1
+vmlal.s32 q4,d20,d7
+vmlal.s32 q4,d21,d6
+vmlal.s32 q4,d26,d5
+vext.32 d11,d12,d12,#0
+vmlal.s32 q4,d27,d4
+vmov.i64 d10,#0
+vmlal.s32 q4,d28,d1
+vmlal.s32 q5,d16,d0
+sub r6,r7,#32
+vmlal.s32 q5,d17,d7
+vmlal.s32 q5,d14,d6
+vext.32 d30,d9,d8,#0
+vmlal.s32 q5,d15,d5
+vld1.8 {d31},[r6,: 64]!
+vmlal.s32 q5,d29,d4
+vmlal.s32 q15,d20,d0
+vext.32 d0,d6,d18,#1
+vmlal.s32 q15,d21,d25
+vrev64.i32 d0,d0
+vmlal.s32 q15,d26,d24
+vext.32 d1,d7,d19,#1
+vext.32 d7,d10,d10,#0
+vmlal.s32 q15,d27,d23
+vrev64.i32 d1,d1
+vld1.8 {d6},[r6,: 64]
+vmlal.s32 q15,d28,d22
+vmlal.s32 q3,d16,d4
+add r6,r6,#24
+vmlal.s32 q3,d17,d2
+vext.32 d4,d31,d30,#0
+vmov d17,d11
+vmlal.s32 q3,d14,d1
+vext.32 d11,d13,d13,#0
+vext.32 d13,d30,d30,#0
+vmlal.s32 q3,d15,d0
+vext.32 d1,d8,d8,#0
+vmlal.s32 q3,d29,d3
+vld1.8 {d5},[r6,: 64]
+sub r6,r6,#16
+vext.32 d10,d6,d6,#0
+vmov.i32 q1,#0xffffffff
+vshl.i64 q4,q1,#25
+add r7,sp,#512
+vld1.8 {d14-d15},[r7,: 128]
+vadd.i64 q9,q2,q7
+vshl.i64 q1,q1,#26
+vshr.s64 q10,q9,#26
+vld1.8 {d0},[r6,: 64]!
+vadd.i64 q5,q5,q10
+vand q9,q9,q1
+vld1.8 {d16},[r6,: 64]!
+add r6,sp,#528
+vld1.8 {d20-d21},[r6,: 128]
+vadd.i64 q11,q5,q10
+vsub.i64 q2,q2,q9
+vshr.s64 q9,q11,#25
+vext.32 d12,d5,d4,#0
+vand q11,q11,q4
+vadd.i64 q0,q0,q9
+vmov d19,d7
+vadd.i64 q3,q0,q7
+vsub.i64 q5,q5,q11
+vshr.s64 q11,q3,#26
+vext.32 d18,d11,d10,#0
+vand q3,q3,q1
+vadd.i64 q8,q8,q11
+vadd.i64 q11,q8,q10
+vsub.i64 q0,q0,q3
+vshr.s64 q3,q11,#25
+vand q11,q11,q4
+vadd.i64 q3,q6,q3
+vadd.i64 q6,q3,q7
+vsub.i64 q8,q8,q11
+vshr.s64 q11,q6,#26
+vand q6,q6,q1
+vadd.i64 q9,q9,q11
+vadd.i64 d25,d19,d21
+vsub.i64 q3,q3,q6
+vshr.s64 d23,d25,#25
+vand q4,q12,q4
+vadd.i64 d21,d23,d23
+vshl.i64 d25,d23,#4
+vadd.i64 d21,d21,d23
+vadd.i64 d25,d25,d21
+vadd.i64 d4,d4,d25
+vzip.i32 q0,q8
+vadd.i64 d12,d4,d14
+add r6,r8,#8
+vst1.8 d0,[r6,: 64]
+vsub.i64 d19,d19,d9
+add r6,r6,#16
+vst1.8 d16,[r6,: 64]
+vshr.s64 d22,d12,#26
+vand q0,q6,q1
+vadd.i64 d10,d10,d22
+vzip.i32 q3,q9
+vsub.i64 d4,d4,d0
+sub r6,r6,#8
+vst1.8 d6,[r6,: 64]
+add r6,r6,#16
+vst1.8 d18,[r6,: 64]
+vzip.i32 q2,q5
+sub r6,r6,#32
+vst1.8 d4,[r6,: 64]
+subs r5,r5,#1
+bhi ._squaringloop
+._skipsquaringloop:
+mov r2,r2
+add r5,r3,#288
+add r6,r3,#144
+vmov.i32 q0,#19
+vmov.i32 q1,#0
+vmov.i32 q2,#1
+vzip.i32 q1,q2
+vld1.8 {d4-d5},[r5,: 128]!
+vld1.8 {d6-d7},[r5,: 128]!
+vld1.8 {d9},[r5,: 64]
+vld1.8 {d10-d11},[r2,: 128]!
+add r5,sp,#416
+vld1.8 {d12-d13},[r2,: 128]!
+vmul.i32 q7,q2,q0
+vld1.8 {d8},[r2,: 64]
+vext.32 d17,d11,d10,#1
+vmul.i32 q9,q3,q0
+vext.32 d16,d10,d8,#1
+vshl.u32 q10,q5,q1
+vext.32 d22,d14,d4,#1
+vext.32 d24,d18,d6,#1
+vshl.u32 q13,q6,q1
+vshl.u32 d28,d8,d2
+vrev64.i32 d22,d22
+vmul.i32 d1,d9,d1
+vrev64.i32 d24,d24
+vext.32 d29,d8,d13,#1
+vext.32 d0,d1,d9,#1
+vrev64.i32 d0,d0
+vext.32 d2,d9,d1,#1
+vext.32 d23,d15,d5,#1
+vmull.s32 q4,d20,d4
+vrev64.i32 d23,d23
+vmlal.s32 q4,d21,d1
+vrev64.i32 d2,d2
+vmlal.s32 q4,d26,d19
+vext.32 d3,d5,d15,#1
+vmlal.s32 q4,d27,d18
+vrev64.i32 d3,d3
+vmlal.s32 q4,d28,d15
+vext.32 d14,d12,d11,#1
+vmull.s32 q5,d16,d23
+vext.32 d15,d13,d12,#1
+vmlal.s32 q5,d17,d4
+vst1.8 d8,[r5,: 64]!
+vmlal.s32 q5,d14,d1
+vext.32 d12,d9,d8,#0
+vmlal.s32 q5,d15,d19
+vmov.i64 d13,#0
+vmlal.s32 q5,d29,d18
+vext.32 d25,d19,d7,#1
+vmlal.s32 q6,d20,d5
+vrev64.i32 d25,d25
+vmlal.s32 q6,d21,d4
+vst1.8 d11,[r5,: 64]!
+vmlal.s32 q6,d26,d1
+vext.32 d9,d10,d10,#0
+vmlal.s32 q6,d27,d19
+vmov.i64 d8,#0
+vmlal.s32 q6,d28,d18
+vmlal.s32 q4,d16,d24
+vmlal.s32 q4,d17,d5
+vmlal.s32 q4,d14,d4
+vst1.8 d12,[r5,: 64]!
+vmlal.s32 q4,d15,d1
+vext.32 d10,d13,d12,#0
+vmlal.s32 q4,d29,d19
+vmov.i64 d11,#0
+vmlal.s32 q5,d20,d6
+vmlal.s32 q5,d21,d5
+vmlal.s32 q5,d26,d4
+vext.32 d13,d8,d8,#0
+vmlal.s32 q5,d27,d1
+vmov.i64 d12,#0
+vmlal.s32 q5,d28,d19
+vst1.8 d9,[r5,: 64]!
+vmlal.s32 q6,d16,d25
+vmlal.s32 q6,d17,d6
+vst1.8 d10,[r5,: 64]
+vmlal.s32 q6,d14,d5
+vext.32 d8,d11,d10,#0
+vmlal.s32 q6,d15,d4
+vmov.i64 d9,#0
+vmlal.s32 q6,d29,d1
+vmlal.s32 q4,d20,d7
+vmlal.s32 q4,d21,d6
+vmlal.s32 q4,d26,d5
+vext.32 d11,d12,d12,#0
+vmlal.s32 q4,d27,d4
+vmov.i64 d10,#0
+vmlal.s32 q4,d28,d1
+vmlal.s32 q5,d16,d0
+sub r2,r5,#32
+vmlal.s32 q5,d17,d7
+vmlal.s32 q5,d14,d6
+vext.32 d30,d9,d8,#0
+vmlal.s32 q5,d15,d5
+vld1.8 {d31},[r2,: 64]!
+vmlal.s32 q5,d29,d4
+vmlal.s32 q15,d20,d0
+vext.32 d0,d6,d18,#1
+vmlal.s32 q15,d21,d25
+vrev64.i32 d0,d0
+vmlal.s32 q15,d26,d24
+vext.32 d1,d7,d19,#1
+vext.32 d7,d10,d10,#0
+vmlal.s32 q15,d27,d23
+vrev64.i32 d1,d1
+vld1.8 {d6},[r2,: 64]
+vmlal.s32 q15,d28,d22
+vmlal.s32 q3,d16,d4
+add r2,r2,#24
+vmlal.s32 q3,d17,d2
+vext.32 d4,d31,d30,#0
+vmov d17,d11
+vmlal.s32 q3,d14,d1
+vext.32 d11,d13,d13,#0
+vext.32 d13,d30,d30,#0
+vmlal.s32 q3,d15,d0
+vext.32 d1,d8,d8,#0
+vmlal.s32 q3,d29,d3
+vld1.8 {d5},[r2,: 64]
+sub r2,r2,#16
+vext.32 d10,d6,d6,#0
+vmov.i32 q1,#0xffffffff
+vshl.i64 q4,q1,#25
+add r5,sp,#512
+vld1.8 {d14-d15},[r5,: 128]
+vadd.i64 q9,q2,q7
+vshl.i64 q1,q1,#26
+vshr.s64 q10,q9,#26
+vld1.8 {d0},[r2,: 64]!
+vadd.i64 q5,q5,q10
+vand q9,q9,q1
+vld1.8 {d16},[r2,: 64]!
+add r2,sp,#528
+vld1.8 {d20-d21},[r2,: 128]
+vadd.i64 q11,q5,q10
+vsub.i64 q2,q2,q9
+vshr.s64 q9,q11,#25
+vext.32 d12,d5,d4,#0
+vand q11,q11,q4
+vadd.i64 q0,q0,q9
+vmov d19,d7
+vadd.i64 q3,q0,q7
+vsub.i64 q5,q5,q11
+vshr.s64 q11,q3,#26
+vext.32 d18,d11,d10,#0
+vand q3,q3,q1
+vadd.i64 q8,q8,q11
+vadd.i64 q11,q8,q10
+vsub.i64 q0,q0,q3
+vshr.s64 q3,q11,#25
+vand q11,q11,q4
+vadd.i64 q3,q6,q3
+vadd.i64 q6,q3,q7
+vsub.i64 q8,q8,q11
+vshr.s64 q11,q6,#26
+vand q6,q6,q1
+vadd.i64 q9,q9,q11
+vadd.i64 d25,d19,d21
+vsub.i64 q3,q3,q6
+vshr.s64 d23,d25,#25
+vand q4,q12,q4
+vadd.i64 d21,d23,d23
+vshl.i64 d25,d23,#4
+vadd.i64 d21,d21,d23
+vadd.i64 d25,d25,d21
+vadd.i64 d4,d4,d25
+vzip.i32 q0,q8
+vadd.i64 d12,d4,d14
+add r2,r6,#8
+vst1.8 d0,[r2,: 64]
+vsub.i64 d19,d19,d9
+add r2,r2,#16
+vst1.8 d16,[r2,: 64]
+vshr.s64 d22,d12,#26
+vand q0,q6,q1
+vadd.i64 d10,d10,d22
+vzip.i32 q3,q9
+vsub.i64 d4,d4,d0
+sub r2,r2,#8
+vst1.8 d6,[r2,: 64]
+add r2,r2,#16
+vst1.8 d18,[r2,: 64]
+vzip.i32 q2,q5
+sub r2,r2,#32
+vst1.8 d4,[r2,: 64]
+cmp r4,#0
+beq ._skippostcopy
+add r2,r3,#144
+mov r4,r4
+vld1.8 {d0-d1},[r2,: 128]!
+vld1.8 {d2-d3},[r2,: 128]!
+vld1.8 {d4},[r2,: 64]
+vst1.8 {d0-d1},[r4,: 128]!
+vst1.8 {d2-d3},[r4,: 128]!
+vst1.8 d4,[r4,: 64]
+._skippostcopy:
+cmp r1,#1
+bne ._skipfinalcopy
+add r2,r3,#288
+add r4,r3,#144
+vld1.8 {d0-d1},[r2,: 128]!
+vld1.8 {d2-d3},[r2,: 128]!
+vld1.8 {d4},[r2,: 64]
+vst1.8 {d0-d1},[r4,: 128]!
+vst1.8 {d2-d3},[r4,: 128]!
+vst1.8 d4,[r4,: 64]
+._skipfinalcopy:
+add r1,r1,#1
+cmp r1,#12
+blo ._invertloop
+add r1,r3,#144
+ldr r2,[r1],#4
+ldr r3,[r1],#4
+ldr r4,[r1],#4
+ldr r5,[r1],#4
+ldr r6,[r1],#4
+ldr r7,[r1],#4
+ldr r8,[r1],#4
+ldr r9,[r1],#4
+ldr r10,[r1],#4
+ldr r1,[r1]
+add r11,r1,r1,LSL #4
+add r11,r11,r1,LSL #1
+add r11,r11,#16777216
+mov r11,r11,ASR #25
+add r11,r11,r2
+mov r11,r11,ASR #26
+add r11,r11,r3
+mov r11,r11,ASR #25
+add r11,r11,r4
+mov r11,r11,ASR #26
+add r11,r11,r5
+mov r11,r11,ASR #25
+add r11,r11,r6
+mov r11,r11,ASR #26
+add r11,r11,r7
+mov r11,r11,ASR #25
+add r11,r11,r8
+mov r11,r11,ASR #26
+add r11,r11,r9
+mov r11,r11,ASR #25
+add r11,r11,r10
+mov r11,r11,ASR #26
+add r11,r11,r1
+mov r11,r11,ASR #25
+add r2,r2,r11
+add r2,r2,r11,LSL #1
+add r2,r2,r11,LSL #4
+mov r11,r2,ASR #26
+add r3,r3,r11
+sub r2,r2,r11,LSL #26
+mov r11,r3,ASR #25
+add r4,r4,r11
+sub r3,r3,r11,LSL #25
+mov r11,r4,ASR #26
+add r5,r5,r11
+sub r4,r4,r11,LSL #26
+mov r11,r5,ASR #25
+add r6,r6,r11
+sub r5,r5,r11,LSL #25
+mov r11,r6,ASR #26
+add r7,r7,r11
+sub r6,r6,r11,LSL #26
+mov r11,r7,ASR #25
+add r8,r8,r11
+sub r7,r7,r11,LSL #25
+mov r11,r8,ASR #26
+add r9,r9,r11
+sub r8,r8,r11,LSL #26
+mov r11,r9,ASR #25
+add r10,r10,r11
+sub r9,r9,r11,LSL #25
+mov r11,r10,ASR #26
+add r1,r1,r11
+sub r10,r10,r11,LSL #26
+mov r11,r1,ASR #25
+sub r1,r1,r11,LSL #25
+add r2,r2,r3,LSL #26
+mov r3,r3,LSR #6
+add r3,r3,r4,LSL #19
+mov r4,r4,LSR #13
+add r4,r4,r5,LSL #13
+mov r5,r5,LSR #19
+add r5,r5,r6,LSL #6
+add r6,r7,r8,LSL #25
+mov r7,r8,LSR #7
+add r7,r7,r9,LSL #19
+mov r8,r9,LSR #13
+add r8,r8,r10,LSL #12
+mov r9,r10,LSR #20
+add r1,r9,r1,LSL #6
+str r2,[r0],#4
+str r3,[r0],#4
+str r4,[r0],#4
+str r5,[r0],#4
+str r6,[r0],#4
+str r7,[r0],#4
+str r8,[r0],#4
+str r1,[r0]
+ldrd r4,[sp,#0]
+ldrd r6,[sp,#8]
+ldrd r8,[sp,#16]
+ldrd r10,[sp,#24]
+ldr r12,[sp,#480]
+ldr r14,[sp,#484]
+ldr r0,=0
+mov sp,r12
+vpop {q4,q5,q6,q7}
+bx lr
diff --git a/src/crypto/curve25519/asm/x25519-asm-x86_64.S b/src/crypto/curve25519/asm/x25519-asm-x86_64.S
new file mode 100644
index 0000000..7e86a23
--- /dev/null
+++ b/src/crypto/curve25519/asm/x25519-asm-x86_64.S
@@ -0,0 +1,1931 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+/* This file is adapted from crypto_scalarmult/curve25519/amd64-51/ in
+ * SUPERCOP 20141124 (http://bench.cr.yp.to/supercop.html). That code is public
+ * domain licensed but the standard ISC license is included above to keep
+ * licensing simple. */
+
+.data
+.p2align 4
+
+#if defined(__APPLE__)
+/* OS X's C ABI prefixes functions with underscore. */
+#define C_ABI(x) _ ## x
+#define HIDDEN .private_extern
+#else
+#define C_ABI(x) x
+#define HIDDEN .hidden
+#endif
+
+x25519_x86_64_REDMASK51: .quad 0x0007FFFFFFFFFFFF
+x25519_x86_64_121666_213: .quad 996687872
+x25519_x86_64_2P0: .quad 0xFFFFFFFFFFFDA
+x25519_x86_64_2P1234: .quad 0xFFFFFFFFFFFFE
+x25519_x86_64_4P0: .quad 0x1FFFFFFFFFFFB4
+x25519_x86_64_4P1234: .quad 0x1FFFFFFFFFFFFC
+x25519_x86_64_MU0: .quad 0xED9CE5A30A2C131B
+x25519_x86_64_MU1: .quad 0x2106215D086329A7
+x25519_x86_64_MU2: .quad 0xFFFFFFFFFFFFFFEB
+x25519_x86_64_MU3: .quad 0xFFFFFFFFFFFFFFFF
+x25519_x86_64_MU4: .quad 0x000000000000000F
+x25519_x86_64_ORDER0: .quad 0x5812631A5CF5D3ED
+x25519_x86_64_ORDER1: .quad 0x14DEF9DEA2F79CD6
+x25519_x86_64_ORDER2: .quad 0x0000000000000000
+x25519_x86_64_ORDER3: .quad 0x1000000000000000
+x25519_x86_64_EC2D0: .quad 1859910466990425
+x25519_x86_64_EC2D1: .quad 932731440258426
+x25519_x86_64_EC2D2: .quad 1072319116312658
+x25519_x86_64_EC2D3: .quad 1815898335770999
+x25519_x86_64_EC2D4: .quad 633789495995903
+x25519_x86_64__38: .quad 38
+
+.text
+.p2align 5
+
+.globl C_ABI(x25519_x86_64_freeze)
+HIDDEN C_ABI(x25519_x86_64_freeze)
+C_ABI(x25519_x86_64_freeze):
+mov %rsp,%r11
+and $31,%r11
+add $64,%r11
+sub %r11,%rsp
+movq %r11,0(%rsp)
+movq %r12,8(%rsp)
+movq %r13,16(%rsp)
+movq %r14,24(%rsp)
+movq %r15,32(%rsp)
+movq %rbx,40(%rsp)
+movq %rbp,48(%rsp)
+movq 0(%rdi),%rsi
+movq 8(%rdi),%rdx
+movq 16(%rdi),%rcx
+movq 24(%rdi),%r8
+movq 32(%rdi),%r9
+movq x25519_x86_64_REDMASK51(%rip),%rax
+mov %rax,%r10
+sub $18,%r10
+mov $3,%r11
+._reduceloop:
+mov %rsi,%r12
+shr $51,%r12
+and %rax,%rsi
+add %r12,%rdx
+mov %rdx,%r12
+shr $51,%r12
+and %rax,%rdx
+add %r12,%rcx
+mov %rcx,%r12
+shr $51,%r12
+and %rax,%rcx
+add %r12,%r8
+mov %r8,%r12
+shr $51,%r12
+and %rax,%r8
+add %r12,%r9
+mov %r9,%r12
+shr $51,%r12
+and %rax,%r9
+imulq $19,%r12,%r12
+add %r12,%rsi
+sub $1,%r11
+ja ._reduceloop
+mov $1,%r12
+cmp %r10,%rsi
+cmovl %r11,%r12
+cmp %rax,%rdx
+cmovne %r11,%r12
+cmp %rax,%rcx
+cmovne %r11,%r12
+cmp %rax,%r8
+cmovne %r11,%r12
+cmp %rax,%r9
+cmovne %r11,%r12
+neg %r12
+and %r12,%rax
+and %r12,%r10
+sub %r10,%rsi
+sub %rax,%rdx
+sub %rax,%rcx
+sub %rax,%r8
+sub %rax,%r9
+movq %rsi,0(%rdi)
+movq %rdx,8(%rdi)
+movq %rcx,16(%rdi)
+movq %r8,24(%rdi)
+movq %r9,32(%rdi)
+movq 0(%rsp),%r11
+movq 8(%rsp),%r12
+movq 16(%rsp),%r13
+movq 24(%rsp),%r14
+movq 32(%rsp),%r15
+movq 40(%rsp),%rbx
+movq 48(%rsp),%rbp
+add %r11,%rsp
+mov %rdi,%rax
+mov %rsi,%rdx
+ret
+
+.p2align 5
+.globl C_ABI(x25519_x86_64_mul)
+HIDDEN C_ABI(x25519_x86_64_mul)
+C_ABI(x25519_x86_64_mul):
+mov %rsp,%r11
+and $31,%r11
+add $96,%r11
+sub %r11,%rsp
+movq %r11,0(%rsp)
+movq %r12,8(%rsp)
+movq %r13,16(%rsp)
+movq %r14,24(%rsp)
+movq %r15,32(%rsp)
+movq %rbx,40(%rsp)
+movq %rbp,48(%rsp)
+movq %rdi,56(%rsp)
+mov %rdx,%rcx
+movq 24(%rsi),%rdx
+imulq $19,%rdx,%rax
+movq %rax,64(%rsp)
+mulq 16(%rcx)
+mov %rax,%r8
+mov %rdx,%r9
+movq 32(%rsi),%rdx
+imulq $19,%rdx,%rax
+movq %rax,72(%rsp)
+mulq 8(%rcx)
+add %rax,%r8
+adc %rdx,%r9
+movq 0(%rsi),%rax
+mulq 0(%rcx)
+add %rax,%r8
+adc %rdx,%r9
+movq 0(%rsi),%rax
+mulq 8(%rcx)
+mov %rax,%r10
+mov %rdx,%r11
+movq 0(%rsi),%rax
+mulq 16(%rcx)
+mov %rax,%r12
+mov %rdx,%r13
+movq 0(%rsi),%rax
+mulq 24(%rcx)
+mov %rax,%r14
+mov %rdx,%r15
+movq 0(%rsi),%rax
+mulq 32(%rcx)
+mov %rax,%rbx
+mov %rdx,%rbp
+movq 8(%rsi),%rax
+mulq 0(%rcx)
+add %rax,%r10
+adc %rdx,%r11
+movq 8(%rsi),%rax
+mulq 8(%rcx)
+add %rax,%r12
+adc %rdx,%r13
+movq 8(%rsi),%rax
+mulq 16(%rcx)
+add %rax,%r14
+adc %rdx,%r15
+movq 8(%rsi),%rax
+mulq 24(%rcx)
+add %rax,%rbx
+adc %rdx,%rbp
+movq 8(%rsi),%rdx
+imulq $19,%rdx,%rax
+mulq 32(%rcx)
+add %rax,%r8
+adc %rdx,%r9
+movq 16(%rsi),%rax
+mulq 0(%rcx)
+add %rax,%r12
+adc %rdx,%r13
+movq 16(%rsi),%rax
+mulq 8(%rcx)
+add %rax,%r14
+adc %rdx,%r15
+movq 16(%rsi),%rax
+mulq 16(%rcx)
+add %rax,%rbx
+adc %rdx,%rbp
+movq 16(%rsi),%rdx
+imulq $19,%rdx,%rax
+mulq 24(%rcx)
+add %rax,%r8
+adc %rdx,%r9
+movq 16(%rsi),%rdx
+imulq $19,%rdx,%rax
+mulq 32(%rcx)
+add %rax,%r10
+adc %rdx,%r11
+movq 24(%rsi),%rax
+mulq 0(%rcx)
+add %rax,%r14
+adc %rdx,%r15
+movq 24(%rsi),%rax
+mulq 8(%rcx)
+add %rax,%rbx
+adc %rdx,%rbp
+movq 64(%rsp),%rax
+mulq 24(%rcx)
+add %rax,%r10
+adc %rdx,%r11
+movq 64(%rsp),%rax
+mulq 32(%rcx)
+add %rax,%r12
+adc %rdx,%r13
+movq 32(%rsi),%rax
+mulq 0(%rcx)
+add %rax,%rbx
+adc %rdx,%rbp
+movq 72(%rsp),%rax
+mulq 16(%rcx)
+add %rax,%r10
+adc %rdx,%r11
+movq 72(%rsp),%rax
+mulq 24(%rcx)
+add %rax,%r12
+adc %rdx,%r13
+movq 72(%rsp),%rax
+mulq 32(%rcx)
+add %rax,%r14
+adc %rdx,%r15
+movq x25519_x86_64_REDMASK51(%rip),%rsi
+shld $13,%r8,%r9
+and %rsi,%r8
+shld $13,%r10,%r11
+and %rsi,%r10
+add %r9,%r10
+shld $13,%r12,%r13
+and %rsi,%r12
+add %r11,%r12
+shld $13,%r14,%r15
+and %rsi,%r14
+add %r13,%r14
+shld $13,%rbx,%rbp
+and %rsi,%rbx
+add %r15,%rbx
+imulq $19,%rbp,%rdx
+add %rdx,%r8
+mov %r8,%rdx
+shr $51,%rdx
+add %r10,%rdx
+mov %rdx,%rcx
+shr $51,%rdx
+and %rsi,%r8
+add %r12,%rdx
+mov %rdx,%r9
+shr $51,%rdx
+and %rsi,%rcx
+add %r14,%rdx
+mov %rdx,%rax
+shr $51,%rdx
+and %rsi,%r9
+add %rbx,%rdx
+mov %rdx,%r10
+shr $51,%rdx
+and %rsi,%rax
+imulq $19,%rdx,%rdx
+add %rdx,%r8
+and %rsi,%r10
+movq %r8,0(%rdi)
+movq %rcx,8(%rdi)
+movq %r9,16(%rdi)
+movq %rax,24(%rdi)
+movq %r10,32(%rdi)
+movq 0(%rsp),%r11
+movq 8(%rsp),%r12
+movq 16(%rsp),%r13
+movq 24(%rsp),%r14
+movq 32(%rsp),%r15
+movq 40(%rsp),%rbx
+movq 48(%rsp),%rbp
+add %r11,%rsp
+mov %rdi,%rax
+mov %rsi,%rdx
+ret
+
+.p2align 5
+.globl C_ABI(x25519_x86_64_square)
+HIDDEN C_ABI(x25519_x86_64_square)
+C_ABI(x25519_x86_64_square):
+mov %rsp,%r11
+and $31,%r11
+add $64,%r11
+sub %r11,%rsp
+movq %r11,0(%rsp)
+movq %r12,8(%rsp)
+movq %r13,16(%rsp)
+movq %r14,24(%rsp)
+movq %r15,32(%rsp)
+movq %rbx,40(%rsp)
+movq %rbp,48(%rsp)
+movq 0(%rsi),%rax
+mulq 0(%rsi)
+mov %rax,%rcx
+mov %rdx,%r8
+movq 0(%rsi),%rax
+shl $1,%rax
+mulq 8(%rsi)
+mov %rax,%r9
+mov %rdx,%r10
+movq 0(%rsi),%rax
+shl $1,%rax
+mulq 16(%rsi)
+mov %rax,%r11
+mov %rdx,%r12
+movq 0(%rsi),%rax
+shl $1,%rax
+mulq 24(%rsi)
+mov %rax,%r13
+mov %rdx,%r14
+movq 0(%rsi),%rax
+shl $1,%rax
+mulq 32(%rsi)
+mov %rax,%r15
+mov %rdx,%rbx
+movq 8(%rsi),%rax
+mulq 8(%rsi)
+add %rax,%r11
+adc %rdx,%r12
+movq 8(%rsi),%rax
+shl $1,%rax
+mulq 16(%rsi)
+add %rax,%r13
+adc %rdx,%r14
+movq 8(%rsi),%rax
+shl $1,%rax
+mulq 24(%rsi)
+add %rax,%r15
+adc %rdx,%rbx
+movq 8(%rsi),%rdx
+imulq $38,%rdx,%rax
+mulq 32(%rsi)
+add %rax,%rcx
+adc %rdx,%r8
+movq 16(%rsi),%rax
+mulq 16(%rsi)
+add %rax,%r15
+adc %rdx,%rbx
+movq 16(%rsi),%rdx
+imulq $38,%rdx,%rax
+mulq 24(%rsi)
+add %rax,%rcx
+adc %rdx,%r8
+movq 16(%rsi),%rdx
+imulq $38,%rdx,%rax
+mulq 32(%rsi)
+add %rax,%r9
+adc %rdx,%r10
+movq 24(%rsi),%rdx
+imulq $19,%rdx,%rax
+mulq 24(%rsi)
+add %rax,%r9
+adc %rdx,%r10
+movq 24(%rsi),%rdx
+imulq $38,%rdx,%rax
+mulq 32(%rsi)
+add %rax,%r11
+adc %rdx,%r12
+movq 32(%rsi),%rdx
+imulq $19,%rdx,%rax
+mulq 32(%rsi)
+add %rax,%r13
+adc %rdx,%r14
+movq x25519_x86_64_REDMASK51(%rip),%rsi
+shld $13,%rcx,%r8
+and %rsi,%rcx
+shld $13,%r9,%r10
+and %rsi,%r9
+add %r8,%r9
+shld $13,%r11,%r12
+and %rsi,%r11
+add %r10,%r11
+shld $13,%r13,%r14
+and %rsi,%r13
+add %r12,%r13
+shld $13,%r15,%rbx
+and %rsi,%r15
+add %r14,%r15
+imulq $19,%rbx,%rdx
+add %rdx,%rcx
+mov %rcx,%rdx
+shr $51,%rdx
+add %r9,%rdx
+and %rsi,%rcx
+mov %rdx,%r8
+shr $51,%rdx
+add %r11,%rdx
+and %rsi,%r8
+mov %rdx,%r9
+shr $51,%rdx
+add %r13,%rdx
+and %rsi,%r9
+mov %rdx,%rax
+shr $51,%rdx
+add %r15,%rdx
+and %rsi,%rax
+mov %rdx,%r10
+shr $51,%rdx
+imulq $19,%rdx,%rdx
+add %rdx,%rcx
+and %rsi,%r10
+movq %rcx,0(%rdi)
+movq %r8,8(%rdi)
+movq %r9,16(%rdi)
+movq %rax,24(%rdi)
+movq %r10,32(%rdi)
+movq 0(%rsp),%r11
+movq 8(%rsp),%r12
+movq 16(%rsp),%r13
+movq 24(%rsp),%r14
+movq 32(%rsp),%r15
+movq 40(%rsp),%rbx
+movq 48(%rsp),%rbp
+add %r11,%rsp
+mov %rdi,%rax
+mov %rsi,%rdx
+ret
+
+.p2align 5
+.globl C_ABI(x25519_x86_64_ladderstep)
+HIDDEN C_ABI(x25519_x86_64_ladderstep)
+C_ABI(x25519_x86_64_ladderstep):
+mov %rsp,%r11
+and $31,%r11
+add $352,%r11
+sub %r11,%rsp
+movq %r11,0(%rsp)
+movq %r12,8(%rsp)
+movq %r13,16(%rsp)
+movq %r14,24(%rsp)
+movq %r15,32(%rsp)
+movq %rbx,40(%rsp)
+movq %rbp,48(%rsp)
+movq 40(%rdi),%rsi
+movq 48(%rdi),%rdx
+movq 56(%rdi),%rcx
+movq 64(%rdi),%r8
+movq 72(%rdi),%r9
+mov %rsi,%rax
+mov %rdx,%r10
+mov %rcx,%r11
+mov %r8,%r12
+mov %r9,%r13
+add x25519_x86_64_2P0(%rip),%rax
+add x25519_x86_64_2P1234(%rip),%r10
+add x25519_x86_64_2P1234(%rip),%r11
+add x25519_x86_64_2P1234(%rip),%r12
+add x25519_x86_64_2P1234(%rip),%r13
+addq 80(%rdi),%rsi
+addq 88(%rdi),%rdx
+addq 96(%rdi),%rcx
+addq 104(%rdi),%r8
+addq 112(%rdi),%r9
+subq 80(%rdi),%rax
+subq 88(%rdi),%r10
+subq 96(%rdi),%r11
+subq 104(%rdi),%r12
+subq 112(%rdi),%r13
+movq %rsi,56(%rsp)
+movq %rdx,64(%rsp)
+movq %rcx,72(%rsp)
+movq %r8,80(%rsp)
+movq %r9,88(%rsp)
+movq %rax,96(%rsp)
+movq %r10,104(%rsp)
+movq %r11,112(%rsp)
+movq %r12,120(%rsp)
+movq %r13,128(%rsp)
+movq 96(%rsp),%rax
+mulq 96(%rsp)
+mov %rax,%rsi
+mov %rdx,%rcx
+movq 96(%rsp),%rax
+shl $1,%rax
+mulq 104(%rsp)
+mov %rax,%r8
+mov %rdx,%r9
+movq 96(%rsp),%rax
+shl $1,%rax
+mulq 112(%rsp)
+mov %rax,%r10
+mov %rdx,%r11
+movq 96(%rsp),%rax
+shl $1,%rax
+mulq 120(%rsp)
+mov %rax,%r12
+mov %rdx,%r13
+movq 96(%rsp),%rax
+shl $1,%rax
+mulq 128(%rsp)
+mov %rax,%r14
+mov %rdx,%r15
+movq 104(%rsp),%rax
+mulq 104(%rsp)
+add %rax,%r10
+adc %rdx,%r11
+movq 104(%rsp),%rax
+shl $1,%rax
+mulq 112(%rsp)
+add %rax,%r12
+adc %rdx,%r13
+movq 104(%rsp),%rax
+shl $1,%rax
+mulq 120(%rsp)
+add %rax,%r14
+adc %rdx,%r15
+movq 104(%rsp),%rdx
+imulq $38,%rdx,%rax
+mulq 128(%rsp)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 112(%rsp),%rax
+mulq 112(%rsp)
+add %rax,%r14
+adc %rdx,%r15
+movq 112(%rsp),%rdx
+imulq $38,%rdx,%rax
+mulq 120(%rsp)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 112(%rsp),%rdx
+imulq $38,%rdx,%rax
+mulq 128(%rsp)
+add %rax,%r8
+adc %rdx,%r9
+movq 120(%rsp),%rdx
+imulq $19,%rdx,%rax
+mulq 120(%rsp)
+add %rax,%r8
+adc %rdx,%r9
+movq 120(%rsp),%rdx
+imulq $38,%rdx,%rax
+mulq 128(%rsp)
+add %rax,%r10
+adc %rdx,%r11
+movq 128(%rsp),%rdx
+imulq $19,%rdx,%rax
+mulq 128(%rsp)
+add %rax,%r12
+adc %rdx,%r13
+movq x25519_x86_64_REDMASK51(%rip),%rdx
+shld $13,%rsi,%rcx
+and %rdx,%rsi
+shld $13,%r8,%r9
+and %rdx,%r8
+add %rcx,%r8
+shld $13,%r10,%r11
+and %rdx,%r10
+add %r9,%r10
+shld $13,%r12,%r13
+and %rdx,%r12
+add %r11,%r12
+shld $13,%r14,%r15
+and %rdx,%r14
+add %r13,%r14
+imulq $19,%r15,%rcx
+add %rcx,%rsi
+mov %rsi,%rcx
+shr $51,%rcx
+add %r8,%rcx
+and %rdx,%rsi
+mov %rcx,%r8
+shr $51,%rcx
+add %r10,%rcx
+and %rdx,%r8
+mov %rcx,%r9
+shr $51,%rcx
+add %r12,%rcx
+and %rdx,%r9
+mov %rcx,%rax
+shr $51,%rcx
+add %r14,%rcx
+and %rdx,%rax
+mov %rcx,%r10
+shr $51,%rcx
+imulq $19,%rcx,%rcx
+add %rcx,%rsi
+and %rdx,%r10
+movq %rsi,136(%rsp)
+movq %r8,144(%rsp)
+movq %r9,152(%rsp)
+movq %rax,160(%rsp)
+movq %r10,168(%rsp)
+movq 56(%rsp),%rax
+mulq 56(%rsp)
+mov %rax,%rsi
+mov %rdx,%rcx
+movq 56(%rsp),%rax
+shl $1,%rax
+mulq 64(%rsp)
+mov %rax,%r8
+mov %rdx,%r9
+movq 56(%rsp),%rax
+shl $1,%rax
+mulq 72(%rsp)
+mov %rax,%r10
+mov %rdx,%r11
+movq 56(%rsp),%rax
+shl $1,%rax
+mulq 80(%rsp)
+mov %rax,%r12
+mov %rdx,%r13
+movq 56(%rsp),%rax
+shl $1,%rax
+mulq 88(%rsp)
+mov %rax,%r14
+mov %rdx,%r15
+movq 64(%rsp),%rax
+mulq 64(%rsp)
+add %rax,%r10
+adc %rdx,%r11
+movq 64(%rsp),%rax
+shl $1,%rax
+mulq 72(%rsp)
+add %rax,%r12
+adc %rdx,%r13
+movq 64(%rsp),%rax
+shl $1,%rax
+mulq 80(%rsp)
+add %rax,%r14
+adc %rdx,%r15
+movq 64(%rsp),%rdx
+imulq $38,%rdx,%rax
+mulq 88(%rsp)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 72(%rsp),%rax
+mulq 72(%rsp)
+add %rax,%r14
+adc %rdx,%r15
+movq 72(%rsp),%rdx
+imulq $38,%rdx,%rax
+mulq 80(%rsp)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 72(%rsp),%rdx
+imulq $38,%rdx,%rax
+mulq 88(%rsp)
+add %rax,%r8
+adc %rdx,%r9
+movq 80(%rsp),%rdx
+imulq $19,%rdx,%rax
+mulq 80(%rsp)
+add %rax,%r8
+adc %rdx,%r9
+movq 80(%rsp),%rdx
+imulq $38,%rdx,%rax
+mulq 88(%rsp)
+add %rax,%r10
+adc %rdx,%r11
+movq 88(%rsp),%rdx
+imulq $19,%rdx,%rax
+mulq 88(%rsp)
+add %rax,%r12
+adc %rdx,%r13
+movq x25519_x86_64_REDMASK51(%rip),%rdx
+shld $13,%rsi,%rcx
+and %rdx,%rsi
+shld $13,%r8,%r9
+and %rdx,%r8
+add %rcx,%r8
+shld $13,%r10,%r11
+and %rdx,%r10
+add %r9,%r10
+shld $13,%r12,%r13
+and %rdx,%r12
+add %r11,%r12
+shld $13,%r14,%r15
+and %rdx,%r14
+add %r13,%r14
+imulq $19,%r15,%rcx
+add %rcx,%rsi
+mov %rsi,%rcx
+shr $51,%rcx
+add %r8,%rcx
+and %rdx,%rsi
+mov %rcx,%r8
+shr $51,%rcx
+add %r10,%rcx
+and %rdx,%r8
+mov %rcx,%r9
+shr $51,%rcx
+add %r12,%rcx
+and %rdx,%r9
+mov %rcx,%rax
+shr $51,%rcx
+add %r14,%rcx
+and %rdx,%rax
+mov %rcx,%r10
+shr $51,%rcx
+imulq $19,%rcx,%rcx
+add %rcx,%rsi
+and %rdx,%r10
+movq %rsi,176(%rsp)
+movq %r8,184(%rsp)
+movq %r9,192(%rsp)
+movq %rax,200(%rsp)
+movq %r10,208(%rsp)
+mov %rsi,%rsi
+mov %r8,%rdx
+mov %r9,%rcx
+mov %rax,%r8
+mov %r10,%r9
+add x25519_x86_64_2P0(%rip),%rsi
+add x25519_x86_64_2P1234(%rip),%rdx
+add x25519_x86_64_2P1234(%rip),%rcx
+add x25519_x86_64_2P1234(%rip),%r8
+add x25519_x86_64_2P1234(%rip),%r9
+subq 136(%rsp),%rsi
+subq 144(%rsp),%rdx
+subq 152(%rsp),%rcx
+subq 160(%rsp),%r8
+subq 168(%rsp),%r9
+movq %rsi,216(%rsp)
+movq %rdx,224(%rsp)
+movq %rcx,232(%rsp)
+movq %r8,240(%rsp)
+movq %r9,248(%rsp)
+movq 120(%rdi),%rsi
+movq 128(%rdi),%rdx
+movq 136(%rdi),%rcx
+movq 144(%rdi),%r8
+movq 152(%rdi),%r9
+mov %rsi,%rax
+mov %rdx,%r10
+mov %rcx,%r11
+mov %r8,%r12
+mov %r9,%r13
+add x25519_x86_64_2P0(%rip),%rax
+add x25519_x86_64_2P1234(%rip),%r10
+add x25519_x86_64_2P1234(%rip),%r11
+add x25519_x86_64_2P1234(%rip),%r12
+add x25519_x86_64_2P1234(%rip),%r13
+addq 160(%rdi),%rsi
+addq 168(%rdi),%rdx
+addq 176(%rdi),%rcx
+addq 184(%rdi),%r8
+addq 192(%rdi),%r9
+subq 160(%rdi),%rax
+subq 168(%rdi),%r10
+subq 176(%rdi),%r11
+subq 184(%rdi),%r12
+subq 192(%rdi),%r13
+movq %rsi,256(%rsp)
+movq %rdx,264(%rsp)
+movq %rcx,272(%rsp)
+movq %r8,280(%rsp)
+movq %r9,288(%rsp)
+movq %rax,296(%rsp)
+movq %r10,304(%rsp)
+movq %r11,312(%rsp)
+movq %r12,320(%rsp)
+movq %r13,328(%rsp)
+movq 280(%rsp),%rsi
+imulq $19,%rsi,%rax
+movq %rax,336(%rsp)
+mulq 112(%rsp)
+mov %rax,%rsi
+mov %rdx,%rcx
+movq 288(%rsp),%rdx
+imulq $19,%rdx,%rax
+movq %rax,344(%rsp)
+mulq 104(%rsp)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 256(%rsp),%rax
+mulq 96(%rsp)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 256(%rsp),%rax
+mulq 104(%rsp)
+mov %rax,%r8
+mov %rdx,%r9
+movq 256(%rsp),%rax
+mulq 112(%rsp)
+mov %rax,%r10
+mov %rdx,%r11
+movq 256(%rsp),%rax
+mulq 120(%rsp)
+mov %rax,%r12
+mov %rdx,%r13
+movq 256(%rsp),%rax
+mulq 128(%rsp)
+mov %rax,%r14
+mov %rdx,%r15
+movq 264(%rsp),%rax
+mulq 96(%rsp)
+add %rax,%r8
+adc %rdx,%r9
+movq 264(%rsp),%rax
+mulq 104(%rsp)
+add %rax,%r10
+adc %rdx,%r11
+movq 264(%rsp),%rax
+mulq 112(%rsp)
+add %rax,%r12
+adc %rdx,%r13
+movq 264(%rsp),%rax
+mulq 120(%rsp)
+add %rax,%r14
+adc %rdx,%r15
+movq 264(%rsp),%rdx
+imulq $19,%rdx,%rax
+mulq 128(%rsp)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 272(%rsp),%rax
+mulq 96(%rsp)
+add %rax,%r10
+adc %rdx,%r11
+movq 272(%rsp),%rax
+mulq 104(%rsp)
+add %rax,%r12
+adc %rdx,%r13
+movq 272(%rsp),%rax
+mulq 112(%rsp)
+add %rax,%r14
+adc %rdx,%r15
+movq 272(%rsp),%rdx
+imulq $19,%rdx,%rax
+mulq 120(%rsp)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 272(%rsp),%rdx
+imulq $19,%rdx,%rax
+mulq 128(%rsp)
+add %rax,%r8
+adc %rdx,%r9
+movq 280(%rsp),%rax
+mulq 96(%rsp)
+add %rax,%r12
+adc %rdx,%r13
+movq 280(%rsp),%rax
+mulq 104(%rsp)
+add %rax,%r14
+adc %rdx,%r15
+movq 336(%rsp),%rax
+mulq 120(%rsp)
+add %rax,%r8
+adc %rdx,%r9
+movq 336(%rsp),%rax
+mulq 128(%rsp)
+add %rax,%r10
+adc %rdx,%r11
+movq 288(%rsp),%rax
+mulq 96(%rsp)
+add %rax,%r14
+adc %rdx,%r15
+movq 344(%rsp),%rax
+mulq 112(%rsp)
+add %rax,%r8
+adc %rdx,%r9
+movq 344(%rsp),%rax
+mulq 120(%rsp)
+add %rax,%r10
+adc %rdx,%r11
+movq 344(%rsp),%rax
+mulq 128(%rsp)
+add %rax,%r12
+adc %rdx,%r13
+movq x25519_x86_64_REDMASK51(%rip),%rdx
+shld $13,%rsi,%rcx
+and %rdx,%rsi
+shld $13,%r8,%r9
+and %rdx,%r8
+add %rcx,%r8
+shld $13,%r10,%r11
+and %rdx,%r10
+add %r9,%r10
+shld $13,%r12,%r13
+and %rdx,%r12
+add %r11,%r12
+shld $13,%r14,%r15
+and %rdx,%r14
+add %r13,%r14
+imulq $19,%r15,%rcx
+add %rcx,%rsi
+mov %rsi,%rcx
+shr $51,%rcx
+add %r8,%rcx
+mov %rcx,%r8
+shr $51,%rcx
+and %rdx,%rsi
+add %r10,%rcx
+mov %rcx,%r9
+shr $51,%rcx
+and %rdx,%r8
+add %r12,%rcx
+mov %rcx,%rax
+shr $51,%rcx
+and %rdx,%r9
+add %r14,%rcx
+mov %rcx,%r10
+shr $51,%rcx
+and %rdx,%rax
+imulq $19,%rcx,%rcx
+add %rcx,%rsi
+and %rdx,%r10
+movq %rsi,96(%rsp)
+movq %r8,104(%rsp)
+movq %r9,112(%rsp)
+movq %rax,120(%rsp)
+movq %r10,128(%rsp)
+movq 320(%rsp),%rsi
+imulq $19,%rsi,%rax
+movq %rax,256(%rsp)
+mulq 72(%rsp)
+mov %rax,%rsi
+mov %rdx,%rcx
+movq 328(%rsp),%rdx
+imulq $19,%rdx,%rax
+movq %rax,264(%rsp)
+mulq 64(%rsp)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 296(%rsp),%rax
+mulq 56(%rsp)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 296(%rsp),%rax
+mulq 64(%rsp)
+mov %rax,%r8
+mov %rdx,%r9
+movq 296(%rsp),%rax
+mulq 72(%rsp)
+mov %rax,%r10
+mov %rdx,%r11
+movq 296(%rsp),%rax
+mulq 80(%rsp)
+mov %rax,%r12
+mov %rdx,%r13
+movq 296(%rsp),%rax
+mulq 88(%rsp)
+mov %rax,%r14
+mov %rdx,%r15
+movq 304(%rsp),%rax
+mulq 56(%rsp)
+add %rax,%r8
+adc %rdx,%r9
+movq 304(%rsp),%rax
+mulq 64(%rsp)
+add %rax,%r10
+adc %rdx,%r11
+movq 304(%rsp),%rax
+mulq 72(%rsp)
+add %rax,%r12
+adc %rdx,%r13
+movq 304(%rsp),%rax
+mulq 80(%rsp)
+add %rax,%r14
+adc %rdx,%r15
+movq 304(%rsp),%rdx
+imulq $19,%rdx,%rax
+mulq 88(%rsp)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 312(%rsp),%rax
+mulq 56(%rsp)
+add %rax,%r10
+adc %rdx,%r11
+movq 312(%rsp),%rax
+mulq 64(%rsp)
+add %rax,%r12
+adc %rdx,%r13
+movq 312(%rsp),%rax
+mulq 72(%rsp)
+add %rax,%r14
+adc %rdx,%r15
+movq 312(%rsp),%rdx
+imulq $19,%rdx,%rax
+mulq 80(%rsp)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 312(%rsp),%rdx
+imulq $19,%rdx,%rax
+mulq 88(%rsp)
+add %rax,%r8
+adc %rdx,%r9
+movq 320(%rsp),%rax
+mulq 56(%rsp)
+add %rax,%r12
+adc %rdx,%r13
+movq 320(%rsp),%rax
+mulq 64(%rsp)
+add %rax,%r14
+adc %rdx,%r15
+movq 256(%rsp),%rax
+mulq 80(%rsp)
+add %rax,%r8
+adc %rdx,%r9
+movq 256(%rsp),%rax
+mulq 88(%rsp)
+add %rax,%r10
+adc %rdx,%r11
+movq 328(%rsp),%rax
+mulq 56(%rsp)
+add %rax,%r14
+adc %rdx,%r15
+movq 264(%rsp),%rax
+mulq 72(%rsp)
+add %rax,%r8
+adc %rdx,%r9
+movq 264(%rsp),%rax
+mulq 80(%rsp)
+add %rax,%r10
+adc %rdx,%r11
+movq 264(%rsp),%rax
+mulq 88(%rsp)
+add %rax,%r12
+adc %rdx,%r13
+movq x25519_x86_64_REDMASK51(%rip),%rdx
+shld $13,%rsi,%rcx
+and %rdx,%rsi
+shld $13,%r8,%r9
+and %rdx,%r8
+add %rcx,%r8
+shld $13,%r10,%r11
+and %rdx,%r10
+add %r9,%r10
+shld $13,%r12,%r13
+and %rdx,%r12
+add %r11,%r12
+shld $13,%r14,%r15
+and %rdx,%r14
+add %r13,%r14
+imulq $19,%r15,%rcx
+add %rcx,%rsi
+mov %rsi,%rcx
+shr $51,%rcx
+add %r8,%rcx
+mov %rcx,%r8
+shr $51,%rcx
+and %rdx,%rsi
+add %r10,%rcx
+mov %rcx,%r9
+shr $51,%rcx
+and %rdx,%r8
+add %r12,%rcx
+mov %rcx,%rax
+shr $51,%rcx
+and %rdx,%r9
+add %r14,%rcx
+mov %rcx,%r10
+shr $51,%rcx
+and %rdx,%rax
+imulq $19,%rcx,%rcx
+add %rcx,%rsi
+and %rdx,%r10
+mov %rsi,%rdx
+mov %r8,%rcx
+mov %r9,%r11
+mov %rax,%r12
+mov %r10,%r13
+add x25519_x86_64_2P0(%rip),%rdx
+add x25519_x86_64_2P1234(%rip),%rcx
+add x25519_x86_64_2P1234(%rip),%r11
+add x25519_x86_64_2P1234(%rip),%r12
+add x25519_x86_64_2P1234(%rip),%r13
+addq 96(%rsp),%rsi
+addq 104(%rsp),%r8
+addq 112(%rsp),%r9
+addq 120(%rsp),%rax
+addq 128(%rsp),%r10
+subq 96(%rsp),%rdx
+subq 104(%rsp),%rcx
+subq 112(%rsp),%r11
+subq 120(%rsp),%r12
+subq 128(%rsp),%r13
+movq %rsi,120(%rdi)
+movq %r8,128(%rdi)
+movq %r9,136(%rdi)
+movq %rax,144(%rdi)
+movq %r10,152(%rdi)
+movq %rdx,160(%rdi)
+movq %rcx,168(%rdi)
+movq %r11,176(%rdi)
+movq %r12,184(%rdi)
+movq %r13,192(%rdi)
+movq 120(%rdi),%rax
+mulq 120(%rdi)
+mov %rax,%rsi
+mov %rdx,%rcx
+movq 120(%rdi),%rax
+shl $1,%rax
+mulq 128(%rdi)
+mov %rax,%r8
+mov %rdx,%r9
+movq 120(%rdi),%rax
+shl $1,%rax
+mulq 136(%rdi)
+mov %rax,%r10
+mov %rdx,%r11
+movq 120(%rdi),%rax
+shl $1,%rax
+mulq 144(%rdi)
+mov %rax,%r12
+mov %rdx,%r13
+movq 120(%rdi),%rax
+shl $1,%rax
+mulq 152(%rdi)
+mov %rax,%r14
+mov %rdx,%r15
+movq 128(%rdi),%rax
+mulq 128(%rdi)
+add %rax,%r10
+adc %rdx,%r11
+movq 128(%rdi),%rax
+shl $1,%rax
+mulq 136(%rdi)
+add %rax,%r12
+adc %rdx,%r13
+movq 128(%rdi),%rax
+shl $1,%rax
+mulq 144(%rdi)
+add %rax,%r14
+adc %rdx,%r15
+movq 128(%rdi),%rdx
+imulq $38,%rdx,%rax
+mulq 152(%rdi)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 136(%rdi),%rax
+mulq 136(%rdi)
+add %rax,%r14
+adc %rdx,%r15
+movq 136(%rdi),%rdx
+imulq $38,%rdx,%rax
+mulq 144(%rdi)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 136(%rdi),%rdx
+imulq $38,%rdx,%rax
+mulq 152(%rdi)
+add %rax,%r8
+adc %rdx,%r9
+movq 144(%rdi),%rdx
+imulq $19,%rdx,%rax
+mulq 144(%rdi)
+add %rax,%r8
+adc %rdx,%r9
+movq 144(%rdi),%rdx
+imulq $38,%rdx,%rax
+mulq 152(%rdi)
+add %rax,%r10
+adc %rdx,%r11
+movq 152(%rdi),%rdx
+imulq $19,%rdx,%rax
+mulq 152(%rdi)
+add %rax,%r12
+adc %rdx,%r13
+movq x25519_x86_64_REDMASK51(%rip),%rdx
+shld $13,%rsi,%rcx
+and %rdx,%rsi
+shld $13,%r8,%r9
+and %rdx,%r8
+add %rcx,%r8
+shld $13,%r10,%r11
+and %rdx,%r10
+add %r9,%r10
+shld $13,%r12,%r13
+and %rdx,%r12
+add %r11,%r12
+shld $13,%r14,%r15
+and %rdx,%r14
+add %r13,%r14
+imulq $19,%r15,%rcx
+add %rcx,%rsi
+mov %rsi,%rcx
+shr $51,%rcx
+add %r8,%rcx
+and %rdx,%rsi
+mov %rcx,%r8
+shr $51,%rcx
+add %r10,%rcx
+and %rdx,%r8
+mov %rcx,%r9
+shr $51,%rcx
+add %r12,%rcx
+and %rdx,%r9
+mov %rcx,%rax
+shr $51,%rcx
+add %r14,%rcx
+and %rdx,%rax
+mov %rcx,%r10
+shr $51,%rcx
+imulq $19,%rcx,%rcx
+add %rcx,%rsi
+and %rdx,%r10
+movq %rsi,120(%rdi)
+movq %r8,128(%rdi)
+movq %r9,136(%rdi)
+movq %rax,144(%rdi)
+movq %r10,152(%rdi)
+movq 160(%rdi),%rax
+mulq 160(%rdi)
+mov %rax,%rsi
+mov %rdx,%rcx
+movq 160(%rdi),%rax
+shl $1,%rax
+mulq 168(%rdi)
+mov %rax,%r8
+mov %rdx,%r9
+movq 160(%rdi),%rax
+shl $1,%rax
+mulq 176(%rdi)
+mov %rax,%r10
+mov %rdx,%r11
+movq 160(%rdi),%rax
+shl $1,%rax
+mulq 184(%rdi)
+mov %rax,%r12
+mov %rdx,%r13
+movq 160(%rdi),%rax
+shl $1,%rax
+mulq 192(%rdi)
+mov %rax,%r14
+mov %rdx,%r15
+movq 168(%rdi),%rax
+mulq 168(%rdi)
+add %rax,%r10
+adc %rdx,%r11
+movq 168(%rdi),%rax
+shl $1,%rax
+mulq 176(%rdi)
+add %rax,%r12
+adc %rdx,%r13
+movq 168(%rdi),%rax
+shl $1,%rax
+mulq 184(%rdi)
+add %rax,%r14
+adc %rdx,%r15
+movq 168(%rdi),%rdx
+imulq $38,%rdx,%rax
+mulq 192(%rdi)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 176(%rdi),%rax
+mulq 176(%rdi)
+add %rax,%r14
+adc %rdx,%r15
+movq 176(%rdi),%rdx
+imulq $38,%rdx,%rax
+mulq 184(%rdi)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 176(%rdi),%rdx
+imulq $38,%rdx,%rax
+mulq 192(%rdi)
+add %rax,%r8
+adc %rdx,%r9
+movq 184(%rdi),%rdx
+imulq $19,%rdx,%rax
+mulq 184(%rdi)
+add %rax,%r8
+adc %rdx,%r9
+movq 184(%rdi),%rdx
+imulq $38,%rdx,%rax
+mulq 192(%rdi)
+add %rax,%r10
+adc %rdx,%r11
+movq 192(%rdi),%rdx
+imulq $19,%rdx,%rax
+mulq 192(%rdi)
+add %rax,%r12
+adc %rdx,%r13
+movq x25519_x86_64_REDMASK51(%rip),%rdx
+shld $13,%rsi,%rcx
+and %rdx,%rsi
+shld $13,%r8,%r9
+and %rdx,%r8
+add %rcx,%r8
+shld $13,%r10,%r11
+and %rdx,%r10
+add %r9,%r10
+shld $13,%r12,%r13
+and %rdx,%r12
+add %r11,%r12
+shld $13,%r14,%r15
+and %rdx,%r14
+add %r13,%r14
+imulq $19,%r15,%rcx
+add %rcx,%rsi
+mov %rsi,%rcx
+shr $51,%rcx
+add %r8,%rcx
+and %rdx,%rsi
+mov %rcx,%r8
+shr $51,%rcx
+add %r10,%rcx
+and %rdx,%r8
+mov %rcx,%r9
+shr $51,%rcx
+add %r12,%rcx
+and %rdx,%r9
+mov %rcx,%rax
+shr $51,%rcx
+add %r14,%rcx
+and %rdx,%rax
+mov %rcx,%r10
+shr $51,%rcx
+imulq $19,%rcx,%rcx
+add %rcx,%rsi
+and %rdx,%r10
+movq %rsi,160(%rdi)
+movq %r8,168(%rdi)
+movq %r9,176(%rdi)
+movq %rax,184(%rdi)
+movq %r10,192(%rdi)
+movq 184(%rdi),%rsi
+imulq $19,%rsi,%rax
+movq %rax,56(%rsp)
+mulq 16(%rdi)
+mov %rax,%rsi
+mov %rdx,%rcx
+movq 192(%rdi),%rdx
+imulq $19,%rdx,%rax
+movq %rax,64(%rsp)
+mulq 8(%rdi)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 160(%rdi),%rax
+mulq 0(%rdi)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 160(%rdi),%rax
+mulq 8(%rdi)
+mov %rax,%r8
+mov %rdx,%r9
+movq 160(%rdi),%rax
+mulq 16(%rdi)
+mov %rax,%r10
+mov %rdx,%r11
+movq 160(%rdi),%rax
+mulq 24(%rdi)
+mov %rax,%r12
+mov %rdx,%r13
+movq 160(%rdi),%rax
+mulq 32(%rdi)
+mov %rax,%r14
+mov %rdx,%r15
+movq 168(%rdi),%rax
+mulq 0(%rdi)
+add %rax,%r8
+adc %rdx,%r9
+movq 168(%rdi),%rax
+mulq 8(%rdi)
+add %rax,%r10
+adc %rdx,%r11
+movq 168(%rdi),%rax
+mulq 16(%rdi)
+add %rax,%r12
+adc %rdx,%r13
+movq 168(%rdi),%rax
+mulq 24(%rdi)
+add %rax,%r14
+adc %rdx,%r15
+movq 168(%rdi),%rdx
+imulq $19,%rdx,%rax
+mulq 32(%rdi)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 176(%rdi),%rax
+mulq 0(%rdi)
+add %rax,%r10
+adc %rdx,%r11
+movq 176(%rdi),%rax
+mulq 8(%rdi)
+add %rax,%r12
+adc %rdx,%r13
+movq 176(%rdi),%rax
+mulq 16(%rdi)
+add %rax,%r14
+adc %rdx,%r15
+movq 176(%rdi),%rdx
+imulq $19,%rdx,%rax
+mulq 24(%rdi)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 176(%rdi),%rdx
+imulq $19,%rdx,%rax
+mulq 32(%rdi)
+add %rax,%r8
+adc %rdx,%r9
+movq 184(%rdi),%rax
+mulq 0(%rdi)
+add %rax,%r12
+adc %rdx,%r13
+movq 184(%rdi),%rax
+mulq 8(%rdi)
+add %rax,%r14
+adc %rdx,%r15
+movq 56(%rsp),%rax
+mulq 24(%rdi)
+add %rax,%r8
+adc %rdx,%r9
+movq 56(%rsp),%rax
+mulq 32(%rdi)
+add %rax,%r10
+adc %rdx,%r11
+movq 192(%rdi),%rax
+mulq 0(%rdi)
+add %rax,%r14
+adc %rdx,%r15
+movq 64(%rsp),%rax
+mulq 16(%rdi)
+add %rax,%r8
+adc %rdx,%r9
+movq 64(%rsp),%rax
+mulq 24(%rdi)
+add %rax,%r10
+adc %rdx,%r11
+movq 64(%rsp),%rax
+mulq 32(%rdi)
+add %rax,%r12
+adc %rdx,%r13
+movq x25519_x86_64_REDMASK51(%rip),%rdx
+shld $13,%rsi,%rcx
+and %rdx,%rsi
+shld $13,%r8,%r9
+and %rdx,%r8
+add %rcx,%r8
+shld $13,%r10,%r11
+and %rdx,%r10
+add %r9,%r10
+shld $13,%r12,%r13
+and %rdx,%r12
+add %r11,%r12
+shld $13,%r14,%r15
+and %rdx,%r14
+add %r13,%r14
+imulq $19,%r15,%rcx
+add %rcx,%rsi
+mov %rsi,%rcx
+shr $51,%rcx
+add %r8,%rcx
+mov %rcx,%r8
+shr $51,%rcx
+and %rdx,%rsi
+add %r10,%rcx
+mov %rcx,%r9
+shr $51,%rcx
+and %rdx,%r8
+add %r12,%rcx
+mov %rcx,%rax
+shr $51,%rcx
+and %rdx,%r9
+add %r14,%rcx
+mov %rcx,%r10
+shr $51,%rcx
+and %rdx,%rax
+imulq $19,%rcx,%rcx
+add %rcx,%rsi
+and %rdx,%r10
+movq %rsi,160(%rdi)
+movq %r8,168(%rdi)
+movq %r9,176(%rdi)
+movq %rax,184(%rdi)
+movq %r10,192(%rdi)
+movq 200(%rsp),%rsi
+imulq $19,%rsi,%rax
+movq %rax,56(%rsp)
+mulq 152(%rsp)
+mov %rax,%rsi
+mov %rdx,%rcx
+movq 208(%rsp),%rdx
+imulq $19,%rdx,%rax
+movq %rax,64(%rsp)
+mulq 144(%rsp)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 176(%rsp),%rax
+mulq 136(%rsp)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 176(%rsp),%rax
+mulq 144(%rsp)
+mov %rax,%r8
+mov %rdx,%r9
+movq 176(%rsp),%rax
+mulq 152(%rsp)
+mov %rax,%r10
+mov %rdx,%r11
+movq 176(%rsp),%rax
+mulq 160(%rsp)
+mov %rax,%r12
+mov %rdx,%r13
+movq 176(%rsp),%rax
+mulq 168(%rsp)
+mov %rax,%r14
+mov %rdx,%r15
+movq 184(%rsp),%rax
+mulq 136(%rsp)
+add %rax,%r8
+adc %rdx,%r9
+movq 184(%rsp),%rax
+mulq 144(%rsp)
+add %rax,%r10
+adc %rdx,%r11
+movq 184(%rsp),%rax
+mulq 152(%rsp)
+add %rax,%r12
+adc %rdx,%r13
+movq 184(%rsp),%rax
+mulq 160(%rsp)
+add %rax,%r14
+adc %rdx,%r15
+movq 184(%rsp),%rdx
+imulq $19,%rdx,%rax
+mulq 168(%rsp)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 192(%rsp),%rax
+mulq 136(%rsp)
+add %rax,%r10
+adc %rdx,%r11
+movq 192(%rsp),%rax
+mulq 144(%rsp)
+add %rax,%r12
+adc %rdx,%r13
+movq 192(%rsp),%rax
+mulq 152(%rsp)
+add %rax,%r14
+adc %rdx,%r15
+movq 192(%rsp),%rdx
+imulq $19,%rdx,%rax
+mulq 160(%rsp)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 192(%rsp),%rdx
+imulq $19,%rdx,%rax
+mulq 168(%rsp)
+add %rax,%r8
+adc %rdx,%r9
+movq 200(%rsp),%rax
+mulq 136(%rsp)
+add %rax,%r12
+adc %rdx,%r13
+movq 200(%rsp),%rax
+mulq 144(%rsp)
+add %rax,%r14
+adc %rdx,%r15
+movq 56(%rsp),%rax
+mulq 160(%rsp)
+add %rax,%r8
+adc %rdx,%r9
+movq 56(%rsp),%rax
+mulq 168(%rsp)
+add %rax,%r10
+adc %rdx,%r11
+movq 208(%rsp),%rax
+mulq 136(%rsp)
+add %rax,%r14
+adc %rdx,%r15
+movq 64(%rsp),%rax
+mulq 152(%rsp)
+add %rax,%r8
+adc %rdx,%r9
+movq 64(%rsp),%rax
+mulq 160(%rsp)
+add %rax,%r10
+adc %rdx,%r11
+movq 64(%rsp),%rax
+mulq 168(%rsp)
+add %rax,%r12
+adc %rdx,%r13
+movq x25519_x86_64_REDMASK51(%rip),%rdx
+shld $13,%rsi,%rcx
+and %rdx,%rsi
+shld $13,%r8,%r9
+and %rdx,%r8
+add %rcx,%r8
+shld $13,%r10,%r11
+and %rdx,%r10
+add %r9,%r10
+shld $13,%r12,%r13
+and %rdx,%r12
+add %r11,%r12
+shld $13,%r14,%r15
+and %rdx,%r14
+add %r13,%r14
+imulq $19,%r15,%rcx
+add %rcx,%rsi
+mov %rsi,%rcx
+shr $51,%rcx
+add %r8,%rcx
+mov %rcx,%r8
+shr $51,%rcx
+and %rdx,%rsi
+add %r10,%rcx
+mov %rcx,%r9
+shr $51,%rcx
+and %rdx,%r8
+add %r12,%rcx
+mov %rcx,%rax
+shr $51,%rcx
+and %rdx,%r9
+add %r14,%rcx
+mov %rcx,%r10
+shr $51,%rcx
+and %rdx,%rax
+imulq $19,%rcx,%rcx
+add %rcx,%rsi
+and %rdx,%r10
+movq %rsi,40(%rdi)
+movq %r8,48(%rdi)
+movq %r9,56(%rdi)
+movq %rax,64(%rdi)
+movq %r10,72(%rdi)
+movq 216(%rsp),%rax
+mulq x25519_x86_64_121666_213(%rip)
+shr $13,%rax
+mov %rax,%rsi
+mov %rdx,%rcx
+movq 224(%rsp),%rax
+mulq x25519_x86_64_121666_213(%rip)
+shr $13,%rax
+add %rax,%rcx
+mov %rdx,%r8
+movq 232(%rsp),%rax
+mulq x25519_x86_64_121666_213(%rip)
+shr $13,%rax
+add %rax,%r8
+mov %rdx,%r9
+movq 240(%rsp),%rax
+mulq x25519_x86_64_121666_213(%rip)
+shr $13,%rax
+add %rax,%r9
+mov %rdx,%r10
+movq 248(%rsp),%rax
+mulq x25519_x86_64_121666_213(%rip)
+shr $13,%rax
+add %rax,%r10
+imulq $19,%rdx,%rdx
+add %rdx,%rsi
+addq 136(%rsp),%rsi
+addq 144(%rsp),%rcx
+addq 152(%rsp),%r8
+addq 160(%rsp),%r9
+addq 168(%rsp),%r10
+movq %rsi,80(%rdi)
+movq %rcx,88(%rdi)
+movq %r8,96(%rdi)
+movq %r9,104(%rdi)
+movq %r10,112(%rdi)
+movq 104(%rdi),%rsi
+imulq $19,%rsi,%rax
+movq %rax,56(%rsp)
+mulq 232(%rsp)
+mov %rax,%rsi
+mov %rdx,%rcx
+movq 112(%rdi),%rdx
+imulq $19,%rdx,%rax
+movq %rax,64(%rsp)
+mulq 224(%rsp)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 80(%rdi),%rax
+mulq 216(%rsp)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 80(%rdi),%rax
+mulq 224(%rsp)
+mov %rax,%r8
+mov %rdx,%r9
+movq 80(%rdi),%rax
+mulq 232(%rsp)
+mov %rax,%r10
+mov %rdx,%r11
+movq 80(%rdi),%rax
+mulq 240(%rsp)
+mov %rax,%r12
+mov %rdx,%r13
+movq 80(%rdi),%rax
+mulq 248(%rsp)
+mov %rax,%r14
+mov %rdx,%r15
+movq 88(%rdi),%rax
+mulq 216(%rsp)
+add %rax,%r8
+adc %rdx,%r9
+movq 88(%rdi),%rax
+mulq 224(%rsp)
+add %rax,%r10
+adc %rdx,%r11
+movq 88(%rdi),%rax
+mulq 232(%rsp)
+add %rax,%r12
+adc %rdx,%r13
+movq 88(%rdi),%rax
+mulq 240(%rsp)
+add %rax,%r14
+adc %rdx,%r15
+movq 88(%rdi),%rdx
+imulq $19,%rdx,%rax
+mulq 248(%rsp)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 96(%rdi),%rax
+mulq 216(%rsp)
+add %rax,%r10
+adc %rdx,%r11
+movq 96(%rdi),%rax
+mulq 224(%rsp)
+add %rax,%r12
+adc %rdx,%r13
+movq 96(%rdi),%rax
+mulq 232(%rsp)
+add %rax,%r14
+adc %rdx,%r15
+movq 96(%rdi),%rdx
+imulq $19,%rdx,%rax
+mulq 240(%rsp)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 96(%rdi),%rdx
+imulq $19,%rdx,%rax
+mulq 248(%rsp)
+add %rax,%r8
+adc %rdx,%r9
+movq 104(%rdi),%rax
+mulq 216(%rsp)
+add %rax,%r12
+adc %rdx,%r13
+movq 104(%rdi),%rax
+mulq 224(%rsp)
+add %rax,%r14
+adc %rdx,%r15
+movq 56(%rsp),%rax
+mulq 240(%rsp)
+add %rax,%r8
+adc %rdx,%r9
+movq 56(%rsp),%rax
+mulq 248(%rsp)
+add %rax,%r10
+adc %rdx,%r11
+movq 112(%rdi),%rax
+mulq 216(%rsp)
+add %rax,%r14
+adc %rdx,%r15
+movq 64(%rsp),%rax
+mulq 232(%rsp)
+add %rax,%r8
+adc %rdx,%r9
+movq 64(%rsp),%rax
+mulq 240(%rsp)
+add %rax,%r10
+adc %rdx,%r11
+movq 64(%rsp),%rax
+mulq 248(%rsp)
+add %rax,%r12
+adc %rdx,%r13
+movq x25519_x86_64_REDMASK51(%rip),%rdx
+shld $13,%rsi,%rcx
+and %rdx,%rsi
+shld $13,%r8,%r9
+and %rdx,%r8
+add %rcx,%r8
+shld $13,%r10,%r11
+and %rdx,%r10
+add %r9,%r10
+shld $13,%r12,%r13
+and %rdx,%r12
+add %r11,%r12
+shld $13,%r14,%r15
+and %rdx,%r14
+add %r13,%r14
+imulq $19,%r15,%rcx
+add %rcx,%rsi
+mov %rsi,%rcx
+shr $51,%rcx
+add %r8,%rcx
+mov %rcx,%r8
+shr $51,%rcx
+and %rdx,%rsi
+add %r10,%rcx
+mov %rcx,%r9
+shr $51,%rcx
+and %rdx,%r8
+add %r12,%rcx
+mov %rcx,%rax
+shr $51,%rcx
+and %rdx,%r9
+add %r14,%rcx
+mov %rcx,%r10
+shr $51,%rcx
+and %rdx,%rax
+imulq $19,%rcx,%rcx
+add %rcx,%rsi
+and %rdx,%r10
+movq %rsi,80(%rdi)
+movq %r8,88(%rdi)
+movq %r9,96(%rdi)
+movq %rax,104(%rdi)
+movq %r10,112(%rdi)
+movq 0(%rsp),%r11
+movq 8(%rsp),%r12
+movq 16(%rsp),%r13
+movq 24(%rsp),%r14
+movq 32(%rsp),%r15
+movq 40(%rsp),%rbx
+movq 48(%rsp),%rbp
+add %r11,%rsp
+mov %rdi,%rax
+mov %rsi,%rdx
+ret
+
+.p2align 5
+.globl C_ABI(x25519_x86_64_work_cswap)
+HIDDEN C_ABI(x25519_x86_64_work_cswap)
+C_ABI(x25519_x86_64_work_cswap):
+mov %rsp,%r11
+and $31,%r11
+add $0,%r11
+sub %r11,%rsp
+cmp $1,%rsi
+movq 0(%rdi),%rsi
+movq 80(%rdi),%rdx
+movq 8(%rdi),%rcx
+movq 88(%rdi),%r8
+mov %rsi,%r9
+cmove %rdx,%rsi
+cmove %r9,%rdx
+mov %rcx,%r9
+cmove %r8,%rcx
+cmove %r9,%r8
+movq %rsi,0(%rdi)
+movq %rdx,80(%rdi)
+movq %rcx,8(%rdi)
+movq %r8,88(%rdi)
+movq 16(%rdi),%rsi
+movq 96(%rdi),%rdx
+movq 24(%rdi),%rcx
+movq 104(%rdi),%r8
+mov %rsi,%r9
+cmove %rdx,%rsi
+cmove %r9,%rdx
+mov %rcx,%r9
+cmove %r8,%rcx
+cmove %r9,%r8
+movq %rsi,16(%rdi)
+movq %rdx,96(%rdi)
+movq %rcx,24(%rdi)
+movq %r8,104(%rdi)
+movq 32(%rdi),%rsi
+movq 112(%rdi),%rdx
+movq 40(%rdi),%rcx
+movq 120(%rdi),%r8
+mov %rsi,%r9
+cmove %rdx,%rsi
+cmove %r9,%rdx
+mov %rcx,%r9
+cmove %r8,%rcx
+cmove %r9,%r8
+movq %rsi,32(%rdi)
+movq %rdx,112(%rdi)
+movq %rcx,40(%rdi)
+movq %r8,120(%rdi)
+movq 48(%rdi),%rsi
+movq 128(%rdi),%rdx
+movq 56(%rdi),%rcx
+movq 136(%rdi),%r8
+mov %rsi,%r9
+cmove %rdx,%rsi
+cmove %r9,%rdx
+mov %rcx,%r9
+cmove %r8,%rcx
+cmove %r9,%r8
+movq %rsi,48(%rdi)
+movq %rdx,128(%rdi)
+movq %rcx,56(%rdi)
+movq %r8,136(%rdi)
+movq 64(%rdi),%rsi
+movq 144(%rdi),%rdx
+movq 72(%rdi),%rcx
+movq 152(%rdi),%r8
+mov %rsi,%r9
+cmove %rdx,%rsi
+cmove %r9,%rdx
+mov %rcx,%r9
+cmove %r8,%rcx
+cmove %r9,%r8
+movq %rsi,64(%rdi)
+movq %rdx,144(%rdi)
+movq %rcx,72(%rdi)
+movq %r8,152(%rdi)
+add %r11,%rsp
+mov %rdi,%rax
+mov %rsi,%rdx
+ret
diff --git a/src/crypto/curve25519/curve25519.c b/src/crypto/curve25519/curve25519.c
new file mode 100644
index 0000000..272db6c
--- /dev/null
+++ b/src/crypto/curve25519/curve25519.c
@@ -0,0 +1,4898 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+/* This code is mostly taken from the ref10 version of Ed25519 in SUPERCOP
+ * 20141124 (http://bench.cr.yp.to/supercop.html). That code is released as
+ * public domain but this file has the ISC license just to keep licencing
+ * simple.
+ *
+ * The field functions are shared by Ed25519 and X25519 where possible. */
+
+#include <openssl/curve25519.h>
+
+#include <string.h>
+
+#include <openssl/cpu.h>
+#include <openssl/mem.h>
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+
+#include "internal.h"
+
+
+/* fe means field element. Here the field is \Z/(2^255-19). An element t,
+ * entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77
+ * t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on
+ * context. */
+typedef int32_t fe[10];
+
+static uint64_t load_3(const uint8_t *in) {
+ uint64_t result;
+ result = (uint64_t)in[0];
+ result |= ((uint64_t)in[1]) << 8;
+ result |= ((uint64_t)in[2]) << 16;
+ return result;
+}
+
+static uint64_t load_4(const uint8_t *in) {
+ uint64_t result;
+ result = (uint64_t)in[0];
+ result |= ((uint64_t)in[1]) << 8;
+ result |= ((uint64_t)in[2]) << 16;
+ result |= ((uint64_t)in[3]) << 24;
+ return result;
+}
+
+static void fe_frombytes(fe h, const uint8_t *s) {
+ /* Ignores top bit of h. */
+ int64_t h0 = load_4(s);
+ int64_t h1 = load_3(s + 4) << 6;
+ int64_t h2 = load_3(s + 7) << 5;
+ int64_t h3 = load_3(s + 10) << 3;
+ int64_t h4 = load_3(s + 13) << 2;
+ int64_t h5 = load_4(s + 16);
+ int64_t h6 = load_3(s + 20) << 7;
+ int64_t h7 = load_3(s + 23) << 5;
+ int64_t h8 = load_3(s + 26) << 4;
+ int64_t h9 = (load_3(s + 29) & 8388607) << 2;
+ int64_t carry0;
+ int64_t carry1;
+ int64_t carry2;
+ int64_t carry3;
+ int64_t carry4;
+ int64_t carry5;
+ int64_t carry6;
+ int64_t carry7;
+ int64_t carry8;
+ int64_t carry9;
+
+ carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
+ carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
+ carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
+ carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
+ carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
+
+ carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
+ carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
+ carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
+ carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
+ carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
+
+ h[0] = h0;
+ h[1] = h1;
+ h[2] = h2;
+ h[3] = h3;
+ h[4] = h4;
+ h[5] = h5;
+ h[6] = h6;
+ h[7] = h7;
+ h[8] = h8;
+ h[9] = h9;
+}
+
+/* Preconditions:
+ * |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+ *
+ * Write p=2^255-19; q=floor(h/p).
+ * Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
+ *
+ * Proof:
+ * Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.
+ * Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4.
+ *
+ * Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).
+ * Then 0<y<1.
+ *
+ * Write r=h-pq.
+ * Have 0<=r<=p-1=2^255-20.
+ * Thus 0<=r+19(2^-255)r<r+19(2^-255)2^255<=2^255-1.
+ *
+ * Write x=r+19(2^-255)r+y.
+ * Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q.
+ *
+ * Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1))
+ * so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q. */
+static void fe_tobytes(uint8_t *s, const fe h) {
+ int32_t h0 = h[0];
+ int32_t h1 = h[1];
+ int32_t h2 = h[2];
+ int32_t h3 = h[3];
+ int32_t h4 = h[4];
+ int32_t h5 = h[5];
+ int32_t h6 = h[6];
+ int32_t h7 = h[7];
+ int32_t h8 = h[8];
+ int32_t h9 = h[9];
+ int32_t q;
+ int32_t carry0;
+ int32_t carry1;
+ int32_t carry2;
+ int32_t carry3;
+ int32_t carry4;
+ int32_t carry5;
+ int32_t carry6;
+ int32_t carry7;
+ int32_t carry8;
+ int32_t carry9;
+
+ q = (19 * h9 + (((int32_t) 1) << 24)) >> 25;
+ q = (h0 + q) >> 26;
+ q = (h1 + q) >> 25;
+ q = (h2 + q) >> 26;
+ q = (h3 + q) >> 25;
+ q = (h4 + q) >> 26;
+ q = (h5 + q) >> 25;
+ q = (h6 + q) >> 26;
+ q = (h7 + q) >> 25;
+ q = (h8 + q) >> 26;
+ q = (h9 + q) >> 25;
+
+ /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */
+ h0 += 19 * q;
+ /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */
+
+ carry0 = h0 >> 26; h1 += carry0; h0 -= carry0 << 26;
+ carry1 = h1 >> 25; h2 += carry1; h1 -= carry1 << 25;
+ carry2 = h2 >> 26; h3 += carry2; h2 -= carry2 << 26;
+ carry3 = h3 >> 25; h4 += carry3; h3 -= carry3 << 25;
+ carry4 = h4 >> 26; h5 += carry4; h4 -= carry4 << 26;
+ carry5 = h5 >> 25; h6 += carry5; h5 -= carry5 << 25;
+ carry6 = h6 >> 26; h7 += carry6; h6 -= carry6 << 26;
+ carry7 = h7 >> 25; h8 += carry7; h7 -= carry7 << 25;
+ carry8 = h8 >> 26; h9 += carry8; h8 -= carry8 << 26;
+ carry9 = h9 >> 25; h9 -= carry9 << 25;
+ /* h10 = carry9 */
+
+ /* Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
+ * Have h0+...+2^230 h9 between 0 and 2^255-1;
+ * evidently 2^255 h10-2^255 q = 0.
+ * Goal: Output h0+...+2^230 h9. */
+
+ s[0] = h0 >> 0;
+ s[1] = h0 >> 8;
+ s[2] = h0 >> 16;
+ s[3] = (h0 >> 24) | (h1 << 2);
+ s[4] = h1 >> 6;
+ s[5] = h1 >> 14;
+ s[6] = (h1 >> 22) | (h2 << 3);
+ s[7] = h2 >> 5;
+ s[8] = h2 >> 13;
+ s[9] = (h2 >> 21) | (h3 << 5);
+ s[10] = h3 >> 3;
+ s[11] = h3 >> 11;
+ s[12] = (h3 >> 19) | (h4 << 6);
+ s[13] = h4 >> 2;
+ s[14] = h4 >> 10;
+ s[15] = h4 >> 18;
+ s[16] = h5 >> 0;
+ s[17] = h5 >> 8;
+ s[18] = h5 >> 16;
+ s[19] = (h5 >> 24) | (h6 << 1);
+ s[20] = h6 >> 7;
+ s[21] = h6 >> 15;
+ s[22] = (h6 >> 23) | (h7 << 3);
+ s[23] = h7 >> 5;
+ s[24] = h7 >> 13;
+ s[25] = (h7 >> 21) | (h8 << 4);
+ s[26] = h8 >> 4;
+ s[27] = h8 >> 12;
+ s[28] = (h8 >> 20) | (h9 << 6);
+ s[29] = h9 >> 2;
+ s[30] = h9 >> 10;
+ s[31] = h9 >> 18;
+}
+
+/* h = f */
+static void fe_copy(fe h, const fe f) {
+ memmove(h, f, sizeof(int32_t) * 10);
+}
+
+/* h = 0 */
+static void fe_0(fe h) { memset(h, 0, sizeof(int32_t) * 10); }
+
+/* h = 1 */
+static void fe_1(fe h) {
+ memset(h, 0, sizeof(int32_t) * 10);
+ h[0] = 1;
+}
+
+/* h = f + g
+ * Can overlap h with f or g.
+ *
+ * Preconditions:
+ * |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+ * |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+ *
+ * Postconditions:
+ * |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */
+static void fe_add(fe h, const fe f, const fe g) {
+ unsigned i;
+ for (i = 0; i < 10; i++) {
+ h[i] = f[i] + g[i];
+ }
+}
+
+/* h = f - g
+ * Can overlap h with f or g.
+ *
+ * Preconditions:
+ * |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+ * |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+ *
+ * Postconditions:
+ * |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */
+static void fe_sub(fe h, const fe f, const fe g) {
+ unsigned i;
+ for (i = 0; i < 10; i++) {
+ h[i] = f[i] - g[i];
+ }
+}
+
+/* h = f * g
+ * Can overlap h with f or g.
+ *
+ * Preconditions:
+ * |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
+ * |g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
+ *
+ * Postconditions:
+ * |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
+ *
+ * Notes on implementation strategy:
+ *
+ * Using schoolbook multiplication.
+ * Karatsuba would save a little in some cost models.
+ *
+ * Most multiplications by 2 and 19 are 32-bit precomputations;
+ * cheaper than 64-bit postcomputations.
+ *
+ * There is one remaining multiplication by 19 in the carry chain;
+ * one *19 precomputation can be merged into this,
+ * but the resulting data flow is considerably less clean.
+ *
+ * There are 12 carries below.
+ * 10 of them are 2-way parallelizable and vectorizable.
+ * Can get away with 11 carries, but then data flow is much deeper.
+ *
+ * With tighter constraints on inputs can squeeze carries into int32. */
+static void fe_mul(fe h, const fe f, const fe g) {
+ int32_t f0 = f[0];
+ int32_t f1 = f[1];
+ int32_t f2 = f[2];
+ int32_t f3 = f[3];
+ int32_t f4 = f[4];
+ int32_t f5 = f[5];
+ int32_t f6 = f[6];
+ int32_t f7 = f[7];
+ int32_t f8 = f[8];
+ int32_t f9 = f[9];
+ int32_t g0 = g[0];
+ int32_t g1 = g[1];
+ int32_t g2 = g[2];
+ int32_t g3 = g[3];
+ int32_t g4 = g[4];
+ int32_t g5 = g[5];
+ int32_t g6 = g[6];
+ int32_t g7 = g[7];
+ int32_t g8 = g[8];
+ int32_t g9 = g[9];
+ int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */
+ int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */
+ int32_t g3_19 = 19 * g3;
+ int32_t g4_19 = 19 * g4;
+ int32_t g5_19 = 19 * g5;
+ int32_t g6_19 = 19 * g6;
+ int32_t g7_19 = 19 * g7;
+ int32_t g8_19 = 19 * g8;
+ int32_t g9_19 = 19 * g9;
+ int32_t f1_2 = 2 * f1;
+ int32_t f3_2 = 2 * f3;
+ int32_t f5_2 = 2 * f5;
+ int32_t f7_2 = 2 * f7;
+ int32_t f9_2 = 2 * f9;
+ int64_t f0g0 = f0 * (int64_t) g0;
+ int64_t f0g1 = f0 * (int64_t) g1;
+ int64_t f0g2 = f0 * (int64_t) g2;
+ int64_t f0g3 = f0 * (int64_t) g3;
+ int64_t f0g4 = f0 * (int64_t) g4;
+ int64_t f0g5 = f0 * (int64_t) g5;
+ int64_t f0g6 = f0 * (int64_t) g6;
+ int64_t f0g7 = f0 * (int64_t) g7;
+ int64_t f0g8 = f0 * (int64_t) g8;
+ int64_t f0g9 = f0 * (int64_t) g9;
+ int64_t f1g0 = f1 * (int64_t) g0;
+ int64_t f1g1_2 = f1_2 * (int64_t) g1;
+ int64_t f1g2 = f1 * (int64_t) g2;
+ int64_t f1g3_2 = f1_2 * (int64_t) g3;
+ int64_t f1g4 = f1 * (int64_t) g4;
+ int64_t f1g5_2 = f1_2 * (int64_t) g5;
+ int64_t f1g6 = f1 * (int64_t) g6;
+ int64_t f1g7_2 = f1_2 * (int64_t) g7;
+ int64_t f1g8 = f1 * (int64_t) g8;
+ int64_t f1g9_38 = f1_2 * (int64_t) g9_19;
+ int64_t f2g0 = f2 * (int64_t) g0;
+ int64_t f2g1 = f2 * (int64_t) g1;
+ int64_t f2g2 = f2 * (int64_t) g2;
+ int64_t f2g3 = f2 * (int64_t) g3;
+ int64_t f2g4 = f2 * (int64_t) g4;
+ int64_t f2g5 = f2 * (int64_t) g5;
+ int64_t f2g6 = f2 * (int64_t) g6;
+ int64_t f2g7 = f2 * (int64_t) g7;
+ int64_t f2g8_19 = f2 * (int64_t) g8_19;
+ int64_t f2g9_19 = f2 * (int64_t) g9_19;
+ int64_t f3g0 = f3 * (int64_t) g0;
+ int64_t f3g1_2 = f3_2 * (int64_t) g1;
+ int64_t f3g2 = f3 * (int64_t) g2;
+ int64_t f3g3_2 = f3_2 * (int64_t) g3;
+ int64_t f3g4 = f3 * (int64_t) g4;
+ int64_t f3g5_2 = f3_2 * (int64_t) g5;
+ int64_t f3g6 = f3 * (int64_t) g6;
+ int64_t f3g7_38 = f3_2 * (int64_t) g7_19;
+ int64_t f3g8_19 = f3 * (int64_t) g8_19;
+ int64_t f3g9_38 = f3_2 * (int64_t) g9_19;
+ int64_t f4g0 = f4 * (int64_t) g0;
+ int64_t f4g1 = f4 * (int64_t) g1;
+ int64_t f4g2 = f4 * (int64_t) g2;
+ int64_t f4g3 = f4 * (int64_t) g3;
+ int64_t f4g4 = f4 * (int64_t) g4;
+ int64_t f4g5 = f4 * (int64_t) g5;
+ int64_t f4g6_19 = f4 * (int64_t) g6_19;
+ int64_t f4g7_19 = f4 * (int64_t) g7_19;
+ int64_t f4g8_19 = f4 * (int64_t) g8_19;
+ int64_t f4g9_19 = f4 * (int64_t) g9_19;
+ int64_t f5g0 = f5 * (int64_t) g0;
+ int64_t f5g1_2 = f5_2 * (int64_t) g1;
+ int64_t f5g2 = f5 * (int64_t) g2;
+ int64_t f5g3_2 = f5_2 * (int64_t) g3;
+ int64_t f5g4 = f5 * (int64_t) g4;
+ int64_t f5g5_38 = f5_2 * (int64_t) g5_19;
+ int64_t f5g6_19 = f5 * (int64_t) g6_19;
+ int64_t f5g7_38 = f5_2 * (int64_t) g7_19;
+ int64_t f5g8_19 = f5 * (int64_t) g8_19;
+ int64_t f5g9_38 = f5_2 * (int64_t) g9_19;
+ int64_t f6g0 = f6 * (int64_t) g0;
+ int64_t f6g1 = f6 * (int64_t) g1;
+ int64_t f6g2 = f6 * (int64_t) g2;
+ int64_t f6g3 = f6 * (int64_t) g3;
+ int64_t f6g4_19 = f6 * (int64_t) g4_19;
+ int64_t f6g5_19 = f6 * (int64_t) g5_19;
+ int64_t f6g6_19 = f6 * (int64_t) g6_19;
+ int64_t f6g7_19 = f6 * (int64_t) g7_19;
+ int64_t f6g8_19 = f6 * (int64_t) g8_19;
+ int64_t f6g9_19 = f6 * (int64_t) g9_19;
+ int64_t f7g0 = f7 * (int64_t) g0;
+ int64_t f7g1_2 = f7_2 * (int64_t) g1;
+ int64_t f7g2 = f7 * (int64_t) g2;
+ int64_t f7g3_38 = f7_2 * (int64_t) g3_19;
+ int64_t f7g4_19 = f7 * (int64_t) g4_19;
+ int64_t f7g5_38 = f7_2 * (int64_t) g5_19;
+ int64_t f7g6_19 = f7 * (int64_t) g6_19;
+ int64_t f7g7_38 = f7_2 * (int64_t) g7_19;
+ int64_t f7g8_19 = f7 * (int64_t) g8_19;
+ int64_t f7g9_38 = f7_2 * (int64_t) g9_19;
+ int64_t f8g0 = f8 * (int64_t) g0;
+ int64_t f8g1 = f8 * (int64_t) g1;
+ int64_t f8g2_19 = f8 * (int64_t) g2_19;
+ int64_t f8g3_19 = f8 * (int64_t) g3_19;
+ int64_t f8g4_19 = f8 * (int64_t) g4_19;
+ int64_t f8g5_19 = f8 * (int64_t) g5_19;
+ int64_t f8g6_19 = f8 * (int64_t) g6_19;
+ int64_t f8g7_19 = f8 * (int64_t) g7_19;
+ int64_t f8g8_19 = f8 * (int64_t) g8_19;
+ int64_t f8g9_19 = f8 * (int64_t) g9_19;
+ int64_t f9g0 = f9 * (int64_t) g0;
+ int64_t f9g1_38 = f9_2 * (int64_t) g1_19;
+ int64_t f9g2_19 = f9 * (int64_t) g2_19;
+ int64_t f9g3_38 = f9_2 * (int64_t) g3_19;
+ int64_t f9g4_19 = f9 * (int64_t) g4_19;
+ int64_t f9g5_38 = f9_2 * (int64_t) g5_19;
+ int64_t f9g6_19 = f9 * (int64_t) g6_19;
+ int64_t f9g7_38 = f9_2 * (int64_t) g7_19;
+ int64_t f9g8_19 = f9 * (int64_t) g8_19;
+ int64_t f9g9_38 = f9_2 * (int64_t) g9_19;
+ int64_t h0 = f0g0+f1g9_38+f2g8_19+f3g7_38+f4g6_19+f5g5_38+f6g4_19+f7g3_38+f8g2_19+f9g1_38;
+ int64_t h1 = f0g1+f1g0 +f2g9_19+f3g8_19+f4g7_19+f5g6_19+f6g5_19+f7g4_19+f8g3_19+f9g2_19;
+ int64_t h2 = f0g2+f1g1_2 +f2g0 +f3g9_38+f4g8_19+f5g7_38+f6g6_19+f7g5_38+f8g4_19+f9g3_38;
+ int64_t h3 = f0g3+f1g2 +f2g1 +f3g0 +f4g9_19+f5g8_19+f6g7_19+f7g6_19+f8g5_19+f9g4_19;
+ int64_t h4 = f0g4+f1g3_2 +f2g2 +f3g1_2 +f4g0 +f5g9_38+f6g8_19+f7g7_38+f8g6_19+f9g5_38;
+ int64_t h5 = f0g5+f1g4 +f2g3 +f3g2 +f4g1 +f5g0 +f6g9_19+f7g8_19+f8g7_19+f9g6_19;
+ int64_t h6 = f0g6+f1g5_2 +f2g4 +f3g3_2 +f4g2 +f5g1_2 +f6g0 +f7g9_38+f8g8_19+f9g7_38;
+ int64_t h7 = f0g7+f1g6 +f2g5 +f3g4 +f4g3 +f5g2 +f6g1 +f7g0 +f8g9_19+f9g8_19;
+ int64_t h8 = f0g8+f1g7_2 +f2g6 +f3g5_2 +f4g4 +f5g3_2 +f6g2 +f7g1_2 +f8g0 +f9g9_38;
+ int64_t h9 = f0g9+f1g8 +f2g7 +f3g6 +f4g5 +f5g4 +f6g3 +f7g2 +f8g1 +f9g0 ;
+ int64_t carry0;
+ int64_t carry1;
+ int64_t carry2;
+ int64_t carry3;
+ int64_t carry4;
+ int64_t carry5;
+ int64_t carry6;
+ int64_t carry7;
+ int64_t carry8;
+ int64_t carry9;
+
+ /* |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38))
+ * i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8
+ * |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19))
+ * i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9 */
+
+ carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
+ carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
+ /* |h0| <= 2^25 */
+ /* |h4| <= 2^25 */
+ /* |h1| <= 1.71*2^59 */
+ /* |h5| <= 1.71*2^59 */
+
+ carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
+ carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
+ /* |h1| <= 2^24; from now on fits into int32 */
+ /* |h5| <= 2^24; from now on fits into int32 */
+ /* |h2| <= 1.41*2^60 */
+ /* |h6| <= 1.41*2^60 */
+
+ carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
+ carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
+ /* |h2| <= 2^25; from now on fits into int32 unchanged */
+ /* |h6| <= 2^25; from now on fits into int32 unchanged */
+ /* |h3| <= 1.71*2^59 */
+ /* |h7| <= 1.71*2^59 */
+
+ carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
+ carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
+ /* |h3| <= 2^24; from now on fits into int32 unchanged */
+ /* |h7| <= 2^24; from now on fits into int32 unchanged */
+ /* |h4| <= 1.72*2^34 */
+ /* |h8| <= 1.41*2^60 */
+
+ carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
+ carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
+ /* |h4| <= 2^25; from now on fits into int32 unchanged */
+ /* |h8| <= 2^25; from now on fits into int32 unchanged */
+ /* |h5| <= 1.01*2^24 */
+ /* |h9| <= 1.71*2^59 */
+
+ carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
+ /* |h9| <= 2^24; from now on fits into int32 unchanged */
+ /* |h0| <= 1.1*2^39 */
+
+ carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
+ /* |h0| <= 2^25; from now on fits into int32 unchanged */
+ /* |h1| <= 1.01*2^24 */
+
+ h[0] = h0;
+ h[1] = h1;
+ h[2] = h2;
+ h[3] = h3;
+ h[4] = h4;
+ h[5] = h5;
+ h[6] = h6;
+ h[7] = h7;
+ h[8] = h8;
+ h[9] = h9;
+}
+
+/* h = f * f
+ * Can overlap h with f.
+ *
+ * Preconditions:
+ * |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
+ *
+ * Postconditions:
+ * |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
+ *
+ * See fe_mul.c for discussion of implementation strategy. */
+static void fe_sq(fe h, const fe f) {
+ int32_t f0 = f[0];
+ int32_t f1 = f[1];
+ int32_t f2 = f[2];
+ int32_t f3 = f[3];
+ int32_t f4 = f[4];
+ int32_t f5 = f[5];
+ int32_t f6 = f[6];
+ int32_t f7 = f[7];
+ int32_t f8 = f[8];
+ int32_t f9 = f[9];
+ int32_t f0_2 = 2 * f0;
+ int32_t f1_2 = 2 * f1;
+ int32_t f2_2 = 2 * f2;
+ int32_t f3_2 = 2 * f3;
+ int32_t f4_2 = 2 * f4;
+ int32_t f5_2 = 2 * f5;
+ int32_t f6_2 = 2 * f6;
+ int32_t f7_2 = 2 * f7;
+ int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */
+ int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */
+ int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */
+ int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */
+ int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */
+ int64_t f0f0 = f0 * (int64_t) f0;
+ int64_t f0f1_2 = f0_2 * (int64_t) f1;
+ int64_t f0f2_2 = f0_2 * (int64_t) f2;
+ int64_t f0f3_2 = f0_2 * (int64_t) f3;
+ int64_t f0f4_2 = f0_2 * (int64_t) f4;
+ int64_t f0f5_2 = f0_2 * (int64_t) f5;
+ int64_t f0f6_2 = f0_2 * (int64_t) f6;
+ int64_t f0f7_2 = f0_2 * (int64_t) f7;
+ int64_t f0f8_2 = f0_2 * (int64_t) f8;
+ int64_t f0f9_2 = f0_2 * (int64_t) f9;
+ int64_t f1f1_2 = f1_2 * (int64_t) f1;
+ int64_t f1f2_2 = f1_2 * (int64_t) f2;
+ int64_t f1f3_4 = f1_2 * (int64_t) f3_2;
+ int64_t f1f4_2 = f1_2 * (int64_t) f4;
+ int64_t f1f5_4 = f1_2 * (int64_t) f5_2;
+ int64_t f1f6_2 = f1_2 * (int64_t) f6;
+ int64_t f1f7_4 = f1_2 * (int64_t) f7_2;
+ int64_t f1f8_2 = f1_2 * (int64_t) f8;
+ int64_t f1f9_76 = f1_2 * (int64_t) f9_38;
+ int64_t f2f2 = f2 * (int64_t) f2;
+ int64_t f2f3_2 = f2_2 * (int64_t) f3;
+ int64_t f2f4_2 = f2_2 * (int64_t) f4;
+ int64_t f2f5_2 = f2_2 * (int64_t) f5;
+ int64_t f2f6_2 = f2_2 * (int64_t) f6;
+ int64_t f2f7_2 = f2_2 * (int64_t) f7;
+ int64_t f2f8_38 = f2_2 * (int64_t) f8_19;
+ int64_t f2f9_38 = f2 * (int64_t) f9_38;
+ int64_t f3f3_2 = f3_2 * (int64_t) f3;
+ int64_t f3f4_2 = f3_2 * (int64_t) f4;
+ int64_t f3f5_4 = f3_2 * (int64_t) f5_2;
+ int64_t f3f6_2 = f3_2 * (int64_t) f6;
+ int64_t f3f7_76 = f3_2 * (int64_t) f7_38;
+ int64_t f3f8_38 = f3_2 * (int64_t) f8_19;
+ int64_t f3f9_76 = f3_2 * (int64_t) f9_38;
+ int64_t f4f4 = f4 * (int64_t) f4;
+ int64_t f4f5_2 = f4_2 * (int64_t) f5;
+ int64_t f4f6_38 = f4_2 * (int64_t) f6_19;
+ int64_t f4f7_38 = f4 * (int64_t) f7_38;
+ int64_t f4f8_38 = f4_2 * (int64_t) f8_19;
+ int64_t f4f9_38 = f4 * (int64_t) f9_38;
+ int64_t f5f5_38 = f5 * (int64_t) f5_38;
+ int64_t f5f6_38 = f5_2 * (int64_t) f6_19;
+ int64_t f5f7_76 = f5_2 * (int64_t) f7_38;
+ int64_t f5f8_38 = f5_2 * (int64_t) f8_19;
+ int64_t f5f9_76 = f5_2 * (int64_t) f9_38;
+ int64_t f6f6_19 = f6 * (int64_t) f6_19;
+ int64_t f6f7_38 = f6 * (int64_t) f7_38;
+ int64_t f6f8_38 = f6_2 * (int64_t) f8_19;
+ int64_t f6f9_38 = f6 * (int64_t) f9_38;
+ int64_t f7f7_38 = f7 * (int64_t) f7_38;
+ int64_t f7f8_38 = f7_2 * (int64_t) f8_19;
+ int64_t f7f9_76 = f7_2 * (int64_t) f9_38;
+ int64_t f8f8_19 = f8 * (int64_t) f8_19;
+ int64_t f8f9_38 = f8 * (int64_t) f9_38;
+ int64_t f9f9_38 = f9 * (int64_t) f9_38;
+ int64_t h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38;
+ int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38;
+ int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19;
+ int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38;
+ int64_t h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38;
+ int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38;
+ int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19;
+ int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38;
+ int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38;
+ int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2;
+ int64_t carry0;
+ int64_t carry1;
+ int64_t carry2;
+ int64_t carry3;
+ int64_t carry4;
+ int64_t carry5;
+ int64_t carry6;
+ int64_t carry7;
+ int64_t carry8;
+ int64_t carry9;
+
+ carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
+ carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
+
+ carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
+ carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
+
+ carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
+ carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
+
+ carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
+ carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
+
+ carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
+ carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
+
+ carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
+
+ carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
+
+ h[0] = h0;
+ h[1] = h1;
+ h[2] = h2;
+ h[3] = h3;
+ h[4] = h4;
+ h[5] = h5;
+ h[6] = h6;
+ h[7] = h7;
+ h[8] = h8;
+ h[9] = h9;
+}
+
+static void fe_invert(fe out, const fe z) {
+ fe t0;
+ fe t1;
+ fe t2;
+ fe t3;
+ int i;
+
+ fe_sq(t0, z);
+ for (i = 1; i < 1; ++i) {
+ fe_sq(t0, t0);
+ }
+ fe_sq(t1, t0);
+ for (i = 1; i < 2; ++i) {
+ fe_sq(t1, t1);
+ }
+ fe_mul(t1, z, t1);
+ fe_mul(t0, t0, t1);
+ fe_sq(t2, t0);
+ for (i = 1; i < 1; ++i) {
+ fe_sq(t2, t2);
+ }
+ fe_mul(t1, t1, t2);
+ fe_sq(t2, t1);
+ for (i = 1; i < 5; ++i) {
+ fe_sq(t2, t2);
+ }
+ fe_mul(t1, t2, t1);
+ fe_sq(t2, t1);
+ for (i = 1; i < 10; ++i) {
+ fe_sq(t2, t2);
+ }
+ fe_mul(t2, t2, t1);
+ fe_sq(t3, t2);
+ for (i = 1; i < 20; ++i) {
+ fe_sq(t3, t3);
+ }
+ fe_mul(t2, t3, t2);
+ fe_sq(t2, t2);
+ for (i = 1; i < 10; ++i) {
+ fe_sq(t2, t2);
+ }
+ fe_mul(t1, t2, t1);
+ fe_sq(t2, t1);
+ for (i = 1; i < 50; ++i) {
+ fe_sq(t2, t2);
+ }
+ fe_mul(t2, t2, t1);
+ fe_sq(t3, t2);
+ for (i = 1; i < 100; ++i) {
+ fe_sq(t3, t3);
+ }
+ fe_mul(t2, t3, t2);
+ fe_sq(t2, t2);
+ for (i = 1; i < 50; ++i) {
+ fe_sq(t2, t2);
+ }
+ fe_mul(t1, t2, t1);
+ fe_sq(t1, t1);
+ for (i = 1; i < 5; ++i) {
+ fe_sq(t1, t1);
+ }
+ fe_mul(out, t1, t0);
+}
+
+/* h = -f
+ *
+ * Preconditions:
+ * |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+ *
+ * Postconditions:
+ * |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. */
+static void fe_neg(fe h, const fe f) {
+ unsigned i;
+ for (i = 0; i < 10; i++) {
+ h[i] = -f[i];
+ }
+}
+
+/* Replace (f,g) with (g,g) if b == 1;
+ * replace (f,g) with (f,g) if b == 0.
+ *
+ * Preconditions: b in {0,1}. */
+static void fe_cmov(fe f, const fe g, unsigned b) {
+ b = 0-b;
+ unsigned i;
+ for (i = 0; i < 10; i++) {
+ int32_t x = f[i] ^ g[i];
+ x &= b;
+ f[i] ^= x;
+ }
+}
+
+/* return 0 if f == 0
+ * return 1 if f != 0
+ *
+ * Preconditions:
+ * |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */
+static int fe_isnonzero(const fe f) {
+ uint8_t s[32];
+ fe_tobytes(s, f);
+
+ static const uint8_t zero[32] = {0};
+ return CRYPTO_memcmp(s, zero, sizeof(zero)) != 0;
+}
+
+/* return 1 if f is in {1,3,5,...,q-2}
+ * return 0 if f is in {0,2,4,...,q-1}
+ *
+ * Preconditions:
+ * |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */
+static int fe_isnegative(const fe f) {
+ uint8_t s[32];
+ fe_tobytes(s, f);
+ return s[0] & 1;
+}
+
+/* h = 2 * f * f
+ * Can overlap h with f.
+ *
+ * Preconditions:
+ * |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
+ *
+ * Postconditions:
+ * |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
+ *
+ * See fe_mul.c for discussion of implementation strategy. */
+static void fe_sq2(fe h, const fe f) {
+ int32_t f0 = f[0];
+ int32_t f1 = f[1];
+ int32_t f2 = f[2];
+ int32_t f3 = f[3];
+ int32_t f4 = f[4];
+ int32_t f5 = f[5];
+ int32_t f6 = f[6];
+ int32_t f7 = f[7];
+ int32_t f8 = f[8];
+ int32_t f9 = f[9];
+ int32_t f0_2 = 2 * f0;
+ int32_t f1_2 = 2 * f1;
+ int32_t f2_2 = 2 * f2;
+ int32_t f3_2 = 2 * f3;
+ int32_t f4_2 = 2 * f4;
+ int32_t f5_2 = 2 * f5;
+ int32_t f6_2 = 2 * f6;
+ int32_t f7_2 = 2 * f7;
+ int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */
+ int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */
+ int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */
+ int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */
+ int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */
+ int64_t f0f0 = f0 * (int64_t) f0;
+ int64_t f0f1_2 = f0_2 * (int64_t) f1;
+ int64_t f0f2_2 = f0_2 * (int64_t) f2;
+ int64_t f0f3_2 = f0_2 * (int64_t) f3;
+ int64_t f0f4_2 = f0_2 * (int64_t) f4;
+ int64_t f0f5_2 = f0_2 * (int64_t) f5;
+ int64_t f0f6_2 = f0_2 * (int64_t) f6;
+ int64_t f0f7_2 = f0_2 * (int64_t) f7;
+ int64_t f0f8_2 = f0_2 * (int64_t) f8;
+ int64_t f0f9_2 = f0_2 * (int64_t) f9;
+ int64_t f1f1_2 = f1_2 * (int64_t) f1;
+ int64_t f1f2_2 = f1_2 * (int64_t) f2;
+ int64_t f1f3_4 = f1_2 * (int64_t) f3_2;
+ int64_t f1f4_2 = f1_2 * (int64_t) f4;
+ int64_t f1f5_4 = f1_2 * (int64_t) f5_2;
+ int64_t f1f6_2 = f1_2 * (int64_t) f6;
+ int64_t f1f7_4 = f1_2 * (int64_t) f7_2;
+ int64_t f1f8_2 = f1_2 * (int64_t) f8;
+ int64_t f1f9_76 = f1_2 * (int64_t) f9_38;
+ int64_t f2f2 = f2 * (int64_t) f2;
+ int64_t f2f3_2 = f2_2 * (int64_t) f3;
+ int64_t f2f4_2 = f2_2 * (int64_t) f4;
+ int64_t f2f5_2 = f2_2 * (int64_t) f5;
+ int64_t f2f6_2 = f2_2 * (int64_t) f6;
+ int64_t f2f7_2 = f2_2 * (int64_t) f7;
+ int64_t f2f8_38 = f2_2 * (int64_t) f8_19;
+ int64_t f2f9_38 = f2 * (int64_t) f9_38;
+ int64_t f3f3_2 = f3_2 * (int64_t) f3;
+ int64_t f3f4_2 = f3_2 * (int64_t) f4;
+ int64_t f3f5_4 = f3_2 * (int64_t) f5_2;
+ int64_t f3f6_2 = f3_2 * (int64_t) f6;
+ int64_t f3f7_76 = f3_2 * (int64_t) f7_38;
+ int64_t f3f8_38 = f3_2 * (int64_t) f8_19;
+ int64_t f3f9_76 = f3_2 * (int64_t) f9_38;
+ int64_t f4f4 = f4 * (int64_t) f4;
+ int64_t f4f5_2 = f4_2 * (int64_t) f5;
+ int64_t f4f6_38 = f4_2 * (int64_t) f6_19;
+ int64_t f4f7_38 = f4 * (int64_t) f7_38;
+ int64_t f4f8_38 = f4_2 * (int64_t) f8_19;
+ int64_t f4f9_38 = f4 * (int64_t) f9_38;
+ int64_t f5f5_38 = f5 * (int64_t) f5_38;
+ int64_t f5f6_38 = f5_2 * (int64_t) f6_19;
+ int64_t f5f7_76 = f5_2 * (int64_t) f7_38;
+ int64_t f5f8_38 = f5_2 * (int64_t) f8_19;
+ int64_t f5f9_76 = f5_2 * (int64_t) f9_38;
+ int64_t f6f6_19 = f6 * (int64_t) f6_19;
+ int64_t f6f7_38 = f6 * (int64_t) f7_38;
+ int64_t f6f8_38 = f6_2 * (int64_t) f8_19;
+ int64_t f6f9_38 = f6 * (int64_t) f9_38;
+ int64_t f7f7_38 = f7 * (int64_t) f7_38;
+ int64_t f7f8_38 = f7_2 * (int64_t) f8_19;
+ int64_t f7f9_76 = f7_2 * (int64_t) f9_38;
+ int64_t f8f8_19 = f8 * (int64_t) f8_19;
+ int64_t f8f9_38 = f8 * (int64_t) f9_38;
+ int64_t f9f9_38 = f9 * (int64_t) f9_38;
+ int64_t h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38;
+ int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38;
+ int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19;
+ int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38;
+ int64_t h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38;
+ int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38;
+ int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19;
+ int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38;
+ int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38;
+ int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2;
+ int64_t carry0;
+ int64_t carry1;
+ int64_t carry2;
+ int64_t carry3;
+ int64_t carry4;
+ int64_t carry5;
+ int64_t carry6;
+ int64_t carry7;
+ int64_t carry8;
+ int64_t carry9;
+
+ h0 += h0;
+ h1 += h1;
+ h2 += h2;
+ h3 += h3;
+ h4 += h4;
+ h5 += h5;
+ h6 += h6;
+ h7 += h7;
+ h8 += h8;
+ h9 += h9;
+
+ carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
+ carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
+
+ carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
+ carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
+
+ carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
+ carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
+
+ carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
+ carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
+
+ carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
+ carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
+
+ carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
+
+ carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
+
+ h[0] = h0;
+ h[1] = h1;
+ h[2] = h2;
+ h[3] = h3;
+ h[4] = h4;
+ h[5] = h5;
+ h[6] = h6;
+ h[7] = h7;
+ h[8] = h8;
+ h[9] = h9;
+}
+
+static void fe_pow22523(fe out, const fe z) {
+ fe t0;
+ fe t1;
+ fe t2;
+ int i;
+
+ fe_sq(t0, z);
+ for (i = 1; i < 1; ++i) {
+ fe_sq(t0, t0);
+ }
+ fe_sq(t1, t0);
+ for (i = 1; i < 2; ++i) {
+ fe_sq(t1, t1);
+ }
+ fe_mul(t1, z, t1);
+ fe_mul(t0, t0, t1);
+ fe_sq(t0, t0);
+ for (i = 1; i < 1; ++i) {
+ fe_sq(t0, t0);
+ }
+ fe_mul(t0, t1, t0);
+ fe_sq(t1, t0);
+ for (i = 1; i < 5; ++i) {
+ fe_sq(t1, t1);
+ }
+ fe_mul(t0, t1, t0);
+ fe_sq(t1, t0);
+ for (i = 1; i < 10; ++i) {
+ fe_sq(t1, t1);
+ }
+ fe_mul(t1, t1, t0);
+ fe_sq(t2, t1);
+ for (i = 1; i < 20; ++i) {
+ fe_sq(t2, t2);
+ }
+ fe_mul(t1, t2, t1);
+ fe_sq(t1, t1);
+ for (i = 1; i < 10; ++i) {
+ fe_sq(t1, t1);
+ }
+ fe_mul(t0, t1, t0);
+ fe_sq(t1, t0);
+ for (i = 1; i < 50; ++i) {
+ fe_sq(t1, t1);
+ }
+ fe_mul(t1, t1, t0);
+ fe_sq(t2, t1);
+ for (i = 1; i < 100; ++i) {
+ fe_sq(t2, t2);
+ }
+ fe_mul(t1, t2, t1);
+ fe_sq(t1, t1);
+ for (i = 1; i < 50; ++i) {
+ fe_sq(t1, t1);
+ }
+ fe_mul(t0, t1, t0);
+ fe_sq(t0, t0);
+ for (i = 1; i < 2; ++i) {
+ fe_sq(t0, t0);
+ }
+ fe_mul(out, t0, z);
+}
+
+/* ge means group element.
+
+ * Here the group is the set of pairs (x,y) of field elements (see fe.h)
+ * satisfying -x^2 + y^2 = 1 + d x^2y^2
+ * where d = -121665/121666.
+ *
+ * Representations:
+ * ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z
+ * ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT
+ * ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T
+ * ge_precomp (Duif): (y+x,y-x,2dxy) */
+
+typedef struct {
+ fe X;
+ fe Y;
+ fe Z;
+} ge_p2;
+
+typedef struct {
+ fe X;
+ fe Y;
+ fe Z;
+ fe T;
+} ge_p3;
+
+typedef struct {
+ fe X;
+ fe Y;
+ fe Z;
+ fe T;
+} ge_p1p1;
+
+typedef struct {
+ fe yplusx;
+ fe yminusx;
+ fe xy2d;
+} ge_precomp;
+
+typedef struct {
+ fe YplusX;
+ fe YminusX;
+ fe Z;
+ fe T2d;
+} ge_cached;
+
+static void ge_tobytes(uint8_t *s, const ge_p2 *h) {
+ fe recip;
+ fe x;
+ fe y;
+
+ fe_invert(recip, h->Z);
+ fe_mul(x, h->X, recip);
+ fe_mul(y, h->Y, recip);
+ fe_tobytes(s, y);
+ s[31] ^= fe_isnegative(x) << 7;
+}
+
+static void ge_p3_tobytes(uint8_t *s, const ge_p3 *h) {
+ fe recip;
+ fe x;
+ fe y;
+
+ fe_invert(recip, h->Z);
+ fe_mul(x, h->X, recip);
+ fe_mul(y, h->Y, recip);
+ fe_tobytes(s, y);
+ s[31] ^= fe_isnegative(x) << 7;
+}
+
+static const fe d = {-10913610, 13857413, -15372611, 6949391, 114729,
+ -8787816, -6275908, -3247719, -18696448, -12055116};
+
+static const fe sqrtm1 = {-32595792, -7943725, 9377950, 3500415, 12389472,
+ -272473, -25146209, -2005654, 326686, 11406482};
+
+static int ge_frombytes_negate_vartime(ge_p3 *h, const uint8_t *s) {
+ fe u;
+ fe v;
+ fe v3;
+ fe vxx;
+ fe check;
+
+ fe_frombytes(h->Y, s);
+ fe_1(h->Z);
+ fe_sq(u, h->Y);
+ fe_mul(v, u, d);
+ fe_sub(u, u, h->Z); /* u = y^2-1 */
+ fe_add(v, v, h->Z); /* v = dy^2+1 */
+
+ fe_sq(v3, v);
+ fe_mul(v3, v3, v); /* v3 = v^3 */
+ fe_sq(h->X, v3);
+ fe_mul(h->X, h->X, v);
+ fe_mul(h->X, h->X, u); /* x = uv^7 */
+
+ fe_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */
+ fe_mul(h->X, h->X, v3);
+ fe_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */
+
+ fe_sq(vxx, h->X);
+ fe_mul(vxx, vxx, v);
+ fe_sub(check, vxx, u); /* vx^2-u */
+ if (fe_isnonzero(check)) {
+ fe_add(check, vxx, u); /* vx^2+u */
+ if (fe_isnonzero(check)) {
+ return -1;
+ }
+ fe_mul(h->X, h->X, sqrtm1);
+ }
+
+ if (fe_isnegative(h->X) == (s[31] >> 7)) {
+ fe_neg(h->X, h->X);
+ }
+
+ fe_mul(h->T, h->X, h->Y);
+ return 0;
+}
+
+static void ge_p2_0(ge_p2 *h) {
+ fe_0(h->X);
+ fe_1(h->Y);
+ fe_1(h->Z);
+}
+
+static void ge_p3_0(ge_p3 *h) {
+ fe_0(h->X);
+ fe_1(h->Y);
+ fe_1(h->Z);
+ fe_0(h->T);
+}
+
+static void ge_precomp_0(ge_precomp *h) {
+ fe_1(h->yplusx);
+ fe_1(h->yminusx);
+ fe_0(h->xy2d);
+}
+
+/* r = p */
+static void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) {
+ fe_copy(r->X, p->X);
+ fe_copy(r->Y, p->Y);
+ fe_copy(r->Z, p->Z);
+}
+
+static const fe d2 = {-21827239, -5839606, -30745221, 13898782, 229458,
+ 15978800, -12551817, -6495438, 29715968, 9444199};
+
+/* r = p */
+static void ge_p3_to_cached(ge_cached *r, const ge_p3 *p) {
+ fe_add(r->YplusX, p->Y, p->X);
+ fe_sub(r->YminusX, p->Y, p->X);
+ fe_copy(r->Z, p->Z);
+ fe_mul(r->T2d, p->T, d2);
+}
+
+/* r = p */
+static void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) {
+ fe_mul(r->X, p->X, p->T);
+ fe_mul(r->Y, p->Y, p->Z);
+ fe_mul(r->Z, p->Z, p->T);
+}
+
+/* r = p */
+static void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) {
+ fe_mul(r->X, p->X, p->T);
+ fe_mul(r->Y, p->Y, p->Z);
+ fe_mul(r->Z, p->Z, p->T);
+ fe_mul(r->T, p->X, p->Y);
+}
+
+/* r = 2 * p */
+static void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) {
+ fe t0;
+
+ fe_sq(r->X, p->X);
+ fe_sq(r->Z, p->Y);
+ fe_sq2(r->T, p->Z);
+ fe_add(r->Y, p->X, p->Y);
+ fe_sq(t0, r->Y);
+ fe_add(r->Y, r->Z, r->X);
+ fe_sub(r->Z, r->Z, r->X);
+ fe_sub(r->X, t0, r->Y);
+ fe_sub(r->T, r->T, r->Z);
+}
+
+/* r = 2 * p */
+static void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) {
+ ge_p2 q;
+ ge_p3_to_p2(&q, p);
+ ge_p2_dbl(r, &q);
+}
+
+/* r = p + q */
+static void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
+ fe t0;
+
+ fe_add(r->X, p->Y, p->X);
+ fe_sub(r->Y, p->Y, p->X);
+ fe_mul(r->Z, r->X, q->yplusx);
+ fe_mul(r->Y, r->Y, q->yminusx);
+ fe_mul(r->T, q->xy2d, p->T);
+ fe_add(t0, p->Z, p->Z);
+ fe_sub(r->X, r->Z, r->Y);
+ fe_add(r->Y, r->Z, r->Y);
+ fe_add(r->Z, t0, r->T);
+ fe_sub(r->T, t0, r->T);
+}
+
+/* r = p - q */
+static void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
+ fe t0;
+
+ fe_add(r->X, p->Y, p->X);
+ fe_sub(r->Y, p->Y, p->X);
+ fe_mul(r->Z, r->X, q->yminusx);
+ fe_mul(r->Y, r->Y, q->yplusx);
+ fe_mul(r->T, q->xy2d, p->T);
+ fe_add(t0, p->Z, p->Z);
+ fe_sub(r->X, r->Z, r->Y);
+ fe_add(r->Y, r->Z, r->Y);
+ fe_sub(r->Z, t0, r->T);
+ fe_add(r->T, t0, r->T);
+}
+
+/* r = p + q */
+static void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
+ fe t0;
+
+ fe_add(r->X, p->Y, p->X);
+ fe_sub(r->Y, p->Y, p->X);
+ fe_mul(r->Z, r->X, q->YplusX);
+ fe_mul(r->Y, r->Y, q->YminusX);
+ fe_mul(r->T, q->T2d, p->T);
+ fe_mul(r->X, p->Z, q->Z);
+ fe_add(t0, r->X, r->X);
+ fe_sub(r->X, r->Z, r->Y);
+ fe_add(r->Y, r->Z, r->Y);
+ fe_add(r->Z, t0, r->T);
+ fe_sub(r->T, t0, r->T);
+}
+
+/* r = p - q */
+static void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
+ fe t0;
+
+ fe_add(r->X, p->Y, p->X);
+ fe_sub(r->Y, p->Y, p->X);
+ fe_mul(r->Z, r->X, q->YminusX);
+ fe_mul(r->Y, r->Y, q->YplusX);
+ fe_mul(r->T, q->T2d, p->T);
+ fe_mul(r->X, p->Z, q->Z);
+ fe_add(t0, r->X, r->X);
+ fe_sub(r->X, r->Z, r->Y);
+ fe_add(r->Y, r->Z, r->Y);
+ fe_sub(r->Z, t0, r->T);
+ fe_add(r->T, t0, r->T);
+}
+
+static uint8_t equal(signed char b, signed char c) {
+ uint8_t ub = b;
+ uint8_t uc = c;
+ uint8_t x = ub ^ uc; /* 0: yes; 1..255: no */
+ uint32_t y = x; /* 0: yes; 1..255: no */
+ y -= 1; /* 4294967295: yes; 0..254: no */
+ y >>= 31; /* 1: yes; 0: no */
+ return y;
+}
+
+static void cmov(ge_precomp *t, ge_precomp *u, uint8_t b) {
+ fe_cmov(t->yplusx, u->yplusx, b);
+ fe_cmov(t->yminusx, u->yminusx, b);
+ fe_cmov(t->xy2d, u->xy2d, b);
+}
+
+#if defined(OPENSSL_SMALL)
+
+/* This block of code replaces the standard base-point table with a much smaller
+ * one. The standard table is 30,720 bytes while this one is just 960.
+ *
+ * This table contains 15 pairs of group elements, (x, y), where each field
+ * element is serialised with |fe_tobytes|. If |i| is the index of the group
+ * element then consider i+1 as a four-bit number: (i₀, i₁, i₂, i₃) (where i₀
+ * is the most significant bit). The value of the group element is then:
+ * (i₀×2^192 + i₁×2^128 + i₂×2^64 + i₃)G, where G is the generator. */
+static const uint8_t kSmallPrecomp[15 * 2 * 32] = {
+ 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, 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, 0x02, 0xa2, 0xed, 0xf4, 0x8f, 0x6b, 0x0b, 0x3e,
+ 0xeb, 0x35, 0x1a, 0xd5, 0x7e, 0xdb, 0x78, 0x00, 0x96, 0x8a, 0xa0, 0xb4,
+ 0xcf, 0x60, 0x4b, 0xd4, 0xd5, 0xf9, 0x2d, 0xbf, 0x88, 0xbd, 0x22, 0x62,
+ 0x13, 0x53, 0xe4, 0x82, 0x57, 0xfa, 0x1e, 0x8f, 0x06, 0x2b, 0x90, 0xba,
+ 0x08, 0xb6, 0x10, 0x54, 0x4f, 0x7c, 0x1b, 0x26, 0xed, 0xda, 0x6b, 0xdd,
+ 0x25, 0xd0, 0x4e, 0xea, 0x42, 0xbb, 0x25, 0x03, 0xa2, 0xfb, 0xcc, 0x61,
+ 0x67, 0x06, 0x70, 0x1a, 0xc4, 0x78, 0x3a, 0xff, 0x32, 0x62, 0xdd, 0x2c,
+ 0xab, 0x50, 0x19, 0x3b, 0xf2, 0x9b, 0x7d, 0xb8, 0xfd, 0x4f, 0x29, 0x9c,
+ 0xa7, 0x91, 0xba, 0x0e, 0x46, 0x5e, 0x51, 0xfe, 0x1d, 0xbf, 0xe5, 0xe5,
+ 0x9b, 0x95, 0x0d, 0x67, 0xf8, 0xd1, 0xb5, 0x5a, 0xa1, 0x93, 0x2c, 0xc3,
+ 0xde, 0x0e, 0x97, 0x85, 0x2d, 0x7f, 0xea, 0xab, 0x3e, 0x47, 0x30, 0x18,
+ 0x24, 0xe8, 0xb7, 0x60, 0xae, 0x47, 0x80, 0xfc, 0xe5, 0x23, 0xe7, 0xc2,
+ 0xc9, 0x85, 0xe6, 0x98, 0xa0, 0x29, 0x4e, 0xe1, 0x84, 0x39, 0x2d, 0x95,
+ 0x2c, 0xf3, 0x45, 0x3c, 0xff, 0xaf, 0x27, 0x4c, 0x6b, 0xa6, 0xf5, 0x4b,
+ 0x11, 0xbd, 0xba, 0x5b, 0x9e, 0xc4, 0xa4, 0x51, 0x1e, 0xbe, 0xd0, 0x90,
+ 0x3a, 0x9c, 0xc2, 0x26, 0xb6, 0x1e, 0xf1, 0x95, 0x7d, 0xc8, 0x6d, 0x52,
+ 0xe6, 0x99, 0x2c, 0x5f, 0x9a, 0x96, 0x0c, 0x68, 0x29, 0xfd, 0xe2, 0xfb,
+ 0xe6, 0xbc, 0xec, 0x31, 0x08, 0xec, 0xe6, 0xb0, 0x53, 0x60, 0xc3, 0x8c,
+ 0xbe, 0xc1, 0xb3, 0x8a, 0x8f, 0xe4, 0x88, 0x2b, 0x55, 0xe5, 0x64, 0x6e,
+ 0x9b, 0xd0, 0xaf, 0x7b, 0x64, 0x2a, 0x35, 0x25, 0x10, 0x52, 0xc5, 0x9e,
+ 0x58, 0x11, 0x39, 0x36, 0x45, 0x51, 0xb8, 0x39, 0x93, 0xfc, 0x9d, 0x6a,
+ 0xbe, 0x58, 0xcb, 0xa4, 0x0f, 0x51, 0x3c, 0x38, 0x05, 0xca, 0xab, 0x43,
+ 0x63, 0x0e, 0xf3, 0x8b, 0x41, 0xa6, 0xf8, 0x9b, 0x53, 0x70, 0x80, 0x53,
+ 0x86, 0x5e, 0x8f, 0xe3, 0xc3, 0x0d, 0x18, 0xc8, 0x4b, 0x34, 0x1f, 0xd8,
+ 0x1d, 0xbc, 0xf2, 0x6d, 0x34, 0x3a, 0xbe, 0xdf, 0xd9, 0xf6, 0xf3, 0x89,
+ 0xa1, 0xe1, 0x94, 0x9f, 0x5d, 0x4c, 0x5d, 0xe9, 0xa1, 0x49, 0x92, 0xef,
+ 0x0e, 0x53, 0x81, 0x89, 0x58, 0x87, 0xa6, 0x37, 0xf1, 0xdd, 0x62, 0x60,
+ 0x63, 0x5a, 0x9d, 0x1b, 0x8c, 0xc6, 0x7d, 0x52, 0xea, 0x70, 0x09, 0x6a,
+ 0xe1, 0x32, 0xf3, 0x73, 0x21, 0x1f, 0x07, 0x7b, 0x7c, 0x9b, 0x49, 0xd8,
+ 0xc0, 0xf3, 0x25, 0x72, 0x6f, 0x9d, 0xed, 0x31, 0x67, 0x36, 0x36, 0x54,
+ 0x40, 0x92, 0x71, 0xe6, 0x11, 0x28, 0x11, 0xad, 0x93, 0x32, 0x85, 0x7b,
+ 0x3e, 0xb7, 0x3b, 0x49, 0x13, 0x1c, 0x07, 0xb0, 0x2e, 0x93, 0xaa, 0xfd,
+ 0xfd, 0x28, 0x47, 0x3d, 0x8d, 0xd2, 0xda, 0xc7, 0x44, 0xd6, 0x7a, 0xdb,
+ 0x26, 0x7d, 0x1d, 0xb8, 0xe1, 0xde, 0x9d, 0x7a, 0x7d, 0x17, 0x7e, 0x1c,
+ 0x37, 0x04, 0x8d, 0x2d, 0x7c, 0x5e, 0x18, 0x38, 0x1e, 0xaf, 0xc7, 0x1b,
+ 0x33, 0x48, 0x31, 0x00, 0x59, 0xf6, 0xf2, 0xca, 0x0f, 0x27, 0x1b, 0x63,
+ 0x12, 0x7e, 0x02, 0x1d, 0x49, 0xc0, 0x5d, 0x79, 0x87, 0xef, 0x5e, 0x7a,
+ 0x2f, 0x1f, 0x66, 0x55, 0xd8, 0x09, 0xd9, 0x61, 0x38, 0x68, 0xb0, 0x07,
+ 0xa3, 0xfc, 0xcc, 0x85, 0x10, 0x7f, 0x4c, 0x65, 0x65, 0xb3, 0xfa, 0xfa,
+ 0xa5, 0x53, 0x6f, 0xdb, 0x74, 0x4c, 0x56, 0x46, 0x03, 0xe2, 0xd5, 0x7a,
+ 0x29, 0x1c, 0xc6, 0x02, 0xbc, 0x59, 0xf2, 0x04, 0x75, 0x63, 0xc0, 0x84,
+ 0x2f, 0x60, 0x1c, 0x67, 0x76, 0xfd, 0x63, 0x86, 0xf3, 0xfa, 0xbf, 0xdc,
+ 0xd2, 0x2d, 0x90, 0x91, 0xbd, 0x33, 0xa9, 0xe5, 0x66, 0x0c, 0xda, 0x42,
+ 0x27, 0xca, 0xf4, 0x66, 0xc2, 0xec, 0x92, 0x14, 0x57, 0x06, 0x63, 0xd0,
+ 0x4d, 0x15, 0x06, 0xeb, 0x69, 0x58, 0x4f, 0x77, 0xc5, 0x8b, 0xc7, 0xf0,
+ 0x8e, 0xed, 0x64, 0xa0, 0xb3, 0x3c, 0x66, 0x71, 0xc6, 0x2d, 0xda, 0x0a,
+ 0x0d, 0xfe, 0x70, 0x27, 0x64, 0xf8, 0x27, 0xfa, 0xf6, 0x5f, 0x30, 0xa5,
+ 0x0d, 0x6c, 0xda, 0xf2, 0x62, 0x5e, 0x78, 0x47, 0xd3, 0x66, 0x00, 0x1c,
+ 0xfd, 0x56, 0x1f, 0x5d, 0x3f, 0x6f, 0xf4, 0x4c, 0xd8, 0xfd, 0x0e, 0x27,
+ 0xc9, 0x5c, 0x2b, 0xbc, 0xc0, 0xa4, 0xe7, 0x23, 0x29, 0x02, 0x9f, 0x31,
+ 0xd6, 0xe9, 0xd7, 0x96, 0xf4, 0xe0, 0x5e, 0x0b, 0x0e, 0x13, 0xee, 0x3c,
+ 0x09, 0xed, 0xf2, 0x3d, 0x76, 0x91, 0xc3, 0xa4, 0x97, 0xae, 0xd4, 0x87,
+ 0xd0, 0x5d, 0xf6, 0x18, 0x47, 0x1f, 0x1d, 0x67, 0xf2, 0xcf, 0x63, 0xa0,
+ 0x91, 0x27, 0xf8, 0x93, 0x45, 0x75, 0x23, 0x3f, 0xd1, 0xf1, 0xad, 0x23,
+ 0xdd, 0x64, 0x93, 0x96, 0x41, 0x70, 0x7f, 0xf7, 0xf5, 0xa9, 0x89, 0xa2,
+ 0x34, 0xb0, 0x8d, 0x1b, 0xae, 0x19, 0x15, 0x49, 0x58, 0x23, 0x6d, 0x87,
+ 0x15, 0x4f, 0x81, 0x76, 0xfb, 0x23, 0xb5, 0xea, 0xcf, 0xac, 0x54, 0x8d,
+ 0x4e, 0x42, 0x2f, 0xeb, 0x0f, 0x63, 0xdb, 0x68, 0x37, 0xa8, 0xcf, 0x8b,
+ 0xab, 0xf5, 0xa4, 0x6e, 0x96, 0x2a, 0xb2, 0xd6, 0xbe, 0x9e, 0xbd, 0x0d,
+ 0xb4, 0x42, 0xa9, 0xcf, 0x01, 0x83, 0x8a, 0x17, 0x47, 0x76, 0xc4, 0xc6,
+ 0x83, 0x04, 0x95, 0x0b, 0xfc, 0x11, 0xc9, 0x62, 0xb8, 0x0c, 0x76, 0x84,
+ 0xd9, 0xb9, 0x37, 0xfa, 0xfc, 0x7c, 0xc2, 0x6d, 0x58, 0x3e, 0xb3, 0x04,
+ 0xbb, 0x8c, 0x8f, 0x48, 0xbc, 0x91, 0x27, 0xcc, 0xf9, 0xb7, 0x22, 0x19,
+ 0x83, 0x2e, 0x09, 0xb5, 0x72, 0xd9, 0x54, 0x1c, 0x4d, 0xa1, 0xea, 0x0b,
+ 0xf1, 0xc6, 0x08, 0x72, 0x46, 0x87, 0x7a, 0x6e, 0x80, 0x56, 0x0a, 0x8a,
+ 0xc0, 0xdd, 0x11, 0x6b, 0xd6, 0xdd, 0x47, 0xdf, 0x10, 0xd9, 0xd8, 0xea,
+ 0x7c, 0xb0, 0x8f, 0x03, 0x00, 0x2e, 0xc1, 0x8f, 0x44, 0xa8, 0xd3, 0x30,
+ 0x06, 0x89, 0xa2, 0xf9, 0x34, 0xad, 0xdc, 0x03, 0x85, 0xed, 0x51, 0xa7,
+ 0x82, 0x9c, 0xe7, 0x5d, 0x52, 0x93, 0x0c, 0x32, 0x9a, 0x5b, 0xe1, 0xaa,
+ 0xca, 0xb8, 0x02, 0x6d, 0x3a, 0xd4, 0xb1, 0x3a, 0xf0, 0x5f, 0xbe, 0xb5,
+ 0x0d, 0x10, 0x6b, 0x38, 0x32, 0xac, 0x76, 0x80, 0xbd, 0xca, 0x94, 0x71,
+ 0x7a, 0xf2, 0xc9, 0x35, 0x2a, 0xde, 0x9f, 0x42, 0x49, 0x18, 0x01, 0xab,
+ 0xbc, 0xef, 0x7c, 0x64, 0x3f, 0x58, 0x3d, 0x92, 0x59, 0xdb, 0x13, 0xdb,
+ 0x58, 0x6e, 0x0a, 0xe0, 0xb7, 0x91, 0x4a, 0x08, 0x20, 0xd6, 0x2e, 0x3c,
+ 0x45, 0xc9, 0x8b, 0x17, 0x79, 0xe7, 0xc7, 0x90, 0x99, 0x3a, 0x18, 0x25,
+};
+
+static void ge_scalarmult_base(ge_p3 *h, const uint8_t a[32]) {
+ /* kSmallPrecomp is first expanded into matching |ge_precomp| elements. */
+ ge_precomp multiples[15];
+
+ unsigned i;
+ for (i = 0; i < 15; i++) {
+ const uint8_t *bytes = &kSmallPrecomp[i*(2 * 32)];
+ fe x, y;
+ fe_frombytes(x, bytes);
+ fe_frombytes(y, bytes + 32);
+
+ ge_precomp *out = &multiples[i];
+ fe_add(out->yplusx, y, x);
+ fe_sub(out->yminusx, y, x);
+ fe_mul(out->xy2d, x, y);
+ fe_mul(out->xy2d, out->xy2d, d2);
+ }
+
+ /* See the comment above |kSmallPrecomp| about the structure of the
+ * precomputed elements. This loop does 64 additions and 64 doublings to
+ * calculate the result. */
+ ge_p3_0(h);
+
+ for (i = 63; i < 64; i--) {
+ unsigned j;
+ signed char index = 0;
+
+ for (j = 0; j < 4; j++) {
+ const uint8_t bit = 1 & (a[(8 * j) + (i / 8)] >> (i & 7));
+ index |= (bit << j);
+ }
+
+ ge_precomp e;
+ ge_precomp_0(&e);
+
+ for (j = 1; j < 16; j++) {
+ cmov(&e, &multiples[j-1], equal(index, j));
+ }
+
+ ge_cached cached;
+ ge_p1p1 r;
+ ge_p3_to_cached(&cached, h);
+ ge_add(&r, h, &cached);
+ ge_p1p1_to_p3(h, &r);
+
+ ge_madd(&r, h, &e);
+ ge_p1p1_to_p3(h, &r);
+ }
+}
+
+#else
+
+/* base[i][j] = (j+1)*256^i*B */
+static ge_precomp base[32][8] = {
+ {
+ {
+ {25967493, -14356035, 29566456, 3660896, -12694345, 4014787,
+ 27544626, -11754271, -6079156, 2047605},
+ {-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692,
+ 5043384, 19500929, -15469378},
+ {-8738181, 4489570, 9688441, -14785194, 10184609, -12363380,
+ 29287919, 11864899, -24514362, -4438546},
+ },
+ {
+ {-12815894, -12976347, -21581243, 11784320, -25355658, -2750717,
+ -11717903, -3814571, -358445, -10211303},
+ {-21703237, 6903825, 27185491, 6451973, -29577724, -9554005,
+ -15616551, 11189268, -26829678, -5319081},
+ {26966642, 11152617, 32442495, 15396054, 14353839, -12752335,
+ -3128826, -9541118, -15472047, -4166697},
+ },
+ {
+ {15636291, -9688557, 24204773, -7912398, 616977, -16685262,
+ 27787600, -14772189, 28944400, -1550024},
+ {16568933, 4717097, -11556148, -1102322, 15682896, -11807043,
+ 16354577, -11775962, 7689662, 11199574},
+ {30464156, -5976125, -11779434, -15670865, 23220365, 15915852,
+ 7512774, 10017326, -17749093, -9920357},
+ },
+ {
+ {-17036878, 13921892, 10945806, -6033431, 27105052, -16084379,
+ -28926210, 15006023, 3284568, -6276540},
+ {23599295, -8306047, -11193664, -7687416, 13236774, 10506355,
+ 7464579, 9656445, 13059162, 10374397},
+ {7798556, 16710257, 3033922, 2874086, 28997861, 2835604, 32406664,
+ -3839045, -641708, -101325},
+ },
+ {
+ {10861363, 11473154, 27284546, 1981175, -30064349, 12577861,
+ 32867885, 14515107, -15438304, 10819380},
+ {4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668,
+ 12483688, -12668491, 5581306},
+ {19563160, 16186464, -29386857, 4097519, 10237984, -4348115,
+ 28542350, 13850243, -23678021, -15815942},
+ },
+ {
+ {-15371964, -12862754, 32573250, 4720197, -26436522, 5875511,
+ -19188627, -15224819, -9818940, -12085777},
+ {-8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240,
+ -15689887, 1762328, 14866737},
+ {-18199695, -15951423, -10473290, 1707278, -17185920, 3916101,
+ -28236412, 3959421, 27914454, 4383652},
+ },
+ {
+ {5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852,
+ 5230134, -23952439, -15175766},
+ {-30269007, -3463509, 7665486, 10083793, 28475525, 1649722,
+ 20654025, 16520125, 30598449, 7715701},
+ {28881845, 14381568, 9657904, 3680757, -20181635, 7843316,
+ -31400660, 1370708, 29794553, -1409300},
+ },
+ {
+ {14499471, -2729599, -33191113, -4254652, 28494862, 14271267,
+ 30290735, 10876454, -33154098, 2381726},
+ {-7195431, -2655363, -14730155, 462251, -27724326, 3941372,
+ -6236617, 3696005, -32300832, 15351955},
+ {27431194, 8222322, 16448760, -3907995, -18707002, 11938355,
+ -32961401, -2970515, 29551813, 10109425},
+ },
+ },
+ {
+ {
+ {-13657040, -13155431, -31283750, 11777098, 21447386, 6519384,
+ -2378284, -1627556, 10092783, -4764171},
+ {27939166, 14210322, 4677035, 16277044, -22964462, -12398139,
+ -32508754, 12005538, -17810127, 12803510},
+ {17228999, -15661624, -1233527, 300140, -1224870, -11714777,
+ 30364213, -9038194, 18016357, 4397660},
+ },
+ {
+ {-10958843, -7690207, 4776341, -14954238, 27850028, -15602212,
+ -26619106, 14544525, -17477504, 982639},
+ {29253598, 15796703, -2863982, -9908884, 10057023, 3163536, 7332899,
+ -4120128, -21047696, 9934963},
+ {5793303, 16271923, -24131614, -10116404, 29188560, 1206517,
+ -14747930, 4559895, -30123922, -10897950},
+ },
+ {
+ {-27643952, -11493006, 16282657, -11036493, 28414021, -15012264,
+ 24191034, 4541697, -13338309, 5500568},
+ {12650548, -1497113, 9052871, 11355358, -17680037, -8400164,
+ -17430592, 12264343, 10874051, 13524335},
+ {25556948, -3045990, 714651, 2510400, 23394682, -10415330, 33119038,
+ 5080568, -22528059, 5376628},
+ },
+ {
+ {-26088264, -4011052, -17013699, -3537628, -6726793, 1920897,
+ -22321305, -9447443, 4535768, 1569007},
+ {-2255422, 14606630, -21692440, -8039818, 28430649, 8775819,
+ -30494562, 3044290, 31848280, 12543772},
+ {-22028579, 2943893, -31857513, 6777306, 13784462, -4292203,
+ -27377195, -2062731, 7718482, 14474653},
+ },
+ {
+ {2385315, 2454213, -22631320, 46603, -4437935, -15680415, 656965,
+ -7236665, 24316168, -5253567},
+ {13741529, 10911568, -33233417, -8603737, -20177830, -1033297,
+ 33040651, -13424532, -20729456, 8321686},
+ {21060490, -2212744, 15712757, -4336099, 1639040, 10656336,
+ 23845965, -11874838, -9984458, 608372},
+ },
+ {
+ {-13672732, -15087586, -10889693, -7557059, -6036909, 11305547,
+ 1123968, -6780577, 27229399, 23887},
+ {-23244140, -294205, -11744728, 14712571, -29465699, -2029617,
+ 12797024, -6440308, -1633405, 16678954},
+ {-29500620, 4770662, -16054387, 14001338, 7830047, 9564805,
+ -1508144, -4795045, -17169265, 4904953},
+ },
+ {
+ {24059557, 14617003, 19037157, -15039908, 19766093, -14906429,
+ 5169211, 16191880, 2128236, -4326833},
+ {-16981152, 4124966, -8540610, -10653797, 30336522, -14105247,
+ -29806336, 916033, -6882542, -2986532},
+ {-22630907, 12419372, -7134229, -7473371, -16478904, 16739175,
+ 285431, 2763829, 15736322, 4143876},
+ },
+ {
+ {2379352, 11839345, -4110402, -5988665, 11274298, 794957, 212801,
+ -14594663, 23527084, -16458268},
+ {33431127, -11130478, -17838966, -15626900, 8909499, 8376530,
+ -32625340, 4087881, -15188911, -14416214},
+ {1767683, 7197987, -13205226, -2022635, -13091350, 448826, 5799055,
+ 4357868, -4774191, -16323038},
+ },
+ },
+ {
+ {
+ {6721966, 13833823, -23523388, -1551314, 26354293, -11863321,
+ 23365147, -3949732, 7390890, 2759800},
+ {4409041, 2052381, 23373853, 10530217, 7676779, -12885954, 21302353,
+ -4264057, 1244380, -12919645},
+ {-4421239, 7169619, 4982368, -2957590, 30256825, -2777540, 14086413,
+ 9208236, 15886429, 16489664},
+ },
+ {
+ {1996075, 10375649, 14346367, 13311202, -6874135, -16438411,
+ -13693198, 398369, -30606455, -712933},
+ {-25307465, 9795880, -2777414, 14878809, -33531835, 14780363,
+ 13348553, 12076947, -30836462, 5113182},
+ {-17770784, 11797796, 31950843, 13929123, -25888302, 12288344,
+ -30341101, -7336386, 13847711, 5387222},
+ },
+ {
+ {-18582163, -3416217, 17824843, -2340966, 22744343, -10442611,
+ 8763061, 3617786, -19600662, 10370991},
+ {20246567, -14369378, 22358229, -543712, 18507283, -10413996,
+ 14554437, -8746092, 32232924, 16763880},
+ {9648505, 10094563, 26416693, 14745928, -30374318, -6472621,
+ 11094161, 15689506, 3140038, -16510092},
+ },
+ {
+ {-16160072, 5472695, 31895588, 4744994, 8823515, 10365685,
+ -27224800, 9448613, -28774454, 366295},
+ {19153450, 11523972, -11096490, -6503142, -24647631, 5420647,
+ 28344573, 8041113, 719605, 11671788},
+ {8678025, 2694440, -6808014, 2517372, 4964326, 11152271, -15432916,
+ -15266516, 27000813, -10195553},
+ },
+ {
+ {-15157904, 7134312, 8639287, -2814877, -7235688, 10421742, 564065,
+ 5336097, 6750977, -14521026},
+ {11836410, -3979488, 26297894, 16080799, 23455045, 15735944,
+ 1695823, -8819122, 8169720, 16220347},
+ {-18115838, 8653647, 17578566, -6092619, -8025777, -16012763,
+ -11144307, -2627664, -5990708, -14166033},
+ },
+ {
+ {-23308498, -10968312, 15213228, -10081214, -30853605, -11050004,
+ 27884329, 2847284, 2655861, 1738395},
+ {-27537433, -14253021, -25336301, -8002780, -9370762, 8129821,
+ 21651608, -3239336, -19087449, -11005278},
+ {1533110, 3437855, 23735889, 459276, 29970501, 11335377, 26030092,
+ 5821408, 10478196, 8544890},
+ },
+ {
+ {32173121, -16129311, 24896207, 3921497, 22579056, -3410854,
+ 19270449, 12217473, 17789017, -3395995},
+ {-30552961, -2228401, -15578829, -10147201, 13243889, 517024,
+ 15479401, -3853233, 30460520, 1052596},
+ {-11614875, 13323618, 32618793, 8175907, -15230173, 12596687,
+ 27491595, -4612359, 3179268, -9478891},
+ },
+ {
+ {31947069, -14366651, -4640583, -15339921, -15125977, -6039709,
+ -14756777, -16411740, 19072640, -9511060},
+ {11685058, 11822410, 3158003, -13952594, 33402194, -4165066,
+ 5977896, -5215017, 473099, 5040608},
+ {-20290863, 8198642, -27410132, 11602123, 1290375, -2799760,
+ 28326862, 1721092, -19558642, -3131606},
+ },
+ },
+ {
+ {
+ {7881532, 10687937, 7578723, 7738378, -18951012, -2553952, 21820786,
+ 8076149, -27868496, 11538389},
+ {-19935666, 3899861, 18283497, -6801568, -15728660, -11249211,
+ 8754525, 7446702, -5676054, 5797016},
+ {-11295600, -3793569, -15782110, -7964573, 12708869, -8456199,
+ 2014099, -9050574, -2369172, -5877341},
+ },
+ {
+ {-22472376, -11568741, -27682020, 1146375, 18956691, 16640559,
+ 1192730, -3714199, 15123619, 10811505},
+ {14352098, -3419715, -18942044, 10822655, 32750596, 4699007, -70363,
+ 15776356, -28886779, -11974553},
+ {-28241164, -8072475, -4978962, -5315317, 29416931, 1847569,
+ -20654173, -16484855, 4714547, -9600655},
+ },
+ {
+ {15200332, 8368572, 19679101, 15970074, -31872674, 1959451,
+ 24611599, -4543832, -11745876, 12340220},
+ {12876937, -10480056, 33134381, 6590940, -6307776, 14872440,
+ 9613953, 8241152, 15370987, 9608631},
+ {-4143277, -12014408, 8446281, -391603, 4407738, 13629032, -7724868,
+ 15866074, -28210621, -8814099},
+ },
+ {
+ {26660628, -15677655, 8393734, 358047, -7401291, 992988, -23904233,
+ 858697, 20571223, 8420556},
+ {14620715, 13067227, -15447274, 8264467, 14106269, 15080814,
+ 33531827, 12516406, -21574435, -12476749},
+ {236881, 10476226, 57258, -14677024, 6472998, 2466984, 17258519,
+ 7256740, 8791136, 15069930},
+ },
+ {
+ {1276410, -9371918, 22949635, -16322807, -23493039, -5702186,
+ 14711875, 4874229, -30663140, -2331391},
+ {5855666, 4990204, -13711848, 7294284, -7804282, 1924647, -1423175,
+ -7912378, -33069337, 9234253},
+ {20590503, -9018988, 31529744, -7352666, -2706834, 10650548,
+ 31559055, -11609587, 18979186, 13396066},
+ },
+ {
+ {24474287, 4968103, 22267082, 4407354, 24063882, -8325180,
+ -18816887, 13594782, 33514650, 7021958},
+ {-11566906, -6565505, -21365085, 15928892, -26158305, 4315421,
+ -25948728, -3916677, -21480480, 12868082},
+ {-28635013, 13504661, 19988037, -2132761, 21078225, 6443208,
+ -21446107, 2244500, -12455797, -8089383},
+ },
+ {
+ {-30595528, 13793479, -5852820, 319136, -25723172, -6263899,
+ 33086546, 8957937, -15233648, 5540521},
+ {-11630176, -11503902, -8119500, -7643073, 2620056, 1022908,
+ -23710744, -1568984, -16128528, -14962807},
+ {23152971, 775386, 27395463, 14006635, -9701118, 4649512, 1689819,
+ 892185, -11513277, -15205948},
+ },
+ {
+ {9770129, 9586738, 26496094, 4324120, 1556511, -3550024, 27453819,
+ 4763127, -19179614, 5867134},
+ {-32765025, 1927590, 31726409, -4753295, 23962434, -16019500,
+ 27846559, 5931263, -29749703, -16108455},
+ {27461885, -2977536, 22380810, 1815854, -23033753, -3031938,
+ 7283490, -15148073, -19526700, 7734629},
+ },
+ },
+ {
+ {
+ {-8010264, -9590817, -11120403, 6196038, 29344158, -13430885,
+ 7585295, -3176626, 18549497, 15302069},
+ {-32658337, -6171222, -7672793, -11051681, 6258878, 13504381,
+ 10458790, -6418461, -8872242, 8424746},
+ {24687205, 8613276, -30667046, -3233545, 1863892, -1830544,
+ 19206234, 7134917, -11284482, -828919},
+ },
+ {
+ {11334899, -9218022, 8025293, 12707519, 17523892, -10476071,
+ 10243738, -14685461, -5066034, 16498837},
+ {8911542, 6887158, -9584260, -6958590, 11145641, -9543680, 17303925,
+ -14124238, 6536641, 10543906},
+ {-28946384, 15479763, -17466835, 568876, -1497683, 11223454,
+ -2669190, -16625574, -27235709, 8876771},
+ },
+ {
+ {-25742899, -12566864, -15649966, -846607, -33026686, -796288,
+ -33481822, 15824474, -604426, -9039817},
+ {10330056, 70051, 7957388, -9002667, 9764902, 15609756, 27698697,
+ -4890037, 1657394, 3084098},
+ {10477963, -7470260, 12119566, -13250805, 29016247, -5365589,
+ 31280319, 14396151, -30233575, 15272409},
+ },
+ {
+ {-12288309, 3169463, 28813183, 16658753, 25116432, -5630466,
+ -25173957, -12636138, -25014757, 1950504},
+ {-26180358, 9489187, 11053416, -14746161, -31053720, 5825630,
+ -8384306, -8767532, 15341279, 8373727},
+ {28685821, 7759505, -14378516, -12002860, -31971820, 4079242,
+ 298136, -10232602, -2878207, 15190420},
+ },
+ {
+ {-32932876, 13806336, -14337485, -15794431, -24004620, 10940928,
+ 8669718, 2742393, -26033313, -6875003},
+ {-1580388, -11729417, -25979658, -11445023, -17411874, -10912854,
+ 9291594, -16247779, -12154742, 6048605},
+ {-30305315, 14843444, 1539301, 11864366, 20201677, 1900163,
+ 13934231, 5128323, 11213262, 9168384},
+ },
+ {
+ {-26280513, 11007847, 19408960, -940758, -18592965, -4328580,
+ -5088060, -11105150, 20470157, -16398701},
+ {-23136053, 9282192, 14855179, -15390078, -7362815, -14408560,
+ -22783952, 14461608, 14042978, 5230683},
+ {29969567, -2741594, -16711867, -8552442, 9175486, -2468974,
+ 21556951, 3506042, -5933891, -12449708},
+ },
+ {
+ {-3144746, 8744661, 19704003, 4581278, -20430686, 6830683,
+ -21284170, 8971513, -28539189, 15326563},
+ {-19464629, 10110288, -17262528, -3503892, -23500387, 1355669,
+ -15523050, 15300988, -20514118, 9168260},
+ {-5353335, 4488613, -23803248, 16314347, 7780487, -15638939,
+ -28948358, 9601605, 33087103, -9011387},
+ },
+ {
+ {-19443170, -15512900, -20797467, -12445323, -29824447, 10229461,
+ -27444329, -15000531, -5996870, 15664672},
+ {23294591, -16632613, -22650781, -8470978, 27844204, 11461195,
+ 13099750, -2460356, 18151676, 13417686},
+ {-24722913, -4176517, -31150679, 5988919, -26858785, 6685065,
+ 1661597, -12551441, 15271676, -15452665},
+ },
+ },
+ {
+ {
+ {11433042, -13228665, 8239631, -5279517, -1985436, -725718,
+ -18698764, 2167544, -6921301, -13440182},
+ {-31436171, 15575146, 30436815, 12192228, -22463353, 9395379,
+ -9917708, -8638997, 12215110, 12028277},
+ {14098400, 6555944, 23007258, 5757252, -15427832, -12950502,
+ 30123440, 4617780, -16900089, -655628},
+ },
+ {
+ {-4026201, -15240835, 11893168, 13718664, -14809462, 1847385,
+ -15819999, 10154009, 23973261, -12684474},
+ {-26531820, -3695990, -1908898, 2534301, -31870557, -16550355,
+ 18341390, -11419951, 32013174, -10103539},
+ {-25479301, 10876443, -11771086, -14625140, -12369567, 1838104,
+ 21911214, 6354752, 4425632, -837822},
+ },
+ {
+ {-10433389, -14612966, 22229858, -3091047, -13191166, 776729,
+ -17415375, -12020462, 4725005, 14044970},
+ {19268650, -7304421, 1555349, 8692754, -21474059, -9910664, 6347390,
+ -1411784, -19522291, -16109756},
+ {-24864089, 12986008, -10898878, -5558584, -11312371, -148526,
+ 19541418, 8180106, 9282262, 10282508},
+ },
+ {
+ {-26205082, 4428547, -8661196, -13194263, 4098402, -14165257,
+ 15522535, 8372215, 5542595, -10702683},
+ {-10562541, 14895633, 26814552, -16673850, -17480754, -2489360,
+ -2781891, 6993761, -18093885, 10114655},
+ {-20107055, -929418, 31422704, 10427861, -7110749, 6150669,
+ -29091755, -11529146, 25953725, -106158},
+ },
+ {
+ {-4234397, -8039292, -9119125, 3046000, 2101609, -12607294,
+ 19390020, 6094296, -3315279, 12831125},
+ {-15998678, 7578152, 5310217, 14408357, -33548620, -224739,
+ 31575954, 6326196, 7381791, -2421839},
+ {-20902779, 3296811, 24736065, -16328389, 18374254, 7318640,
+ 6295303, 8082724, -15362489, 12339664},
+ },
+ {
+ {27724736, 2291157, 6088201, -14184798, 1792727, 5857634, 13848414,
+ 15768922, 25091167, 14856294},
+ {-18866652, 8331043, 24373479, 8541013, -701998, -9269457, 12927300,
+ -12695493, -22182473, -9012899},
+ {-11423429, -5421590, 11632845, 3405020, 30536730, -11674039,
+ -27260765, 13866390, 30146206, 9142070},
+ },
+ {
+ {3924129, -15307516, -13817122, -10054960, 12291820, -668366,
+ -27702774, 9326384, -8237858, 4171294},
+ {-15921940, 16037937, 6713787, 16606682, -21612135, 2790944,
+ 26396185, 3731949, 345228, -5462949},
+ {-21327538, 13448259, 25284571, 1143661, 20614966, -8849387,
+ 2031539, -12391231, -16253183, -13582083},
+ },
+ {
+ {31016211, -16722429, 26371392, -14451233, -5027349, 14854137,
+ 17477601, 3842657, 28012650, -16405420},
+ {-5075835, 9368966, -8562079, -4600902, -15249953, 6970560,
+ -9189873, 16292057, -8867157, 3507940},
+ {29439664, 3537914, 23333589, 6997794, -17555561, -11018068,
+ -15209202, -15051267, -9164929, 6580396},
+ },
+ },
+ {
+ {
+ {-12185861, -7679788, 16438269, 10826160, -8696817, -6235611,
+ 17860444, -9273846, -2095802, 9304567},
+ {20714564, -4336911, 29088195, 7406487, 11426967, -5095705,
+ 14792667, -14608617, 5289421, -477127},
+ {-16665533, -10650790, -6160345, -13305760, 9192020, -1802462,
+ 17271490, 12349094, 26939669, -3752294},
+ },
+ {
+ {-12889898, 9373458, 31595848, 16374215, 21471720, 13221525,
+ -27283495, -12348559, -3698806, 117887},
+ {22263325, -6560050, 3984570, -11174646, -15114008, -566785,
+ 28311253, 5358056, -23319780, 541964},
+ {16259219, 3261970, 2309254, -15534474, -16885711, -4581916,
+ 24134070, -16705829, -13337066, -13552195},
+ },
+ {
+ {9378160, -13140186, -22845982, -12745264, 28198281, -7244098,
+ -2399684, -717351, 690426, 14876244},
+ {24977353, -314384, -8223969, -13465086, 28432343, -1176353,
+ -13068804, -12297348, -22380984, 6618999},
+ {-1538174, 11685646, 12944378, 13682314, -24389511, -14413193,
+ 8044829, -13817328, 32239829, -5652762},
+ },
+ {
+ {-18603066, 4762990, -926250, 8885304, -28412480, -3187315, 9781647,
+ -10350059, 32779359, 5095274},
+ {-33008130, -5214506, -32264887, -3685216, 9460461, -9327423,
+ -24601656, 14506724, 21639561, -2630236},
+ {-16400943, -13112215, 25239338, 15531969, 3987758, -4499318,
+ -1289502, -6863535, 17874574, 558605},
+ },
+ {
+ {-13600129, 10240081, 9171883, 16131053, -20869254, 9599700,
+ 33499487, 5080151, 2085892, 5119761},
+ {-22205145, -2519528, -16381601, 414691, -25019550, 2170430,
+ 30634760, -8363614, -31999993, -5759884},
+ {-6845704, 15791202, 8550074, -1312654, 29928809, -12092256,
+ 27534430, -7192145, -22351378, 12961482},
+ },
+ {
+ {-24492060, -9570771, 10368194, 11582341, -23397293, -2245287,
+ 16533930, 8206996, -30194652, -5159638},
+ {-11121496, -3382234, 2307366, 6362031, -135455, 8868177, -16835630,
+ 7031275, 7589640, 8945490},
+ {-32152748, 8917967, 6661220, -11677616, -1192060, -15793393,
+ 7251489, -11182180, 24099109, -14456170},
+ },
+ {
+ {5019558, -7907470, 4244127, -14714356, -26933272, 6453165,
+ -19118182, -13289025, -6231896, -10280736},
+ {10853594, 10721687, 26480089, 5861829, -22995819, 1972175,
+ -1866647, -10557898, -3363451, -6441124},
+ {-17002408, 5906790, 221599, -6563147, 7828208, -13248918, 24362661,
+ -2008168, -13866408, 7421392},
+ },
+ {
+ {8139927, -6546497, 32257646, -5890546, 30375719, 1886181,
+ -21175108, 15441252, 28826358, -4123029},
+ {6267086, 9695052, 7709135, -16603597, -32869068, -1886135,
+ 14795160, -7840124, 13746021, -1742048},
+ {28584902, 7787108, -6732942, -15050729, 22846041, -7571236,
+ -3181936, -363524, 4771362, -8419958},
+ },
+ },
+ {
+ {
+ {24949256, 6376279, -27466481, -8174608, -18646154, -9930606,
+ 33543569, -12141695, 3569627, 11342593},
+ {26514989, 4740088, 27912651, 3697550, 19331575, -11472339, 6809886,
+ 4608608, 7325975, -14801071},
+ {-11618399, -14554430, -24321212, 7655128, -1369274, 5214312,
+ -27400540, 10258390, -17646694, -8186692},
+ },
+ {
+ {11431204, 15823007, 26570245, 14329124, 18029990, 4796082,
+ -31446179, 15580664, 9280358, -3973687},
+ {-160783, -10326257, -22855316, -4304997, -20861367, -13621002,
+ -32810901, -11181622, -15545091, 4387441},
+ {-20799378, 12194512, 3937617, -5805892, -27154820, 9340370,
+ -24513992, 8548137, 20617071, -7482001},
+ },
+ {
+ {-938825, -3930586, -8714311, 16124718, 24603125, -6225393,
+ -13775352, -11875822, 24345683, 10325460},
+ {-19855277, -1568885, -22202708, 8714034, 14007766, 6928528,
+ 16318175, -1010689, 4766743, 3552007},
+ {-21751364, -16730916, 1351763, -803421, -4009670, 3950935, 3217514,
+ 14481909, 10988822, -3994762},
+ },
+ {
+ {15564307, -14311570, 3101243, 5684148, 30446780, -8051356,
+ 12677127, -6505343, -8295852, 13296005},
+ {-9442290, 6624296, -30298964, -11913677, -4670981, -2057379,
+ 31521204, 9614054, -30000824, 12074674},
+ {4771191, -135239, 14290749, -13089852, 27992298, 14998318,
+ -1413936, -1556716, 29832613, -16391035},
+ },
+ {
+ {7064884, -7541174, -19161962, -5067537, -18891269, -2912736,
+ 25825242, 5293297, -27122660, 13101590},
+ {-2298563, 2439670, -7466610, 1719965, -27267541, -16328445,
+ 32512469, -5317593, -30356070, -4190957},
+ {-30006540, 10162316, -33180176, 3981723, -16482138, -13070044,
+ 14413974, 9515896, 19568978, 9628812},
+ },
+ {
+ {33053803, 199357, 15894591, 1583059, 27380243, -4580435, -17838894,
+ -6106839, -6291786, 3437740},
+ {-18978877, 3884493, 19469877, 12726490, 15913552, 13614290,
+ -22961733, 70104, 7463304, 4176122},
+ {-27124001, 10659917, 11482427, -16070381, 12771467, -6635117,
+ -32719404, -5322751, 24216882, 5944158},
+ },
+ {
+ {8894125, 7450974, -2664149, -9765752, -28080517, -12389115,
+ 19345746, 14680796, 11632993, 5847885},
+ {26942781, -2315317, 9129564, -4906607, 26024105, 11769399,
+ -11518837, 6367194, -9727230, 4782140},
+ {19916461, -4828410, -22910704, -11414391, 25606324, -5972441,
+ 33253853, 8220911, 6358847, -1873857},
+ },
+ {
+ {801428, -2081702, 16569428, 11065167, 29875704, 96627, 7908388,
+ -4480480, -13538503, 1387155},
+ {19646058, 5720633, -11416706, 12814209, 11607948, 12749789,
+ 14147075, 15156355, -21866831, 11835260},
+ {19299512, 1155910, 28703737, 14890794, 2925026, 7269399, 26121523,
+ 15467869, -26560550, 5052483},
+ },
+ },
+ {
+ {
+ {-3017432, 10058206, 1980837, 3964243, 22160966, 12322533, -6431123,
+ -12618185, 12228557, -7003677},
+ {32944382, 14922211, -22844894, 5188528, 21913450, -8719943,
+ 4001465, 13238564, -6114803, 8653815},
+ {22865569, -4652735, 27603668, -12545395, 14348958, 8234005,
+ 24808405, 5719875, 28483275, 2841751},
+ },
+ {
+ {-16420968, -1113305, -327719, -12107856, 21886282, -15552774,
+ -1887966, -315658, 19932058, -12739203},
+ {-11656086, 10087521, -8864888, -5536143, -19278573, -3055912,
+ 3999228, 13239134, -4777469, -13910208},
+ {1382174, -11694719, 17266790, 9194690, -13324356, 9720081,
+ 20403944, 11284705, -14013818, 3093230},
+ },
+ {
+ {16650921, -11037932, -1064178, 1570629, -8329746, 7352753, -302424,
+ 16271225, -24049421, -6691850},
+ {-21911077, -5927941, -4611316, -5560156, -31744103, -10785293,
+ 24123614, 15193618, -21652117, -16739389},
+ {-9935934, -4289447, -25279823, 4372842, 2087473, 10399484,
+ 31870908, 14690798, 17361620, 11864968},
+ },
+ {
+ {-11307610, 6210372, 13206574, 5806320, -29017692, -13967200,
+ -12331205, -7486601, -25578460, -16240689},
+ {14668462, -12270235, 26039039, 15305210, 25515617, 4542480,
+ 10453892, 6577524, 9145645, -6443880},
+ {5974874, 3053895, -9433049, -10385191, -31865124, 3225009,
+ -7972642, 3936128, -5652273, -3050304},
+ },
+ {
+ {30625386, -4729400, -25555961, -12792866, -20484575, 7695099,
+ 17097188, -16303496, -27999779, 1803632},
+ {-3553091, 9865099, -5228566, 4272701, -5673832, -16689700,
+ 14911344, 12196514, -21405489, 7047412},
+ {20093277, 9920966, -11138194, -5343857, 13161587, 12044805,
+ -32856851, 4124601, -32343828, -10257566},
+ },
+ {
+ {-20788824, 14084654, -13531713, 7842147, 19119038, -13822605,
+ 4752377, -8714640, -21679658, 2288038},
+ {-26819236, -3283715, 29965059, 3039786, -14473765, 2540457,
+ 29457502, 14625692, -24819617, 12570232},
+ {-1063558, -11551823, 16920318, 12494842, 1278292, -5869109,
+ -21159943, -3498680, -11974704, 4724943},
+ },
+ {
+ {17960970, -11775534, -4140968, -9702530, -8876562, -1410617,
+ -12907383, -8659932, -29576300, 1903856},
+ {23134274, -14279132, -10681997, -1611936, 20684485, 15770816,
+ -12989750, 3190296, 26955097, 14109738},
+ {15308788, 5320727, -30113809, -14318877, 22902008, 7767164,
+ 29425325, -11277562, 31960942, 11934971},
+ },
+ {
+ {-27395711, 8435796, 4109644, 12222639, -24627868, 14818669,
+ 20638173, 4875028, 10491392, 1379718},
+ {-13159415, 9197841, 3875503, -8936108, -1383712, -5879801,
+ 33518459, 16176658, 21432314, 12180697},
+ {-11787308, 11500838, 13787581, -13832590, -22430679, 10140205,
+ 1465425, 12689540, -10301319, -13872883},
+ },
+ },
+ {
+ {
+ {5414091, -15386041, -21007664, 9643570, 12834970, 1186149,
+ -2622916, -1342231, 26128231, 6032912},
+ {-26337395, -13766162, 32496025, -13653919, 17847801, -12669156,
+ 3604025, 8316894, -25875034, -10437358},
+ {3296484, 6223048, 24680646, -12246460, -23052020, 5903205,
+ -8862297, -4639164, 12376617, 3188849},
+ },
+ {
+ {29190488, -14659046, 27549113, -1183516, 3520066, -10697301,
+ 32049515, -7309113, -16109234, -9852307},
+ {-14744486, -9309156, 735818, -598978, -20407687, -5057904,
+ 25246078, -15795669, 18640741, -960977},
+ {-6928835, -16430795, 10361374, 5642961, 4910474, 12345252,
+ -31638386, -494430, 10530747, 1053335},
+ },
+ {
+ {-29265967, -14186805, -13538216, -12117373, -19457059, -10655384,
+ -31462369, -2948985, 24018831, 15026644},
+ {-22592535, -3145277, -2289276, 5953843, -13440189, 9425631,
+ 25310643, 13003497, -2314791, -15145616},
+ {-27419985, -603321, -8043984, -1669117, -26092265, 13987819,
+ -27297622, 187899, -23166419, -2531735},
+ },
+ {
+ {-21744398, -13810475, 1844840, 5021428, -10434399, -15911473,
+ 9716667, 16266922, -5070217, 726099},
+ {29370922, -6053998, 7334071, -15342259, 9385287, 2247707,
+ -13661962, -4839461, 30007388, -15823341},
+ {-936379, 16086691, 23751945, -543318, -1167538, -5189036, 9137109,
+ 730663, 9835848, 4555336},
+ },
+ {
+ {-23376435, 1410446, -22253753, -12899614, 30867635, 15826977,
+ 17693930, 544696, -11985298, 12422646},
+ {31117226, -12215734, -13502838, 6561947, -9876867, -12757670,
+ -5118685, -4096706, 29120153, 13924425},
+ {-17400879, -14233209, 19675799, -2734756, -11006962, -5858820,
+ -9383939, -11317700, 7240931, -237388},
+ },
+ {
+ {-31361739, -11346780, -15007447, -5856218, -22453340, -12152771,
+ 1222336, 4389483, 3293637, -15551743},
+ {-16684801, -14444245, 11038544, 11054958, -13801175, -3338533,
+ -24319580, 7733547, 12796905, -6335822},
+ {-8759414, -10817836, -25418864, 10783769, -30615557, -9746811,
+ -28253339, 3647836, 3222231, -11160462},
+ },
+ {
+ {18606113, 1693100, -25448386, -15170272, 4112353, 10045021,
+ 23603893, -2048234, -7550776, 2484985},
+ {9255317, -3131197, -12156162, -1004256, 13098013, -9214866,
+ 16377220, -2102812, -19802075, -3034702},
+ {-22729289, 7496160, -5742199, 11329249, 19991973, -3347502,
+ -31718148, 9936966, -30097688, -10618797},
+ },
+ {
+ {21878590, -5001297, 4338336, 13643897, -3036865, 13160960,
+ 19708896, 5415497, -7360503, -4109293},
+ {27736861, 10103576, 12500508, 8502413, -3413016, -9633558,
+ 10436918, -1550276, -23659143, -8132100},
+ {19492550, -12104365, -29681976, -852630, -3208171, 12403437,
+ 30066266, 8367329, 13243957, 8709688},
+ },
+ },
+ {
+ {
+ {12015105, 2801261, 28198131, 10151021, 24818120, -4743133,
+ -11194191, -5645734, 5150968, 7274186},
+ {2831366, -12492146, 1478975, 6122054, 23825128, -12733586,
+ 31097299, 6083058, 31021603, -9793610},
+ {-2529932, -2229646, 445613, 10720828, -13849527, -11505937,
+ -23507731, 16354465, 15067285, -14147707},
+ },
+ {
+ {7840942, 14037873, -33364863, 15934016, -728213, -3642706,
+ 21403988, 1057586, -19379462, -12403220},
+ {915865, -16469274, 15608285, -8789130, -24357026, 6060030,
+ -17371319, 8410997, -7220461, 16527025},
+ {32922597, -556987, 20336074, -16184568, 10903705, -5384487,
+ 16957574, 52992, 23834301, 6588044},
+ },
+ {
+ {32752030, 11232950, 3381995, -8714866, 22652988, -10744103,
+ 17159699, 16689107, -20314580, -1305992},
+ {-4689649, 9166776, -25710296, -10847306, 11576752, 12733943,
+ 7924251, -2752281, 1976123, -7249027},
+ {21251222, 16309901, -2983015, -6783122, 30810597, 12967303, 156041,
+ -3371252, 12331345, -8237197},
+ },
+ {
+ {8651614, -4477032, -16085636, -4996994, 13002507, 2950805,
+ 29054427, -5106970, 10008136, -4667901},
+ {31486080, 15114593, -14261250, 12951354, 14369431, -7387845,
+ 16347321, -13662089, 8684155, -10532952},
+ {19443825, 11385320, 24468943, -9659068, -23919258, 2187569,
+ -26263207, -6086921, 31316348, 14219878},
+ },
+ {
+ {-28594490, 1193785, 32245219, 11392485, 31092169, 15722801,
+ 27146014, 6992409, 29126555, 9207390},
+ {32382935, 1110093, 18477781, 11028262, -27411763, -7548111,
+ -4980517, 10843782, -7957600, -14435730},
+ {2814918, 7836403, 27519878, -7868156, -20894015, -11553689,
+ -21494559, 8550130, 28346258, 1994730},
+ },
+ {
+ {-19578299, 8085545, -14000519, -3948622, 2785838, -16231307,
+ -19516951, 7174894, 22628102, 8115180},
+ {-30405132, 955511, -11133838, -15078069, -32447087, -13278079,
+ -25651578, 3317160, -9943017, 930272},
+ {-15303681, -6833769, 28856490, 1357446, 23421993, 1057177,
+ 24091212, -1388970, -22765376, -10650715},
+ },
+ {
+ {-22751231, -5303997, -12907607, -12768866, -15811511, -7797053,
+ -14839018, -16554220, -1867018, 8398970},
+ {-31969310, 2106403, -4736360, 1362501, 12813763, 16200670,
+ 22981545, -6291273, 18009408, -15772772},
+ {-17220923, -9545221, -27784654, 14166835, 29815394, 7444469,
+ 29551787, -3727419, 19288549, 1325865},
+ },
+ {
+ {15100157, -15835752, -23923978, -1005098, -26450192, 15509408,
+ 12376730, -3479146, 33166107, -8042750},
+ {20909231, 13023121, -9209752, 16251778, -5778415, -8094914,
+ 12412151, 10018715, 2213263, -13878373},
+ {32529814, -11074689, 30361439, -16689753, -9135940, 1513226,
+ 22922121, 6382134, -5766928, 8371348},
+ },
+ },
+ {
+ {
+ {9923462, 11271500, 12616794, 3544722, -29998368, -1721626,
+ 12891687, -8193132, -26442943, 10486144},
+ {-22597207, -7012665, 8587003, -8257861, 4084309, -12970062, 361726,
+ 2610596, -23921530, -11455195},
+ {5408411, -1136691, -4969122, 10561668, 24145918, 14240566,
+ 31319731, -4235541, 19985175, -3436086},
+ },
+ {
+ {-13994457, 16616821, 14549246, 3341099, 32155958, 13648976,
+ -17577068, 8849297, 65030, 8370684},
+ {-8320926, -12049626, 31204563, 5839400, -20627288, -1057277,
+ -19442942, 6922164, 12743482, -9800518},
+ {-2361371, 12678785, 28815050, 4759974, -23893047, 4884717,
+ 23783145, 11038569, 18800704, 255233},
+ },
+ {
+ {-5269658, -1773886, 13957886, 7990715, 23132995, 728773, 13393847,
+ 9066957, 19258688, -14753793},
+ {-2936654, -10827535, -10432089, 14516793, -3640786, 4372541,
+ -31934921, 2209390, -1524053, 2055794},
+ {580882, 16705327, 5468415, -2683018, -30926419, -14696000,
+ -7203346, -8994389, -30021019, 7394435},
+ },
+ {
+ {23838809, 1822728, -15738443, 15242727, 8318092, -3733104,
+ -21672180, -3492205, -4821741, 14799921},
+ {13345610, 9759151, 3371034, -16137791, 16353039, 8577942, 31129804,
+ 13496856, -9056018, 7402518},
+ {2286874, -4435931, -20042458, -2008336, -13696227, 5038122,
+ 11006906, -15760352, 8205061, 1607563},
+ },
+ {
+ {14414086, -8002132, 3331830, -3208217, 22249151, -5594188,
+ 18364661, -2906958, 30019587, -9029278},
+ {-27688051, 1585953, -10775053, 931069, -29120221, -11002319,
+ -14410829, 12029093, 9944378, 8024},
+ {4368715, -3709630, 29874200, -15022983, -20230386, -11410704,
+ -16114594, -999085, -8142388, 5640030},
+ },
+ {
+ {10299610, 13746483, 11661824, 16234854, 7630238, 5998374, 9809887,
+ -16694564, 15219798, -14327783},
+ {27425505, -5719081, 3055006, 10660664, 23458024, 595578, -15398605,
+ -1173195, -18342183, 9742717},
+ {6744077, 2427284, 26042789, 2720740, -847906, 1118974, 32324614,
+ 7406442, 12420155, 1994844},
+ },
+ {
+ {14012521, -5024720, -18384453, -9578469, -26485342, -3936439,
+ -13033478, -10909803, 24319929, -6446333},
+ {16412690, -4507367, 10772641, 15929391, -17068788, -4658621,
+ 10555945, -10484049, -30102368, -4739048},
+ {22397382, -7767684, -9293161, -12792868, 17166287, -9755136,
+ -27333065, 6199366, 21880021, -12250760},
+ },
+ {
+ {-4283307, 5368523, -31117018, 8163389, -30323063, 3209128,
+ 16557151, 8890729, 8840445, 4957760},
+ {-15447727, 709327, -6919446, -10870178, -29777922, 6522332,
+ -21720181, 12130072, -14796503, 5005757},
+ {-2114751, -14308128, 23019042, 15765735, -25269683, 6002752,
+ 10183197, -13239326, -16395286, -2176112},
+ },
+ },
+ {
+ {
+ {-19025756, 1632005, 13466291, -7995100, -23640451, 16573537,
+ -32013908, -3057104, 22208662, 2000468},
+ {3065073, -1412761, -25598674, -361432, -17683065, -5703415,
+ -8164212, 11248527, -3691214, -7414184},
+ {10379208, -6045554, 8877319, 1473647, -29291284, -12507580,
+ 16690915, 2553332, -3132688, 16400289},
+ },
+ {
+ {15716668, 1254266, -18472690, 7446274, -8448918, 6344164,
+ -22097271, -7285580, 26894937, 9132066},
+ {24158887, 12938817, 11085297, -8177598, -28063478, -4457083,
+ -30576463, 64452, -6817084, -2692882},
+ {13488534, 7794716, 22236231, 5989356, 25426474, -12578208, 2350710,
+ -3418511, -4688006, 2364226},
+ },
+ {
+ {16335052, 9132434, 25640582, 6678888, 1725628, 8517937, -11807024,
+ -11697457, 15445875, -7798101},
+ {29004207, -7867081, 28661402, -640412, -12794003, -7943086,
+ 31863255, -4135540, -278050, -15759279},
+ {-6122061, -14866665, -28614905, 14569919, -10857999, -3591829,
+ 10343412, -6976290, -29828287, -10815811},
+ },
+ {
+ {27081650, 3463984, 14099042, -4517604, 1616303, -6205604, 29542636,
+ 15372179, 17293797, 960709},
+ {20263915, 11434237, -5765435, 11236810, 13505955, -10857102,
+ -16111345, 6493122, -19384511, 7639714},
+ {-2830798, -14839232, 25403038, -8215196, -8317012, -16173699,
+ 18006287, -16043750, 29994677, -15808121},
+ },
+ {
+ {9769828, 5202651, -24157398, -13631392, -28051003, -11561624,
+ -24613141, -13860782, -31184575, 709464},
+ {12286395, 13076066, -21775189, -1176622, -25003198, 4057652,
+ -32018128, -8890874, 16102007, 13205847},
+ {13733362, 5599946, 10557076, 3195751, -5557991, 8536970, -25540170,
+ 8525972, 10151379, 10394400},
+ },
+ {
+ {4024660, -16137551, 22436262, 12276534, -9099015, -2686099,
+ 19698229, 11743039, -33302334, 8934414},
+ {-15879800, -4525240, -8580747, -2934061, 14634845, -698278,
+ -9449077, 3137094, -11536886, 11721158},
+ {17555939, -5013938, 8268606, 2331751, -22738815, 9761013, 9319229,
+ 8835153, -9205489, -1280045},
+ },
+ {
+ {-461409, -7830014, 20614118, 16688288, -7514766, -4807119,
+ 22300304, 505429, 6108462, -6183415},
+ {-5070281, 12367917, -30663534, 3234473, 32617080, -8422642,
+ 29880583, -13483331, -26898490, -7867459},
+ {-31975283, 5726539, 26934134, 10237677, -3173717, -605053,
+ 24199304, 3795095, 7592688, -14992079},
+ },
+ {
+ {21594432, -14964228, 17466408, -4077222, 32537084, 2739898,
+ 6407723, 12018833, -28256052, 4298412},
+ {-20650503, -11961496, -27236275, 570498, 3767144, -1717540,
+ 13891942, -1569194, 13717174, 10805743},
+ {-14676630, -15644296, 15287174, 11927123, 24177847, -8175568,
+ -796431, 14860609, -26938930, -5863836},
+ },
+ },
+ {
+ {
+ {12962541, 5311799, -10060768, 11658280, 18855286, -7954201,
+ 13286263, -12808704, -4381056, 9882022},
+ {18512079, 11319350, -20123124, 15090309, 18818594, 5271736,
+ -22727904, 3666879, -23967430, -3299429},
+ {-6789020, -3146043, 16192429, 13241070, 15898607, -14206114,
+ -10084880, -6661110, -2403099, 5276065},
+ },
+ {
+ {30169808, -5317648, 26306206, -11750859, 27814964, 7069267,
+ 7152851, 3684982, 1449224, 13082861},
+ {10342826, 3098505, 2119311, 193222, 25702612, 12233820, 23697382,
+ 15056736, -21016438, -8202000},
+ {-33150110, 3261608, 22745853, 7948688, 19370557, -15177665,
+ -26171976, 6482814, -10300080, -11060101},
+ },
+ {
+ {32869458, -5408545, 25609743, 15678670, -10687769, -15471071,
+ 26112421, 2521008, -22664288, 6904815},
+ {29506923, 4457497, 3377935, -9796444, -30510046, 12935080, 1561737,
+ 3841096, -29003639, -6657642},
+ {10340844, -6630377, -18656632, -2278430, 12621151, -13339055,
+ 30878497, -11824370, -25584551, 5181966},
+ },
+ {
+ {25940115, -12658025, 17324188, -10307374, -8671468, 15029094,
+ 24396252, -16450922, -2322852, -12388574},
+ {-21765684, 9916823, -1300409, 4079498, -1028346, 11909559, 1782390,
+ 12641087, 20603771, -6561742},
+ {-18882287, -11673380, 24849422, 11501709, 13161720, -4768874,
+ 1925523, 11914390, 4662781, 7820689},
+ },
+ {
+ {12241050, -425982, 8132691, 9393934, 32846760, -1599620, 29749456,
+ 12172924, 16136752, 15264020},
+ {-10349955, -14680563, -8211979, 2330220, -17662549, -14545780,
+ 10658213, 6671822, 19012087, 3772772},
+ {3753511, -3421066, 10617074, 2028709, 14841030, -6721664, 28718732,
+ -15762884, 20527771, 12988982},
+ },
+ {
+ {-14822485, -5797269, -3707987, 12689773, -898983, -10914866,
+ -24183046, -10564943, 3299665, -12424953},
+ {-16777703, -15253301, -9642417, 4978983, 3308785, 8755439, 6943197,
+ 6461331, -25583147, 8991218},
+ {-17226263, 1816362, -1673288, -6086439, 31783888, -8175991,
+ -32948145, 7417950, -30242287, 1507265},
+ },
+ {
+ {29692663, 6829891, -10498800, 4334896, 20945975, -11906496,
+ -28887608, 8209391, 14606362, -10647073},
+ {-3481570, 8707081, 32188102, 5672294, 22096700, 1711240, -33020695,
+ 9761487, 4170404, -2085325},
+ {-11587470, 14855945, -4127778, -1531857, -26649089, 15084046,
+ 22186522, 16002000, -14276837, -8400798},
+ },
+ {
+ {-4811456, 13761029, -31703877, -2483919, -3312471, 7869047,
+ -7113572, -9620092, 13240845, 10965870},
+ {-7742563, -8256762, -14768334, -13656260, -23232383, 12387166,
+ 4498947, 14147411, 29514390, 4302863},
+ {-13413405, -12407859, 20757302, -13801832, 14785143, 8976368,
+ -5061276, -2144373, 17846988, -13971927},
+ },
+ },
+ {
+ {
+ {-2244452, -754728, -4597030, -1066309, -6247172, 1455299,
+ -21647728, -9214789, -5222701, 12650267},
+ {-9906797, -16070310, 21134160, 12198166, -27064575, 708126, 387813,
+ 13770293, -19134326, 10958663},
+ {22470984, 12369526, 23446014, -5441109, -21520802, -9698723,
+ -11772496, -11574455, -25083830, 4271862},
+ },
+ {
+ {-25169565, -10053642, -19909332, 15361595, -5984358, 2159192,
+ 75375, -4278529, -32526221, 8469673},
+ {15854970, 4148314, -8893890, 7259002, 11666551, 13824734,
+ -30531198, 2697372, 24154791, -9460943},
+ {15446137, -15806644, 29759747, 14019369, 30811221, -9610191,
+ -31582008, 12840104, 24913809, 9815020},
+ },
+ {
+ {-4709286, -5614269, -31841498, -12288893, -14443537, 10799414,
+ -9103676, 13438769, 18735128, 9466238},
+ {11933045, 9281483, 5081055, -5183824, -2628162, -4905629, -7727821,
+ -10896103, -22728655, 16199064},
+ {14576810, 379472, -26786533, -8317236, -29426508, -10812974,
+ -102766, 1876699, 30801119, 2164795},
+ },
+ {
+ {15995086, 3199873, 13672555, 13712240, -19378835, -4647646,
+ -13081610, -15496269, -13492807, 1268052},
+ {-10290614, -3659039, -3286592, 10948818, 23037027, 3794475,
+ -3470338, -12600221, -17055369, 3565904},
+ {29210088, -9419337, -5919792, -4952785, 10834811, -13327726,
+ -16512102, -10820713, -27162222, -14030531},
+ },
+ {
+ {-13161890, 15508588, 16663704, -8156150, -28349942, 9019123,
+ -29183421, -3769423, 2244111, -14001979},
+ {-5152875, -3800936, -9306475, -6071583, 16243069, 14684434,
+ -25673088, -16180800, 13491506, 4641841},
+ {10813417, 643330, -19188515, -728916, 30292062, -16600078,
+ 27548447, -7721242, 14476989, -12767431},
+ },
+ {
+ {10292079, 9984945, 6481436, 8279905, -7251514, 7032743, 27282937,
+ -1644259, -27912810, 12651324},
+ {-31185513, -813383, 22271204, 11835308, 10201545, 15351028,
+ 17099662, 3988035, 21721536, -3148940},
+ {10202177, -6545839, -31373232, -9574638, -32150642, -8119683,
+ -12906320, 3852694, 13216206, 14842320},
+ },
+ {
+ {-15815640, -10601066, -6538952, -7258995, -6984659, -6581778,
+ -31500847, 13765824, -27434397, 9900184},
+ {14465505, -13833331, -32133984, -14738873, -27443187, 12990492,
+ 33046193, 15796406, -7051866, -8040114},
+ {30924417, -8279620, 6359016, -12816335, 16508377, 9071735,
+ -25488601, 15413635, 9524356, -7018878},
+ },
+ {
+ {12274201, -13175547, 32627641, -1785326, 6736625, 13267305,
+ 5237659, -5109483, 15663516, 4035784},
+ {-2951309, 8903985, 17349946, 601635, -16432815, -4612556,
+ -13732739, -15889334, -22258478, 4659091},
+ {-16916263, -4952973, -30393711, -15158821, 20774812, 15897498,
+ 5736189, 15026997, -2178256, -13455585},
+ },
+ },
+ {
+ {
+ {-8858980, -2219056, 28571666, -10155518, -474467, -10105698,
+ -3801496, 278095, 23440562, -290208},
+ {10226241, -5928702, 15139956, 120818, -14867693, 5218603, 32937275,
+ 11551483, -16571960, -7442864},
+ {17932739, -12437276, -24039557, 10749060, 11316803, 7535897,
+ 22503767, 5561594, -3646624, 3898661},
+ },
+ {
+ {7749907, -969567, -16339731, -16464, -25018111, 15122143, -1573531,
+ 7152530, 21831162, 1245233},
+ {26958459, -14658026, 4314586, 8346991, -5677764, 11960072,
+ -32589295, -620035, -30402091, -16716212},
+ {-12165896, 9166947, 33491384, 13673479, 29787085, 13096535,
+ 6280834, 14587357, -22338025, 13987525},
+ },
+ {
+ {-24349909, 7778775, 21116000, 15572597, -4833266, -5357778,
+ -4300898, -5124639, -7469781, -2858068},
+ {9681908, -6737123, -31951644, 13591838, -6883821, 386950, 31622781,
+ 6439245, -14581012, 4091397},
+ {-8426427, 1470727, -28109679, -1596990, 3978627, -5123623,
+ -19622683, 12092163, 29077877, -14741988},
+ },
+ {
+ {5269168, -6859726, -13230211, -8020715, 25932563, 1763552,
+ -5606110, -5505881, -20017847, 2357889},
+ {32264008, -15407652, -5387735, -1160093, -2091322, -3946900,
+ 23104804, -12869908, 5727338, 189038},
+ {14609123, -8954470, -6000566, -16622781, -14577387, -7743898,
+ -26745169, 10942115, -25888931, -14884697},
+ },
+ {
+ {20513500, 5557931, -15604613, 7829531, 26413943, -2019404,
+ -21378968, 7471781, 13913677, -5137875},
+ {-25574376, 11967826, 29233242, 12948236, -6754465, 4713227,
+ -8940970, 14059180, 12878652, 8511905},
+ {-25656801, 3393631, -2955415, -7075526, -2250709, 9366908,
+ -30223418, 6812974, 5568676, -3127656},
+ },
+ {
+ {11630004, 12144454, 2116339, 13606037, 27378885, 15676917,
+ -17408753, -13504373, -14395196, 8070818},
+ {27117696, -10007378, -31282771, -5570088, 1127282, 12772488,
+ -29845906, 10483306, -11552749, -1028714},
+ {10637467, -5688064, 5674781, 1072708, -26343588, -6982302,
+ -1683975, 9177853, -27493162, 15431203},
+ },
+ {
+ {20525145, 10892566, -12742472, 12779443, -29493034, 16150075,
+ -28240519, 14943142, -15056790, -7935931},
+ {-30024462, 5626926, -551567, -9981087, 753598, 11981191, 25244767,
+ -3239766, -3356550, 9594024},
+ {-23752644, 2636870, -5163910, -10103818, 585134, 7877383, 11345683,
+ -6492290, 13352335, -10977084},
+ },
+ {
+ {-1931799, -5407458, 3304649, -12884869, 17015806, -4877091,
+ -29783850, -7752482, -13215537, -319204},
+ {20239939, 6607058, 6203985, 3483793, -18386976, -779229, -20723742,
+ 15077870, -22750759, 14523817},
+ {27406042, -6041657, 27423596, -4497394, 4996214, 10002360,
+ -28842031, -4545494, -30172742, -4805667},
+ },
+ },
+ {
+ {
+ {11374242, 12660715, 17861383, -12540833, 10935568, 1099227,
+ -13886076, -9091740, -27727044, 11358504},
+ {-12730809, 10311867, 1510375, 10778093, -2119455, -9145702,
+ 32676003, 11149336, -26123651, 4985768},
+ {-19096303, 341147, -6197485, -239033, 15756973, -8796662, -983043,
+ 13794114, -19414307, -15621255},
+ },
+ {
+ {6490081, 11940286, 25495923, -7726360, 8668373, -8751316, 3367603,
+ 6970005, -1691065, -9004790},
+ {1656497, 13457317, 15370807, 6364910, 13605745, 8362338, -19174622,
+ -5475723, -16796596, -5031438},
+ {-22273315, -13524424, -64685, -4334223, -18605636, -10921968,
+ -20571065, -7007978, -99853, -10237333},
+ },
+ {
+ {17747465, 10039260, 19368299, -4050591, -20630635, -16041286,
+ 31992683, -15857976, -29260363, -5511971},
+ {31932027, -4986141, -19612382, 16366580, 22023614, 88450, 11371999,
+ -3744247, 4882242, -10626905},
+ {29796507, 37186, 19818052, 10115756, -11829032, 3352736, 18551198,
+ 3272828, -5190932, -4162409},
+ },
+ {
+ {12501286, 4044383, -8612957, -13392385, -32430052, 5136599,
+ -19230378, -3529697, 330070, -3659409},
+ {6384877, 2899513, 17807477, 7663917, -2358888, 12363165, 25366522,
+ -8573892, -271295, 12071499},
+ {-8365515, -4042521, 25133448, -4517355, -6211027, 2265927,
+ -32769618, 1936675, -5159697, 3829363},
+ },
+ {
+ {28425966, -5835433, -577090, -4697198, -14217555, 6870930, 7921550,
+ -6567787, 26333140, 14267664},
+ {-11067219, 11871231, 27385719, -10559544, -4585914, -11189312,
+ 10004786, -8709488, -21761224, 8930324},
+ {-21197785, -16396035, 25654216, -1725397, 12282012, 11008919,
+ 1541940, 4757911, -26491501, -16408940},
+ },
+ {
+ {13537262, -7759490, -20604840, 10961927, -5922820, -13218065,
+ -13156584, 6217254, -15943699, 13814990},
+ {-17422573, 15157790, 18705543, 29619, 24409717, -260476, 27361681,
+ 9257833, -1956526, -1776914},
+ {-25045300, -10191966, 15366585, 15166509, -13105086, 8423556,
+ -29171540, 12361135, -18685978, 4578290},
+ },
+ {
+ {24579768, 3711570, 1342322, -11180126, -27005135, 14124956,
+ -22544529, 14074919, 21964432, 8235257},
+ {-6528613, -2411497, 9442966, -5925588, 12025640, -1487420,
+ -2981514, -1669206, 13006806, 2355433},
+ {-16304899, -13605259, -6632427, -5142349, 16974359, -10911083,
+ 27202044, 1719366, 1141648, -12796236},
+ },
+ {
+ {-12863944, -13219986, -8318266, -11018091, -6810145, -4843894,
+ 13475066, -3133972, 32674895, 13715045},
+ {11423335, -5468059, 32344216, 8962751, 24989809, 9241752,
+ -13265253, 16086212, -28740881, -15642093},
+ {-1409668, 12530728, -6368726, 10847387, 19531186, -14132160,
+ -11709148, 7791794, -27245943, 4383347},
+ },
+ },
+ {
+ {
+ {-28970898, 5271447, -1266009, -9736989, -12455236, 16732599,
+ -4862407, -4906449, 27193557, 6245191},
+ {-15193956, 5362278, -1783893, 2695834, 4960227, 12840725, 23061898,
+ 3260492, 22510453, 8577507},
+ {-12632451, 11257346, -32692994, 13548177, -721004, 10879011,
+ 31168030, 13952092, -29571492, -3635906},
+ },
+ {
+ {3877321, -9572739, 32416692, 5405324, -11004407, -13656635,
+ 3759769, 11935320, 5611860, 8164018},
+ {-16275802, 14667797, 15906460, 12155291, -22111149, -9039718,
+ 32003002, -8832289, 5773085, -8422109},
+ {-23788118, -8254300, 1950875, 8937633, 18686727, 16459170, -905725,
+ 12376320, 31632953, 190926},
+ },
+ {
+ {-24593607, -16138885, -8423991, 13378746, 14162407, 6901328,
+ -8288749, 4508564, -25341555, -3627528},
+ {8884438, -5884009, 6023974, 10104341, -6881569, -4941533, 18722941,
+ -14786005, -1672488, 827625},
+ {-32720583, -16289296, -32503547, 7101210, 13354605, 2659080,
+ -1800575, -14108036, -24878478, 1541286},
+ },
+ {
+ {2901347, -1117687, 3880376, -10059388, -17620940, -3612781,
+ -21802117, -3567481, 20456845, -1885033},
+ {27019610, 12299467, -13658288, -1603234, -12861660, -4861471,
+ -19540150, -5016058, 29439641, 15138866},
+ {21536104, -6626420, -32447818, -10690208, -22408077, 5175814,
+ -5420040, -16361163, 7779328, 109896},
+ },
+ {
+ {30279744, 14648750, -8044871, 6425558, 13639621, -743509, 28698390,
+ 12180118, 23177719, -554075},
+ {26572847, 3405927, -31701700, 12890905, -19265668, 5335866,
+ -6493768, 2378492, 4439158, -13279347},
+ {-22716706, 3489070, -9225266, -332753, 18875722, -1140095,
+ 14819434, -12731527, -17717757, -5461437},
+ },
+ {
+ {-5056483, 16566551, 15953661, 3767752, -10436499, 15627060,
+ -820954, 2177225, 8550082, -15114165},
+ {-18473302, 16596775, -381660, 15663611, 22860960, 15585581,
+ -27844109, -3582739, -23260460, -8428588},
+ {-32480551, 15707275, -8205912, -5652081, 29464558, 2713815,
+ -22725137, 15860482, -21902570, 1494193},
+ },
+ {
+ {-19562091, -14087393, -25583872, -9299552, 13127842, 759709,
+ 21923482, 16529112, 8742704, 12967017},
+ {-28464899, 1553205, 32536856, -10473729, -24691605, -406174,
+ -8914625, -2933896, -29903758, 15553883},
+ {21877909, 3230008, 9881174, 10539357, -4797115, 2841332, 11543572,
+ 14513274, 19375923, -12647961},
+ },
+ {
+ {8832269, -14495485, 13253511, 5137575, 5037871, 4078777, 24880818,
+ -6222716, 2862653, 9455043},
+ {29306751, 5123106, 20245049, -14149889, 9592566, 8447059, -2077124,
+ -2990080, 15511449, 4789663},
+ {-20679756, 7004547, 8824831, -9434977, -4045704, -3750736,
+ -5754762, 108893, 23513200, 16652362},
+ },
+ },
+ {
+ {
+ {-33256173, 4144782, -4476029, -6579123, 10770039, -7155542,
+ -6650416, -12936300, -18319198, 10212860},
+ {2756081, 8598110, 7383731, -6859892, 22312759, -1105012, 21179801,
+ 2600940, -9988298, -12506466},
+ {-24645692, 13317462, -30449259, -15653928, 21365574, -10869657,
+ 11344424, 864440, -2499677, -16710063},
+ },
+ {
+ {-26432803, 6148329, -17184412, -14474154, 18782929, -275997,
+ -22561534, 211300, 2719757, 4940997},
+ {-1323882, 3911313, -6948744, 14759765, -30027150, 7851207,
+ 21690126, 8518463, 26699843, 5276295},
+ {-13149873, -6429067, 9396249, 365013, 24703301, -10488939, 1321586,
+ 149635, -15452774, 7159369},
+ },
+ {
+ {9987780, -3404759, 17507962, 9505530, 9731535, -2165514, 22356009,
+ 8312176, 22477218, -8403385},
+ {18155857, -16504990, 19744716, 9006923, 15154154, -10538976,
+ 24256460, -4864995, -22548173, 9334109},
+ {2986088, -4911893, 10776628, -3473844, 10620590, -7083203,
+ -21413845, 14253545, -22587149, 536906},
+ },
+ {
+ {4377756, 8115836, 24567078, 15495314, 11625074, 13064599, 7390551,
+ 10589625, 10838060, -15420424},
+ {-19342404, 867880, 9277171, -3218459, -14431572, -1986443,
+ 19295826, -15796950, 6378260, 699185},
+ {7895026, 4057113, -7081772, -13077756, -17886831, -323126, -716039,
+ 15693155, -5045064, -13373962},
+ },
+ {
+ {-7737563, -5869402, -14566319, -7406919, 11385654, 13201616,
+ 31730678, -10962840, -3918636, -9669325},
+ {10188286, -15770834, -7336361, 13427543, 22223443, 14896287,
+ 30743455, 7116568, -21786507, 5427593},
+ {696102, 13206899, 27047647, -10632082, 15285305, -9853179,
+ 10798490, -4578720, 19236243, 12477404},
+ },
+ {
+ {-11229439, 11243796, -17054270, -8040865, -788228, -8167967,
+ -3897669, 11180504, -23169516, 7733644},
+ {17800790, -14036179, -27000429, -11766671, 23887827, 3149671,
+ 23466177, -10538171, 10322027, 15313801},
+ {26246234, 11968874, 32263343, -5468728, 6830755, -13323031,
+ -15794704, -101982, -24449242, 10890804},
+ },
+ {
+ {-31365647, 10271363, -12660625, -6267268, 16690207, -13062544,
+ -14982212, 16484931, 25180797, -5334884},
+ {-586574, 10376444, -32586414, -11286356, 19801893, 10997610,
+ 2276632, 9482883, 316878, 13820577},
+ {-9882808, -4510367, -2115506, 16457136, -11100081, 11674996,
+ 30756178, -7515054, 30696930, -3712849},
+ },
+ {
+ {32988917, -9603412, 12499366, 7910787, -10617257, -11931514,
+ -7342816, -9985397, -32349517, 7392473},
+ {-8855661, 15927861, 9866406, -3649411, -2396914, -16655781,
+ -30409476, -9134995, 25112947, -2926644},
+ {-2504044, -436966, 25621774, -5678772, 15085042, -5479877,
+ -24884878, -13526194, 5537438, -13914319},
+ },
+ },
+ {
+ {
+ {-11225584, 2320285, -9584280, 10149187, -33444663, 5808648,
+ -14876251, -1729667, 31234590, 6090599},
+ {-9633316, 116426, 26083934, 2897444, -6364437, -2688086, 609721,
+ 15878753, -6970405, -9034768},
+ {-27757857, 247744, -15194774, -9002551, 23288161, -10011936,
+ -23869595, 6503646, 20650474, 1804084},
+ },
+ {
+ {-27589786, 15456424, 8972517, 8469608, 15640622, 4439847, 3121995,
+ -10329713, 27842616, -202328},
+ {-15306973, 2839644, 22530074, 10026331, 4602058, 5048462, 28248656,
+ 5031932, -11375082, 12714369},
+ {20807691, -7270825, 29286141, 11421711, -27876523, -13868230,
+ -21227475, 1035546, -19733229, 12796920},
+ },
+ {
+ {12076899, -14301286, -8785001, -11848922, -25012791, 16400684,
+ -17591495, -12899438, 3480665, -15182815},
+ {-32361549, 5457597, 28548107, 7833186, 7303070, -11953545,
+ -24363064, -15921875, -33374054, 2771025},
+ {-21389266, 421932, 26597266, 6860826, 22486084, -6737172,
+ -17137485, -4210226, -24552282, 15673397},
+ },
+ {
+ {-20184622, 2338216, 19788685, -9620956, -4001265, -8740893,
+ -20271184, 4733254, 3727144, -12934448},
+ {6120119, 814863, -11794402, -622716, 6812205, -15747771, 2019594,
+ 7975683, 31123697, -10958981},
+ {30069250, -11435332, 30434654, 2958439, 18399564, -976289,
+ 12296869, 9204260, -16432438, 9648165},
+ },
+ {
+ {32705432, -1550977, 30705658, 7451065, -11805606, 9631813, 3305266,
+ 5248604, -26008332, -11377501},
+ {17219865, 2375039, -31570947, -5575615, -19459679, 9219903, 294711,
+ 15298639, 2662509, -16297073},
+ {-1172927, -7558695, -4366770, -4287744, -21346413, -8434326,
+ 32087529, -1222777, 32247248, -14389861},
+ },
+ {
+ {14312628, 1221556, 17395390, -8700143, -4945741, -8684635,
+ -28197744, -9637817, -16027623, -13378845},
+ {-1428825, -9678990, -9235681, 6549687, -7383069, -468664, 23046502,
+ 9803137, 17597934, 2346211},
+ {18510800, 15337574, 26171504, 981392, -22241552, 7827556,
+ -23491134, -11323352, 3059833, -11782870},
+ },
+ {
+ {10141598, 6082907, 17829293, -1947643, 9830092, 13613136,
+ -25556636, -5544586, -33502212, 3592096},
+ {33114168, -15889352, -26525686, -13343397, 33076705, 8716171,
+ 1151462, 1521897, -982665, -6837803},
+ {-32939165, -4255815, 23947181, -324178, -33072974, -12305637,
+ -16637686, 3891704, 26353178, 693168},
+ },
+ {
+ {30374239, 1595580, -16884039, 13186931, 4600344, 406904, 9585294,
+ -400668, 31375464, 14369965},
+ {-14370654, -7772529, 1510301, 6434173, -18784789, -6262728,
+ 32732230, -13108839, 17901441, 16011505},
+ {18171223, -11934626, -12500402, 15197122, -11038147, -15230035,
+ -19172240, -16046376, 8764035, 12309598},
+ },
+ },
+ {
+ {
+ {5975908, -5243188, -19459362, -9681747, -11541277, 14015782,
+ -23665757, 1228319, 17544096, -10593782},
+ {5811932, -1715293, 3442887, -2269310, -18367348, -8359541,
+ -18044043, -15410127, -5565381, 12348900},
+ {-31399660, 11407555, 25755363, 6891399, -3256938, 14872274,
+ -24849353, 8141295, -10632534, -585479},
+ },
+ {
+ {-12675304, 694026, -5076145, 13300344, 14015258, -14451394,
+ -9698672, -11329050, 30944593, 1130208},
+ {8247766, -6710942, -26562381, -7709309, -14401939, -14648910,
+ 4652152, 2488540, 23550156, -271232},
+ {17294316, -3788438, 7026748, 15626851, 22990044, 113481, 2267737,
+ -5908146, -408818, -137719},
+ },
+ {
+ {16091085, -16253926, 18599252, 7340678, 2137637, -1221657,
+ -3364161, 14550936, 3260525, -7166271},
+ {-4910104, -13332887, 18550887, 10864893, -16459325, -7291596,
+ -23028869, -13204905, -12748722, 2701326},
+ {-8574695, 16099415, 4629974, -16340524, -20786213, -6005432,
+ -10018363, 9276971, 11329923, 1862132},
+ },
+ {
+ {14763076, -15903608, -30918270, 3689867, 3511892, 10313526,
+ -21951088, 12219231, -9037963, -940300},
+ {8894987, -3446094, 6150753, 3013931, 301220, 15693451, -31981216,
+ -2909717, -15438168, 11595570},
+ {15214962, 3537601, -26238722, -14058872, 4418657, -15230761,
+ 13947276, 10730794, -13489462, -4363670},
+ },
+ {
+ {-2538306, 7682793, 32759013, 263109, -29984731, -7955452,
+ -22332124, -10188635, 977108, 699994},
+ {-12466472, 4195084, -9211532, 550904, -15565337, 12917920,
+ 19118110, -439841, -30534533, -14337913},
+ {31788461, -14507657, 4799989, 7372237, 8808585, -14747943, 9408237,
+ -10051775, 12493932, -5409317},
+ },
+ {
+ {-25680606, 5260744, -19235809, -6284470, -3695942, 16566087,
+ 27218280, 2607121, 29375955, 6024730},
+ {842132, -2794693, -4763381, -8722815, 26332018, -12405641,
+ 11831880, 6985184, -9940361, 2854096},
+ {-4847262, -7969331, 2516242, -5847713, 9695691, -7221186, 16512645,
+ 960770, 12121869, 16648078},
+ },
+ {
+ {-15218652, 14667096, -13336229, 2013717, 30598287, -464137,
+ -31504922, -7882064, 20237806, 2838411},
+ {-19288047, 4453152, 15298546, -16178388, 22115043, -15972604,
+ 12544294, -13470457, 1068881, -12499905},
+ {-9558883, -16518835, 33238498, 13506958, 30505848, -1114596,
+ -8486907, -2630053, 12521378, 4845654},
+ },
+ {
+ {-28198521, 10744108, -2958380, 10199664, 7759311, -13088600,
+ 3409348, -873400, -6482306, -12885870},
+ {-23561822, 6230156, -20382013, 10655314, -24040585, -11621172,
+ 10477734, -1240216, -3113227, 13974498},
+ {12966261, 15550616, -32038948, -1615346, 21025980, -629444,
+ 5642325, 7188737, 18895762, 12629579},
+ },
+ },
+ {
+ {
+ {14741879, -14946887, 22177208, -11721237, 1279741, 8058600,
+ 11758140, 789443, 32195181, 3895677},
+ {10758205, 15755439, -4509950, 9243698, -4879422, 6879879, -2204575,
+ -3566119, -8982069, 4429647},
+ {-2453894, 15725973, -20436342, -10410672, -5803908, -11040220,
+ -7135870, -11642895, 18047436, -15281743},
+ },
+ {
+ {-25173001, -11307165, 29759956, 11776784, -22262383, -15820455,
+ 10993114, -12850837, -17620701, -9408468},
+ {21987233, 700364, -24505048, 14972008, -7774265, -5718395,
+ 32155026, 2581431, -29958985, 8773375},
+ {-25568350, 454463, -13211935, 16126715, 25240068, 8594567,
+ 20656846, 12017935, -7874389, -13920155},
+ },
+ {
+ {6028182, 6263078, -31011806, -11301710, -818919, 2461772,
+ -31841174, -5468042, -1721788, -2776725},
+ {-12278994, 16624277, 987579, -5922598, 32908203, 1248608, 7719845,
+ -4166698, 28408820, 6816612},
+ {-10358094, -8237829, 19549651, -12169222, 22082623, 16147817,
+ 20613181, 13982702, -10339570, 5067943},
+ },
+ {
+ {-30505967, -3821767, 12074681, 13582412, -19877972, 2443951,
+ -19719286, 12746132, 5331210, -10105944},
+ {30528811, 3601899, -1957090, 4619785, -27361822, -15436388,
+ 24180793, -12570394, 27679908, -1648928},
+ {9402404, -13957065, 32834043, 10838634, -26580150, -13237195,
+ 26653274, -8685565, 22611444, -12715406},
+ },
+ {
+ {22190590, 1118029, 22736441, 15130463, -30460692, -5991321,
+ 19189625, -4648942, 4854859, 6622139},
+ {-8310738, -2953450, -8262579, -3388049, -10401731, -271929,
+ 13424426, -3567227, 26404409, 13001963},
+ {-31241838, -15415700, -2994250, 8939346, 11562230, -12840670,
+ -26064365, -11621720, -15405155, 11020693},
+ },
+ {
+ {1866042, -7949489, -7898649, -10301010, 12483315, 13477547,
+ 3175636, -12424163, 28761762, 1406734},
+ {-448555, -1777666, 13018551, 3194501, -9580420, -11161737,
+ 24760585, -4347088, 25577411, -13378680},
+ {-24290378, 4759345, -690653, -1852816, 2066747, 10693769,
+ -29595790, 9884936, -9368926, 4745410},
+ },
+ {
+ {-9141284, 6049714, -19531061, -4341411, -31260798, 9944276,
+ -15462008, -11311852, 10931924, -11931931},
+ {-16561513, 14112680, -8012645, 4817318, -8040464, -11414606,
+ -22853429, 10856641, -20470770, 13434654},
+ {22759489, -10073434, -16766264, -1871422, 13637442, -10168091,
+ 1765144, -12654326, 28445307, -5364710},
+ },
+ {
+ {29875063, 12493613, 2795536, -3786330, 1710620, 15181182,
+ -10195717, -8788675, 9074234, 1167180},
+ {-26205683, 11014233, -9842651, -2635485, -26908120, 7532294,
+ -18716888, -9535498, 3843903, 9367684},
+ {-10969595, -6403711, 9591134, 9582310, 11349256, 108879, 16235123,
+ 8601684, -139197, 4242895},
+ },
+ },
+ {
+ {
+ {22092954, -13191123, -2042793, -11968512, 32186753, -11517388,
+ -6574341, 2470660, -27417366, 16625501},
+ {-11057722, 3042016, 13770083, -9257922, 584236, -544855, -7770857,
+ 2602725, -27351616, 14247413},
+ {6314175, -10264892, -32772502, 15957557, -10157730, 168750,
+ -8618807, 14290061, 27108877, -1180880},
+ },
+ {
+ {-8586597, -7170966, 13241782, 10960156, -32991015, -13794596,
+ 33547976, -11058889, -27148451, 981874},
+ {22833440, 9293594, -32649448, -13618667, -9136966, 14756819,
+ -22928859, -13970780, -10479804, -16197962},
+ {-7768587, 3326786, -28111797, 10783824, 19178761, 14905060,
+ 22680049, 13906969, -15933690, 3797899},
+ },
+ {
+ {21721356, -4212746, -12206123, 9310182, -3882239, -13653110,
+ 23740224, -2709232, 20491983, -8042152},
+ {9209270, -15135055, -13256557, -6167798, -731016, 15289673,
+ 25947805, 15286587, 30997318, -6703063},
+ {7392032, 16618386, 23946583, -8039892, -13265164, -1533858,
+ -14197445, -2321576, 17649998, -250080},
+ },
+ {
+ {-9301088, -14193827, 30609526, -3049543, -25175069, -1283752,
+ -15241566, -9525724, -2233253, 7662146},
+ {-17558673, 1763594, -33114336, 15908610, -30040870, -12174295,
+ 7335080, -8472199, -3174674, 3440183},
+ {-19889700, -5977008, -24111293, -9688870, 10799743, -16571957,
+ 40450, -4431835, 4862400, 1133},
+ },
+ {
+ {-32856209, -7873957, -5422389, 14860950, -16319031, 7956142,
+ 7258061, 311861, -30594991, -7379421},
+ {-3773428, -1565936, 28985340, 7499440, 24445838, 9325937, 29727763,
+ 16527196, 18278453, 15405622},
+ {-4381906, 8508652, -19898366, -3674424, -5984453, 15149970,
+ -13313598, 843523, -21875062, 13626197},
+ },
+ {
+ {2281448, -13487055, -10915418, -2609910, 1879358, 16164207,
+ -10783882, 3953792, 13340839, 15928663},
+ {31727126, -7179855, -18437503, -8283652, 2875793, -16390330,
+ -25269894, -7014826, -23452306, 5964753},
+ {4100420, -5959452, -17179337, 6017714, -18705837, 12227141,
+ -26684835, 11344144, 2538215, -7570755},
+ },
+ {
+ {-9433605, 6123113, 11159803, -2156608, 30016280, 14966241,
+ -20474983, 1485421, -629256, -15958862},
+ {-26804558, 4260919, 11851389, 9658551, -32017107, 16367492,
+ -20205425, -13191288, 11659922, -11115118},
+ {26180396, 10015009, -30844224, -8581293, 5418197, 9480663, 2231568,
+ -10170080, 33100372, -1306171},
+ },
+ {
+ {15121113, -5201871, -10389905, 15427821, -27509937, -15992507,
+ 21670947, 4486675, -5931810, -14466380},
+ {16166486, -9483733, -11104130, 6023908, -31926798, -1364923,
+ 2340060, -16254968, -10735770, -10039824},
+ {28042865, -3557089, -12126526, 12259706, -3717498, -6945899,
+ 6766453, -8689599, 18036436, 5803270},
+ },
+ },
+ {
+ {
+ {-817581, 6763912, 11803561, 1585585, 10958447, -2671165, 23855391,
+ 4598332, -6159431, -14117438},
+ {-31031306, -14256194, 17332029, -2383520, 31312682, -5967183,
+ 696309, 50292, -20095739, 11763584},
+ {-594563, -2514283, -32234153, 12643980, 12650761, 14811489, 665117,
+ -12613632, -19773211, -10713562},
+ },
+ {
+ {30464590, -11262872, -4127476, -12734478, 19835327, -7105613,
+ -24396175, 2075773, -17020157, 992471},
+ {18357185, -6994433, 7766382, 16342475, -29324918, 411174, 14578841,
+ 8080033, -11574335, -10601610},
+ {19598397, 10334610, 12555054, 2555664, 18821899, -10339780,
+ 21873263, 16014234, 26224780, 16452269},
+ },
+ {
+ {-30223925, 5145196, 5944548, 16385966, 3976735, 2009897, -11377804,
+ -7618186, -20533829, 3698650},
+ {14187449, 3448569, -10636236, -10810935, -22663880, -3433596,
+ 7268410, -10890444, 27394301, 12015369},
+ {19695761, 16087646, 28032085, 12999827, 6817792, 11427614,
+ 20244189, -1312777, -13259127, -3402461},
+ },
+ {
+ {30860103, 12735208, -1888245, -4699734, -16974906, 2256940,
+ -8166013, 12298312, -8550524, -10393462},
+ {-5719826, -11245325, -1910649, 15569035, 26642876, -7587760,
+ -5789354, -15118654, -4976164, 12651793},
+ {-2848395, 9953421, 11531313, -5282879, 26895123, -12697089,
+ -13118820, -16517902, 9768698, -2533218},
+ },
+ {
+ {-24719459, 1894651, -287698, -4704085, 15348719, -8156530,
+ 32767513, 12765450, 4940095, 10678226},
+ {18860224, 15980149, -18987240, -1562570, -26233012, -11071856,
+ -7843882, 13944024, -24372348, 16582019},
+ {-15504260, 4970268, -29893044, 4175593, -20993212, -2199756,
+ -11704054, 15444560, -11003761, 7989037},
+ },
+ {
+ {31490452, 5568061, -2412803, 2182383, -32336847, 4531686,
+ -32078269, 6200206, -19686113, -14800171},
+ {-17308668, -15879940, -31522777, -2831, -32887382, 16375549,
+ 8680158, -16371713, 28550068, -6857132},
+ {-28126887, -5688091, 16837845, -1820458, -6850681, 12700016,
+ -30039981, 4364038, 1155602, 5988841},
+ },
+ {
+ {21890435, -13272907, -12624011, 12154349, -7831873, 15300496,
+ 23148983, -4470481, 24618407, 8283181},
+ {-33136107, -10512751, 9975416, 6841041, -31559793, 16356536,
+ 3070187, -7025928, 1466169, 10740210},
+ {-1509399, -15488185, -13503385, -10655916, 32799044, 909394,
+ -13938903, -5779719, -32164649, -15327040},
+ },
+ {
+ {3960823, -14267803, -28026090, -15918051, -19404858, 13146868,
+ 15567327, 951507, -3260321, -573935},
+ {24740841, 5052253, -30094131, 8961361, 25877428, 6165135,
+ -24368180, 14397372, -7380369, -6144105},
+ {-28888365, 3510803, -28103278, -1158478, -11238128, -10631454,
+ -15441463, -14453128, -1625486, -6494814},
+ },
+ },
+ {
+ {
+ {793299, -9230478, 8836302, -6235707, -27360908, -2369593, 33152843,
+ -4885251, -9906200, -621852},
+ {5666233, 525582, 20782575, -8038419, -24538499, 14657740, 16099374,
+ 1468826, -6171428, -15186581},
+ {-4859255, -3779343, -2917758, -6748019, 7778750, 11688288,
+ -30404353, -9871238, -1558923, -9863646},
+ },
+ {
+ {10896332, -7719704, 824275, 472601, -19460308, 3009587, 25248958,
+ 14783338, -30581476, -15757844},
+ {10566929, 12612572, -31944212, 11118703, -12633376, 12362879,
+ 21752402, 8822496, 24003793, 14264025},
+ {27713862, -7355973, -11008240, 9227530, 27050101, 2504721,
+ 23886875, -13117525, 13958495, -5732453},
+ },
+ {
+ {-23481610, 4867226, -27247128, 3900521, 29838369, -8212291,
+ -31889399, -10041781, 7340521, -15410068},
+ {4646514, -8011124, -22766023, -11532654, 23184553, 8566613,
+ 31366726, -1381061, -15066784, -10375192},
+ {-17270517, 12723032, -16993061, 14878794, 21619651, -6197576,
+ 27584817, 3093888, -8843694, 3849921},
+ },
+ {
+ {-9064912, 2103172, 25561640, -15125738, -5239824, 9582958,
+ 32477045, -9017955, 5002294, -15550259},
+ {-12057553, -11177906, 21115585, -13365155, 8808712, -12030708,
+ 16489530, 13378448, -25845716, 12741426},
+ {-5946367, 10645103, -30911586, 15390284, -3286982, -7118677,
+ 24306472, 15852464, 28834118, -7646072},
+ },
+ {
+ {-17335748, -9107057, -24531279, 9434953, -8472084, -583362,
+ -13090771, 455841, 20461858, 5491305},
+ {13669248, -16095482, -12481974, -10203039, -14569770, -11893198,
+ -24995986, 11293807, -28588204, -9421832},
+ {28497928, 6272777, -33022994, 14470570, 8906179, -1225630,
+ 18504674, -14165166, 29867745, -8795943},
+ },
+ {
+ {-16207023, 13517196, -27799630, -13697798, 24009064, -6373891,
+ -6367600, -13175392, 22853429, -4012011},
+ {24191378, 16712145, -13931797, 15217831, 14542237, 1646131,
+ 18603514, -11037887, 12876623, -2112447},
+ {17902668, 4518229, -411702, -2829247, 26878217, 5258055, -12860753,
+ 608397, 16031844, 3723494},
+ },
+ {
+ {-28632773, 12763728, -20446446, 7577504, 33001348, -13017745,
+ 17558842, -7872890, 23896954, -4314245},
+ {-20005381, -12011952, 31520464, 605201, 2543521, 5991821, -2945064,
+ 7229064, -9919646, -8826859},
+ {28816045, 298879, -28165016, -15920938, 19000928, -1665890,
+ -12680833, -2949325, -18051778, -2082915},
+ },
+ {
+ {16000882, -344896, 3493092, -11447198, -29504595, -13159789,
+ 12577740, 16041268, -19715240, 7847707},
+ {10151868, 10572098, 27312476, 7922682, 14825339, 4723128,
+ -32855931, -6519018, -10020567, 3852848},
+ {-11430470, 15697596, -21121557, -4420647, 5386314, 15063598,
+ 16514493, -15932110, 29330899, -15076224},
+ },
+ },
+ {
+ {
+ {-25499735, -4378794, -15222908, -6901211, 16615731, 2051784,
+ 3303702, 15490, -27548796, 12314391},
+ {15683520, -6003043, 18109120, -9980648, 15337968, -5997823,
+ -16717435, 15921866, 16103996, -3731215},
+ {-23169824, -10781249, 13588192, -1628807, -3798557, -1074929,
+ -19273607, 5402699, -29815713, -9841101},
+ },
+ {
+ {23190676, 2384583, -32714340, 3462154, -29903655, -1529132,
+ -11266856, 8911517, -25205859, 2739713},
+ {21374101, -3554250, -33524649, 9874411, 15377179, 11831242,
+ -33529904, 6134907, 4931255, 11987849},
+ {-7732, -2978858, -16223486, 7277597, 105524, -322051, -31480539,
+ 13861388, -30076310, 10117930},
+ },
+ {
+ {-29501170, -10744872, -26163768, 13051539, -25625564, 5089643,
+ -6325503, 6704079, 12890019, 15728940},
+ {-21972360, -11771379, -951059, -4418840, 14704840, 2695116, 903376,
+ -10428139, 12885167, 8311031},
+ {-17516482, 5352194, 10384213, -13811658, 7506451, 13453191,
+ 26423267, 4384730, 1888765, -5435404},
+ },
+ {
+ {-25817338, -3107312, -13494599, -3182506, 30896459, -13921729,
+ -32251644, -12707869, -19464434, -3340243},
+ {-23607977, -2665774, -526091, 4651136, 5765089, 4618330, 6092245,
+ 14845197, 17151279, -9854116},
+ {-24830458, -12733720, -15165978, 10367250, -29530908, -265356,
+ 22825805, -7087279, -16866484, 16176525},
+ },
+ {
+ {-23583256, 6564961, 20063689, 3798228, -4740178, 7359225, 2006182,
+ -10363426, -28746253, -10197509},
+ {-10626600, -4486402, -13320562, -5125317, 3432136, -6393229,
+ 23632037, -1940610, 32808310, 1099883},
+ {15030977, 5768825, -27451236, -2887299, -6427378, -15361371,
+ -15277896, -6809350, 2051441, -15225865},
+ },
+ {
+ {-3362323, -7239372, 7517890, 9824992, 23555850, 295369, 5148398,
+ -14154188, -22686354, 16633660},
+ {4577086, -16752288, 13249841, -15304328, 19958763, -14537274,
+ 18559670, -10759549, 8402478, -9864273},
+ {-28406330, -1051581, -26790155, -907698, -17212414, -11030789,
+ 9453451, -14980072, 17983010, 9967138},
+ },
+ {
+ {-25762494, 6524722, 26585488, 9969270, 24709298, 1220360, -1677990,
+ 7806337, 17507396, 3651560},
+ {-10420457, -4118111, 14584639, 15971087, -15768321, 8861010,
+ 26556809, -5574557, -18553322, -11357135},
+ {2839101, 14284142, 4029895, 3472686, 14402957, 12689363, -26642121,
+ 8459447, -5605463, -7621941},
+ },
+ {
+ {-4839289, -3535444, 9744961, 2871048, 25113978, 3187018, -25110813,
+ -849066, 17258084, -7977739},
+ {18164541, -10595176, -17154882, -1542417, 19237078, -9745295,
+ 23357533, -15217008, 26908270, 12150756},
+ {-30264870, -7647865, 5112249, -7036672, -1499807, -6974257, 43168,
+ -5537701, -32302074, 16215819},
+ },
+ },
+ {
+ {
+ {-6898905, 9824394, -12304779, -4401089, -31397141, -6276835,
+ 32574489, 12532905, -7503072, -8675347},
+ {-27343522, -16515468, -27151524, -10722951, 946346, 16291093,
+ 254968, 7168080, 21676107, -1943028},
+ {21260961, -8424752, -16831886, -11920822, -23677961, 3968121,
+ -3651949, -6215466, -3556191, -7913075},
+ },
+ {
+ {16544754, 13250366, -16804428, 15546242, -4583003, 12757258,
+ -2462308, -8680336, -18907032, -9662799},
+ {-2415239, -15577728, 18312303, 4964443, -15272530, -12653564,
+ 26820651, 16690659, 25459437, -4564609},
+ {-25144690, 11425020, 28423002, -11020557, -6144921, -15826224,
+ 9142795, -2391602, -6432418, -1644817},
+ },
+ {
+ {-23104652, 6253476, 16964147, -3768872, -25113972, -12296437,
+ -27457225, -16344658, 6335692, 7249989},
+ {-30333227, 13979675, 7503222, -12368314, -11956721, -4621693,
+ -30272269, 2682242, 25993170, -12478523},
+ {4364628, 5930691, 32304656, -10044554, -8054781, 15091131,
+ 22857016, -10598955, 31820368, 15075278},
+ },
+ {
+ {31879134, -8918693, 17258761, 90626, -8041836, -4917709, 24162788,
+ -9650886, -17970238, 12833045},
+ {19073683, 14851414, -24403169, -11860168, 7625278, 11091125,
+ -19619190, 2074449, -9413939, 14905377},
+ {24483667, -11935567, -2518866, -11547418, -1553130, 15355506,
+ -25282080, 9253129, 27628530, -7555480},
+ },
+ {
+ {17597607, 8340603, 19355617, 552187, 26198470, -3176583, 4593324,
+ -9157582, -14110875, 15297016},
+ {510886, 14337390, -31785257, 16638632, 6328095, 2713355, -20217417,
+ -11864220, 8683221, 2921426},
+ {18606791, 11874196, 27155355, -5281482, -24031742, 6265446,
+ -25178240, -1278924, 4674690, 13890525},
+ },
+ {
+ {13609624, 13069022, -27372361, -13055908, 24360586, 9592974,
+ 14977157, 9835105, 4389687, 288396},
+ {9922506, -519394, 13613107, 5883594, -18758345, -434263, -12304062,
+ 8317628, 23388070, 16052080},
+ {12720016, 11937594, -31970060, -5028689, 26900120, 8561328,
+ -20155687, -11632979, -14754271, -10812892},
+ },
+ {
+ {15961858, 14150409, 26716931, -665832, -22794328, 13603569,
+ 11829573, 7467844, -28822128, 929275},
+ {11038231, -11582396, -27310482, -7316562, -10498527, -16307831,
+ -23479533, -9371869, -21393143, 2465074},
+ {20017163, -4323226, 27915242, 1529148, 12396362, 15675764,
+ 13817261, -9658066, 2463391, -4622140},
+ },
+ {
+ {-16358878, -12663911, -12065183, 4996454, -1256422, 1073572,
+ 9583558, 12851107, 4003896, 12673717},
+ {-1731589, -15155870, -3262930, 16143082, 19294135, 13385325,
+ 14741514, -9103726, 7903886, 2348101},
+ {24536016, -16515207, 12715592, -3862155, 1511293, 10047386,
+ -3842346, -7129159, -28377538, 10048127},
+ },
+ },
+ {
+ {
+ {-12622226, -6204820, 30718825, 2591312, -10617028, 12192840,
+ 18873298, -7297090, -32297756, 15221632},
+ {-26478122, -11103864, 11546244, -1852483, 9180880, 7656409,
+ -21343950, 2095755, 29769758, 6593415},
+ {-31994208, -2907461, 4176912, 3264766, 12538965, -868111, 26312345,
+ -6118678, 30958054, 8292160},
+ },
+ {
+ {31429822, -13959116, 29173532, 15632448, 12174511, -2760094,
+ 32808831, 3977186, 26143136, -3148876},
+ {22648901, 1402143, -22799984, 13746059, 7936347, 365344, -8668633,
+ -1674433, -3758243, -2304625},
+ {-15491917, 8012313, -2514730, -12702462, -23965846, -10254029,
+ -1612713, -1535569, -16664475, 8194478},
+ },
+ {
+ {27338066, -7507420, -7414224, 10140405, -19026427, -6589889,
+ 27277191, 8855376, 28572286, 3005164},
+ {26287124, 4821776, 25476601, -4145903, -3764513, -15788984,
+ -18008582, 1182479, -26094821, -13079595},
+ {-7171154, 3178080, 23970071, 6201893, -17195577, -4489192,
+ -21876275, -13982627, 32208683, -1198248},
+ },
+ {
+ {-16657702, 2817643, -10286362, 14811298, 6024667, 13349505,
+ -27315504, -10497842, -27672585, -11539858},
+ {15941029, -9405932, -21367050, 8062055, 31876073, -238629,
+ -15278393, -1444429, 15397331, -4130193},
+ {8934485, -13485467, -23286397, -13423241, -32446090, 14047986,
+ 31170398, -1441021, -27505566, 15087184},
+ },
+ {
+ {-18357243, -2156491, 24524913, -16677868, 15520427, -6360776,
+ -15502406, 11461896, 16788528, -5868942},
+ {-1947386, 16013773, 21750665, 3714552, -17401782, -16055433,
+ -3770287, -10323320, 31322514, -11615635},
+ {21426655, -5650218, -13648287, -5347537, -28812189, -4920970,
+ -18275391, -14621414, 13040862, -12112948},
+ },
+ {
+ {11293895, 12478086, -27136401, 15083750, -29307421, 14748872,
+ 14555558, -13417103, 1613711, 4896935},
+ {-25894883, 15323294, -8489791, -8057900, 25967126, -13425460,
+ 2825960, -4897045, -23971776, -11267415},
+ {-15924766, -5229880, -17443532, 6410664, 3622847, 10243618,
+ 20615400, 12405433, -23753030, -8436416},
+ },
+ {
+ {-7091295, 12556208, -20191352, 9025187, -17072479, 4333801,
+ 4378436, 2432030, 23097949, -566018},
+ {4565804, -16025654, 20084412, -7842817, 1724999, 189254, 24767264,
+ 10103221, -18512313, 2424778},
+ {366633, -11976806, 8173090, -6890119, 30788634, 5745705, -7168678,
+ 1344109, -3642553, 12412659},
+ },
+ {
+ {-24001791, 7690286, 14929416, -168257, -32210835, -13412986,
+ 24162697, -15326504, -3141501, 11179385},
+ {18289522, -14724954, 8056945, 16430056, -21729724, 7842514,
+ -6001441, -1486897, -18684645, -11443503},
+ {476239, 6601091, -6152790, -9723375, 17503545, -4863900, 27672959,
+ 13403813, 11052904, 5219329},
+ },
+ },
+ {
+ {
+ {20678546, -8375738, -32671898, 8849123, -5009758, 14574752,
+ 31186971, -3973730, 9014762, -8579056},
+ {-13644050, -10350239, -15962508, 5075808, -1514661, -11534600,
+ -33102500, 9160280, 8473550, -3256838},
+ {24900749, 14435722, 17209120, -15292541, -22592275, 9878983,
+ -7689309, -16335821, -24568481, 11788948},
+ },
+ {
+ {-3118155, -11395194, -13802089, 14797441, 9652448, -6845904,
+ -20037437, 10410733, -24568470, -1458691},
+ {-15659161, 16736706, -22467150, 10215878, -9097177, 7563911,
+ 11871841, -12505194, -18513325, 8464118},
+ {-23400612, 8348507, -14585951, -861714, -3950205, -6373419,
+ 14325289, 8628612, 33313881, -8370517},
+ },
+ {
+ {-20186973, -4967935, 22367356, 5271547, -1097117, -4788838,
+ -24805667, -10236854, -8940735, -5818269},
+ {-6948785, -1795212, -32625683, -16021179, 32635414, -7374245,
+ 15989197, -12838188, 28358192, -4253904},
+ {-23561781, -2799059, -32351682, -1661963, -9147719, 10429267,
+ -16637684, 4072016, -5351664, 5596589},
+ },
+ {
+ {-28236598, -3390048, 12312896, 6213178, 3117142, 16078565,
+ 29266239, 2557221, 1768301, 15373193},
+ {-7243358, -3246960, -4593467, -7553353, -127927, -912245, -1090902,
+ -4504991, -24660491, 3442910},
+ {-30210571, 5124043, 14181784, 8197961, 18964734, -11939093,
+ 22597931, 7176455, -18585478, 13365930},
+ },
+ {
+ {-7877390, -1499958, 8324673, 4690079, 6261860, 890446, 24538107,
+ -8570186, -9689599, -3031667},
+ {25008904, -10771599, -4305031, -9638010, 16265036, 15721635,
+ 683793, -11823784, 15723479, -15163481},
+ {-9660625, 12374379, -27006999, -7026148, -7724114, -12314514,
+ 11879682, 5400171, 519526, -1235876},
+ },
+ {
+ {22258397, -16332233, -7869817, 14613016, -22520255, -2950923,
+ -20353881, 7315967, 16648397, 7605640},
+ {-8081308, -8464597, -8223311, 9719710, 19259459, -15348212,
+ 23994942, -5281555, -9468848, 4763278},
+ {-21699244, 9220969, -15730624, 1084137, -25476107, -2852390,
+ 31088447, -7764523, -11356529, 728112},
+ },
+ {
+ {26047220, -11751471, -6900323, -16521798, 24092068, 9158119,
+ -4273545, -12555558, -29365436, -5498272},
+ {17510331, -322857, 5854289, 8403524, 17133918, -3112612, -28111007,
+ 12327945, 10750447, 10014012},
+ {-10312768, 3936952, 9156313, -8897683, 16498692, -994647,
+ -27481051, -666732, 3424691, 7540221},
+ },
+ {
+ {30322361, -6964110, 11361005, -4143317, 7433304, 4989748, -7071422,
+ -16317219, -9244265, 15258046},
+ {13054562, -2779497, 19155474, 469045, -12482797, 4566042, 5631406,
+ 2711395, 1062915, -5136345},
+ {-19240248, -11254599, -29509029, -7499965, -5835763, 13005411,
+ -6066489, 12194497, 32960380, 1459310},
+ },
+ },
+ {
+ {
+ {19852034, 7027924, 23669353, 10020366, 8586503, -6657907, 394197,
+ -6101885, 18638003, -11174937},
+ {31395534, 15098109, 26581030, 8030562, -16527914, -5007134,
+ 9012486, -7584354, -6643087, -5442636},
+ {-9192165, -2347377, -1997099, 4529534, 25766844, 607986, -13222,
+ 9677543, -32294889, -6456008},
+ },
+ {
+ {-2444496, -149937, 29348902, 8186665, 1873760, 12489863, -30934579,
+ -7839692, -7852844, -8138429},
+ {-15236356, -15433509, 7766470, 746860, 26346930, -10221762,
+ -27333451, 10754588, -9431476, 5203576},
+ {31834314, 14135496, -770007, 5159118, 20917671, -16768096,
+ -7467973, -7337524, 31809243, 7347066},
+ },
+ {
+ {-9606723, -11874240, 20414459, 13033986, 13716524, -11691881,
+ 19797970, -12211255, 15192876, -2087490},
+ {-12663563, -2181719, 1168162, -3804809, 26747877, -14138091,
+ 10609330, 12694420, 33473243, -13382104},
+ {33184999, 11180355, 15832085, -11385430, -1633671, 225884,
+ 15089336, -11023903, -6135662, 14480053},
+ },
+ {
+ {31308717, -5619998, 31030840, -1897099, 15674547, -6582883,
+ 5496208, 13685227, 27595050, 8737275},
+ {-20318852, -15150239, 10933843, -16178022, 8335352, -7546022,
+ -31008351, -12610604, 26498114, 66511},
+ {22644454, -8761729, -16671776, 4884562, -3105614, -13559366,
+ 30540766, -4286747, -13327787, -7515095},
+ },
+ {
+ {-28017847, 9834845, 18617207, -2681312, -3401956, -13307506,
+ 8205540, 13585437, -17127465, 15115439},
+ {23711543, -672915, 31206561, -8362711, 6164647, -9709987,
+ -33535882, -1426096, 8236921, 16492939},
+ {-23910559, -13515526, -26299483, -4503841, 25005590, -7687270,
+ 19574902, 10071562, 6708380, -6222424},
+ },
+ {
+ {2101391, -4930054, 19702731, 2367575, -15427167, 1047675, 5301017,
+ 9328700, 29955601, -11678310},
+ {3096359, 9271816, -21620864, -15521844, -14847996, -7592937,
+ -25892142, -12635595, -9917575, 6216608},
+ {-32615849, 338663, -25195611, 2510422, -29213566, -13820213,
+ 24822830, -6146567, -26767480, 7525079},
+ },
+ {
+ {-23066649, -13985623, 16133487, -7896178, -3389565, 778788,
+ -910336, -2782495, -19386633, 11994101},
+ {21691500, -13624626, -641331, -14367021, 3285881, -3483596,
+ -25064666, 9718258, -7477437, 13381418},
+ {18445390, -4202236, 14979846, 11622458, -1727110, -3582980,
+ 23111648, -6375247, 28535282, 15779576},
+ },
+ {
+ {30098053, 3089662, -9234387, 16662135, -21306940, 11308411,
+ -14068454, 12021730, 9955285, -16303356},
+ {9734894, -14576830, -7473633, -9138735, 2060392, 11313496,
+ -18426029, 9924399, 20194861, 13380996},
+ {-26378102, -7965207, -22167821, 15789297, -18055342, -6168792,
+ -1984914, 15707771, 26342023, 10146099},
+ },
+ },
+ {
+ {
+ {-26016874, -219943, 21339191, -41388, 19745256, -2878700,
+ -29637280, 2227040, 21612326, -545728},
+ {-13077387, 1184228, 23562814, -5970442, -20351244, -6348714,
+ 25764461, 12243797, -20856566, 11649658},
+ {-10031494, 11262626, 27384172, 2271902, 26947504, -15997771, 39944,
+ 6114064, 33514190, 2333242},
+ },
+ {
+ {-21433588, -12421821, 8119782, 7219913, -21830522, -9016134,
+ -6679750, -12670638, 24350578, -13450001},
+ {-4116307, -11271533, -23886186, 4843615, -30088339, 690623,
+ -31536088, -10406836, 8317860, 12352766},
+ {18200138, -14475911, -33087759, -2696619, -23702521, -9102511,
+ -23552096, -2287550, 20712163, 6719373},
+ },
+ {
+ {26656208, 6075253, -7858556, 1886072, -28344043, 4262326, 11117530,
+ -3763210, 26224235, -3297458},
+ {-17168938, -14854097, -3395676, -16369877, -19954045, 14050420,
+ 21728352, 9493610, 18620611, -16428628},
+ {-13323321, 13325349, 11432106, 5964811, 18609221, 6062965,
+ -5269471, -9725556, -30701573, -16479657},
+ },
+ {
+ {-23860538, -11233159, 26961357, 1640861, -32413112, -16737940,
+ 12248509, -5240639, 13735342, 1934062},
+ {25089769, 6742589, 17081145, -13406266, 21909293, -16067981,
+ -15136294, -3765346, -21277997, 5473616},
+ {31883677, -7961101, 1083432, -11572403, 22828471, 13290673,
+ -7125085, 12469656, 29111212, -5451014},
+ },
+ {
+ {24244947, -15050407, -26262976, 2791540, -14997599, 16666678,
+ 24367466, 6388839, -10295587, 452383},
+ {-25640782, -3417841, 5217916, 16224624, 19987036, -4082269,
+ -24236251, -5915248, 15766062, 8407814},
+ {-20406999, 13990231, 15495425, 16395525, 5377168, 15166495,
+ -8917023, -4388953, -8067909, 2276718},
+ },
+ {
+ {30157918, 12924066, -17712050, 9245753, 19895028, 3368142,
+ -23827587, 5096219, 22740376, -7303417},
+ {2041139, -14256350, 7783687, 13876377, -25946985, -13352459,
+ 24051124, 13742383, -15637599, 13295222},
+ {33338237, -8505733, 12532113, 7977527, 9106186, -1715251,
+ -17720195, -4612972, -4451357, -14669444},
+ },
+ {
+ {-20045281, 5454097, -14346548, 6447146, 28862071, 1883651,
+ -2469266, -4141880, 7770569, 9620597},
+ {23208068, 7979712, 33071466, 8149229, 1758231, -10834995, 30945528,
+ -1694323, -33502340, -14767970},
+ {1439958, -16270480, -1079989, -793782, 4625402, 10647766, -5043801,
+ 1220118, 30494170, -11440799},
+ },
+ {
+ {-5037580, -13028295, -2970559, -3061767, 15640974, -6701666,
+ -26739026, 926050, -1684339, -13333647},
+ {13908495, -3549272, 30919928, -6273825, -21521863, 7989039,
+ 9021034, 9078865, 3353509, 4033511},
+ {-29663431, -15113610, 32259991, -344482, 24295849, -12912123,
+ 23161163, 8839127, 27485041, 7356032},
+ },
+ },
+ {
+ {
+ {9661027, 705443, 11980065, -5370154, -1628543, 14661173, -6346142,
+ 2625015, 28431036, -16771834},
+ {-23839233, -8311415, -25945511, 7480958, -17681669, -8354183,
+ -22545972, 14150565, 15970762, 4099461},
+ {29262576, 16756590, 26350592, -8793563, 8529671, -11208050,
+ 13617293, -9937143, 11465739, 8317062},
+ },
+ {
+ {-25493081, -6962928, 32500200, -9419051, -23038724, -2302222,
+ 14898637, 3848455, 20969334, -5157516},
+ {-20384450, -14347713, -18336405, 13884722, -33039454, 2842114,
+ -21610826, -3649888, 11177095, 14989547},
+ {-24496721, -11716016, 16959896, 2278463, 12066309, 10137771,
+ 13515641, 2581286, -28487508, 9930240},
+ },
+ {
+ {-17751622, -2097826, 16544300, -13009300, -15914807, -14949081,
+ 18345767, -13403753, 16291481, -5314038},
+ {-33229194, 2553288, 32678213, 9875984, 8534129, 6889387, -9676774,
+ 6957617, 4368891, 9788741},
+ {16660756, 7281060, -10830758, 12911820, 20108584, -8101676,
+ -21722536, -8613148, 16250552, -11111103},
+ },
+ {
+ {-19765507, 2390526, -16551031, 14161980, 1905286, 6414907, 4689584,
+ 10604807, -30190403, 4782747},
+ {-1354539, 14736941, -7367442, -13292886, 7710542, -14155590,
+ -9981571, 4383045, 22546403, 437323},
+ {31665577, -12180464, -16186830, 1491339, -18368625, 3294682,
+ 27343084, 2786261, -30633590, -14097016},
+ },
+ {
+ {-14467279, -683715, -33374107, 7448552, 19294360, 14334329,
+ -19690631, 2355319, -19284671, -6114373},
+ {15121312, -15796162, 6377020, -6031361, -10798111, -12957845,
+ 18952177, 15496498, -29380133, 11754228},
+ {-2637277, -13483075, 8488727, -14303896, 12728761, -1622493,
+ 7141596, 11724556, 22761615, -10134141},
+ },
+ {
+ {16918416, 11729663, -18083579, 3022987, -31015732, -13339659,
+ -28741185, -12227393, 32851222, 11717399},
+ {11166634, 7338049, -6722523, 4531520, -29468672, -7302055,
+ 31474879, 3483633, -1193175, -4030831},
+ {-185635, 9921305, 31456609, -13536438, -12013818, 13348923,
+ 33142652, 6546660, -19985279, -3948376},
+ },
+ {
+ {-32460596, 11266712, -11197107, -7899103, 31703694, 3855903,
+ -8537131, -12833048, -30772034, -15486313},
+ {-18006477, 12709068, 3991746, -6479188, -21491523, -10550425,
+ -31135347, -16049879, 10928917, 3011958},
+ {-6957757, -15594337, 31696059, 334240, 29576716, 14796075,
+ -30831056, -12805180, 18008031, 10258577},
+ },
+ {
+ {-22448644, 15655569, 7018479, -4410003, -30314266, -1201591,
+ -1853465, 1367120, 25127874, 6671743},
+ {29701166, -14373934, -10878120, 9279288, -17568, 13127210,
+ 21382910, 11042292, 25838796, 4642684},
+ {-20430234, 14955537, -24126347, 8124619, -5369288, -5990470,
+ 30468147, -13900640, 18423289, 4177476},
+ },
+ },
+};
+
+static uint8_t negative(signed char b) {
+ uint32_t x = b;
+ x >>= 31; /* 1: yes; 0: no */
+ return x;
+}
+
+static void table_select(ge_precomp *t, int pos, signed char b) {
+ ge_precomp minust;
+ uint8_t bnegative = negative(b);
+ uint8_t babs = b - (((-bnegative) & b) << 1);
+
+ ge_precomp_0(t);
+ cmov(t, &base[pos][0], equal(babs, 1));
+ cmov(t, &base[pos][1], equal(babs, 2));
+ cmov(t, &base[pos][2], equal(babs, 3));
+ cmov(t, &base[pos][3], equal(babs, 4));
+ cmov(t, &base[pos][4], equal(babs, 5));
+ cmov(t, &base[pos][5], equal(babs, 6));
+ cmov(t, &base[pos][6], equal(babs, 7));
+ cmov(t, &base[pos][7], equal(babs, 8));
+ fe_copy(minust.yplusx, t->yminusx);
+ fe_copy(minust.yminusx, t->yplusx);
+ fe_neg(minust.xy2d, t->xy2d);
+ cmov(t, &minust, bnegative);
+}
+
+/* h = a * B
+ * where a = a[0]+256*a[1]+...+256^31 a[31]
+ * B is the Ed25519 base point (x,4/5) with x positive.
+ *
+ * Preconditions:
+ * a[31] <= 127 */
+static void ge_scalarmult_base(ge_p3 *h, const uint8_t *a) {
+ signed char e[64];
+ signed char carry;
+ ge_p1p1 r;
+ ge_p2 s;
+ ge_precomp t;
+ int i;
+
+ for (i = 0; i < 32; ++i) {
+ e[2 * i + 0] = (a[i] >> 0) & 15;
+ e[2 * i + 1] = (a[i] >> 4) & 15;
+ }
+ /* each e[i] is between 0 and 15 */
+ /* e[63] is between 0 and 7 */
+
+ carry = 0;
+ for (i = 0; i < 63; ++i) {
+ e[i] += carry;
+ carry = e[i] + 8;
+ carry >>= 4;
+ e[i] -= carry << 4;
+ }
+ e[63] += carry;
+ /* each e[i] is between -8 and 8 */
+
+ ge_p3_0(h);
+ for (i = 1; i < 64; i += 2) {
+ table_select(&t, i / 2, e[i]);
+ ge_madd(&r, h, &t);
+ ge_p1p1_to_p3(h, &r);
+ }
+
+ ge_p3_dbl(&r, h);
+ ge_p1p1_to_p2(&s, &r);
+ ge_p2_dbl(&r, &s);
+ ge_p1p1_to_p2(&s, &r);
+ ge_p2_dbl(&r, &s);
+ ge_p1p1_to_p2(&s, &r);
+ ge_p2_dbl(&r, &s);
+ ge_p1p1_to_p3(h, &r);
+
+ for (i = 0; i < 64; i += 2) {
+ table_select(&t, i / 2, e[i]);
+ ge_madd(&r, h, &t);
+ ge_p1p1_to_p3(h, &r);
+ }
+}
+
+#endif
+
+static void slide(signed char *r, const uint8_t *a) {
+ int i;
+ int b;
+ int k;
+
+ for (i = 0; i < 256; ++i) {
+ r[i] = 1 & (a[i >> 3] >> (i & 7));
+ }
+
+ for (i = 0; i < 256; ++i) {
+ if (r[i]) {
+ for (b = 1; b <= 6 && i + b < 256; ++b) {
+ if (r[i + b]) {
+ if (r[i] + (r[i + b] << b) <= 15) {
+ r[i] += r[i + b] << b;
+ r[i + b] = 0;
+ } else if (r[i] - (r[i + b] << b) >= -15) {
+ r[i] -= r[i + b] << b;
+ for (k = i + b; k < 256; ++k) {
+ if (!r[k]) {
+ r[k] = 1;
+ break;
+ }
+ r[k] = 0;
+ }
+ } else {
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+static ge_precomp Bi[8] = {
+ {
+ {25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626,
+ -11754271, -6079156, 2047605},
+ {-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692,
+ 5043384, 19500929, -15469378},
+ {-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919,
+ 11864899, -24514362, -4438546},
+ },
+ {
+ {15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600,
+ -14772189, 28944400, -1550024},
+ {16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577,
+ -11775962, 7689662, 11199574},
+ {30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774,
+ 10017326, -17749093, -9920357},
+ },
+ {
+ {10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885,
+ 14515107, -15438304, 10819380},
+ {4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668,
+ 12483688, -12668491, 5581306},
+ {19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350,
+ 13850243, -23678021, -15815942},
+ },
+ {
+ {5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852,
+ 5230134, -23952439, -15175766},
+ {-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025,
+ 16520125, 30598449, 7715701},
+ {28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660,
+ 1370708, 29794553, -1409300},
+ },
+ {
+ {-22518993, -6692182, 14201702, -8745502, -23510406, 8844726, 18474211,
+ -1361450, -13062696, 13821877},
+ {-6455177, -7839871, 3374702, -4740862, -27098617, -10571707, 31655028,
+ -7212327, 18853322, -14220951},
+ {4566830, -12963868, -28974889, -12240689, -7602672, -2830569, -8514358,
+ -10431137, 2207753, -3209784},
+ },
+ {
+ {-25154831, -4185821, 29681144, 7868801, -6854661, -9423865, -12437364,
+ -663000, -31111463, -16132436},
+ {25576264, -2703214, 7349804, -11814844, 16472782, 9300885, 3844789,
+ 15725684, 171356, 6466918},
+ {23103977, 13316479, 9739013, -16149481, 817875, -15038942, 8965339,
+ -14088058, -30714912, 16193877},
+ },
+ {
+ {-33521811, 3180713, -2394130, 14003687, -16903474, -16270840, 17238398,
+ 4729455, -18074513, 9256800},
+ {-25182317, -4174131, 32336398, 5036987, -21236817, 11360617, 22616405,
+ 9761698, -19827198, 630305},
+ {-13720693, 2639453, -24237460, -7406481, 9494427, -5774029, -6554551,
+ -15960994, -2449256, -14291300},
+ },
+ {
+ {-3151181, -5046075, 9282714, 6866145, -31907062, -863023, -18940575,
+ 15033784, 25105118, -7894876},
+ {-24326370, 15950226, -31801215, -14592823, -11662737, -5090925,
+ 1573892, -2625887, 2198790, -15804619},
+ {-3099351, 10324967, -2241613, 7453183, -5446979, -2735503, -13812022,
+ -16236442, -32461234, -12290683},
+ },
+};
+
+/* r = a * A + b * B
+ * where a = a[0]+256*a[1]+...+256^31 a[31].
+ * and b = b[0]+256*b[1]+...+256^31 b[31].
+ * B is the Ed25519 base point (x,4/5) with x positive. */
+void ge_double_scalarmult_vartime(ge_p2 *r, const uint8_t *a,
+ const ge_p3 *A, const uint8_t *b) {
+ signed char aslide[256];
+ signed char bslide[256];
+ ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */
+ ge_p1p1 t;
+ ge_p3 u;
+ ge_p3 A2;
+ int i;
+
+ slide(aslide, a);
+ slide(bslide, b);
+
+ ge_p3_to_cached(&Ai[0], A);
+ ge_p3_dbl(&t, A);
+ ge_p1p1_to_p3(&A2, &t);
+ ge_add(&t, &A2, &Ai[0]);
+ ge_p1p1_to_p3(&u, &t);
+ ge_p3_to_cached(&Ai[1], &u);
+ ge_add(&t, &A2, &Ai[1]);
+ ge_p1p1_to_p3(&u, &t);
+ ge_p3_to_cached(&Ai[2], &u);
+ ge_add(&t, &A2, &Ai[2]);
+ ge_p1p1_to_p3(&u, &t);
+ ge_p3_to_cached(&Ai[3], &u);
+ ge_add(&t, &A2, &Ai[3]);
+ ge_p1p1_to_p3(&u, &t);
+ ge_p3_to_cached(&Ai[4], &u);
+ ge_add(&t, &A2, &Ai[4]);
+ ge_p1p1_to_p3(&u, &t);
+ ge_p3_to_cached(&Ai[5], &u);
+ ge_add(&t, &A2, &Ai[5]);
+ ge_p1p1_to_p3(&u, &t);
+ ge_p3_to_cached(&Ai[6], &u);
+ ge_add(&t, &A2, &Ai[6]);
+ ge_p1p1_to_p3(&u, &t);
+ ge_p3_to_cached(&Ai[7], &u);
+
+ ge_p2_0(r);
+
+ for (i = 255; i >= 0; --i) {
+ if (aslide[i] || bslide[i]) {
+ break;
+ }
+ }
+
+ for (; i >= 0; --i) {
+ ge_p2_dbl(&t, r);
+
+ if (aslide[i] > 0) {
+ ge_p1p1_to_p3(&u, &t);
+ ge_add(&t, &u, &Ai[aslide[i] / 2]);
+ } else if (aslide[i] < 0) {
+ ge_p1p1_to_p3(&u, &t);
+ ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]);
+ }
+
+ if (bslide[i] > 0) {
+ ge_p1p1_to_p3(&u, &t);
+ ge_madd(&t, &u, &Bi[bslide[i] / 2]);
+ } else if (bslide[i] < 0) {
+ ge_p1p1_to_p3(&u, &t);
+ ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]);
+ }
+
+ ge_p1p1_to_p2(r, &t);
+ }
+}
+
+/* The set of scalars is \Z/l
+ * where l = 2^252 + 27742317777372353535851937790883648493. */
+
+/* Input:
+ * s[0]+256*s[1]+...+256^63*s[63] = s
+ *
+ * Output:
+ * s[0]+256*s[1]+...+256^31*s[31] = s mod l
+ * where l = 2^252 + 27742317777372353535851937790883648493.
+ * Overwrites s in place. */
+static void sc_reduce(uint8_t *s) {
+ int64_t s0 = 2097151 & load_3(s);
+ int64_t s1 = 2097151 & (load_4(s + 2) >> 5);
+ int64_t s2 = 2097151 & (load_3(s + 5) >> 2);
+ int64_t s3 = 2097151 & (load_4(s + 7) >> 7);
+ int64_t s4 = 2097151 & (load_4(s + 10) >> 4);
+ int64_t s5 = 2097151 & (load_3(s + 13) >> 1);
+ int64_t s6 = 2097151 & (load_4(s + 15) >> 6);
+ int64_t s7 = 2097151 & (load_3(s + 18) >> 3);
+ int64_t s8 = 2097151 & load_3(s + 21);
+ int64_t s9 = 2097151 & (load_4(s + 23) >> 5);
+ int64_t s10 = 2097151 & (load_3(s + 26) >> 2);
+ int64_t s11 = 2097151 & (load_4(s + 28) >> 7);
+ int64_t s12 = 2097151 & (load_4(s + 31) >> 4);
+ int64_t s13 = 2097151 & (load_3(s + 34) >> 1);
+ int64_t s14 = 2097151 & (load_4(s + 36) >> 6);
+ int64_t s15 = 2097151 & (load_3(s + 39) >> 3);
+ int64_t s16 = 2097151 & load_3(s + 42);
+ int64_t s17 = 2097151 & (load_4(s + 44) >> 5);
+ int64_t s18 = 2097151 & (load_3(s + 47) >> 2);
+ int64_t s19 = 2097151 & (load_4(s + 49) >> 7);
+ int64_t s20 = 2097151 & (load_4(s + 52) >> 4);
+ int64_t s21 = 2097151 & (load_3(s + 55) >> 1);
+ int64_t s22 = 2097151 & (load_4(s + 57) >> 6);
+ int64_t s23 = (load_4(s + 60) >> 3);
+ int64_t carry0;
+ int64_t carry1;
+ int64_t carry2;
+ int64_t carry3;
+ int64_t carry4;
+ int64_t carry5;
+ int64_t carry6;
+ int64_t carry7;
+ int64_t carry8;
+ int64_t carry9;
+ int64_t carry10;
+ int64_t carry11;
+ int64_t carry12;
+ int64_t carry13;
+ int64_t carry14;
+ int64_t carry15;
+ int64_t carry16;
+
+ s11 += s23 * 666643;
+ s12 += s23 * 470296;
+ s13 += s23 * 654183;
+ s14 -= s23 * 997805;
+ s15 += s23 * 136657;
+ s16 -= s23 * 683901;
+ s23 = 0;
+
+ s10 += s22 * 666643;
+ s11 += s22 * 470296;
+ s12 += s22 * 654183;
+ s13 -= s22 * 997805;
+ s14 += s22 * 136657;
+ s15 -= s22 * 683901;
+ s22 = 0;
+
+ s9 += s21 * 666643;
+ s10 += s21 * 470296;
+ s11 += s21 * 654183;
+ s12 -= s21 * 997805;
+ s13 += s21 * 136657;
+ s14 -= s21 * 683901;
+ s21 = 0;
+
+ s8 += s20 * 666643;
+ s9 += s20 * 470296;
+ s10 += s20 * 654183;
+ s11 -= s20 * 997805;
+ s12 += s20 * 136657;
+ s13 -= s20 * 683901;
+ s20 = 0;
+
+ s7 += s19 * 666643;
+ s8 += s19 * 470296;
+ s9 += s19 * 654183;
+ s10 -= s19 * 997805;
+ s11 += s19 * 136657;
+ s12 -= s19 * 683901;
+ s19 = 0;
+
+ s6 += s18 * 666643;
+ s7 += s18 * 470296;
+ s8 += s18 * 654183;
+ s9 -= s18 * 997805;
+ s10 += s18 * 136657;
+ s11 -= s18 * 683901;
+ s18 = 0;
+
+ carry6 = (s6 + (1 << 20)) >> 21;
+ s7 += carry6;
+ s6 -= carry6 << 21;
+ carry8 = (s8 + (1 << 20)) >> 21;
+ s9 += carry8;
+ s8 -= carry8 << 21;
+ carry10 = (s10 + (1 << 20)) >> 21;
+ s11 += carry10;
+ s10 -= carry10 << 21;
+ carry12 = (s12 + (1 << 20)) >> 21;
+ s13 += carry12;
+ s12 -= carry12 << 21;
+ carry14 = (s14 + (1 << 20)) >> 21;
+ s15 += carry14;
+ s14 -= carry14 << 21;
+ carry16 = (s16 + (1 << 20)) >> 21;
+ s17 += carry16;
+ s16 -= carry16 << 21;
+
+ carry7 = (s7 + (1 << 20)) >> 21;
+ s8 += carry7;
+ s7 -= carry7 << 21;
+ carry9 = (s9 + (1 << 20)) >> 21;
+ s10 += carry9;
+ s9 -= carry9 << 21;
+ carry11 = (s11 + (1 << 20)) >> 21;
+ s12 += carry11;
+ s11 -= carry11 << 21;
+ carry13 = (s13 + (1 << 20)) >> 21;
+ s14 += carry13;
+ s13 -= carry13 << 21;
+ carry15 = (s15 + (1 << 20)) >> 21;
+ s16 += carry15;
+ s15 -= carry15 << 21;
+
+ s5 += s17 * 666643;
+ s6 += s17 * 470296;
+ s7 += s17 * 654183;
+ s8 -= s17 * 997805;
+ s9 += s17 * 136657;
+ s10 -= s17 * 683901;
+ s17 = 0;
+
+ s4 += s16 * 666643;
+ s5 += s16 * 470296;
+ s6 += s16 * 654183;
+ s7 -= s16 * 997805;
+ s8 += s16 * 136657;
+ s9 -= s16 * 683901;
+ s16 = 0;
+
+ s3 += s15 * 666643;
+ s4 += s15 * 470296;
+ s5 += s15 * 654183;
+ s6 -= s15 * 997805;
+ s7 += s15 * 136657;
+ s8 -= s15 * 683901;
+ s15 = 0;
+
+ s2 += s14 * 666643;
+ s3 += s14 * 470296;
+ s4 += s14 * 654183;
+ s5 -= s14 * 997805;
+ s6 += s14 * 136657;
+ s7 -= s14 * 683901;
+ s14 = 0;
+
+ s1 += s13 * 666643;
+ s2 += s13 * 470296;
+ s3 += s13 * 654183;
+ s4 -= s13 * 997805;
+ s5 += s13 * 136657;
+ s6 -= s13 * 683901;
+ s13 = 0;
+
+ s0 += s12 * 666643;
+ s1 += s12 * 470296;
+ s2 += s12 * 654183;
+ s3 -= s12 * 997805;
+ s4 += s12 * 136657;
+ s5 -= s12 * 683901;
+ s12 = 0;
+
+ carry0 = (s0 + (1 << 20)) >> 21;
+ s1 += carry0;
+ s0 -= carry0 << 21;
+ carry2 = (s2 + (1 << 20)) >> 21;
+ s3 += carry2;
+ s2 -= carry2 << 21;
+ carry4 = (s4 + (1 << 20)) >> 21;
+ s5 += carry4;
+ s4 -= carry4 << 21;
+ carry6 = (s6 + (1 << 20)) >> 21;
+ s7 += carry6;
+ s6 -= carry6 << 21;
+ carry8 = (s8 + (1 << 20)) >> 21;
+ s9 += carry8;
+ s8 -= carry8 << 21;
+ carry10 = (s10 + (1 << 20)) >> 21;
+ s11 += carry10;
+ s10 -= carry10 << 21;
+
+ carry1 = (s1 + (1 << 20)) >> 21;
+ s2 += carry1;
+ s1 -= carry1 << 21;
+ carry3 = (s3 + (1 << 20)) >> 21;
+ s4 += carry3;
+ s3 -= carry3 << 21;
+ carry5 = (s5 + (1 << 20)) >> 21;
+ s6 += carry5;
+ s5 -= carry5 << 21;
+ carry7 = (s7 + (1 << 20)) >> 21;
+ s8 += carry7;
+ s7 -= carry7 << 21;
+ carry9 = (s9 + (1 << 20)) >> 21;
+ s10 += carry9;
+ s9 -= carry9 << 21;
+ carry11 = (s11 + (1 << 20)) >> 21;
+ s12 += carry11;
+ s11 -= carry11 << 21;
+
+ s0 += s12 * 666643;
+ s1 += s12 * 470296;
+ s2 += s12 * 654183;
+ s3 -= s12 * 997805;
+ s4 += s12 * 136657;
+ s5 -= s12 * 683901;
+ s12 = 0;
+
+ carry0 = s0 >> 21;
+ s1 += carry0;
+ s0 -= carry0 << 21;
+ carry1 = s1 >> 21;
+ s2 += carry1;
+ s1 -= carry1 << 21;
+ carry2 = s2 >> 21;
+ s3 += carry2;
+ s2 -= carry2 << 21;
+ carry3 = s3 >> 21;
+ s4 += carry3;
+ s3 -= carry3 << 21;
+ carry4 = s4 >> 21;
+ s5 += carry4;
+ s4 -= carry4 << 21;
+ carry5 = s5 >> 21;
+ s6 += carry5;
+ s5 -= carry5 << 21;
+ carry6 = s6 >> 21;
+ s7 += carry6;
+ s6 -= carry6 << 21;
+ carry7 = s7 >> 21;
+ s8 += carry7;
+ s7 -= carry7 << 21;
+ carry8 = s8 >> 21;
+ s9 += carry8;
+ s8 -= carry8 << 21;
+ carry9 = s9 >> 21;
+ s10 += carry9;
+ s9 -= carry9 << 21;
+ carry10 = s10 >> 21;
+ s11 += carry10;
+ s10 -= carry10 << 21;
+ carry11 = s11 >> 21;
+ s12 += carry11;
+ s11 -= carry11 << 21;
+
+ s0 += s12 * 666643;
+ s1 += s12 * 470296;
+ s2 += s12 * 654183;
+ s3 -= s12 * 997805;
+ s4 += s12 * 136657;
+ s5 -= s12 * 683901;
+ s12 = 0;
+
+ carry0 = s0 >> 21;
+ s1 += carry0;
+ s0 -= carry0 << 21;
+ carry1 = s1 >> 21;
+ s2 += carry1;
+ s1 -= carry1 << 21;
+ carry2 = s2 >> 21;
+ s3 += carry2;
+ s2 -= carry2 << 21;
+ carry3 = s3 >> 21;
+ s4 += carry3;
+ s3 -= carry3 << 21;
+ carry4 = s4 >> 21;
+ s5 += carry4;
+ s4 -= carry4 << 21;
+ carry5 = s5 >> 21;
+ s6 += carry5;
+ s5 -= carry5 << 21;
+ carry6 = s6 >> 21;
+ s7 += carry6;
+ s6 -= carry6 << 21;
+ carry7 = s7 >> 21;
+ s8 += carry7;
+ s7 -= carry7 << 21;
+ carry8 = s8 >> 21;
+ s9 += carry8;
+ s8 -= carry8 << 21;
+ carry9 = s9 >> 21;
+ s10 += carry9;
+ s9 -= carry9 << 21;
+ carry10 = s10 >> 21;
+ s11 += carry10;
+ s10 -= carry10 << 21;
+
+ s[0] = s0 >> 0;
+ s[1] = s0 >> 8;
+ s[2] = (s0 >> 16) | (s1 << 5);
+ s[3] = s1 >> 3;
+ s[4] = s1 >> 11;
+ s[5] = (s1 >> 19) | (s2 << 2);
+ s[6] = s2 >> 6;
+ s[7] = (s2 >> 14) | (s3 << 7);
+ s[8] = s3 >> 1;
+ s[9] = s3 >> 9;
+ s[10] = (s3 >> 17) | (s4 << 4);
+ s[11] = s4 >> 4;
+ s[12] = s4 >> 12;
+ s[13] = (s4 >> 20) | (s5 << 1);
+ s[14] = s5 >> 7;
+ s[15] = (s5 >> 15) | (s6 << 6);
+ s[16] = s6 >> 2;
+ s[17] = s6 >> 10;
+ s[18] = (s6 >> 18) | (s7 << 3);
+ s[19] = s7 >> 5;
+ s[20] = s7 >> 13;
+ s[21] = s8 >> 0;
+ s[22] = s8 >> 8;
+ s[23] = (s8 >> 16) | (s9 << 5);
+ s[24] = s9 >> 3;
+ s[25] = s9 >> 11;
+ s[26] = (s9 >> 19) | (s10 << 2);
+ s[27] = s10 >> 6;
+ s[28] = (s10 >> 14) | (s11 << 7);
+ s[29] = s11 >> 1;
+ s[30] = s11 >> 9;
+ s[31] = s11 >> 17;
+}
+
+/* Input:
+ * a[0]+256*a[1]+...+256^31*a[31] = a
+ * b[0]+256*b[1]+...+256^31*b[31] = b
+ * c[0]+256*c[1]+...+256^31*c[31] = c
+ *
+ * Output:
+ * s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
+ * where l = 2^252 + 27742317777372353535851937790883648493. */
+static void sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b,
+ const uint8_t *c) {
+ int64_t a0 = 2097151 & load_3(a);
+ int64_t a1 = 2097151 & (load_4(a + 2) >> 5);
+ int64_t a2 = 2097151 & (load_3(a + 5) >> 2);
+ int64_t a3 = 2097151 & (load_4(a + 7) >> 7);
+ int64_t a4 = 2097151 & (load_4(a + 10) >> 4);
+ int64_t a5 = 2097151 & (load_3(a + 13) >> 1);
+ int64_t a6 = 2097151 & (load_4(a + 15) >> 6);
+ int64_t a7 = 2097151 & (load_3(a + 18) >> 3);
+ int64_t a8 = 2097151 & load_3(a + 21);
+ int64_t a9 = 2097151 & (load_4(a + 23) >> 5);
+ int64_t a10 = 2097151 & (load_3(a + 26) >> 2);
+ int64_t a11 = (load_4(a + 28) >> 7);
+ int64_t b0 = 2097151 & load_3(b);
+ int64_t b1 = 2097151 & (load_4(b + 2) >> 5);
+ int64_t b2 = 2097151 & (load_3(b + 5) >> 2);
+ int64_t b3 = 2097151 & (load_4(b + 7) >> 7);
+ int64_t b4 = 2097151 & (load_4(b + 10) >> 4);
+ int64_t b5 = 2097151 & (load_3(b + 13) >> 1);
+ int64_t b6 = 2097151 & (load_4(b + 15) >> 6);
+ int64_t b7 = 2097151 & (load_3(b + 18) >> 3);
+ int64_t b8 = 2097151 & load_3(b + 21);
+ int64_t b9 = 2097151 & (load_4(b + 23) >> 5);
+ int64_t b10 = 2097151 & (load_3(b + 26) >> 2);
+ int64_t b11 = (load_4(b + 28) >> 7);
+ int64_t c0 = 2097151 & load_3(c);
+ int64_t c1 = 2097151 & (load_4(c + 2) >> 5);
+ int64_t c2 = 2097151 & (load_3(c + 5) >> 2);
+ int64_t c3 = 2097151 & (load_4(c + 7) >> 7);
+ int64_t c4 = 2097151 & (load_4(c + 10) >> 4);
+ int64_t c5 = 2097151 & (load_3(c + 13) >> 1);
+ int64_t c6 = 2097151 & (load_4(c + 15) >> 6);
+ int64_t c7 = 2097151 & (load_3(c + 18) >> 3);
+ int64_t c8 = 2097151 & load_3(c + 21);
+ int64_t c9 = 2097151 & (load_4(c + 23) >> 5);
+ int64_t c10 = 2097151 & (load_3(c + 26) >> 2);
+ int64_t c11 = (load_4(c + 28) >> 7);
+ int64_t s0;
+ int64_t s1;
+ int64_t s2;
+ int64_t s3;
+ int64_t s4;
+ int64_t s5;
+ int64_t s6;
+ int64_t s7;
+ int64_t s8;
+ int64_t s9;
+ int64_t s10;
+ int64_t s11;
+ int64_t s12;
+ int64_t s13;
+ int64_t s14;
+ int64_t s15;
+ int64_t s16;
+ int64_t s17;
+ int64_t s18;
+ int64_t s19;
+ int64_t s20;
+ int64_t s21;
+ int64_t s22;
+ int64_t s23;
+ int64_t carry0;
+ int64_t carry1;
+ int64_t carry2;
+ int64_t carry3;
+ int64_t carry4;
+ int64_t carry5;
+ int64_t carry6;
+ int64_t carry7;
+ int64_t carry8;
+ int64_t carry9;
+ int64_t carry10;
+ int64_t carry11;
+ int64_t carry12;
+ int64_t carry13;
+ int64_t carry14;
+ int64_t carry15;
+ int64_t carry16;
+ int64_t carry17;
+ int64_t carry18;
+ int64_t carry19;
+ int64_t carry20;
+ int64_t carry21;
+ int64_t carry22;
+
+ s0 = c0 + a0 * b0;
+ s1 = c1 + a0 * b1 + a1 * b0;
+ s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0;
+ s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0;
+ s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0;
+ s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0;
+ s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0;
+ s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 +
+ a6 * b1 + a7 * b0;
+ s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 +
+ a6 * b2 + a7 * b1 + a8 * b0;
+ s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 +
+ a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0;
+ s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 +
+ a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0;
+ s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 +
+ a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0;
+ s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 +
+ a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1;
+ s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 +
+ a9 * b4 + a10 * b3 + a11 * b2;
+ s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 +
+ a10 * b4 + a11 * b3;
+ s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 +
+ a11 * b4;
+ s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5;
+ s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6;
+ s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7;
+ s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8;
+ s20 = a9 * b11 + a10 * b10 + a11 * b9;
+ s21 = a10 * b11 + a11 * b10;
+ s22 = a11 * b11;
+ s23 = 0;
+
+ carry0 = (s0 + (1 << 20)) >> 21;
+ s1 += carry0;
+ s0 -= carry0 << 21;
+ carry2 = (s2 + (1 << 20)) >> 21;
+ s3 += carry2;
+ s2 -= carry2 << 21;
+ carry4 = (s4 + (1 << 20)) >> 21;
+ s5 += carry4;
+ s4 -= carry4 << 21;
+ carry6 = (s6 + (1 << 20)) >> 21;
+ s7 += carry6;
+ s6 -= carry6 << 21;
+ carry8 = (s8 + (1 << 20)) >> 21;
+ s9 += carry8;
+ s8 -= carry8 << 21;
+ carry10 = (s10 + (1 << 20)) >> 21;
+ s11 += carry10;
+ s10 -= carry10 << 21;
+ carry12 = (s12 + (1 << 20)) >> 21;
+ s13 += carry12;
+ s12 -= carry12 << 21;
+ carry14 = (s14 + (1 << 20)) >> 21;
+ s15 += carry14;
+ s14 -= carry14 << 21;
+ carry16 = (s16 + (1 << 20)) >> 21;
+ s17 += carry16;
+ s16 -= carry16 << 21;
+ carry18 = (s18 + (1 << 20)) >> 21;
+ s19 += carry18;
+ s18 -= carry18 << 21;
+ carry20 = (s20 + (1 << 20)) >> 21;
+ s21 += carry20;
+ s20 -= carry20 << 21;
+ carry22 = (s22 + (1 << 20)) >> 21;
+ s23 += carry22;
+ s22 -= carry22 << 21;
+
+ carry1 = (s1 + (1 << 20)) >> 21;
+ s2 += carry1;
+ s1 -= carry1 << 21;
+ carry3 = (s3 + (1 << 20)) >> 21;
+ s4 += carry3;
+ s3 -= carry3 << 21;
+ carry5 = (s5 + (1 << 20)) >> 21;
+ s6 += carry5;
+ s5 -= carry5 << 21;
+ carry7 = (s7 + (1 << 20)) >> 21;
+ s8 += carry7;
+ s7 -= carry7 << 21;
+ carry9 = (s9 + (1 << 20)) >> 21;
+ s10 += carry9;
+ s9 -= carry9 << 21;
+ carry11 = (s11 + (1 << 20)) >> 21;
+ s12 += carry11;
+ s11 -= carry11 << 21;
+ carry13 = (s13 + (1 << 20)) >> 21;
+ s14 += carry13;
+ s13 -= carry13 << 21;
+ carry15 = (s15 + (1 << 20)) >> 21;
+ s16 += carry15;
+ s15 -= carry15 << 21;
+ carry17 = (s17 + (1 << 20)) >> 21;
+ s18 += carry17;
+ s17 -= carry17 << 21;
+ carry19 = (s19 + (1 << 20)) >> 21;
+ s20 += carry19;
+ s19 -= carry19 << 21;
+ carry21 = (s21 + (1 << 20)) >> 21;
+ s22 += carry21;
+ s21 -= carry21 << 21;
+
+ s11 += s23 * 666643;
+ s12 += s23 * 470296;
+ s13 += s23 * 654183;
+ s14 -= s23 * 997805;
+ s15 += s23 * 136657;
+ s16 -= s23 * 683901;
+ s23 = 0;
+
+ s10 += s22 * 666643;
+ s11 += s22 * 470296;
+ s12 += s22 * 654183;
+ s13 -= s22 * 997805;
+ s14 += s22 * 136657;
+ s15 -= s22 * 683901;
+ s22 = 0;
+
+ s9 += s21 * 666643;
+ s10 += s21 * 470296;
+ s11 += s21 * 654183;
+ s12 -= s21 * 997805;
+ s13 += s21 * 136657;
+ s14 -= s21 * 683901;
+ s21 = 0;
+
+ s8 += s20 * 666643;
+ s9 += s20 * 470296;
+ s10 += s20 * 654183;
+ s11 -= s20 * 997805;
+ s12 += s20 * 136657;
+ s13 -= s20 * 683901;
+ s20 = 0;
+
+ s7 += s19 * 666643;
+ s8 += s19 * 470296;
+ s9 += s19 * 654183;
+ s10 -= s19 * 997805;
+ s11 += s19 * 136657;
+ s12 -= s19 * 683901;
+ s19 = 0;
+
+ s6 += s18 * 666643;
+ s7 += s18 * 470296;
+ s8 += s18 * 654183;
+ s9 -= s18 * 997805;
+ s10 += s18 * 136657;
+ s11 -= s18 * 683901;
+ s18 = 0;
+
+ carry6 = (s6 + (1 << 20)) >> 21;
+ s7 += carry6;
+ s6 -= carry6 << 21;
+ carry8 = (s8 + (1 << 20)) >> 21;
+ s9 += carry8;
+ s8 -= carry8 << 21;
+ carry10 = (s10 + (1 << 20)) >> 21;
+ s11 += carry10;
+ s10 -= carry10 << 21;
+ carry12 = (s12 + (1 << 20)) >> 21;
+ s13 += carry12;
+ s12 -= carry12 << 21;
+ carry14 = (s14 + (1 << 20)) >> 21;
+ s15 += carry14;
+ s14 -= carry14 << 21;
+ carry16 = (s16 + (1 << 20)) >> 21;
+ s17 += carry16;
+ s16 -= carry16 << 21;
+
+ carry7 = (s7 + (1 << 20)) >> 21;
+ s8 += carry7;
+ s7 -= carry7 << 21;
+ carry9 = (s9 + (1 << 20)) >> 21;
+ s10 += carry9;
+ s9 -= carry9 << 21;
+ carry11 = (s11 + (1 << 20)) >> 21;
+ s12 += carry11;
+ s11 -= carry11 << 21;
+ carry13 = (s13 + (1 << 20)) >> 21;
+ s14 += carry13;
+ s13 -= carry13 << 21;
+ carry15 = (s15 + (1 << 20)) >> 21;
+ s16 += carry15;
+ s15 -= carry15 << 21;
+
+ s5 += s17 * 666643;
+ s6 += s17 * 470296;
+ s7 += s17 * 654183;
+ s8 -= s17 * 997805;
+ s9 += s17 * 136657;
+ s10 -= s17 * 683901;
+ s17 = 0;
+
+ s4 += s16 * 666643;
+ s5 += s16 * 470296;
+ s6 += s16 * 654183;
+ s7 -= s16 * 997805;
+ s8 += s16 * 136657;
+ s9 -= s16 * 683901;
+ s16 = 0;
+
+ s3 += s15 * 666643;
+ s4 += s15 * 470296;
+ s5 += s15 * 654183;
+ s6 -= s15 * 997805;
+ s7 += s15 * 136657;
+ s8 -= s15 * 683901;
+ s15 = 0;
+
+ s2 += s14 * 666643;
+ s3 += s14 * 470296;
+ s4 += s14 * 654183;
+ s5 -= s14 * 997805;
+ s6 += s14 * 136657;
+ s7 -= s14 * 683901;
+ s14 = 0;
+
+ s1 += s13 * 666643;
+ s2 += s13 * 470296;
+ s3 += s13 * 654183;
+ s4 -= s13 * 997805;
+ s5 += s13 * 136657;
+ s6 -= s13 * 683901;
+ s13 = 0;
+
+ s0 += s12 * 666643;
+ s1 += s12 * 470296;
+ s2 += s12 * 654183;
+ s3 -= s12 * 997805;
+ s4 += s12 * 136657;
+ s5 -= s12 * 683901;
+ s12 = 0;
+
+ carry0 = (s0 + (1 << 20)) >> 21;
+ s1 += carry0;
+ s0 -= carry0 << 21;
+ carry2 = (s2 + (1 << 20)) >> 21;
+ s3 += carry2;
+ s2 -= carry2 << 21;
+ carry4 = (s4 + (1 << 20)) >> 21;
+ s5 += carry4;
+ s4 -= carry4 << 21;
+ carry6 = (s6 + (1 << 20)) >> 21;
+ s7 += carry6;
+ s6 -= carry6 << 21;
+ carry8 = (s8 + (1 << 20)) >> 21;
+ s9 += carry8;
+ s8 -= carry8 << 21;
+ carry10 = (s10 + (1 << 20)) >> 21;
+ s11 += carry10;
+ s10 -= carry10 << 21;
+
+ carry1 = (s1 + (1 << 20)) >> 21;
+ s2 += carry1;
+ s1 -= carry1 << 21;
+ carry3 = (s3 + (1 << 20)) >> 21;
+ s4 += carry3;
+ s3 -= carry3 << 21;
+ carry5 = (s5 + (1 << 20)) >> 21;
+ s6 += carry5;
+ s5 -= carry5 << 21;
+ carry7 = (s7 + (1 << 20)) >> 21;
+ s8 += carry7;
+ s7 -= carry7 << 21;
+ carry9 = (s9 + (1 << 20)) >> 21;
+ s10 += carry9;
+ s9 -= carry9 << 21;
+ carry11 = (s11 + (1 << 20)) >> 21;
+ s12 += carry11;
+ s11 -= carry11 << 21;
+
+ s0 += s12 * 666643;
+ s1 += s12 * 470296;
+ s2 += s12 * 654183;
+ s3 -= s12 * 997805;
+ s4 += s12 * 136657;
+ s5 -= s12 * 683901;
+ s12 = 0;
+
+ carry0 = s0 >> 21;
+ s1 += carry0;
+ s0 -= carry0 << 21;
+ carry1 = s1 >> 21;
+ s2 += carry1;
+ s1 -= carry1 << 21;
+ carry2 = s2 >> 21;
+ s3 += carry2;
+ s2 -= carry2 << 21;
+ carry3 = s3 >> 21;
+ s4 += carry3;
+ s3 -= carry3 << 21;
+ carry4 = s4 >> 21;
+ s5 += carry4;
+ s4 -= carry4 << 21;
+ carry5 = s5 >> 21;
+ s6 += carry5;
+ s5 -= carry5 << 21;
+ carry6 = s6 >> 21;
+ s7 += carry6;
+ s6 -= carry6 << 21;
+ carry7 = s7 >> 21;
+ s8 += carry7;
+ s7 -= carry7 << 21;
+ carry8 = s8 >> 21;
+ s9 += carry8;
+ s8 -= carry8 << 21;
+ carry9 = s9 >> 21;
+ s10 += carry9;
+ s9 -= carry9 << 21;
+ carry10 = s10 >> 21;
+ s11 += carry10;
+ s10 -= carry10 << 21;
+ carry11 = s11 >> 21;
+ s12 += carry11;
+ s11 -= carry11 << 21;
+
+ s0 += s12 * 666643;
+ s1 += s12 * 470296;
+ s2 += s12 * 654183;
+ s3 -= s12 * 997805;
+ s4 += s12 * 136657;
+ s5 -= s12 * 683901;
+ s12 = 0;
+
+ carry0 = s0 >> 21;
+ s1 += carry0;
+ s0 -= carry0 << 21;
+ carry1 = s1 >> 21;
+ s2 += carry1;
+ s1 -= carry1 << 21;
+ carry2 = s2 >> 21;
+ s3 += carry2;
+ s2 -= carry2 << 21;
+ carry3 = s3 >> 21;
+ s4 += carry3;
+ s3 -= carry3 << 21;
+ carry4 = s4 >> 21;
+ s5 += carry4;
+ s4 -= carry4 << 21;
+ carry5 = s5 >> 21;
+ s6 += carry5;
+ s5 -= carry5 << 21;
+ carry6 = s6 >> 21;
+ s7 += carry6;
+ s6 -= carry6 << 21;
+ carry7 = s7 >> 21;
+ s8 += carry7;
+ s7 -= carry7 << 21;
+ carry8 = s8 >> 21;
+ s9 += carry8;
+ s8 -= carry8 << 21;
+ carry9 = s9 >> 21;
+ s10 += carry9;
+ s9 -= carry9 << 21;
+ carry10 = s10 >> 21;
+ s11 += carry10;
+ s10 -= carry10 << 21;
+
+ s[0] = s0 >> 0;
+ s[1] = s0 >> 8;
+ s[2] = (s0 >> 16) | (s1 << 5);
+ s[3] = s1 >> 3;
+ s[4] = s1 >> 11;
+ s[5] = (s1 >> 19) | (s2 << 2);
+ s[6] = s2 >> 6;
+ s[7] = (s2 >> 14) | (s3 << 7);
+ s[8] = s3 >> 1;
+ s[9] = s3 >> 9;
+ s[10] = (s3 >> 17) | (s4 << 4);
+ s[11] = s4 >> 4;
+ s[12] = s4 >> 12;
+ s[13] = (s4 >> 20) | (s5 << 1);
+ s[14] = s5 >> 7;
+ s[15] = (s5 >> 15) | (s6 << 6);
+ s[16] = s6 >> 2;
+ s[17] = s6 >> 10;
+ s[18] = (s6 >> 18) | (s7 << 3);
+ s[19] = s7 >> 5;
+ s[20] = s7 >> 13;
+ s[21] = s8 >> 0;
+ s[22] = s8 >> 8;
+ s[23] = (s8 >> 16) | (s9 << 5);
+ s[24] = s9 >> 3;
+ s[25] = s9 >> 11;
+ s[26] = (s9 >> 19) | (s10 << 2);
+ s[27] = s10 >> 6;
+ s[28] = (s10 >> 14) | (s11 << 7);
+ s[29] = s11 >> 1;
+ s[30] = s11 >> 9;
+ s[31] = s11 >> 17;
+}
+
+void ED25519_keypair(uint8_t out_public_key[32], uint8_t out_private_key[64]) {
+ uint8_t seed[32];
+ RAND_bytes(seed, 32);
+
+ uint8_t az[SHA512_DIGEST_LENGTH];
+ SHA512(seed, 32, az);
+
+ az[0] &= 248;
+ az[31] &= 63;
+ az[31] |= 64;
+
+ ge_p3 A;
+ ge_scalarmult_base(&A, az);
+ ge_p3_tobytes(out_public_key, &A);
+
+ memcpy(out_private_key, seed, 32);
+ memmove(out_private_key + 32, out_public_key, 32);
+}
+
+int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
+ const uint8_t private_key[64]) {
+ uint8_t az[SHA512_DIGEST_LENGTH];
+ SHA512(private_key, 32, az);
+
+ az[0] &= 248;
+ az[31] &= 63;
+ az[31] |= 64;
+
+ SHA512_CTX hash_ctx;
+ SHA512_Init(&hash_ctx);
+ SHA512_Update(&hash_ctx, az + 32, 32);
+ SHA512_Update(&hash_ctx, message, message_len);
+ uint8_t nonce[SHA512_DIGEST_LENGTH];
+ SHA512_Final(nonce, &hash_ctx);
+
+ sc_reduce(nonce);
+ ge_p3 R;
+ 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, private_key + 32, 32);
+ SHA512_Update(&hash_ctx, message, message_len);
+ uint8_t hram[SHA512_DIGEST_LENGTH];
+ SHA512_Final(hram, &hash_ctx);
+
+ sc_reduce(hram);
+ sc_muladd(out_sig + 32, hram, az, nonce);
+
+ return 1;
+}
+
+int ED25519_verify(const uint8_t *message, size_t message_len,
+ const uint8_t signature[64], const uint8_t public_key[32]) {
+ ge_p3 A;
+ if ((signature[63] & 224) != 0 ||
+ ge_frombytes_negate_vartime(&A, public_key) != 0) {
+ return 0;
+ }
+
+ uint8_t pkcopy[32];
+ memcpy(pkcopy, public_key, 32);
+ uint8_t rcopy[32];
+ memcpy(rcopy, signature, 32);
+ uint8_t scopy[32];
+ memcpy(scopy, signature + 32, 32);
+
+ SHA512_CTX hash_ctx;
+ SHA512_Init(&hash_ctx);
+ SHA512_Update(&hash_ctx, signature, 32);
+ SHA512_Update(&hash_ctx, public_key, 32);
+ SHA512_Update(&hash_ctx, message, message_len);
+ uint8_t h[SHA512_DIGEST_LENGTH];
+ SHA512_Final(h, &hash_ctx);
+
+ sc_reduce(h);
+
+ ge_p2 R;
+ ge_double_scalarmult_vartime(&R, h, &A, scopy);
+
+ uint8_t rcheck[32];
+ ge_tobytes(rcheck, &R);
+
+ return CRYPTO_memcmp(rcheck, rcopy, sizeof(rcheck)) == 0;
+}
+
+
+#if defined(BORINGSSL_X25519_X86_64)
+
+static void x25519_scalar_mult(uint8_t out[32], const uint8_t scalar[32],
+ const uint8_t point[32]) {
+ x25519_x86_64(out, scalar, point);
+}
+
+#else
+
+/* Replace (f,g) with (g,f) if b == 1;
+ * replace (f,g) with (f,g) if b == 0.
+ *
+ * Preconditions: b in {0,1}. */
+static void fe_cswap(fe f, fe g, unsigned int b) {
+ b = 0-b;
+ unsigned i;
+ for (i = 0; i < 10; i++) {
+ int32_t x = f[i] ^ g[i];
+ x &= b;
+ f[i] ^= x;
+ g[i] ^= x;
+ }
+}
+
+/* h = f * 121666
+ * Can overlap h with f.
+ *
+ * Preconditions:
+ * |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+ *
+ * Postconditions:
+ * |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. */
+static void fe_mul121666(fe h, fe f) {
+ int32_t f0 = f[0];
+ int32_t f1 = f[1];
+ int32_t f2 = f[2];
+ int32_t f3 = f[3];
+ int32_t f4 = f[4];
+ int32_t f5 = f[5];
+ int32_t f6 = f[6];
+ int32_t f7 = f[7];
+ int32_t f8 = f[8];
+ int32_t f9 = f[9];
+ int64_t h0 = f0 * (int64_t) 121666;
+ int64_t h1 = f1 * (int64_t) 121666;
+ int64_t h2 = f2 * (int64_t) 121666;
+ int64_t h3 = f3 * (int64_t) 121666;
+ int64_t h4 = f4 * (int64_t) 121666;
+ int64_t h5 = f5 * (int64_t) 121666;
+ int64_t h6 = f6 * (int64_t) 121666;
+ int64_t h7 = f7 * (int64_t) 121666;
+ int64_t h8 = f8 * (int64_t) 121666;
+ int64_t h9 = f9 * (int64_t) 121666;
+ int64_t carry0;
+ int64_t carry1;
+ int64_t carry2;
+ int64_t carry3;
+ int64_t carry4;
+ int64_t carry5;
+ int64_t carry6;
+ int64_t carry7;
+ int64_t carry8;
+ int64_t carry9;
+
+ carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
+ carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
+ carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
+ carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
+ carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
+
+ carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
+ carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
+ carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
+ carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
+ carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
+
+ h[0] = h0;
+ h[1] = h1;
+ h[2] = h2;
+ h[3] = h3;
+ h[4] = h4;
+ h[5] = h5;
+ h[6] = h6;
+ h[7] = h7;
+ h[8] = h8;
+ h[9] = h9;
+}
+
+static void x25519_scalar_mult_generic(uint8_t out[32],
+ const uint8_t scalar[32],
+ const uint8_t point[32]) {
+ fe x1, x2, z2, x3, z3, tmp0, tmp1;
+
+ uint8_t e[32];
+ memcpy(e, scalar, 32);
+ e[0] &= 248;
+ e[31] &= 127;
+ e[31] |= 64;
+ fe_frombytes(x1, point);
+ fe_1(x2);
+ fe_0(z2);
+ fe_copy(x3, x1);
+ fe_1(z3);
+
+ unsigned swap = 0;
+ int pos;
+ for (pos = 254; pos >= 0; --pos) {
+ unsigned b = 1 & (e[pos / 8] >> (pos & 7));
+ swap ^= b;
+ fe_cswap(x2, x3, swap);
+ fe_cswap(z2, z3, swap);
+ swap = b;
+ fe_sub(tmp0, x3, z3);
+ fe_sub(tmp1, x2, z2);
+ fe_add(x2, x2, z2);
+ fe_add(z2, x3, z3);
+ fe_mul(z3, tmp0, x2);
+ fe_mul(z2, z2, tmp1);
+ fe_sq(tmp0, tmp1);
+ fe_sq(tmp1, x2);
+ fe_add(x3, z3, z2);
+ fe_sub(z2, z3, z2);
+ fe_mul(x2, tmp1, tmp0);
+ fe_sub(tmp1, tmp1, tmp0);
+ fe_sq(z2, z2);
+ fe_mul121666(z3, tmp1);
+ fe_sq(x3, x3);
+ fe_add(tmp0, tmp0, z3);
+ fe_mul(z3, x1, z2);
+ fe_mul(z2, tmp1, tmp0);
+ }
+ fe_cswap(x2, x3, swap);
+ fe_cswap(z2, z3, swap);
+
+ fe_invert(z2, z2);
+ fe_mul(x2, x2, z2);
+ fe_tobytes(out, x2);
+}
+
+static void x25519_scalar_mult(uint8_t out[32], const uint8_t scalar[32],
+ const uint8_t point[32]) {
+#if defined(BORINGSSL_X25519_NEON)
+ if (CRYPTO_is_NEON_capable()) {
+ x25519_NEON(out, scalar, point);
+ return;
+ }
+#endif
+
+ x25519_scalar_mult_generic(out, scalar, point);
+}
+
+#endif /* BORINGSSL_X25519_X86_64 */
+
+
+void X25519_keypair(uint8_t out_public_value[32], uint8_t out_private_key[32]) {
+ RAND_bytes(out_private_key, 32);
+ X25519_public_from_private(out_public_value, out_private_key);
+}
+
+int 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);
+ /* The all-zero output results when the input is a point of small order. */
+ return CRYPTO_memcmp(kZeros, out_shared_key, 32) != 0;
+}
+
+#if defined(BORINGSSL_X25519_X86_64)
+
+/* When |BORINGSSL_X25519_X86_64| is set, base point multiplication is done with
+ * the Montgomery ladder because it's faster. Otherwise it's done using the
+ * Ed25519 tables. */
+
+void X25519_public_from_private(uint8_t out_public_value[32],
+ const uint8_t private_key[32]) {
+ static const uint8_t kMongomeryBasePoint[32] = {9};
+ x25519_scalar_mult(out_public_value, private_key, kMongomeryBasePoint);
+}
+
+#else
+
+void X25519_public_from_private(uint8_t out_public_value[32],
+ const uint8_t private_key[32]) {
+#if defined(BORINGSSL_X25519_NEON)
+ if (CRYPTO_is_NEON_capable()) {
+ static const uint8_t kMongomeryBasePoint[32] = {9};
+ x25519_NEON(out_public_value, private_key, kMongomeryBasePoint);
+ return;
+ }
+#endif
+
+ uint8_t e[32];
+ memcpy(e, private_key, 32);
+ e[0] &= 248;
+ e[31] &= 127;
+ e[31] |= 64;
+
+ ge_p3 A;
+ ge_scalarmult_base(&A, e);
+
+ /* We only need the u-coordinate of the curve25519 point. The map is
+ * u=(y+1)/(1-y). Since y=Y/Z, this gives u=(Z+Y)/(Z-Y). */
+ fe zplusy, zminusy, zminusy_inv;
+ fe_add(zplusy, A.Z, A.Y);
+ fe_sub(zminusy, A.Z, A.Y);
+ fe_invert(zminusy_inv, zminusy);
+ fe_mul(zplusy, zplusy, zminusy_inv);
+ fe_tobytes(out_public_value, zplusy);
+}
+
+#endif /* BORINGSSL_X25519_X86_64 */
diff --git a/src/crypto/curve25519/ed25519_test.cc b/src/crypto/curve25519/ed25519_test.cc
new file mode 100644
index 0000000..1b6a0b6
--- /dev/null
+++ b/src/crypto/curve25519/ed25519_test.cc
@@ -0,0 +1,63 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <stdint.h>
+#include <string.h>
+
+#include <openssl/curve25519.h>
+
+#include "../test/file_test.h"
+
+
+static bool TestSignature(FileTest *t, void *arg) {
+ std::vector<uint8_t> private_key, public_key, message, expected_signature;
+ if (!t->GetBytes(&private_key, "PRIV") ||
+ private_key.size() != 64 ||
+ !t->GetBytes(&public_key, "PUB") ||
+ public_key.size() != 32 ||
+ !t->GetBytes(&message, "MESSAGE") ||
+ !t->GetBytes(&expected_signature, "SIG") ||
+ expected_signature.size() != 64) {
+ return false;
+ }
+
+ uint8_t signature[64];
+ if (!ED25519_sign(signature, message.data(), message.size(),
+ private_key.data())) {
+ t->PrintLine("ED25519_sign failed");
+ return false;
+ }
+
+ if (!t->ExpectBytesEqual(expected_signature.data(), expected_signature.size(),
+ signature, sizeof(signature))) {
+ return false;
+ }
+
+ if (!ED25519_verify(message.data(), message.size(), signature,
+ public_key.data())) {
+ t->PrintLine("ED25519_verify failed");
+ return false;
+ }
+
+ return true;
+}
+
+int main(int argc, char **argv) {
+ if (argc != 2) {
+ fprintf(stderr, "%s <test input.txt>\n", argv[0]);
+ return 1;
+ }
+
+ return FileTestMain(TestSignature, nullptr, argv[1]);
+}
diff --git a/src/crypto/curve25519/ed25519_tests.txt b/src/crypto/curve25519/ed25519_tests.txt
new file mode 100644
index 0000000..4d43417
--- /dev/null
+++ b/src/crypto/curve25519/ed25519_tests.txt
@@ -0,0 +1,2577 @@
+# The contents of this file were generated from
+# http://ed25519.cr.yp.to/python/sign.input using the following Python script:
+#
+# import sys
+#
+# isFirst = True
+#
+# for line in sys.stdin.readlines():
+# (private, public, message, sig_and_message, _) = line.split(':')
+#
+# if not isFirst:
+# print
+# print "PRIV:", private
+# print "PUB:", public
+# print "MESSAGE:", message
+# print "SIG:", sig_and_message[:128]
+# isFirst = False
+
+PRIV: 9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a
+PUB: d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a
+MESSAGE:
+SIG: e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b
+
+PRIV: 4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c
+PUB: 3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c
+MESSAGE: 72
+SIG: 92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00
+
+PRIV: c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025
+PUB: fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025
+MESSAGE: af82
+SIG: 6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a
+
+PRIV: 0d4a05b07352a5436e180356da0ae6efa0345ff7fb1572575772e8005ed978e9e61a185bcef2613a6c7cb79763ce945d3b245d76114dd440bcf5f2dc1aa57057
+PUB: e61a185bcef2613a6c7cb79763ce945d3b245d76114dd440bcf5f2dc1aa57057
+MESSAGE: cbc77b
+SIG: d9868d52c2bebce5f3fa5a79891970f309cb6591e3e1702a70276fa97c24b3a8e58606c38c9758529da50ee31b8219cba45271c689afa60b0ea26c99db19b00c
+
+PRIV: 6df9340c138cc188b5fe4464ebaa3f7fc206a2d55c3434707e74c9fc04e20ebbc0dac102c4533186e25dc43128472353eaabdb878b152aeb8e001f92d90233a7
+PUB: c0dac102c4533186e25dc43128472353eaabdb878b152aeb8e001f92d90233a7
+MESSAGE: 5f4c8989
+SIG: 124f6fc6b0d100842769e71bd530664d888df8507df6c56dedfdb509aeb93416e26b918d38aa06305df3095697c18b2aa832eaa52edc0ae49fbae5a85e150c07
+
+PRIV: b780381a65edf8b78f6945e8dbec7941ac049fd4c61040cf0c324357975a293ce253af0766804b869bb1595be9765b534886bbaab8305bf50dbc7f899bfb5f01
+PUB: e253af0766804b869bb1595be9765b534886bbaab8305bf50dbc7f899bfb5f01
+MESSAGE: 18b6bec097
+SIG: b2fc46ad47af464478c199e1f8be169f1be6327c7f9a0a6689371ca94caf04064a01b22aff1520abd58951341603faed768cf78ce97ae7b038abfe456aa17c09
+
+PRIV: 78ae9effe6f245e924a7be63041146ebc670dbd3060cba67fbc6216febc44546fbcfbfa40505d7f2be444a33d185cc54e16d615260e1640b2b5087b83ee3643d
+PUB: fbcfbfa40505d7f2be444a33d185cc54e16d615260e1640b2b5087b83ee3643d
+MESSAGE: 89010d855972
+SIG: 6ed629fc1d9ce9e1468755ff636d5a3f40a5d9c91afd93b79d241830f7e5fa29854b8f20cc6eecbb248dbd8d16d14e99752194e4904d09c74d639518839d2300
+
+PRIV: 691865bfc82a1e4b574eecde4c7519093faf0cf867380234e3664645c61c5f7998a5e3a36e67aaba89888bf093de1ad963e774013b3902bfab356d8b90178a63
+PUB: 98a5e3a36e67aaba89888bf093de1ad963e774013b3902bfab356d8b90178a63
+MESSAGE: b4a8f381e70e7a
+SIG: 6e0af2fe55ae377a6b7a7278edfb419bd321e06d0df5e27037db8812e7e3529810fa5552f6c0020985ca17a0e02e036d7b222a24f99b77b75fdd16cb05568107
+
+PRIV: 3b26516fb3dc88eb181b9ed73f0bcd52bcd6b4c788e4bcaf46057fd078bee073f81fb54a825fced95eb033afcd64314075abfb0abd20a970892503436f34b863
+PUB: f81fb54a825fced95eb033afcd64314075abfb0abd20a970892503436f34b863
+MESSAGE: 4284abc51bb67235
+SIG: d6addec5afb0528ac17bb178d3e7f2887f9adbb1ad16e110545ef3bc57f9de2314a5c8388f723b8907be0f3ac90c6259bbe885ecc17645df3db7d488f805fa08
+
+PRIV: edc6f5fbdd1cee4d101c063530a30490b221be68c036f5b07d0f953b745df192c1a49c66e617f9ef5ec66bc4c6564ca33de2a5fb5e1464062e6d6c6219155efd
+PUB: c1a49c66e617f9ef5ec66bc4c6564ca33de2a5fb5e1464062e6d6c6219155efd
+MESSAGE: 672bf8965d04bc5146
+SIG: 2c76a04af2391c147082e33faacdbe56642a1e134bd388620b852b901a6bc16ff6c9cc9404c41dea12ed281da067a1513866f9d964f8bdd24953856c50042901
+
+PRIV: 4e7d21fb3b1897571a445833be0f9fd41cd62be3aa04040f8934e1fcbdcacd4531b2524b8348f7ab1dfafa675cc538e9a84e3fe5819e27c12ad8bbc1a36e4dff
+PUB: 31b2524b8348f7ab1dfafa675cc538e9a84e3fe5819e27c12ad8bbc1a36e4dff
+MESSAGE: 33d7a786aded8c1bf691
+SIG: 28e4598c415ae9de01f03f9f3fab4e919e8bf537dd2b0cdf6e79b9e6559c9409d9151a4c40f083193937627c369488259e99da5a9f0a87497fa6696a5dd6ce08
+
+PRIV: a980f892db13c99a3e8971e965b2ff3d41eafd54093bc9f34d1fd22d84115bb644b57ee30cdb55829d0a5d4f046baef078f1e97a7f21b62d75f8e96ea139c35f
+PUB: 44b57ee30cdb55829d0a5d4f046baef078f1e97a7f21b62d75f8e96ea139c35f
+MESSAGE: 3486f68848a65a0eb5507d
+SIG: 77d389e599630d934076329583cd4105a649a9292abc44cd28c40000c8e2f5ac7660a81c85b72af8452d7d25c070861dae91601c7803d656531650dd4e5c4100
+
+PRIV: 5b5a619f8ce1c66d7ce26e5a2ae7b0c04febcd346d286c929e19d0d5973bfef96fe83693d011d111131c4f3fbaaa40a9d3d76b30012ff73bb0e39ec27ab18257
+PUB: 6fe83693d011d111131c4f3fbaaa40a9d3d76b30012ff73bb0e39ec27ab18257
+MESSAGE: 5a8d9d0a22357e6655f9c785
+SIG: 0f9ad9793033a2fa06614b277d37381e6d94f65ac2a5a94558d09ed6ce922258c1a567952e863ac94297aec3c0d0c8ddf71084e504860bb6ba27449b55adc40e
+
+PRIV: 940c89fe40a81dafbdb2416d14ae469119869744410c3303bfaa0241dac57800a2eb8c0501e30bae0cf842d2bde8dec7386f6b7fc3981b8c57c9792bb94cf2dd
+PUB: a2eb8c0501e30bae0cf842d2bde8dec7386f6b7fc3981b8c57c9792bb94cf2dd
+MESSAGE: b87d3813e03f58cf19fd0b6395
+SIG: d8bb64aad8c9955a115a793addd24f7f2b077648714f49c4694ec995b330d09d640df310f447fd7b6cb5c14f9fe9f490bcf8cfadbfd2169c8ac20d3b8af49a0c
+
+PRIV: 9acad959d216212d789a119252ebfe0c96512a23c73bd9f3b202292d6916a738cf3af898467a5b7a52d33d53bc037e2642a8da996903fc252217e9c033e2f291
+PUB: cf3af898467a5b7a52d33d53bc037e2642a8da996903fc252217e9c033e2f291
+MESSAGE: 55c7fa434f5ed8cdec2b7aeac173
+SIG: 6ee3fe81e23c60eb2312b2006b3b25e6838e02106623f844c44edb8dafd66ab0671087fd195df5b8f58a1d6e52af42908053d55c7321010092748795ef94cf06
+
+PRIV: d5aeee41eeb0e9d1bf8337f939587ebe296161e6bf5209f591ec939e1440c300fd2a565723163e29f53c9de3d5e8fbe36a7ab66e1439ec4eae9c0a604af291a5
+PUB: fd2a565723163e29f53c9de3d5e8fbe36a7ab66e1439ec4eae9c0a604af291a5
+MESSAGE: 0a688e79be24f866286d4646b5d81c
+SIG: f68d04847e5b249737899c014d31c805c5007a62c0a10d50bb1538c5f35503951fbc1e08682f2cc0c92efe8f4985dec61dcbd54d4b94a22547d24451271c8b00
+
+PRIV: 0a47d10452ae2febec518a1c7c362890c3fc1a49d34b03b6467d35c904a8362d34e5a8508c4743746962c066e4badea2201b8ab484de5c4f94476ccd2143955b
+PUB: 34e5a8508c4743746962c066e4badea2201b8ab484de5c4f94476ccd2143955b
+MESSAGE: c942fa7ac6b23ab7ff612fdc8e68ef39
+SIG: 2a3d27dc40d0a8127949a3b7f908b3688f63b7f14f651aacd715940bdbe27a0809aac142f47ab0e1e44fa490ba87ce5392f33a891539caf1ef4c367cae54500c
+
+PRIV: f8148f7506b775ef46fdc8e8c756516812d47d6cfbfa318c27c9a22641e56f170445e456dacc7d5b0bbed23c8200cdb74bdcb03e4c7b73f0a2b9b46eac5d4372
+PUB: 0445e456dacc7d5b0bbed23c8200cdb74bdcb03e4c7b73f0a2b9b46eac5d4372
+MESSAGE: 7368724a5b0efb57d28d97622dbde725af
+SIG: 3653ccb21219202b8436fb41a32ba2618c4a133431e6e63463ceb3b6106c4d56e1d2ba165ba76eaad3dc39bffb130f1de3d8e6427db5b71938db4e272bc3e20b
+
+PRIV: 77f88691c4eff23ebb7364947092951a5ff3f10785b417e918823a552dab7c7574d29127f199d86a8676aec33b4ce3f225ccb191f52c191ccd1e8cca65213a6b
+PUB: 74d29127f199d86a8676aec33b4ce3f225ccb191f52c191ccd1e8cca65213a6b
+MESSAGE: bd8e05033f3a8bcdcbf4beceb70901c82e31
+SIG: fbe929d743a03c17910575492f3092ee2a2bf14a60a3fcacec74a58c7334510fc262db582791322d6c8c41f1700adb80027ecabc14270b703444ae3ee7623e0a
+
+PRIV: ab6f7aee6a0837b334ba5eb1b2ad7fcecfab7e323cab187fe2e0a95d80eff1325b96dca497875bf9664c5e75facf3f9bc54bae913d66ca15ee85f1491ca24d2c
+PUB: 5b96dca497875bf9664c5e75facf3f9bc54bae913d66ca15ee85f1491ca24d2c
+MESSAGE: 8171456f8b907189b1d779e26bc5afbb08c67a
+SIG: 73bca64e9dd0db88138eedfafcea8f5436cfb74bfb0e7733cf349baa0c49775c56d5934e1d38e36f39b7c5beb0a836510c45126f8ec4b6810519905b0ca07c09
+
+PRIV: 8d135de7c8411bbdbd1b31e5dc678f2ac7109e792b60f38cd24936e8a898c32d1ca281938529896535a7714e3584085b86ef9fec723f42819fc8dd5d8c00817f
+PUB: 1ca281938529896535a7714e3584085b86ef9fec723f42819fc8dd5d8c00817f
+MESSAGE: 8ba6a4c9a15a244a9c26bb2a59b1026f21348b49
+SIG: a1adc2bc6a2d980662677e7fdff6424de7dba50f5795ca90fdf3e96e256f3285cac71d3360482e993d0294ba4ec7440c61affdf35fe83e6e04263937db93f105
+
+PRIV: 0e765d720e705f9366c1ab8c3fa84c9a44370c06969f803296884b2846a652a47fae45dd0a05971026d410bc497af5be7d0827a82a145c203f625dfcb8b03ba8
+PUB: 7fae45dd0a05971026d410bc497af5be7d0827a82a145c203f625dfcb8b03ba8
+MESSAGE: 1d566a6232bbaab3e6d8804bb518a498ed0f904986
+SIG: bb61cf84de61862207c6a455258bc4db4e15eea0317ff88718b882a06b5cf6ec6fd20c5a269e5d5c805bafbcc579e2590af414c7c227273c102a10070cdfe80f
+
+PRIV: db36e326d676c2d19cc8fe0c14b709202ecfc761d27089eb6ea4b1bb021ecfa748359b850d23f0715d94bb8bb75e7e14322eaf14f06f28a805403fbda002fc85
+PUB: 48359b850d23f0715d94bb8bb75e7e14322eaf14f06f28a805403fbda002fc85
+MESSAGE: 1b0afb0ac4ba9ab7b7172cddc9eb42bba1a64bce47d4
+SIG: b6dcd09989dfbac54322a3ce87876e1d62134da998c79d24b50bd7a6a797d86a0e14dc9d7491d6c14a673c652cfbec9f962a38c945da3b2f0879d0b68a921300
+
+PRIV: c89955e0f7741d905df0730b3dc2b0ce1a13134e44fef3d40d60c020ef19df77fdb30673402faf1c8033714f3517e47cc0f91fe70cf3836d6c23636e3fd2287c
+PUB: fdb30673402faf1c8033714f3517e47cc0f91fe70cf3836d6c23636e3fd2287c
+MESSAGE: 507c94c8820d2a5793cbf3442b3d71936f35fe3afef316
+SIG: 7ef66e5e86f2360848e0014e94880ae2920ad8a3185a46b35d1e07dea8fa8ae4f6b843ba174d99fa7986654a0891c12a794455669375bf92af4cc2770b579e0c
+
+PRIV: 4e62627fc221142478aee7f00781f817f662e3b75db29bb14ab47cf8e84104d6b1d39801892027d58a8c64335163195893bfc1b61dbeca3260497e1f30371107
+PUB: b1d39801892027d58a8c64335163195893bfc1b61dbeca3260497e1f30371107
+MESSAGE: d3d615a8472d9962bb70c5b5466a3d983a4811046e2a0ef5
+SIG: 836afa764d9c48aa4770a4388b654e97b3c16f082967febca27f2fc47ddfd9244b03cfc729698acf5109704346b60b230f255430089ddc56912399d1122de70a
+
+PRIV: 6b83d7da8908c3e7205b39864b56e5f3e17196a3fc9c2f5805aad0f5554c142dd0c846f97fe28585c0ee159015d64c56311c886eddcc185d296dbb165d2625d6
+PUB: d0c846f97fe28585c0ee159015d64c56311c886eddcc185d296dbb165d2625d6
+MESSAGE: 6ada80b6fa84f7034920789e8536b82d5e4678059aed27f71c
+SIG: 16e462a29a6dd498685a3718b3eed00cc1598601ee47820486032d6b9acc9bf89f57684e08d8c0f05589cda2882a05dc4c63f9d0431d6552710812433003bc08
+
+PRIV: 19a91fe23a4e9e33ecc474878f57c64cf154b394203487a7035e1ad9cd697b0d2bf32ba142ba4622d8f3e29ecd85eea07b9c47be9d64412c9b510b27dd218b23
+PUB: 2bf32ba142ba4622d8f3e29ecd85eea07b9c47be9d64412c9b510b27dd218b23
+MESSAGE: 82cb53c4d5a013bae5070759ec06c3c6955ab7a4050958ec328c
+SIG: 881f5b8c5a030df0f75b6634b070dd27bd1ee3c08738ae349338b3ee6469bbf9760b13578a237d5182535ede121283027a90b5f865d63a6537dca07b44049a0f
+
+PRIV: 1d5b8cb6215c18141666baeefcf5d69dad5bea9a3493dddaa357a4397a13d4de94d23d977c33e49e5e4992c68f25ec99a27c41ce6b91f2bfa0cd8292fe962835
+PUB: 94d23d977c33e49e5e4992c68f25ec99a27c41ce6b91f2bfa0cd8292fe962835
+MESSAGE: a9a8cbb0ad585124e522abbfb40533bdd6f49347b55b18e8558cb0
+SIG: 3acd39bec8c3cd2b44299722b5850a0400c1443590fd4861d59aae7496acb3df73fc3fdf7969ae5f50ba47dddc435246e5fd376f6b891cd4c2caf5d614b6170c
+
+PRIV: 6a91b3227c472299089bdce9356e726a40efd840f11002708b7ee55b64105ac29d084aa8b97a6b9bafa496dbc6f76f3306a116c9d917e681520a0f914369427e
+PUB: 9d084aa8b97a6b9bafa496dbc6f76f3306a116c9d917e681520a0f914369427e
+MESSAGE: 5cb6f9aa59b80eca14f6a68fb40cf07b794e75171fba96262c1c6adc
+SIG: f5875423781b66216cb5e8998de5d9ffc29d1d67107054ace3374503a9c3ef811577f269de81296744bd706f1ac478caf09b54cdf871b3f802bd57f9a6cb9101
+
+PRIV: 93eaa854d791f05372ce72b94fc6503b2ff8ae6819e6a21afe825e27ada9e4fb16cee8a3f2631834c88b670897ff0b08ce90cc147b4593b3f1f403727f7e7ad5
+PUB: 16cee8a3f2631834c88b670897ff0b08ce90cc147b4593b3f1f403727f7e7ad5
+MESSAGE: 32fe27994124202153b5c70d3813fdee9c2aa6e7dc743d4d535f1840a5
+SIG: d834197c1a3080614e0a5fa0aaaa808824f21c38d692e6ffbd200f7dfb3c8f44402a7382180b98ad0afc8eec1a02acecf3cb7fde627b9f18111f260ab1db9a07
+
+PRIV: 941cac69fb7b1815c57bb987c4d6c2ad2c35d5f9a3182a79d4ba13eab253a8ad23be323c562dfd71ce65f5bba56a74a3a6dfc36b573d2f94f635c7f9b4fd5a5b
+PUB: 23be323c562dfd71ce65f5bba56a74a3a6dfc36b573d2f94f635c7f9b4fd5a5b
+MESSAGE: bb3172795710fe00054d3b5dfef8a11623582da68bf8e46d72d27cece2aa
+SIG: 0f8fad1e6bde771b4f5420eac75c378bae6db5ac6650cd2bc210c1823b432b48e016b10595458ffab92f7a8989b293ceb8dfed6c243a2038fc06652aaaf16f02
+
+PRIV: 1acdbb793b0384934627470d795c3d1dd4d79cea59ef983f295b9b59179cbb283f60c7541afa76c019cf5aa82dcdb088ed9e4ed9780514aefb379dabc844f31a
+PUB: 3f60c7541afa76c019cf5aa82dcdb088ed9e4ed9780514aefb379dabc844f31a
+MESSAGE: 7cf34f75c3dac9a804d0fcd09eba9b29c9484e8a018fa9e073042df88e3c56
+SIG: be71ef4806cb041d885effd9e6b0fbb73d65d7cdec47a89c8a994892f4e55a568c4cc78d61f901e80dbb628b86a23ccd594e712b57fa94c2d67ec26634878507
+
+PRIV: 8ed7a797b9cea8a8370d419136bcdf683b759d2e3c6947f17e13e2485aa9d420b49f3a78b1c6a7fca8f3466f33bc0e929f01fba04306c2a7465f46c3759316d9
+PUB: b49f3a78b1c6a7fca8f3466f33bc0e929f01fba04306c2a7465f46c3759316d9
+MESSAGE: a750c232933dc14b1184d86d8b4ce72e16d69744ba69818b6ac33b1d823bb2c3
+SIG: 04266c033b91c1322ceb3446c901ffcf3cc40c4034e887c9597ca1893ba7330becbbd8b48142ef35c012c6ba51a66df9308cb6268ad6b1e4b03e70102495790b
+
+PRIV: f2ab396fe8906e3e5633e99cabcd5b09df0859b516230b1e0450b580b65f616c8ea074245159a116aa7122a25ec16b891d625a68f33660423908f6bdc44f8c1b
+PUB: 8ea074245159a116aa7122a25ec16b891d625a68f33660423908f6bdc44f8c1b
+MESSAGE: 5a44e34b746c5fd1898d552ab354d28fb4713856d7697dd63eb9bd6b99c280e187
+SIG: a06a23d982d81ab883aae230adbc368a6a9977f003cebb00d4c2e4018490191a84d3a282fdbfb2fc88046e62de43e15fb575336b3c8b77d19ce6a009ce51f50c
+
+PRIV: 550a41c013f79bab8f06e43ad1836d51312736a9713806fafe6645219eaa1f9daf6b7145474dc9954b9af93a9cdb34449d5b7c651c824d24e230b90033ce59c0
+PUB: af6b7145474dc9954b9af93a9cdb34449d5b7c651c824d24e230b90033ce59c0
+MESSAGE: 8bc4185e50e57d5f87f47515fe2b1837d585f0aae9e1ca383b3ec908884bb900ff27
+SIG: 16dc1e2b9fa909eefdc277ba16ebe207b8da5e91143cde78c5047a89f681c33c4e4e3428d5c928095903a811ec002d52a39ed7f8b3fe1927200c6dd0b9ab3e04
+
+PRIV: 19ac3e272438c72ddf7b881964867cb3b31ff4c793bb7ea154613c1db068cb7ef85b80e050a1b9620db138bfc9e100327e25c257c59217b601f1f6ac9a413d3f
+PUB: f85b80e050a1b9620db138bfc9e100327e25c257c59217b601f1f6ac9a413d3f
+MESSAGE: 95872d5f789f95484e30cbb0e114028953b16f5c6a8d9f65c003a83543beaa46b38645
+SIG: ea855d781cbea4682e350173cb89e8619ccfddb97cdce16f9a2f6f6892f46dbe68e04b12b8d88689a7a31670cdff409af98a93b49a34537b6aa009d2eb8b4701
+
+PRIV: ca267de96c93c238fafb1279812059ab93ac03059657fd994f8fa5a09239c821017370c879090a81c7f272c2fc80e3aac2bc603fcb379afc98691160ab745b26
+PUB: 017370c879090a81c7f272c2fc80e3aac2bc603fcb379afc98691160ab745b26
+MESSAGE: e05f71e4e49a72ec550c44a3b85aca8f20ff26c3ee94a80f1b431c7d154ec9603ee02531
+SIG: ac957f82335aa7141e96b59d63e3ccee95c3a2c47d026540c2af42dc9533d5fd81827d1679ad187aeaf37834915e75b147a9286806c8017516ba43dd051a5e0c
+
+PRIV: 3dff5e899475e7e91dd261322fab09980c52970de1da6e2e201660cc4fce7032f30162bac98447c4042fac05da448034629be2c6a58d30dfd578ba9fb5e3930b
+PUB: f30162bac98447c4042fac05da448034629be2c6a58d30dfd578ba9fb5e3930b
+MESSAGE: 938f0e77621bf3ea52c7c4911c5157c2d8a2a858093ef16aa9b107e69d98037ba139a3c382
+SIG: 5efe7a92ff9623089b3e3b78f352115366e26ba3fb1a416209bc029e9cadccd9f4affa333555a8f3a35a9d0f7c34b292cae77ec96fa3adfcaadee2d9ced8f805
+
+PRIV: 9a6b847864e70cfe8ba6ab22fa0ca308c0cc8bec7141fbcaa3b81f5d1e1cfcfc34ad0fbdb2566507a81c2b1f8aa8f53dccaa64cc87ada91b903e900d07eee930
+PUB: 34ad0fbdb2566507a81c2b1f8aa8f53dccaa64cc87ada91b903e900d07eee930
+MESSAGE: 838367471183c71f7e717724f89d401c3ad9863fd9cc7aa3cf33d3c529860cb581f3093d87da
+SIG: 2ab255169c489c54c732232e37c87349d486b1eba20509dbabe7fed329ef08fd75ba1cd145e67b2ea26cb5cc51cab343eeb085fe1fd7b0ec4c6afcd9b979f905
+
+PRIV: 575be07afca5d063c238cd9b8028772cc49cda34471432a2e166e096e2219efc94e5eb4d5024f49d7ebf79817c8de11497dc2b55622a51ae123ffc749dbb16e0
+PUB: 94e5eb4d5024f49d7ebf79817c8de11497dc2b55622a51ae123ffc749dbb16e0
+MESSAGE: 33e5918b66d33d55fe717ca34383eae78f0af82889caf6696e1ac9d95d1ffb32cba755f9e3503e
+SIG: 58271d44236f3b98c58fd7ae0d2f49ef2b6e3affdb225aa3ba555f0e11cc53c23ad19baf24346590d05d7d5390582082cf94d39cad6530ab93d13efb39279506
+
+PRIV: 15ffb45514d43444d61fcb105e30e135fd268523dda20b82758b1794231104411772c5abc2d23fd2f9d1c3257be7bc3c1cd79cee40844b749b3a7743d2f964b8
+PUB: 1772c5abc2d23fd2f9d1c3257be7bc3c1cd79cee40844b749b3a7743d2f964b8
+MESSAGE: da9c5559d0ea51d255b6bd9d7638b876472f942b330fc0e2b30aea68d77368fce4948272991d257e
+SIG: 6828cd7624e793b8a4ceb96d3c2a975bf773e5ff6645f353614058621e58835289e7f31f42dfe6af6d736f2644511e320c0fa698582a79778d18730ed3e8cb08
+
+PRIV: fe0568642943b2e1afbfd1f10fe8df87a4236bea40dce742072cb21886eec1fa299ebd1f13177dbdb66a912bbf712038fdf73b06c3ac020c7b19126755d47f61
+PUB: 299ebd1f13177dbdb66a912bbf712038fdf73b06c3ac020c7b19126755d47f61
+MESSAGE: c59d0862ec1c9746abcc3cf83c9eeba2c7082a036a8cb57ce487e763492796d47e6e063a0c1feccc2d
+SIG: d59e6dfcc6d7e3e2c58dec81e985d245e681acf6594a23c59214f7bed8015d813c7682b60b3583440311e72a8665ba2c96dec23ce826e160127e18132b030404
+
+PRIV: 5ecb16c2df27c8cf58e436a9d3affbd58e9538a92659a0f97c4c4f994635a8cada768b20c437dd3aa5f84bb6a077ffa34ab68501c5352b5cc3fdce7fe6c2398d
+PUB: da768b20c437dd3aa5f84bb6a077ffa34ab68501c5352b5cc3fdce7fe6c2398d
+MESSAGE: 56f1329d9a6be25a6159c72f12688dc8314e85dd9e7e4dc05bbecb7729e023c86f8e0937353f27c7ede9
+SIG: 1c723a20c6772426a670e4d5c4a97c6ebe9147f71bb0a415631e44406e290322e4ca977d348fe7856a8edc235d0fe95f7ed91aefddf28a77e2c7dbfd8f552f0a
+
+PRIV: d599d637b3c30a82a9984e2f758497d144de6f06b9fba04dd40fd949039d7c846791d8ce50a44689fc178727c5c3a1c959fbeed74ef7d8e7bd3c1ab4da31c51f
+PUB: 6791d8ce50a44689fc178727c5c3a1c959fbeed74ef7d8e7bd3c1ab4da31c51f
+MESSAGE: a7c04e8ba75d0a03d8b166ad7a1d77e1b91c7aaf7befdd99311fc3c54a684ddd971d5b3211c3eeaff1e54e
+SIG: ebf10d9ac7c96108140e7def6fe9533d727646ff5b3af273c1df95762a66f32b65a09634d013f54b5dd6011f91bc336ca8b355ce33f8cfbec2535a4c427f8205
+
+PRIV: 30ab8232fa7018f0ce6c39bd8f782fe2e159758bb0f2f4386c7f28cfd2c85898ecfb6a2bd42f31b61250ba5de7e46b4719afdfbc660db71a7bd1df7b0a3abe37
+PUB: ecfb6a2bd42f31b61250ba5de7e46b4719afdfbc660db71a7bd1df7b0a3abe37
+MESSAGE: 63b80b7956acbecf0c35e9ab06b914b0c7014fe1a4bbc0217240c1a33095d707953ed77b15d211adaf9b97dc
+SIG: 9af885344cc7239498f712df80bc01b80638291ed4a1d28baa5545017a72e2f65649ccf9603da6eb5bfab9f5543a6ca4a7af3866153c76bf66bf95def615b00c
+
+PRIV: 0ddcdc872c7b748d40efe96c2881ae189d87f56148ed8af3ebbbc80324e38bdd588ddadcbcedf40df0e9697d8bb277c7bb1498fa1d26ce0a835a760b92ca7c85
+PUB: 588ddadcbcedf40df0e9697d8bb277c7bb1498fa1d26ce0a835a760b92ca7c85
+MESSAGE: 65641cd402add8bf3d1d67dbeb6d41debfbef67e4317c35b0a6d5bbbae0e034de7d670ba1413d056f2d6f1de12
+SIG: c179c09456e235fe24105afa6e8ec04637f8f943817cd098ba95387f9653b2add181a31447d92d1a1ddf1ceb0db62118de9dffb7dcd2424057cbdff5d41d0403
+
+PRIV: 89f0d68299ba0a5a83f248ae0c169f8e3849a9b47bd4549884305c9912b46603aba3e795aab2012acceadd7b3bd9daeeed6ff5258bdcd7c93699c2a3836e3832
+PUB: aba3e795aab2012acceadd7b3bd9daeeed6ff5258bdcd7c93699c2a3836e3832
+MESSAGE: 4f1846dd7ad50e545d4cfbffbb1dc2ff145dc123754d08af4e44ecc0bc8c91411388bc7653e2d893d1eac2107d05
+SIG: 2c691fa8d487ce20d5d2fa41559116e0bbf4397cf5240e152556183541d66cf753582401a4388d390339dbef4d384743caa346f55f8daba68ba7b9131a8a6e0b
+
+PRIV: 0a3c1844e2db070fb24e3c95cb1cc6714ef84e2ccd2b9dd2f1460ebf7ecf13b172e409937e0610eb5c20b326dc6ea1bbbc0406701c5cd67d1fbde09192b07c01
+PUB: 72e409937e0610eb5c20b326dc6ea1bbbc0406701c5cd67d1fbde09192b07c01
+MESSAGE: 4c8274d0ed1f74e2c86c08d955bde55b2d54327e82062a1f71f70d536fdc8722cdead7d22aaead2bfaa1ad00b82957
+SIG: 87f7fdf46095201e877a588fe3e5aaf476bd63138d8a878b89d6ac60631b3458b9d41a3c61a588e1db8d29a5968981b018776c588780922f5aa732ba6379dd05
+
+PRIV: c8d7a8818b98dfdb20839c871cb5c48e9e9470ca3ad35ba2613a5d3199c8ab2390d2efbba4d43e6b2b992ca16083dbcfa2b322383907b0ee75f3e95845d3c47f
+PUB: 90d2efbba4d43e6b2b992ca16083dbcfa2b322383907b0ee75f3e95845d3c47f
+MESSAGE: 783e33c3acbdbb36e819f544a7781d83fc283d3309f5d3d12c8dcd6b0b3d0e89e38cfd3b4d0885661ca547fb9764abff
+SIG: fa2e994421aef1d5856674813d05cbd2cf84ef5eb424af6ecd0dc6fdbdc2fe605fe985883312ecf34f59bfb2f1c9149e5b9cc9ecda05b2731130f3ed28ddae0b
+
+PRIV: b482703612d0c586f76cfcb21cfd2103c957251504a8c0ac4c86c9c6f3e429fffd711dc7dd3b1dfb9df9704be3e6b26f587fe7dd7ba456a91ba43fe51aec09ad
+PUB: fd711dc7dd3b1dfb9df9704be3e6b26f587fe7dd7ba456a91ba43fe51aec09ad
+MESSAGE: 29d77acfd99c7a0070a88feb6247a2bce9984fe3e6fbf19d4045042a21ab26cbd771e184a9a75f316b648c6920db92b87b
+SIG: 58832bdeb26feafc31b46277cf3fb5d7a17dfb7ccd9b1f58ecbe6feb979666828f239ba4d75219260ecac0acf40f0e5e2590f4caa16bbbcd8a155d347967a607
+
+PRIV: 84e50dd9a0f197e3893c38dbd91fafc344c1776d3a400e2f0f0ee7aa829eb8a22c50f870ee48b36b0ac2f8a5f336fb090b113050dbcc25e078200a6e16153eea
+PUB: 2c50f870ee48b36b0ac2f8a5f336fb090b113050dbcc25e078200a6e16153eea
+MESSAGE: f3992cde6493e671f1e129ddca8038b0abdb77bb9035f9f8be54bd5d68c1aeff724ff47d29344391dc536166b8671cbbf123
+SIG: 69e6a4491a63837316e86a5f4ba7cd0d731ecc58f1d0a264c67c89befdd8d3829d8de13b33cc0bf513931715c7809657e2bfb960e5c764c971d733746093e500
+
+PRIV: b322d46577a2a991a4d1698287832a39c487ef776b4bff037a05c7f1812bdeeceb2bcadfd3eec2986baff32b98e7c4dbf03ff95d8ad5ff9aa9506e5472ff845f
+PUB: eb2bcadfd3eec2986baff32b98e7c4dbf03ff95d8ad5ff9aa9506e5472ff845f
+MESSAGE: 19f1bf5dcf1750c611f1c4a2865200504d82298edd72671f62a7b1471ac3d4a30f7de9e5da4108c52a4ce70a3e114a52a3b3c5
+SIG: c7b55137317ca21e33489ff6a9bfab97c855dc6f85684a70a9125a261b56d5e6f149c5774d734f2d8debfc77b721896a8267c23768e9badb910eef83ec258802
+
+PRIV: 960cab5034b9838d098d2dcbf4364bec16d388f6376d73a6273b70f82bbc98c05e3c19f2415acf729f829a4ebd5c40e1a6bc9fbca95703a9376087ed0937e51a
+PUB: 5e3c19f2415acf729f829a4ebd5c40e1a6bc9fbca95703a9376087ed0937e51a
+MESSAGE: f8b21962447b0a8f2e4279de411bea128e0be44b6915e6cda88341a68a0d818357db938eac73e0af6d31206b3948f8c48a447308
+SIG: 27d4c3a1811ef9d4360b3bdd133c2ccc30d02c2f248215776cb07ee4177f9b13fc42dd70a6c2fed8f225c7663c7f182e7ee8eccff20dc7b0e1d5834ec5b1ea01
+
+PRIV: eb77b2638f23eebc82efe45ee9e5a0326637401e663ed029699b21e6443fb48e9ef27608961ac711de71a6e2d4d4663ea3ecd42fb7e4e8627c39622df4af0bbc
+PUB: 9ef27608961ac711de71a6e2d4d4663ea3ecd42fb7e4e8627c39622df4af0bbc
+MESSAGE: 99e3d00934003ebafc3e9fdb687b0f5ff9d5782a4b1f56b9700046c077915602c3134e22fc90ed7e690fddd4433e2034dcb2dc99ab
+SIG: 18dc56d7bd9acd4f4daa78540b4ac8ff7aa9815f45a0bba370731a14eaabe96df8b5f37dbf8eae4cb15a64b244651e59d6a3d6761d9e3c50f2d0cbb09c05ec06
+
+PRIV: b625aa89d3f7308715427b6c39bbac58effd3a0fb7316f7a22b99ee5922f2dc965a99c3e16fea894ec33c6b20d9105e2a04e2764a4769d9bbd4d8bacfeab4a2e
+PUB: 65a99c3e16fea894ec33c6b20d9105e2a04e2764a4769d9bbd4d8bacfeab4a2e
+MESSAGE: e07241dbd3adbe610bbe4d005dd46732a4c25086ecb8ec29cd7bca116e1bf9f53bfbf3e11fa49018d39ff1154a06668ef7df5c678e6a
+SIG: 01bb901d83b8b682d3614af46a807ba2691358feb775325d3423f549ff0aa5757e4e1a74e9c70f9721d8f354b319d4f4a1d91445c870fd0ffb94fed64664730d
+
+PRIV: b1c9f8bd03fe82e78f5c0fb06450f27dacdf716434db268275df3e1dc177af427fc88b1f7b3f11c629be671c21621f5c10672fafc8492da885742059ee6774cf
+PUB: 7fc88b1f7b3f11c629be671c21621f5c10672fafc8492da885742059ee6774cf
+MESSAGE: 331da7a9c1f87b2ac91ee3b86d06c29163c05ed6f8d8a9725b471b7db0d6acec7f0f702487163f5eda020ca5b493f399e1c8d308c3c0c2
+SIG: 4b229951ef262f16978f7914bc672e7226c5f8379d2778c5a2dc0a2650869f7acfbd0bcd30fdb0619bb44fc1ae5939b87cc318133009c20395b6c7eb98107701
+
+PRIV: 6d8cdb2e075f3a2f86137214cb236ceb89a6728bb4a200806bf3557fb78fac6957a04c7a5113cddfe49a4c124691d46c1f9cdc8f343f9dcb72a1330aeca71fda
+PUB: 57a04c7a5113cddfe49a4c124691d46c1f9cdc8f343f9dcb72a1330aeca71fda
+MESSAGE: 7f318dbd121c08bfddfeff4f6aff4e45793251f8abf658403358238984360054f2a862c5bb83ed89025d2014a7a0cee50da3cb0e76bbb6bf
+SIG: a6cbc947f9c87d1455cf1a708528c090f11ecee4855d1dbaadf47454a4de55fa4ce84b36d73a5b5f8f59298ccf21992df492ef34163d87753b7e9d32f2c3660b
+
+PRIV: 47adc6d6bf571ee9570ca0f75b604ac43e303e4ab339ca9b53cacc5be45b2ccba3f527a1c1f17dfeed92277347c9f98ab475de1755b0ab546b8a15d01b9bd0be
+PUB: a3f527a1c1f17dfeed92277347c9f98ab475de1755b0ab546b8a15d01b9bd0be
+MESSAGE: ce497c5ff5a77990b7d8f8699eb1f5d8c0582f70cb7ac5c54d9d924913278bc654d37ea227590e15202217fc98dac4c0f3be2183d133315739
+SIG: 4e8c318343c306adbba60c92b75cb0569b9219d8a86e5d57752ed235fc109a43c2cf4e942cacf297279fbb28675347e08027722a4eb7395e00a17495d32edf0b
+
+PRIV: 3c19b50b0fe47961719c381d0d8da9b9869d312f13e3298b97fb22f0af29cbbe0f7eda091499625e2bae8536ea35cda5483bd16a9c7e416b341d6f2c83343612
+PUB: 0f7eda091499625e2bae8536ea35cda5483bd16a9c7e416b341d6f2c83343612
+MESSAGE: 8ddcd63043f55ec3bfc83dceae69d8f8b32f4cdb6e2aebd94b4314f8fe7287dcb62732c9052e7557fe63534338efb5b6254c5d41d2690cf5144f
+SIG: efbd41f26a5d62685516f882b6ec74e0d5a71830d203c231248f26e99a9c6578ec900d68cdb8fa7216ad0d24f9ecbc9ffa655351666582f626645395a31fa704
+
+PRIV: 34e1e9d539107eb86b393a5ccea1496d35bc7d5e9a8c5159d957e4e5852b3eb00ecb2601d5f7047428e9f909883a12420085f04ee2a88b6d95d3d7f2c932bd76
+PUB: 0ecb2601d5f7047428e9f909883a12420085f04ee2a88b6d95d3d7f2c932bd76
+MESSAGE: a6d4d0542cfe0d240a90507debacabce7cbbd48732353f4fad82c7bb7dbd9df8e7d9a16980a45186d8786c5ef65445bcc5b2ad5f660ffc7c8eaac0
+SIG: 32d22904d3e7012d6f5a441b0b4228064a5cf95b723a66b048a087ecd55920c31c204c3f2006891a85dd1932e3f1d614cfd633b5e63291c6d8166f3011431e09
+
+PRIV: 49dd473ede6aa3c866824a40ada4996c239a20d84c9365e4f0a4554f8031b9cf788de540544d3feb0c919240b390729be487e94b64ad973eb65b4669ecf23501
+PUB: 788de540544d3feb0c919240b390729be487e94b64ad973eb65b4669ecf23501
+MESSAGE: 3a53594f3fba03029318f512b084a071ebd60baec7f55b028dc73bfc9c74e0ca496bf819dd92ab61cd8b74be3c0d6dcd128efc5ed3342cba124f726c
+SIG: d2fde02791e720852507faa7c3789040d9ef86646321f313ac557f4002491542dd67d05c6990cdb0d495501fbc5d5188bfbb84dc1bf6098bee0603a47fc2690f
+
+PRIV: 331c64da482b6b551373c36481a02d8136ecadbb01ab114b4470bf41607ac57152a00d96a3148b4726692d9eff89160ea9f99a5cc4389f361fed0bb16a42d521
+PUB: 52a00d96a3148b4726692d9eff89160ea9f99a5cc4389f361fed0bb16a42d521
+MESSAGE: 20e1d05a0d5b32cc8150b8116cef39659dd5fb443ab15600f78e5b49c45326d9323f2850a63c3808859495ae273f58a51e9de9a145d774b40ba9d753d3
+SIG: 22c99aa946ead39ac7997562810c01c20b46bd610645bd2d56dcdcbaacc5452c74fbf4b8b1813b0e94c30d808ce5498e61d4f7ccbb4cc5f04dfc6140825a9600
+
+PRIV: 5c0b96f2af8712122cf743c8f8dc77b6cd5570a7de13297bb3dde1886213cce20510eaf57d7301b0e1d527039bf4c6e292300a3a61b4765434f3203c100351b1
+PUB: 0510eaf57d7301b0e1d527039bf4c6e292300a3a61b4765434f3203c100351b1
+MESSAGE: 54e0caa8e63919ca614b2bfd308ccfe50c9ea888e1ee4446d682cb5034627f97b05392c04e835556c31c52816a48e4fb196693206b8afb4408662b3cb575
+SIG: 06e5d8436ac7705b3a90f1631cdd38ec1a3fa49778a9b9f2fa5ebea4e7d560ada7dd26ff42fafa8ba420323742761aca6904940dc21bbef63ff72daab45d430b
+
+PRIV: de84f2435f78dedb87da18194ff6a336f08111150def901c1ac418146eb7b54ad3a92bbaa4d63af79c2226a7236e6427428df8b362427f873023b22d2f5e03f2
+PUB: d3a92bbaa4d63af79c2226a7236e6427428df8b362427f873023b22d2f5e03f2
+MESSAGE: 205135ec7f417c858072d5233fb36482d4906abd60a74a498c347ff248dfa2722ca74e879de33169fadc7cd44d6c94a17d16e1e630824ba3e0df22ed68eaab
+SIG: 471ebc973cfdaceec07279307368b73be35bc6f8d8312b70150567369096706dc471126c3576f9f0eb550df5ac6a525181110029dd1fc11174d1aaced48d630f
+
+PRIV: ba4d6e67b2ce67a1e44326494044f37a442f3b81725bc1f9341462718b55ee20f73fa076f84b6db675a5fda5ad67e351a41e8e7f29add16809ca010387e9c6cc
+PUB: f73fa076f84b6db675a5fda5ad67e351a41e8e7f29add16809ca010387e9c6cc
+MESSAGE: 4bafdac9099d4057ed6dd08bcaee8756e9a40f2cb9598020eb95019528409bbea38b384a59f119f57297bfb2fa142fc7bb1d90dbddde772bcde48c5670d5fa13
+SIG: 57b9d2a711207f837421bae7dd48eaa18eab1a9a70a0f1305806fee17b458f3a0964b302d1834d3e0ac9e8496f000b77f0083b41f8a957e632fbc7840eee6a06
+
+PRIV: 0d131c45aea6f3a4e1b9a2cf60c55104587efaa846b222bf0a7b74ce7a3f63b63c6729dbe93b499c4e614a2f21beb729438d498e1ac8d14cbad9717a5dbd97cd
+PUB: 3c6729dbe93b499c4e614a2f21beb729438d498e1ac8d14cbad9717a5dbd97cd
+MESSAGE: b4291d08b88fb2f7b8f99d0dce40079fcbab718bbd8f4e8eabc3c1428b6a071fb2a3c8eba1cacccfa871b365c708bef2685bc13e6b80bc14a5f249170ffc56d014
+SIG: a9c5ee86fb06d9e46b379c32dda7c92c9c13db274dc24116fbdd878696045488cc75a52fff67d1a5113d06e333ac67ff664b3f2a405fa1d14dd5bbb97409b606
+
+PRIV: a75e3b6b4170e444781be4eeac3e0fdaa4b4356f705486bcb071a325ae071fba993d38a7d72f0aee15ff6f4fdc37ca7724fd1373a3766b275dbc77e647980e0a
+PUB: 993d38a7d72f0aee15ff6f4fdc37ca7724fd1373a3766b275dbc77e647980e0a
+MESSAGE: 4037866f6548b01cc6bcf3a940e3945aa2d188b4b7f182aa77ec4d6b0428ab5b84d85df192a5a38ada089d76fa26bf67736a7041a5eb8f0c5719eb396693c45160f8
+SIG: a5db4d3d3329abe3697959e6b5947ea8601b03ef8e1d6fe202144931272ca0a09b5eb0f390572ea7ef03c6131e9de5f16bf0b034244f7e104ff5311bbf663a0d
+
+PRIV: bcbcf561ecc05a41c7d7e55e696d32ce39b4d03c1f5f3f3a8927fe5e62e844b24ddf53fad6a7a9ed30f3afecca136fd7843b72c243090891ae4021a32cadff1a
+PUB: 4ddf53fad6a7a9ed30f3afecca136fd7843b72c243090891ae4021a32cadff1a
+MESSAGE: 6f6716b6784740980aebc3248807e31c1286ac7b681c00b66c88ff7a336d441fa5c3eb256d20cf6d1ac92ccfe4be6dcc41b1aff846d360c243001cabdfbf1a9b240455
+SIG: 9ff15115f6661f3211d7a40764967629ba6a5263951bdc3c6a4c90d070f7be00024b80d83b6bc27587fcff5f5ccc0eb3cde1497cf56895147a063f61f08adf0b
+
+PRIV: 210532805fa9cc9be916d213cac374e3cd6fc2602a544d0c1ce29d30105d69ab10699e499be99e2b11b98f6f86b67cdc4ccf69f3c53ce094875647d2d0d0ecc5
+PUB: 10699e499be99e2b11b98f6f86b67cdc4ccf69f3c53ce094875647d2d0d0ecc5
+MESSAGE: 9fc4d28cfd25e6c0c5e724e19ca39d71e53bf4aa2796c54c3351f108fc70f2611a62e0ab90af6ade5216788e9eb2a873059b1e79d7d59debd68f2d4d80ffe31bf74b928c
+SIG: 4c2d31d5bbc42e026dc1e079ecc4dd072c5d2cce65e3db8d8a1dd9057faa0371727f727231a0f060fa27097533b6db3b8f6252f2793d75662caadf5f0fcc710e
+
+PRIV: 185d64b69479e0ba0a5844a10ad84125ba11c4b40d63eda2c57afc7e019c8e0ca5764f6398a5ae2266a38f9714533c4bbd8d07826f63e204cbac374b0acef1bd
+PUB: a5764f6398a5ae2266a38f9714533c4bbd8d07826f63e204cbac374b0acef1bd
+MESSAGE: 4a0824fe70d4315413d0a0cafbf4f5fe117d5e07e1c3a4effb9d0ae91490234878ccf6792a91f68c6a520de16071f08abe35dc5ea428f1957b663371ce24c609dd55b8f493
+SIG: 43e0387da5ba09a190f6e7b2680578d889769bcc445e5ef571b492871c155c5b9f620bfacfbf2df1fd87444604b71b2e237baaa7ee2093ede4a601edf883e307
+
+PRIV: cfa9d9164b3c4f6f722635d2066cd7ea5e5533d2c74f8add669c371faa47642641169a66f9a63f285782a6c2db81cc3f70b3ada21a68c84745c88a74c3b0a2de
+PUB: 41169a66f9a63f285782a6c2db81cc3f70b3ada21a68c84745c88a74c3b0a2de
+MESSAGE: 757621b1675db7cacef7f2782587ff3af51a3ef2f4bcf9279c4ce94002e1f00424bf0eb621982cc85cb4d171e564a0c2f6e3567a1aae2cddb7e9b25f47dc20a51050542969ca
+SIG: 01d7c9b5701af71e2f4877ffc9b7b5305f52816d4458e37e41c7719fac1d76a01fff3f50fe1a5875ccc3fb70001c947a33fc8b207de13572ccdb8ba98933ab01
+
+PRIV: 1acb4a256c2f8993ca24de1e0014606d668b5e756032d269f1d24d351c8eea4acbbdcd8cbc885ab43a057e5f9579f1161954159e7b562ea26cd9a43c88d3f96d
+PUB: cbbdcd8cbc885ab43a057e5f9579f1161954159e7b562ea26cd9a43c88d3f96d
+MESSAGE: c46a6d61aa0aed1c1d8547a70b89b7196475d5a4870881b1ecd0f0cb9c745f8a2adc8024e2dc55b53aa5d383a81aabc1a47e8d07d00b7f0b56ceddbfb1f424bb5c02184678a666
+SIG: 05aa76f7fe51892303d78914715995e7d768ff7714ce270f175e56af17ae018d3fa939f5f620de82bcd1549687b205c7871203e624238c4e309fab7f92fbaa05
+
+PRIV: ace3c46424823622979fc3a84a7da69c1d527d8312e8fb018375bd3a96c29c18937cf34136d9e1cce0de11b12c70cbfb7455448421e92c82e7c40934bff8c676
+PUB: 937cf34136d9e1cce0de11b12c70cbfb7455448421e92c82e7c40934bff8c676
+MESSAGE: a9f137bc9021bf105aee25be21cd9ee5b3547cf10cc5f98476fb588bd70e2d6d6b0834e842e4ee94303cf96b09c1715381b36e14a491b80f895ea421b8ec2b1d3c187e02935c5526
+SIG: feb8896dd3fe6001ffea171b37b788a69f7f850193a63406f56376dd263d099aef80ece67e2c43f40eca462c6b71e79406b18db74ae5d49844e3b132bc2a1307
+
+PRIV: 88f681934e33c35c07dc6e5a832942ae3d59903ccde2f76ccb7587cea7ec41b66a4e8aa5adb63d22fd7b14a26fdb03b7c8aa6ccd5a196f2c54b0465adb5092e1
+PUB: 6a4e8aa5adb63d22fd7b14a26fdb03b7c8aa6ccd5a196f2c54b0465adb5092e1
+MESSAGE: 6e8bac1f853b81fef94707e18cc61c6f0a9cbc2a41d078dcc83fc0229c7f8dbe6dbdd90854b1f1ae2b9f2b120b86a8786b4e78ce23ab86baaf88754af0f3d88881dae0bc5261bfd038
+SIG: 45b27bf1b9eac06b62b686f6d546563b2dfe5b175dbef32bf78c35a16c958a9d4f26d291de9bb2066c0a286113cc09172d40a36d4cbd951708860226eb30cd05
+
+PRIV: 48050a6e0158f6ad253412e4497cff62d5ee555edffe59e4dc401522813295ce975e010abb9a3e56659137b0506057f283982f886ca172c7bc2c500ed9bd26c1
+PUB: 975e010abb9a3e56659137b0506057f283982f886ca172c7bc2c500ed9bd26c1
+MESSAGE: ed6eec29fb7049dff707f0a4426ebc8f5b350e95870b9d6198c8139e9c3e1e409937d1a858a0dea482a5cb1a854ed3b5a9397acb63bff6b64039ef2eb1159e99858310bbbd86125c3e0e
+SIG: 7216ab60c35168187d0fce4753c86e80058d540b76bf95843a5898841060a99a44de6f439625a3f6365f59c377bf45909bbfef5c50b25f3194e5fbd34ea5e706
+
+PRIV: 18d13d0c00e8e3386a5cfb30a9e79fe88b1861ed2d1201eb170038e194770403a4afc833401876090d9b880c41267d68cbbeeaa38afb20884e27328f3b7f535e
+PUB: a4afc833401876090d9b880c41267d68cbbeeaa38afb20884e27328f3b7f535e
+MESSAGE: 910f6c272dd97931ac47310d244cadb43251365e02ba9f6a5b3c3226be9d7d3a74a2ba4906e8e71a4bf3d3556ebdfc666cd6b12f20c4a00834b88fbb244575199286b0b9344cf334aff007
+SIG: 033988154c5d79d2510be83e778015dfe2fb85b8111f7ec139918b5400e3d656ee80a9f5c9072b5b467a5cc5a57cc8ad1062b5bff10862d9d369dde2cc966701
+
+PRIV: 4adc8c28646a93a817293a14d29b48e2c6d712a68993547a5c5e4d1452acbc3a7f40473628f23fc0dff0021afd487740d4916a9122e6c97d36433e5ebf04f88c
+PUB: 7f40473628f23fc0dff0021afd487740d4916a9122e6c97d36433e5ebf04f88c
+MESSAGE: 09fb5501f1688f80a0ab9e22d778ae130acaf74d7f5185b4da198c6b9edac4302e2b753e578766e17d4056dc40d95cf4ca8bcc6565795e97d68bcda79fa77c493397716356164caab5d19cfd
+SIG: 6d3b4e90ec408311f9b15b9253d3d95c5d152620c260d56302555a8804a5104ba5e8d29ee108e764a64219297298ab7674bbca784dee28773b34e185a386c208
+
+PRIV: f26e1c84697a4908151b447dcf6c7c7a38b04081db9e7c7738e6fec900bed0c1a86e1422c1235ff8e1aa083470d5e42288cb007ab50e795dd0b4ff87394966c4
+PUB: a86e1422c1235ff8e1aa083470d5e42288cb007ab50e795dd0b4ff87394966c4
+MESSAGE: 54ed47606a1487c2f900cefb6e899dbaf6c31cc88ebe3558b83b93f6d422c31e888e48e520eeaedd7e554a9cd40c2c519d533b6144cee484c389e976b1e4022b50e7dbb87ead7e541a2004daf7
+SIG: 44f3344b9566c9dfd22d6198e1cbf95d9e28f2982fc7f166ab25dda30c46f768c558e0394fb9ab3e1d4db4cf487c17641a13f3f48939e0c64827a75103c57406
+
+PRIV: cc0c33f3a86f5a17d30c186ce0f3b740bafa5fe3c7090f143541e2b2c1e534bc967a71c7cf9b82cc78cbe109104d8b438a8d1fd71d260d029046a9a4526866ff
+PUB: 967a71c7cf9b82cc78cbe109104d8b438a8d1fd71d260d029046a9a4526866ff
+MESSAGE: 1944e5e155d75e0d0be92e1be14cec370ad13791f2bfd40f271214e94fcf213c71bc20d7ce0c7584421ac4efc451883cc3f4956f21f73a4216720438bc38ff2cfdf3709905a50a9d94b1d9e7932b
+SIG: e277b3dd655c33ff75fa920af1fcc859401e6c7a6ef4c6bfbfac5069638f19ca115baf13c09c82af793facb6abd0cd58e8481b08c1b68ad7a2665c4a614a2806
+
+PRIV: f0bc979375a7073068dba7f6c094db6598b4e45df7d549583c22fded8048fa2eb42b6c57a78f1d90090a7181ab2ae09f426cbc2be96eb2cf27abc70d7d32a4b3
+PUB: b42b6c57a78f1d90090a7181ab2ae09f426cbc2be96eb2cf27abc70d7d32a4b3
+MESSAGE: 27ab3049b5c6351f6cfe38b13a059f5037257ee3d65d6079656856edc876ea081fd8a9480466f8839478088466f51ecbfaf2d65def25f0c4dd8d08588202812232f57945df8a6fa161ed8c0343b583
+SIG: 19dbc3027f9fae707deb76f588f9fd07aa8eae29bd4e1d04c2c984388286b3b122248a6c03ed67eca35df4db3dc1e4237f267892518497d9552a21de19b5140f
+
+PRIV: 3022975f298c0ad5ddbe90954f20e63ae0c0d2704cf13c221f5b3720af4dba32b845bce38e26ab027b8247463d437a71bbddca2a2381d81fad4c297df9140bd5
+PUB: b845bce38e26ab027b8247463d437a71bbddca2a2381d81fad4c297df9140bd5
+MESSAGE: 9aa19a595d989378cdc06891887ef5f9c246e5f83c0b658710673e4e7db760c76354c4f5d1e90db04a23b4fb434c69384593d010e312b11d299c9f97482de887cecfe82ea723bca79a1bd64d03ef19ee
+SIG: ae14a860fad0051b3eb72b3721a82f7b9546b2867261e2b7b638979e2561bdeb89b600768f82450a66c8b0481283fa21cb6c53bde350effb68a7d1114bfdb203
+
+PRIV: 0f710b6c481f71449589753312ef64932b4652ebe0e07597f7da1c4f3dcffb806973ff2932ccddfc1d16c4c0da50c8b29fe6452d1ee84d52064ebf3d628d403e
+PUB: 6973ff2932ccddfc1d16c4c0da50c8b29fe6452d1ee84d52064ebf3d628d403e
+MESSAGE: 85d85744ad55e9ef9a65ca91e85c8a4f80e4c58f8e4e9354e833986098b7d9fe9fdc0dedb0d75d2539fba00034fc0c2e84344d1edaa09d4f63d5546d67803dd6b54ddcc0b1d3f2582dd75289e31de42e69
+SIG: 02a8d26aee11420fb4f09d1163e14b867df7c6f6c8f8dc7a78034659f0401cad0aa90397efdd0704b798db1936503026e2a1adc297e27974d4be312a3753f804
+
+PRIV: 7a05f121f60112dd16fee8c91bc2a11479f4b67ee33456042c8de167fc588017b3b05be989cea7197505d4b54335e5e1d77a4b52ba7282604bbc1cf6c4e87a6c
+PUB: b3b05be989cea7197505d4b54335e5e1d77a4b52ba7282604bbc1cf6c4e87a6c
+MESSAGE: d9c59e8cc4ede537be2122ab492a5b915a9b0a114b2ade356fc0457ef98722d5f567b86211e28369d14168ec4a3c804076e154adc70a668cf64a20d13cf190d115cd688d036e46938251df4964dc3517b10c
+SIG: d30ce8a322b450a2fb1afd329cec8559ccf112bd83965f9ec4736270a0914e061196bf5209778c9f8ccf39c4668bbf0e1363f81afe45dd74e80d5875ddbf6f01
+
+PRIV: bf381f8dfb5d0c6d64e416ac23e0d0fcb86ebb899b1d146abd911b92a7808eb6863fad8d1f1bc630a15f6fe8ecefe6b4497b60b21ae8830da46742045fef156f
+PUB: 863fad8d1f1bc630a15f6fe8ecefe6b4497b60b21ae8830da46742045fef156f
+MESSAGE: 8654f2f5c6dcd2cfcbb6ed8d2bc5fb5fec53e3effb0de65aac507fa56c897732395aa09946d3b6586a92edd6dc99315e1ba74c6a0247c4ba7760b948eb3c0932d9fe1f0e9fea6eb61a548a9ab48ffdf1547329
+SIG: 99b75378738fcac8067669e8509b5d2607e1ef76af9004e13fe5d3932df60b168216f58565340fa4d638055a89044ee7d45e2bd082a53382289a34700648980e
+
+PRIV: 36983241a0a8e60ce02a61b3fafab15a7313a5a270d015b9c9ec070dc42deeda6647984d42b9a5b3b1afa3b7f8f49d4c2b05e38984e99cea8fd68235d2ae4627
+PUB: 6647984d42b9a5b3b1afa3b7f8f49d4c2b05e38984e99cea8fd68235d2ae4627
+MESSAGE: cebb9e404451818253c0392a4554ee7323c5d5b8b226775700b806ed5b91337916ea7ecbc3d4103fc65e5372ae7e5f9ba2d8f5aee24ccf6e631ae20c4af9b5f728cdf89e8189def1a5b3d35347aa203525ea1d2e
+SIG: ee37df8af422f91f85dfe43efe79f62378068ccdbaf3916eecbc3adfed0508bdebaf5ce06b3bc279f78087f0db8db3c6823edfb32c12217830be723d8872b30c
+
+PRIV: d06899f93a408dacb41c969718346f1e289bb5ea65e283ff79c705a074517c3546bf2a08a076c47d7f11b733f8141c355363ed85d7def26ba6a0ce15ac5f2be8
+PUB: 46bf2a08a076c47d7f11b733f8141c355363ed85d7def26ba6a0ce15ac5f2be8
+MESSAGE: 0864c39ac4fda8eb9048597bd40be0401021fd2dd3a3390a8facce984b260a13fa2c7cfc00d192fadf134a0ad5a181ee89eff0c795eaa0fbfe2f3b26115d07168db42ed21a51303b1958e4a42dc065b22ce48f17a6
+SIG: 6f89de92a66bc5f4144339124950bdf588144cb372f6736245351c9476becc59a258f9a933ffff2bef4b46cd1057395225799fd09dede6823db0e325dbc8140d
+
+PRIV: eebca7966970ee9f2cc4d74c6f1d8e0ebff7c45aebad349fb9f86df628dfff0e89101e0309f767e64ae9c98c4a5d8d2328fb3ef262d082f49b64ca209e1990f6
+PUB: 89101e0309f767e64ae9c98c4a5d8d2328fb3ef262d082f49b64ca209e1990f6
+MESSAGE: 0fac790adb9f59e5cb0ddcb2b667172f2a21034d93bcaddf188606fa9e776db33a8fcc6bd7f5567883fc0de351aa9afaa36d2075b1ba853bada849b8661d5c8154e7b0afea656dd15e01a9c5ba21589b02f8fc5481c2
+SIG: 7d447ee5328c9fe7f11936cc42998754a56cd1d2a6951af4fee7c4a8eb319d4923707c793c55d79067f822d5b16bb5776e38dffabc67237a916a81a63339b003
+
+PRIV: 3820b6b15939d0afe18c9cb3d9a2a08f167dd458eb6c7e3f1558b0c6db4c689080b85c6559fea8b400e1999cc5bfed507ad7fc294cd9ba0ce2dd2584a91089b0
+PUB: 80b85c6559fea8b400e1999cc5bfed507ad7fc294cd9ba0ce2dd2584a91089b0
+MESSAGE: 3e5ad92d44b40e8614d8087c9c743de0c0861a07f1f5146d71cac2f3740024e841cc2d46027cf5d261d3ee7c1875b39551017b5fb1468114fc3e098a899cdbd558b39f098e156b6e9801ebcdd65fed56dbfcaf2c8c787b
+SIG: 823ee2c0c8d87faa0ec0141e9ce08b51e57c839792d1fbd97a967207fd415849ebfb5dadb5a1dc2c0a8b7fc63fc354857b8c90c44720e13f45cd01e7aa23140c
+
+PRIV: 0d20fa4a37ff30c4dcc3e44ea7ac501137e5807e9781330ac310982cc3d39dbd67bb0a01bc8617b491eff1a326c1c70f7d0c5b95a5ad48241aedce1c6f0883cf
+PUB: 67bb0a01bc8617b491eff1a326c1c70f7d0c5b95a5ad48241aedce1c6f0883cf
+MESSAGE: 35e0f4b4a517f9c7aa4514f03e6d65f19b27c62cc069f6bf07dd6378bd6afe2b766560006cbd5730a00919ed11191fb0c8dac56e153fc1cea4bdce5046cccb717759a4083e1c16f740763264cc804de0d0e1a4b5a23067af
+SIG: deab12ed82ba94b469ca98b66fa20444b4b7881c4f0f853409c9a1504a5b2b6d7860f26ada6bf73459b9cdb573c8017121338efa60f4148086d7a3a8ed59bb07
+
+PRIV: bee161881d819b370d240d509ba46b06fb828e20310d9f6b309780703e98927b10854380de89162bfb9f7835a2716a3a6e0265671b250b389d01c3bcc03736b8
+PUB: 10854380de89162bfb9f7835a2716a3a6e0265671b250b389d01c3bcc03736b8
+MESSAGE: 5a6fe599b6b09b05c0ba6a622df3a92b3d376d24d04ea85ebe767bc2ec4d14e83e6937dc0b914b4809fdb607906841a6fd1dcdf61aaea8f9bb81b2ccaa32df412989ae53646680a71a211c8440eab0f1aec5e4fc00e6a2c96d
+SIG: b07d072eb3831fae8a06effa9201797496dce126b8e11fef2fa07f664dc5cf3d4bf9c38a8b3c09fb5f14fa2deb219e7d852fdd27c7ba32d309942f2746dfe404
+
+PRIV: 70150e9516164a3d7b7e8b6f255b65cac9f07459b32d11bb94b3d277208abc992328bec8e40351047882e8b43bc1ab085386fa47987e46ea87608814c5da713c
+PUB: 2328bec8e40351047882e8b43bc1ab085386fa47987e46ea87608814c5da713c
+MESSAGE: 77be8eceaab431a13c2a28d0d1556489d8c392fd7ae41157f7caf082cb54e45f08626be0076be844d38fde901a5eab0e8832d69dac22fb8507fb8ec4faf7c88fd26da308461afe385987972b5e760a34a5e18b9a82b4aaa529b7
+SIG: eda3f5033ea7953a0d583c6457522e84ad78445304d48e577d4d69e8641febe15248d8d90ce0944a8f801d39099bc77494bac4ce2a20b38369c6adfb71e03d0f
+
+PRIV: 3f87fcfdb421422a9c5fb98268313c15128c78844ef9eb3b3713fa77b6718903533ec59228374bd03a4699e3a8896b86182fcf8fc3085fdb8f5c4671524d6fe0
+PUB: 533ec59228374bd03a4699e3a8896b86182fcf8fc3085fdb8f5c4671524d6fe0
+MESSAGE: c00fed2d689468bcbacccd446e8d8f299e2a86925e62e59709afaf4857469ff1e006d00fa3e18a3615f8f06b6ebdff785dde58851d2c239038a0c344dce985bd1fc8deb4779ae5f8932e2f9ed5990b6472dbe4e6fef6917657e0b5
+SIG: f6519d7edb6134111974033f03b8d89e9c76caec8965a8e17cd45fff19de2615d73eccdb4a6664a8f0e23adf98988e96251bf26eb7a4ccaac1079f0a772f9b05
+
+PRIV: 44ceef044ff998d4abeaaf374eb41d086718b63097b1e35f89634c14897132eae83c86677d03ed3a5e8c95f41f0b325ff4333702f2ff6936f57ff30aa31485c7
+PUB: e83c86677d03ed3a5e8c95f41f0b325ff4333702f2ff6936f57ff30aa31485c7
+MESSAGE: 8d3e2dec4644c7b51633b13e6375ca42ff9138465f43d7800c7313199f67c9cf1b520b1820bd630ecf1c992e2767b38eb5bbc441a4ab8d317db441db35a0fe3abe7a9e4541881c2d7b1a2612306959815d1da41267d9649dd4494ace
+SIG: 554552d6b790d421d06b0a67f8e002ad7a1ed01c06cf00cbeaec2a268bda29f1183f0ceafc625fa5fdb847dc86fae1a20406e459d4a0177cb515220a568e0800
+
+PRIV: 98ef2a44d4c8476dff05aa78dcf9c6dc086cb2f622a06745d60cbf223faaba6642fdb1daa39f0159119beec1bedf6f0394b26a2a29bd1fde081eccdadecc226a
+PUB: 42fdb1daa39f0159119beec1bedf6f0394b26a2a29bd1fde081eccdadecc226a
+MESSAGE: c8b5fcfc3c18c7d95957b668e91c731d50c7fcea4f9575bbf784625870e238df546e2cb1a19d2808dd5b230d3871fdec16100ee1fbf9b722fa3744a750a3b396b05f9c21b8c0f61ead57a78c5ecf72b579cfe88a3f404c8acf524f9ab9
+SIG: ab5e8724a3e6ff76058cfb214d574e04d05574ecdd4ffe8c07c7af396e882687c5d79ef1e62fbb4c5f1bd06b9bd897826edde0d111d918e8ef961ff2a00d7700
+
+PRIV: 93a8c792a239c931917c114824a0174f8bc4ebbf98af8c7e321e0f5bea4015ec9b2eaa8a9c2c25ff4f6e13bb12bae5d06fda0eb1105fafae5880ff168740bb74
+PUB: 9b2eaa8a9c2c25ff4f6e13bb12bae5d06fda0eb1105fafae5880ff168740bb74
+MESSAGE: 901bf4e041caf16e04f2ffde8d6fe97e93d0900f6bc0fc09a9a0179d137b4b7788e57eb92766a9c634f35adb5c2988af1e86208f461998f59cfec99204b484fbcad3951e7ee4405523705d9739b44307db03f713fda78db421ef3121b3ba
+SIG: cfe32c4435d911d772dc0727e78d689d0164c5069597cb441b22c1d26236479f1afd7089121b9ab4f61bbb1fae1ab42f7635a92a53784d7170916b703aa5cc09
+
+PRIV: 7001fa0c4404c28aa5b5fcff30a961f21a22f5b85a9e382e07aea8a8924d0ec1daebb63c4d8f40ceba8ec35e3dd946a6b75bc74fcb29ade7b55eee3cc3aea5ca
+PUB: daebb63c4d8f40ceba8ec35e3dd946a6b75bc74fcb29ade7b55eee3cc3aea5ca
+MESSAGE: 44f48cfb02f08777a57873855f96be4c0291323f2739b275d90757a15472e5750436e0107408fe3026c00625689983f990eba9becbfce403ccd56356ad2741fd21445dfb23d76112e578b3395cf9d960955f1da8f399ca286f21390e25a59a
+SIG: 64eac9ce87460618636b41fd2decc1673bfc48c5f479dfacb51e86686407374b1d10bf65d6d7474214d7770c9e5c7f806c80d53d48b720870e5e78f32e3a7e05
+
+PRIV: 3adce3a3d3fbc977dd4b300a74749f13a3b04a5d73a2cd75a994e3195efebdac6ff19b1f18d64851d5c74845c6407f0bf596a52e385e020127e83e54cff5ac19
+PUB: 6ff19b1f18d64851d5c74845c6407f0bf596a52e385e020127e83e54cff5ac19
+MESSAGE: fe6c1a31068e332d12aab37d99406568deaa36bdb277cee55304633bd0a267a850e203bb3fabe5110bcc1ca4316698ab1cf00f0b0f1d97ef2180887f0ec0991e8c1111f0c0e1d2b712433ad2b3071bd66e1d81f7fa47bb4bb31ac0f059bb3cb8
+SIG: 7dda89f85b40539f5ad8c6de4953f7094a715b63dda30ec7cf65a785ceae5fc688707ee00be682cecbe7ee37d8fc39ee6d83c64409681708a0898a183b288a06
+
+PRIV: 14803c1f23a47fcdd35e5d146e20ca630cd712c047d5330b652e31857acbc9e836f2d5bd6d8324fa6e9db7f7d854ebe48c0e6299998122e9d44b8adbef54f093
+PUB: 36f2d5bd6d8324fa6e9db7f7d854ebe48c0e6299998122e9d44b8adbef54f093
+MESSAGE: 555983679d026e5354b4cc055ae1bc14653c7281ec722372f3feb778e841da821b3d0b8ee7a9a9129ea06824be8379fbbdcb0748f423721ccb172a1bafa1d5ae9fc1c51e93d41dd551c3086079b620286c1c40c1223bbcbb76722e92ca21d8410a
+SIG: 07a7de6ce97664b3ea0928e1385c3309be08a47cbf4daa9186a1b948c86fbba39c4efcfcb7a0a3866bc94c6788ffe6be0d4972e56d0c3292d1cc6e25447b9904
+
+PRIV: 1a61154d3472cd96b328ee674beb4fc86763a969fb410494e0678414e31a46a67576d93ac85d0fc61f258c55cf90bd87a635099c0e810ed0b937258d13b42559
+PUB: 7576d93ac85d0fc61f258c55cf90bd87a635099c0e810ed0b937258d13b42559
+MESSAGE: 64c565efbcb8b9528ed47253f3c6a4035db781d6f0976b5e5ba8447d4ed54b04105293ef4c000d8b2e1b5b75e727e5d2a077743b50d183b491764801a2504d16ee6d7d8ac4fe40e6bfc2a8129c7285a5ac691c35e642ed162cf7fbc64516733a23b3
+SIG: ada1666c9c3b8284b8a21c4f2618ef0808a646f3f10941e470f738e1785e2de9fdd9c8cb526f945c7a8c6994f151b7d066581b1d755307947c62befc8ab7070f
+
+PRIV: f215d34fe2d757cff9cf5c05430994de587987ce45cb0459f61ec6c825c622591ed506485b09a6450be7c9337d9fe87ef99c96f8bd11cd631ca160d0fd73067e
+PUB: 1ed506485b09a6450be7c9337d9fe87ef99c96f8bd11cd631ca160d0fd73067e
+MESSAGE: fbed2a7df418ec0e8036312ec239fcee6ef97dc8c2df1f2e14adee287808b788a6072143b851d975c8e8a0299df846b19113e38cee83da71ea8e9bd6f57bdcd3557523f4feb616caa595aea01eb0b3d490b99b525ea4fbb9258bc7fbb0deea8f568cb2
+SIG: cbef65b6f3fd580969fc3340cfae4f7c99df1340cce54626183144ef468871634b0a5c0033534108e1c67c0dc99d3014f01084e98c95e1014b309b1dbb2e6704
+
+PRIV: 8c9f95083075a43fe426d19f1e87719b40043de88eb0ee971f70e10c7694ce4ee91d167aa3ebc23e70aab45dabe905e416262f910e2a955dd8619efc74c24e85
+PUB: e91d167aa3ebc23e70aab45dabe905e416262f910e2a955dd8619efc74c24e85
+MESSAGE: b69d70e860f55c427ef2a71df36e05bbc43bb2e06463aa5de34419c6a614eea6695335a87526c1226488d842891d0574df343c9c1e17aed6958ecee87474221eb77a599ecb059344c0d052c0002a66e5a6013185af69a01ba5dbc660d36cae235f67fe0e
+SIG: cac555222dafec76a0b47b9d2c586b3b3b9b3b9c8364beb3cae1e8dd7f1ae9dd74f22b8dd4ad2b290f81351a415a99f030f10778be4cda85d1d353331e70f109
+
+PRIV: d7eb1fba424feed100777eedb4874bf20810ad686b67e31d27ecf610609a33f5a25acb11a6c825713a085fa754692886a87d07fb9be1a53eb961728bb66c9060
+PUB: a25acb11a6c825713a085fa754692886a87d07fb9be1a53eb961728bb66c9060
+MESSAGE: a1d0f81e3d59089cc2b19e07d2fce43db4cf171faa642f3b0bbde77ae3d53af5c02bf8fc12ffb4e57f7c8a015d6c2d178944fae9f7c8fc969d4b77bea51876ae99d59e94ad2456e0ed72c52cf4e5340da17c44dbff86457a519b6fffe269066290d629fe69
+SIG: 2bf719682b07cc5ecc0480f37e9d123ff6f44c26e6958e59f080466f9cd373a16500daf123dc3f1334774bfc9fa84503b16dbf21a815c1ada6ebef4920461702
+
+PRIV: 4f6aeb35fce14fbcbb9aa8a4f6451bf95b98df047fa8c43f1ead3b404d3f928fbf66a9edd09481db8444a176c8ce0578d2934f0cdc9734e86fcaac05bf3330f1
+PUB: bf66a9edd09481db8444a176c8ce0578d2934f0cdc9734e86fcaac05bf3330f1
+MESSAGE: 2dfbb3f59e19ea17d44a5bde4ad227a1a351dda17af840ee0a75da21a5cca89b6d1c567c333e9cc910e2157e05e86ad5d931145064594c47baeea8663a34649c43e90eb95ca10f7d51597b378a722f1f704adf9f22e9f885b89d1f938006a2efcdb42aaff5e3
+SIG: 6adb07e364f2a455cb05867abc511acd9d658977f0cacafc92828e7b724f6bbf98bf0bfb29f4e5e6c74738d4fdd816d9252407ae4f3afc574c4f00614824e203
+
+PRIV: ef4a6762b400975204ccc13abb47344015454906850ff14940cbb83aa22414aeeaca450996f50cfaf2bd7f9d7fa7087f09ad49664206a80bc2e5bbbb85bb668e
+PUB: eaca450996f50cfaf2bd7f9d7fa7087f09ad49664206a80bc2e5bbbb85bb668e
+MESSAGE: a4b63eaed5a64a94f2cad212ce2ae71092fd3ea744f5bd89562b2fc2a6c9e4d7aa27add56264a5a55016610be6c19ff7d4989e9504740853012715a79ece9e12c301b3317c7d9b6730db862a4a1d28058e0f8b5ddd9738c7c62ea572cfe59eae08e2b8b6593b58
+SIG: 02697d44cad862f1daf5708205f450d408525b10c01ffd06cfee80374f3db16fa9a49c19a9844b345f2f9559ea74aab173baa078c54370a5166700c6dafb780a
+
+PRIV: 55017e5f61f0c5bafbcde6f849f42a31e5e7a878c1d3f9126fc569fd417ea9f266914f74ed932fc881ff0166683f675a7c28a926fddd6469cdb3f28e6dec42cc
+PUB: 66914f74ed932fc881ff0166683f675a7c28a926fddd6469cdb3f28e6dec42cc
+MESSAGE: 2fc84a0998fa6e168a866410bb68105df249a28cfc76604be94fd7dffff2fc1dedd220199465575e8df860190f16aca4084169be16c6ba32eb67042ffd4f230316a26b2624a42f8f90ad57f6916486fa91fd94ed68aded4e632430ef719446979bfaf345409c387f
+SIG: b1a5e7c49b8fc6b4331e0416ce7e4ed59edd56300b802e0d72abca4a6fcb876c03bf331579124ae0d3fe43f7898bc87e93fc2da3970fc8638957d18c6613c808
+
+PRIV: 0553fba866942341217cf278ac57cb21acd09d9916cc6af0ac46941ea139d545840c66e57c2d4f52a4a2796d2a53c5709b96a628c2e063fe6efd47f283ef5e82
+PUB: 840c66e57c2d4f52a4a2796d2a53c5709b96a628c2e063fe6efd47f283ef5e82
+MESSAGE: c1fae6262a0e98a6b1235fcb62283b7f0a097f9d002416d318fefc60c5a1584f900ad0ab26ccfae0d6d84aa9aa2df16d4c117ea2724676cb866d4870a872fc829a7c2a5d21ba83340adb339a34c5184c7f5ead0f077289b33677ed6a1ba34be1994e25763bd1d9faec
+SIG: bc3364c152ee5c808ac340f49ea2cc404e93517121220cce6f7c30a22500e41bcdb6e820480f8fccdd22ff9ad96da532802f431e94240fb83d4bceaa09b92b0d
+
+PRIV: 7a5ac602de19f3c21040bcddbff42f6aee6f95c1b093868f48e50482dbf4f9c7fbb6c7531cda21e7d17ea903c4d14be6c68b4ca803a16bd87120f5aaf7dce1d4
+PUB: fbb6c7531cda21e7d17ea903c4d14be6c68b4ca803a16bd87120f5aaf7dce1d4
+MESSAGE: bd1685419279eb81e4cf3c909031f0f09c5ffae7e2ce6ba9d96c2bce87b8ba0dd763231001e532c7ddd62103abf701288e19dd8f5302e8f5d31b64cc339bd8b7a95550c8a116fd486948772bd5af8dfd46001c59767b0d6bdce383a7078992d1022fbcaf90710687b9aa
+SIG: 84101dd4b5e8ca3ed98c1e8a06e11d7e424b0d12ca714ee7374b64c29d51a2021cc77ac75389d9b0a646a447623d7d04d1241866b0ca6edd1b7ac015666b700d
+
+PRIV: 50414cf549bcc55b5b6b75ea3782b2ea7c087b6a0106175e469ca2cc764aeb01d0f30c12e997f96e7aeecd1bff6a012ec388ebf8f3f4af664804d1638e4c346a
+PUB: d0f30c12e997f96e7aeecd1bff6a012ec388ebf8f3f4af664804d1638e4c346a
+MESSAGE: 75ad77e8c54b0b05fb2d162e7cadb8a7528081b863f76a441b374469413e5714edf54f800496af0157c17e425583414d4361f2134171c0b87c22ce6820a4850ab49d99a9badce9e36110e7f3060118b3590f82b43771e9fbb081afe62227e024d98de6cdec028d7c49490d
+SIG: b309800160de43a63a89a0acb8a6050059589b3eaecac20b256fece438042f69415d8a56883ee3836d3134a7fc1de64fa8c8cecc3ce27589f606058820857a0c
+
+PRIV: 93cb00d8fe9c9777a683631f39ba0f48761482cf1c366bd863cf71510153255587e94a1ea5258d61180cb828590ff1418a87d01e702686ba8abc2692c8dc3c91
+PUB: 87e94a1ea5258d61180cb828590ff1418a87d01e702686ba8abc2692c8dc3c91
+MESSAGE: 88d8538d31867813d88fef7228d49a7e950d738396f116dda1025f7913547c5d1dc5677a6de4b4a5880507b361780b61b43f7795263db22ff341645f2f5914fd6088c2811211ed4756ac019a6035d66e3170c1d82bfaa30596b396b3260cc1d10d413dd47ebe6daa0c30dc42
+SIG: 09824fa2dfbc4d6ef76a9e4145961116769130553b3edffa50d04f39b8b79facbd237acf71354a53a6e5fee754e823b0b290f9619320a13d561269a221639f03
+
+PRIV: 2b4cae380e95ce694c26ac7957447347f98e31b4bf02d744e131529071e2301de6fc705a79c98e115b4e28d3aa1506b74ee74276c5fc1109a7f4d89c6fafb889
+PUB: e6fc705a79c98e115b4e28d3aa1506b74ee74276c5fc1109a7f4d89c6fafb889
+MESSAGE: e0b8250e27b7c0291dbc47a6da6f1268987afdf0a1e90be69bcbc4370865217830d5208693be7b7045099a22ea27f952eb3f79a9a0f1b5a87b19367790788d34c219c2e2a6b834020fb4fd149dc56b544fddbb42071a162fc7cb33c146cac05a31b183e9daadc616f3af449b17
+SIG: 555e45656ba9cfbf5155d0e52576e5197abbbc9dd233993eec2a1ee7f6a86409c0b71b0a661978ff5e0acdc9463dc449906f474f8e79bb86168bf70741e34b02
+
+PRIV: b56491e54999bb5a1715ebfa2feb14a545a3a43c2fdfd4be0c95fc11819ad695cd42bf414f9bfc72ec069882a800557cdf31bc3464fb102c310e6dbd3ae20863
+PUB: cd42bf414f9bfc72ec069882a800557cdf31bc3464fb102c310e6dbd3ae20863
+MESSAGE: eb4418ba30683ec7959bdb1ec7b263f83e81f054ddcdbe0a6738ca7763e246935bac419026c22bfbdd1236336cc16107c53513e3ddf34e120846962c3bdd54f5ad5749597208f15a8bb56667baa895f08340db89b85c435e770931928d8abc99262f839aedd9be2aa138c9259adf
+SIG: e3be3e71a89852df3cffd72d68207869dd3eceb49b1f029493eccbb932444ebe8c8c6db5f0a5a67e2194408df9841913a5ac1a606896419a668f4f47c56c2b08
+
+PRIV: 6579c247dd2cd02ba2f7d7a950a330752681e92c0dc62984bbea279ea521c3810b087bea1a1b3d15805cb604f4bb8d68edde274faf521fe6df50c55f8ad4a70d
+PUB: 0b087bea1a1b3d15805cb604f4bb8d68edde274faf521fe6df50c55f8ad4a70d
+MESSAGE: df7c552ffc89374b9571a6024a8d0471d7eb6be8dfca6f4166b581b65479015a0568129074cc04d6342c758ca18f7987dec536b7033d5f9681504340e20986f027b8cf1f263be76db3525d173422950ea8dceddc585640918aa9d25ca89cba701c2020153873f46108c772cb388d55
+SIG: eccaf801ae0a912e21c6b83a5f0e4e88d4b2713459ff93449fc0b21a9f416050113cbae4e814d20c0a798f76d2f9d326ed83959ea02abdc1ab350a467123f709
+
+PRIV: 18fba60c5026f3c9dd7aedc04209d5260361de400e190aeb60169e05a3367c9fdfff347f3dd255530bf7fb34d02ba486d112bb46e950e2ef80e517014cc95734
+PUB: dfff347f3dd255530bf7fb34d02ba486d112bb46e950e2ef80e517014cc95734
+MESSAGE: 34f08a804d7829cc3914f000ce1a3288acce2149c8a02086b9f67afccd83a178b0bcfd4970c056997da7dc3d47562f16663cedc52f82d710850cf4050379efdac23bee17c330a383ad137f788473b2b0723603b6deb1fdbf6c523fc948a0ccc4ff100fb946d874c1f990436ae8c4f3b2
+SIG: 4bc011e40f0f59c618f6bbe230b6f7bc2f50e3617c7faab7f4c21cb84f77eba994cb7c2a1bf10b01bb20084497fdf0a6ab5d9bcd22c4a2c5a78f79926825940f
+
+PRIV: 073cc15b0536285933b2be39253cf4fd696b81610f5dd3adac2e9cbf338ef2f600b551d371544375dac5c4e96cd1f0215207e8e166a1fe49d5b0a51ac18443ec
+PUB: 00b551d371544375dac5c4e96cd1f0215207e8e166a1fe49d5b0a51ac18443ec
+MESSAGE: c285362bc8ef628f7aedf654231ee51acdf2cf69a886b942bb9bfed8155105d9209ded2af24f169ad5fcd451370f5827a85111c7a52e032c5038617c0c0170e2a6c231dc401d12062edb186036114e38793b79089077581b9783f40007103ef17472491c00e7138aecc5084d3c85010470
+SIG: 3aa52a83062a8f28a5d6b7607f484b66cc374896b766123126333c579581316c742806f627b5bc55cad705cc1d4782b044080c8ac840f38c0c50d35e345c7803
+
+PRIV: fd894a1e8232203b289505d5c68c68791ffc0e54f2a87530fbba5b3a3f2caf00e95ab565945c7ae5d533df5d0cccc7e9abbc838e20a0b61c930f5d41d81a6fe7
+PUB: e95ab565945c7ae5d533df5d0cccc7e9abbc838e20a0b61c930f5d41d81a6fe7
+MESSAGE: 2669624a94f2c44a05b7dc3ebf93e58a4bf3a01c273657e7e7878976f6b6ea737fa3f22cc8365b8b220c007d5b642726a408fe2fab69ebb3bd072b349f4dc3377ee7cc752934254215d23989bd3cd02ce999adec9784993f4c19940815f39c9e229247f5205c36cba44e714266369289b4a7
+SIG: f51102219e8804be713e556df4e4afa2f8866fe86541a1c2a0934d24c3c9beb280a70dd8d527fe8b7e0b948214d5f2f9638619914b72d55dc198b0229a848708
+
+PRIV: 18ef464e28f87ffcfa4d3a9c09a22910951b8c719fdacdb56de62c4b406df00cc5064c9d43ee2da75b06bb09c77267dbd0d39128f1cdc6bfa451a03e93af4a70
+PUB: c5064c9d43ee2da75b06bb09c77267dbd0d39128f1cdc6bfa451a03e93af4a70
+MESSAGE: 9c825707d9358365ab9d38f7e728d628aa722a4f1a20a38e47c999fff8fc32417fbe072f96eb6a0e11e4da9b6de9615445280e93c77a3634d3d2c6879856c248f9800f60a0d38dc1cea8b7f31f286cb0374827b4c6ba144a6694f2b908ead68d18340124cb59cf1701863bd4f3efc709f3627a
+SIG: d1e7f16e8e597d428adea65591d551b54b667aff2020c464f7f4e53c4773f70433249a3c71b4d11c89c3faa892809227b9f29ef4f7f5d020d4674d4021359405
+
+PRIV: c911bdf2f9e7cc5fff35c96e15cc12eafd05ab0db31f649f7408acd0cada76e0de44696cd6bd2cbe9b11a0ef18b88164801a969d5e06ed453eb4008cce9a5725
+PUB: de44696cd6bd2cbe9b11a0ef18b88164801a969d5e06ed453eb4008cce9a5725
+MESSAGE: 76c471241d17192984b00362696e4d9d4d2b7f839c2064117e50a1598f3a1172b16c55e5396866084752024f3a7eb68bb3ffdb80979a0af6d0f6af26b6f0bc0c0384433bcfd44c75eb654a8a8225cb9c4a7fb3c824c3af6125fd46db287e70492d154632cb8f62432659d958d6281d04a54f5f5f
+SIG: d584b5da371ae4f5c9859b25f70dc56c1b7b4e02d1ae6636283b1b7b11217afdcdf65d1b49ca2c8ef17966e9bc65f10c310b77bb5df7aff5ec1b379a2ce55d0d
+
+PRIV: d3703299c41db36d77dd3a49541f3fb21d0b2bad1f6e074affd96f1c40d0f927862c5ef616a5f066fd87758a56ab45056fea4bd33f008be24f7b540e095e148e
+PUB: 862c5ef616a5f066fd87758a56ab45056fea4bd33f008be24f7b540e095e148e
+MESSAGE: ac92edbe22257bb06d94aa950e62d18ca2ac0a8fc106000d2231f8a13b8d7a209ccd8cc49a6cd68a7f36c02fb8f728d15595167f0ba8cfe95c8a1e435f327513014ac428b75d4f72e7c834dd70e1a448f1847d3498475f74e3d9334dc7dcc4fed72bf6c7fe3b1d4f53d429616f1df44f19733158b6
+SIG: df28277121eac44630084cce75917ae9f6bec65af5572dc30719bde661cf696b85b8672dd4983cab30bd05cc3a119d7db9babd522d7b3a6bcf3886ecd25e080f
+
+PRIV: d411cd33576d0efe9ec413ccdaabd4fcbafec01a3af4b3cbe34f8b05ef8b59bae870344df98dd3a8702c4519bf9e8b35a9d189e746f7203dbbf9bbfab22d6f63
+PUB: e870344df98dd3a8702c4519bf9e8b35a9d189e746f7203dbbf9bbfab22d6f63
+MESSAGE: 11d2c2a7f0190988126696431b4bbcd90ab7b56a32da6404ae446aa762a4ddc66094971538eeb85bde0470a510be0d6d85780ee730a9854138728ae6816162268da852858eaed4ec74c7ac62e6e7096dc002df0bdf5fa40da565b41d181a3f0ad0c5e0b976743e315d9db8ed4160abe69c13a2b3f09a
+SIG: 83460d15461d6717710bafd6a47a1eaa900a80f2bf8b8aae2468773614ee84bd628c9717476368ef3640cf760acac83ad60232a76963b7d52588b11dc004d70d
+
+PRIV: e10a2f1380c3e4720e8a8707a9bcb25a0f58270d7059cd7626c7153447edfb87a3c717acab366a40b51187bbf35b2d15e97cfeacd7349c06ef1c91ac93e90656
+PUB: a3c717acab366a40b51187bbf35b2d15e97cfeacd7349c06ef1c91ac93e90656
+MESSAGE: 135212a9cf00d0a05220be7323bfa4a5ba7fc5465514007702121a9c92e46bd473062f00841af83cb7bc4b2cd58dc4d5b151244cc8293e795796835ed36822c6e09893ec991b38ada4b21a06e691afa887db4e9d7b1d2afc65ba8d2f5e6926ff53d2d44d55fa095f3fad62545c714f0f3f59e4bfe91af8
+SIG: 094bf6f953ca0eb77df45129b7bf10d192cf6ddeae94ad6202b8eacfbec119e5291578fe64a084ae600fe07efdb8a782610dbdb0b49eb5f2a46c432355552f01
+
+PRIV: b2e697b3d3efec976ef3369530c792717bdbb428d9ed0c11ec0ea9b2e5f39f82c4d2e4b3c236d6c9b8c74fa384612c4710d83aa16ad7ef01fbb7421d4fb3f0f6
+PUB: c4d2e4b3c236d6c9b8c74fa384612c4710d83aa16ad7ef01fbb7421d4fb3f0f6
+MESSAGE: 7b436232ac2111a84059510c48362588fcb7383426be5e6f62f372e4f7cca83c81c2357f9b54f4a15291065b6d41aad1ea93cffa776b9acaa58afe2b51644b97af9a3e53f84e40aa6d86051e6914cd039d4170a9a526dd69955ff507c33f74e2176591fb0b3cd7f00ee418f2c258a9981cccee72f01c8430
+SIG: 5047fa38197b8328e78dd8a10e966afb7bd3d43608280f1c257d25ca43bc1c06e94a5747ab6215ece54cdeff8c56567d70d2f91f9ec8c260aa1080a6ab5a7a02
+
+PRIV: 19a679a7a905a1e2b3038e6e418b3da97c3089c7cd351ea07bc8d1af64eacc4619f08361f469b4ae1e0ceb94f47a7de7317410a92dd013b16ae0d0532fa4b3ef
+PUB: 19f08361f469b4ae1e0ceb94f47a7de7317410a92dd013b16ae0d0532fa4b3ef
+MESSAGE: 980c7b4d2939061ac7b9ba441117a19485661781a4083067c55acf93026c082a93cc124f095e1b4f2c3f6c135412a5096228e8a071e8b4b668ba9d9644ea9f4dabfc54a9856c3e965e6363395ab709037dda229baf927cd01f9af5e039afc42f3cec634f5d832d2ab7c7cad3ad7b8cf27ebdac698431ad8236
+SIG: 4347b7b4f7c3c4dd315b8384a0b0caeed84bdabe24b2915f12512dfd04770fc996a1bfb729afef9edd611447081a5330617eaea1c1dab1bf13cea8997204910c
+
+PRIV: f03b8363ee5b0eef7018a49bc02adf731da54ee50a7f03b88a29a2082b189c4331287ef5a2e64104ab7790b312f35c7ad4af6beb0d7ceb8a58f36a54ce272c3e
+PUB: 31287ef5a2e64104ab7790b312f35c7ad4af6beb0d7ceb8a58f36a54ce272c3e
+MESSAGE: 24191b5464b35ac7bcf4a375f033efba8943b09b9ff0fc403ca7aae702a3cbf396c5131bc008132cf5f12910d586dc1db9c084574a96babee95642f922371c0382ec0402a26feb142e4146bbd3360c2b36834fe45af5e2868d4d56fdd504cebf0c2d7f5791b4429417c8b65a98e0b15c466c137f410524fce737
+SIG: e8fa967e6afadf6a877d87e5f5c52bb634b75a7804199a2bc9d027b63a35654d9ddd06830455641dbfb49edce42e20e7d4104a071c2cbbec23018c297ced9908
+
+PRIV: 11086b0d11e415ab1ce02aaf8f0621b54430f6fb135c74f40d38e8c64737064b7166dfbc691eb8c201114ba0d1a2c7b87f7a1fd8d0b36058b0d7dcabe1ae30da
+PUB: 7166dfbc691eb8c201114ba0d1a2c7b87f7a1fd8d0b36058b0d7dcabe1ae30da
+MESSAGE: 4b5b2936c5e360a38455503721078f8adb404a7ee7ecc14801dc87a67a152b769569fbeac0afa25a2070a1686b900ac1633d499808cdb2e81ce3916d5a3c04d19c5bb2699a662b8aba4af94d390bac7ccc8ec910ed2acdf86ebb71adb601877885eef3c91662fc30738e352cc74353ccf8d8edeefacc042c10a0e5
+SIG: e907459d5adcd0d0c36418581f19d0eebda7138ebd9faa0b262201f458c856310bb77f4c7de922495dcfe8b248eda2ad0df6a73f47bbfb894baa7d8869875802
+
+PRIV: efce7667a8ef91228caed14eb477a345e5e8239234080848760ed0970713fa869193055a84df1eacca28ce2a08c2a07a50f04c024ecf1fe4a47d2efbaf63ed58
+PUB: 9193055a84df1eacca28ce2a08c2a07a50f04c024ecf1fe4a47d2efbaf63ed58
+MESSAGE: aa1bc80d7bcc1d94a23a57cedf5027482477dc46b86890bc0e5ac29ae6c91bbc43130348797305f75543580a8a069b348a7bd8fc3e015230b7c1940c7f80a82b12900910dbcf0630da03f081d44c7f955d4a1172f56ecc7c5ac646696bffdf4eb6d88bdd9cc3843528b72583abb3bad02e56ef7646eed5139551cdeb
+SIG: e5a63124db1696b64140b6e9612fa9587b3eef710109398d44ba0ca63c0ebad06f0a6c8994ea34b3a2af91a89bf41ae614d7727d716fd42f8b92e1ac64fdbf03
+
+PRIV: 88fccaa96ad884d1165be71dd0c4f5f8f4421c60fbfa498bfee9b967462443bdc75cb0e0237b45b8656eea9f3d1a9d4acd01a103aa269bb24fd54122fd81f2ac
+PUB: c75cb0e0237b45b8656eea9f3d1a9d4acd01a103aa269bb24fd54122fd81f2ac
+MESSAGE: 9d0eac98556bfa8672c35705d1d61ac4d0fca19dc0d993015877857d27fd80f74acace666c563485d81e53603a6aef40875fa551cc105f2cc10b39694679cdf4a6b073bc88645fc51a36da179d3d1e3c7722454c5e73577c61aa7d148c4ba50ea46c56a1c3b3b3c470f93100494e08bc5514ac763a85483c42c7cdc27c
+SIG: 27d3a197cc9994212063bce8d799e77b6853b7355ebe369bcf1889a418a82caa3a7987a663f621defe86b3ac4ad44faeed16c9116ace28fccf915557fa779903
+
+PRIV: 670b30626fe367d8b45f43733d6f25b37eccbcb551963f0ac8b666b48041c72d65aa4c6d4ba0ab34bc75b39f09527ca6f2425f52415cdffdf2dff273f8ea612c
+PUB: 65aa4c6d4ba0ab34bc75b39f09527ca6f2425f52415cdffdf2dff273f8ea612c
+MESSAGE: d00bcca7e184d10e1f1fe420b50639e1d5deba52a751236e68c59bb4bff9802f5fc165ed42fd6d534670a7c6fb60e4307d947915a248bf2f93465c2cb44d8f453d2c015afbc8ed58818ea51726a25177930e9ea192ef4514f4bb0eb4e0f5d4ae3c46e357c81187f7ed174733fff959c3f9fae6486cfa1356a95699211de5
+SIG: 1b6b4377d2b98e0f9d24ae8dfe30e2396e2004380d3431488e5843cf8d2d7a0070ab21f8a3b51ce84d2f4ba209f739f922bebf798096693f5622873d79ae6f04
+
+PRIV: 813c4daed67a190d68bb635d73af6da74f32fdf7c48cca6e59262946b8e8c71fa2095457d7697020e2b884d95a96578c2a900a7666ac0dc7bd38f1931d7945d8
+PUB: a2095457d7697020e2b884d95a96578c2a900a7666ac0dc7bd38f1931d7945d8
+MESSAGE: ce54cb0450e689a0dbef785308b3177472fcd6d38203e58a0590b31fa253f9ea590be5368a922de88b63450102684443fb8189e601282003323b89c81e92eaef2b5ddc4a55c53fa3cfad4160248b3c286ff80d31d161b7b8dee713552b56f1507fb72eadfa89054e9d1600ac874c4b0a961004eb6d0d4bfd2ecb9c734f00ba
+SIG: b446574ff6a4bd2b572e487c4ab443ca641075168aa4e1092f71f30bdb068ce46a395efee1ee660b9fac26d54109722c15cdb791bfb87fff63c6596ad4f2270c
+
+PRIV: 8400962bb769f63868cae5a3fec8db6a9c8d3f1c846c8dceeb642b6946efa8e398be21001993a7eb1a1277ff74c15504183d25fdfcc05f0d4dea892f6e301890
+PUB: 98be21001993a7eb1a1277ff74c15504183d25fdfcc05f0d4dea892f6e301890
+MESSAGE: f7e67d982a2ff93ecda4087152b4864c943b1ba7021f5407043ccb4253d348c27b9283acb26c194fd1cbb79e6afc32ff686b55b0b3617218dcf39316b4b66b3c8c0d67267a86db8adf3750801bcf9327d4c25441b96197832b4cde0eac3ff22892a2f0bc17c2c213c02377a333e308ed271658049383b7e2e57b6b8b125512e0
+SIG: 0ad71b0025f3d9a50db338414d6d670e7799b7270a8444f6ae7f12ae7eb71bd03ffd3c4f36631f69fdcc4061468ff582ede495243ef1361a3b3295fa813ba205
+
+PRIV: 6288722035d1ea699bc7cfdf18d89625423180b683fa74639f4f30f15359cc85e17faa019572861a064e1bc571256dea1468f3a48590a89138aaa85925080cd7
+PUB: e17faa019572861a064e1bc571256dea1468f3a48590a89138aaa85925080cd7
+MESSAGE: 8b6caacac51d8949fb86acbcb1b99d859ff67c64147bc1216909dcab07ee6ef09f403863327394689dc34abc778fcb5c1f5091acf5a08f9d842211d1ae2eb40be9bb8d6679077471547a6c71ff77b519d4b7108e32bc46251c60dee8e332b6229316e6d57c22ab826ff1bc33f2b0213807c19280af110fd26ee27468201cff49cb
+SIG: 9dec92b6e89adbe8f4e1b5e93ac4fcf957de7d1970a226770ec4eda647c8e3b3dffb2731a39e16e4a0119d3662a937e560522491ec7a1696be04c076b12e3501
+
+PRIV: 13038a3a65ef32759a9cd903acb554b252de00e7cdb77bbed1970b20680ee17bb6a308e67f9b46c66499456ab5cd135cb2fe84a32eb045358626604da4122c8f
+PUB: b6a308e67f9b46c66499456ab5cd135cb2fe84a32eb045358626604da4122c8f
+MESSAGE: ddf00b4033a2a088022dabe93356432f50ddc6c6e1a659dc1a93124a4c2ffffd182765a2f56c43ea0bfd8de8015060889ae6941c3f3e255d4421a1c36201be846a2738a71f120cad598ca8527d70ff8d5a0993b55cb5153517110a41962daff42250158f2096d1ddaf7186e50298cbe51fcb429cbea411293f8a7bd9cf069fa237e4
+SIG: 5261558ecc3c98ff36351f42f504cad4a32ffda5a744560960b4c106e4492f02e20478887afee4f770f05597a7e388caceae805ae351e0e45e8e578e6a6ff20c
+
+PRIV: b9de5b063d3ca3a773f114941b2e4227c07511c0f5c06017b9c8845018f234325295243c8646e096674dda15979b322b9dd0faf27d024a0ed5771334e1179ed2
+PUB: 5295243c8646e096674dda15979b322b9dd0faf27d024a0ed5771334e1179ed2
+MESSAGE: 9493cc23896b84096046ae1053afe39499e9424254b366fe143f4da321e2dc9e4784208e12a542d899828dde7eff625a7f12416990c2841ffb095bf94c0c610e5a663918b689031ccd6b519349d04de1c212ca2a9d7abf52e1b4fd467bb665b6919ef8f91617e205565bf56647e5f8d508ea200a84467f8fa122e74bc3b9979f1174e5
+SIG: 92ba760d14d1415cfaf218ca847014088ae51ad821113a6f8630356f7ba85c005e2330f1066d0df464806052a4174610050462f3e013d702e7c77185a032580b
+
+PRIV: 8ff0297cc08842b5e67552ec2843e04353a34d74ef89b8565d97205b74ca133a0f7ef98c5ba4af984dfb77bc4e537b2b39e6273bb3e7b95fe1b7e6781952bd4a
+PUB: 0f7ef98c5ba4af984dfb77bc4e537b2b39e6273bb3e7b95fe1b7e6781952bd4a
+MESSAGE: 2bdc3a486c5e4ea62dcfec8a9d4fcf9ea9490dbcc715615d58490a72ce833fa22387ca50a0052508cf0aff1ca727f0fed46ffa7d3c8e23c5bb01d47e90ff06d3858a557d9926481579daf4384aea50e96ec615d2a3bf3c1122f1f24dd6ed98a5de421883589c213998ca5432373e68bbbe89428ca9885d0593d5e6215116b8266386452b
+SIG: 0783737f706e6ff36614f850074fca1f485f24fcde2a28af544f37abd69b7a581defd8c771b031e108d19d788c74c5f20bb3f1c21cd92be317bacd8f650b4905
+
+PRIV: 050d553d282dca3269c83c181768ec067b81c9fe0c94f2a0ebbb0c942d0fcd7c63e230b003c53a5672e832ff7f24430be223e497de840233f595a3e200c7127e
+PUB: 63e230b003c53a5672e832ff7f24430be223e497de840233f595a3e200c7127e
+MESSAGE: 15e13b8c01004f6aa5b236dbb281677f746d81e548e0aa80f0e414521521d856cd694e7c9152bb5e43776b60f6b560ed1ad3e4b390dbf3e46ef9257443f39c149e0240a02d021e1e3d7d046b26fd004eee7ca16a8059e126c74cb3f2194db47bf60465ecef5c704d2e2c75e2e50060ea2a31cb72b7b3c6b1b5ec72ab38004085281a22fe86
+SIG: 3f0e83765b31bbe8e1fb92e9678d6cde571a03ba7f1dcc1128461f708525457f4e0e2353aa2b598c063ff1bffdac916b5a2200655156904b0585577a1628560d
+
+PRIV: 69497cd7b4e868cfa0328d92bd6052d772b2767395c14595b279851a9cdd31aa5d276d626e230d18e7bcd61141cb93c90ef0f79e01321212d838ec71457b1aac
+PUB: 5d276d626e230d18e7bcd61141cb93c90ef0f79e01321212d838ec71457b1aac
+MESSAGE: 53cd080a0c61f1a093d3b3a74571c296303f363b4107edbe880b7aa9dfe44ab5d5dc5f74be9c8d876f04d754653491ab51b135fc953f71287b62ff41b67c742bd3445671a9d4f2dc174ca1b0335f78627a0dd4b30650504178039e7393638510ffe84091b57298d3ac9001c367c1452fbcb33dc54a5dc316fb2a5270764a2ac820a0b63fbdc6
+SIG: beafa58340960908e8d86e40329e3a4523fc7be770addb86e34c3772f84cd9fb338d1f3b65bfcdb09f35c6da36d1a3adf8f91f1ffd5782cc830206433a08410d
+
+PRIV: 2165a486b612bbff529cd00346964a3cb8cdcffa51dc3d524dd5adc5ac936d687ebc839a465e14f5892476e4a13b3988f83b3cd27ef79e193f86fa16f34a1ce1
+PUB: 7ebc839a465e14f5892476e4a13b3988f83b3cd27ef79e193f86fa16f34a1ce1
+MESSAGE: b728da7a36167c6085bd2d962cf63959facd95c9ad4542028afba90ec9c6c0760bdae935429c3feb3933e2f00042c672ad2cd7348d92bc33f81751e294ae9171b945b193144ef8acb9a1bd9abf0475ce0d0ac789b200c32e9c9a2736b168369ce5f97b1e8d2e7900e1a759178441f1fc430564ae129bae7857740511a668f32c0a3b077a9d8b19
+SIG: 7ec6fba56ba52460a1b4f2738689c1883dda9aaffc8bde17cb6029bdce3a0ebe2fffda55939b70bbd07fdbf6fc5cda87fed8ba58575f894a366e45e5705eea09
+
+PRIV: 1c64ad63dd147034598e128f7406ec0530746ea1c5b72ecf79e888065486fa1bbaa6bcc1c3d8d3b11ffc1587adddc58bfd96c2b992b6c6f59fcc50ccbcdd0eb9
+PUB: baa6bcc1c3d8d3b11ffc1587adddc58bfd96c2b992b6c6f59fcc50ccbcdd0eb9
+MESSAGE: 9ebd8e337893bb053ef2b9e3269df54848494f03cd63576b33e64b1080be4be015264a403fb9602bbf90ca19b241a9b66863909b9008ce1b2ffcf236efa4c2668f0f47db9ff5fa157d9cb605412be7dd8b07ea878cccae6bf50f935b86d19e1b648b69e528553a56d8afb78221ad53307b7a4ec8d2fd4861b55dc5dae8e93ef387fbbe0b4ce7f788
+SIG: 7477e54158f13b7128c0a110ca6b65f42514fb70cd5cf28a8b1cc6110ea06fcf94290da13f85a11c2351d3bbccbb4c64e0215d6d0f0099e7f27bc94e949b150b
+
+PRIV: 55abbc5dac4128134dc8c6018a213ed4b60fcc8e90cbd41db2d21eda5373e936251afaa2646926b2a371f2a09d5865b98c9a5eb6ca047cd0d8ee36e5e0416974
+PUB: 251afaa2646926b2a371f2a09d5865b98c9a5eb6ca047cd0d8ee36e5e0416974
+MESSAGE: 47010e1398ad55fabe371dd8648f768d90df4b965a3b396100b303b40a17518bed6d86b09f734ab7c10b5f3a01b53deec5f8534b70c79f3f29b284fdec486f22f44c22ccd5c6463594415267baa611f70b1b316caa1b68b5e0e99b31c5bb0ce13679a23c31a63999698164cbf37d103ba92490188be59937f123043ec786efe3d411f9b0623a6ad972
+SIG: f6a61c2e661a9eb7bde182e38ec99af985f61698a5d7fa430d16e3f1a93709b75522320de48afcc595ab209122ae0ce132cdf4b0391746e7ff341177570c8108
+
+PRIV: f2dcf4a1a0d46ddb2d72f8fdd80bbec5b7dea5913da4966c2f4d12c261f0bf98d39570a25ca59f2257f93f96600df4f63e684bf63ae8dffd914e4629c3d5095f
+PUB: d39570a25ca59f2257f93f96600df4f63e684bf63ae8dffd914e4629c3d5095f
+MESSAGE: 3b00e808fca4c11651d853d6b90f952ccf5647e102d4ee0ad7a5d181d5b4258c523cd39e3d9825298d84c8cba09f43dbba119988222c76059caf17b4bf9931c45e617448aeade151181497b24552367e52bc45ac79088806d3368207aafefd3057845dce819d5aaaa77b218e2aed3da76d40c1f07699f8172e4a5c803f7a2aceb9a47a8952e1b2f053f2
+SIG: 42882a811dad2d851885e4cbe9044708d91a86f15dfa1d66c3eb304314531f3015208c711b9bdbc5fb233951e569b59d34e415eec4b37ffd374d412c9a360d0c
+
+PRIV: 2246bfb06155859e10a748ff8f5919ad5d1daab756f01057b790d07474775f4ffa6349b62dc8c6a2feeef6ffc33ae085c649795c1c9d9898e75c13ae1625db34
+PUB: fa6349b62dc8c6a2feeef6ffc33ae085c649795c1c9d9898e75c13ae1625db34
+MESSAGE: 63ee1c7bbb15cebe1c22532d481682754bdaf58b8bc997ae30a34c9d23c33f1690c346ab0a7365ff62457424b6105f8421eca0ce3c630acfeb9a1cc416390edf4920e22b2367e9fb5d2ab25bee56da03ea55e3f57882d48b89229314d734cb83c79f4e17ee64bae6f7addbe9b525fcd03a91409a2dde907751db8cc97e08d0ea89c4d18718d26d0b897b64
+SIG: 2be4915a352f7785483046d8ae9625b8b63257af57c073691256ee076d6e1b972a101f551c705d3f96157c33b56ea049be4af4dc561cbe3c1ec5072d7f134e07
+
+PRIV: c088a3dd2cb8bd5d684db8538dc22473b6f014f64fe86af168b4bb01b90a1dd0aad615a9c28759f03d373abe666691dead8b84f9b8b50a67f8f0aa4a701580d1
+PUB: aad615a9c28759f03d373abe666691dead8b84f9b8b50a67f8f0aa4a701580d1
+MESSAGE: 74906ae05a5af8e9968b6feb498569d6345a24f9711befb136e6c3b5ed49339e59a7938b4ba1a118f169b9ace0f7842a26a645f14c0ad22ebbcda93e67e4c348efc3d9ecbb1419e6262d0436a58ea82c2202389065ccf67c4f550e45b5f6a12a6c011b2e0a30101d5c62328bbf99c8c95563a6e33bdd9cce72b1f720139c2fd3e04913146ae5bac5288e0e3e
+SIG: 3bb459d1ac575a180c1728d8b8924970492a0c8d2a378c29d1d41785c8379a58e2ba3606785e1c5da29e5527552bc6dc89a2b69c27fe51ed253a9f3b565b2700
+
+PRIV: 45667d1e7b5910979c4a328317968371c864d564a661c5cce557c9ecc61bab9eedcdf5e1a170e00c8c687e7e9c18f9893b5fe495cd2977ceb7f446c0149aa9d3
+PUB: edcdf5e1a170e00c8c687e7e9c18f9893b5fe495cd2977ceb7f446c0149aa9d3
+MESSAGE: cd66cec476c87c8dbf47ec91dac48fb5b42db1282a573e0a5cf0b91768986608e1d7ebd05f5251bcf8b47a17093229acefbd44beb21c0c0c928dd3cd3f8966ecce6910331c508ea76baf904d8c21f6c17c2c58d00afd3259b8bf794c146b12b995cddd1c4289c5be3168ebd616b384c281ce1b38a10e1807808853c681a640a009b4d2acd7934f8c6d07578161
+SIG: 6de668f1ca6f292814625289a0808020c87c89ac94f5b0508e557bdf8000a5ca808f021c9679b50ee2f320064c95a464a8439379828c3b76cfa766455e128c0b
+
+PRIV: 24897428ae6546d85b3190ebe3f1f7bf7c712528ac851a588b07d5c8f94eecd15f348fe3ea5b2c023d0af7ede60e55f91aa55199699da15a11c3791d68d710bd
+PUB: 5f348fe3ea5b2c023d0af7ede60e55f91aa55199699da15a11c3791d68d710bd
+MESSAGE: 5201d9725f1dffa1863fa4d84c301861141acdfb64be1fbfdd5b9386db20ef394099eebcfdfecc62c6268607a84d55c55cd0efdc372ecf3067343e7b0731c2685461e24b953f99949e59ba3e67ed0f0848313793962a292c459814c5e28690ec1f45171f1abab86fdd14568b00caf48581115ee5ea83b000282fbbf0c0b2a1116039a35cfa3f201422207a3d4948
+SIG: 1b5e75def49f51d6b2de008c71fc1a909bd42ca813298dce4eeef717815d7a6c078c2f3d9a3fce1ab5b3ad8ef8d45cdf2eb4901c32eea2d5e018dcf2833cad0c
+
+PRIV: 7b04aca7cf926216cb960a3890786339d0a615967680190123fda3b60c6aeb11cdbc3e70e4e8fd13d0cce2852a3b9372c3a6160cd6deaba90f9b3022f70c91f9
+PUB: cdbc3e70e4e8fd13d0cce2852a3b9372c3a6160cd6deaba90f9b3022f70c91f9
+MESSAGE: 1cb09624b1f14a0260c7f56d8c60b5fe45837114232551ef5966386e0c2b441b75cfdb8df2185785d22cf526fa9df7fd45d9d83881b66c1feee0913e238121eedbb7ab504da0bee8998016684535031991f11bfcd9b95690aad2d19bd6a9de1844ed1362302df4217230b25c0552ce277534c650cae526577f25d8b1fe9f9febca2c814670d4805b21adef852daf94
+SIG: 25d2d361751d52b4fe66ea18e4b9866bde3d121a7312fd9e28a1e295e087e3176c94c874a2e81600f24c4654f43d1b67d47b64822648590ce5ce44f3b5ddc502
+
+PRIV: ea73bf64a1a97877c3c3e7ca4644b71aaa66314c8f1b66bafaebd5edfb888bcdcaac93902e5764ade47294edd51faa14620940c668b5c1c392a6928325d4c3fd
+PUB: caac93902e5764ade47294edd51faa14620940c668b5c1c392a6928325d4c3fd
+MESSAGE: 362eec68b912852786bb4f9afff9ecf7cb28c9de6b18422a8ca940b0d7e6dcb83aa44be0afb5f1806d43f0e31d71f922f853615a26e287a27f08a04fbce3d45a0c6c311d4b7cb17e425bbeb0a6b410b5d6dbb7ac11df9850a131a691e3b60b0b214ebe044106e982433287595267b031b5d4a09262ded8934fdfdf964d868ef9a2c842f804eafddefcb71d9f16a59bf8
+SIG: bd86cb9c70a055279a86a9e64870988b8a7345c3cd2948a0fabcfb38abce3c420b4d5521618e11d2de827d9de569f6bc3be66aad40636cdaa64760ded3b7c209
+
+PRIV: b8123c116b33bad0dcbc2c4dc06a3d66850dab360cdb5a033c14895c4ee31bfbbdca151ba32c6bb31531b05fdf86c6d78c8cd1935611d5ff111a0f00635b1885
+PUB: bdca151ba32c6bb31531b05fdf86c6d78c8cd1935611d5ff111a0f00635b1885
+MESSAGE: 7970f6666634548c848bb52338817b26a4d0ca68df3d28afff207c2d028067a18e4c9543025f5b0228aa691e5088513151a94494e15d1f54210328e0df159b352c30aaa7a844f18a9f4c395dcbb3fb9fcfbed1103e0706fbf9c35fe2666848fa35dc2cf5227ebee89e7d3bcfae2721b25fdec3d3174ea7ce267a55dd61d58201e96bda303cf418edf6e32fb92f5dc1a0b1
+SIG: 9cf13eba3dcc37b8fc70ccb2327436b9f08855e726aa7ed82bd5cb7df45fdf9ec1f96afad193f47572d770444b65b74a37cc034fc514cb3f91b2d8ada5b02006
+
+PRIV: b18e1d0045995ec3d010c387ccfeb984d783af8fbb0f40fa7db126d889f6dadd77f48b59caeda77751ed138b0ec667ff50f8768c25d48309a8f386a2bad187fb
+PUB: 77f48b59caeda77751ed138b0ec667ff50f8768c25d48309a8f386a2bad187fb
+MESSAGE: 916c7d1d268fc0e77c1bef238432573c39be577bbea0998936add2b50a653171ce18a542b0b7f96c1691a3be6031522894a8634183eda38798a0c5d5d79fbd01dd04a8646d71873b77b221998a81922d8105f892316369d5224c9983372d2313c6b1f4556ea26ba49d46e8b561e0fc76633ac9766e68e21fba7edca93c4c7460376d7f3ac22ff372c18f613f2ae2e856af40
+SIG: 6bd710a368c1249923fc7a1610747403040f0cc30815a00f9ff548a896bbda0b4eb2ca19ebcf917f0f34200a9edbad3901b64ab09cc5ef7b9bcc3c40c0ff7509
+
+PRIV: 93649c63910b35718e48c590d261c48e4ef8336613f6aa077b462676b3ba882906a685898b855212ebc289915d105a4320d620d85771b8c6b15bf10a1be6e9b8
+PUB: 06a685898b855212ebc289915d105a4320d620d85771b8c6b15bf10a1be6e9b8
+MESSAGE: 2cd1a951056c9ebae1399b6bd2d82c0ae277856290d06920ac56cac8fb42435101c72aa9c08dd2d12426325562c2f0a49cd821b11b939aafa593b4095c021bcb4827b107b9664d68282888bc4a44af3e3bdc861be6af309044c3daab57b77023dc902d47ebc326f9bdd02dbc02cd540ff81b2ddf7cf679a41193dfe5f8c8ca1aaefc41ef740280d9823e30a354717c8431f5d8
+SIG: 6274f2d4f431d5affefa35e7cf584a599017193da99094ca908b75acb608d1bf981857be93a7dafb0fadb3ff0906f48a5ee950456f782c2d605b14095ba0ff0f
+
+PRIV: 1c15cbeb89362d69476a2aa4a5f3ef2089cf87286349e0dfe0e72d9e3e5a66c713a882a1064182582c211847e19b4dac59722c9ffd34826d96f33113400fac7a
+PUB: 13a882a1064182582c211847e19b4dac59722c9ffd34826d96f33113400fac7a
+MESSAGE: 091c9b9b116ae83d23d01a6295211785d446b6228dd687ddf79bd0d5a4daa8c79d2cbfc37365f1f285e361738123e34e2bcbfc664ce1253a11d9e4a7982e58cf9468e1017ea14d2cc6d0865d40fde8cb560241e96ac1617c791f0ca7c6410cadf328611b18aef333d8350ac497f0a4ae2d03fdf0e23e426d34f4514780d1474e113583541f3c043672057172618cb2059eaaed56
+SIG: 5998b2808adfdeeaebe2c3eac026d3f825f9c7f2af97ca324fbd57aac1bedff78a8ee621d037ee3ad2a712e9a009c58ea3e6f2a828f74b86da275a44a4b1e50b
+
+PRIV: 11241ffdf34ae8ab875475e94c6cc3291f0b8820dc85e20f32fc53b24ae6897809c045e4bd5137314c0ec1d031faf914910c45a4676f5a3cd8f581bcccb03c97
+PUB: 09c045e4bd5137314c0ec1d031faf914910c45a4676f5a3cd8f581bcccb03c97
+MESSAGE: 3b89deccb7023e4b2b7aff2c3951870af413a9b04dd86ac78b7c8fd887492d8dde49d8fda149edd54781ae2b508030d14416a9a38bed2b9aebbbb20250b3c931acd4e32fbeeec5a26501beab7268d144fce8951a101c4b5178166fbb5927b1dfb1e1ce90d1d123068e3f472c888fdb01fdf70e7f8de9b0adb284b7119f55354316f84ed090030f9c2662061ca48447cc0aef964126
+SIG: 72ce9f91be2e66cfc90f952595946ffc90bfce53087d49e5dd7c087f3faa8f18f2356de971e4429d985a99194b4f92ced3ef47cd7114379e0b3267a9f8b1e706
+
+PRIV: 3bdb162465eaceff98d69c86f70039c517d168aefe6bb101b4f769a86b17c972d76cb7be74328289fd1c64be747cca5bb30295dfaccd0f2e43f51703fd5d3683
+PUB: d76cb7be74328289fd1c64be747cca5bb30295dfaccd0f2e43f51703fd5d3683
+MESSAGE: fbf368feaeba87918b1b8c7b8a26832be6e7fc1cbdb8902519281a0654ec73de0bb07101a9d603f745d4ec2357aee9870cb19a56cb44fbd9c91fc34752612fbd83d6fc1a16bf8a85a215d0148e4af37d298467e5cc486b131352ce092182ce8284159a3812b30bacbff595863811bf9a30a9da494565c3ac1814430018ea0eeed39cdbca27f93140e46949db570bfa2ed4f4073f8833
+SIG: 6f1362a402063791f950984f544928e616a4ef79bbeb6854e9615aab9cdbaec483fb9a04bf22de5d97a15bda2d390483c7f61dbee07bb5141fc173b1aa47650d
+
+PRIV: d5efe51d5cd8e108bd922fc0ea126190a94628ffa53c433a518022792ddc78ef426b01cc61ff5e0e724da1d3b297f5325c18c62f64d5eb48d4a5216a8e9a4073
+PUB: 426b01cc61ff5e0e724da1d3b297f5325c18c62f64d5eb48d4a5216a8e9a4073
+MESSAGE: 9d17bcfe2dfc742f411cb53a94f359c001abf096c741f34af48679f281e7ce6bbd9e87709fc0728a563db2b9cf8ea4fbdcc344c1848e653ce970c6ce29de2ccd520300649adcddfc753971f846aac1ba42ae4528952d94980aa7c6cfa2142907647f894ae974a74d59035a73ef56a10b6612624809520190ace661c3a47095e0322efd781d50d1163598f2da32f31bc9c4f913d1b14861
+SIG: 2306f58fcd4cff2222d81b05a475532b8b19dc67e6d78ddb4205a3b7621cc5aef0b393d5d24dd96c88ccbc53a3208da323be4587d5ec067c820f0723aa44e90e
+
+PRIV: 18af89025ebfa76bd557cfb2dff148245214641fd5bda159f73da04b08e87c880c584459b9ebcccad587b272160bc60b27f4f772b4321de7723afef577edc7b4
+PUB: 0c584459b9ebcccad587b272160bc60b27f4f772b4321de7723afef577edc7b4
+MESSAGE: e82f46652ab914af535d8fb720b557ac95018d9f2a3fcce85771bb40ab14cb9a986e096f3afe5bee829dfd8b97335c536ac971a21655af16a2f8fdba183a4e18564c21492956537a419abbbbb02a4bbdc01481f5c6e658ecf3c34f011ad846f5edcd4939195df85e41303fb9a88fdfbd704396f7559a327318b952b3e60ce8ddde56378579232faf950c78e7f0b17c3b8dece36b788a8473
+SIG: 26bb0882297c2c08a752d3981145dcde55893a11df77f8aa4c19d0b9ed6e5220ed12e9fac3af13d0f0c71568f4a547d30114a6599a236806c4beee6765284408
+
+PRIV: 0c93d99815fff8fe22b9e45aa02b3e6445ce1d6bf5a65dce3da107aa1055940e4d27a47b0fc80800d84d244eebb1deb4436d97633a83e67125ad52ea01685057
+PUB: 4d27a47b0fc80800d84d244eebb1deb4436d97633a83e67125ad52ea01685057
+MESSAGE: 11e877de58c134eaf4c9f1b53c3dc451d3c055f16b09622725b279768512fe10a7adb0765b689ec21d5b6efaa19f1b9d36254df0a9367f441b26bdb90b28cbc403e5074082fa1fed58e140dac97aeaf483e2c13f3cc560abffaba05b763feedb51e60698151cf56efdf1d37d6ce0564486210f052e937f2ea26f63efa5d247ff188329bb1aa83ce3f4f35a3d7dec14599e5feb7b6d5fe4296a
+SIG: 7dc4467abcf6431adb7ccfe868eac8cd8a615a0ff65f6a9e338375b1aae3c49a126c9eba79426d1641c6b97c3e92c194e5ee4431efa2439fd450f2cd018c8700
+
+PRIV: 989e99945635192c023cc5186fc25bbaef47240775d15a56195d88cd07c3748eca0beafdf731d89301f7723c5bb7e5a1c3ff3eab27c97d711bcd76e42054bee4
+PUB: ca0beafdf731d89301f7723c5bb7e5a1c3ff3eab27c97d711bcd76e42054bee4
+MESSAGE: c48414f5c757d03c523ef3f3b8510771b0ff3b4b97de279625d349ec185a29927a66b9593ba19338c2f5e4131f1ac07ea46d2c1b6e4ab5229280b2e2bb9d140d1ef7af7b1692bf2d097b80f811adcfa95d5cbf9eee92a1641c552b4be4a0d734f0afd470b9d7f4e45778951e21fc534f200a128b96adb8373f10cecec2dac2996a062fb3c294315965a9d5d7b077c4b013c64a38429769d23eab
+SIG: aef756bfb8a7266e17d15f3f11ee50ed25be420e95a0742271ebd12294e2cb96ead083b8ff0b829d2edeb14da86e402ef25e6d4a5a7958c184ed10c176cb570b
+
+PRIV: 6bdbbe06d9f4219eea6403a357b25e561992fae0f0f614561dd86d23de415a43ed52dd1cce32d9b485e0940746421d36b9fde6cdf0211545b634044d4b3cb8f1
+PUB: ed52dd1cce32d9b485e0940746421d36b9fde6cdf0211545b634044d4b3cb8f1
+MESSAGE: 582ada13d69293e49bbd461032dfea1ca2025b52e013a33a0387fcfc5f7c0b8ec955982607fc901e1b7f636a9d371e1f91fe476bdd44856e275d67efa14238164354c231124c84de8f5b89d5a58ea6744b4d3b3d7906905233cce694a64d696f5a7024fc9033b1ce390899a3b441a48e53c7c9b30ba12e7d61f35f15e658c7cc4407e2f689ea8a55d01bf5dbacb11954754f920f09dbd48409bbb5
+SIG: 950206605b0f417c90843e2c8d8e66c828bb10b99b36eeeee8caf2e0e5484d93fe02bf533405f4bb74a50e5585fa0daef4821f0301d01b46321baa31e1f08d03
+
+PRIV: d761c8c5a9601b9145b7d051249b004107e452e563100c6c788038c9ee8adad7e6488775d6407efc7b2bca890a7fc62266fc54cdac893343b4f59a196d948898
+PUB: e6488775d6407efc7b2bca890a7fc62266fc54cdac893343b4f59a196d948898
+MESSAGE: 84ead5eabd2fd4b7c79a9a928ab8ee0a16a5fd667a057f8a254663d56daae156d1a49affb2996137b9d8b340e635732f9d2b4c60218442541e72d2b00e1ee7a73c3f67caa499fa9d070b57d076dcde96b0764723c3c659c7a00c1b78b15ccc2223890b51067fc81e23e9458ab0683ba626a53d0c3793a58a9857bb44b3bd85bb6ce53a85694e7f53cc1bd46d50eda37d81f5381b513d1f38339d291b
+SIG: 7ab78b64e6db359a2dc8302e1092ed66fa736b536253a1cd90fdb8c10efd78300225e191963599ba549cc859209df0ff61cd069b03d254e6e7d76c798440f907
+
+PRIV: c5e0c7a7bb8b7ca07bf0a05ea67eff6deebfe3714ee3e1a227f4dc8e242a2fa05135efcd9052bec57a4431caabe82680eec0a33afd59b30203b280ba12be485c
+PUB: 5135efcd9052bec57a4431caabe82680eec0a33afd59b30203b280ba12be485c
+MESSAGE: 3770a6786652c4b78a043edce07f3e204d81997c42afc22331f75a5494a826d7cb69ab4314a473721058a1839981d5b7022d0cd8670377daf3320476d25b9f559561d66ee0a709fe17361e2a52898f5753c4fb43bd0c98b368f512adc09cd927c6622676926d8c2d91a14aca32f226f70036c1c858bcffc2b59f54c1c37bf81eb52ecb3f00da602c94361b52a5afddbfd7e05036e377503050333be512
+SIG: 2e7fdeb3484d0a5e8dce94448979496b0642cabc3733a51f8c3c5c51c19ae319018da91091c2385f2f4e9a59edbca2abd0d085ee40d3f0d42061a5a9832a370c
+
+PRIV: 11bb4748d2547e6196be823c9be7aa18150c204b12ca8d73c1bd46b11a54b475efeb42da28d764966403dd300d9f9451b258ab1c80df06fe5943153f5301cccb
+PUB: efeb42da28d764966403dd300d9f9451b258ab1c80df06fe5943153f5301cccb
+MESSAGE: f4b765b258ba35b427525c7f10a46f0bccd357ec1ad52a5b139417a9d3894c512d89eb88e681b1f30aac4c115ccf36545e83f37834c82e8300cc1eb289af4375968c29c0ffefb40e156c20c0432669ac8dc0a83c13b1e855a84ad0133c40c82c87ee1e7dd4084d741c80de8a7a9f7759e843a562099c4d7df875352039ff4d3824651386c97759ff7dba52064e6d3112e080819aee8ce723a1a2aa464d8a
+SIG: 44c58da49d2365d27029d1eebb3bebf7c032d858aa07e0756b1c26a5412d22691176031341ad37d7bb7843289eb39db491584c1b2a1da2e4a2649c2293826606
+
+PRIV: 7452a00156d794edebff4adb1f7a7eec26217fef67c3d268352b2b5460a7dc255f4dc338cfbd384b5f1c14c226701446b52b1e3e2a3cba1a40ee2825080d1de6
+PUB: 5f4dc338cfbd384b5f1c14c226701446b52b1e3e2a3cba1a40ee2825080d1de6
+MESSAGE: 8c4ee2867656e33f5269414d77b42d8e4750dba93c418bacca10938cc3b570c6603d52c2344488607b2f934f6d269fcb2ad966219b1ab11472f42c672ce20592490ec5baf6a2d2fc8a3ee35374b1902fdefc7870b1b626fa46b12b6cee241f601a9b3fe4c50812e573e6752ce2c7644e3367a6a6b77758d8e4934b58af23abae8fecac25edd734030ee7cf39907e3eed8186a19a807103a9fc49d38f4c8460
+SIG: a8f9fa24a3dea1022e73f0d88b1c37d06d0f0b20bbff0ecdb4a40c86d7e475617c03570a7419d74ba0f1327096bf19f0d0cf9f51d483112f26922378682f4807
+
+PRIV: 880ef106733f04e76195eba280b3fadda0f25dcf96a6a99c8ccf842c68afdae570cee33d41c728ce7b141931e6e8524567d7601eb79f67fdcd07b9d682c650f0
+PUB: 70cee33d41c728ce7b141931e6e8524567d7601eb79f67fdcd07b9d682c650f0
+MESSAGE: f4f38d077f2b03da821bd36fde673d666e52f4832e1c0dcfeef049328acb7bd71ad2bfc49c123516e196c470df0847b3848a45a2c69bea03e2afa7e58205b63b523814fc8e242f059c69ff7e40f97be8125b70a54fdaf35aeafac79114a7b419e6bb9e70bf07adb559819600dc25e51b4b700d27ca5472a0e7cbbfd14e099faa3a72002da538cbe45d621ef0d5252ba29d83f8b3ec8389c9ceb6c6b2e8d8a20f
+SIG: ff6caedd8a468aa07d4c6e7131bbda76182ba958649376e711f44c7bbacba6077bea878ba5949cdeeef05cfd4983b0057d275ea3e18c32659468c30c47ac8f0b
+
+PRIV: a2d88f37ecc2b2c05dd6cb3159962c5f646a9815b2fb37791fc7b606e2913ed558dd67d7a15d4ca0341a4c869566cad8c4ee16e583a10b4824173b08290d92d1
+PUB: 58dd67d7a15d4ca0341a4c869566cad8c4ee16e583a10b4824173b08290d92d1
+MESSAGE: d1b87e9e886dfbbdc8ca8ab9010ecf9bbaf23f72ab3cbe769db1d43c2a474a81651c464e9fb92734634641c9485a0239b3110771e7f75e05252e4d8f4c0aa1ba08626d7e96317c20acde2ad99b23bdadfd6f17468eb402ec5eefa57b47caf972b3dd21d89f0e2989ff87d51ed2e2d639c1644e698cbe0221b8e179f3cfb04a20cb2470216a6882fb4ff799e11536cf64219f0c075176bc7cf0f6c5b7925fcd6155
+SIG: ccf2400cd673e1effd20161d7b68a5fb87c1e99d3635d78c2da1b509fac33346c069163a6c46c7826a48bbbd03b05e6e2351fa62bf89bf7ccf9a9024bd157d07
+
+PRIV: 42aafd0ae26df1e7aa0276860d752783af97280439bb23eae46e3f84caac78dedaa2350adb55dba9df7d7af5101998fe515d311c3cba3eeab9138233190c3b4e
+PUB: daa2350adb55dba9df7d7af5101998fe515d311c3cba3eeab9138233190c3b4e
+MESSAGE: 72131b80ad599b6f5ff698547d16e7499d71275e4e9b30526a5aac0b0c8b14fa4a540cfb1145fc004418bcd318c1a70e6269a3fb69baed86f363f5b8f97f569c20d4f4990e7bb4d0c39921268d636ed0554bd62acfcacd3b8e030217aafac3044c037e0f94da18c6b9a0932c3c5875d3a93fbdadcf67964eec9ec2be69b48f020f6c9874de5f8a5167b5ee024a2c2efd0cdcd2acd8c1f787814141e30b38b163175b
+SIG: 116143650b6c133d617859db2429c2913579790b2197d7b7b1b4962b328721032ceeca58b2d56439e233bb84dc525e284ff8df2bde1db4986fafd21b3d7d6a0a
+
+PRIV: b69c33b11ba67841c3d4e6f9234e35370a28b47662ac560b27c078b66ab1b0219df68e9acf67379261744db5d1e377892f2b692ed5a38b37073c04de5d226737
+PUB: 9df68e9acf67379261744db5d1e377892f2b692ed5a38b37073c04de5d226737
+MESSAGE: f9ea126d3ab21961aa2433900a3982b83e0ef86d52d13440afa4817f9b822fb582cc3932bf450d4677c9188181fe7526ad6fe5abc61d0ae759f215013c0b2b41064cb6278ba7e39e2f4c10d6cc9605b3869e169d7da42e88eb857870fe6118bb02bc08c8055f0c189b62f79fb146b4c543aa30cc0cd57f037e9ef7a63711f66e6f2878931702202702614277d513f0850b758549336b30cf40ab8bd460e60e12deed04
+SIG: 24368fee5bd848b4c661a3be4f310cfc436e79ec4a78501b81095fe51614231b6ca1ab1269996ad2e98e299781af8e29804b24fe5679ca3ba650c5c4cc58ce01
+
+PRIV: 7b63613f6dae01cdcd5e6b37686971cd8d8a99542f6329a12854a9d8ff8105ac72ec43faf34d8730177d1f0743c74c20bf72c2394b8a7d471ffe2a04ab00811c
+PUB: 72ec43faf34d8730177d1f0743c74c20bf72c2394b8a7d471ffe2a04ab00811c
+MESSAGE: 1816488f1fc83e1ed5911637dd42ba2077657dfe1ae422ad0aee59df9dd56a2763c2dd0ef61a12bb825b0dac1eda5fbb691c5ed58f3fb325050b4563a4042099982fffa5d6ed742d95823da8e1787cf746ef63b3fbb0e88a6c0beae4f7318366936b4917f507336068b194680900a7bf4a6fb69a5c387b97e31bc7f9be53c2a89e3651ce1de41b10e921b206ebf32e5621ef8081616dcd7a2059437efad014bb8e2c8221
+SIG: 76f50b2b9c2ad97bfb9499ee41928ac072da5e8bc71d0212550942332b62e70c8bfe1c722542394688decd917aec8f95353e1d72624b70ebed5d17f6c5497702
+
+PRIV: 3558d3a74395bdcba560e2c45a91960cec6cb3edbcd30e722f7f055210f37b51534f43eba403a84f25967c152d93a0175ec8293e6f4375319eadf957401fbbd2
+PUB: 534f43eba403a84f25967c152d93a0175ec8293e6f4375319eadf957401fbbd2
+MESSAGE: be75444f9ce6be1d83af622a8c478d510127db56f1de6eb8a5126522b09fdc6ca0862cec0b8b2aafa31c17a2cc477da533d276a1ae4f8e0759d6afa0b17411b5170b52f20547c72f3e88d48cb456fe625b62feb0f81317edf1ec09ece534b9f500d4e1b1bda2db21982aa95094226ee9f5b0a65da83f91121c96b3b4010ae7826c9e80636cba00f70c3c8a279b01b95294cb850f91709f4376662a580b15ac2981afe9f854
+SIG: b365b5561a13a54517cf90d88b35eb0967d6d58414b8c1547e693159e01378563654c50fb42323f09dd78ffe28056ddfa54febf44891e8a741b6a1687d728605
+
+PRIV: a35b92f244063a19bb5e3ed4d699ed2069607116d2bd08113f0d8373613f35b77ec93601864ee4995a4f7abcd3dfc101e9e7f369e63de1ae68a07aa7f075b329
+PUB: 7ec93601864ee4995a4f7abcd3dfc101e9e7f369e63de1ae68a07aa7f075b329
+MESSAGE: 65cd36dae0168d69974f95f09dd9a59db799f911e1a15b85a00893b8c9a3d48a2f58ac126bfaa0a606c05d94701d273abf7d68817f2c71b1c541795c4f6095e26c9dff803f032f75663fd1698edd97ff3a0e72e1b7c9948b08bacb5f7de502b2fea67ca2fef190d60eae92d15158da444a49d2e9d5a573e8e177e8bbf7e6c49f907136e71d2a66cb07636d48768ff417c8beccf4323181fefb3124e434049ea45dd5019e40b4
+SIG: a23dbe3757e478dbc84d3db3a933b0428cedb6b01b86d8d73f3959878dae6f0588f505cd4d39f2ab4677b64805d629652a22529825c3a91d043749fc71f03706
+
+PRIV: 72d4a564ca15499b5e4e75d8ac0f28217d32114a0c649a7c8eaadd0cc78c520bc766bd73837c4faa5215502f1efc90c003f711bbef55170091028a34493408a9
+PUB: c766bd73837c4faa5215502f1efc90c003f711bbef55170091028a34493408a9
+MESSAGE: 6c7e7b62eb244a45d78436e2970dcd6c0f7db82297a86140ea58dd22c2195adbc956d4c4ec05354b21efe24cfcfe10e17622368848180d2c4680cc215e8ceea6cce222161f1e092239253b9746f7887df2425ab5a880bdba98153be786dc838cbeca016b1d06524bd6bfba809a8bb37adab15d42415f86ec0358365ea87b8150b05441d9d49846871485caae6de359736c27189736d8f1765f3e5c5f6b92168396390bee94cfbd
+SIG: 8fc4f179330b642dd86ca9362651b83b006d8375ccef811d3c6706f91594651df2769953723046ccb9bfe66a667e0d11fc3ea2d8226234fdd5164765260f7b05
+
+PRIV: 2e5aaab298e66c2dc1d77ea7421ff895255f9d900db0450d63f9f79c1a7013cf0381f3f19045719b9e8ceb562f0e965dc07b09f371a963a281c749c2532f654a
+PUB: 0381f3f19045719b9e8ceb562f0e965dc07b09f371a963a281c749c2532f654a
+MESSAGE: 3df0e54c711e3132d7ae953deb7b66869ee531ee40b63ce693206cdb2f4bda0a2569e913ac3e6532c5d9648efd4627780fb8a31d107e033f054d19ed8b7c49dc407d2e949de25f99307221d35843f6d5eb7de5cdf41b91dbbf34cb6c9c530021014b56abc44ac2300313615608a7b4a235e99c14cef8050887032209488b9eaeaa82c09405fc75bec94dd42d6ff1b599a63ee5742f3364093ac92cabab3035822aa867ae56dcc99d
+SIG: 7c7430305b361a9e35b2780c4d4408071b2130931d39830ec8d313aafbc83a65dae19cb747d9d1c4ce3f359cc824ea8c92f66a42b8614e7848b884ac8aa4ae02
+
+PRIV: b636a02448003543db864b40b5d8d6dd9ad611624c9b0fc6890c51ea5592c7901ef360495968e56e6d3fe740b1c84c4e4490ed682deb4305afd596efb280223b
+PUB: 1ef360495968e56e6d3fe740b1c84c4e4490ed682deb4305afd596efb280223b
+MESSAGE: 4aa85aac25034f614ed44f7adcdbeeec25fcc2a9eea32ab6a8699506f7a1cad3bc892e9dce934e75b0a8cd14642b778599286cfd8f50a9e4f2edf9f9d6291a2e2979cf1806b93ed8c9a78fae199b2854a03ec406ab3f720835ee263fbbc91cb4ef0758d775fc784c7d5b251ac8937919a9e67be88c9e44cf2ec7f560269aa0f1113d91b84401db15a3c48c7dacff4939ee01babb982fb95625c6c3ad78749060551bfde8cce4fb8a29
+SIG: d4ba80300d5cb51353c03f28c44fd0a424ffe1e40d78ed7bb1133e8fe4e187505293b20a391da962c6a8ac0acec9c67226af3b6195dabe39b3662294da3e0e09
+
+PRIV: 5ca0543c71f568a00eedf50a9520f4c15b526e3fb0da816c29ea3d50b2f62a12d4a2933ce19454e331b5280100209a6ce8e569f993c2acab51dbe864c5cb2563
+PUB: d4a2933ce19454e331b5280100209a6ce8e569f993c2acab51dbe864c5cb2563
+MESSAGE: 4ef8496978d28c10abd54a26356ee55921ceb350dd4b742c4161fbeba8a1601f8ad0484b21a8cf5a294fac00ec8a6f59e3362e47bfae1e28a2e6d017c5caa75fb0f48482808037ca21476954d778ff1a0586da3ef69d6cef6d2d8df4ae7a85442a1e46c998cf407a6ad4c5463a43c248f3b6937fdbc845b60c6d85e0563cc16ba9675d364f525f669aaac95f428bb58205099f9e4a6dbbd0151fb65babe123e5393ad64026935cb488aa
+SIG: 436823eeff3edce5d8587d68e5473ef3d8dc9465b558b6e8e7cd3137eccc80b4c4e806edf13619d8e717e69f48d7061b68de02c8209be1f7ac26ba8edf606d02
+
+PRIV: 5f87117da9bbb6091c94da6b230b7d8f6de0ed2a076413b92eacdc43abbc6897aa786a146226832aa73c434b0edc2d41d2558f820ab8f87e09e6cda91072b9b6
+PUB: aa786a146226832aa73c434b0edc2d41d2558f820ab8f87e09e6cda91072b9b6
+MESSAGE: 2297c40a2e8365bae4c5f0630c50b13bdd9ad9770a5d9a9451d00874b023d25ecd468b96571b2f16dcb1b0d3d756c1f044fcddd1c51f27727a0369c9cf25bd6aa59551b5b07cf8f807d92b159198639704740fe6eda0f26dba7e75d4530b2800f03fb6aa677d84df75d68d4fbb64ad21001e3fc87b609b9c251e8ccb12bbca927447e2054e07688eb8a20521a52249e7b943bed60e6a93c01e3eb621f0460c18a690b6f6b66edc6e8743a6
+SIG: 0f19e6ea0c05f38185c01c2d6477995daf5065ba9d80173fa6bb23a774dc88b3aae879d8a62471d2d304cc3dc66278a7abcb0bb0771cd278e11e7b932e9f9b0f
+
+PRIV: b53a644c92ba2dc7108b16833f09ad5917846437225a773d32d79c97733c0a58515818c69c0e0a1706b04143842f3e9e271448fbaf3a899119c32f42566ffd33
+PUB: 515818c69c0e0a1706b04143842f3e9e271448fbaf3a899119c32f42566ffd33
+MESSAGE: 13036daaee45fcfde0c53e06d05aa9c01ea94a67e86c6c538ccb283b368daf7078d3fbab580c76ecf82b4e9660f068dcbb500b80595017c5be3c448fbd8a17d97c5643197890e167b35345bf65e75b82c8d65229f2f60aae2772581bc99c49d416bc3d78746ef830f1af944f4a6715ab4ffb01591bac2857f1a9c9d1700888780006a31607338f7af7bedf6efe0b57299ac915526fe5e1e101298708c6e61b84220afe95b53f895987456152
+SIG: 13d2cbac7976ad27f0bf669ad588efb2c91bab8507d57fb16bfea9caff2b0964e75625c4d808d7bbb78c5b464edffe4949ecfbc8b95ff6fdb1bdca2742068100
+
+PRIV: d27c9eafcf88151990bb5b2fa8443e709b5fd8d78d233803322dc86d93d9329508e0eff529776714686196d817fdf71eb5b6e8326516ef489bfe186ac5c5bf6d
+PUB: 08e0eff529776714686196d817fdf71eb5b6e8326516ef489bfe186ac5c5bf6d
+MESSAGE: 77c35bda32a5967d8b302fa7a47583ceab89c9a609a667b753155fa6996f8631d0ebedfe0ac364c77e85ba37311f0de57a0dc2c1e9e400d58b424a322e1d5771e0a9fd9502ad0232ce544f07d8c66e7c3147f8607ac6189bb69066f2fad631185f457f467eba33228ecc40e894a77b571698a9bfac841a54eac5219da99c6a9125c469a22fe81f3b951433896f19ce39b373fd7e5c7b650a5ef2365ae7510b0da5e49d7c07073cf166a98387e8
+SIG: c254e371445633137442eefe40ad4a82e69b1ebf48a685a2bc6ffbac126d228487b2e3537c97ef7410342091962e50c0cb85de7b39ceb41ac4078d40f3407106
+
+PRIV: 70213d3a79c65d6dbba542a3679635003a682af5fa58de6b0d65bfa24184901c4402fb92cc1249dd1ae1690f03b3ec4f1e9bdab0de5bfd289f10296830fd403e
+PUB: 4402fb92cc1249dd1ae1690f03b3ec4f1e9bdab0de5bfd289f10296830fd403e
+MESSAGE: cd6e1cd9c90f566de043d75d7244ecfdb38e8bde2f9a6cd5a4fdac72b5ede6af62d981918c5e610a38789274fa10e527f85fad209b76ca1c281ad5890f9c96d35de522f1ddccb539b8798a0067acdd45b6e344a5d9a97731f545ffa4b17b875c67b48e9d4c4ba72c98a4505583fdbf1e12f22b5a7a494746cc9b6c1b571906c67fcc883a9c15a3806875b659e5816b4276c3190e25cc1ac3de47bf99c49965388f54f3ef8eb569906c6008e5fbbd
+SIG: 5b6ce2774d400ecea8a808f5fd0a797ffc6116752376cd7bfa3b2cca3a84d5593f5c03ad3eec1d89532275c47b7ce2a0e9c59cc4028a8a65e5bb9097ea71c208
+
+PRIV: 5d540b3b14f0c0175c047eaf026c9070659ef13e9d28e0c5c516a428269b14eb1d2d4d551a57c6fb2b04181049d4039d575cf80c0bc6ec7033067f27309344de
+PUB: 1d2d4d551a57c6fb2b04181049d4039d575cf80c0bc6ec7033067f27309344de
+MESSAGE: e4c9e8706898cad4ac68d73c130efa04a54f8ca25919ea6bfaa54c8c720ced854c5e9509102c7b885aeddffbd1b7f2c5922583677ac9eea9a108c7e83e8871aed5a084f5440b0f391ad7ffc6bab4574af1b96770f4370e8e988e85ecb1a8d6034fc3d7f49f7422023b9dab5d0c16beab5f5d37b0a4d7de197ad87cd4ff8ce78eb12e1daf739d8b47ab380abe9093356db5b59717751a49e1948472fdacc259ffffc8c1dbae592607d4ec71cc6a8f6b
+SIG: 32527da755312889935dd5ee91b1bb117a5d377dd23ef5b7e15baffae9a54391a3fd234bdce073e098c58d05bf195b4c3cc63972383ba4b51072971aebcb620d
+
+PRIV: ca41769caf1717b4e45c93c121dc82a534fbc6ec0986662c3222d71492bd1176af3f89f6187dbcf9217750c67ef89ed47b039f9eb062ffec9df64ab52b0b45cb
+PUB: af3f89f6187dbcf9217750c67ef89ed47b039f9eb062ffec9df64ab52b0b45cb
+MESSAGE: 9de8476c5813848ab1451537841cc178002181a2182af305b12e5f7c3b1d56b22cf46ae6276d1826ec0a8c9a7d9f68083b7225bbfaefce82b3b64594052a7700f309233a79fffdfccc5c21400c91cc0e418d5141d486b5219901d6dd2447c1f7b7cf5a0879e70e1dd658d0f2ecf31ebeee11a5c74440c63b9d8b45318c3465d7ff03365edd0385edf80d4fded51f0f7533ee4099f19e93bc9d08dadcd13485db239522ffc81e2c051f8796d62e979fcf
+SIG: 5cda872f7ed6d7c90218ac10bee8e214f3b34d15d25c39255ec9e6b0177aa3cb7368d11cb8ed6ff5cf0c04281d06bc4272b8bc09c23f6f4cd5a810ddc7b9c103
+
+PRIV: fedd63ffd4cfbf618894962e121a9025eea318a80a1adf169d6490445d2e02a0542f2244bdb7d84b87e628a8e6a12f17bf74a9a6d0ea46c595dbfdc680c04b26
+PUB: 542f2244bdb7d84b87e628a8e6a12f17bf74a9a6d0ea46c595dbfdc680c04b26
+MESSAGE: 2e2ae584641be03dd48f9c618077aeaa18212a4241f0c0194ed23e370d741a3ae11a5fec3b040c16eafa4ac8d18abaa7ce8f286967337189f0495ffdd61995cde31dd8dfc3df5700b57a7a29980e9c823fee85d61451176729e72787c6109b47359b93dfd62e1e5a2d642c057242dae500a94ca1a93bc57be1ade76fe4501c0f6377ed0e9246179aecdd9946b671e8190e1ed23f966e96409b948222d8ea5839de904fc51348073b8f40edbd9b4a4b2275
+SIG: ed59d9e23dec3494b0fbc5d10cd02bab86b3eb35abbf9e4d4a926479f134583a44ce72dc4122aca377a4072b7156462b74e8df46b686698636836ef203179c07
+
+PRIV: 38f2184eaa553656ee2902706bcec4acb5af25157ca0f6a2d48de85285fa3bc07ff03fb4c82e9c15d659df424b3e73ed1d78006f3e0b79eb64d98c13aec6ba37
+PUB: 7ff03fb4c82e9c15d659df424b3e73ed1d78006f3e0b79eb64d98c13aec6ba37
+MESSAGE: c2df77c9e479f61983b6c7483ef93fb85a103b213923926523065ebff2257e85427e05cdc27582ef6c16be353a3b250372d6370eecb6c8962917eb656f2641690189d172a111051557abc2494e32cab65ed0633affe92408b55c4ed8af65e2c5e7aab887a3cc8d28c52e9e1336d0b7bb3fe2cd843e7fa1680342f8a4aafa02c4ab252f08c3d46d5f00fd01484263ee635284f6db26d6298de5b0dd238da40a8d2a93376da0302783a0e3be23d9e7f990d25b
+SIG: 4a6413c2c87f2b3856a8decbce493adeae0c69c94134707fb0f18f3049fd3e3d051abdb9d4bee253c6107c02d57ad7cc9f3101db660afac2b7981938e9564f01
+
+PRIV: 8bfca48462d2536f74b84f6af59f5d8582ff8f7ec28745d672e72eb72e79d3e99d10d275c3d3fe459f7fe2901bce389191cc8483c0f51140d9c62b08fade81bb
+PUB: 9d10d275c3d3fe459f7fe2901bce389191cc8483c0f51140d9c62b08fade81bb
+MESSAGE: 81ee4cb9c45da691dacd7dd09aff59737267bb55c3ade1ba32c17b7d0d2d0c6079c39d5fd5b29ba5f9c1762097709843eee5612bd20bc8185bf64d5c934184e13624e6f877a2a5dda15c0df62afbb97057cc91cac9a18406a0e0109cc39b2e3f812e227a4062d5ef81c92c22a7dc797c845d71eb6ea9e42ec8417fba90a96d2bb1439418330b4bb2f99c6d63d304a0e506dca9653e5de0dd56e309db1a76a0faabab163774f000088cef3d1b7a6cf661d2e1d9
+SIG: 44d77e439ef6ca5eb940c60ff8732ddc16269ea023bb2613bd447eba7fd69851226c4819ce8d44985a49f3f41ac7af33c47ffe5f89304a3256e445f8d686e307
+
+PRIV: d7480d4272bcb1557b1bbee04915c126a52ca6d6a8bb5314a0e1a52b59bfc99c99c839d36d8f5b8652618ed7b0fe9ec3d94efff4c453c540631476a5979bbbe0
+PUB: 99c839d36d8f5b8652618ed7b0fe9ec3d94efff4c453c540631476a5979bbbe0
+MESSAGE: 615cc19f942017365ba8bfa256ceccc85ee289a1c34bb1442acc0716c7fc2caeb76a9de19adec106371e47a30d2e1239ce1f7dca25526d604bdd647659d942bcbac368911349c3b946a97da10a42dbcf3c73416d2e6ba22bd29d9f705672e9e338944cef01ad21f009742e07bcd888ca31e1ee953e8c1b1fd954b7dcf1a0b1d5a069065a66cb721adc020f4efe1abdd16742746939285780d753137ae0140bb410fb6ce33676c27aeec593a88cbc73afd9f40511
+SIG: e04dc8442d352173e931818e290858de85688a4649ea3e3c3ae74edaa54ad01b64622ad8a090b6ad60adfd01881882828d39078bb5b2714fd3ea8397a342fd04
+
+PRIV: 3c2d3650735b41ef9006bb45e4be2e0aa5cde851aeac421ee9c1b492d87aa18a3e46ddce298844fcafa00a1b47eaf3de70596df1bbee3c809d1be7dd94080e34
+PUB: 3e46ddce298844fcafa00a1b47eaf3de70596df1bbee3c809d1be7dd94080e34
+MESSAGE: 1425d8d218da1a10a80b6a9c3c2750efe41657984abd5100f451ba949db01046b7126be8402334ed57528bac05622553a86b726722695a8fb331d8565417c4ff0f251a320ad06dedbb750def35d521c3c4cd571a45ada8450653d5e81fe0beb53aaae787b3eb653c2381ed55aaf2590ee5ed8b6626f1c4b0430a54f39658624e6635fefc98fee8fc3e1cc7ff3dd420de9da11a62fcae0e0cb454fc6f7df03954291d26202f1b188b657b3bae07389449b75e67422f
+SIG: 3f2af01ad5377ac39040d41a41e36e7b93fa7235b841791f432ecd7f91a3b21ab7196c883ad5a7db446f6c06672460f3f63ef863d9432be9caeabb79e87e2208
+
+PRIV: 74965996268cdc4c09220bd31ce07b217a03826ee981fa89f3a2359ced095ef14096d027c1c5ee4cbfc04b9d534174029fdb50cf5610d3021ef933b4caf33985
+PUB: 4096d027c1c5ee4cbfc04b9d534174029fdb50cf5610d3021ef933b4caf33985
+MESSAGE: 45b2f064615bf774fce97f51c464685d7b3e4fefff9231240a719b3b0621cd4ad83305675cd6eaaebff791000b0b1fa31d82d8181b7fe57c5e00cec56ff9022e9ce8db66356e408e3ee262fe627789e65535ef1a63e8fec933be3dee34d2facdb8928cc456abf2f3e8cab47eff1ca42e8b0e48d2c73e7bcc5de3f1056fc523dfef6b0023f32889ed394eeda032abf6bcaadaa7f3ee74118760ab6d91df528bdc5807972c85fa7cb56e387d7332e779e52d0dd7db0cfb
+SIG: 8c6628344317a63aca6f78cfaea965b3aa5522ce914195141c08870a1b8dacf34b79c7abc693cd9e5ebe1a2e86f0332d2048db3cbdef01687962d6df249e3800
+
+PRIV: 0abf069c08b2691c3a26f79dc8ed05cb71d220ff78f3a5c5780ae9da18e456439ef3b5cc016cc82dbdda705766aa448bd61fa1aaf1170efe9149daa9fe64a1ae
+PUB: 9ef3b5cc016cc82dbdda705766aa448bd61fa1aaf1170efe9149daa9fe64a1ae
+MESSAGE: 0d055291b2e861eae19ea0fb2069d8c9eef4f1347f3576d78411ae7c0b1c1caf31fde736dc8accacb662df76b620b62ce90b9f92c83309128621d057cf845805949088e938ddbc3d41c5e5541fec8298687ad2f79acda01aa215d25821436eac9d268716d4cd6050260cb4ef6aada4835e073a845821ff211ae2baadceb6e57f06f88345edbf93bfdf54fb74123b57c0fb4a79608d8db6740889e15733507799f7a1fd3017bcd77b28a2bb6c91ecd154e9c5a5ffa0eb62
+SIG: c7566fb3b4d8def667e040f276d3ed98d36dff460126a75b4cc2100386bb01c642f6d8de7e649be6e0818b08d77ce60f4ee5e7717a50884bdee02034ecf1cd0c
+
+PRIV: f3fd5ec5e230b6dad1ac3d3aebadc7863ff89de2a1317f424d15989a3efb0afdf99e5d5eeeaed1205cfb5c2cc4e5e9f6b4e7f64129f860104ca6244eb9feb564
+PUB: f99e5d5eeeaed1205cfb5c2cc4e5e9f6b4e7f64129f860104ca6244eb9feb564
+MESSAGE: 71f28973ed3df05945fa0bdb23e9beca651d3ee6bf9fa45ffdc6061e42fa2e8d76235f0e9e2daa65e52631fc3bead33da055bb492e4758e598a030a33b3c40b34371459b233ccc043cccc3a3cbce549e20e0b2b43305b64aec661aadba6556b17d76e3bbed62c4a4eac4f88603996752d2363c8d4a2789d128f6e959945c68c30146d194ccb6839ec65344601652c18b0074e2bc7668311697d960c7066597924d704d02a0193fafbfdf571ee0dfe414dc2f52896912bc32
+SIG: 44b0124663adb0c73aed49f73403461fcb19111b0ba17aa996566f477e37d524b0e1f107612fc52a7c767b181fbf4d629bddc08f30584dec6124c5d39d423102
+
+PRIV: 738f1310a4e08f917a0a5c1fbaf4ef72f95ee62fcded50868a3daf98856a448d42272c2c8b08470ee5dd8af8849c01b7508d3a3c65b0330e695c841d5dccb2f5
+PUB: 42272c2c8b08470ee5dd8af8849c01b7508d3a3c65b0330e695c841d5dccb2f5
+MESSAGE: f0e7ef6782d04c6943b19eb66ff6226b736e3b0940c09bb126bfc4c4ca7a5e7016c286b7bfd73aa6a79a96031bc81cb5da68cec71a6a0d39780cbe6a0cd4774d3aa06a881610444a8c9d19102294e5f635187aa6f48d11912c7094b38833028d570cb110db60625bb1bdc37affa25ea3c8f8dbfc2514f4365c62b2989a66d27c80384e74ae5fba8c1c2af9c72c4971e64fa6a1dc2517b31ea57ccb0815a7fe2da0f146caa08431d25d151662d9d26e95229d0c62823664123c
+SIG: ce1e3577b6a21016b9dd0b517baa0ccb107bc199b8bbaef68f950c8ed58013c853b4d338eedc675079ab1390462ffefa6a959b043f8b5651c6ca375ce0b4a403
+
+PRIV: 8841d22aded69c131ef5ee0a10ab0a9b77cb754ede8d257a5372726e2b499c6e715ecca63681bc6e9e31d18848902f4d96feaf43b95d008642903b1763bc9fb8
+PUB: 715ecca63681bc6e9e31d18848902f4d96feaf43b95d008642903b1763bc9fb8
+MESSAGE: 087ca6be2a950c024b3e7467fe00a7d364555d5dc6770f5ebd260642525bd3c0f965db36d7b229a57421eec64e4d991cdde59123034470553f4eb0be81ad2936c8ca26bcab4e5d79040e29798728601684a468323cf3baae4d948d0a1fd905effe16dc44642088df53f6388bc480edf4aa207d0ed161eda345712b4c00cb05fcf635ec2588785bfb8a27cdc28996a1db3e6787023393c075d83c9038fed7899c55fec307de3249c14bda49e8b895860942c36d640bb893779142
+SIG: bb2bab7003f1311be9b8c883fc4fd528adfd51a9c99db3dca8da0fca958da19a10eb22332667b1a0065d3dbc0d06269a1259b6a890484aa2143a52695f145b0a
+
+PRIV: c02135e7b65aac72f63c32bf5bef5b68c7f3b8ed56208e59e4752070e9d07095dcf600f244037a75203ae11ac316e8dbe9986f0dce23473939334bf5cea48b0d
+PUB: dcf600f244037a75203ae11ac316e8dbe9986f0dce23473939334bf5cea48b0d
+MESSAGE: 86d9491350d2566e708ed356185d610c73465b2a5c7012919958af2cf76af995230d360de400b7137170dd0835f10fcbec224ee4e42c7d1cebb7f580fea8ed6223163bacdd1923a572cbb6dc26ca8b17ade68c6d2808c4ca1eca28eae9a145f68d4079d8d59d140e958228e7e99520e342dbd7457a9159740f48bdc27b93bdabeba465cbf0c8df5ef2c0f9386eebe656f5d749d5f9147f525266910d7b80396a90be5cc188a9a945f93e753fc99bafa18ee0a6dff79bf8484898ef
+SIG: dd5cbae479eb5e229574c21ec3bed911113a57a1916d3313457515d55cc5b6e6ebc52c93f821d13988dbba8df5096d55ff9c39e7f9d561cb58930c96a7a5d60b
+
+PRIV: 154a47eba1b8c38362ea61faeb0c0ad7e61e412a3cba4688af0db2a487208b1c16de2c894a50cbd4ca90419a4ca64942cb14bd335c5d3f4a53e239c280bda725
+PUB: 16de2c894a50cbd4ca90419a4ca64942cb14bd335c5d3f4a53e239c280bda725
+MESSAGE: bf607e8b6e14d9c8acd96815af0c035ac73c4104c93786ccc1c9f859395dd781900320ebf356aa991cdc9f503fcee9f83675888a7d592002d2a54a573a96994b3fa865538c617ed8ad1ff62018288a674f449be0aab5222f74c4fd475ed6a8dfb27f45287b22b2b6c3bd15179f267d157d7d8a4159679be85b25c2bb2ba850aaed9ae3ae571be4f75836329cf36f412c1c80f1413b7661eab4a8e11b6024244fc62323ff02e38aceb1737bd474bf1e98015dbc788b027bbe217cf4e7
+SIG: f4b6eb1a8d950e887fd2f30f70a23b41871495bfa5b8a4ad3996cd9bf51eb742e07f4c4d2da4b01ab087367a50e2b65b3cef514e40d837540b8c89966485910f
+
+PRIV: d3028431ce2eef73bd940ab84ca29f13fb26436aa25e1b7bf26cb33f17fdf81763df203e2860bac4d352e722c1c91fe3776e1cbcae8553a4f19890260bf0e457
+PUB: 63df203e2860bac4d352e722c1c91fe3776e1cbcae8553a4f19890260bf0e457
+MESSAGE: 086335d61275d168eaac0540477f50d4b15f9e50b9be693921ed54a9941bc40643cda62e1d805d0250a81146bd5fe2d39e81444d21e2b21b031c111306cacbf52717f6fb4cd3416f1215f8dddcedd2f0096b0fcfa0a6cc2cde7a2bab7f1e32790b5361df3671424cc722f231bf71895bcdcb7b22ee074e8fb4a9678504e735366c172f07637b7a93149bb21f38883378a1db273fc23239e35337f9ce566d8ddf3b3133cad7f2ce81edb503ce1d27c5a657160b78dca9aeaea379be9c85
+SIG: ce9729a96c3ed28943b27839c73382ecd572960c1f9e90c5eff9dd499ff48f17d25edd1268effe41ee6a81ce48d84de513df9c41442621b2f5491e346be18c04
+
+PRIV: ee8985dc27504440a8758d4c53e4225215797a00cd8631d59bd93bc66f373d5ecd647bb065693d486589156a9fa261437534dc86f46f72d0a800399a7af010f7
+PUB: cd647bb065693d486589156a9fa261437534dc86f46f72d0a800399a7af010f7
+MESSAGE: f2220485addfebce02a833aca33381d1df917ed609950ed24f85e3b02b2b994b4d939784e332f41064c8b4a2630ab36961742aa1cffdcb08c144eeaedeafd48b5dbe96bf24350e14fd68286bc08eeaef8bc6ad9e195d1484afcd30afa8ced4848126d56c81b43c27a5dbbdec1a50c11062ce21c61d860c25a862fbb75c3bd51c8dc07636668669bbf751eacaccb3b51d2c0d4140316cfce2eb18d2908cecd5a188679bc5f5de290f548e7ebc57d41b589a24ce88ee48d97e8d0c7c769960
+SIG: 5bd60ad5e9bad9932ca9c75f231a76889ae7a8b864b91d1fcba5c5d4bfa1d92838adb974842a0710779b3e3094044909e92c7cf046ce519f4c68e8f19ec03c02
+
+PRIV: 80dfe2bf7387bad4654eb076f8dae9595163e40127f5df492dad7df04c7221c4d1783ceeb9cf8e4d07764c473fa4061b8274397103f2076d703249d758b8fbd5
+PUB: d1783ceeb9cf8e4d07764c473fa4061b8274397103f2076d703249d758b8fbd5
+MESSAGE: aa09d784bb09dc999931ebb4c00e424cefeca104818d8eaf0661f09728ad025ef47393210571f17404e9aa6d8cbd5fd88cd7dfb8e2e8a108c05de206f3408234a3b463dbe71a07d05587324524b7326ee79d3348ddbed7871b86fcb488031dc9ea93f6b8d7fda6239348a562444faf1e72d31af35443e9df53e762f3e56b48668f9784b3368ab278a48ef4546a26cfad0d0a5161698f26ee8d34fc2b3d6dfb93b009ac296f6afe487ee335eac9f02cfcae5fcbd1a16ba4e71be1b112562fc2
+SIG: 27279e3cdcb03ef557a5defc2f6c58128a6dc3f8b0385958014e709c1f61b0ae6b403576f0e454d5e4c64c173138ee4bbd5fe7b60d06c5abe23fe99ee3b46a00
+
+PRIV: da1f868542cd7cce7a5ca3fa3c24081b4d2344b21a157f0264a347132d19659dcb3a25a53f272ea813804468d6500e96a1eaf822705b7790a8ac3e98cc4e524b
+PUB: cb3a25a53f272ea813804468d6500e96a1eaf822705b7790a8ac3e98cc4e524b
+MESSAGE: c6987ef380d5d0e74196443aaa3a32356cbc02636c5a4b6d62a8114b2111bc1abddd9e44b3672c18b58d4ef591af4562e020049f8e1274688e1f8e5296d2f9252e7fc84cd1d0c58e98f0f160530aa22c871eef652e71974ce91b4a65fc25fd09fa1b6c32086e98ec708d9abcb1d9cc8e1a089ed8db2206ee9570236ad69b3de6821862fd2c70cd83a32a68b0486229553d928de48d03a104e87381964abea76683976d527c84163a12eee0a55986cf1431e9c86cba8182ca94689bacd165fbce
+SIG: 75c517ade4f08d7746305743d1a776c3c55eb5eedfdfcb5eb1d5634a1bdaf7a4b8d24187d6c8850e3ced6567a03c4c59389a4cf47114ce5473160f230546e60d
+
+PRIV: f13daec0ef33ddd133c7d244d10fd27ddb23705280ff5f1815f0f656d836fe842dc7f1367de672c51e005c74f876f982593996873acba079292734c209c2b111
+PUB: 2dc7f1367de672c51e005c74f876f982593996873acba079292734c209c2b111
+MESSAGE: ec02ff1804b2b309af3158b66272a14a3aad83c41a719846f7088ca9792af575c78913c432759f0b9a748bdc5568496e41658cc1cdb8da6c91d07c3ec2f4af504249b996aa00c0071cdfa793f82d0ec5d267262f518fc029b88e20b6201fb9e05abd3f9524c5da2fa8978ff2efd48120cf00822d1bee90df816125d8edc0cfb5de66d16be63896a412a62b031b7118ac13fe2c9faa6b1a3342f9ccf7884166cf489a84de26b5ce5b21856a3af289bc6622c0aab9f2142d393f5d4b236779dbb066
+SIG: db771833f7fdbacdab2b5cc80eed50afdf13783b7fe5e903d5dbb4c2e535316a6eef4c34f004d2b9a4e2700bd6e2acdd564c3c80cc68a303f5fb091cb4340f0a
+
+PRIV: 42dc16c57fb6f128945fa101e05bbf548ef7d97726b692fe404069cc57ccefa00a1ba5df523996f954b34ddcfabad3f3dee21a5fa7a4ce322d216bd8ccaf438c
+PUB: 0a1ba5df523996f954b34ddcfabad3f3dee21a5fa7a4ce322d216bd8ccaf438c
+MESSAGE: f2714c23a3a6fc11ad15c980b7350fc84217877661188055ff750d82c49c5fef7bc8e6aac574a1b79a3f26d16969c0f406eeab3e9e12850a55709745e30dffa62a69dfb2b64b3c1bd2bc3586e26d4eea714d2a7b71cf79fb8ffbf2aaad00ca3e4f2b6f503cc1fef2eab3656fb44f8d62a8db8ab58f394693949eea57fafecf005f6ebf1287dba4d2d623c02ea171f567e526add20709ebcab962f83d98ef668ebd01ef20488b3665e3a446fbfb13d34050942c749bb2dffc766367fd452e68e5b0c6
+SIG: c75977e83bcfe9df7292a860ed972555b5c24416fd4b7ee3285388fa5b1447608e4a347813cfe093512a7651e422e9867db7b97c0b0867f0b8c7b7f4f02c310d
+
+PRIV: 90b455c6bb9cec83e137357065339d030525d0ea7f5b923a2d5972c3c12aa37b5cef038c16bfa4b4c923a0fe70cd7f25c8bc837fdf5a7efb9d95f21b96be925a
+PUB: 5cef038c16bfa4b4c923a0fe70cd7f25c8bc837fdf5a7efb9d95f21b96be925a
+MESSAGE: c62cfdb9d21eee6be47f30727aaee51f0703789a431d32228533350217a93a18900669c95956f3f2ae90dc745a71e18340d058d16b4c6fe33b64af8dad973fe5dc02e8520705c7a8bb3ccbe1838c6c249337f9b6a4c0e1f8a4e5d103196fa79998923d0422e9d079a72cc2a8f86d659031a607d4cca0b947b3abeeeef64c28da420d05de665a5510fe55f77598ecad7faa0ac284800b53829394c4ae90be66678ff04ab46da265ae06402d8c83cad84d61a051de0260559888e779f74b72a5d71c132f
+SIG: c9345eec2c4a0aec732386494a69a3fce8b8a1be366bbed1659f131fe97cc037fb1b7c1b68b0f3023945d20090a0cd2c1553a47faec4d66fd816ce121168f309
+
+PRIV: dc185c2ba0b378dfe5dda510c32feff535ca2e8a02434b326e0158bc878e884833d6cc05a434e419280d5864a1af209a2c676814b70f72f8141ac7e0573ee63e
+PUB: 33d6cc05a434e419280d5864a1af209a2c676814b70f72f8141ac7e0573ee63e
+MESSAGE: e276b11912cca5a84bba650c172aef3a4d5f91ac722913bb891a3ab0424ab07ea709cb8bba3a3d11f82f51c2af0162a82f7219ce27b35a30507d536a930817e40f85a22a5a432b94d192c3c8911777cfdb7fe937a67502770d6d75753d3ae88229e08f1ed23b4328d862ac61863c063ea9848f8ab96a0213d7b936c48fe754836c98487859d199b3d940392716a1d569e6c0cb1ba918932cf88525e256c8abb11aaf0b454655d5db55713cebba287ae202651ac872bfc80feaa7e00d47c0be38e658f7c5
+SIG: f1e44514d2ecbcc8d1a7e84bf584ce731835e9894f88974f098d456b60718f575ef4d8062f2182504250cf83bb2af2a79b1f58a6a97bd98da467132d7bec2f05
+
+PRIV: 90721c43bc366f24bf4e8c993e138024682f1029dba35abeb0d60c7fa710021c7c63a2f13b7b220a0bb752e3800753b8b6b32669378ce131bb77a9a8d230e9ae
+PUB: 7c63a2f13b7b220a0bb752e3800753b8b6b32669378ce131bb77a9a8d230e9ae
+MESSAGE: 651c9617cac958c7edd4a5f3fedfb83dc971abfbb69a31e898cca8472ef068034a6d2376ee0e72d0a9bfee275796c3795adac8ebe1d12b66ec268f6b75fa3941154f99e223faf2cbab5b92e2b3ba7b79be7700ef9dba69253cce5356b0c4e74703cfcafdb5546850b46232675c90c02d5e426d33d60cebf0c7930182379dbb007f536163c8ddbbd3157bb2da62340133f00ae2682ec6baa6416b5a01521cc10e04695295f2e5b94c05f00383ffe954830797f6df823172532f98165fe314ab325929af8385
+SIG: d2064a6d6c99c6c3f152d2d435f24e34b5459b082ef11e944a77ff54ddf9862737ecb2ac8d54207d36c51ad41f36490a111ba80e126bfecb09def6accbdf880e
+
+PRIV: 9cec246758e412e7378b4579eafe9fac5a25d5405f9270b5d7e543414ec3d5da975a9e6a152caebb2f9dd0deb76dd922b6dc77055dda03fbae9e7c685d073aa1
+PUB: 975a9e6a152caebb2f9dd0deb76dd922b6dc77055dda03fbae9e7c685d073aa1
+MESSAGE: 17ec9bd47add6ccfbd787af0d9013e9cc979aaf850e09426d3b28edfd71296eb31ff8b21c5fe7be050f536324c3ec48850e0b508a36bb4cb7e754b327183a1b394d88a7941d1ce8dac62a5d8291874d78485e51f29ed05865a206e52ecb12c5d107d4ff96f25d3c5d181d2c4ba6463600db1cca32857fcf597cbdfb2fda2708a8aba281b43c3d28c4a4e7983361509f61a1074e6f0ad6101c7b567ee4078e9839c47f46531b729ff0efeef7c9d1a8d833d9c0f42812a34187c3a778c165c09d6459c9c7ceaa2
+SIG: 9bad1e3b1279ef658f4d071644c63ae2b7a780357e9dc426f1650ec0634dfc520f8eda9dc8f10aa7324c5942d2347ff8802bd90e95fcec313352cdae64f32a04
+
+PRIV: d1403f63202e080525843bde255eeb6b6783c1caae9d6ed00ba60805bed1941f238aea3ad6d6f27783e70516bbfcca4770366b50ed0fe6a4e966b53af121a721
+PUB: 238aea3ad6d6f27783e70516bbfcca4770366b50ed0fe6a4e966b53af121a721
+MESSAGE: c4f17d442fba4ca0df8dc1d0628d7d7f36b60b5758d7c13b80b8f97a62124d96a23b279565495a8accab5997115b13a4ba220a73957eb7930520acbbfb6f54cf68726b6450c6ffa9470b055ea262914e2bc612633f1ac3d0618a23dff188a733d76bcbcc460f52ab61e19938f9c8caaa792c208d1f6c754728905fda51d881a347a53da744d3baadc0a76c474c558680269095f9084a74471d5c09ffc29141b5bfaf4954dfacbca663d037b17ebf9559882233e5ca5a8bf75cca4fc9c5a4109f32e145f3853b17
+SIG: 8e60e73c063816795e29f5d64ece1159f1b5d5021a6f8f655e261a4d0026f5b94ff2923250499d995298480512e4126276aa4a226d015a95827b3ce692e23302
+
+PRIV: bdf6bdc31ab0b5313784483abeca6ea5e9cdc68f81b21f350d09c3907bb9b6a103627712b755e5069fb9ab8f9e899724029a7f268af9398821eeec9360c9285b
+PUB: 03627712b755e5069fb9ab8f9e899724029a7f268af9398821eeec9360c9285b
+MESSAGE: 90a66aafa5642a98e79f0d88147080167b11e4466518f195cddd8940d12ee4918d31a6d4cb77d0bf5af29983bbe5085610a79daf0c75a78ccbcffbbdab2189c394ae24e265bd8c55fd3f4098e1b175577549518e7a4dcf7452086dd1278dd58ea4c0aa690e917951ef39fcff60cbfa1e90910bab5374928d4722f702bf5ad6028ffda6541fa5ba1a3779ec78b0a95fe3850c748b6c8f42f330ec79541a52a1cf57db72df4f92ce7f748aeef1af33bc5ae0a82c89dff216f23aec168a7dbb510aa632daabcc971b3f
+SIG: 38fac603ed246f833f1c0fd4585698b0a71305eff0d14a0049b3cef073bd036dd451b3dabadaaeaea2aeaf83d395746f4e86866ada971cbe482edb0419332f0e
+
+PRIV: 57b3b14ace1cd0cd603e6328bd219ee7d9d094487fa668f28aeec02b43c909a724e6b6395f97ea0e237186d469b71923d2113adf403beeeb4a2d27909aaf3eda
+PUB: 24e6b6395f97ea0e237186d469b71923d2113adf403beeeb4a2d27909aaf3eda
+MESSAGE: b2e0dedd802eed996dbd5836bf8688b0d1201bf5442ff9bbd351aeefe1a0c21fea2b5c9fe5edee47e921099b05aedaa80367c1ce08821d783a5b64cf059c0f4335083986a5a6ecff8c84fd40e0ba5dd5e5d2f01112a84ce5cf8e0db78beb182d9139c0b0f3e0060a3fa73869e96423f170df9af1cb9c35566d87dff542223f6d439bdb54729d366aff637b0f36a5d14b15d612bd03076cc4d04c1f25b3ba84e0d1fe474e5718d1a17d5a488465662ee4c3f664b4c9274b649d78cea4e85243f3713239048a908ce3e1
+SIG: fc79fdc6d090887a61e43c6b9187b657d2e4d9cbafd6e7caeb7ebdea842825b78fb949d2c49a0cf38b6c73296d82c8ddeb1fe2d40aaddd7964da68acf8c66f0e
+
+PRIV: 018a2c3deea50ab506751f9c2adaadfd9e2192121609931684eb265e193e7f89af410bdddefc644ef12c9899ff71b9e1d0dfa3d69d8c2cd676c1916b34591cfd
+PUB: af410bdddefc644ef12c9899ff71b9e1d0dfa3d69d8c2cd676c1916b34591cfd
+MESSAGE: cf7813efac12ad1c7c7322ccbe54aa0e9a8ba4fd4345b06e4ce7a35c8b1cd5e3f7f0688533849ba2cf4c75b6f20926a1194a72df0e1b1b34456a2133112d006722fe811d5e40c4121159ded88990c0ac2bfd34f35af4f07cc402e9a381a675d03fec7ec438c4ad9d929aec8f242def023c993c9e8ba18c7428e88fde68a4711e506d7969f63c8e0bc83ff0de4e1336106c05e09d5922400e8a81bf54885667899785882b70f20dd8fb1e75f5855b765a256da4341bf23ea0ffa18aadda381816946001045669c8d04df0
+SIG: 7a44e6a31932dee6dc2d8394e29a6551d13e6c6ffdfa218fa5b998668d8439db5e05379fbfa0da5b563ed966435ae2c54e3ad16e1a9fca1f5a157a080704ab03
+
+PRIV: bea445e9b6d3f21235912cd6c42ec0577297ca20a10357880c2b846dd8e2cc77024174966221699ea4b0a37e517ff9b16598ae4d4e83bfa3ca50bc616841f595
+PUB: 024174966221699ea4b0a37e517ff9b16598ae4d4e83bfa3ca50bc616841f595
+MESSAGE: 4743c7c099ab815927b3674d0054b6de59af2811abc2cf7fde08f62929185adc238fadd5e75ae3ba0036ff565a79405b424f6552331e2789d9709ac1ecbd839aa1e91c854817597958cc4bd91d07377507c2c8d3c006cfeb6c0a6c5a50eee115e21153dd198ea0a3aff62b7075d5a461788783f050e659c572963d7a59e5afaa2b9c501f43c6ac08ab4797c4566d22b93cdf65a99a2a1d638e79f72b5f4631fe5e9e5f968f6db7a1880df51d8febc14942672f8ea6fc3a72814a44d66d148420a69000f68c330de5b80fc6
+SIG: 6964b9c5903e74e99328acef036558eecd3369150a52e2cbad4bbb97d461b3dfc6b3e8455813a4f4bdca46302e02e683ecea1820171c538e54c3de6c954aa407
+
+PRIV: 6447540ed7be0a11c2a8de793d83c6e244983db18d78ec9d75f1729c92e0fdf1391212c8edc4d334a5bec860ef0f5ebb5ec44e8bb51c0f6741998959b2b379fc
+PUB: 391212c8edc4d334a5bec860ef0f5ebb5ec44e8bb51c0f6741998959b2b379fc
+MESSAGE: a4381c7638c48799e9b5c43f67fc3aa3cbb5ec4234f37e70ccccced1627a57683d1e53f4e0883d8b462bf83f1308630368c89b491533ddb8c9a5b9e8155002fdd581a9a5be0e430b9086a6beac4720210f87b14e862d97e5cc69286786a7586723f231ef0e3e1b932dbba3a18a0cb221cb07f80e6a8e1300056c13e702b23bfb3250ec7cc864d5c7ec5786240709c56024ea6be5f7b15a4fa5555e39a744a1dc557df5b948db220b3d5745746691dacb4421641cdcc12e7ec0450293f19ec57b09cff135847aabe446a61332
+SIG: 3ab5f88e2f7276b5b6583dffba5639993a905dbf9b88ceeaaaae3335800e4a5f10f83da6d6225a8dbe99ae80075009dd508786b3975113db478e14ba101bee0f
+
+PRIV: 0c587a811add88b994458c3c808ac4e3a83afab26d4cff5c961b9df0b5c8334406783b0cdcc5028c5638bd748f0bc76f7e94d1aa2015ca948738a3500460aca0
+PUB: 06783b0cdcc5028c5638bd748f0bc76f7e94d1aa2015ca948738a3500460aca0
+MESSAGE: f56dc6b76076325b2126ed11d1f09decef9d15c31d0e90cdb1a27e089cc56329f6ec3f665eb6739ec5678b3f37ee1fb37deb9e240092b7a88fd25525acd55e294eb1046f9b1b69a847eb9ceb7b1593b9f6978ef618c15de4e059ecc3bfda3297a19c2df202adf72155cf21eabd03948df15198e8a68b0884f93ad5e36eb0983cca30e45a8b4b5fb8136fdea8a3341dd7877540a557debf7530cc33aeeef6271c3f0af6d09787e815f2f1dd25ce4d2fd09ffa9f53081b469c500da4d44180c04eb1869329cbf2d823187e831c24
+SIG: 33b4f4274f20008a721d1e8d054a2b4e95327e38bb07b33c4bee7e1ce020a442fb2627eda3b7ac93cd3ab0b12b99935a1a9233111604da4acffb5315b907120b
+
+PRIV: 66cf401a2142fcf4a8018046cf4140bca18d76ef6266e7a024757df172a5d65367d48dfd23743cc2ca40e4dfd6b8cc5d84be82dd2b1120cc476e6af6f25ecc98
+PUB: 67d48dfd23743cc2ca40e4dfd6b8cc5d84be82dd2b1120cc476e6af6f25ecc98
+MESSAGE: daa8efb3fd41f12fbc55bd60464157a26d718632d882aedb6bf98e47dd2337879e0b46452e062e6dfbff3e7bca7289e4ef6b3f41d4b03bdc2c842afe97f3029883ed45f6054dde9690649abb2b8dc28f5fe8cecf80fc1ea411bfc40bbf4fd20b218cf47ea8ee118d4d5aefa5c1bfa08a8fb1b30d6de0977cd15e50292c501f2e71ce2740ff828b8432da5a594bab5223760b64792ed3a69dd75e2829234943656513df1a17a2a067a9a8eaa64e19569f46939d34b99271ae50a47d7dbca3620c81255b0e1fd1f3cec851f1b11b35
+SIG: d6b0e80e60bc1b29ab8f74808fc460847795ccb887bac0ecaa8e135297a85097712b24b0a1fbaf7a67c5d530a47d0643fc8702c059d215fb112dbe475e5bca0d
+
+PRIV: 5dbf885aa598e895571f5f65090b72323e9d70b0f58110687afbbc383afedcacfa17eba76e3bc3ea6dab3a5b120dc5ecb9ae6f00138f7d36dda9268bc4722174
+PUB: fa17eba76e3bc3ea6dab3a5b120dc5ecb9ae6f00138f7d36dda9268bc4722174
+MESSAGE: 1e0b6cf15ce03337179c02d65408df5be9200c3782b6004af94ea4decb257999d6fdff301d11d00c98c372fac0d026cb56dfefe3def7eb99ac68d6968e17124d8446f53e8d2d3dd890d37a23c7e0b83a484b3c93bddf6c118e0281959d27bd87d37e843d5785f4a40771398494e6c4322fbb675c1d479321032148f7fe52564ddf7ae7ac269d0cd2e552fec589aeae0fb93fe3eeaef0856096cf4f6b3497e7235cc8494d810a0b46c5eac87f187e505bb7764f8045c9541983f7b025698009a23d9df0bd1a473cbee4cf5e9488ecbc
+SIG: e1429dab2e42cd035b7fc602efd6baf94706f16eaf2f8b5fed329239e875605fb172f5dd9ae2bc2eb42eb474567e292f5206e82e694bca0d6d433b867634cb0d
+
+PRIV: 84b3aedd4797a565c351de7dfa0700b9ff7c4d7291c8808d8a8ae505cdd22590d7ad72caa7c22209ec4678d11d5590a6cb28a07117fe5aef57b50751583201a5
+PUB: d7ad72caa7c22209ec4678d11d5590a6cb28a07117fe5aef57b50751583201a5
+MESSAGE: 532567ffa53b5c0fcd29c39499d2e78ecd20e63123499240e775088b394dc65c8baaa0fe8f6aa7e70181f9e10add8b4a8beb0b2ec38a43309f100cd4be91c6f48e79dc0aee93a15c9403773b354a8d42ed48d8f276230fa6de5ada501ee0a653b4458f0ecf6d5b3c33e2141c662f6ea055f741e54586917d2e0c4eb2b56621f9665fef3246f0bd800b533e3bc615c4021f8d0e2ad233a11e7736c493acc31faee76a097dc40db9efc22446eacf1cc18f51fd10236a2f942d0a53c3ce209108b5938c0a9e536b89ef0ad6b405a10f22c3
+SIG: 9220f0edaaaee1b876350dbe9266061767b86296c351d4cac99d07cd612c6efb24f8f9b0b975f95c42c5b6afedc892f87efedd39d5160294c27658bdcf42850b
+
+PRIV: 6950bfcf480b98ea18a2d5ae5ba6e7668f4c283ff2711357740ffe32cf25819a8e4c6f233f7b86321c9d6799bac28aafcd2503d7aa0a7bded8722727fbbcaeb8
+PUB: 8e4c6f233f7b86321c9d6799bac28aafcd2503d7aa0a7bded8722727fbbcaeb8
+MESSAGE: a401b922aba57ee0c6ac1c8f1b48296a8562eef137526893886a08306e2203667788618b939864467a31f16edce152a42c25546b640ea8bed189a4f89886a37f106911eae1f50081bf795e70c6504437d2a80cb839479ecbb87c129bcc5fe31d716ef978c206d7f08a793466594f4d75e215bb6374596f8e7d00eea724780943e89bd3863c951bbd24efee23c97c2c797c7fafbf8f2c8b43f37a5f881129a09573fa7a034a285e80dc4ba4bc9564a4dcedeb33167e0b30c5a00b9a109a2231cfa0012b29b2b3450b892eccef0808e503f8
+SIG: 94de5df7a25ecd70205d40bc9499fc7cd7136568060a419a93be6e318664bb6dfce60e2d4e633f7ec148fe4f834ed277c1fec4c4e2a86f44c4589c817888db00
+
+PRIV: 61b260f5b848b271ef48e5a56d297432d89f2ab85bd538fa668870d0560220e56086fe8735f399f1af2e395e0fdfb5629ebcb04b6ed4a54a9e47052c6e8191d4
+PUB: 6086fe8735f399f1af2e395e0fdfb5629ebcb04b6ed4a54a9e47052c6e8191d4
+MESSAGE: 2826295d79945f675476bc4d45ef800d80b1f0398e4be60e3de4571ed108df989f032de6c2345d9948d677927ea0b8cf1a5ca36fd5f23c25dc0d2ab5bd565a54af46fd97d338d770e3a7b47efb54c07a1664707771eb4e37d9d70ba779251dcdcd3bf6d1248adec53f787259c4d594d5fd4ced8e3db7621d4965d48298178124931a3d0cd269b2d53b7cd261b96d370c5d9693c8ad133ed58945ee3540e10625d924aeba9bdafc656100aab276fa996b1db477bf85ea559081d5b4c7307dc1595654aca82f7b6d2ddaf7357c15a4d7d8b908
+SIG: 9828fec8ff5cf85a98f450770b5bdb4b80daca44379d8f53c91c348e22df64ac48f2b6e2a7b3b642bc8193a194316229e69447ed241cd423d83b6fe7b2d44b00
+
+PRIV: 936dc1cef6a310747f350088055a39aa762d9a4b52c8c8e4c682794380c2725c03b31800412df4d56f1532c05828c0b72528a67a781bef4c06c1fb6ff2ce324b
+PUB: 03b31800412df4d56f1532c05828c0b72528a67a781bef4c06c1fb6ff2ce324b
+MESSAGE: eb58fe86c4ef349c29ae6fb04f10850e38c6823dbe64a09a5bf1e0ce600d394efa6fb96ed6a8f2c9d4bec05e6a5ebd5a1bf4d0c51db934e57b79e5c6a879d975197dbb10475f65c7f8a8c6a77a420384b5062a2740f1401740ee0f5e043aad7a2a2b4260c5d907f705edaf65b0e375dfc7b00bd660db6147f2ebe870a0ee18dc2ba3c92b0b76fae2b90932cdb6c149e46f3feecf4c26f0441f3a9e006678aecff8ccaecaeda73a18a68ac988b62e83a9bb5188aede38df77a9a164abbdd9d58e52a6caf7222389f198e85fbf966236dcdbd4c1
+SIG: 3f994b8ef528f6421c6a6a22e977ade5cee887263de38b719acd12d469bfd8c3f68e7ac07d2fae80a2092778df0b463537ad3a0551997a3d5b51f832d9c8230b
+
+PRIV: f89eed09dec551361fa46f375973d4fbfa5c5c12f1b5e5abf45cfa05ff31a3403e0efdca3919fa10d4a849cef1de428851bd08efd248594fd89cdeb9deee43b0
+PUB: 3e0efdca3919fa10d4a849cef1de428851bd08efd248594fd89cdeb9deee43b0
+MESSAGE: 4cf9773da05fd322fc147be900ef5cf256c88afdad4b08c230dfc8981fb69f476f7d45ef7c9006bc10032ba53436ac22843e0d76289cf68f9818fa64031d4b40955059aa69110915889f5e22732a1343912581ab3b11a3bae7a471359508596575f888160beef966e5708f0e3147eacfcec1caa3ef240c5e0a14c186546c8eeb64658350b1affc0cfd2ac213af670afca7bbc9dddd28a465b586e69c388cd73478d68efb322bdf86d9213011e711b2b95fefa7bb9b5939761706aa7121024906420bddf1d8800a4338d938fa137cf27e9ffc51c6
+SIG: 897e6f2797c3f326d2cdb1d2673d360631f063304580ff5b4eb43d39ad6851834c9cf891d9f0905bf8de075f7635dfca601adc0f14e7b2c76f7571bfa468ed0c
+
+PRIV: 400796ef60c5cf4084dee1801c4a1975e482e70aef961cd42e2fd5a3fa1a0fbef47da38128f2d012cc5797571d479c83e7d8a3409802f9a7d976c27067cbbe43
+PUB: f47da38128f2d012cc5797571d479c83e7d8a3409802f9a7d976c27067cbbe43
+MESSAGE: c473325e785b27df4471eefb9ebebd6461d570800181100ff36caf3c38f67c1921b157ec8e6126f955aebd90ea3fe5385f8042cd704b27cc1d6978c0e2a296695f5ef97b7c2e16ae4ff4d063c688d7f46e964e1f0a00503f357345977683d6e4c3423d56bdb6ce864b6987e085e83e70c7c1a14e0e413f592a72a71e017d505b64c24f1a1a6b813e064e6e0cf8bd4571d0ff2f267a6a13e0cd430463b6ca3b88f0cd40b0fb83d5bedf6f7d47e170e87d0a750093693eda232a6daf98125727b9588ecb894ae373bae3a445a106306469a4c2cd77ff
+SIG: 84d3aa3f361844396754d80d9fa05b8b2fa4abf3a0f36b639bee9cfb5c8530a3a9cc34677f92a913c41e800f2e8041f7666d07ed85f16a57d817b1241fc5ee04
+
+PRIV: 6703a6232c5e2e65e0ab3b92e2aaf9f5fbd33fb46988047d6f4d0ff5387fa029047cffca8b7b11ac6eacc0eaa0c5b73c75b9c637956973af9d97b2dd5b605d6f
+PUB: 047cffca8b7b11ac6eacc0eaa0c5b73c75b9c637956973af9d97b2dd5b605d6f
+MESSAGE: a26b30a769197932a3a62854968d760151612366778dc994576a2e0e0355496b46200e506948a0d102b6651b2e7334ca6c6eaef8bca44b425970a0b37d6bde0da9d3c1b9f51cbb25bc335cd6fa928a74f2c0dc2c6e99d37a12863a474d4df43aad35415ffcaa24d8c29f914572ab2abec3892db49e679c5ea220c2f519a7d033ac1a2c5a467869e30eda3d2635ca863431473f958d552bdc5582352c290d0ce4fa9cfd0ad42799c227ec90b7c9e5db9f5a7b6d569212eed94d323326805f2b3a0010d6c11eb4107c8283037652f50dc067b6dc81f4db
+SIG: cae96879e5b603be866609d4a053bfa12a51378e99b2a2812e4789267d8f32f473243f8af74b9be73f47dea50f0d165ebf49458b73e53d88580c191a182d1904
+
+PRIV: e0e72f8f178633626733bcbda2ad2a50e653890f15359b6c22fc7345ad333109d13cee540d84b5667d516fe7ec7239bf8da91546ee791f84edd8ffcf3a083e76
+PUB: d13cee540d84b5667d516fe7ec7239bf8da91546ee791f84edd8ffcf3a083e76
+MESSAGE: 791fd613c1095292c8a4a2c86b47ae026155b8465b607dbb416477ef79a297c9d7758ce34af9dcbf1c68474f30909fbe74b7ba429632f2403aad832b486b72c23054ad42f7653a9ddb456cc791f348886a7ae5dcec7c0ba815f7a93a10fe331e903b970f7b5028be49d14bc5620d63792672b98b9488c67ae16646693e112047f0ac8921ff561c92dd0596d32df0a6e507ac1b07de516c98428d570a37db9bcd7c7e61c6948ab3fe91250dd1d5bd671275df9a972f22c2ba36804747aec1ea2416c1f41ab87befde31629b2d43317ce41cda03626286c0
+SIG: 14552171b95245ac0f0e5a6e7a2f541721068db650c6dada04c28cab7c49195f6436712144cb31913c562e30c39d8a8549fb64ffea81c7445143b5f23286da05
+
+PRIV: 544dafd9960d829756c6d4b3eadd44375fe78051876bf978a381b0decaaa8096ae4f6425c1b67ccb77f9aacfea28eaef769c8cacee035205cdcd787e8d07629d
+PUB: ae4f6425c1b67ccb77f9aacfea28eaef769c8cacee035205cdcd787e8d07629d
+MESSAGE: 447fe7344cad1fae09d6a7d05f09d503c1b3d3d5dfa584810c35bc41e4955693706154e2d751b2f1b525e1a14547ba7f8b232088a6fc922702d93a11cd82949c27bed645dc351fb4c1242cf41d01575412e792aed214531d94fd66e03dd32e972fd77f6947a353e1ae5e00f5a6ca77992472f096b6e7475fe534e913a77bcb0d681fdfb3a7a0dcb56d274df4aa109d4a8a37794a9276f50006696ff12ca4d0254039df0fb3f72a960da05c9872f2e33ee81d1cf7a6f48bbce0aa18c7c0f06ba55e67689e0af587b500eab79cc7f9640bca104b7fbf31f08e
+SIG: a2ae117c8de4ca6d6fe75e466023bd550c26fedd3e74ca13adb625f272e175f14d5df550ace7d82288efefabf96311a123bee23889ad3711bff2b8087946bf0e
+
+PRIV: bfbcd867027a199978d53e359d70318fc78c7cc7bb5c7996ba797c8554f3f0f07c5ae3bab9201199dfbe74b7d1ec157125bdbaa4520f501da3f248579dc6c22d
+PUB: 7c5ae3bab9201199dfbe74b7d1ec157125bdbaa4520f501da3f248579dc6c22d
+MESSAGE: 117fae13e78777b6219f020214c1b87c57046d1c09ce82ee2b5629898d9b0de74a15cfe99f80548ba913d7036c56285a4cba493b52d2cb70d6365ace3da12b1f34a2778af36ef52ab82ede04cacaf2793f5f89831e3b205a9ee4c1d6fbdab4ba4d9fae65dd79a5fe76b4b39a3092cc7148d211e85ee82ab463d34dcee9061d9c21ded2051bbd50b413f0e21a0e48d1ffa8dcae240b3495be25d93151b57aa271ab99aa708ca28080cab4804fcefa929f5f1ef3f4c6c0fbfb40bef7ea1b509b36ba1260323512379d7bc3fdbb5d3faac9b00e21f12ea1ca2e29
+SIG: e48615b65633e61993b0aaa1fafb74b9629c384fd592bd735fa1f62c5cad11291fcd8c2e91a50bfe0b03b43502fff3a5c382b9c2821907efc34da5ba054af00e
+
+PRIV: df2df8a9d66d5638cdee09324e7b10f8ed29ab91387e3147b7dc03f7cd8005085c042e157fb7fb12d4d4fef2847141ecfb57c1253e14eaf3004d6513f52fe625
+PUB: 5c042e157fb7fb12d4d4fef2847141ecfb57c1253e14eaf3004d6513f52fe625
+MESSAGE: 21576615c9346a63dccf0c50ecbd7c6d72ad452cfed43ea73202cc7a98576056b9664b54622905a1e7221720730ac685d3bd3977ec3959d446bfa941e725b6fe16afe5432c4b4bdee7aa0fd8030948ed6fcba7c0bdb40c2e517da97456e74e1f93d5ed676de0f4a8b0aea449404bd15b6da79dc1b813965fe5572410d76f5b5eac663050570311dc9842b6fbf8806aec03151715cacf7f21802e8bf5e98a89c0d7d0d098b73c6efc09962e36b4e030c1a64b5d349f5f2042c74428671e4a2c7fea0caee2422d85c4fcddfed32213859a69955d4e3ebb7e1b2022
+SIG: 9a1074531ed43d07bffc7f2b6c13b8838fc75cba02c7d1ec7ba38bca3cef20dc9badf3a3064a2c93b1842441420b6a8d421a960d70dfb7c70eec295f21f83f0a
+
+PRIV: e8ee065f9907f1efa2daecb23a0425f353094da02bc2c931f0a587efc0d13de1c72651b7fb7ac0337a172977496fd7f2a72aea889385835e563c6b6053a32dc1
+PUB: c72651b7fb7ac0337a172977496fd7f2a72aea889385835e563c6b6053a32dc1
+MESSAGE: a2f0c1373473a305d8f1d99138b06b9a9694ffaa8a88222de9f729bee1305175dfb17001cc77f67b6d40c90c1a28fb226c11286db4a13e45e69211242bcdd01cb6e2c454e76c0cab881b4d2d9d3ab100a5d61d1725d866e4fdb66d93d77f5b308693b9b5a333e57fa25d1e5d2e38df6e4e9ec84159bbee1ffea926836a0101c91483bd5bc88a6f1cc4d4e7f008ad08453a0123429dd335781c7cbf8d685a8999ed1177607004a13c4cb5ea4908c542607d3f2cd6690cf1f2a7455bbd38f538f07a103964317efbcee37eb46931c027cf153ef86e43d78281ebd710
+SIG: a510dff42d4559a19a7bf0fe0bea53d3e1f22dfa6be55039895e12a5d07da5f2e37713ccb2eb216011628f6983f871fee286e66fff4be7582c961a1ed7568404
+
+PRIV: c72e67d8c3fec004ff618718a9099eb8ad7b06ff3b8c542a7e8b9847313475e14eb002d3cceb188c6658fec51cb479a65264ac555c75cdc2249cf1ce3defc16d
+PUB: 4eb002d3cceb188c6658fec51cb479a65264ac555c75cdc2249cf1ce3defc16d
+MESSAGE: a8f34135c0132ec95b64b0cbf51d66900143370406791fbb55f2b8ca953cc74a46e08b002fa2da21b951b8871f7a29bc6d38790afc66a329c397d9f9250bae0e30ae3426e08d8ead0179a3b313c908839192f289a3f3b6e960b4c5cebef0a09daa9c7a15c19d4ebc6fc2ac3cd02232e832b234edd7965d687bfeb758f70fa7963841b7859bb97c971bd557bc8769524ac4c6eeb3579793334b522d176bc62f86b4d5c0d4017036d2b6bd4e4384416ef8263139691a8606170d73c93d6417dcc1a08a537c9ed4400471a46f52907b46b10a8b6889dbb4647a8bbc7149
+SIG: 2d7bab8ebda7fca5bb3c25f51dc51b73e6ff6a3bb1b52acc7811a7d2595cd6fdaf730494418e2f57efdc5617b066fd7b6207680d94fb8c43d3d4740b41cb6901
+
+PRIV: 696450b557ec3c94cf1af1326475634aa81def3814ff30a02ba7f2044b59c0fe8584773c566b0eed3f43281705b575a434e47d6cf6b251b89803fef53534cb29
+PUB: 8584773c566b0eed3f43281705b575a434e47d6cf6b251b89803fef53534cb29
+MESSAGE: cc257829f30a5f90dfdbc247d42e388738b76c41ef8a82a5e0225ddf1e386d77080b3b9df86c54b85cdf2c32f367aba0c3b6bf888a5a6903529b6aeb4d5407a10180149114130228fc4356ccf366b77be89796a9e71a0c693f31e584a4f143097ba370363b67b2f2e2fd8d6fe8b4e8dbf0d7dcc1a8360041158aa2aff7e2a325b8e518f193a28bae05e3d52b26621af402026d7f250e86dcee301a58b631eadf4527e958f02a61587f0bb516cefac009fe51052fff53336dbd94e7266d3b43caba8a1b38e5d871c2a24a4c412fff3f7a9a52a8ab23bac9791b2b5a669a
+SIG: ce8b0a5779f4f5f401e84d65927a0c28df829e95d09bfa97111b8700078ff894cf7277e34a716144d55306fc9e2f64cd287583cc8003be0e8faf26af7640140e
+
+PRIV: a8dd35f054fb6ff6f0ab094a0d3d1c262832181df35ccd5192545ebd6a9cf529ca412338d3814b886d964b71925e1aabb3ffd07834dbe7dc512568882b53e4a3
+PUB: ca412338d3814b886d964b71925e1aabb3ffd07834dbe7dc512568882b53e4a3
+MESSAGE: 55a7ad9132d63ac161e7adb132b9189fdd84c361c1e4f5419a6df73df4d7aeb29a8dc4bf01490d4f484e2d12077517f5fc7ad0bdeda20a6cb0227942290b08c3fe33ab9b2135bc38a6579a54bd982f7d1417ce867117aea918dbd3dd476e7eb5b5d3c3e48a864a2f942a31501aa2b29b53b80513c95d6a411844f0dedf16a29ac267d331e53bdc2539bfcf32dc9b5d640f1231e2cafb0ae94bb5189426863364262efb47b5b5ccdbbc93324216a799b6f50d3704f15ed59af6cc7d910cf062d1be632dca5df213d487d8564f2b2bd7d818bba27c364013d92d7f72625462
+SIG: fa709fbc8382af83d11812618dfaca452eab83e4c53fe9e5858467d07b6767e17975c1e06393d6dde15a34d9473d1cf4d6d8c2d57394520080fac4e43448be07
+
+PRIV: ae1d2c6b171be24c2e413d364dcda97fa476aaf9123d3366b0be03a142fe6e7dd437f57542c681dd543487408ec7a44bd42a5fd545ce2f4c8297d67bb0b3aa7b
+PUB: d437f57542c681dd543487408ec7a44bd42a5fd545ce2f4c8297d67bb0b3aa7b
+MESSAGE: 9e6c2fc76e30f17cd8b498845da44f22d55bec150c6130b411c6339d14b39969ab1033be687569a991a06f70b2a8a6931a777b0e4be6723cd75e5aa7532813ef50b3d37271640fa2fb287c0355257641ea935c851c0b6ac68be72c88dfc5856fb53543fb377b0dbf64808afcc4274aa456855ad28f61267a419bc72166b9ca73cd3bb79bf7dd259baa75911440974b68e8ba95a78cbbe1cb6ad807a33a1cce2f406ff7bcbd058b44a311b38ab4d4e61416c4a74d883d6a6a794abd9cf1c039028bf1b20e3d4990aae86f32bf06cd8349a7a884cce0165e36a0640e987b9d51
+SIG: 909008f3fcfff43988aee1314b15b1822caaa8dab120bd452af494e08335b44a94c313c4b145eadd5166eaac034e29b7e6ac7941d5961fc49d260e1c4820b00e
+
+PRIV: 0265a7944baccfebf417b87ae1e6df2ff2a544ffb58225a08e092be03f02609763d327615ea0139be0740b618aff1acfa818d4b0c2cfeaf0da93cdd5245fb5a9
+PUB: 63d327615ea0139be0740b618aff1acfa818d4b0c2cfeaf0da93cdd5245fb5a9
+MESSAGE: 874ed712a2c41c26a2d9527c55233fde0a4ffb86af8e8a1dd0a820502c5a26932bf87ee0de72a8874ef2eebf83384d443f7a5f46a1233b4fb514a2469981824894f325bf86aa0fe1217153d40f3556c43a8ea9269444e149fb70e9415ae0766c565d93d1d6368f9a23a0ad76f9a09dbf79634aa97178677734d04ef1a5b3f87ce1ee9fc5a9ac4e7a72c9d7d31ec89e28a845d2e1103c15d6410ce3c723b0cc2209f698aa9fa288bbbecfd9e5f89cdcb09d3c215feb47a58b71ea70e2abead67f1b08ea6f561fb93ef05232eedabfc1c7702ab039bc465cf57e207f1093fc8208
+SIG: b6c445b7eddca5935c61708d44ea5906bd19cc54224eae3c8e46ce99f5cbbd341f26623938f5fe04070b1b02e71fbb7c78a90c0dda66cb143fab02e6a0bae306
+
+PRIV: 6bce4dfd53bfa5506f2f554d2d994a0dc40cafcdec7e1be050006e5c5a4b38a1c890023728d8397070291771e65e034d34d4aae5e247653e4ff4c074591da702
+PUB: c890023728d8397070291771e65e034d34d4aae5e247653e4ff4c074591da702
+MESSAGE: 3239190747ee33d40bf870ac9ad49d88ee320f63c05257e8ab2c60306597ce76d1f1e792ab6a65caa544fbec20892fd4960594f31b3763ef07d4982eae4a2dbf3377dcc1e3f95e46ed39b7f0222f04bb5c3b434c8f9f310de9f122a29f8241e81e206549ae628d2b8ad768972c98847c1188ad04c835356378bef79cd126869405b129fdbdc3bc489cbd1399505dadef7617b5be5da173d3e80e5838c99e349276242729e0219bd7476ae5c4f81a12878fb483a6c0e9b0df2962eb0bf00157782cf768a1b71c010169ee8522def0024ad7e45775a290639c53aaf48198c42de75c
+SIG: 99ae6782ff27646c27f61e23636ae1881521cfa5ed256f70bce7ce00b68280ce8e0c82aa765afb8b5a1ff2fe42c57441e458e443dc8b123477ae33d884888c0b
+
+PRIV: 17861a8d4154acd4fa9c8fc947c1886c11290be222872ff4f8cd25939e4d136143773f4449065eaebaf8937baf758560b0c4d2de46977839b3b873d5d7d5fd8f
+PUB: 43773f4449065eaebaf8937baf758560b0c4d2de46977839b3b873d5d7d5fd8f
+MESSAGE: 184df5ea3215ebe180390b0ff042ba2381155a038dc732f76a01c7e70f82d1ccc9de9a0596b3fee447209c992684f643df21f4cf9d179262790e8623e42472dc351997e6da189c07e1e8882c07f86c6337ec0113912cf92215c8de1982b8fc57bfabc55a3e8736f73610429d97feb51d794f505d0c5a0b3abd48ef7f55a628f90b8567a1c15ea9d190d7bf4ec2bc9334ada6cb92808dfc2064836fcfa46b96fd7a5d6f4b054dab09b73595feb89ed005b9ec9d3188121de69696d64e7c7bbdfc1c469faf148c38a7785970afe1acd06a92c99478fe44974e3bb2095e4467e9b2e996
+SIG: a5ee024ccdbdd4c21a24709ec53dccb7ee17626dd00a093d0884f5b45c4c9d1691840151c33c8aa07b69b34e16f61647ebe793ae4daa70cff48e6ab42ffdbc00
+
+PRIV: 0a84baa54f11cf17090fec61f3f9401508a3a03887aca1a7939394b1ee40a925309a73c62d23d740f2e93c18587ac15e7ec480d25ac0794e10f8cd461cc2b130
+PUB: 309a73c62d23d740f2e93c18587ac15e7ec480d25ac0794e10f8cd461cc2b130
+MESSAGE: fe70017b14678b0d3ad03e183d6f53314378379ab3da65b3511257b3d54086e86f2031139021391af9d72085ff7c3dc8c1e2d91e53333855423d0f785e2cc5f8b7799fcf1b70e6becb788e53e9020f2995ddb0c383a1f81038fc3d543ce0a38c9c288a9bc4077f4277dcc6c5642263fcfe19688005a603f57675d2434f3ed1f46d32f14eaeb073e83ee7086da2fb67659d3fb68c62320b7727b3b8ea006576bc2c7e6b5f1ecefa8b92e70c92c88951d0c12d91de801c38b7ca5a0a04b4c3429aba86386e96e06afd20d4c5c2fe2b9b4273eb05201a79273abdbeb37ed1830d226b6bdb
+SIG: 4d870bd53af8f13f214d9934ec903ac48284092cd9b162a44ccec851fa942de715ccda07b7991d712723e7a4d5b4f0374ab85ac3867e0b53ebc46b530f9fed05
+
+PRIV: 38379423dafdbf25e19d7231bddd80b4cefcfe2aed932584dfa0cc3c9f9232de597e81dcee9448b77de6829e7921c8a390535d89a0849430aed66364ee140d8b
+PUB: 597e81dcee9448b77de6829e7921c8a390535d89a0849430aed66364ee140d8b
+MESSAGE: 36125ca66668802906237e63a2fe5ae610f11a7cf92520d19e6690a3adfafd5d07a784bc1a0e185273d11d340d5eff901597dedf450c4699d43f3fb168d557f6c9c03077c3cdc370d34832ccdf2a8e3d75796490ed0242899d25ddf44bfc66f329cf4c45168703c31bc9202d890f3969ffd3ac35a12818dca751ceb8808fe81efa26a5e0d200c5ec1d94a5097ea74b6498fe288f30c48d727e9d3d35c8e12d85420702556f2861484ffd09b4f12265cc9abafeb82cf590028895a7d050ff57ccf5f28022d016ab4094b062e48b66fd36d1e19626e5215efa40fb7e3b7062f81e954830c9
+SIG: d8b50a88aed6f2a96d082213adf8b2519f6a0bbd30dd3cb0f3fd3ce1c643fc029946cd43462ed22513f1d65fca24bde3818166baa86daa798792afafe0c1a10a
+
+PRIV: f925d274aaf1fe1a21656237385e97f7783e78090c5d4217fece7057c80f426d3b0fc370be3a4b19a88ab998c59504ffb59a87606338e673df5b3fab4d9bfb8d
+PUB: 3b0fc370be3a4b19a88ab998c59504ffb59a87606338e673df5b3fab4d9bfb8d
+MESSAGE: 143caafa5f62b13e43dffa49d420fa99f771b1926d40d6cb2bbb427f27b6c266eb3deb2d8bbbd47b8214ad40251cb1907ad65eb94193e54ad85c6700b4189e80f1cc0154c63ed151a8bbbd30e01637ca58e70aa3ee52ef75d0873078a405014f786eb2d77b7f4422f927823e475e05b24245f9068a67f14f4f3cfb1eb30bfede7b3262230ced9e31361db19636b2c12fdf1b9c14510acd5bc18c0ddf7635e003503e6f71e1c365cdfb4c65ee75b4de0694af87076374d631e6c4b8e240fa51dab5e1f80ca2a06c49f42ea09e0475defb184d9cde9f58f959e64092aac8f2027e468126f2fb
+SIG: 79549a317d10a0be322a94a151ad11e77efc4836cc8006a85081273d7602a638963a9caf19c3edf1e25fad1e9d68701a71dea727da6a5c5bcac9339589224b05
+
+PRIV: 971f806be6f07d41be8830ff8dae704b08638ad6cff722d8432538127b769625af6ac98dce2078a6c73f6097bab63f205caf6953afa284d042bd50a4fce96cb4
+PUB: af6ac98dce2078a6c73f6097bab63f205caf6953afa284d042bd50a4fce96cb4
+MESSAGE: 013455d049aa54ed995fbd94e6369955495395e4438822259b1060e9a34779042a1a69211f6ea2077399dd234806ba0b353cd79a57e1c49b250ab27106dcde576ecfa115eae461febb12d2da25ffcf17b715f8d95c2f0c425d5a81f700115b70d49e1cfe49fcaa14fa205e28ec85247f1a6e7128bf3bb3060dc08464bda6538540d0ac472093e5a0720fde2f3dc4788e0e9b0dbfe2a2b5f1a0f3f80de984025b15c65af77f671e1c5e2840444de5c7eda025e6dc1a3ff16e26cc54cdeed56be73f9b01ab2b1bc16c8ef58a5b76dd47287807e5c50f0d7c0a5b8120dfde645a012c5cf11491bc
+SIG: 2037a0a7674b84ff27d0b22f62b4bac65e2dc0f5fdc899feb7800f25c29981dee641c5a50f8b9410970b49d2d53658c89ee16961dccf5391a6918f2a84eada0b
+
+PRIV: 2bb0652f8fff6901991148c68a3267877271006ae9589149bb206850cdf52fb0c03b77be983e74a234c1986496b292e139992eb7529e70b3afad7ae4fdcf8a66
+PUB: c03b77be983e74a234c1986496b292e139992eb7529e70b3afad7ae4fdcf8a66
+MESSAGE: b923ca67e396d8656fa3dbce8289a38bd3c128cefb30efc1862bb944b4507805419824ce2b83d690ef4cf107492817143bf64c024989af1a7d2e1f5ac97874f86bb0d3773ff840f514d9a1394a3959b011d3a6b816a3fae5de17b2a9ff349863d27fbbb50cca734108751000d6358ca0647a93eb49e2e7af06287d48f2c09d5c1c73e4d8f77ea2bcaa7356795b26728719bed5ffdb821578bd5d66bf92edaf8b238b2bbd7d1e2c30a787f901a33d0a76669a9c3c7f2b552ccb8349c7ded5e1a46170cf28e359e2fdd54b05a562f528c68a56974df82d466637c8e53246a7217e4386801e0e3266
+SIG: 4e158deaaec3d88941296af2d27341012b0241d4e0f46e435e375c9875e89f5e32c057b527bc3411af096a77bfceb45b983efe455e3f03155d6bc7b0acc8e60c
+
+PRIV: db9b812cb3c7c03b977f487d3d65ccd9cd2f3dee11602067dbfb72b589ff3f79ffa038ad8c3b378ce75d65844d08e3d6a92d194a1b7862e9d9720d20679b2944
+PUB: ffa038ad8c3b378ce75d65844d08e3d6a92d194a1b7862e9d9720d20679b2944
+MESSAGE: a70092c7697cd4a209567c38ba7fb71aa8f15e5827a20876923943fd6adc659c9867ac6f58a61dc7cec3d362411682000c1a9ad1295eb8b70f242d86b5865eb76b87e3f2c6941d2612ee3bcde8f19765566733152ef54e95690943285f78b375f4036585d4739deedeef6d946db61ca458ef4f650da963c385e29dfdee415fe495845f55197a870f8cdeb5a010ba6bbb32bf1a588cc774d4890184c4b2924a5b8073313bce226585f1adfc229c90bc6cc9d212e62f05d33bedac961d77cf8c2620e451de817f8c1bb16a2c59ff804b635a73a8cf8c181b3f9401c3b643d18a2f706ea9cae47071a6
+SIG: a628a77421b2abab576eed35d2ee3d14561b21fa14a6e2fac263c3eadd79f2fc0669f9429b910b8422b4b29ac026a42e98d181be3507c5ed7c748a1fdcf1d807
+
+PRIV: ce379bbe2fa8abcba51c7a7543de5b7180771b3c44bc6b41892e7b88979bab907f3cff89f41babf4fa64cba33a5bb17f413bbf2a1e112b50a8e9b1f821d849bf
+PUB: 7f3cff89f41babf4fa64cba33a5bb17f413bbf2a1e112b50a8e9b1f821d849bf
+MESSAGE: 001a74f095c814d3beed67a8d15fc18efe235dc3f6457812a4039b7a46fe9a0e9de81a7a4e5fbab5ebe9e1e4801bd11b45c9f7ad0636a09bff42164be5749a04c02f0ab61f0ecfdfef799b827da6a274c8d3b39f2e3805a6791287eedb2314d3f842b558b9b489afe1ed37bbbcfc5e60a431d5ac60b39e946d903d6bf6b140e12c7e07f9ed7ac46a3999c6245c8ab1bdb21879a317a3dcd257a5c4f349b7f59e4e43d62d9f1cd16f518f1ca6cad37e2cb20f2598c4134291c6b8a98aae5247e26eefb76aa38c9c8231c17e9dbf271cec80fba5b4a834bd9be81ea841637aa9cdd4c4bf26d7ad24ca3c
+SIG: da98dfb189385b2c853b6cf375738046a8f27ef27974abcecea1db02989b951fe433a6ce1e225b3fa82032fe060a7d3f6c183fd1157f791a064b407650571600
+
+PRIV: 2b2ee809d647023e7b77fc541f44875a35fa941d37f7c5b21fd34934d23919352c29d53e1bf2c7879d73d20ba88ca07a0b216d7f6d05d93663a65c3d9e10633a
+PUB: 2c29d53e1bf2c7879d73d20ba88ca07a0b216d7f6d05d93663a65c3d9e10633a
+MESSAGE: c4147d64ebfda41a1be5977262958104e940c3876bcd5b6956acfdec32c660914d62623c210663cb2cbe6249d7f5274991c60e950e8e2809049953c69581d2469f4fe982c7434fedd9d4e00ae08896d62cc1fb984dd233150cc2483e159cff4097df8c036bb633003abbfbe18c8fa79b5a22270838123fc9be39b8892c80384a385028c1a81ec58c8f21060e78afd2c04bfd2d30ca3977c6edad518cc1e2004cdc14bf3d15f5f528e5af277fa182275870e5c012f5f82fb1afd04edde4578ddd2160a1a3dbc050e80bdd811bc88ead79bf93f010cd0fd4433d0bc348dacfd0947cceda62bfa49711d013
+SIG: 12d90685775572c9eabc9be2574ca9ae66f0e652e578b21736cd6e654f7c6b1545883d56bf760ccfc3cf87544e0004c798061257e130030cb997a788369a9a05
+
+PRIV: 4ea18d6b4af8053b885ec188be48deb86ffb2a69a4cec86637bbd7b41b807c46e5986059976233ed77382c3d9959f34e317962696553e86ed1e5902c4bedd167
+PUB: e5986059976233ed77382c3d9959f34e317962696553e86ed1e5902c4bedd167
+MESSAGE: e9c89a1a1119373206ce40ede3b89a82f89462a1dee9e789e9845eec21f571c0faefd430ad338e4a72c047a39a4259580387fb9aacaddc36a2b51e7b60a87ca1321ff806794cd6dd4549a4df45c2dae3e539c4d7d06b6e6e9f466ffca2fa4978ce3dc792e44a6283880cd138a75a226f985da41ffdc0e32a5a85c85fe9a43ae78fcfe57f4dd7540a6dd3924a49ab39eb69950d421151d96b1e4fd3935890f634cd52a73a755f5c2fb72f9cd5a2e67ea930915e133b47cf6b7c10a9d889c6af6b5f1f4f51094d27fbba228ac2268b344027fd49e426343cc0134399b4b510aaea50234df42c37fa1c4f4d0e
+SIG: 27570c002a487d000ca3928b83cb4319722c46dfb4cca260de790ec0e3c1932688f87362952818b54f51bc7aeeb263f960bc0da8964bf312ef93e81f06c80b04
+
+PRIV: fc1b75d17d3807217351d2aa40d9b04f525b89ed3f5fcdb311bec2aec5cb7ece55e484e774a4392a9d6eeff835a8fbb232cf6276a89c74fc0d1bb2045a8b21be
+PUB: 55e484e774a4392a9d6eeff835a8fbb232cf6276a89c74fc0d1bb2045a8b21be
+MESSAGE: d031bd11da308097e3beb6ffdb2600ee6a193ca6d8324501c972b1a25166fa7a369f5bc882ea45612cf02580254d21b40b0363237e835dae2656c1b7f4736e88be53d6b119c07f5729bbd82f67de03588322879243c5990a7e61f56907b24171a57cbb0bbefba2316277af9326f9cbf3538bcbf6780be41825a2ca774b41bdb1cd5c608851ec2339eb2f4feeddaa891a6326b29d97d7fbf311e3bb749c5d4c058dcc14f452f9334991e271c16d6508c818633927f429804ca7a38170f1b9f6bd73ed675e11e8c0d321fac912730b4ba2f7c428534adcaa4dad314c55807e6c642d494c6b2f0e8cd129775cc0
+SIG: 9a68d151fea3909893359e60b96b68b2a3e2946f2b47b875398a1e39eb01463d35eae7d976f833a762b51f2726ee0dccad5ce3600564fd9dd58c23807fdffd05
+
+PRIV: 0d0bf4d42ef810b179eb841771de6dbde76361caf894e42a14b1e09787ea3e067171510b43fc17efa80b15e320b1b0a408332542e0d36e4ab9a649cd941b5aed
+PUB: 7171510b43fc17efa80b15e320b1b0a408332542e0d36e4ab9a649cd941b5aed
+MESSAGE: 8e2179975d0a8e5a69fe875a3cb1e79aec49c3853e30dd0320fe3ebfb638b82f89ad1643036b37e56e0b55e0a9e22a4e283d7a27485ce9102db6787d6628b77913e10896774e495c26e8bab26e7f9a94d29aaa36aec9c26ad3f50e5d8c0b7698bb5f01b876d0d65fcf5e9e32cd7b89829ed05b0b8f63a93858985bc9569fce429fd37a211abed650f585c3b55900443b6c5d6e8a48ba67deeed07b76e969fc88430fce2709c0bb5ce926ab7f44e0cd79f4ec359ef76748883fcc3d026edd06c8b9cba54b990d30aa41f1448a10893fb0539280c599d42361433a34cdafd8ebdd92efb9c38a36daf4c74060c696
+SIG: 24446bdf03416a4d08614466fb851db50e91a623cacd1b0b35660f3cf933200e15308708da3499a5ad25f0f0306b7942762e20a765b7ca9b901c750b3a95320a
+
+PRIV: 57b5194d26abe4ab2116c0f03d23dbe116d48825a25e77d64648b43692ae25bf499c02dbad2a4eab3b6ff1aba3944b91c3f273a382c548a6f3a19c83f0a86724
+PUB: 499c02dbad2a4eab3b6ff1aba3944b91c3f273a382c548a6f3a19c83f0a86724
+MESSAGE: b4813c9d13215fe9f63a78ff7ac95173eb810b4613f0f48d6876b2bd3b2c72bc7d98cb1ac32bc41ca47f09896f79204ecfb8264ce8f3c3e76dc124da8ddc6e0dfc1e13b5a529f20c82613fb9a82e5f5d77326a861faedabc7325c59af33dae6744025e649774fc4f79134bf9f6e3d5875dd91bc8a14cc36a66283d01d8d108c13327eca53057ba50bf210c19f139de6494982646198a1246c271b0a368c10aab95cd8961235d742df4545be68bd010dc0db23b673e623609e420ee76b1056c520f9ce8fbe8ee1863df97d17b7174636c3a2b612295091948810d1d4b8a5843760a2887dc55ef512af041ec54fad3
+SIG: 4c7345960c8fd48a7dead71dbd61908468efa865a135568c8f9ca0055483468617a7e335840f57c6cd8f2c9805cd47a9d7cdfde53da8ef4f1adbb6f698aaf100
+
+PRIV: 068d27b21e2acfcc19c3e9673dd44142d98aacae894930e20ca067439e749a79e22ddd396f955bb90e284776aa76e921e50699d0ca8914a9b7b841eb5ff47d6d
+PUB: e22ddd396f955bb90e284776aa76e921e50699d0ca8914a9b7b841eb5ff47d6d
+MESSAGE: 1c6815423d1a2c5ebe8828d1646527c17b2006e547f016b5350f010d79b13df4fb8c6ed57ba9c26c3cb0e0a64178b650a3ea5444a4fad5b20a3eb8caa702634011cf7892a0727b6e8150b0770429a37a8a0bb3a7edb891a7c90240bc0360b14e6dd770a990b31b31f33ddbf653988f82742e5eec31b27368eb0e4f1ecf4d676f49214a520d1e5b2bbb59ac2e13267e07a0cbacbed9f94d7473ed697828b0928fcc616ee02e51fcd8db4d8f7533b7b139a05e06f9e0eae32993e3025aef0590b3fbb4292a3ac40765e8584ead00266acdcbdde1457a03b7d57bd5c9e64fb06b64a50f35f0a1ec34b6ddbde767b96ffd
+SIG: 0c173c488ad001cbb9c43d7b30a7c071a2fdb08cf7f37daf71d7ae7128dc0d43f0f095b2929c54b773ed4a1f0bf0dc4f364f0601e8d5ae062f5b78c05bfbc702
+
+PRIV: a34d52563159e0723e9f3fd133bd96e20adae623f8c798013bc36b441489bdc21fb658e645de6d3efdb083a73fbd592fcd4b800e03c7bd681aeae6576bfbbe2f
+PUB: 1fb658e645de6d3efdb083a73fbd592fcd4b800e03c7bd681aeae6576bfbbe2f
+MESSAGE: 1d215f85c089f35f307a746c66c7c1e41d6ba37730d759e6e5622d6c6a198e40f63d37873b715df7518b3c6bb5e95a467726b97c9a0f8f5dfcdbfd1e0de357661ddeab555042b945fd899fad6d382d7917da9e12dfbda0d69900b3975165a73d0ac9de01fd3048b8fe5f0b90be67e03dc22f653a0a13eb4b0b753f3f3bbf787369ebd8bf5e00eb78bf0b3515a91e68b1d5fc6920bf4f4259f8a730efc7f1016d501ef6fb7cb8366fc8e716cfa50ea8b203cca1a316707e0b0fc57eafce82d62f7ff3ae04ac8fd041b55b19a352a69e6d4b79d0e650175168e34fa3358eac816cecf2c8dd1bf2a589113e91bb818f91f8
+SIG: 5fab5a7140d47873684305aa6353d3862f5fc13e54a40c9563cceac8f74008c6c445631fa864e0f1c345b5954f80056aeba25662b78827b5e8e3a9437813720f
+
+PRIV: 58dfe768bf52118494b29975154cf452bd9746dc7de1d6bcd18ee6a05acfd8580f1476c6cc2a1b4764af75805e77341f14a0d8b09c6a5b2ea287fd517c3fa6b9
+PUB: 0f1476c6cc2a1b4764af75805e77341f14a0d8b09c6a5b2ea287fd517c3fa6b9
+MESSAGE: 609794201c4f6faf488790d61dbff3f41b328c5b0695cbe9aa8a136d72b4977b21b500f216e9f32168ada8c13bff25327647e30d8a244d74d88303abc90b7f71aa07ca04d17bc8a0167d6e63fb88baa1dab81d50f1e91f46f5af77f2e8408b826336a35052efffdf4af79596af1bb2259f83c1bc109cfdc3dd50fd96d310f27ea4c6c7690f21815ea92bd79389680cfe3ed40c80181190688d24222d9a1ed52ce6a16b41dbd9107eb6d2e3594e4494d75dd7c089e3b26ffd00d1003c92c4c39ae5382ef9291491a880ca4ec3ac2b86e66719b92b6f7cea2cb0bbb1cf624d0d1abeae556e5f73909dd546277037ec972fd4
+SIG: 977137a38af44f4b262abff7e07282433c58926d562fbc6180bde6cd9497861fb6d955cf383d999fa1037b8b1754ce888c9ffc1560a451d0e9db8d74d2940604
+
+PRIV: 5a63ef9bd7dbf0e89fef155983659e8a0a6ca002bc42fad5a45af8e0281923f4e632f4dc994231cc1790c21afadaa977a589b0eb0da19fcb2792911b15ecf8af
+PUB: e632f4dc994231cc1790c21afadaa977a589b0eb0da19fcb2792911b15ecf8af
+MESSAGE: 796bc8361c6e8eec39838b24f53971e820f82361e0510eb4def1db2512387d6bf35bbdfa318879209435d6887b1410b3ebc1455f91f985e0fab1ce1c505c455576bca03539d048ad3a0ed1f11c73bac6809e2ea147975bee27c65261aca117df0fae7008e2c3c130bec5533ab89351c2140c9d1a62bdf688629787f954e1c610cbb75edb86209d7c357cd06ef41931dd5dfd1c7d407fa4ee1ef29393beab5713173802cce2d56229cfa76b601662c4d9a84a4936c52abb1981378b717eb55cb604a68d34f03b219f32226ca0e669348a2d8d2453930eb6e9c2bf66fa4e92c75136e148cdb034130d3f646382e1c71579ac70
+SIG: 75461f99650c0368058113a15ba16bd2337b2e633da38112878c4834fac9ba2e307c866c02af79bea33659614cbb4465c57ec3effd4c478ae38a34a05cf1ed07
+
+PRIV: 8b2f06141e401163f90f674b04dc90dcb6dd3386419339662ecb0dffadf2500b54da934a659119198553fd4566b660d8d610adc3290cb84829c894148cf3f67e
+PUB: 54da934a659119198553fd4566b660d8d610adc3290cb84829c894148cf3f67e
+MESSAGE: 1deb25d43458690323a7d26a26695090993474f467c6fde5ddb34da945be3cea2f6b75652ae21cbc4fd22763a1b45583e1c3e88bbb5fea2049b7336c91159988c01526824ca3bef16b362b9202b8b9754185bd61bea8f539aadf4a1ab135fbc31d2a8e33178073106cbbc02d4cd0d3c8feaa8eb733084356251795afbd78ac3c4f8a3ba19aed755c646f35569c7a6c675b6d6918e834969aca03f71a2e72ccb17003bb75b62e852aaf58b3baea89bcd64a32eb14a6b9e10de48971e53d0e9ac99a78f42de0382ef0e80ed3cfa343f35e4a9983b9aeed986d3a57f47e5e46d40e9d677302809a2d37e4ec011f051b4d031ed600
+SIG: d68e3750dc56432397401c98ff1529db9ed48fea246dd4ed383ec74c1a463aeb784c87b1fda8bbce970fc97aa9807ddbe95d41fb022ea68c1e311654fa1da207
+
+PRIV: dc649fbb1bee0a44814d6d9e9080d5d90c1fc173ab5fefed826a74723a774e0a0214c89f3867ad2e8870e50f8c2a6254986d9c220e3338411300cd9c6404d4b1
+PUB: 0214c89f3867ad2e8870e50f8c2a6254986d9c220e3338411300cd9c6404d4b1
+MESSAGE: 328700a8ae581c1edc4e2c00c78bf4606097f9bd75aade205a243c5fd7434d6222da937e2881a2e3c574356d4d5679301da99e11cf749c27921c8caa2ab2a564d87c5df8ecf1a72b680184824f6986022e3fc98bd2a21c3455abf1154954fb30c89882947b02f35af7b1bfad05237d242e2b74832fc536196f2e59d1acd0c1db6f1943d0f6043bbd6a769083ed66ba0e05a50feb0acf72b6c16ba9af039afb7fe2a4aaeb4d06181c5a1878689e67a3f5d0ad39e794d6239a7e0a12ce820c5be60fd5f1dd79702f49d02b79755fe873f5785c72f74625cd7e2428262597d31482c2c0508801fd96319d61b91ba253a5e722f414cf
+SIG: 0e0c5e4e184375da4ef7e2a2e4888050cd84e2fe21d08e84a852db2be3fbc372c472de0954dcd1dc11aec493c569f40fc6f77f03ee524fb06ec40faa1d6cc10f
+
+PRIV: 39b8062da43e64e1676765d62c7fb8e0a99c4fd417d6f7e3319bb13044205f3b6227cefe88ea4fb27b37b5f797778bd72fdafeadccd9aeb67ad437ce08fba6a8
+PUB: 6227cefe88ea4fb27b37b5f797778bd72fdafeadccd9aeb67ad437ce08fba6a8
+MESSAGE: 740af679e3069fad059fa4825fa41c59fbd484aa649303c27c4f7a94711c5b713b2a6b8987859e2271a6a71eb0b4a15abde4f5168f6cb9dbdc6a27a2a13d52c9720896a1f4ce3a5345ee793b6cc3ad80d7d58163d5455b9cbd073e2b7adbff95590c7172271bd91fefdbd01657ee1750651036cdc3560b444ca2184bf4f3ea89fc973aab6fb4a8ee5704bbe5a71c99fa3b5ef0d0396249758297699ae202b819690dc7ac4692770346907845e2210d5363adeec03f0fc7761b7e0ec0fea1bcf6b04fc54b3e4c40d19b8fa649ac8479e8f80730c0c94e9f4a1ad506f2bcab0c49540f6decaa77b3d657dc38a02b28a977ece482545a
+SIG: c5f626490c0ef4e1efc3edeb0cbc3f7de267057fb7b6eb8f0c813584965bc5c421feedf54241cae001ec6d5e25c9b1fba0385e5dbd95a06ec1d8ae519144960d
+
+PRIV: 52f4675d8ccd0eb909df0a516648db26fa033ba41d43fc3845896d456e14265ff39e7dafc97b0a84dcbf7fa14a9403ee1fa92b85e5a7e5d05f031b44ddf1f794
+PUB: f39e7dafc97b0a84dcbf7fa14a9403ee1fa92b85e5a7e5d05f031b44ddf1f794
+MESSAGE: 74427110857cb4af0a3342c2b52997bce1a0db6405c74e9651c5b85979acb071e567fe70412c4e0d8c9fa421914f6a62f2ae420b7b2f4cf80c90574221222288b65867eaa66e7e0a0557a26c549f9a7a4e70838ba4074b4cd7a9d758b378b88dd49441df802a444dcbc30624933b59922f33c20f019fe78ee24b8fba79a682f388505ac9c97f4eb87c611880026b4c23306b865173f5d716abc6cd9a9906db3430136f754129c443b20c42be2fbcbcd44034d714f58a4ba8e756607a02b608ef49648f2ad0cea99e7ab30a8dd7814004f725f49301d7b304dcda625c296d928cb581736ab739c86b469241a8259351fd37b4780a9993
+SIG: 4bf668827a720af68898a06ea7b44545a34ca896ecf311feea47e0686d911fadaa03118997153c65361fea15de9bb891b8909872045508ffad0cd9eab21a9702
+
+PRIV: bad73c9fda4ceb9da6c701c2a6e2efc0467afa0a74f8750c52cf1fd4c8e7489abb0f027a9035376e1aa3206c3d774475e351f5767ef86ef48a72c037c24cce62
+PUB: bb0f027a9035376e1aa3206c3d774475e351f5767ef86ef48a72c037c24cce62
+MESSAGE: 74b966cb780771aee63d734df3756702d1d5fdeddf32136c6358b836318a4f984fe71e7716adddbd649eba44cd4282e0055d8c1ed2d35123d66e5a98f1c0838ded563b9a20eb8007538fc7b0713e7e485e3c28f6ebc421a29dce2524db7f29205761036ada62e5b0b7d5b7f294ff17f338232fa5fd42b6f7253304092d848f50735248595da0f7ef28e568e9916bfc56d7ed0d811b59d5d891ae43e1b198071306bf525c678c6343998005fbb7869d1c40f8cac807fe2ef03f3d5b933f58978ef2906fccf7444a2936e63d928c690926c9c994ed3d666263e956fdfea27764bc5f74125bc46bc102dd3e5ff93b5e123e4b38bdef697e15
+SIG: 197d6b6cc88a98c06dfca0c01225edfe38a0b2289f29f8a44ec0816a952d585e2d59b5b08de100c0606296ccf5e92a99e093623144b8b22db87d929225546005
+
+PRIV: 707327a431dba77639b3966b2bc095f8eedf57f7a200e3b0077ce420389c92feee2496910864189fdaa3c7757eb3cda9ab1e70fc9e7f71a38a0bfc845931c95a
+PUB: ee2496910864189fdaa3c7757eb3cda9ab1e70fc9e7f71a38a0bfc845931c95a
+MESSAGE: 32ef31b64eee700fca2ab21a267f8d9d3bdc689c7538fe959bf713fa995db2c0ad36dde430a8417d437b72c74e26dbe31d93701d4617fe51825cff7a544fc9f44e4345e14b4b11e15f26ffc2af8035f3f970e4dda44c0ebc0363c2b56fde218663bf78839092538fc2f39153d4eb29da0c1a08aa966601cc68ca96e993b01b173a261b2ef327650382f568fe944855b0f4fd9d15e752ac74dcfd37b3786fffcef23339c21e9270dce8891dd5eeeba9608fdc7b6fbcc99fa1b5903daa0968e1b691d19d06f215ded047ef9d76610f5de220f5041b313faf9e96c9fd7db54b5225726af435f9cbd9fd87ab40ce8f2c6940b55f0faae87850ca
+SIG: fb99029feca387a5d765961e361d7172b98b7e0f11290bb1e5b57b51bc2123d0bce29020392a4fec9ae6a72c4c386cea1857cb8f9c50aa9a76d7f1687fcf2900
+
+PRIV: 6aa5c9f008f990473ba4a6286a416614026661f11e1a24efa81ac35852d1d070605ac9b4dbdd5033d6c828bfafa93c0039440aa11ca724ae834043e07bd032d5
+PUB: 605ac9b4dbdd5033d6c828bfafa93c0039440aa11ca724ae834043e07bd032d5
+MESSAGE: b5165d3963f6e6f9ea5657e9f07ff3a321eb338f9a8c3d3c42306b2b278978b31c623a631be3b04c41edfdeddf538e1b765bc8785401c1af29d0467a64411c497395d755dca03ae3272f4bc1fb1918dcc1ed6f04d6498404a8ce1409d447f570a4359522cc54629202ebe507ab693843141bd5ea0573b20f321a483ff383a46897f5926fe0b8afc25572707b63eeed283532928a4144196497942c572ac547605139256b0aa0eaf04db1a256012ed453b173ee19ad6e9b1af3f45ff3044a641f8c8eb0ac7bb45abbded47286b2a069d3908694ee06f2fbd0ef605a7911026ea9ea3c4913f38c04d8b69565a7027867ab3092d05f4cfb18fc7c
+SIG: 9756303b90655e935251032ab19cfc95ca1c2a2c3ea28b033bd47066cbd4c7d8982a8b9886f1b9cd02e88a65564da8dcc34f308ba9f10144ba469c2efa49e004
+
+PRIV: 8efb8b79742be21e6d31de678bc81450ba8621082cd6f0003e22861e2291c48133381e356c4fd386a3f7b969afd9f5c00d2067b698b3f1f00f3784202d3084cf
+PUB: 33381e356c4fd386a3f7b969afd9f5c00d2067b698b3f1f00f3784202d3084cf
+MESSAGE: 6b750325d3a0f08a147700b51a9b3725571094818ed69d1f761013eb86f323f73c49f5e439877c2783b336d1f1a674ef3e431fc1ae0180082df5fca69f848139fe6ab6739a0592ebd6d4705c7f0136b22189a11d60d4d3c9bc80fe7d7c00952d5742f9c0c2121fe792df133f221db991fc960ee64b9d32e0178e542bce8efa8d03ac8026cd77ba8bf0b24215b9faed2eaec920e925d5ec46fff6bde725e91c8280e4ada232a5433ae9680ebb53eb55553147c93370574854896154514299c093219a111dca4e637ad5001338c6d4d5ee9098c65832f7af835bcb622128423036c79a5737738a7539f8d4a6b8b221b56d1401aeb74d4571bc009d
+SIG: 923005cb4848402aa8f9d5da74030b009444924c214ad600ddbab4c153a6ff022b53cf6364cd7ee99bef34fe144da964edfc38a0ba633312650ebf0e55a06009
+
+PRIV: ed046d688b2b0a1bc3daf2119dd321a607b16d2a2d1d963add1209c665b5ccba8734f1ffcbd71cfde290017ea6253e580d59e65b541b46521f5e5ec1451eaec6
+PUB: 8734f1ffcbd71cfde290017ea6253e580d59e65b541b46521f5e5ec1451eaec6
+MESSAGE: b9cc90fd8de2a141f95116db3b04be83e98522597ec2174964245180b9a473767d6d470a217db5ff5a1ab777e1e28a0b16975e2bacb873020444b47ed8326421b90ebb503688f090c11b3b13617c5c5052c297a41e2893775e34d59ada49d994c0e4a9f5220e9f0315a67705a3ec08af0dc724b5cf67ff34fada8ba7109ed2b5a8907bb403fb1a838b4b059f18c792d7bfec05dee0c9cbbf1753409d7db3aceaf47b4c61398497b0eca6c1f8ac08a7ea1eb9c40bc4e92e888212f7d9ee14fdb73158160944ff9bcdfef1a7469cc70f9474e5f24dfffea585f09eaaab4be2afebbe8e6cf86d35680dc5d1b92913e848256ec736316fd0a2142063b0
+SIG: 721bfd4776cfba13330fd37269e979c1d7b6ce54a51b82f456e137378e582f192a12089da5aba76a7b161813dce56b72892a35330c94f7ff21d09cf09e553504
+
+PRIV: 76ac8e570a39b3a0232c45497537fb2155acec3617865ed1df210f00b49d1b8d312a3ad899ae6a25507ae6e4524e10b63a6e7ae53d9cffd39cf28521d93533d6
+PUB: 312a3ad899ae6a25507ae6e4524e10b63a6e7ae53d9cffd39cf28521d93533d6
+MESSAGE: 53ced9db2b479e59d3ed643f7cc3784c24b8bd4c63206c72e23fa850028899a41ce1a8bdc003f12b7c29972c9a08bcd231fe0e1a0fef0bafbfa4e0e027d72004075ba37d490eb9964e783bb98f9e503e9c1fd3d23fb0017cc7c7a9f86d171f041e2355d8c5e6229d34c7eeacb6358cf3060d5d265bae2004a558878659a30dfed5f2ec788b4e14397b5d00c29db5d4ebf16639a8df292a3d24f6983cbca760d903e976f5b698642ba1fed49e79c38f4bb3946efccc9d6aefad336d558f78e4f205422e10384a4e531e75807efb389d2af4cab43825fb87f196a9080769fe7585782970a6918affe10d20d629b705845597418d699de3f1de854f94bd
+SIG: cf03f525913c44303b2f80079393c21c1158146ecf99636f5d97adfdd9f35839804c23804cbf1e553cfd4b73f689a9143aec298f8276e1e4ee0891f1ba75de04
+
+PRIV: f64a66ba0f0819f3001416c220bf52d860130a19764aa8ab38d15b2aa75ac0228125253cd337e00d45b45079b585349561e5f542a81f6d2fcfd985c10feab2af
+PUB: 8125253cd337e00d45b45079b585349561e5f542a81f6d2fcfd985c10feab2af
+MESSAGE: 8072862ed0ab35921db5ec2cba8e6aedb0441fdf47491006c01e6456ad70fae3c4152dcfbfdbb8f0fddec5e96b12bf67989ba96793f4861a11b63909ce8d19b8ca64a544b31ce051fbc88e062806d9965cbd2967b01614e86b532fbf59843218dc9c19c80315f044731719371092a3da38878bc4cf77de972e860466b8fc45e465dc3d0ebf94bdea60ef0b9891ced41b997b11b31ee4167db60c9cfc8b85beacfe223cc1829213774085d7c06d2b2e632cc21cd9660df47c4fa918bdd596ddf622dcb652642b67527ba8ed15a819a8e21f48d7ee70247f5200e37c259dffd17eec8c232f970cb03182fe3964132993f6ecb7c4db18ccef390c9eb3639e
+SIG: 4de6f5250822d7c9d5bb98582500b5c085f541ebdc450ed1acaf83684827ed1dc77147aae4b19e14a7dc5bbe1f1e4f5771d8a6e4f2351739afb08c806d558701
+
+PRIV: 8439b1d60aa48460135eb1002cc112792995079a77e6e8ab020b9abaca8920b4eadc3e0c5bddbc3052c3b2f8b0a94566c2b2c879ed17034ac0e6a45f2b3e32d2
+PUB: eadc3e0c5bddbc3052c3b2f8b0a94566c2b2c879ed17034ac0e6a45f2b3e32d2
+MESSAGE: 5419f6d24eb46635d4a7f8eab803cfd0d04de092afbd86f2a6961a8d1eb8c0d197ba55ee08c991822a5aa702bae0337abd5ca7faa15e1f1ae369946e9b81216c0f5fc22bbd4433c3de93c5caa2741683bbd0e1a78df28dda19174101876334d40339659f021ae766162c6cc5421b79cf9d5c090ed4af07ec84493035bd0b2421b533684295bbe76a70fec596ef8c89c5c9dda3c33b7735d2d2f20b28f1a5402e72d04ba291dd59f14af08adf56eeb086d769c6bec3451891372345fd6bd02dcf95e803af0353150e182e323aaf683e036d9a135d2e6f98cb4d327e2ce7d54247f3592ed067b4ce7627174f996f28165c9c11f07e5ee9cee63851c6b68ea2
+SIG: 62da81e16440821b593b6ee6540e15d1aea75d23e0a1bbfedc808c9548f87e8bbf36915a39a74716f645cca5714d170af907576d4f3705e543d2adddc5ff2303
+
+PRIV: 3a046397f0afc072bc7f907c74d38fd1b9afdf27e14a3534768b0dd2df3a1c2299cd70ef3be342493393872f54c47deaa081021892d11a3268f3145ed4f3abe5
+PUB: 99cd70ef3be342493393872f54c47deaa081021892d11a3268f3145ed4f3abe5
+MESSAGE: f08ddef46cc6c34179820c9861375172fddf774f8dc3f7d64aa432da8e5fae644c0a8a9e6908517d505debd612868ac6daf95cd7e1699750022ccd4b88dbae2bbf73546ee4b835d319a842dae8b9ed683323f31e5cc57919bc9dbe3bcfffb2ada48072697ff4a7d310c91adbca81faf26a0eb7bb0c404ac9d8dfec63e9c64e2f420c07d323b7c0dc3b73507283aeb1cee51db4e1a83a692c7c1ea398f6f30940fab85e2138d4b85aa4e231e5424f5b064ed026f0ccb99d1c85a9eb15f5934a11359d411cf94ae8ffa3361a224f46bab852d184a248b4c31fe3a7e7f5134c051031a9f328a7be4a7cbbb1d8d863a400fd2d58daa44f1b9d8e9ddf961ce6322f
+SIG: 5024ce60257965687080c5b1fc7d1301c32aa6fcc835497d9cb23a74a6ca2724f55353c1b757827ca5440c9ef8f8c1050913e20aabec35c497b56041b5deb209
+
+PRIV: 124f7416a80453e4cf1cd7b5e050a9761418258bf7d27beb7f23238c4540be2d0da34ab173990150df7399b6bcddba93c6dbcbf4d176941cb5071e8734c5dc92
+PUB: 0da34ab173990150df7399b6bcddba93c6dbcbf4d176941cb5071e8734c5dc92
+MESSAGE: 9dcb9873ff054db11d0a9b19de6885ffba7f0e681cf7fb8f6cd950c48328d1f919ca46054eeee6c9e57843ebdda7b24bc3503c4d612abb1a314f39f58221d2b54dc755acca7969740e7fa8b1a9523b8c7379fd395253f4e6cd054ee24b75613c3581d49e19246a7b3be1cecb334be44f3d626fe3b7b269e628d44580c20636eba2642f2744b959e65757d0ee601843f188e95d17253fef567068a5405a3a9e677fea3d7d55f7ead19a3f30c5f985671b55fa120cb9d05f471b6e1e8d779a2c803a19e6d0d7cd507887ed647c2a95483f933991ed45ae301a2b0e954a5703d248c78810aa0b199cc2bebb2f1d71cc40487dbd42eee0f745f7d285685b1fb31b15
+SIG: b0572104aa69e529e3465a6fd28f404a4ec20276a993b1725eb8c5f650b4a216f1871b24e368cc46cd1ee0174cda1b5e4ae2200aa9fc44522d975a9c51814908
+
+PRIV: 25d13b3837601b07a975693e5a33d5337c34c1127fe4c27490612aaf7f642e9a3a07cd68ee2692d51cfad1a80e7763b18a043c74f4e1b01edc55ba9a9e07795a
+PUB: 3a07cd68ee2692d51cfad1a80e7763b18a043c74f4e1b01edc55ba9a9e07795a
+MESSAGE: 115b3220b45ca8f36c7ff5b53887d47e669b78dac13b98cc7aaca5c2e19fce81ec8617ca410e11c9a9118a668453b329ffb718eaec739172f0a849a0848192a5bdea18ab4f60d8d1a0d338952d77b2cc13efe83c76e8dd58803b1d8b3c9729ef102b20835b7de872bef3010f15a4caddf07cf7bdd222d84b174bc21527cffb1b7ffde81e281d30cb7bce25ea3dffb6ea1fbb06cb70569a95ed1a07e97ca42de70aa218159efd608fa9b0896e0b58518a322f251d133e58c8fc1428ab0a170ed845c75fb403f1ffb97d2d2a6d4f277911d326c1cabbb8516cbc17908ab81ff8d79af44611ea1d05879c1ec81d06936e0f4a0aef6d5748e181d30ec25236597a973d
+SIG: 20cbf08392fea6a99cf446a95c199caa0c0f9813cc217b8d228e2ed90bab95ea92cd73ac95834764d33e42243c80a7603491c8d3e49ac715fd8a5b9e4789bb03
+
+PRIV: 7b3a76decaea60c41e95b05877a7da82064c27278c8d7df5f0bb95f0ad2d0435f80db5c28721b1c611bd87eb145a98bbf383b068045df2458d1a6fda099f7fc2
+PUB: f80db5c28721b1c611bd87eb145a98bbf383b068045df2458d1a6fda099f7fc2
+MESSAGE: 375fadaedd9cac49b64e1574028046069f4c83654c8a7011abdb64db16b47fa311798172f9072217b0a6a43e5df6ffcc1154bcec1c68e1d35ec05880d012ce76e4cebf301bb2ec983d00b4a0540c937ff1c6df9441c61bdb3be8e0c7c11a35d49b6f55c381269a0e768efbd453447fe48b75ac39646ca82eca7d149304423491871c10dbcfc5973a57fab8371c30cbc4e90becc0b67152226ee177b4ff368ec879b391eb95e36dcbb07b2c16ba395545d4529f727b1a11ef65d120976b7ccc86af4bd204cb9489c921e43ba5e850cfe59899f1c1ec4aa5c92b6dac6914b1952b53dcb540b409231381568987bb2236bc40895df3f17eab7c0274f2244f958612e88e
+SIG: 2cd26fb3c4f7440a72affe93564f6f6559adb15cc7a2ba10879fb7d67e47d4ebd02fe4823698a5fbd4a907fd69184c255a170e5f1747fce968102dc219b50d02
+
+PRIV: 5ff8d4052608eb033a5e94b603ce384d8452f60a26498b9112567f3410c18666c4900de24d9af2482763109926af7c481380fabcda9440c1a53ea1cdc27e6568
+PUB: c4900de24d9af2482763109926af7c481380fabcda9440c1a53ea1cdc27e6568
+MESSAGE: 138c60557c2e9008afc03d45bec71f961149a0835926751c8ff3935c7d652d83e1b0b1da7d5bbe0b8e171a4e49aae06fd8a9deff78dcde4d25b1aa899998a0f99e1df6f9337a3ea2f24b76c317a7014db4e5283191795a70d8821d217846490f958701d39dc2c8ce47d928938874d87b3558989bc77af820979a351eef9594aa5b94f3341eded4ea20b08c3e7c5610d43267818dfac0a87ddf527fbce8512bbf85b66c9bb5d62f0fe84048f23b19604a5c8d82b1f25a8da02731feb2ecae489b8475f7bd326ddf1a08189e46c08cf50538c2a363e2f4eb2c01a204c7ffbc0b981adc0fd997aafdf2a222ee84c309f6e95ec7de4fa85d4768d5c003165028225e22e09e
+SIG: b737d4e5be27deb6d87729c636dff7a406c013f313c38cf683fe14f75a3b3005d9535d7e5815c8f8b37c51d6927111c979f7d9d81a347aa9cc09ed4e6c18e90f
+
+PRIV: eedefc1757e3a7e5ed3946dbedc396a362f683d2c51b0b9f60765d4bfc5134dea9872bc2192fc02b189ceed403ab9f270a032a835fdebfaf1c9d6934ed8304bc
+PUB: a9872bc2192fc02b189ceed403ab9f270a032a835fdebfaf1c9d6934ed8304bc
+MESSAGE: b194db73f994cbdc3cbe630ba72c47c2249bc0592ab547942b1d1b882b44f5b3855e568bdddf92ef05022d88fcfc294e76b64a00e9c74355373763e49a4ebc47243d48a9ad588994a518f80f8615c2b31da587a53e529d435a8697350dfcde02d20cce7d5eeefe3f5ab2aac601259cda38538a1b8301f9832e75ab90f8a932f267eac181003965d5266f206180c6c380ece803577ccb46176bf607159486f24259747e2ca6fb1912db7b78a973b2846387c1208030ee1f400d0c5b5e8bde9635ae55638ba17c734de8638bb85dfcd76629a7f9f40d6ab954d55bf8575fc9c9a595097e0893db5a7b8a6c455ecbd3d22d725e19de2941f467f9eb93d66a0e2bbdbf92ed1c
+SIG: d5bea8ea9a5fe9ed6d2bf839930c0c6cd5039e988f551fdedb5437e1c1af0ed7b3897c035711c3c51926be8d1b32024d5cd582f5f8369ad84d18b12502652f07
+
+PRIV: 09d22bbaa5956cfacbbf9fd5510975128686c40c6ea96b89ef4c0f0c649bcd7fe559ea8acbdc61b6709a7d83ae15849a6c78b203923dd0a299239ee4886930ba
+PUB: e559ea8acbdc61b6709a7d83ae15849a6c78b203923dd0a299239ee4886930ba
+MESSAGE: 1c26a0f3a1a5b2d7d5b297af8a6a689d7c62a25267e197d23becd2f2b816c4de92fbdaffb941c3fc8db7a84335a84cfbc92cb3ac806ed58df16b6b8e119a48df4f27c71e931a5938e7d002734885e13a258a15b6e1136efba72f1d096b689f7618f49c968063e8f991fa0b55601e430eee13492a1b09413eb23813591a7a9f070cc396ca9d1facdd4f4ce37c40f7245f55035e10fad6b85b5f01a1daacc0df94069f7de8f6467f96d1fb98648e8a0520a8cd723c98e9dc2dd4b2934d8228f0ae1a415bd3a7cda38d7a9983ce1af6f8c970a2a591635fe12b917536ef815eaf1a3138d70ce70a794264d7c986d9ee3290445f15a9248f2765271e5a992196ae331abd4164bf
+SIG: e65275c4328a70ad62408ed7fb1728be87a73a814fee8ebd94f2665c71bc66ab0c1b07a600b30bc081a74c536857c20610384be268d9af3e3ecddd3eb0c14c0c
+
+PRIV: 77826ed351a3f09254ae5692885d774cb3f24410a4809fd90f8a00da9aee99033eac8f41ee73e6ef136821f7957a1c27e15638d0e3916e6caac6fb7beb7bcfb0
+PUB: 3eac8f41ee73e6ef136821f7957a1c27e15638d0e3916e6caac6fb7beb7bcfb0
+MESSAGE: 1ff06c0b3999cecb1900a47d267beafbb35d93d14cb2c8925e3e3fe5d967586925ee4baa41998edd0103205810aad5c0bbdc77874476810246d13089a64db576424fae0bed9664a42a491147d1ee3b9c3b1ba4875be15462392540f9978d9a4630ba4c525499751a45efc299ec7d73b17f9ad275ee71a687e72690d7320242d2dc2bd4d5c5cf0f17a465185dcf60f8efff53903f20b0c2ab2192d44368f2f2fb36048af071f7aa857b14ad1d11461205bebe17e02be2e3ccb6092821885c4e0d4811be3f45b1fea088453e022432f562562b43a355cb56270cedb6c2c42dbf9be850e77192fdc65cfd36834be988dbe9a93e2518c138b090fb9da827cb1c91c8fe52fe7c57f7
+SIG: 977adccdb829b40bbd8e53856a783db346a39dff62041a2972d29009f1c9ff81b8ad54cb901e497c1d3021b50b6c69ee73558fd7be05d625f5727f9af2ce8702
+
+PRIV: 99a99531c3cd6e3e9c900a9eeb26267e72f09d11b651a897ebb79be016f64c6e9bf9f8b48a2728e02608fc19899d219656839d1cc1e9a8984df674ec26662f41
+PUB: 9bf9f8b48a2728e02608fc19899d219656839d1cc1e9a8984df674ec26662f41
+MESSAGE: 7a89c0c1952fdc4298dcaea854efc134656be147e9e8e82fc9a449059d80570f75676b81c4a94f76a968200cdeb0988c73f59afc72ad4c3103e19fe63b7e95e140b5cb2efc7b97a6ffbb6c298ddace3be6d2ed3d598b8bdf0c2fe6c97602142a76e978514c196c1b9a88efdc1925fc506155cff9a2f21ab634e2b93e96928a5d8f7ce4cb7326d9689469242ba9c6a01b77496badef87578f5a17284e900a72df141c6199b0e71ab5da4375037617ec6196d4f4e23ae2916a72d0fce796022305ac9fbbbbe4705b340e42b78e1c02bb1001860cdcaf71ed89255dd56cc0b31c59d4596dcef84e22234be562bd801e94111d83a78064c90f9d82fce91f68abb03c73b6bd8d7e02d4
+SIG: 0e89da5d949cf2bf40c7e17c2d0f9ceabc88a092eb4d49cfbfeab7c8bff43245c67b9e2e92f9bcb9b34b3fcf8b01fa2ea7a9649f814c3aa98b3dd04540c31d09
+
+PRIV: aa58403e763bac405db065eb11eb6be3e3b6cf00ec4a222b52bff4b6e3d156ac167f9b9a4665f93f5d7d3016ace6fbd13420b2e51e72bde59eedf26993b66cae
+PUB: 167f9b9a4665f93f5d7d3016ace6fbd13420b2e51e72bde59eedf26993b66cae
+MESSAGE: 3baa0998ff02b32b90b51f9a840c7b5c5870cfb1810a9b0f77b55909d47ad335147a991c29fbebfc592e9307175c1964129a2d5efc6215807453bcd726969781222bcad1c99a49748b9ee667c4d0c82889e2f50064c115dbd8fb483d72ab0ccadf76bddb2dc727dbc3fa5c4624c283d8921c8aa4425110dcdd69c05e5ed59b359625eeaaec1e27eafe9d9a5ce736c3f9c527ea547818b9bca6811be4cc15058a6f5b683303b80c90c94a83b8b15869713a66b1e0f656331b286d1ef7698834ab3e138417aad6bb3ab3bd9fc78761a482dfc654f3f8628c8d9fc16018898f1641e8622bd272e38d41706cb9cebe6ee5e173576bf61bb1188cf2f39c62220bba88fcb4de4898b25b04
+SIG: 64b598ca5b8f9ae742e46ee0d8c1aaf31458b50c25d267a677e44be5b755f14d51801a30399bfcc38d14071aa0ae93da825a581ab6c20725a0a910b4735dfa0b
+
+PRIV: 1044ee3708c0b0e909a8cb2ba2cd0af8d28a5de01d962e826087fb232df7b2d246d241ea0c702c1889d44655824629b67284d4e644a48fa45455d27ac5f62529
+PUB: 46d241ea0c702c1889d44655824629b67284d4e644a48fa45455d27ac5f62529
+MESSAGE: b8a445455fb66e17e3143d35204c9ea93474eebeef93963ee5c1d377ca217acd4ca63e5755da08fbffdbd4352bf165193896c8d6f76bb4cd3bc2d3a476a4e320824a1210ce74d0014d747f111eec310c5c89ed4d0850e811f80a8bb28dcaf6f411df83e2c1dfd90c4ad23561454eb5d756b63b4ea7f37dc5d466c16ef70d11190c4f5316fe2aa8597440e88bbebaeb35ea5f04f07b0339264158ef909ad5163bfc248cd724133e274f812695f290e57176a96b9393d07bb310299f5d2a6b6dd1dabcb51bf29c5afa7ebb0701c6c84767ac137793091fe0ed6e47d780628a32c84f83e00e9c16742a523ecb63c24f4a338ed299a06194924f44c5a5d3c937ff9b0945982ad24a2d1c79
+SIG: 7d6bed7f87d090abe013c31e1203903bac9c93445d06c7b53d31d15f970d88647a7ed2c3a63050ba19d68043aadd18bd861de1ac4715b8e828b2b16f8a92b001
+
+PRIV: 95dd1a5e658fa6c8d42507b3e5b8edb5baeca62deb00fc5d4dca8e1ab5835e593a5323dd1e07f323bb6d83e9c2db92a29f62e2e003ee0deacd7e2e4e030d8d27
+PUB: 3a5323dd1e07f323bb6d83e9c2db92a29f62e2e003ee0deacd7e2e4e030d8d27
+MESSAGE: 9b7afd48c474604c26367531556840c388668b0f3840063dfc9869ad5b901274b931293d04f3c8e8f7f8eab815a641d7c351284e8bb0437ac551bb29438964e6a7c7ba772344b333f9eda5a77568c8931ddcaf21e32e07b10bf4820fb859bcf87b81c4bff426f24a4d468f2e9aeda8f17d939709970db11df76247e98a39eb8b38f5949f349f2ae05ab48c018517c48fa0205dc7f1566453e105e48c52eb455c0c40802f797b3eefb1e2f3b1f84315aed5b0711c6499a691b74b91f12ef70f76c4c05c1aa1a993e2f3e528ab343dd2368162f4036a61a13a88045dcdefa85d68532275bcf5b8f5f00efdea999a95783175d9ee95a925d48a544934d8c6b262225b6ebea35415dd44df1f
+SIG: d02a7523dcbd29576ba809b531037774df41734a41175813119c6a6a788cd9b8ad780865678667699ae66d010919a966a051c08163df67a977ee6e220d0dc30f
+
+PRIV: 1abc0b9aa01dc57ca53efe7380962b1a88d50a964f5cd98640982c74393f29268d4fd14394d7c1405700306983fbf76ea9f171b15a6b56612a1feb1cbdae5dd5
+PUB: 8d4fd14394d7c1405700306983fbf76ea9f171b15a6b56612a1feb1cbdae5dd5
+MESSAGE: da2dd940d5e1db6e80bf7e2b782e7e745cd4fd252e981517975887dd05ac77ed837d082961575efedf301fdf24b70718b991b8d92bdd2e6bee17c8aa4bc694a727bcfc78fd85195c42caf883a2c38d161cadd79cfda9a39110e1264d30bd4c5c4a5876777f233b071b1b0b408935f0468954cc744af8063b004ede56cd981c4dd5608abffeaec9e58f3fafaa671467804b7fa2558f4f95174201f183d80a5914065fed53115b41ebc338f78df050053b8a4e75ea7c6fdc354dad27bfd8a2e66fcd7ae2f587d24be0d4a33da30a220e51bc05fa4e412b959fd95d89ea6ec0162516c096a9433a9e7cf599c928bd5305c2173bf7493ed0c1c603cd03f082cce44237a79ffd8be9a672c2ebaa
+SIG: f738af2d3e290b3d23d9aff7414bfc5ffa47235dc053687a8ba5c8541b8511f781566cdaa130e0677db55fa8be9d81a092cb58923a8628494d2f62d95c167100
+
+PRIV: cbffce2c9bd3e23e406e5f66e632dcfa726654d29a955cec983173235fa359d049653edd64a55f7cd40eaf3f8e72eb96dbcdee398f34817f2c95867949710b14
+PUB: 49653edd64a55f7cd40eaf3f8e72eb96dbcdee398f34817f2c95867949710b14
+MESSAGE: 1ffde6826e4f0c24a7961f191e74cc0bbc928e3f1aec3efab32765c2501cbc1620e7ee6f61fccfb00cfca9fb98143b529bcc8c3d0fdf89ee7c342f101815fabf7deaf9f302a288fe175826d590d99ee6fd92da74f9596b783c0e7d47d711a32f39ea4165e5212431441b498c6b70db3b09d1f4e4a14a6bae39da5088bb85b3285ce9df2f90681af2c74dece439aeb91e1c1b0712eddbee8d72569828f37cb720c509d02aec476070484e9b16ec7179947ac96caf0e1be8b6b74f372d7235fe6e3999df733bccd482dfe2e631f56b582667dce5e3121763adfacf3b18cf2095f7394dee4927fc2bea6b5824d90cd59e854ec5872b4551b02efaba5ad54a9b7a8f6de5d7cda5825b325b076ded
+SIG: e7ced4fa2a7dff73f1068bbad0ec9a1109043c97a62effa148876f0969ed4dc608e28bce797af3b82532c94dec4d6811b7f563679129facf17bb73d69375eb05
+
+PRIV: 9f91231497484cab39b9e20f861181d397908577bbb2968242d071bca4813ffb8824bc6cd6a6f15a5f41668f2b3bae8fc4967383078d08b51d6d1b2b93a1071f
+PUB: 8824bc6cd6a6f15a5f41668f2b3bae8fc4967383078d08b51d6d1b2b93a1071f
+MESSAGE: 21d4fbc98163c3fb6e09f775c2ab7b18b18792340bafedacb49605622e3c08aa3b2b8d0e0902f361aa1c0f652e2732b10a0c5c6a05098996b588267cc8951a78b5d431e7222bbb508eeef1b5e8b8d01d3991e18dddc6ca8d222ef177ce62938d1810eecf06f4738b28f440946ccad2a12e39d38611bed3a39f93419a179ec2b1b52d5fe5c80c23b84d8803755f5146092cc199b4bdcea5bcf2037bd53ff6346694155f027d8ce2baffe30a5666596c00783aaeade9c77fc8637942ece017d6484c2899b1918d3a480bd5157678d4772d271f9b99768ee1bcc46b2489ae87cd030f47d1333c7672cb902cb4f5fe746e853de57940ba2264d3e629644d653a5b7af78ce64a993f36250f8cb7cb45
+SIG: 0a1c706dd8a13077ab18386c65fa97cf9dfc43542d1846ecbddeb7b3c93f3c66f3ccd0447aacdd4dad8fbf736c4ff9dbdb62bfc14d8883e385bce9bac56a350c
+
+PRIV: 1e2bd5487c5f5ced461f604dccb4e78eb91608f0b821f5afc4e3e534f7960392ef825475cf2051a2017ae532f077d96774347d2767ea7b45f9c1b860ab993506
+PUB: ef825475cf2051a2017ae532f077d96774347d2767ea7b45f9c1b860ab993506
+MESSAGE: 1dbbbb13cdad88854b809ceded273343d306a8deabf3ff02c9cec6f002b8e9e10ef5d1b0f5711f33267aa91c171b61e960f740457b81d751a473f44f750a080cab80af7ccca7dffcfac9ee4c39dc85cbdf51259ccd3470d9bad3ad30f4ee5dbd4fac6bd5c6c4df7311a470044695a7e1a7e18572207588afa57eebcd4d575b6d424457ee92465ce1863e3c677cf875fdb98d4078ebe7144260807052577144cb8e0359aa42ad155d79dae3deb99c4632c191c799cbfe587d954787068d663bdfc0fab1334f1876bf498c4db5c53db7b0204ed5a521c62f09eaca8d0189f3b394143f29c421cb5c8d07bd751baf4cbe3bf4be1701df4b2207dfb2904d84f4dbda51cba576d5a5bb16efe698edd608
+SIG: 4d33c96a2e3a5db7391adf65c1cc3565fe76eeafd0b5c7abb0b492a0b51e1fa33639946a243b2ddef357552298ce0aa95eac6fbfe660988271877eb2a7da1806
+
+PRIV: f78db14d6d1a643dd7735baf2635321244e7ec8ca72c5c38c98c809db9cb5a555414f75f52f3864afb0c79c2c5c1d06b4bce400fbddf17fe9cfb2a8bac47a0dd
+PUB: 5414f75f52f3864afb0c79c2c5c1d06b4bce400fbddf17fe9cfb2a8bac47a0dd
+MESSAGE: 05caf1b8edc3b173fbc1ed29b95e2bf06d814ba2407d4b31c728d04ec273d25394423ac7d4fff2ca36ee90273093c756e2bd13c96d4a3dc7f5be1759fcd328eb66c5882b58fa4588e5b2a3713a4154a2340d0b06ad019601b0e028e497f898256b028af95cd8168df5e58a57cd1ebfc0a0c91ced61dbb480aca7df8dca91eb16e98007cd2cd1a2045b0e4477d12d5a4072f365426567c9d61577f3485c8f46605e7f475ef04a3948f60dba8c5508d14bfddb9b11dd044ef2d84c16b9a9038d8e78eda43b91297df35f4361a383b41d49677a687d5b344ad1ab0fc73017b3bebf32306fb3fd7b3d5071f3ab5f6e49aa15540cad6503bea7784cf9421801ce1385839893362a97fae121300d6783af0f
+SIG: d7cbd4181f67712007b7f0e18452e0a024464d9dc9b5ff9cf669d1b91169d7573262f83336b97c861bfab3fcf669223ce8caf319f21d23f1fa331a2d89b6ca0b
+
+PRIV: 7dfa328e90a1b849c219e3da832df9ed77448234f0d89ea5d17a3d64e7883dafe30ce6fd5f5800389a70cd117364f59945afb180f229927360b06b4835f8dc91
+PUB: e30ce6fd5f5800389a70cd117364f59945afb180f229927360b06b4835f8dc91
+MESSAGE: e5e495d663f47236714532687a24308f942ca9c33e088f7f106a5a723518cacbbef4a68c939a6950b2dc2589f82d354e575272d42b1383d315ab8a20aa0cdc9d4df678ab3b26612b5dca66e71f9f3fa7d9e731dc481e2bc7127cea3b6203ca6cd8162e90886a73dc46c83ddefc4b9e2d53d29dd387c624e08bd8d53be928a40a9aa8ae8b1c8d0fb6a7bd6dce5f62315b7a2181f627f256bbe7e2a95bf464e6132204c174209629840235b2c39913301a4b40325d118d384bc7ac028cd4f12702e161191b149e4209058a55122bbb8b22b24683ba4f8e2e6ccfc08dc8c8b1bcfb6d60bd8f062196933df319ab16906d085730eba1720d4b02c67daf38cce6aba38e25d68ef95b2f521913a1d77d5eb650
+SIG: 1c61d53b872f8cde598609682c79f6c5df007c513a71cfb3a06dcb82d85c4b00ccc40b00e59f595393088b4cd0432855c67a207da71f87e72c409b3e50279507
+
+PRIV: 6ce13d3c2ec71fed83131a69d5d030314ab49e6565ef68163fff09ac5d9b47e79c7b1118fab91e0e7b192a23d95fb877cb7936cc6c8a330592f48e6784edc292
+PUB: 9c7b1118fab91e0e7b192a23d95fb877cb7936cc6c8a330592f48e6784edc292
+MESSAGE: 10bbc311eb2a765e0167ff37618ff70e13f02d7b0617ae4ac06befbbe149c972a994f680ca4dc9a92ec7efa53997fad356b9ff4ebdee629541d1f4dea62ed0d2494f9ccfdf07a9310491f61c4b3e2700b4a3c668d678329a38c2eff9d8cba431fb959e7f7655bd0fbd77d53bbbc2eb8dc51dd718ed98728a181686be122b844d3da331e329d3959b5923f7734325a021026e2754e17a15108be801465ad958dbcf21df890cfe5d5b883ca43c61cedccbdb58b849ea75374f1e918e803e577a5dc7a1c17936eccfcd3481bd2b1eb075b83237ca6f3c07c19e9af9731267be82d4898eee96ebc900d48b059d51b0dd415b1c890660a88d25f5c5f35d8e45e523e0ce3336923ab43670e35c5057d56c758876
+SIG: 608b2bf6f6da05c2ac5bbfd795a2ac32c79c74153f9431dea59768ff4c225e3b693b645a506766b860850ee97ea43032b05b69e56767e8eb9d1918df9afba805
+
+PRIV: d45ee69a5f1a7cfdd0343f8770d1c6bc026f067a70dbe839a86f2aa068c33f81fc8d9fb0e4f34793090755e0328096e01e281ea351b8d95cd9116e131a5ca54e
+PUB: fc8d9fb0e4f34793090755e0328096e01e281ea351b8d95cd9116e131a5ca54e
+MESSAGE: eb5ed8ab79cbfe61c25981b9d1d6b70f10b60194b4161fe17d11aff1767994aa0813e9ece2f4c5d531b99e8adf1888c30a63893eb451aaf55acd5a52ad8c401faa88d6eacf3e49470566114fd0c6a274e9544846b0ae9bfa124d7951eb26715e19253ff7edc8a70965776f23ce46031e034a200723ba3d11e11d353d7e7cd84aede267ff64bed418cb9f28c61cd0f63b6ce2ecae14b20bc6bdaed8c428bad18be4b7d66338364acd8042a8256f258a69969b8d3ca2eab3aea3706e5f21c3b1efcc254a824bb4e7ea7aba8827c8eb82786c665aa973821931ff990a63fd34a74a6d8c22a882b0b935152ccb36fcc76f4eca65d67c8680942f75dfad073439c0916065e83877f7ba209303f33548d9e40d4a6b
+SIG: 156c51c5f915d89b8d1400350f8f217a5c02e2629ede9f4a30b6e71d1ea7a953cc6db31ba5c778c269920b649fb4221c6d38cf2cea2a7de3ad423e04faaa0607
+
+PRIV: 8a76eaab3a21ec5a975c8b9e197a989e8e030899eb45d78968d0fb697b92e46d2d9c813d2d81e2730b0d17d8512bb8b5d33f436cabaa13e141ca1cb785014344
+PUB: 2d9c813d2d81e2730b0d17d8512bb8b5d33f436cabaa13e141ca1cb785014344
+MESSAGE: c6c78f2e2080461aed9f12b4f77c989b19716780fab60e6ecb9793b4bc7ed69e5f70fa6bdba16e9bd3194969eea6665abfd630deeefa3d717b6d254dd24bc97dde21f0f29f9ed34b8bd7a013380f4f82c984fdbd95af9805b744bcd952c5a71fbb57d11f411c18cc30bc3594f7ad8228cb6099394a1b6b0a818581bdf93cce58f3a4a23e55db3e69ca9d60cfb3a907fb68329e2ffb6c65f1e828d28127109c9e9fb70160f2ef82a2ee9f9bd170c51e13fd3fc1866b22c79fe6d5101217979dbe2724dcad8a9bc69acc42c112dc697bd271eea550e9e50406bfd28245b83b8f012d34db6dbdd55ae6e575745c153d6e7534901027eadc2fcc33a5287ddbca6d3aeab8972294dc6c712b9942547277340e7ad19e
+SIG: fceecca4b014fecd90b921b0fa3b15aeaa4e62caa1fb22729c70269232c33cef0d0aeea66432c128afb9a3646bc7f03a12774da8758398c2a0dcce0bbbf6740a
+
+PRIV: 18a8f93648cdcf47133630af1e11c0ceea3de07327314c96580df775597d7a9c2912f41ab4c87e3937a03331802cba87716b4eea14b9fba6f546d0ac2c0973df
+PUB: 2912f41ab4c87e3937a03331802cba87716b4eea14b9fba6f546d0ac2c0973df
+MESSAGE: 592093ac7cd671d6070b0027edac1fb015cc205d78bb603f378eb9f8aa388ca830db3cb23420c7e852db0b55241eb88a02cc627aa94143be439aab4bf2634757470406e842f20eb10f0700e3c2da364f588a8000f23850c12ce976f326d2df1bac13e95020b412b175bf74bd7ebbacf3ae55c0daebb5c010bf804feee1d7d49fae050bea55996f53cfe1f15a0cf20727db4ee311c260bad9682d7b965e27a9491f471d4a473aff646c7d424d5a0bdcbb8a0233f4b3060dd04c98ec98dfd05ec7247884e2d8e152d4ae52b3d5865d9efd6706a60e088e1e7c9f624510abc7a2045a2c7a7588e2535e73191dd5cf05421563f556a13e8236670343cd5ba4d466e245c4ee3b5a41e70c9a0f5e6ea2c559ebe61ba81e
+SIG: 3b77394cd69f8b45d00cfe3a79a7900628a56518b379ed8a11581fc3a376e5d66807df11e70904f696c741d21d139310fa1b89a93bdc4d2c3997991f5220ee00
+
+PRIV: 206cd2b8114aae188d81862ccec4cb92c4ef5fc78c24435a19f9ed9b8a22f47e97a67ac2811f529456df532737d76bed7e387da83bd55459372fdfb27ffacff3
+PUB: 97a67ac2811f529456df532737d76bed7e387da83bd55459372fdfb27ffacff3
+MESSAGE: 480c4800f68c79f5dfc0c3666c0ac429b30fe0c5fe848750db2171380b80c8e9fec0a054b16d08674cefe2f64ec28bb6b0596b35235575f189bee259aca766c222ac0a46cf2af75774da4e34a0b54fc2ac49ec8bedf4887cd9b7be4fdb7f686902ddfab04627e26ea2dc3d97d62a4b1546180218ed8fa113334819b5275cc54afdee44309008596507971675e6d8b8a8edec4718f2d4bd735213cbbd18791faa8054174907a7ac17d7143a4757e493beeec4849d0b836f18bb2b3c9016f25af47fb96199251720549f15d149503d41095e25f26209daac39154485c3ded7cb1a8c3e83a52f5a06ec09cf83df00726b7968f64c0cbae299512fb438560f04b3b644346f938ac8e90486614cd844b54eae078bf678b3
+SIG: 73a40d9da08fb98ea25b67e721557a1a51225294d316b53149af895fa4d63cb4a3f56f688566ef6da42fd2941dffa06d497aa902165d50213a6214116299a90c
+
+PRIV: 59b144a708abec972729a04a6c13f0ea020b4ed4a48298023a568958c21215ecc4f4720092ed6179a082ae4d6145df3771786efca9bd9bb79c9f6667d2cb56b3
+PUB: c4f4720092ed6179a082ae4d6145df3771786efca9bd9bb79c9f6667d2cb56b3
+MESSAGE: 3857bd260b8aad9d073f06765d37fe893a3f53e23de866ddac33495a39ad33ee9e9d5c22502bc1c4b5470d0e3f3a585223fe4cb93cc4ad2b5ba6d78826a53fc0253dc580a2018cc9ff1cfedbd3ac0b53292deefbc14e589acf496cb5f7670130fdbb6cf38d208953c015a0474675b724bd109f7cb89c33016751fe7aa785d099d09ab20dd5258cd764ac8daf343ce4790ead0863af43121aa527a37a11628f47869668f8eac00d80b6bf9906663d7a2899c1cb678cd7b3eb3bc80226b8b13b6e46877f38f07c3d9c86d3368baac4a6f6b93ccebcec9811474b6a6a4da5c3a5966571eed05edcc0e3fe7cd15915c91f44eee8c149ae451f375518a79fb600a971a39b9433dfa19f91931b1932275747c262eedcbd27f1
+SIG: 1a80850fcbd6e643c6ba8eb684dbef7df015159228daedcf0604709186054db185aa7baacb09d6caad01638eff8e468735a60124de0c5376e94340e541a98007
+
+PRIV: 8d1621eeab83270de857335c665bbf5726e3722225fd016e23bf90ab47aeec3dbecdbc024dae6a94ed4e29c80f2aff796aed8feb2c1b3790a8c72d7b048a2c61
+PUB: becdbc024dae6a94ed4e29c80f2aff796aed8feb2c1b3790a8c72d7b048a2c61
+MESSAGE: 97facddc82cccccf788c31b3305e93eba956f89613e6e53542b043267fee544c2b0a8ae8886a31b9d321a63c27623baefea840b2a8af5b2330193ffb5baf873c335528afeae2160163c851c5a2e58154a1b0569c2d1366c0710437623b0e08c686e54fc279ed4c45f3e856868375f78224c777b13d75de10d79173552425d15a561904155f2117b2f14713eb0b04648a3bdeb3302167d1973e788a06cb00d48ccb269fa71af8ba68eae55dbbfd9594d5c2b4dc13ae0321718561acdf67dc8cfcc25bc46bb66e096a1941d9335207d3f7d11e8904904fabe3a50a3883e7078047df252f38b67cd28a6ac45c7d7a1d2a1de8d45747cf09301e01cdafd0cd99a6e91b704d509fce692fbdef2f71a5ce0b35bc15c65f876824
+SIG: e08d6caa5f39327d6e6652ed74dd1a37844b979f5cce747a606f5679f4898bbb7643df7e931b54a2b40ebdefe83003f61ca0f11112f023c6a3e8cc18cafe5f0d
+
+PRIV: f2735d50ee3a9a65b58c8acf551663e98809ec406f73e3e7f4e73bc4ea923874df48a5b94a07af3c2c99b8388762243233c850dc175317d602638e5b86ab49ed
+PUB: df48a5b94a07af3c2c99b8388762243233c850dc175317d602638e5b86ab49ed
+MESSAGE: ae31e94e7197e4e4d0239348025ed6681e513ce1a6e0aa0e5b979373912150ef113e50ef0569c483f7568c4bbc4703c5dacaa80a0de4e738383fa1f10d6d4071a31b99e6485143972316c86522e37c6887a1c307b29b0dd6f9f1b438310af9d8d7346fb41f9b2dd2e80b14c45eb87d4ed48e37a5260b52257b3e99787a13c55392ba930c08e0240e960def0c29b8550745cf149dee53a5d174ec065d2d6677dee1fc42057062c34e27ea5dbcdb861b9f670c6032c7846cec8e87a7c9520e27967b0186ee71b77ed6d029bbdd70949cec4a709329fa37fee002490cc1bc4c2df6f763f9858f33d750c5b505a67e237063c0486f9456d3c620d9ac7c98f1381de0effe41c18259504a150d68a6a28b0a3eea803b855315c9e0
+SIG: 6942a7696417efaa591b95e11f02d763bef5279b932a8e2a7cbb9f583695c14ce5cc556bec66799b33cb592da4df2735f9eef2c3ceca4362164b6cc93da4e105
+
+PRIV: cad9d21a01c7e1d15df2fbd79c516eb8c3401e9fe28467cc7b21679d4e331a3da7b55c15d6790b40536fcae5ad2892cd66b18689f499c1fdeea66d4a7df39424
+PUB: a7b55c15d6790b40536fcae5ad2892cd66b18689f499c1fdeea66d4a7df39424
+MESSAGE: 70702bf19c919f9836defd7b846fd9992d8b7eb2e106aeb71e60a31b4ea25a41b212dc7de7c91cbd613d58d0595db833cfe7e50584f25569602c7744fa675d156d0f63cd2b7c089c8a00686a437169826a12dc485b38c068a8007142e5163747011a07a415683622ab1e23ce577c732ba14f401fbc3043e0693a9205c19a92298a3d9b08fb7afafae0a9f016bc750ee631a5f5da5db6f9ba2692c74caaaeb4d097e90e3c02d2e3a7fb3aa000040b7c17b74564e646bea16bad611ebc0859a3828804ab4f5cfba417d254515ca3620a3ad683c46ca6267bb49539bb30e369087e67438e9489562750dccba3aa0b1b0a6c267032d20c2adb75e68df1123b5259bfe4eac6cadca6778138a37318adb30e8d669f3bc9692cc74b68
+SIG: 31927d01db9f2472f4df6f63c18ebd83c2b1aaf88d580e848854df8cba6395d3da7bd6bb9edc1fce1c7d7e1360558fcddfa93915be076efb8ea2dc5ea7b20d0a
+
+PRIV: d9be842255e9a16b0a51a8674218cee7cd9a8bdf343508397f4ddb05f3fa00827931bc6dfa3324943aab183d1285515919399ffe0b710677f0915d3a5be51e92
+PUB: 7931bc6dfa3324943aab183d1285515919399ffe0b710677f0915d3a5be51e92
+MESSAGE: ac6c55b134663e41f02a6dcb8549eaa1c013f59658d81d812f95b74009513723671945e1324f90f8a3f971369181b587bab45665f788d663ab78140c5a22c1c18d4afedc7448a748afe5bf2387003c1d65ab18482ef98922b470da80ad14c944951ce4aed37390cce79a8e01b24c7dfc1141c0eca2c7f773ed4b11806a34615513486e4ee11af08078a1b4054cf9880298608dd9b3faa1a242a452fe511604b3102c313d14cc27c6f0f8471d94555317eaa264cdf52c69e18f461e47903d21298716b172ee9cb178f08ff2d3c9c162121c2ed21d8734b2f0630d399146cbf76e028a143f2bf7bb50af0f57b9ba8021d264b00c6662f84c86cb6d5952b3d241f7dc3e700c96616cbcfb0d0e753ffd5d21ee320e65e97e25cb8609
+SIG: c93845658c9560d2c0e28f282adbd4652bafd3bb2edec17c94878f7b94d3c77afec906ed292a8dfbf5f8e7c118e8f2ca33dda7909d9b695b8ff5a1c0e97ac807
+
+PRIV: cfc48cc6f65811fe7d7bba85d1cd84858fd6f7edd638f4f552363ee7685f69cad29c10694c5e8e3f3447ed78d34dbd74a2b301373ba871b5850c333dff7bf8d0
+PUB: d29c10694c5e8e3f3447ed78d34dbd74a2b301373ba871b5850c333dff7bf8d0
+MESSAGE: 8e7defb9d16d036bd642cf226e32773e605361c5ec4b951255788db0a042c63e5a4367d61524f10e6258991325a39ab6b03612260c3fe3df20b34202d34395bd4ed40bd61373df781a4c8bcfbd15301060f07437732333d8e49736322dee6b22438e787d8856b70c26ec57d6dade9c3c28e27220c5670e393544ed095937298dc3adc73865f777e90037bdef834716476d78f4e6cb4961a4c68a8a836338a9f5da179c4d5e93c3f70dd35eec709653dd8de37996b12056d4eefcb4b6b3c13ba984d832275c4386ebf4a8ff7f078be3d428c1e0d9b162381f06a5b7bb12704003d91f25d1d8fd43626ce70fff59d2927768a76bf7f9ef76ff95489f38edcd1c9e9b8a8b0ef66c32805776d5ae9fbd84a7af4fa6563ec70ac5733a44
+SIG: 80c5d51e96d1cac8efd3459825e79c1e9f65af701d1d29e1f95b036707113b77984b7b3350f04077333c957f8fbc7d9b040c362651417b9899027cd33edb1103
+
+PRIV: 15c9f7c4d84a5a479041952e6a8cac24e76fd2d275c197e6b521929b43ba6c5d8633c1829d29091df71fd5c0ef640572e4b64974cd097dbebbcddeba041647c0
+PUB: 8633c1829d29091df71fd5c0ef640572e4b64974cd097dbebbcddeba041647c0
+MESSAGE: 11730dd45dda80d84d080d92e9bddaeea6878e4a0b3b512d9ea733808e1cef51d49048d6c78116a4bde3c64aceaa52beca86b331ab59e9185c70286a02bb5dd04f5c7f4e9c7e445e77458565f159c783dfd4d976a910e937789d2141d416ed3a7f608d26737a86b20b624e3c36af18d25c7d59b8d7427ec6c4d3d438d7ae0949dd7d748c1ffd6f28e8285d440422d22a3761202e9584f5cdb3504547aa4b685730c982cba213de08020a5e4e46a95fac4b481bea0b630abd030ddd335a20fe2cf7094aef4813956991913c6821f4b5410df4f133fe63e22c08092a0a65972722a27ae42011a807c327b417237c540114eecb9f0e96cda5dcf0246f1d2717f49b9cea9dc6a3da9b396f0270529226f5dcba6499918a6c289fe055fec8
+SIG: 1e36bea5a583767ebd80306cab233155b7b42814b43473cf45cdc5039c939744a9694b87220daf4ccd29f25cea405e7c08db2ef17f3f034dbb49cff60283e306
+
+PRIV: 6d2d0d823f294746b9a5512e14e73c1d855b5e4bca65fe817729810cc5ef840d1b6480a6a90dfb472984855cef6f1ab31eb7b3f13c8ac00fa556d20b53e5ae17
+PUB: 1b6480a6a90dfb472984855cef6f1ab31eb7b3f13c8ac00fa556d20b53e5ae17
+MESSAGE: 8772721f72eaf7f73040c068a7c3753bffca7dc2d0930c6525f425e6005c25cd4c0ff5095c9c61a5d8a1967b8c86010c884e509e6b1670f79046e22979ebd354734090d3ada21435c1f8254f7b5222cd5564f064e977640366449f4e5008f870f9c4840565bf4fb5f574c9774ba2568e71a9ccd82ffc59b694f26e7de4ce2e3fd880a0eef387931333ede00dcb065e6d0f79591a2aa956df1948a265cb95750d8a233b15c288a05487c515663f93e740fb1570fbe4bd80c68e8d9297345a8a01cdbd88f4a39bed9c5ef09f144bce5de568bf3733bc53b2039a29cb3e194501adc1c10e86383aac8b0f85c67a6689bbe1470a392476313439ca88d98c021c0eaec25fb2f9a160ce5c786170be0238fb8785dd33bfa9059a6c3702d0de05
+SIG: b515f49eb32ad478692df88f07b7802c6e0e5327aa08a6366e4cb1d1e26f9e65fc81abebe2215d649100f27598273a412b624e842d8130403797e57dec975a0a
+
+PRIV: c0cf799af7395bf27bafa36cab437045e39c903bf807548319ce44f287494fbbafbf550ca290c905bdd92fc8831ebe3dfeb6daae4f56005253cc50951e50edc2
+PUB: afbf550ca290c905bdd92fc8831ebe3dfeb6daae4f56005253cc50951e50edc2
+MESSAGE: dbe65780e968de9e40ffb57cf59a60fd93b3f9a5e7d8ed5180adbc578ca1bc48bd9fb60a1324c9c2c1141479a0dcf0f1d07e84936526df42333c0d773e3fed9e4038de5b95ad905c92cbe040487bf55e10e1edb429a0ecc4e0e8d00a988a9cd53e2eb372f4fc4cd9537b269ba3a23cefbc8df6476e75434b81d93e8891bf417c82e363f3e4abf80a4f73aca84ac7df6337f536d63d939d92cba64be742221116069ef251abba0b00af01718bb580ddbeb79973ef10a68b4d0fa023d6ebd3079d6b32a1aa20a21e9202f27590c3f0c0cc253073c3f822aac459d39f50758b70c00710a3c98438416508522e512adaa0afd503a7ceb04fb94a4a932ce80cd5a7f11bb861263f58e5749d542a110de7c7689dfcb0c51afa9d54a58ff89f3f67
+SIG: 5bba01a4c7b25542d06912de70aa1e220423fdf8338a9e693395cb6f0dc1fbfd018e3c77e50aef90a9080f30f1f5792b2431078fe6e3e00464245e17cd8dc107
+
+PRIV: cdaa50e8527dc7a50fb37e28fa8b9568c37e8567e0b499997b9aed676180c3b07c56e164510268c182b423747904f1d3a5809330f6e1b29266ec46e73be1550f
+PUB: 7c56e164510268c182b423747904f1d3a5809330f6e1b29266ec46e73be1550f
+MESSAGE: 94fcfbaaa303dece7b908f874cc5f095061f1754bb35780db666b63ab8290811bf1c521a7f8f785ea270dfb39d0d6ed95ab71955a11ffaeaa268e081ff3e4f2425b41880a987151e678e89111350942d820c3eec36212426663be175e5286b4ad1cc804e3e3a03b9fa3e82838ebbc2615a645f2ca1468ac4a1cdbe523761e83f4381b0c8550ae5e8c8cd1fda57191436e27cb883bc64be86a9dc6110ef3401d88a7debd1b701d9c257a6826cf01e9e2922e3ae577f2834275fb0ecda80ed8cf1801e0bc5e01e26a77c48bdf46a5c4894d22ab53e741827e24bed5f0750ffad05e53f1d5e61dfd316b191d9797ef713131a8b430abe3fac5f3c4a2ca021878b15adc8c5f542114260e687a9d199d230c4e0d3fc696993b59ccfa3ffa9d8d2fb
+SIG: 137bd10a50ef609384fe668768fb871de741ca0f53ff8477d7ebfa90aafd5e2681fdf1b89250463c15db8e17a58825fe9427de089c34de13cd07bba18d4aa40d
+
+PRIV: 0fdea9bee6288f947e0adbdda4dfb2baa03891af25024a5e138ac77984d0050770abd86430d7e8d63209c8b373ec4e4b79e989e6725facefbade3c7574d23cd0
+PUB: 70abd86430d7e8d63209c8b373ec4e4b79e989e6725facefbade3c7574d23cd0
+MESSAGE: cf72c1a180a2bc37d8478d9a7a39acf03bf2a50790f7902f81121222d31d3ec916f4f24cef9d7c41dc021b0e8487bb892e47305e54520303e89b30b263dac4a9ba375d46c40fcf400535c959d2b746a7fc970cf65b472e84b5f1d0ebadcfa1aed6fc47facce16a366a3b1d6e516813c1960975f8f2b43042fb4eeaabe63c6f65db45ddb7db888a19a9d7ba6ca479fcd70c5d1e970f12c14f4d24fb7e2f357bd3a94aa1b868ccc0847f2eef21853e253bafbf07c4e6176a1ef077167841ebbe5629337157f39f75c71d21e7e96c51a1b16fa8dc60f0b1279fcda2641fc8591e3c492f15bf83caf1d95b2cd91332f1b4202fe72862ca2ea2ef92c11db831d82f8fc3d41fe29a76c211a758e2f71bd89d2c6610f201429f348d56e10e3b7af53e27
+SIG: 80c42dd5df03b285a86ac95ce6669f786a978a813a9d7b8c6a23de76fbd09bdb66c5dd1cc9f1a176cba388d5051764a32fa27f0028ba4898068bd01a3ee17208
+
+PRIV: 03d5e466f8298ab5438a30976d1322a7215a642dd5fb4c3f8519409a7522f0924b3ed4db080e2a452e16912c14504424920a60975604e4f379258d1c8b193d6f
+PUB: 4b3ed4db080e2a452e16912c14504424920a60975604e4f379258d1c8b193d6f
+MESSAGE: 1b47b70013cb53e1f8f4971e0f39563ce87edbc2cedd99e5a35585df8b00a852f7b9c97c7e4a5465fc5605ae8c5c36570a99201a7ad6031287ef0c7b2ba6e57b056d0fc8d6ca43bf6cbdab098934b403197b525d22d45e6b29c78f8d6183e41ffe197dae25ba22b06669ae05badd7e1da6932a7d054cbab3f54e5146223ad8671231bc16fe62679bd2817a6b80e653998c4949f81ff53b6173163e11da3e6d3c76d84c713225b4173d6bf06a85b6988a48be4359cb515503ca563f4353f8e7d45e4d94462c89a04a00f1b3b0ca6422d5db029c507d464834a20c78a713661d84edffc496d69282619894437b4487954cbea2aa7261e6a62b6851154a5d25fb6b4f09c59473d385ce03e91ba865eab66c58c0abb0b7a78e4be927e55460ccd70d82
+SIG: 6d7e4658f26f337c98e03f13542e2f39440ff7bf8d88f3f6dfa4d64948cd96b79051492fc28f65f2cc0d23a0c4d5e2307bb1c47e11e53b371f091b69f80dbd05
+
+PRIV: 76cc18a1dafffa100586c06a7b40f79c35fe558c339c2999a5f43875cfade03e4b9da8d2f137dc6c857a99a5998dd89dd5f05971a21e8c776670eb47bc1270a5
+PUB: 4b9da8d2f137dc6c857a99a5998dd89dd5f05971a21e8c776670eb47bc1270a5
+MESSAGE: 4522b1d82373f7a318221e7e57617503ddf44fd53997522a1d963c85b708d0b245de372ad52ec7f54f6213d271f7c91d5a1d36d134db389df0b081a06bc0c7a4875f724092793172c9115641c6d054f1d992e0fae4df58695f0ea3449d7a4b3a8857e19803fe49b6d52c9ff3746a574a2756956579f9fb809a0edec92c55e95ffefa3d05f165822f464a21999f29691f6744ac5a3ee49017880645e837edebfd2e0f24997f041145a72e2376ada283186ca2b836362977195baee30a3acc81b243f3ee376a2c4764c783667a4b1177e7951d3e3c7be4f1bd7ae8c60fd5fb0fd91f0c1c14d0d2327e8f20d92c0dfcc53870e9d99fdbf9dd9a17e882509ae7baa8653e39edc8ee569000d624cb93a0754a798d1f811f6a0ef5501a17bcf25fd0f91626
+SIG: db74751c66e6b1866044dd9ae99f19e6334f179e79d8b8e0c8cd71d22cefb9eab7e3e7a9c2da225f2a9d93a313d1cbf1b7fe2597b8d702bf3017a6a6bc7b7b06
+
+PRIV: 71ad980d58ad8e7d33306689358936a372d5190b24ec7f9bde749cb81150efdafd35a75fe5abc20104691a24a4659440b55aeaea902ac3be274af27aa8312869
+PUB: fd35a75fe5abc20104691a24a4659440b55aeaea902ac3be274af27aa8312869
+MESSAGE: e87ae073ff5dcc5485a19940e4e3ff263a0618a9025ad4032dfb36d171ce881f71c18a49210eb45819806142e2f00db3041835bf2c3bccf1dba02b8b5a5bdaf8fea316c0623dd48a564ec166f037d587c8c01684e5e5c0ba9dba4d23b49a0309244e282a51408622edb05704747e0cdeec976893777071098972c113a8ab639c31f1613233ee460eea8a8c10e1e6e152214529878cf1adaeaf78cf19bac71361815bf57955498fab4f0f2b7586c86f9f4c2ddf8972f9b9e0eb636d84bcc14385b2d038be55a963702efe225a50bdd0c4da92a2a6a09100ea04a211d396458dceb4487116837d139eb0f122538ed3986ad0af4da2dffc89f3269ca88538086e691e5beae9581e7c63d8e612da2c47f74dde1d94951eadb0df60c3897d2a3095c506093b
+SIG: 81670b1029e481e9ff3c171f05c16861c846ee79cdf2e21e3bf952bcfac97565f2b1dcedf69d2e7eb35caf5662e8bc671fbb96756a63a596264d1b7f4af97e06
+
+PRIV: 61594e24e75f996b4fb6b3e563f6a4f9915cfa65ddb199b01fed7f8ed7824ecb8627d2141579cd2521aa076800ac354b9e3a47d71cedc8547434268225e33005
+PUB: 8627d2141579cd2521aa076800ac354b9e3a47d71cedc8547434268225e33005
+MESSAGE: bc01b08c7caa236100a012a726477d0ec389dbfadac73d5106424c5d1f3d1cef1695cfd93a7062ec8bf1067047854920162f651357bedf1cd5a92ec29bdb5dff716e8f6025515a9549ba36cdc35ced7c5c0c368e6cd92f2f10ae146a20728c374bba509641ce88cb42fff0cedfd9fd67f310f9d01a3f3690eb21db17bce67ae35c4cd24c209f09f044759d8d5a7d248e2bd966524ba8c0c28974726b43bd05de843433cc400598922974623d9acbfdc761c4c04375a952ce54caffaa96acff6d9dc278742af476e1865cb8c20d13d1c1900863bca231e44c6b0d47cb41d510f7958f48f304d03da033484a3e1f273faf6983375b7d3be03d8a0a002def6365beb2fa8ccf1a94987adcd33d0da1177fc5159b6e56d004301e921dbc12ec0a73f413cf2c48
+SIG: 6302b3ff2710be306c92b9aae30d23c3d4beff394e63201e6ad11713345c4fcb5cc8d3dd10adfb82bb11a189ce7ec3e4222727624fc17881c14788d2710e1608
+
+PRIV: 54e6bbfbf8c06ff2c066318c2ebf03d506547bf43c2d7a5d4df305a3032b71383b71aa1def666d9188f403f82ed30454aba5bc9f470f6eb988da187c92523284
+PUB: 3b71aa1def666d9188f403f82ed30454aba5bc9f470f6eb988da187c92523284
+MESSAGE: 0318d7cb4805af9821dd3f914b0e076fea04a7d2db3a59a00affead3325a2be40c1f87f53276a8552604f228b976e288b9be906a7bd25b2ffab8a8af5d0f6e08786fd034e2fe1eb7ee033979860dd1e5327287e9e615f5dc5a960f17026b56842fc8d44cad002edc8501cfb956001502e4ddc81a7700d9c0be88eb4aaa64a6cbc39de82f13c11086de1a4270d3af97284bac1caef1d3edaa1071666bd83b2ede3962d98b9d93497ddfd8e97dab3089950cf30ed11db77ad1437a0af5889d8efc44e612420e3907267df3acff4bd3fb6e8ca5badf8e72f9de39528653058524456a81da5f84982afac34bef5f71e91f8f90938a6f5f1f287716de56a0946d261e87bc775ce189e41a77baede7320a3c608fc971e55d0a773c4d848d428637f11b4e4460390c
+SIG: 3df4d09079f830e3f982283681ba37b50f3c73de2c5d22a291358ebb1fb854e510f63f9a48e9fff7fd8311302ea3e969394e6d49c9e3182054942f6a744cee03
+
+PRIV: 6862061be0de9dfd998118204b2b98db3ce7d7e819dbc10794af0ab2b06e84349c5f7c2265dde1b25e4f27ec71580d52dc89f2c3a712bc1ad5d6d69e711e08d4
+PUB: 9c5f7c2265dde1b25e4f27ec71580d52dc89f2c3a712bc1ad5d6d69e711e08d4
+MESSAGE: 1740dde8434a0d689925679b0c180300cdbd0cf6a89ad8fde34653316cee4c571a4105c9e9e0284238fef2c38a09157c5db94340571b390adfb69ff4c0dc5053253a679d42cc1f1bf1ff429229ea0a5044c6f79564e0dd287f53f015b83187d9ad27d91039af062c437b1575a0eab6aeb8aa0d27b27665d6dea9041ff9963a3118b3298a8544e3fd69ac6877e3e4052fe4422bf03560b2c57ec531ee8b5ff53c28dbde35bb45c35077636e6f841b59d7eb77bc7791b6093858a3a80a3aa6d778dbf53db9d06119c50b71c791c0495c576d1b59d396873ed871485352c8299a359da5ee9d7f36ed1455f89851a30851bea719685aecd08f25562609dd106630735277e1d6519bb1687de8b8c68b9671452edbb3491da264cdfa0017c512d2769759cb925fb664
+SIG: 965edb34e8ab8bc3204a3201d22186372de4242600297cfdb57aa1df074ec50ddf10105e9d4c89a266c34db7772aa94cba946429e68ba62bf9a0ac90f5f05b02
+
+PRIV: b2250bbcb268d2477c8312b1900fd99982baa29a68974fbf8778a1228dc9755044aa8df1181674b05ade980f7eddbaf3bd7422a920287cb2d2db59a063eebf74
+PUB: 44aa8df1181674b05ade980f7eddbaf3bd7422a920287cb2d2db59a063eebf74
+MESSAGE: 7ef0ae1336a6fab37f99da5fa7d0dec7409c072623ead84f241d53d0596b461705fb1b3c537d36b89e8960febb4cdc0d427ce2fc1be58dbbce151e35acd8b6ace40a19822914a4bd8c4af632f136418ac49b184d55193ebcc32d0d798709b1a8fe294fba8a1fe72d976b4400d4a393242311b0f8cc994e89475b0038ae5d8914938e8f6e87c6f50b9d656c45d7b14231efed97f3c90668913670bf5be2efd5c270c7cbaf01e8572e9800978dfe2e10a2fc0440b855629bf9cd409ea941cb69226cac771b15ea77c0326848806ff8d2e201e6e26cd5f45430dadcff8f59c321c1c9c6a29b94882935447d3e6c2e8804b1161576bdf0320fe53c307d9cde426077a7677cde3c1bc83e18e60a0c4ee6dccd877c213a8e4cca640ee04929804570ae1f96157c04357a
+SIG: f2b8d92ed51ebd1000bf9dd3411a9fa9e7aee54c4c86e24ad0f9ad5c55643a12d680019ca03f216bd4bd32c9ce1cd8a528c3ffaa5d5b1dc91a4be56f0e2c5e06
+
+PRIV: b809361f55cfe8137fbda880fc62cbe44c216e141893346302b336045de21878fd23e42ff06644ead347abcc1b3e03b0e88593b61254981dd8ae59454e61b3e0
+PUB: fd23e42ff06644ead347abcc1b3e03b0e88593b61254981dd8ae59454e61b3e0
+MESSAGE: 17ace197d083aaf1726f53e5ef81b5a8c09222f260ee5f1f5404ab78d900d489688449b843bad3c498aac6d80b4639b76e6e81c55276a6f9c7cecd70b71aaaf2018ef76c0e30154aae86a5c86d4e8d0e4ec68cc427060bd56514f7238086bbef5bfca1f5671b18041838fd013572443dba48fbdd95ca740b0daa4327164a1e34677249708f77bd793e7caa6638b5dc9fbe6f0dfd4120209097209c93cedfaf21b6bf59ca6e99e6209639444f0e827bbcc0a61c3a237ca22a283213223ab658e712c7556238d3a5fe31722d65f5706ef6d64d73232d3043220f14e5cfd3c2c83a83d68e20274b6f96b29de040cec8475030b6a8a87d29808dd381795c3d22acf5dc193b720d95a752d9f123c209ffba004e48dd06dd8c9e172bc9e087d80bc5216c0b0b6e77031241
+SIG: b5b5950d3772d2eef88e1b0f5df5ffae2f2103885e71446d346fbb5daef94967a6b7b6e4be885110065876c665b7812de46ad31ec3bfcbeaee13ed0c1e0b300e
+
+PRIV: eeef8074c2eb9a1cee2f2d3bb05325546a9fb7cbe44b599461fc5885f5fd9cac9b892941a0573b7a1673ef480f081168d9b7496a81f9177dc427ca1f84cbbf7d
+PUB: 9b892941a0573b7a1673ef480f081168d9b7496a81f9177dc427ca1f84cbbf7d
+MESSAGE: 9ae39feade905affcbedd2e72a6f2429b3d1108e5bc1a9dbaf490a6299bccd94acc413adacc918b14afa85c78bc168cc00740c3da0e08183915f79b7fe3868ce2a7e886b32ad45009805bfb81b8c07b3b1022420c0f009b889d7fc22fd1997ae34198438ca94778575122fcaaf96e6502c33a75a129a2d0dbb073d93820d9c96683db318990be3fef4cafc890afbd9b1504c7439a08a065e7814ee4f9b6f57ee16baed3f0e3aa35dd23d3528a458919ad77048b4e2e6172346be249a50af02bc6c853304c208ae0ba02771262a0d8a465f71fa0635e53eb2ef0a847d56a0bcd7dd3fe077c92bcdca3069a4a682a2859928315ce3eb445c6072a71492ee82e172a20be0b648b756e6c775376f0c7c3df8e64288089c2f81ce9593c6e08bb1cc1b27fcbd392fc7952c55
+SIG: 6f7101984fd6892e2144b7d45619830caeb6713bfab4eebbe217c5becd249bd9d752eb76e9fa995e7c71ff7df86bb260cdda173ff5deec6af204b7dde011de09
+
+PRIV: 61faeb15f857f6557862c8b8c7ef41f80545520996fcc1127b8c2491822201ae60a290c0fc425a0874673d94f9bb1400f9dacde9954f9f5b05dd48ab747a3950
+PUB: 60a290c0fc425a0874673d94f9bb1400f9dacde9954f9f5b05dd48ab747a3950
+MESSAGE: 253b566eccb563bd6e480c69739b8e372519a3437254e0e5029cac86c71638f2df2a6cf9e56db2569934deba90db75547e3671747df64d6f2aaf3c110fa67a7094ccbe4cc5355f0d43235136ee26dbe37f4225d3bbfe245595280585fb548f894e86c516102580291fa7a02859557fb98eb588870828b0990ae9d74f3831da58946bc7a5ce1ba498b4e8be8989a3b50d7e8789f56b8b4fecbc2a33bfa3ef591a0fbcd932fa93e19f3a812ae5e4e3b4b242be7705a5874af73be310b0058266a378f23c1348524715b0ccc18d6634b23636c316ba6a1dd2fd5092c06716a717b54d0eb9fc7f636f85bbf225a2cf035b4b7cfddd75351682c0576c6b3ba5a1c0b25ec594e7709dd09a0079772ff3acc67fb6c1b37bb3742b726e77e80561d9ab73160b73362581da5b9c7f
+SIG: 31f90f50b2dc705f1d92f12ca9975d76f1b2826ada3cc185b0ed6c83860777bd8c489b59855a91f64839d49ba467985abb376c47a4908b271b8f77c58d01fd04
+
+PRIV: e6b9cd4da07cb34f30391cf68f0d87c7cfcf68f810ffa40f9739c95deb037f71569ede0f04630b43a04c5a66b6a5636b766c75965984a7477e15491960fdd864
+PUB: 569ede0f04630b43a04c5a66b6a5636b766c75965984a7477e15491960fdd864
+MESSAGE: 69def0523afda696f8448f9c1143abc26533e68695a090df0d9e43d0c0eff43583e6f709d2043c815fbb3f96ba2b0dc3be6fecad5dd38148788e4a0385a9fe7a921fcb8ccee0e4d3aed4bc3d216d84b414f9580b02820c03d92e675e685c4b5851f363bb4df97b417c3fd90022eeafa20dfbe82964f2ff073d255758fbe567c76b2c35e2b09f8a8d7afa32c6f5ad01bc3ebf6e210606db038ecb6820ce1ea4dd529fc1adfbc2a138565ac6d0f4a4109bdd47b8aa6ef4b8bede454680d1dbdb75fe1eb2e548d5de7cb6d792fef3aa0d8480a6030b30f104d7e76b58e9f476ebf2cc832923b50c50c111c3515fc518852323426ca778a596d3195da8585d8c3aa92083313a6e6585b70c98b185b472798a61cde77e62ec272f14b0d9eb4f22f9c7c05817da6fdefe7879a584
+SIG: 1e375c94bd809ca0cdd02f89ecec4e437732dd20a0a84b254eae889d8070e682d113b0be22e41e6cdc3be877680e7eeb7f0995e6622dc0b434fb0949dd994b0c
+
+PRIV: 4d9044f17b5a0977dc5aa9916a924300a244a1ef7f060277ad4978351ea64291ab9c0692a606b2567c19c30f9faa3b4cfe72fb237077767b76d3b2ae1490a6d4
+PUB: ab9c0692a606b2567c19c30f9faa3b4cfe72fb237077767b76d3b2ae1490a6d4
+MESSAGE: 7c8c7189af67327af1c6dd2c30e975f190e3b38d008b4585167e0d450740d46734587f6d208784245cc5cb062a2a277f17ebb2746f9bdf4a8237ca479ab0a430177e19ed7dd3622576b14cdc08282214fe5ee4d76b43c16ac90864c51be8aed45d7b980df7917f290fdf795846465f27fcb7e5730637944f0577c92f32375e995bc0cda9d7196f2c0c1ac8b80d12a0439963ebd2254c347703575816e7964c13d44d629280c312ea265344de38f3b18d9150f8f924afb44b6bfb9eda513d59e65e2ef18666e6c2a21c4018665befe92cae581d3cb14e23e97d830002cb90931ae0210068af394ebe351be5b817f3674bfbf40049030e4fe505d34a1d502a2c50d8e638e926c230676b7edefb6bec77b1c0ce609325287ba5fdd7a9976987bd07fc6a4344956ebf818f08586c
+SIG: 6fa48aea4d5b9af65af964cdb709443a11fa84f7d44acddab16e04a6fcefb27ae33c05b36da13c23de517d6e6ac574a03ea630ba4fbb958131129aa7f1354c01
+
+PRIV: 75ad76bb4c0c229a5adc79e444b13f88a96459862c8cf0ba498d0c996af94a7af074dd2b9c1c309105ec951bb5812a91ddb54023b3809ab379c56af0461af617
+PUB: f074dd2b9c1c309105ec951bb5812a91ddb54023b3809ab379c56af0461af617
+MESSAGE: 0ca8c1c74128d74e9d0a7bf8964291d074917f2f9920efb911520567642a50a615abcbd00aed4abbfef1a983cce333e1d0df3e6404fb9043c6803914cd5fffbc66a0790c7878a24089a571f895662a1d18be3f01ff97fb3323334b6f5baf96551448e4090d033c464294d09133b151d5b5c6321b50e2241de0ef6f882889ccf4ad3540d5a1e3f7548fb13be71c16516606e79d0449c2a08e5dc23148843c84e97ed24069161c8e75208f33e95b3e10d1d49a2faef9d986ab62809f62ad39c7cc871f375a4f5a6faf104d7e11b890cfb0589902685216ec07cb8e8e9e7a7c43635e23212b69ca3b7ed54f0b97949e3d9a6662f8e4b3ab09cd495294c331c047d86ee785ff658bcd7fcf9c480605ce05e810068d60fc9b26b5f063eb9000d2657a5094284ac80f1375d0b66d6f5f
+SIG: 0c4643a8be6dc22f4beb6bcc70c6172ec7608378653cb4e99f3ae795eadf4e982a297609ca7938f5df632b095628cb75062d3d51fc0f3323bfa7b22ec4d47205
+
+PRIV: adc6e9b2e103b62c24ad4346410e83a1a0bd253e4abf77911850c6d9666e09f9fce316e33c910821beeddd634bedc58ee57999a76ece384605283b99b543b78b
+PUB: fce316e33c910821beeddd634bedc58ee57999a76ece384605283b99b543b78b
+MESSAGE: 8cccd98ebbf2439ffdfac41687638faa444e1ca4b63d13e898eaa8355492f28813ab813fd01510e112be106b2045d30f63335d248904d521de181abac03e3d2cb2d16c44b3b012a0c51f9901aef9056c724d7a2c6b2acb0a07555940e4c6e21154890611adeb6489f461d3e5ecd1af5a4d2b0adaf41747436eb414757a8fe4775674e3c6e5de4569d6fc6c788e10905eba32c270a393e6f721a765294e2ac99a9b6e534d3df08d1db97d602ac3195cb0b77f5bd4acaf737fadd6991f0688abc74918047574eac28289739a664e0e0e20574a2c25fde49d14539db1cedd4a9204a70acff0a62c8f25cd768ffab15c4db316840a4d1bc92e212670be07c5bdcf537590607dfbbbb4d9f98b89da0b4df7d88f3eca4814d16bfa20c8d2fa94f9f259f2ee2d3a83c9e4171b1a262c4b99
+SIG: cb017d6d2682c9854366259aa35f30d491cfaa930998c297dbddc6aded5b3d401cf76d80d8a2764de131718b6e0c481d7196bc72579716b0c0f6ff053e68c50c
+
+PRIV: 37fc1beda4060b6c57883ddba0776c2bcf5ac28a651326021cca97723730fbb07bd7bf1c99dc82e06f08bb454d8fb288a57927e07ff1b12af15ee2c12fbb6b3d
+PUB: 7bd7bf1c99dc82e06f08bb454d8fb288a57927e07ff1b12af15ee2c12fbb6b3d
+MESSAGE: 3dfcac0265a024a83cb932674489a163aac314bf3d969f27596e451733b99deba5eeb779210baf95bf545a1ae6b8a915860693ee890f939320e06a844483d18c6a1bcd03c638bb7d1fe2a82eb448a311b1302ea6428f54a39f45a4d560be1557a2b254c45c137f45cc68356836e21bed0b7f73a518ce09db0be393927c339bf2a4b5987539404ce650284de12e3b553b262efe23848332ccfdc35e791a0ab43f139c71ed0fcb2d173bb377ee46b1a9dca9277e77df855f2830251e31e26acd86763c8d7eac22c882fc174f2b5e75ca6ad1ade03f942bb2a13bf541906159158c68363c7480c5b27a99320f8283a2699d4369c071c50dbd90b7792e4772efbc0b195bce84cc4dcfff7072a48968db69f9feddd0f9ced659eb5db7167f35f988cec114887dcbfdf27d02d300b3e1abec
+SIG: a01dd65fada27039f168b123419d8abfbda48c572ece24fda06e1a5ec31e084f4ee1cbf9961e88ed51e189fcb7f5f235de1e5b28d08f2bfca190b0f019ecc207
+
+PRIV: 8d42f4ddd2bbd2b827b0a0d31d8f758ebd13a1b9b3712228948ca610bb8858e5b7354898794f9db0a8af6eeafcdbdf011d3fbef0212ad938a4a4ad27ab16ebbf
+PUB: b7354898794f9db0a8af6eeafcdbdf011d3fbef0212ad938a4a4ad27ab16ebbf
+MESSAGE: e3a2bebc0496d8974a8f4061880369314ed9e440c1b77e26fe5071ce694ffd2136db0c4d5e880e6000083a75c90d3cf72b9cf5a2b1a9002c2701a2ff59b0699a8f42d79dd8a5fb71a8125453d91fb80080a3f0a16584282f17ec7dfdc2e5c69c4d9bdf484d55944dae273f211cfb76ad37da45871365439af35eea1fbecd4ca679b59b5e01bacf49c7f4e5efaa406ba1daeb085482af5ded89dc6885ffbe3d14d2931b83897e28ad06e5564e2789baea81bd932aa279fe8e324b9a8ef111c2abe2f137d4bb50d8ab76cebc0bd982a23919751ad4d49e88eb14173d3310289a872317e4a451e88d54320891870f15b2d53324430877a9fb5b49bb929f211c5b89764dd9c3a595a1451e9f85a238540002566e53a99ed1e6ddc9b4853f455edb4cf1980d56bbdc1313a36e76ea9cbb048a
+SIG: 70764be39c6dca0f067abe1eca490fda951fd4e9499695266e270b9b05eae706ca8d1ca6a92d7c488ec6ad8ba11457a42a5e31702a9c2bce892dc40535c09f01
+
+PRIV: b62de5a1acfe4ca2d1f0c132afcbdae66fb29a02f297fbc2407fadbbf2454200b63b2d0bf355f7b6d0bac07403411c40afbbb2f707503b3fc2cee8a1c7d0a838
+PUB: b63b2d0bf355f7b6d0bac07403411c40afbbb2f707503b3fc2cee8a1c7d0a838
+MESSAGE: e659e51d7b193c4b8e2b3ed73a9d7557ed2bab6153883ab723592f730a914567142b3fa435db3219f83a542dc7a4bd805af666ea865b853146f8e3a9fe870711f90d12b0693492af2a1edf99a16458f781f1266ec437a5296a822ca9d69ce844b5c59097a2a56f3eb8fd273a636116db774300922d45b744657a692f5e8bfbcb06d2422818aeb51e7cda68acfbeda16e7c79580dcccde24e8e3d601b16e063b43a6d0d1407552f7504f5be19882e4ffe32344f5f473e73a8f6ed37b0d8d9e5e0a0dc9828395bcbd8f3a4e3124869249d058be0e045de0b1e12b1c83ba0aa227c95b82bf742c3eac0152b33e6d19be8b33a35bf705daab10622a90aed022ea6e439ed50a9308437929924ba3ab111ad0caa6feb0a6eb165824ebdb0866571efc07e5222ed8686b14d9270bf76b945d52014
+SIG: 5cdb00e98de73eab480be42f8a8a6163809a0d37101b6a5a4eed6a0c92030d09a5562c729080ce6f6594c8fafb1f594772db7a90a9e7da15896e82f70569390d
+
+PRIV: 9732059d7bf0200f5f30412430336be4ef1e3cae62938ad08729ce3ba714cfd40de8425f5e30b2b8aebb8072009a30cf0411c3c8238f4e4208760c56c33e434f
+PUB: 0de8425f5e30b2b8aebb8072009a30cf0411c3c8238f4e4208760c56c33e434f
+MESSAGE: 1a13e7ab603b48eb896fe17173fb31950b0dcd5a35ffdbe1371c7a5bfba593317589d9652d88797729180b8d0e515abfe6548f160421e537d5c94aef2b34c7ebb097420003bc0f361b423e7e14630a803c118202540049f68c9cf46fae0368d162e400d77bb4523cf6c753b975c245bc99ed2f413a9d06c2da6ce0cc0987b6406b809e8eb319033d2de9131dee3b1b7b5c95d653ced8fccf998da1768511eca4d3c5f735adab96503b3551803e4922635095ef811be4c08a6cbac917cbe6cd91a4ae5a330ccec0e8e815371217a3de62f2d2d61466219833f33447132f4d43350c58cbaf422475edb128c56d80a495726b1fdbc56551eb72d0f4fec26ba8bff5eed6774b85039a5292834b5d1cc1b09ba0a3954d29323673f5e71276a12ac4c579355bf1ecca48e6a716b9fcecdc565c51b9
+SIG: fba1749b641dd4df34664bc43c00468c7d75e84afad72de473fd1e9c87da15ea604fc2549a1a867fa80850e9c2a59cd99053886760a8d9764b84dd672676720d
+
+PRIV: 9c7f6f379e3857007e2ac6324cbbced57ac9eee4477813f83a81fc8cefa964d5a54ba396d687634d3eccf41c5782494f5f10a521a1e5d388523d80eeba5b0b2b
+PUB: a54ba396d687634d3eccf41c5782494f5f10a521a1e5d388523d80eeba5b0b2b
+MESSAGE: 3f2d3072fe7383e541551ea9abdbaeae6a464ae6b9f0ba786a441b2d08da5bcada3c5424dc6931d6b39523e2de0a0c2e4e6b5b8cda925e5eac938416a2c51bf13d49531d7ec7114b1c82feaf90f3f87591e397d02702f8ec1b30d99f5be7d2203e4fe4db2ea47e7b4589d8ac506248d7347466edbc96ea32bf3a6ea7502dd60c9e84902715ab2c6ca68f5b00e1d909d83aa6ab662d8aea870ecd861fec69f2eec0ae677d2995b0ed688faa8ef78244e0d1195697b07122ceaa11f5a6ea58fbdfa2e2ec2df9d18693ae96d47127556e91f0864982c13419b04a63f208e730d26951882aefe001bca3408bd9862748c6cc876c28cac3bb2eb3395818c2091e0fbd7a0b4468c6b0d00cd008c11c3c3ad01080a1f5a40ae2e4b0c3a071efc8e1d1ba6ace6d4df0ff19829b0c680b3aeb759177ed34
+SIG: 65685f9ca5982e15a22ba3c83a0348348482dfae57cea178f0780c057baebe4af632f984540a26019a7fb34253c9ece7ff308ada233ce0686347ab5b21ce570b
+
+PRIV: a478f35abb73727b6be6ee5e56eec323c9517882fd6919360ebbbf5d5cb8b83a7a6e266a54d135dda0009ccda8a94a4712ae5cb14761e8436e97c4b7814d8e8c
+PUB: 7a6e266a54d135dda0009ccda8a94a4712ae5cb14761e8436e97c4b7814d8e8c
+MESSAGE: 0173a34050b43748061ff8f5a3d7c43b6360847786e8bb75e536fb47b645b214f221ba24d83d28bc025024663e534f90f6e83a93d8bddeda2cd8808155652a908c437c2db6f3ed4912f57ca5b97928a73be964af59df4439854bb006fc295a87b7b72239c7fadfec40715509d98579daadfb8d524b4cec6620705efd4104c297144aea722974e12c5ecee5391ef2d93ac2b124e4ac496147c8b70363585d7078ccc53e2ae593350bc25548a0542526ab00afe477a0f4b27397c72bc74a8a8ab156e62b8bb47c3fbb4b34913e459687476bf33142c614702107ffe2cc01e25fa30275e1e2e63cea9168e4a47c02de097d4d853b27675c5bb330b94a974ead85e2bdee8ee17cbb5653346658df2f91f6bd739491dd71988b3a976a3e2e7a9d137410f4acba9feb5f11798c9a43b6adce14365a7c6d
+SIG: 9d16fd40b9f8dd9b4a1a8c6d703b9fccbb940b1e0ae77a5970374af0cf726f4479fd30d7dff5cf53494d9a296ab6b9e46ea6c136b4db2c71c21b97c1c8254d0a
+
+PRIV: ffe825148c0959b3a68de86ad8e8af7fa5e078f363dc124213c90020da0c9089139152a0bd22962dd919ae3e0b1620e03c033c2ad0a3979ec6bcd1705e23d598
+PUB: 139152a0bd22962dd919ae3e0b1620e03c033c2ad0a3979ec6bcd1705e23d598
+MESSAGE: f125780d0cd088530f0c87b70bd42ebab56adb5ad4345f929ae5deae07fb55322153a8f023d38843bf5d6a93fe993eee71bc2ee563b25a50918f03efdb5dbf7269add69ded3e66953895620d9b6cf46ba2348f8d66d7f092235e378c1e3edfebeb78084bc8dea013f9933aae14a041948276d01f1cb5834b0e590e13d931d19292bb1d8041ff2fe2e1171a2e0b9a059821d0924dde7f3b1bb59813f5e3c63520aafb8801ba62c7097d4d8cf437a568a7f0087c6ea0fce6e568c4883f1cd12c749d06a6feb278f1086a8b04769921f78a9959062ab06f98ee80c2c7854ffa760f86a89ee1a51266053d195e61bb1dbd18dd89ff394e408ace0f641a395d56118ea72b7d8adf78b1655ecece7e8250e8a3a91cb8fca0d9ce0baf8980a387c5ed4318663280e5b4531f3187c47eaea7c329728ddd0e40
+SIG: fe4e89ee31786c0a3d3de3649bb93f0b8aef1caf5a832ec5e4067810705adddf539b8f4e05ad08cf3479e45b42c96528f6d59a4625703ddbf15b63093965d80d
+
+PRIV: 49aff421a7cd12722aa84c48c1fb1c5f8d9e277d0a99ecbc9348c3aaa74be42288d2c26266f493bc67578ca0b1f51160cf0fdb6a09a906db9faa686f11f8208d
+PUB: 88d2c26266f493bc67578ca0b1f51160cf0fdb6a09a906db9faa686f11f8208d
+MESSAGE: 70a1ac144b75fda75586a79c36fd39cce5f5cae2e6375852d3b62a9630336a293ea6d2ac6e5b57da21ef364a595bb0750f5bf4d2b320676423870e4b8e0869601f16680619048c4ede276da69f205a70176e25ea04bd089763e709ba343fc8831e52044eabf9441e6997f8ba1aeb9ef0f491170667a7f5fc9627cbd0551b76be27283a4b0c5f667846688226a115ee8020df08042b19b59fe551316a6cb6916860b9ecd74154b4051038a17352372ec14d3c957d2ef50ff786189a8aeb9c08f45eeb5eb8b040339974aa9798c425d7becb228c447a6d0b3cef271893e0f7076e223a7e87c6a3d270a033bc97a4565edce0aa91ffc3f7801775a6f29b230245bd71fa034353de372395d1bfcbdebba081330f7c076be99c2cf4867f15b78d52f46fc7391c9cb95e5d64643baffe72a8e3a650667fbb3e
+SIG: 749181284df05dbe5974b91782a1a76ea08642cb0f0c98db586c575c210cdc8b651bd34b757ae38e4b6be9465235bd0eca430e26c3eede561c6e824dfa200e0a
+
+PRIV: 703a6e2b62d0090c61d8659b6a963e03c9d62c1b38f7d70e5f9ff05590cd0360370c21de6ef2fab534ada999869c90bc9b92ccbf249b79d39d95441d1ede210a
+PUB: 370c21de6ef2fab534ada999869c90bc9b92ccbf249b79d39d95441d1ede210a
+MESSAGE: d42a1756e84df4b4e9773f86f7674a2cd78e71e40aa8f644e6702dfbc2c2c5ca90fc242e9cb0099cc8f2c2d3136baafc0ff695482fdacdef9f565610b6e1900722f435c6385b35e9f6c436ca037e03f64e2233dffa58db3b91cc1daa0bb0c54c8a43e469d2cff7fa2bf8f5d1d877931089c82ed89aba42f2ee2b86e445cfd09f4cd78b35191bf467e784eef75dc987e046d37d4d4e8e9bbe14af80d03a1f40898384b9d3279fac9c57fd9c7eecbe19a5acc15033b84e07fd0e409bdbd5a57f65641183a6c0a8ec426d1f1d223166ff0a1900b2e92b7d85835d019d17775e5093ccd126f90f63cb7d15cbeb531324219cd64ded6714b21a65371af07210dfdf0e4e58ddc7d59f4cfa65c421d814ee2c9bf6dbf64873d579b09ee5dcedd733063e039ac9a5f9ca4c2525a4cc8e984da7185e2d64fad81c8a
+SIG: e5fd64da028800c6ceed068a5e596f1621c70a8cb138b31b32647eb4b07bd2ecc5942c18844f367033f67398e314ba2c7ccf299c069787777025d845f2aad60e
+
+PRIV: 76849c188e3edd0ff5f8fb874dc0456645518445e41a7d6833e616c3c48c9868d670e2ea07db60c22ab79a93ebf49d22a6245ee3af07b3be584eda694c37729e
+PUB: d670e2ea07db60c22ab79a93ebf49d22a6245ee3af07b3be584eda694c37729e
+MESSAGE: 1eccb0bc8eca3ab5bee68c5f8caa34536766c705f50827db7ac375d4fe30b58ffb7e2fe490cc71a8ff86c006d6174d05793ab8a55dd51b06de417bc0ac452cdc7cfb0bb00362b6765d20db23eb1848027064a1d9091d3b10ed776f28b76768bdfc08f0bc511f76faeba76cfc4cb5c83dc9ebe8a8d79edca923eccd524009cafedc90e3ad87d1392e1fccf4e60ccab95dc0ab54bf44245a007a96d46634b1b2965b829c3d7daa765972b54a7b365b6f34d77d7176acd8d894f6b417091b6c00edb7a4e81379988bfcecb692e9c3c4310a7e240e5c1063cde113f22a684a50a112ff47d3898812efb92637072b86163ad89316d221195acbfad0a03a1fbc2d967fe83f84c8459fccd490b9c5b3e55d27e9484e943c417f2128d73701da28f49fd3683f33a39cdee234bd305b9491e2f3eb621be3dd1dbbb31b
+SIG: 7141399d51daa6eb4519bf3f01b233920fa908fefa612f0cd7d5af8a9a3c44190e3f6384a8d14d37c97030ef5018cf8aee8aeb1569a73d84862a59b7df72fe09
+
+PRIV: 83ae48ad70da0bb3cdf87481ee2c0c8571c2ca986712f8bc2329e9a3e33383c5b785309000df95f5a04f7d89c4113301057adaeeb29bcd28d99371b537bba2f6
+PUB: b785309000df95f5a04f7d89c4113301057adaeeb29bcd28d99371b537bba2f6
+MESSAGE: b7521d3f71c679fa7037fe7488a641f6b97c49454acc8e36b903d8f9ebb54d89cb56efd19e04ba6a7c8f48a7d3ec9decd3f1cd0faf6e978118e6adce9c6c6be63c6a6a1ae21651828479a46bc9a0f7943040f940a0d470c8e577c5d575cb53c1bf3ab1feb050dcb6fef0ba4447f299fdb9f27ecb0714ecfefd74bad7b122a462c24a209848a03389074578c5bdc36396d809b0f14018da64917e6bf87ef405c8f3e333ff9c3baf6339667620794bb4743f0514b5de7d7fdd947a7e3501ee88efad159e33a1072fbb99c7c71e9d13a502d5a07c4f817eeb7f0c5319aa41a96d5ff4f15a73c29b571fe211090e172c8db518624612a5c371a9d7cef6de35ebef96e88e1a78af3bd5dd35251ab54d73718f3e70d2d59021531dc73184f0fc69c2e92965844ec27c1c02af5e9a3469de355db2256e0ec2a4eba30a
+SIG: 43332351d3fb7b45fcf37c607d442ea80dbda2cb69c2884f424e65ea3a331ed8472d4368405cb736b2d6685ad782e239fe833ed789a2923185166f608342ee05
+
+PRIV: 39e56a65623a0aebade0da12ce1df378bc924073f73a549effaebc465d1a78e283da8ad50bad09eb3e94c725df3cc3a119736adc859ca1a10503f48ff2fec596
+PUB: 83da8ad50bad09eb3e94c725df3cc3a119736adc859ca1a10503f48ff2fec596
+MESSAGE: a96dc2ea3fa1351492a4619d9194681f8ec400a97158244482653838ccb7e156a82d564368f83a6ee1be46bc34b817200e8464c3d12b5ef2c50b19565b881c4c3d4563fb947eb47c3ee9c1ee7853269874455bfacba305f307d1ac5309eeae5c07fa5c4d428edbc8b9528c4415243a9ef580aff8fcfb12000a71fceee89de97f90279529bcc822ed3cb34c82ba5fec15f4945663636d67b5feceacc31d25f98aea07f7800d5a1034251cb91dd0963ec2c1a54773a4d96c18357f8d101de58e932f8c6cdde8e3cfcef5a7443fdba7b78320403c0196844724a612183e34bdd808ce7b958861ca37115730eaede1fd0baabe976efefd0365fdf926776c536f47ff80de5c18291bb7e9f1b913ffd1d94468b789752fae6ca897c0cca53ef1e731d00c8bdbe8929ea6b1dce1f31a20688d37b0f3a2b4153b306bdba1
+SIG: 398e8260011f57d8ac8c58d5457bc652c7414aaf6fb2f426b7899056605c0afc28392423b2b571f5e6c3c7f6d60245e53ebd03bdc5ad3c1ad8738cb32214d00f
+
+PRIV: 4b9921852f409a323ae38175e8d76a211fc4d9c654178eea3baa7a767a6fda064c723e436b6bd97f44af52503b21cc50d5f6ad6cfc8288345dde8054e995582e
+PUB: 4c723e436b6bd97f44af52503b21cc50d5f6ad6cfc8288345dde8054e995582e
+MESSAGE: 3f33d8fb83e68741090a37bedd745cf141aaaed8c92ffa742a52561777885805ace14246ab98a8cb598c9ce3de9b29bae5fa04b1cf828de11aff80a7ef8a3a38aede4f3c3563a25d049badcad5ed7e47fdbba6e111307eebe9ef4906bc989728b76e84afe808e6653b271e21104aa665f1898dd2aab23090e22b4e344a2616fbd8ee4ad8ed8108395eba817fbd14fec5c17dcf56b8220856b2b833e091407d5089b35ddf34b86ff7dc9fde52b21ef12176ef3370b7f3a0a8cb1b058a51aefff3d279d80f51a68bfb592587b45c5c63a7e4d625b887de486a118316c3b6a238575f92ac5b1c94c3f5dbbd96686000d6d39cccd558d420e4d447a8cbc4bc7b8c6a03af0f0034fb3518d93800f0f713e4b13732e16ada51801d7e559cf839d1058f64955698311399345416850dddcc5601a684fd09e6afd3944f5e19
+SIG: cbf1f1642df950eb71fd09590d34c265922c58bd8026bba3fc0e594a6bb1f2b90da3dc1d5f6b6d5b405a896d1dbb71b8685c4dfc444acaffe65ab8331789f507
+
+PRIV: 1bff652a2c8309a393ac11da3aa97fb078bb284ed5e1b8ccc983652ef8556cd0aaabdc091fc3682354201744e9b73fd2a6cfb281914bf2c70ec3dc1dec7216b0
+PUB: aaabdc091fc3682354201744e9b73fd2a6cfb281914bf2c70ec3dc1dec7216b0
+MESSAGE: 48d02698a97bdcb3ef078dcfcf5750005f1702d300e7e89bc436e381113401f852b8b4acff60ffbd4ab46d202168d98b8735e79cb350e35b070ff6bdcafd954b551969b6b1a70c9131ebd40d96140291d8d2b091540a8b18d8e5465915c25dbc6b5c9a687942533c372c8b4e95a953677169b950edd3464375cd43132ff9bd541ee22bd418ce23195f65d8b289f633ec8d71e1a801b06c3c827f627e723d2199100ce73e8e4a4440e778317a474910793b47b10ffb55db7f281c7d7a033bd80048b82673b87cf95e99422ba628688f3c971890ca15d12f572fa1977a17307069da304ead3026eb01042668890d17008cd1e92c46cbe9c857e7193de3aba3911e4f86fe0a1698ab7cdb9251a8424b2848b96ad81ea239d365fdea92ea5c0473d0a6bb1e371356bdfad2d0350336d3e1947c936fd0c25195445011731b
+SIG: 93c9c33493fc64172d51e16a0a1cd729a0d99e3cb864e89a42987f39dd8cd26545fdfe37581911e803677da4c55b0a683ddf62b728f8f30685ae58f628ebe609
+
+PRIV: 002fdd1f7641793ab064bb7aa848f762e7ec6e332ffc26eeacda141ae33b178377d1d8ebacd13f4e2f8a40e28c4a63bc9ce3bfb69716334bcb28a33eb134086c
+PUB: 77d1d8ebacd13f4e2f8a40e28c4a63bc9ce3bfb69716334bcb28a33eb134086c
+MESSAGE: 5ac1dfc324f43e6cb79a87ab0470fa857b51fb944982e19074ca44b1e40082c1d07b92efa7ea55ad42b7c027e0b9e33756d95a2c1796a7c2066811dc41858377d4b835c1688d638884cd2ad8970b74c1a54aadd27064163928a77988b24403aa85af82ceab6b728e554761af7175aeb99215b7421e4474c04d213e01ff03e3529b11077cdf28964b8c49c5649e3a46fa0a09dcd59dcad58b9b922a83210acd5e65065531400234f5e40cddcf9804968e3e9ac6f5c44af65001e158067fc3a660502d13fa8874fa93332138d9606bc41b4cee7edc39d753dae12a873941bb357f7e92a4498847d6605456cb8c0b425a47d7d3ca37e54e903a41e6450a35ebe5237c6f0c1bbbc1fd71fb7cd893d189850295c199b7d88af26bc8548975fda1099ffefee42a52f3428ddff35e0173d3339562507ac5d2c45bbd2c19cfe89b
+SIG: 0df3aa0d0999ad3dc580378f52d152700d5b3b057f56a66f92112e441e1cb9123c66f18712c87efe22d2573777296241216904d7cdd7d5ea433928bd2872fa0c
+
+PRIV: 25b0f0bb3dcb422a6f3c6c220eaadb11dbfe489c2d455b276cefe8cba057f9f3fe03c9c4394adc74b13f47654bead8bc855958b4194fdab2097ac1b157933c05
+PUB: fe03c9c4394adc74b13f47654bead8bc855958b4194fdab2097ac1b157933c05
+MESSAGE: 54d99f969efa8870fc20fa9a962bb372619c324439728af3139c2a07e8c1b29c1e4eedc2d40ba722f63ce37670362af6f5202add668c4fb4d62fa8bacbc7d07ff3bd38c15a01064259cc34134861632967460541a99b8d5182bf59347b5a59879aa3b091a1f3e04135bd6301be5226d4895e5e9c2b15e48e5ecdf44129e6122853a606fc118466fa720b5ab165635c3bde04d74289274fa03547accbde780e1fa0bf2c56f8436a53e73878a424a29aa9de385dba419ae6a5d12e004276152b58d325b302400a55333c38cde4908ae1d0121cbeca950809c543314277c1485e68d9f9c0a962d1b1e0dda1d4a52b56f8308a80b92acc9f4ebc3ed45d91a129da8675621af676703def3b84113183b2e3a8c56157f243f13980f3d1756fea7668c91503d35c839a2120c79ec954fb546d7b542f987289534ffdef62d47fd5ec
+SIG: da50d5242bf51c3951780cafd926d67bdf5640d5d3bb08433831d56e48e2592a1c375968bb4d2fbea56145abf2d82991363b1565fa1effe214011a686e39950e
+
+PRIV: bf5ba5d6a49dd5ef7b4d5d7d3e4ecc505c01f6ccee4c54b5ef7b40af6a4541401be034f813017b900d8990af45fad5b5214b573bd303ef7a75ef4b8c5c5b9842
+PUB: 1be034f813017b900d8990af45fad5b5214b573bd303ef7a75ef4b8c5c5b9842
+MESSAGE: 16152c2e037b1c0d3219ced8e0674aee6b57834b55106c5344625322da638ecea2fc9a424a05ee9512d48fcf75dd8bd4691b3c10c28ec98ee1afa5b863d1c36795ed18105db3a9aabd9d2b4c1747adbaf1a56ffcc0c533c1c0faef331cdb79d961fa39f880a1b8b1164741822efb15a7259a465bef212855751fab66a897bfa211abe0ea2f2e1cd8a11d80e142cde1263eec267a3138ae1fcf4099db0ab53d64f336f4bcd7a363f6db112c0a2453051a0006f813aaf4ae948a2090619374fa58052409c28ef76225687df3cb2d1b0bfb43b09f47f1232f790e6d8dea759e57942099f4c4bd3390f28afc2098244961465c643fc8b29766af2bcbc5440b86e83608cfc937be98bb4827fd5e6b689adc2e26513db531076a6564396255a09975b7034dac06461b255642e3a7ed75fa9fc265011f5f6250382a84ac268d63ba64
+SIG: 279cace6fdaf3945e3837df474b28646143747632bede93e7a66f5ca291d2c24978512ca0cb8827c8c322685bd605503a5ec94dbae61bbdcae1e49650602bc07
+
+PRIV: 65de297b70cbe80980500af0561a24db50001000125f4490366d8300d3128592ba8e2ad929bdcea538741042b57f2067d3153707a453770db9f3c4ca75504d24
+PUB: ba8e2ad929bdcea538741042b57f2067d3153707a453770db9f3c4ca75504d24
+MESSAGE: 131d8f4c2c94b153565b86592e770c987a443461b39aa2408b29e213ab057affc598b583739d6603a83fef0afc514721db0e76f9bd1b72b98c565cc8881af5747c0ba6f58c53dd2377da6c0d3aa805620cc4e75d52aabcba1f9b2849e08bd1b6b92e6f06615b814519606a02dc65a8609f5b29e9c2af5a894f7116ef28cfd1e7b76b64061732f7a5a3f8aa4c2e569e627a3f9749aa597be49d6b94436c352dd5fa7b83c92d2610faa32095ca302152d91a3c9776750e758ee8e9e402c6f5385eaa5df23850e54beb1be437a416c7115ed6aa6de13b55482532787e0bee34b83f3084406765635497c931b62a0518f1fbc2b891dc7262c7c6b67eda594fa530d74c9329bad5be94c287fbcde53aa80272b83322613d9368e5904076fdbcc88b2c0e59c10b02c448e00d1b3e7a9c9640feffb9523a8a60e1d83f04a4b8df69153b
+SIG: 7a9b736b01cc92a3349f1a3c32dbd91959825394ff443c567405e899c8185ce8fad9500e1fce89d95a6253c00477435acf04bff993de1b00495def0834ee1f07
+
+PRIV: 0826e7333324e7ec8c764292f6015d4670e9b8d7c4a89e8d909e8ef435d18d15ffb2348ca8a018058be71d1512f376f91e8b0d552581254e107602217395e662
+PUB: ffb2348ca8a018058be71d1512f376f91e8b0d552581254e107602217395e662
+MESSAGE: 7f9e3e2f03c9df3d21b990f5a4af8295734afe783accc34fb1e9b8e95a0fd837af7e05c13cda0de8fadac9205265a0792b52563bdc2fee766348befcc56b88bbb95f154414fb186ec436aa62ea6fcabb11c017a9d2d15f67e595980e04c9313bc94fbc8c1134c2f40332bc7e311ac1ce11b505f8572ada7fbe196fba822d9a914492fa7185e9f3bea4687200a524c673a1cdf87eb3a140dcdb6a8875613488a2b00adf7175341c1c257635fa1a53a3e21d60c228399eea0991f112c60f653d7148e2c5ceb98f940831f070db1084d79156cc82c46bc9b8e884f3fa81be2da4cdda46bcaa24cc461f76ee647bb0f0f8c15ac5daa795b945e6f85bb310362e48d8095c782c61c52b481b4b002ad06ea74b8d306eff71abf21db710a8913cbe48332be0a0b3f31e0c7a6eba85ce33f357c7aeccd30bfb1a6574408b66fe404d31c3c5
+SIG: 4bac7fabec8724d81ab09ae130874d70b5213492104372f601ae5abb10532799373c4dad215876441f474e2c006be37c3c8f5f6f017d0870414fd276a8f42808
+
+PRIV: 00ad6227977b5f38ccda994d928bba9086d2daeb013f8690db986648b90c1d4591a4ea005752b92cbebf99a8a5cbecd240ae3f016c44ad141b2e57ddc773dc8e
+PUB: 91a4ea005752b92cbebf99a8a5cbecd240ae3f016c44ad141b2e57ddc773dc8e
+MESSAGE: cb5bc5b98b2efce43543e91df041e0dbb53ed8f67bf0f197c52b2211e7a45e2e1ec818c1a80e10abf6a43535f5b79d974d8ae28a2295c0a6521763b607d5103c6aef3b2786bd5afd7563695660684337bc3090739fb1cd53a9d644139b6d4caec75bda7f2521fbfe676ab45b98cb317aa7ca79fc54a3d7c578466a6aa64e434e923465a7f211aa0c61681bb8486e90206a25250d3fdae6fb03299721e99e2a914910d91760089b5d281e131e6c836bc2de08f7e02c48d323c647e9536c00ec1039201c0362618c7d47aa8e7b9715ffc439987ae1d31154a6198c5aa11c128f4082f556c99baf103ecadc3b2f3b2ec5b469623bc03a53caf3814b16300aedbda538d676d1f607102639db2a62c446707ce6469bd873a0468225be88b0aef5d4020459b94b32fe2b0133e92e7ba54dd2a5397ed85f966ab39ed0730cca8e7dacb8a336
+SIG: dc501db79fd782bc88cae792557d5d273f9ba560c7d90037fe84ac879d684f612a77452c4443e95c07b8be192c35769b17bbdfca42280de796d92119d833670d
+
+PRIV: 1521c6dbd6f724de73eaf7b56264f01035c04e01c1f3eb3cbe83efd26c439ada2f61a26ffb68ba4f6e141529dc2617e8531c7151404808093b4fa7fedaea255d
+PUB: 2f61a26ffb68ba4f6e141529dc2617e8531c7151404808093b4fa7fedaea255d
+MESSAGE: 3e3c7c490788e4b1d42f5cbcae3a9930bf617ebdff447f7be2ac2ba7cd5bcfc015760963e6fe5b956fb7cdb35bd5a17f5429ca664f437f08753a741c2bc8692b71a9115c582a25b2f74d329854d60b7817c079b3523aaff8793c2f72fff8cd10592c54e738df1d6452fb72da131c6731ea5c953c62ea177ac1f4735e5154477387109afae15f3ed6eeb08606e28c81d4386f03b9376924b6ef8d221ee29547f82a7ede48e1dc17723e3d42171eeaf96ac84bedc2a01dd86f4d085734fd69f91b5263e439083ff0318536adff4147308e3aafd1b58bb74f6fb0214a46fdcd3524f18df5a719ce57319e791b4ea606b499bfa57a60e707f94e18f1fed22f91bc79e6364a843f9cbf93825c465e9cae9072bc9d3ec4471f21ab2f7e99a633f587aac3db78ae9666a89a18008dd61d60218554411a65740ffd1ae3adc06595e3b7876407b6
+SIG: a817ed23ec398a128601c1832dc6af7643bf3a5f517bcc579450fdb4759028f4966164125f6ebd0d6bf86ff298a39c766d0c21fdb0cbfdf81cd0eb1f03cd8a08
+
+PRIV: 17e5f0a8f34751babc5c723ecf339306992f39ea065ac140fcbc397d2dd32c4b4f1e23cc0f2f69c88ef9162ab5f8c59fb3b8ab2096b77e782c63c07c8c4f2b60
+PUB: 4f1e23cc0f2f69c88ef9162ab5f8c59fb3b8ab2096b77e782c63c07c8c4f2b60
+MESSAGE: c0fad790024019bd6fc08a7a92f5f2ac35cf6432e2eaa53d482f6e1204935336cb3ae65a63c24d0ec6539a10ee18760f2f520537774cdec6e96b55536011daa8f8bcb9cdaf6df5b34648448ac7d7cb7c6bd80d67fbf330f8765297766046a925ab52411d1604c3ed6a85173040125658a32cf4c854ef2813df2be6f3830e5eee5a6163a83ca8849f612991a31e9f88028e50bf8535e11755fad029d94cf25959f6695d09c1ba4315d40f7cf51b3f8166d02faba7511ecd8b1dded5f10cd6843455cff707ed225396c61d0820d20ada70d0c3619ff679422061c9f7c76e97d5a37af61fd62212d2dafc647ebbb979e61d9070ec03609a07f5fc57d119ae64b7a6ef92a5afae660a30ed48d702cc3128c633b4f19060a0578101729ee979f790f45bdbb5fe1a8a62f01a61a31d61af07030450fa0417323e9407bc76e73130e7c69d62e6a7
+SIG: efe2cb63fe7b4fc98946dc82fb6998e741ed9ce6b9c1a93bb45bc0a7d8396d7405282b43fe363ba5b23589f8e1fae130e157ce888cd72d053d0cc19d257a4300
+
+PRIV: 0cd7aa7d605e44d5ffb97966b2cb93c189e4c5a85db87fad7ab8d62463c59b594889855fe4116b4913927f47f2273bf559c3b394a983631a25ae597033185e46
+PUB: 4889855fe4116b4913927f47f2273bf559c3b394a983631a25ae597033185e46
+MESSAGE: 28a55dda6cd0844b6577c9d6da073a4dc35cbc98ac158ab54cf88fd20cc87e83c4bba2d74d82ce0f4854ec4db513de400465aaa5eee790bc84f16337072d3a91cde40d6e0df1ba0cc0645f5d5cbbb642381d7b9e211d25267a8acf77d1edb69c3a630f5b133d24f046a81bf22ff03b31d8447e12c3f7b77114a70cbd20bbd08b0b3827a6bbcf90409e344447a7fbc59bdd97d729071f8d71dcc33e6ef2cbab1d411edf13734db1dd9703276f5eb2d6aa2cb8952dd6712bfae809ce08c3aa502b8135713fac0a9c25b1d45b6a5831e02421bba65b81a596efa24b0576bd1dc7fdfb49be762875e81bd540722bc06140b9aa2ef7b84a801e41ded68d4546ac4873d9e7ced649b64fadaf0b5c4b6eb8d036315233f4326ca01e03393050cd027c24f67303fb846bd2c6b3dba06bed0d59a36289d24bd648f7db0b3a81346612593e3ddd18c557
+SIG: bf9115fd3d02706e398d4bf3b02a82674ff3041508fd39d29f867e501634b9261f516a794f98738d7c7013a3f2f858ffdd08047fb6bf3dddfb4b4f4cbeef3003
+
+PRIV: 33371d9e892f9875052ac8e325ba505e7477c1ace24ba7822643d43d0acef3de35929bded27c249c87d8b8d82f59260a575327b546c3a167c69f5992d5b8e006
+PUB: 35929bded27c249c87d8b8d82f59260a575327b546c3a167c69f5992d5b8e006
+MESSAGE: 27a32efba28204be59b7ff5fe488ca158a91d5986091ecc4458b49e090dd37cbfede7c0f46186fabcbdff78d2844155808efffd873ed9c9261526e04e4f7050b8d7bd267a0fe3d5a449378d54a4febbd2f26824338e2aaaf35a32ff0f62504bda5c2e44abc63159f336cf25e6bb40ddb7d8825dff18fd51fc01951eaedcd33707007e1203ca58b4f7d242f8166a907e099932c001bfb1ec9a61e0ef2da4e8446af208201315d69681710d425d2400c387d7b9df321a4aec602b9c656c3e2310bff8756d18b802134b15604f4edc111149a9879e31241dd34f702f4c349617b13529769a772f5e52a89c098e0dca5920667893a250061b17991626eb9319298685be46b6a8b68422444fa5a36bcf3a687e2eccb9322c87dc80165da898930850b98fc863cada1aa99c6d61c451b9ccf4874c7f0e75b0a0c602f044812c71765adaf02025395b0
+SIG: 985ca446ddc007827cc8f2852cbd8115ef8c5975e9d7ce96d74dfed859aa14a4c15254006bea5e08359efe2625d715e0897ee5a16f151203be5010418637de05
+
+PRIV: beedb8073df58f8c1bffbdbd77ec7decb2c82a9babecefc0331507bdc2c2a7e7b27e908b805e296fc30d2e474b060cd50c0f6f520b3671712183bd89d4e733e9
+PUB: b27e908b805e296fc30d2e474b060cd50c0f6f520b3671712183bd89d4e733e9
+MESSAGE: 35ca57f0f915e5209d54ea4b871ffb585354df1b4a4a1796fbe4d6227d3e1aba5171ed0391a79e83e24d82fdafd15c17b28bf6c94d618c74d65264e58faaacd2902872fdd0efa22e8d2d7ce8e3b8197f0c3615b0a385235fa9fd8e4564ee6e6b1650b4cfb94d872c805c32d4f3a18f966461d3adbb605fa525884f8eb197627396ba4d995d78ac02948a0eaabb58519b9a8e2e7985cd1de2c71d8918d96a0168660ce17cddf364e3ec0d4bd90f2104751a1927ee1d23f3e7a69840ed040b00e5f6e4866ec58813149cc382aebf6162608c79574d553f47230e924a0ef1ebf55d8e1a52abb62a2d7ac86027c7c03cc83fa1949da29e2f3037ab986fd2fffe650e3149babae5a50b1ee9696f3babec72e29697c82422814d272085500fd837fe3c7a973ef4c169af12dd7f02700620bb045bdbf84623f326350570b3cadbc9aea4200b28287e17ab
+SIG: 8c890cccadc7760e1e82e43c44b3dc0b685a48b479ae13cc0a6b0557d0fb1cbabba63d2a96843412ea8d36c50acbf52b92cfb2dce49dc48af6ddcf8ee47a8608
+
+PRIV: 9184ef618816832592bc8eb35f4ffd4ff98dfbf7776c90f2aad212ce7e03351e687b7726010d9bde2c90e573cd2a2a702ff28c4a2af70afc7315c94d575601e5
+PUB: 687b7726010d9bde2c90e573cd2a2a702ff28c4a2af70afc7315c94d575601e5
+MESSAGE: 729eb7e54a9d00c58617af18c345b8dc6e5b4e0f57de2f3c02e54a2ec8f1425ec2e240775b5ab0c10f84ac8bafda4584f7e21c655faecd8030a98906bd68398f26b5d58d92b6cf045e9bd9743c74c9a342ec61ce57f37b981eac4d8bf034608866e985bb68686a68b4a2af88b992a2a6d2dc8ce88bfb0a36cf28bbab7024abfa2bea53313b66c906f4f7cf66970f540095bd0104aa4924dd82e15413c22679f847e48cd0c7ec1f677e005fec0177fbd5c559fc39add613991fbaeae4d24d39d309ef74647f8192cc4c62d0642028c76a1b951f6bc9639deb91ecc08be6043f2109705a42c7eae712649d91d96ccbbfb63d8d0dd6dd112160f61361ecdc6793929ca9aef9ab56944a6fa4a7df1e279eaf58ce8323a9cf62c94279fff7440fbc936baa61489c999330badcb9fc0e184bc5093f330cbb242f71fb378738fea10511dd438364d7f76bcc
+SIG: b3c24e75132c563475422d5ea412b5c1e8e6e5ea1c08ead1393c412da134c9a1638284ea7e2ca032fe3d3e32a9066a8c8839903f6ef46e966bb5e492d8c2aa00
+
+PRIV: 354e13152ee1fe748a1252204c6527bdc1b1eb2eb53678150e6359924708d812d45ff6c5fb83e7bb9669aa8960deb7dbc665c988439b6c9ef672c6811dc8bcf6
+PUB: d45ff6c5fb83e7bb9669aa8960deb7dbc665c988439b6c9ef672c6811dc8bcf6
+MESSAGE: 8e5fccf66b1ba6169cb685733d9d0e0190361c90bcab95c163285a97fe356d2bdcde3c9380268805a384d063da09ccd9969cc3ff7431e60a8e9f869cd62faa0e356151b280bc526e577c2c538c9a724dc48bf88b70321d7e1eeedb3c4af706748c942e67bdabdb41bec2977b1523069e31e29b76300288f88a51b384b80cc2526f1679340ddec3881f5cd28b0378d9cd0a812b68dd3f68f7a23e1b54bee7466ac765cf38df04d67441dfa498c4bffc52045fa6d2dbcdbfa33dfaa77644ffccef0decdb6790c70a0d734ec287cc338cb5a909c0055189301169c4f7702c05c0911a27b16ef9ed934fa6a0ca7b13e413523422535647968030edc40cd73e7d6b345b7581f438316d68e3cd292b846d3f4f7c4862bc7e6b3fb89a27f6f60cd7db2e34ec9aae1013fe37acff8ad888cb9a593ef5e621eae5186c58b31dcfde22870e336d33f440f6b8d49a
+SIG: de2b46e65f3decef34332e500f2e11306fbdcf1be85a1c1ee68ba3045dcec2c7be608d22927da1f44c0e2083ae622cf3c29d893887994efcfa2ca594f5051f03
+
+PRIV: 7ff62d4b3c4d99d342d4bb401d726b21e99f4ef592149fc311b68761f5567ff67fdfdb9eca29d3f01d9486d7e112ce03aa37b91326a4283b9c03999c5eda099a
+PUB: 7fdfdb9eca29d3f01d9486d7e112ce03aa37b91326a4283b9c03999c5eda099a
+MESSAGE: 99c44c796572a4823fc6c3807730839173774c05dbfc1492ed0d00509a95a1de37274b3135ed0456a1718e576597dc13f2a2ab37a45c06cbb4a2d22afad4d5f3d90ab3d8da4dcdaa06d44f2219088401c5dceee26055c4782f78d7d63a380608e1bef89eeef338c2f0897da106fafce2fb2ebc5db669c7c172c9cfe77d3109d239fe5d005c8ee751511b5a88317c729b0d8b70b52f6bd3cda2fe865c77f36e4f1b635f336e036bd718bec90ee78a802811510c4058c1ba364017253aa842922e1dd7d7a0f0fc9c69e43fc4eaeffaaf1ae5fa5d2d73b43079617baba030923fe5b13d2c1c4fe6fac3f2db74e2020a734b6121a0302fce820ba0580ce6135348fdf0632e0008df03ee112168f5cfa0037a26a1f69b1f1317edf2a3ab367455a77e00691215d7aa3133c2159d3da2b134cf04f0defbf07a6064011e64dd14d4f8f064356655428804c2771a
+SIG: 058f79927fbf6178724815c7b11c63baaa90bcc15d7272be082f8a9141861c816433055f6cf6491424853f9ec78bb91ace913a93411b4e5ed58bc4ba5715c60a
+
+PRIV: 6cabadd03f8a2e6ebab96a74f80e18164e4d1b6baa678f5a82e25604af989aaf2a4a3179564194e00100c18bc35351d8b135bbae5b32b28fce1d7b6766ca4b32
+PUB: 2a4a3179564194e00100c18bc35351d8b135bbae5b32b28fce1d7b6766ca4b32
+MESSAGE: 279f78cf3b9ccfc6e1b01e1a82f50ed172e9a8e1e702bb15661dd7dc3a456ff7a7a7fdfb081db3867079630c7f70fd753292ec60ecbf50632e9aa45b996505c66e6dc3c6ae892e21b6a8705e4bbae8f16a3378554b31fdb0139dcd15c96a8a7e4b88756a86d18db5dc74fd7691197dd88e2c7d5df52b049344cdc477c9cd7e89eda99ccfb1d00814d0152b9654df3279372ca5f18b1c946f2894a76b079ddb1c3cd61fbb969aeec9193a6b88fb7d136c07f9821e5c1074b4e93bcaf6fa14d0d1d7e1707589d77ec1337206e53a1f06cc26672ff95c13d5ff444766931ba30a0afdcdadd2098e9c41fd87a3f23cd16dbb0efbf8092ce33e327f42610990e1cee6cb8e54951aa081e69765ae4009aeed758e768de50c23d9a22b4a06dc4d19fc8cbd0cdef4c983461755d0a3b5d6a9c12253e09568339ff7e5f78c5fdf7ec89f9186a621a8c0eed11b67022e
+SIG: 4e65c6c1d493045e8a9250e397c1d1d30ffed24db66a8961aa458f8f0fcb760c39fe8657d7ab8f84000b96d519717cff71f926522c1efec7f8b2624eae55f60c
+
+PRIV: 0fa0c32c3ae34be51b92f91945405981a8e202488558a8e220c288c7d6a5532dd6aee62bd91fc9453635ffcc02b2f38dcab13285140380580ccdff0865df0492
+PUB: d6aee62bd91fc9453635ffcc02b2f38dcab13285140380580ccdff0865df0492
+MESSAGE: 53f44be0e5997ff07264cb64ba1359e2801def8755e64a2362bddaf597e672d021d34fface6d97e0f2b1f6ae625fd33d3c4f6e9ff7d0c73f1da8defb23f324975e921bb2473258177a16612567edf7d5760f3f3e3a6d26aaabc5fde4e2043f73fa70f128020933b1ba3b6bd69498e9503ea670f1ed880d3651f2e4c59e79cabc86e9b703394294112d5d8e213c317423b525a6df70106a9d658a262028b5f45100cb77d1150d8fe461eed434f241015f3276ad7b09a291b4a7f35e3c30051cbf13b1d4a7fa0c81a50f939e7c49673afdc87883c9e3e61f5a1df03755470fda74bf23ea88676b258a97a280d5f90b52b714b596035bae08c8d0fe6d94f8949559b1f27d7116cf59dd3cfbf18202a09c13f5c4fbc8d97225492887d32870c2297e34debd9876d6d01ac27a16b088b079079f2b20feb02537cda314c43cb2dca371b9df37ed11ec97e1a7a6993a
+SIG: 7e9ab85ee94fe4b35dcb545329a0ef25923de5c9dc23e7df1a7e77ab0dcfb89e03f4e785ca6429cb2b0df50da6230f733f00f33a45c4e576cd40bdb84f1ae001
+
+PRIV: 7b06f88026fa86f39fce2426f67cc5996bedd0cfc4b5ebb1b5e3edbb47e080aa3f1469ee6a2e7867e2e9012d402cf5a4861497c01df879a1deb1c539830b58de
+PUB: 3f1469ee6a2e7867e2e9012d402cf5a4861497c01df879a1deb1c539830b58de
+MESSAGE: 71175d4e21721297d9176d817f4e785d9600d923f987fe0b26fd79d33a5ea5d1e818b71f0f92b8c73afddabdcc27f6d16e26aafa874cfd77a00e06c36b041487582bb933760f88b419127345776ea418f83522254fed33819bc5c95f8f8404cc144ebf1486c88515409d3433aaf519d9920f5256e629419e9a95580a35b069b8d25533dfcbc98ad36404a951808e01378c03266326d120046975fde07daef3266caacd821c1403499d7fdf17c033c8d8c3f28f162b5f09dfdaca06285f00c6cb986dfdf5151aa6639608b5b13e78d65a4368585b16138754fbd113835a686cd066c2b89bb0953c24d50e77bf0fc457c1e0fcf5d44da8db9a88f062be3b688d5cdcff1d1c00e81ec9d413882295b341fee8fa427dc109adeb5f284eec202f1bef115bf96b1782d3ccdeb682b69bf92d170c007d5df80e1ed962f677dc24a145a1e4e829e8dec0104e5f78365944
+SIG: 42f133e34e3eb7032a133ed781537ec62e44a5ce8381e5e0bf9e13a914a4b2c757811d6d3b1e86672424ea4230d10f7c610abb7069e61e319b4066a2bd7bc900
+
+PRIV: c3f5e149968a24f4de9119531975f443015ccca305d7119ed4749e8bf6d94fc739aaccdb948a4038538a4588322f806bb129b5876c4bec51271afe4f49690045
+PUB: 39aaccdb948a4038538a4588322f806bb129b5876c4bec51271afe4f49690045
+MESSAGE: c46370e37f2e0cadcf93402f1f0cb048f52881ba750b7a43f56ab11ce348732fb57e7f9aaf8dfcbe455e14e983c248d026a27e7f148d5db5a53f94635702b895127771047a876d14107386c5e0ff8933345bbd7a936d990d33efa28c2ec4e4864ffd2ff576f7c88f954cfc1c459e883bb712dae3cdf6632066f1f4d13a509615b3360cadc5a307f23e52a51b40a6feebe0b18d0e9ee4e348f33cd81a8def222f6a59b12861d335bd9af85cc004be46f1d3a424f4870ae9dc587e5a4ade136b9370649348c33ac3bf1febeebffea37085ed59cac9d9e696470b234609e9a10a9d431ff91e69cb5135fd117ff58a36539744ebe70cea6973c00c7a4d57b62f4a7136d731b8e46ff18ec0ed69070031905075d8541d568cfce6eeb76242b7819a7b6a93552111bb88f165527cfa6966d39fcbe0a7dea008e39c7a3e577ab307cd1d0ea326833d52654e172955f3fcd4
+SIG: 5fa2b531677b00b85b0a313cbd479f55f4ab3ec5cfce5e454d2b74176ccc3399c899f9d6b51ed4c1e76185ac9fe730c4b4014044f7041185bc3c85722eb2ea02
+
+PRIV: 42305c9302f45ea6f87e26e2208fd94b3c4ad037b1b6c83cf6677aa1096a013c3b97b1f11ce45ba46ffbb25b76bfc5ad7b77f90cc69ed76115dea4029469d587
+PUB: 3b97b1f11ce45ba46ffbb25b76bfc5ad7b77f90cc69ed76115dea4029469d587
+MESSAGE: d110828d449198d675e74e8e39439fd15e75bf2cc1f430abfb245836885bafc420f754b89d2fbbf6dd3490792e7a4f766073cfe3b302d089831ace869e2730fde45c2121ec3ef217aa9c43fa7cc7e9ed0a01ad9f1d2fc3613638ca9fc193c98b37455bf5dbf8f38b64708dfdca6c21f0975f1017c5da5f6434bda9f033cec2a631ab50318e017b170b240bf01eb8b36c7e1cb59e7736ac34444208132a8f59e4f313d65d849c6a4fdf13e20ecaee3823e589a171b39b2489497b06e6ff58c2c9f1dc5d3aa3bd10e6443e22d42d07b783f79fd43a46e1cde314b663a95f7246dea131fcd46d1dc333c5454f86b2c4e2e424dea405cc2230d4dcd39a2eab2f92845cf6a7994192063f1202749ef52dcb96f2b79ed6a98118ca0b99ba2285490860eb4c61ab78b9ddc6acc7ad883fa5e96f9d029171223abf7573e36230e0a81f6c1311151473ee264f4b842e923dcb3b
+SIG: 18d05e5d01668e83f40fa3bbee28b388acf318d1b0b5ad668c672f345c8eda14c2f884cd2a9039459ce0810bc5b580fe70d3964a43edb49e73a6ff914bbf040c
+
+PRIV: c57a43dcd7bab8516009546918d71ad459b7345efdca8d4f19929875c839d7222083b444236b9ab31d4e00c89d55c6260fee71ac1a47c4b5ba227404d382b82d
+PUB: 2083b444236b9ab31d4e00c89d55c6260fee71ac1a47c4b5ba227404d382b82d
+MESSAGE: a4f6d9c281cf81a28a0b9e77499aa24bde96cc1264374491c008294ee0af6f6e4bbb686396f59068d358e30fe9992db0c6f16680a1c71e27a4a907ac607d39bdc3258c7956482fb37996f4beb3e5051b8148019a1c256e2ee999ebc8ce64c54e07fedb4fbd8953ebd93b7d69ce5a0082edd6209d12d3619b4fd2eae916461f72a4ce727157251a19209bbff9fbdbd289436f3fcacc6b4e1318521a47839cba4b14f7d7a21e7b5d6b6a753d5804afcd2b1eb7779b92abab8afa8aa4fa51caec0b85dcd0fc2a0676036d3f56630a831ffeb502861dd89161c708a9c006c73c930ce5b94756426ff18aa112fb4eb9a68500b48d4eedbd4167b6ffd0a11d49443a173ce9d949436748fc0634f06bb08b8f3423f4463dba7b4d199b64df578117f0a2645f0b2a1e2ada27d286f76733f25b82ed1d48a5c3898d4ad621e50ed9060daad40a39532e4d1bf162ce36804d5d4e2d
+SIG: 1edef9bc036971f1fa88edf45393c802e6c1a1631c8a06871a09a320821dce40beca97e53a0361a955a4c6d60b8ca8e400c81340911ccb4f56284041cdbb1804
+
+PRIV: 2dddb6b8fd04fa90ece1a709f8418f2e5d0c9c43afe7cfce19e6ad15a73476f78059de6a7c4776489ecc2e7d707ffce30285bf30a23f78d72db49cfd6ed0d492
+PUB: 8059de6a7c4776489ecc2e7d707ffce30285bf30a23f78d72db49cfd6ed0d492
+MESSAGE: 474baa590a4cd72d5424e51d8257b3d44325bc4c5063a0033c86ebbe99ed7212184c19944d082a115379dd4cece973faa0bca6485bd25f3744a719e70aa0291e1b5a96e637c140616a98263357c76b6eb0083fe51414e386870d0fdc7dd9abe4ff6fb5bbf1e7b15dac3e08e2615f655c3104ceb32a4cc2c9e9c43cf282d346ac253ccc46b635ae040973b49735720ffb890469a567c5824e0c00d7ccd5509a718092a906461c4d6163eaf422418f5fc6e009fc3f529ac61a2f89bb8e0ed45d940c4c2331ff8d8e1d6d58d417d8fc2656a02e8701aee75aed918724eebe4a2cf4744c5c401e217023df68a6f6a0228bd05a679a697d8de7036b9ed269090d3c65486afb91e27954eb15b964665ede7ad008f12fb3a9d0e69c13b4254f43819e0818a4195f68b8a38ae81f3fcb1879c95ab4cd0ffc38e381089260cca967ace5a085b457ab5eb363852101377570f9ac9e38
+SIG: c634ea7bf72e895a2e796e2834201415b8b45e05e045559284eb9052c0e84f62a5a9f0c9764f7576788c7228b19ef517c195497325a48a9344b147c12fd75509
+
+PRIV: 5547f1004baedfce5cfc0850b05302374aad24f6163994ecd751df3af3c106207ce620787385ee1951ac49a77352ee0d6f8c5cd47df74e9e3216a6324fc7cf7f
+PUB: 7ce620787385ee1951ac49a77352ee0d6f8c5cd47df74e9e3216a6324fc7cf7f
+MESSAGE: a6c17eeb5b8066c2cd9a89667317a945a0c7c96996e77ae854c509c6cd0631e922ad04503af87a3c4628adafed7600d071c078a22e7f64bda08a362b38b26ca15006d38acf532d0dedea4177a2d33f06956d80e963848ec791b2762fa99449b4f1a1ed9b3f2580be3ac7d7f52fb14421d6222ba76f807750c6cbb0b16f0895fc73d9dfc587e1a9e5d1e58375fbab705b8f0c1fd7df8b3ad446f2f08459e7ed1af59556fbc966dc249c1cf604f3e677c8a09d4363608774bf3811bef0642748c55c516c7a580fa3499050acb30eed870d0d91174cb623e98c3ad121cf81f04e57d49b008424a98a31eeaaf5f38e000f903d48d215ed52f862d636a5a73607de85760167267efe30f8a26ebc5aa0c09f5b258d3361ca69d1d7ee07b59648179ab2170ec50c07f6616f216872529421a6334a4a1ed3d2671ef47bc9a92afb58314e832db8a9003408a0487503fe4f67770dd4b6
+SIG: 29df3ad589009c667baa5e72dabb4e53cb7876de4e7efe5cc21ead7fa878db57f97c1103ddb39a861eb88653c1d4ec3b4306e4584b47b8bc90423119e7e4af00
+
+PRIV: 3dd7203c237aefe9e38a201ff341490179905f9f100828da18fcbe58768b5760f067d7b2ff3a957e8373a7d42ef0832bcda84ebf287249a184a212a94c99ea5b
+PUB: f067d7b2ff3a957e8373a7d42ef0832bcda84ebf287249a184a212a94c99ea5b
+MESSAGE: db28ed31ac04b0c2decee7a6b24fc9a082cc262ca7ccf2a247d6372ec3e9120ecedb4542ea593fea30335c5ab9dd318a3b4fd5834299cf3f53d9ef46137b273c390ec3c26a0b4470d0d94b77d82cae4b24587837b167bb7f8166710baeb3ee70af797316cb7d05fa57e468ae3f0bd449404d8528808b41fcca62f5e0a2aa5d8f3acab008cc5f6e5ab02777bdcde87f0a10ef06a4bb37fe02c94815cf76bfb8f5cdd865cc26dcb5cf492edfd547b535e2e6a6d8540956dcba62cfea19a9474406e934337e454270e01036ac45793b6b8aceda187a08d56a2ce4e98f42ea375b101a6b9fcb4231d171aa463eeb43586a4b82a387bcddaf71a80fd5c1f7292efc2bd8e70c11eaa817106061b6c461c4883d613cc06c7e2a03f73d90fc55cdc07265eefd36be72270383d6c676cae37c93691f1ae3d927b3a1cd963e4229757ae5231eea73a9f71515628305410ac2593b325cc631
+SIG: 4c036935a96abc0d050d907bedbe9946fb97439f039c742e051ccf09add7df44d17da98c2ca01bdc2424da1e4debf347f8fff48ac8030d2cc07f9575c044be04
+
+PRIV: 282775df9ebbd7c5a65f3a2b096e36ee64a8f8ea719da77758739e4e7476111da2b49646033a13937cad6b0e914e3cec54989c252ca5643d076555d8c55e56e0
+PUB: a2b49646033a13937cad6b0e914e3cec54989c252ca5643d076555d8c55e56e0
+MESSAGE: 14cc50c2973ea9d0187a73f71cb9f1ce07e739e049ec2b27e6613c10c26b73a2a966e01ac3be8b505aeaad1485c1c2a3c6c2b00f81b9e5f927b73bfd498601a7622e8544837aad02e72bf72196dc246902e58af253ad7e025e3666d3bfc46b5b02f0eb4a37c9554992abc8651de12fd813177379bb0ce172cd8aaf937f979642bc2ed7c7a430cb14c3cd3101b9f6b91ee3f542acdf017f8c2116297f4564768f4db95dad8a9bcdc8da4d8fb13ef6e2da0b1316d3c8c2f3ed836b35fe2fd33effb409e3bc1b0f85225d2a1de3bfc2d20563946475c4d7ca9fddbaf59ad8f8961d287ae7dd803e7af1fa612329b1bdc04e225600ae731bc01ae0925aed62ac50d46086f3646cf47b072f0d3b044b36f85cec729a8bb2b92883ca4dfb34a8ee8a0273b31af50982bb6131bfa11d55504b1f6f1a0a00438ca26d8ab4f48bcddc9d5a38851abede4151d5b70d720732a00abea2c8b979
+SIG: 15763973859402907d8dcb86adc24a2a168ba3abf2246173d6348afed51ef60b0c0edeff4e10bcef4c6e5778c8bc1f5e9ee0237373445b455155d23de127a202
+
+PRIV: 4730a5cf9772d7d6665ba787bea4c95252e6ecd63ec62390547bf100c0a46375f9f094f7cc1d40f1926b5b22dce465784468b20ab349bc6d4fdf78d0042bbc5b
+PUB: f9f094f7cc1d40f1926b5b22dce465784468b20ab349bc6d4fdf78d0042bbc5b
+MESSAGE: e7476d2e668420e1b0fadfbaa54286fa7fa890a87b8280e26078152295e1e6e55d1241435cc430a8693bb10cde4643f59cbfcc256f45f5090c909a14c7fc49d37bfc25af11e8f4c83f4c32d4aabf43b20fa382bb6622a1848f8ffc4dff3408bb4ec7c67a35b4cdaee5e279c0fc0a66093a9f36a60fdd65e6334a804e845c8530b6fda363b5640337d027243ccfb3c177f43e717896e46ead7f72ca06aa0ff1e77247121baf48be9a445f729ca1390fc46151cbd33fcbd7373f27a6ba55c92cbf6945b09b44b9a4e5800d403070ae66048997b2197f02181a097e563f9b9acc841139258a258bc610d3bd891637356b2edc8c184c35c65af91aaf7b1c16d74a5f5f862548139254ecf550631d5f8849afdb5b64cf366ff2633a93f3a18c39b5150245fb5f33c9e4e2d94af6963a70b88f9e7e519f8fa2a0f2e3749de883d0e6f052a949d0fc7153a8693f6d801d7352eb2f7a465c0e
+SIG: 552c7347bdfe131646ce0932d82a36d2c1b76d7c30ee890e0592e19f9d18b9a56f48d7a9b68c017da6b550c943af4a907baf317e419fbbc96f6cf4bfad42de00
+
+PRIV: 2770aadd1d123e9547832dfb2a837eba089179ef4f23abc4a53f2a714e423ee23c5fbb07530dd3a20ff35a500e3708926310fed8a899690232b42c15bd86e5dc
+PUB: 3c5fbb07530dd3a20ff35a500e3708926310fed8a899690232b42c15bd86e5dc
+MESSAGE: a5cc2055eba3cf6f0c6332c1f2ab5854870913b03ff7093bc94f335add44332231d9869f027d82efd5f1227144ab56e3222dc3ddccf062d9c1b0c1024d9b416dfa3ee8a7027923003465e0ffaefb75b9f29dc6bcf213adc5e318fd8ba93a7aa5bfb495de9d7c5e1a196cd3a2d7721f8ba785aa9052a1811c7fcc8f93932765059cab9c9b718945895ef26f3ac048d4cabf91a9e6aa83ac14d43156827837914eb763a23cba53f60f150f4b70203ec1833ff105849457a8da7327661fb23a554164e05fcf0146b10674964be6f6aa0acc94c41ad57180e5180d199bd9102f55d740e81789b15671bbd0670e6de5d97e1ae626d8a0ebc32c8fd9d24737274e47d2dd5941a272e72a598928ad109cde937bf248d57f5d2942983c51e2a89f8f054d5c48dfad8fcf1ffa97f7de6a3a43ca15fc6720efaec69f0836d84223f9776d111ec2bbc69b2dfd58be8ca12c072164b718cd7c246d64
+SIG: f267715e9a84c7314f2d5869ef4ab8d2149a13f7e8e1c728c423906293b49ce6283454dd1c7b04741df2eabedc4d6ab1397dc95a679df04d2c17d66c79bb7601
+
+PRIV: 4fdab7c1600e70114b11f533242376af7614b4d5da046ac4bedea21d8a361598a25c9a94d6e4ecd95a4bd6805f762eb1c457a8d45d243238b1839cbba8f441cc
+PUB: a25c9a94d6e4ecd95a4bd6805f762eb1c457a8d45d243238b1839cbba8f441cc
+MESSAGE: da405890d11a872c119dab5efcbff61e931f38eccca457edc626d3ea29ed4fe3154fafec1444da74343c06ad90ac9d17b511bcb73bb49d90bafb7c7ea800bd58411df1275c3cae71b700a5dab491a4261678587956aa4a219e1ac6dd3fb2cb8c46197218e726dc7ed234526a6b01c0d72cb93ab3f4f38a08e5940b3f61a72ad2789a0532000fac1d2d2e3ad632ac8b62bb3ff5b99d53597bf4d44b19674924df9b3db3d0253f74627ccab30031c85e291c58b5fa9167522a46746fc307036745d4f9817786e5d300e6c5d503125fea01dec3e3fedbf3861ca2627a0518fb2b24e5a7a014178719e9b345f7b249ce3a413280c8deb674f59a25be92a8ab6400c7c52b0728ae34e22b2ec200c1cbaba2ccd8af29249d17af60c36007a722fc80258a7bebab1cdaad7462a8b7588c2f7e27c6d07afcf60117fed11bd6859e75e3b4fcee3981881e95dd116827dd4b369af069d3c8f2676f8a
+SIG: 5075c090cfbeb6b01802af7f4da5aa4f434d5ee2f3530eebb75c85e08621f83edc08aa96693894a4277633ba81e19e9e55af5c495daa5e1a6f8cbb79c01c7207
+
+PRIV: 264504604e70d72dc4474dbb34913e9c0f806dfe18c7879a41762a9e4390ec61eb2b518ce7dc71c91f3665581651fd03af84c46bf1fed2433222353bc7ec511d
+PUB: eb2b518ce7dc71c91f3665581651fd03af84c46bf1fed2433222353bc7ec511d
+MESSAGE: 901d70e67ed242f2ec1dda813d4c052cfb31fd00cfe5446bf3b93fdb950f952d94ef9c99d1c264a6b13c3554a264beb97ed20e6b5d66ad84db5d8f1de35c496f947a23270954051f8e4dbe0d3ef9ab3003dd47b859356cecb81c50affa68c15dadb5f864d5e1bb4d3bada6f3aba1c83c438d79a94bfb50b43879e9cef08a2bfb22fad943dbf7683779746e31c486f01fd644905048b112ee258042153f46d1c7772a0624bcd6941e9062cfda75dc8712533f4057335c298038cbca29ebdb560a295a88339692808eb3481fd9735ea414f620c143b2133f57bb64e44778a8ca70918202d157426102e1dfc0a8f7b1ae487b74f02792633154dfe74caa1b7088fda22fa8b9bc354c585f1567706e2955493870f54169e0d7691159df43897961d24a852ea970c514948f3b48f71ee586e72ec78db820f253e08db84f6f312c4333bd0b732fe75883507783e9a1fd4fbab8e5870f9bf7ad58aa
+SIG: eea439a00f7e459b402b835150a779eed171ab971bd1b58dcc7f9386dadd583de8dc69e267121dde41f0f9493d450b16219cdf3c22f09482ce402fe17ca49e08
+
+PRIV: 2ca7447a3668b748b1fd3d52d2080d30e34d397bb2846caf8f659ac168788ca5ab331cd40a31d0173c0c8c1c17002532807bf89e3edb6d34c2dd8294632b9fbc
+PUB: ab331cd40a31d0173c0c8c1c17002532807bf89e3edb6d34c2dd8294632b9fbc
+MESSAGE: a82bcd9424bffda0f2f5e9eae17835dbe468f61b785aab82934737a91c5f602cb7c617cdffe87cad726a4972e15a7b8ee147f062d2a5a4d89706b571fa8aa2b95981c78abeaaae86203fa2c0e07297406ea8c27111a86dbe1d5a7c3b7ae930904d9890f6d4abebd1412a73ad5feea64acf065d3e63b5cbe20cf20bbd2d8b94f9053ed5f66633482530124446605918de66455e8cf4b101a127233c4e27d5d55bf95bd3195d0340d43531fc75faf8dded5275bf89750de838fd10c31745be4ca41fa871cb0f9b016706a1a7e3c44bb90ac7a8ad51e272389292fd6c98ad7a069e76e3f5f3e0cc770b9e9b35a765d0d93712d7cdabd17e5d01dd8183af4ad9365db0a0fa41381fce60a081df1c5ab0f8c18f95a7a8b582dfff7f149ea579df0623b33b7508f0c663f01e3a2dcd9dfbee51cc615220fdaffdab51bdae42cb9f7fa9e3b7c69cc8ada5ccd642529ba514fdc54fcf2720b8f5d08b95
+SIG: f93ada15ae9cd2b54f26f86f0c28392aed5eb6b6b44d01a4e33a54e7da37c38e8d53366f73fd85be642e4ec81236d163f0d025e76c8bbdd65d43df49f09c1f01
+
+PRIV: 494ea9bcce26885b7d17d1fc114448f239f0ce46e5f247b4c999fa86296924726901e5efae57536ba5fdd96b59657359065f25d391a1aa8cdc0d38bb5d53c139
+PUB: 6901e5efae57536ba5fdd96b59657359065f25d391a1aa8cdc0d38bb5d53c139
+MESSAGE: 3badbfa5f5a8aa2cce0a60e686cdce654d24452f98fd54872e7395b39464380a0e185557ea134d095730864f4254d3dd946970c10c804fcc0899dfa024205be0f80b1c75449523324fe6a0751e47b4ff4822b8c33e9eaf1d1d96e0de3d4acd89696b7fcc03d49f92f82b9725700b350db1a87615369545561b8599f5ea920a310a8bafc0e8d7468cbf6f3820e943594afdd5166e4e3309dddd7694ef67e694f34fc62724ff96ac3364176f34e8a02b4cf569db5b8f77d58512aedabf0bcd1c2df12db3a9473f948c5c3243309aae46c49efd088b60f31a8a72ad7e5a35acc5d89fa66807eb5d3ba9cdf08d4753cb85089ee36f5c96b432b6928352afad58012225d6157f9e3611426df921b6d1d8374628a63031e9ffb90e42ffbba021f174f68503155430152c9155dc98ffa26c4fab065e1f8e4622c2f28a8cb043110b617441140f8e20adc16f799d1d5096b1f50532be5042d21b81ea46c7
+SIG: 548a093a680361b7dc56f14503b55eeec3b3f4fd4ca99d6aedce0830f7f4ae2f7328539b34c48fc9760922333dae9c7c017e7db73b8faa6c06be05e347992b06
+
+PRIV: 00d735ebaee75dd579a40dfd82508274d01a1572df99b811d5b01190d82192e4ba02517c0fdd3e2614b3f7bf99ed9b492b80edf0495d230f881730ea45bc17c4
+PUB: ba02517c0fdd3e2614b3f7bf99ed9b492b80edf0495d230f881730ea45bc17c4
+MESSAGE: 59c0b69af95d074c88fdc8f063bfdc31b5f4a9bc9cecdffa8128e01e7c1937dde5eb0570b51b7b5d0a67a3555b4cdce2bca7a31a4fe8e1d03ab32b4035e6dadbf1532059ee01d3d9a7633a0e706a1154cab22a07cd74c06a3cb601244cf3cf35a35c3100ba47f31372a2da65dcff0d7a80a1055d8aa99212e899aad7f02e949e6fee4d3c9cefa85069eaff1f6ad06fc300c871ab82b2bedb934d20875c2a263242cdb7f9be192a8710b24c7ea98d43daec8baa5553c678a38f0e0adf7d3ff2dcc799a1dbad6eab1c3d9458a9db922f02e75cfab9d65c7336dae71895d5bb15cac203f2b38b9996c410f8655ad22d3c091c20b7f926d45e780128f19747462abc5c58932fbb9e0bc62d53868802f1b083f183b8a1f9434986d5cf97c04e2f3e145730cba98779c7fed0cab1c05d5e4653c6c3f6736260bc78ee4372862ffe9e90371d762c7432781f35ced884a4baca05653ef25f25a6f3d5628308
+SIG: dcdc54611937d2bd06cacd9818b3be15ce7425427a75f50d197a337a3b8ba6714ef48866f243bd5ac7415e914517a2c1c5a953f432b99db0e620d64f74eb8505
+
+PRIV: 8c34b905440b61911d1d8137c53d46a1a76d4609af973e18eb4c5709295627bbb69a8b2fdf5c20e734c2ffb294bc8ae1011d664f11afe7fbc471925cf72fa99d
+PUB: b69a8b2fdf5c20e734c2ffb294bc8ae1011d664f11afe7fbc471925cf72fa99d
+MESSAGE: 30b57a389b48a0beb1a48432bff6b314bded79c4a1763a5acb57cea1bfb4c6d016cf090f5bd05bbd114e33ae7c17782dfa264f46c45f8c599c603016fe9ff05b6b5a99e92fe713a4cd5c41b292ed2bb2e9cf33a440542e821ec82cbf665c3f02e3dc337d7fdb58e31b27cb2954541468814698510df18c85c81fad12db11ec6b966f4930da5646b991db97445097da30dab61cda53a41083cb96add19de6c5eec323bca9d3530e38c00b35af7360077601be6ac97f3030f930a27b90fe8b6911bae389065adc15e1882300e2a003274d23182d5efd5ba4b9130c07bd5c65fecb8b5cb7eb38836b318befdfd77de4d6ca0181f77ae5740891683225f549dd8426145c97c5818c319f7ab2d868e1a41ceab64c085116069897bf2ca3667652406155ed0646431b6de1ccc03b4279ae4d326679265dce82048e7298e1f87fcec0768ac0f5d8ff84f7210be54d411af8edea7217f4e59413121e148c60da
+SIG: 3e0b72073dc9375eedcca6c4fc1cd315938a050c92716bd2284f4629a962beec0b7d7cf16ab923d58f5b90d3901a8e5c75c8f17dab9998e007d8c49511973d0e
+
+PRIV: 77a83e18c9f000eeff7deeac959ecba2206c0aa39d2f0e2aed5729482a7a022962b1b316135596bfbca6037ed847c61fb7f09fa36ce90abb7789b86f768b59dd
+PUB: 62b1b316135596bfbca6037ed847c61fb7f09fa36ce90abb7789b86f768b59dd
+MESSAGE: f3d5fa2acaefd858f1df26e03059cdcbc2468ad74afc993d0db9c4cde4113f8d55c7da71d38ba06520531c61fddb5f33d5f0353be2376e580711be45c0a30b1fa01b55e228c6fa35e3f95b67909fc7df3fd464d93d661a926f9d11f7550c17fbcc3496526e8f10e0c8916677b2be5b319b688f21e81aaa9482e5c93e64ce8c437b9c1e14fefed70a3fee568811dc31cadab3d5b220254465336dc4d97a3bd096b5e065e0cfbe82849e2c1905aca486533f0da7a61f1e9a55b8e2a83262deeb59f2b13d3a8aef5700845b83b25ae2183c0ddac0ce42f8d25674cb0d0d220a6de7c1858bb07d59a3372344d944602aa451d2b937db0fe6feca0beba81721fc361ea7509e2b6d397e1c191b56f54ab436d0d27ab4c061bd661ad1a4452387e8735754d07fa7ef4d4548b172582425b299046e6301b5ba6b914418f149cf722e10bde2e0d41700f12c8429fc897b7819da92292240cd45565458c9a7b29c12
+SIG: 1eaad8420ac12c99ac1ff4476678e3cbbe94da6a797f174664d5ee0f641433fb1e7cb2f5613e10805df8654cd8e0d45d96230932bc7f20b04eae836435134309
+
+PRIV: 73b03373ef1fd849005ecd6270dd9906f19f4439e40376cdbc520902bc976812663719e08ba3ba1666f6069a3f54991866b18cc6be41991b02eb3026ff9e155f
+PUB: 663719e08ba3ba1666f6069a3f54991866b18cc6be41991b02eb3026ff9e155f
+MESSAGE: d5c2deaba795c30aba321bc7de6996f0d90e4d05c747fb4dae8f3451895def6e16e72f38eace756f36635f8fb0b72a3a0c1f54663817a94d4fd346f835ab0e657f001a6f2cecb86d0825bd02639254f7f7f38ca99dbb86c64a633f73baf933aae3563281f4005e2d0e7cec9fbde8e588a957e211068be65b3d3d35bf4e8d5bb3478333df9ced9b2abaf48697994a145e9321499fc5ee560f4fbb6849e1ae8eb3d1de0083a21a03f6a6b28176f0130d3895e50e75e3d7d0947a7bc2c5b9ff69895d27791442ba8d0f2180712b567f712ea912f3b0d92c19342e0106ff1d87b46ad33af300b90855ba9769d366e79425d98e4de19905a04577707cbe625b84691781cd26bf62260b4a8bd605f77af6f970e1b3a112e8918344bd0d8d2e41dfd2ce9895b0246e50887aa3a577ff73be4b6ae60feb0ca36f6a5f8171ed209e5c566529c0940d9b4bd744ccee56e54a9a0c6e4da520dd315c2872b02db563703e
+SIG: a40abe98fc69da8a1ff9ff5c2cca93632e975980ee8b82c3c376022d6524ab736d01b072f2b681b5f1cd3ea067012ed6d074e949c42327a366caa9e4750a3c08
+
+PRIV: eab179e41ed5c889ffe6aabdc054faf1307c395e46e313e17a14fe01023ffa3086f34746d3f7a01ddbe322f1aca56d22856d38733a3a6900bb08e776450ec803
+PUB: 86f34746d3f7a01ddbe322f1aca56d22856d38733a3a6900bb08e776450ec803
+MESSAGE: 971095cebe5031530224387c5c31966e389b8566390054cf45264b44e18964b7be52c33c4ffb259af16283438fa15dd66bc7791b7533ef10cb0beab524a6437626f4cc74512851adcc2fb129055a482c61107383fb7c5241831d5551634eef0dc0b8f9053a00971aa8fa1ae0898e4b481b6707e97c0f942040b339d92fc17bbade74675af243d8b2dafb15b1db55d12415b85f3037291930ab61600ba3431f8eb425be4491614728af101e81c091f348bc5ffd1bde6ae6cad5c15b3aa7358078cc4effb54a86e7f0e0c55e4cfe0a54605ed443fdf2aaba016585da617e77341d52889d75dd540d39fe8b7993ed705cfddea0cb0d5a731d6bfcdb816afaff47e963eedebdf241af5593353d6d401a34f029a8cdeb1904cc2caa4f9635cc2ba6b7b1a29da625ffc383be2f5a8f1fa4f39b2d4b4f4c2d8838ce258a04d4a120493fdf07f68c0ffd1c16b768a35c55fea2cac696b5c20efc10865cde8a64627dcd
+SIG: 143cb28027c2f82e375e5f340e7fe6e60ce7bd51000b49c74168af85e26ed2ed630ed2672090164cc54b052da694ebdd21a21b3053f4dcfd7895ea5f6c8aa80d
+
+PRIV: fbf146ebd51075570ec51ac410ae9f391db75b610ada6362b4dbd949656cfb66be7c2f5b21d746c8ea3245ce6f268e9da74e00fa85c9c475260c68fa1af6361f
+PUB: be7c2f5b21d746c8ea3245ce6f268e9da74e00fa85c9c475260c68fa1af6361f
+MESSAGE: cd7ad4f17fcff73acc402dc102d09079b29aaf2a0f4b27cf6beeb1e2b23d19ab47deb3ae1becd68861ea279c46691738f4fff47c43047c4f8b56b6bbcc3fde0723d44120dcd307a6310dc4f366b8f3cd52db19b8266a487f7872391c45fe0d3248a7abf2c20022d3769547f683067dcc363cd22fd7cda3cadc15804056f0e2aa2b795008c598be7a961805e6df291ba3041c47ff5640275f46e6ae82092d21abcbcfba11e730216008822de3ce462400596da79f7ae5d1df8389112ad98868fa94fb0546bfe6a67aa8d28c4d32072d2eadd6256255f18c2382e662dfa922a680e06a43622c4871d27d1807f7b2703070c83db8dd929c06038b2183cb8e2b9ec4c778d7ecf9e9ffac77fa7737b055feac2e7982aeeec0b72f1bbca2424e1a844bbac79cb2e7400f81dc449d0560b521a7c16bb4167e6696586058a9b8ed2e5116690b77f2a17e5c0b16a83dcbd2e24552293e258b32ba7f844944379342698627
+SIG: 6768006fe0f201b217dd10eb05d4b82adcfeb2ecfc8373c3308f4150394811eb60491881a2e53d1289d96478e18a64c34b2a19832cdccfd96a2e4a0c469fdc0b
+
+PRIV: dff0eb6b426dea2fd33c1d3fc24df9b31b486facb7edb8502954a3e8da99d9fdc245085ece69fb9aa560d0c27fdb634f7a840d41d8463660fbe82483b0f3cc3a
+PUB: c245085ece69fb9aa560d0c27fdb634f7a840d41d8463660fbe82483b0f3cc3a
+MESSAGE: e7c9e313d86160f4c74aa0ae07369ee22b27f81b3f69097affae28dae48483fb52a5c062306b59610f5cdbff6332b1960cd6f2b8f7b41578c20f0bc9637a0fdfc739d61f699a573f1c1a0b49294506cf4487965e5bb07bbf81803cb3d5cb3829c66c4bee7fc800ede216150934d277dea50edb097b992f11bb669fdf140bf6ae9fec46c3ea32f888fde9d154ea84f01c51265a7d3fef6eefc1ccdbffd1e2c897f05546a3b1ca11d9517cd667c660ec3960f7a8e5e80202a78d3a388b92f5c1dee14ae6acf8e17c841c9557c35a2eeced6e6af6372148e483ccd06c8fe344924e1019fb91cbf7941b9a176a073415867210670410c5dbd0ac4a50e6c0a509ddfdc555f60d696d41c77db8e6c84d5181f872755e64a721b061fcd68c463db4d32c9e01ea501267de22879d7fc12c8ca0379edb45abaa6e64dda2af6d40ccf24fbebad7b5a8d3e52007945ecd3ddc1e3efeb522581ac80e98c863ba0c590a3ed95cd1
+SIG: 6b48b10f545ddb7a89cd5829f4e5b20146cf6bc96e550d06f65de8bdae7ccdded26cd630f86c9266bccf88e924033e04f83a54f8290d7f734cf8673cca8f9703
+
+PRIV: 9f32958c7679b90fd5036056a75ec2eb2f56ec1effc7c012461dc89a3a1674201d7269dcb6d1f584e662d4ce251de0aba290ef78b97d448afb1e5333f1976d26
+PUB: 1d7269dcb6d1f584e662d4ce251de0aba290ef78b97d448afb1e5333f1976d26
+MESSAGE: a56ba86c71360504087e745c41627092ad6b49a71e9daa5640e1044bf04d4f071ad728779e95d1e2460584e6f0773545da82d4814c9189a120f12f3e3819813e5b240d0f26436f70ee353b4d20cea54a1460b5b8f1008d6f95f3aa2d8f1e908fced50d624e3a096938b9353854b96da463a2798a5a312ec790842c10c446e3350c764bf5c972593b9987bf23256daa8894d47f22e85b97607e66fc08a12c789c4746080368d321bb9015a1155b65523ad8e99bb989b44eac756b0734acd7c6357c70b59743246d1652d91b0f9896965141345b9945cf34980452f3502974edb76b9c785fb0f4395266b055f3b5db8aab68e9d7102a1cd9ee3d142504f0e88b282e603a738e051d98de05d1fcc65b5f7e99c4111cc0aec489abd0ecad311bfc13e7d1653b9c31e81c998037f959d5cd980835aa0e0b09bcbed634391151da02bc01a36c9a5800afb984163a7bb815edbc0226eda0595c724ca9b3f8a71178f0d20a5a
+SIG: 9881a5763bdb259a3fefbba3d957162d6c70b804fa94ab613406a6ec42505b8789465ca1a9a33e1895988842270c55e5bdd5483f6b17b31781b593507a6c1808
+
+PRIV: f86d6f766f88b00717b7d6327eb26cf3ceeba5385184426f9cfd8295e2421ff2cb1d250504754183704dbe21c323d66f9f9011758f6d8dab6f597b199662145b
+PUB: cb1d250504754183704dbe21c323d66f9f9011758f6d8dab6f597b199662145b
+MESSAGE: da8423a6b7a18f20aa1f90ed2331b17b24067c40175bc25d8109e21d87ac00528eb3b2f66a2b52dc7ef2f8cecb75c76099cfa23db8da897043ba1cce31e2dfea46075f5e073203eaeb3d62c84c107b6dab33a14eaf149aa61850c15f5a58d88a15aba9196f9e495e8dbecbcf7e8444f5dd72a08a099d7f6209990b562974ea829ef11d29a920e3a799d0d92cb50d50f817631ab09de97c31e9a05f4d78d649fcd93a83752078ab3bb0e16c564d4fb07ca923c0374ba5bf1eea7e73668e135031feafcbb47cbc2ae30ec16a39b9c337e0a62eecdd80c0b7a04924ac3972da4fa9299c14b5a53d37b08bf02268b3bac9ea9355090eeb04ad87bee0593ba4e4443dda38a97afbf2db9952df63f178f3b4c52bcc132be8d9e26881213abdeb7e1c44c4061548909f0520f0dd7520fc408ea28c2cebc0f53063a2d30570e05350e52b390dd9b67662984847be9ad9b4cd50b069ffd29dd9c62ef14701f8d012a4a70c8431cc
+SIG: ec61c0b292203a8f1d87235ede92b74723c8d23408423773ae50b1e9bc4464e03e446da9dce4c39f6dd159bea26c009ed00120bc36d4a247dc0d24bcefcc110c
+
+PRIV: a5b34cefab9479df8389d7e6f6c146aa8affb0bec837f78af64624a145cc344e7b0f4f24d9972bc6fe83826c52716ad1e0d7d19f123858cb3e99fa636ac9631a
+PUB: 7b0f4f24d9972bc6fe83826c52716ad1e0d7d19f123858cb3e99fa636ac9631a
+MESSAGE: e21e98af6c2bac70557eb0e864da2c2b4d6c0a39a059d3477251f6178a39676f4749e7fbea623f148a43a8b0fe0610506fa658abd2f5fa39198f2636b724db22d1aebc2ab07b2b6dbffdee8cece81e1af1493ec1964e16bf86ab258ca0feb77e3c8717e44038abe152c14be15660bf93b2d48d92c4ed7074d2494210621bcf204fba88c654d5ffe01e1a53d08f70bb237089dc807216ff6a85dbec3102237d42590778acf6c1dc566d5a2bb9a63bc21c329c272e5965baeeb0fe891de3cc8cbfa8e541a8881df68942e7ff8dc656bd08575f6aaf924a176d663b1a1f43574d11768c701b269561e55438dbebfd443d2115cb933d1cde4a915b54c325c27f499ef02bd012ff1f9a36390922887600fe712bcdc23eb5974a305372ad52951f83f0e58cc49e289841621917f1fcb0235147240dae4cf3b99b6ac6d8de94efe7c4436714508bcd0114c56068ff1b7c16d51bd906437874d6549ab5d8087896872ec8a09d7412
+SIG: 2fbd899d72b6d39e4f45b8b62cbbd5f3c0acb1ad8540913fa585877e91ccfef7bee50a4b0f9fedf5cc1e0d1953ad399c8389a93391e1b7c929af6d6f3b796c08
+
+PRIV: ad75c9ce299c4d59393367d77a4c9f8df8dcec765c6dbd25b527fb7669913604b9910548fe6312a119c9993eebcfb9dc90030ffb0e4de2b7ccd23cbeb4fef71b
+PUB: b9910548fe6312a119c9993eebcfb9dc90030ffb0e4de2b7ccd23cbeb4fef71b
+MESSAGE: 62fc5ab67deb1fee9ab6cca3b88a1df1e589f0fd4a88f4aa7738948761fe84372c5b18e4655220c1d84d52acad32e229a5c756c20fc62fe4b4b4e5fd7077ae4ed5397aa796f2307ceedb6505b39297856f4aeb5e70938e36ee24a0ac7d9868306f6b53910623b7dc89a6672ad738576ed5d88831dd338321c8902bc2061f65e94d452fdfa0dc665cefb92308e52301bd4627006b363d06b775a395914d8c863e95a00d6893f3376134c429f56478145e4456f7a12d65bb2b8965d728cb2ddbb708f7125c237095a92195d92fa727a372f3545ae701f3808fee802c8967a76e8a940e55fb2d810bfb47ada156f0eda1829b159cf05c7f36cf3847d7b21de84c3dc0fe658347f79396a01139a508b60022db1c0e5aeef47e445e66f783e62c96597bdb16f209c08a9132c7573136170ee3ebf24261265a89fb4f10333375e20b33ab7403464f5249461c6853c5fddb9f58af816892910393a7077b799fdc3489720998feea86
+SIG: 6b7ef27bcfbf2b714985033764fccff555e3f5bc44610d6c8c62117cb3831a07f4a8bddb0eaed1d46b0289b15de1aa4dcc17d71be96a09e66ba4dc4627c78705
+
+PRIV: 1ced574529b9b416977e92eb39448a8717cac2934a243a5c44fb44b73ccc16da85e167d5f062fee82014f3c8b1beaed8eefb2c22d8649c424b86b21b11eb8bda
+PUB: 85e167d5f062fee82014f3c8b1beaed8eefb2c22d8649c424b86b21b11eb8bda
+MESSAGE: 1b3b953cce6d15303c61ca707609f70e7250f6c0deba56a8ce522b5986689651cdb848b842b2229661b8eeabfb8570749ed6c2b10a8fbf515053b5ea7d7a9228349e4646f9505e198029fec9ce0f38e4e0ca73625842d64caf8ced070a6e29c743586aa3db6d82993ac71fd38b783162d8fe04ffd0fa5cbc381d0e219c91937df6c973912fc02fda5377312468274c4bee6dca7f79c8b544861ed5babcf5c50e1473491be01708ac7c9ff58f1e40f855497ce9d7cc47b9410f2edd00f6496740243b8d03b2f5fa742b9c630867f77ac42f2b62c14e5ebddc7b647a05fff43670745f2851eff4909f5d27d57ae87f61e965ee60fdf97724c59267f2610b7ad5de919856d64d7c212659ce8656149b6a6d29d8f92b312be50b6e2a431d36ae022b00a6fe360e3af65432899c43be0427e36d21cfec81f21aa53b33db5ed2c37da8f96ac3e7dc67a1de37546cf7de1008c7e1adbe0f34fa7eb2434d94e6a13f4cf86a98d497622f
+SIG: e0303aefe08a77738dcc657afbb9b835ed279613a53c73fdc5ddbfb350e5cff4d6c9bb43dc07c95bf4e23b64c40f8804c7169952e3c8d59a7197241bfed0740f
+
+PRIV: f0790d93e2d3b84f61ef4c807147aba410e415e72b71b0d61d01026fed99da3defdf649fb033cf328e0b287796f8a25e9c6e2e871b33c2c21a4028a8a25a4b28
+PUB: efdf649fb033cf328e0b287796f8a25e9c6e2e871b33c2c21a4028a8a25a4b28
+MESSAGE: 7973e9f32d74805992eb65da0d637335e50eff0ce68ea2d1f3a02de704492b9cfbe7e7ba96fdb42bb821a513d73fc60402e92c855deaed73ffeaf70952029062c833e14ec1b14f144e2207f6a0e727e5a7e3cbab27d5972970f69518a15b093e740cc0ce11bf5248f0826b8a98bde8bf2c7082c97aff158d08371118c89021cc3974ae8f76d86673c3f824b62c79c4b41f40eaa8943738f03300f68cbe175468eb235a9ff0e6537f8714e97e8f08ca444e41191063b5fabd156e85dcf66606b81dad4a95065584b3e0658c20a706eaf4a0777da4d2e0cd2a0fca60109c2b4403db3f03cd4781c1fbb0272202bcb11687808c50cb98f64b7f3fd3d43333bb5a061b9e377090abb1e0a885cb26b73c163e63ff6451ff2f4ec8249c7e152bd03973a1e964e2b5b235281a938399a112a24529e383a560dc50bb1b622ad74ef35658dcb10ffe022568ac3ffae5b465a8ed7643e8561b352ee9944a35d882c712b187788a0abae5a22f
+SIG: 08773a6a78762cbb1e25fcbb29139941bdf16f4e09a1fa08fc701f32f933edd74c0ae983c12a0a5b020b6bcf44bb719dde8ed0781a8298265640e1608c98b301
+
+PRIV: 4cb9df7ce6fae9d62ba09e8eb70e4c969bdeafcb5ec7d7024326e6603b0621bf018069dd0eb44055a35cd8c77c37ca9fb1ad2417271385e134b2f4e81f52033c
+PUB: 018069dd0eb44055a35cd8c77c37ca9fb1ad2417271385e134b2f4e81f52033c
+MESSAGE: 14627d6ea0e7895460759476dc74c42800ceef994327518151490d9df23067914e44788a12768ccb25471b9c3ba9d14fb436dcba38429b3a0456877763c49175d0e082683e07a9058f3685c6279307b2303d1221b9c29793d8a4877f6df51587384dadf751c5f7bfbd207d519622c37b51ceeee2c20d8269f8cb88d3fe43d6d434d5bbd0e203c1532d97ba552147227496c87f67b50bb76193add0144df1c176657585408362ca2ed04ad62acf1c25e341dfd1498d85b4b1349a8b0b9b02c43523c55853419bfed37d5a2cdf17dfbf1a3bd7759d6ae180f9d27dcd9a8933e29a7c0a30771eea7c2e0fa242925d2336dce585629057d844323964f6d3d11ff0b3f829a3be8c9f0468a6823d8e70ab5a2da21e15fa8b041a29812222e9c30b2bd9a12d1fdee6f87876e8ce81009637a8bb2236129a47ca74289ee4aad429ffe29f47430241ca8cc3848b7200fd6e1470651a9a0a6f72c9033e831df051408a6260f65cbaf6e012b18e
+SIG: e33c07836c537d6bfbd0f4592d6e35b163499ba78dc7ffcec565d04f9a7db781943e29e6ce76763e9baddf57437fd9c6b03239a6e6850e4502a356c2e12c3705
+
+PRIV: a136e009d53e5ef59d0946bc175663a86bc0fcd29eadd95cfc9d266037b1e4fb9c1806ec0454f58314eb8397d64287dee386640d8491aba364607688841715a0
+PUB: 9c1806ec0454f58314eb8397d64287dee386640d8491aba364607688841715a0
+MESSAGE: a49d1c3d49e13c2eda56868a8824aa9f8d2bf72f21955ebafd07b3bdc8e924de20936cee513d8a64a47173a3bd659eff1accff8244b26aae1a0c27fa891bf4d85e8fb1b76a6cab1e7f74c89ee07bb40d714326f09b3fd40632fad208ea816f9072028c14b5b54ecc1c5b7fc809e7e0786e2f11495e76017eb62aa4563f3d00ee84348d9838cd17649f6929a6d206f60e6fc82e0c3464b27e0e6abd22f4469bdfd4cb54f77e329b80f71bf42129ec13c9dfe192adfaa42ee3ddeeda385816fbad5f411938c63b560f4ecd94534be7d98725cd94c99ce492f0f069ba0ec08f877a7812ef27ae19d7a77be63f66bcf8d6cf3a1a61fc9cfef104c7462a21ca7f03afb5bb1ac8c75124b554e8d044b810d95ff8c9dd09a34484d8c4b6c95f95c3c22823f52ce844293724d5259191f1ba0929e2acdbb8b9a7a8adf0c52e78acdfdf057b0985881afbed4dbebdebbdae0a2b63bd4e90f96afdcbbd78f506309f9bdb650013cb73faed73904e
+SIG: bc094ba91c115dee15d753361a75f3f03d6af45c92157e95dbe8d32194b6c5ce72b9dc66f73df12dca0b639f3e791d478616a1f8d7359a42c8eae0dda16b1606
+
+PRIV: ff0f1c57dd884fbeea6e2917282b79ba67f8a6851267b9f4636dafda33bd2b5bfef6378ad12a7c252fa6eb742b05064b41530ff019dc680ab544c027ea2836e7
+PUB: fef6378ad12a7c252fa6eb742b05064b41530ff019dc680ab544c027ea2836e7
+MESSAGE: 522a5e5eff5b5e98fad6878a9d72df6eb318622610a1e1a48183f5590ecef5a6df671b28be91c88cdf7ae2881147fe6c37c28b43f64cf981c455c59e765ce94e1b6491631deaeef6d1da9ebca88643c77f83eae2cfdd2d97f604fe45081d1be5c4ae2d875996b8b6fecd707d3fa219a93ba0488e55247b405e330cfb97d31a1361c9b2084bdb13fb0c058925db8c3c649c9a3e937b533cc6310fa3b16126fb3cc9bb2b35c5c8300015488a30fadca3c8871fa70dfdc7055bf8e631f20c9b2528311e324a7c4edd5462079f3441c9ecf55fa999e731372344fdc0d413e417aaa001a1b2d3d9bc000fec1b02bd7a88a812d9d8a66f9464764c070c93041eefb17ce74eff6d4aff75f0cbf6a789a9ecde74abe33130fca0da853aa7c3313ada3f0ae2f595c6796a93685e729dd18a669d6381825ab3f36a391e7525b2a807a52fa5ec2a030a8cf3b77337ac41fceb580e845eed655a48b547238c2e8137c92f8c27e585caad3106eee3814a
+SIG: d5008486726cce330a29dd7e4d7474d735798201afd1206feb869a112e5b43523c06976761be3cf9b2716378273c94f93572a7d2b8982634e0755c632b449008
+
+PRIV: 0bc6af64de5709d3dbc28f7ef6d3fe28b6de529f08f5857ccb910695de454f56fb491fc900237bdc7e9a119f27150cd911935cd3628749ff40ef41f3955bc8ac
+PUB: fb491fc900237bdc7e9a119f27150cd911935cd3628749ff40ef41f3955bc8ac
+MESSAGE: ac7886e4f4172a22c95e8eea37437b375d72accedcee6cc6e816763301a2d8ef4d6f31a2c1d635818b7026a395ce0dafd71c5180893af76b7ea056c972d680eca01dcbdbae6b26f1c5f33fc988b824fbbe00cacc316469a3bae07aa7c8885af7f65f42e75cef94dbb9aab4825143c85070e7716b7612f64ef0b0166011d23eb5654aa098b02d8d71e57c8fa17bff2fe97dc8193177eadc09fb192d80aa92afa98720d4614817ff3c39d3acce18906fa3de09618931d0d7a60c4429cbfa20cf165c947929ac293ae6c06e7e8f25f1264291e3e1c98f5d93e6ecc2389bc60dbbf4a621b132c552a99c95d26d8d1af61138b570a0de4b497ebe8051c7273a98e6e7876d0b327503af3cb2cc4091ce1925cb2f2957f4ec56ee90f8a09dd57d6e83067a356a4cfe65b1b7a4465da2ab133b0efb5e7d4dbb811bcbbde712afbf0f7dd3f326222284b8c74eac7ad6257fa8c632b7da2559a6266e91e0ef90dbb0aa968f75376b693fcaa5da342221
+SIG: dbc7134d1cd6b0813b53352714b6df939498e91cf37c324337d9c088a1b998347d26185b430900412929e4f63e910379fc42e355a4e98f6fee27dafad1957206
+
+PRIV: 2f5e83bd5b412e71ae3e9084cd369efcc79bf6037c4b174dfd6a11fb0f5da218a22a6da29a5ef6240c49d8896e3a0f1a4281a266c77d383ee6f9d25ffacbb872
+PUB: a22a6da29a5ef6240c49d8896e3a0f1a4281a266c77d383ee6f9d25ffacbb872
+MESSAGE: b766273f060ef3b2ae3340454a391b426bc2e97264f8674553eb00dd6ecfdd59b611d8d662929fec710d0e462020e12cdbf9c1ec8858e85671acf8b7b14424ce92079d7d801e2ad9acac036bc8d2dfaa72aa839bff30c0aa7e414a882c00b645ff9d31bcf5a54382def4d0142efa4f06e823257ff132ee968cdc6738c53f53b84c8df76e9f78dd5056cf3d4d5a80a8f84e3edec48520f2cb4583e708539355ef7aa86fb5a0e87a94dcf14f30a2cca568f139d9ce59eaf459a5c5916cc8f20b26aaf6c7c029379aedb05a07fe585ccac60307c1f58ca9f859157d06d06baa394aace79d51b8cb38cfa2598141e245624e5ab9b9d68731173348905315bf1a5ad61d1e8adaeb810e4e8a86d7c13537b0be860ab2ed35b73399b8808aa91d750f77943f8a8b7e89fdb50728aa3dbbd8a41a6e00756f438c9b9e9d55872df5a9068add8a972b7e43edad9ced2237ca1367be4b7cdb66a54ea12eef129471158610eaf28f99f7f686557dcdf644ea
+SIG: 9f80922bc8db32d0cc43f9936affebe7b2bc35a5d82277cd187b5d50dc7fc4c4832fffa34e9543806b485c04548e7c75429425e14d55d91fc1052efd8667430b
+
+PRIV: 722a2da50e42c11a61c9afac7be1a2fed2267d650f8f7d8e5bc706b807c1b91dfd0b964562f823721e649c3fedb432a76f91e0aead7c61d35f95ed7726d78589
+PUB: fd0b964562f823721e649c3fedb432a76f91e0aead7c61d35f95ed7726d78589
+MESSAGE: 173e8bb885e1f9081404acac999041d2ecfcb73f945e0db36e631d7cd1ab999eb717f34bf07874bf3d34e2530eb6085f4a9f88ae1b0f7d80f221456a8e9a8890b91a50192deaaacc0a1a615a87841e2c5a9e057957af6e48e78cc86198e32e7aa24dcf6cffa329bc72606d65b11682c8ba736cce22a05785df1146331e41609cf9ca711cf464958297138b58a9073f3bbf06ad8a85d135de66652104d88b49d27ad41e59bcc44c7fab68f53f0502e293ffcabaaf755927dfdffbfde3b35c080b5de4c8b785f4da64ef357bc0d1466a6a96560c3c4f3e3c0b563a003f5f95f237171bce1a001771a04ede7cdd9b8ca770fd36ef90e9fe0000a8d7685fd153cc7282de95920a8f8f0898d00bf0c6c933fe5bb9653ff146c4e2acd1a2e0c23c1244844dacf8652716302c2032f9c114679ed26b3ee3ab4a7b18bc4e3071f0977db57cd0ac68c0727a09b4f125fb64af2850b26c8a484263334e2da902d744737044e79ab1cf5b2f93a022b63d40cd
+SIG: c2695a57172aaa31bd0890f231ca8eeec0287a87172669a899ad0891cea4c47579b50420e791cdec8c182c8a0e8dde21b2480b0cfd8111e28e5603347a352d04
+
+PRIV: 5fe9c3960ed5bd374cc94d42357e6a24dc7e3060788f726365defacf13cd12da0ce7b155c8b20ebdaacdc2aa23627e34b1f9ace980650a2530c7607d04814eb4
+PUB: 0ce7b155c8b20ebdaacdc2aa23627e34b1f9ace980650a2530c7607d04814eb4
+MESSAGE: c9490d83d9c3a9370f06c91af001685a02fe49b5ca667733fff189eee853ec1667a6c1b6c787e9244812d2d532866ab74dfc870d6f14033b6bcd39852a3900f8f08cd95a74cb8cbe02b8b8b51e993a06adfebd7fc9854ae5d29f4df9642871d0c5e470d903cfbcbd5adb3275628f28a80bf8c0f0376687dae673bf7a8547e80d4a9855ae2572fc2b205dc8a198016ddc9b50995f5b39f368f540504a551803d6dd5f874828e5541ded052894d9e2dc5e6aa351087e790c0dd5d9c4decb217e4db81c98a184b264e6daeac0f11e074cae2bfc899f54b419c65dcc22664a915fbfffac35cee0f286eb7b144933db933e16c4bcb650d537722489de236373fd8d65fc86118b6def37ca4608bc6ce927b65436ffda7f02bfbf88b045ae7d2c2b45a0b30c8f2a04df953221088c555fe9a5df260982a3d64df194ee952fa9a98c31b96493db6180d13d67c36716f95f8c0bd7a039ad990667ca34a83ac1a18c37dd7c7736aa6b9b6fc2b1ac0ce119ef77
+SIG: 379f9c54c413af0d192e9bc736b29da9d521e7ba7841d309f9bcc1e742ec4308fe9f7ba51e0b22aed487cb4aa3913b9bebfb3aacd38f4039f9bbbebe1ad80002
+
+PRIV: ec2fa541ac14b414149c3825eaa7001b795aa1957d4040dda92573904afa7ee471b363b2408404d7beecdef1e1f511bb6084658b532f7ea63d4e3f5f01c61d31
+PUB: 71b363b2408404d7beecdef1e1f511bb6084658b532f7ea63d4e3f5f01c61d31
+MESSAGE: 2749fc7c4a729e0e0ad71b5b74eb9f9c534ebd02ffc9df4374d813bdd1ae4eb87f1350d5fdc563934515771763e6c33b50e64e0cd114573031d2186b6eca4fc802cddc7cc51d92a61345a17f6ac38cc74d84707a5156be9202dee3444652e79bae7f0d31bd17567961f65dd01a8e4bee38331938ce4b2b550691b99a4bc3c072d186df4b3344a5c8fbfbb9fd2f355f6107e410c3d0c798b68d3fb9c6f7ab5fe27e70871e86767698fe35b77ead4e435a9402cc9ed6a2657b059be0a21003c048bbf5e0ebd93cbb2e71e923cf5c728d1758cd817ad74b454a887126d653b95a7f25e5293b768c9fc5a9c35a2372e3741bc90fd66301427b10824bb4b1e9110bfba84c21a40eb8fed4497e91dc3ffd0438c514c0a8cb4cac6ad0256bf11d5aa7a9c7c00b669b015b0bf81425a21413e2ffb6edc0bd78e385c44fd74558e511c2c25fee1fec18d3990b8690300fa711e93d9854668f0187065e76e7113ae763c30ddd86720b5546a6c3c6f1c43bc67b14
+SIG: 84d18d56f964e3776759bba92c510c2b6d574555c3cddade212da90374554991e7d77e278d63e34693e1958078cc3685f8c41c1f5342e351899638ef61211401
+
+PRIV: 6132692a5ef27bf476b1e991e6c431a8c764f1aebd470282db3321bb7cb09c207a2d166184f9e5f73bea454486b041ceb5fc2314a7bd59cb718e79f0ec989d84
+PUB: 7a2d166184f9e5f73bea454486b041ceb5fc2314a7bd59cb718e79f0ec989d84
+MESSAGE: a9c0861665d8c2de06f9301da70afb27b3024b744c6b38b24259294c97b1d1cb4f0dcf7575a8ed454e2f0980f50313a77363415183fe9677a9eb1e06cb6d34a467cb7b0758d6f55c564b5ba15603e202b18856d89e72a23ab07d8853ff77da7aff1caebd7959f2c710ef31f5078a9f2cdae92641a1cc5f74d0c143ec42afbaa5f378a9e10d5bf74587fa5f49c156233247dafd3929acde888dc684337e40cdc5932e7eb73ffcc90b85c0ad460416691aefbd7efd07b657c350946a0e366b37a6c8089aba5c5fe3bbca064afbe9d47fbc83914af1cb43c2b2efa98e0a43be32ba823202001def36817251b65f9b0506cef6683642a46ed612f8ca81ee97bb04d317b517343ade2b77126d1f02a87b7604c8653b6748cf5488fa6d43df809faa19e69292d38c5d397dd8e20c7af7c5334ec977f5010a0f7cb5b89479ca06db4d12627f067d6c42186a6b1f8742f36ae709ba720e3cd898116666d81b190b9b9d2a72202cb690a03f3310429a71dc048cde
+SIG: eb677f3347e1a1ea929efdf62bf9105a6c8f4993033b4f6d03cb0dbf9c742b270704e383ab7c0676bdb1ad0ce9b16673083c9602ec10ae1dd98e8748b336440b
+
+PRIV: f219b2101164aa9723bde3a7346f68a35061c01f9782072580ba32df903ba891f66b920d5aa1a6085495a1480539beba01ffe60e6a6388d1b2e8eda23355810e
+PUB: f66b920d5aa1a6085495a1480539beba01ffe60e6a6388d1b2e8eda23355810e
+MESSAGE: 015577d3e4a0ec1ab25930106343ff35ab4f1e0a8a2d844aadbb70e5fc5348ccb679c2295c51d702aaae7f6273ce70297b26cb7a253a3db94332e86a15b4a64491232791f7a8b082ee2834af30400e804647a532e9c454d2a0a7320130ab6d4d860073a34667ac25b7e5e2747ba9f5c94594fb68377ae260369c40713b4e32f23195bf91d3d7f1a2719bf408aad8d8a347b112e84b118817cb06513344021763035272a7db728a0ccdaa949c61715d0764140b3e8c01d20ff1593c7f2d55c4e82a1c0cb1ea58442bf80a741bca91f58ab0581b498ee9fe3c92ca654148ef75313543d1aff382befe1a93b02190ce0102175158e2071d02bacad8dbe9fb940fcb610c105ad52c80feb1ec4e524f4c0ec7983e9ce696fa4fcf4bf0514b8f0432b17d5448fc426fea2b01ac7b26c2aed769927534da22576fc1bba726e9d65be01b59f60a648ace2fc3e5e275789fa637cbbd84be3d6ac24457a6292cd656c7b569a52ffea7916b8d04b4f4a75be7ac95142f
+SIG: 17f0127ca3bafa5f4ee959cd60f772be87a0034961517e39a0a1d0f4b9e26db1336e60c82b352c4cbacdbbd11771c3774f8cc5a1a795d6e4f4ebd51def36770b
+
+PRIV: fc180035aec0f5ede7bda93bf77ade7a81ed06de07ee2e3aa8576be81608610a4f215e948cae243ee3143b80282ad792c780d2a6b75060ca1d290ca1a8e3151f
+PUB: 4f215e948cae243ee3143b80282ad792c780d2a6b75060ca1d290ca1a8e3151f
+MESSAGE: b5e8b01625664b222339e0f05f93a990ba48b56ae65439a17520932df011721e284dbe36f98631c066510098a68d7b692a3863e99d58db76ca5667c8043cb10bd7abbaf506529fbb23a5166be038affdb9a234c4f4fcf43bddd6b8d2ce772dd653ed115c095e232b269dd4888d2368cb1c66be29dd383fca67f66765b296564e37555f0c0e484504c591f006ea8533a12583ad2e48318ff6f324ecaf804b1bae04aa896743e67ef61ca383d58e42acfc6410de30776e3ba262373b9e1441943955101a4e768231ad9c6529eff6118dde5df02f94b8d6df2d99f27863b517243a579e7aaff311ea3a0282e47ca876fabc2280fce7adc984dd0b30885b1650f1471dfcb0522d49fec7d042f32a93bc368f076006ea01ec1c7412bf66f62dc88de2c0b74701a5614e855e9fa728fb1f1171385f96afbde70dea02e9aa94dc21848c26302b50ae91f9693a1864e4e095ae03cdc22ad28a0eb7db596779246712fab5f5da327efec3e79612de0a6ccaa536759b8e
+SIG: a43a71c3a19c35660dae6f31a254b8c0ea3593fc8fca74d13640012b9e9473d4afe070db01e7fb399bf4ca6070e062180011285a67dd6858b761e46c6bd32004
+
+PRIV: a2836a65427912122d25dcdfc99d7046fe9b53d5c1bb23617f11890e94ca93ed8c12bda214c8abb2286acffbf8112425040aab9f4d8bb7870b98da0159e882f1
+PUB: 8c12bda214c8abb2286acffbf8112425040aab9f4d8bb7870b98da0159e882f1
+MESSAGE: 813d6061c56eae0ff53041c0244aa5e29e13ec0f3fb428d4beb8a99e04bca8c41bddb0db945f487efe38f2fc14a628fafa2462f860e4e34250eb4e93f139ab1b74a2614519e41ee2403be427930ab8bc82ec89ceafb60905bd4ddbbd13bdb19654314fc92373140b962e2258e038d71b9ec66b84ef8319e03551cb707e747f6c40ad476fbefdce71f3a7b67a1af1869bc6440686e7e0855e4f369d1d88b8099fba54714678627bba1aff41e7707bc97eddf890b0c08dce3e9800d24c6f61092ce28d481b5dea5c096c55d72f8946009131fb968e2bc8a054d825adab76740dcf0d758c8bf54ff38659e71b32bfe2e615aaabb0f5293085649cf60b9847bc62011ce3878af628984a5840a4ad5dae3702db367da0f8a165fed0517eb5c442b0145330241b97eeca733ba6688b9c129a61cd1236aff0e27bcf98c28b0fbeea55a3d7c7193d644b2749f986bd46af8938e8faaeafbd9cec3612ab005bd7c3eeafe9a31279ca6102560666ba16136ff1452f850adb
+SIG: e6a9a6b436559a4320c45c0c2c4a2aedecb90d416d52c82680ac7330d062aebef3e9ac9f2c5ffa455c9be113013a2b282e5600fd306435ada83b1e48ba2a3605
+
+PRIV: f051af426d0c3282fafc8bf912ade1c24211a95ad200e1eef549320e1cb1a252fa87955e0ea13dde49d83dc22e63a2bdf1076725c2cc7f93c76511f28e7944f2
+PUB: fa87955e0ea13dde49d83dc22e63a2bdf1076725c2cc7f93c76511f28e7944f2
+MESSAGE: b48d9f84762b3bcc66e96d76a616fa8fe8e01695251f47cfc1b7b17d60dc9f90d576ef64ee7d388504e2c9079638165a889696471c989a876f8f13b63b58d531fea4dd1229fc631668a047bfae2da281feae1b6de3ebe280abe0a82ee00fbfdc22ce2d10e06a0492ff1404dfc094c40b203bf55721dd787ed4e91d5517aaf58d3bdd35d44a65ae6ba75619b339b650518cefcc17493de27a3b5d41788f87edbde72610f181bf06e208e0eb7cdfe881d91a2d6cc77aa19c0fcf330fedb44675d800eb8cff9505d8887544a503cbe373c4847b19e8f3995726efd6649858595c57ccaf0cbc9eb25de83ba046bc9f1838ac7b8953dd81b81ac0f68d0e9338cb55402552afb6bc16949351b926d151a82efc695e8d7da0dd55099366789718ccbf36030bd2c3c109399be26cdb8b9e2a155f3b2cb1bfa71ab69a23625a4ac118fe91cb2c19788cf52a71d730d576b421d96982a51a2991daec440cda7e6cc3282b8312714278b819bfe2387eb96aa91d40173034f428
+SIG: b8f713578a64466719aceb432fce302a87cf066bf3e102a350616921a840964bfc7e685d8fd17455ac3eb4861edcb8979d35e3a4bd82a078cd707721d733400e
+
+PRIV: a103e92672c65f81ea5da1fff1a4038788479e941d503a756f4a755201a57c1dee63a5b69641217acbaf3339da829ec071b9931e5987153514d30140837a7af4
+PUB: ee63a5b69641217acbaf3339da829ec071b9931e5987153514d30140837a7af4
+MESSAGE: b1984e9eec085d524c1eb3b95c89c84ae085be5dc65c326e19025e1210a1d50edbbba5d1370cf15d68d687eb113233e0fba50f9433c7d358773950c67931db8296bbcbecec888e87e71a2f7579fad2fa162b85fb97473c456b9a5ce2956676969c7bf4c45679085b62f2c224fc7f458794273f6d12c5f3e0d06951824d1cca3e2f904559ed28e2868b366d79d94dc98667b9b5924268f3e39b1291e5abe4a758f77019dacbb22bd8196e0a83a5677658836e96ca5635055a1e63d65d036a68d87ac2fd283fdda390319909c5cc7680368848873d597f298e0c6172308030ffd452bb1363617b316ed7cd949a165dc8abb53f991aef3f3e9502c5dfe4756b7c6bfdfe89f5e00febdd6afb0402818f11cf8d1d5864fe9da1b86e39aa935831506cf2400ea7ed75bd9533b23e202fe875d7d9638c89d11cb2d6e6021ae6bd27c7754810d35cd3a61494f27b16fc794e2cd2f0d3453ada933865db78c579571f8fc5c5c6be8eaffce6a852e5b3b1c524c49313d427abcb
+SIG: 2aa2035c2ce5b5e6ae161e168f3ad0d6592bcf2c4a049d3ed342fceb56be9c7cb372027573ae0178e8878ebefca7b030327b8aad41857de58cb78e1a00cbac05
+
+PRIV: d47c1b4b9e50cbb71fd07d096d91d87213d44b024373044761c4822f9d9df880f4e1cb86c8ca2cfee43e58594a8778436d3ea519704e00c1bbe48bbb1c9454f8
+PUB: f4e1cb86c8ca2cfee43e58594a8778436d3ea519704e00c1bbe48bbb1c9454f8
+MESSAGE: 88d7009d51de3d337eef0f215ea66ab830ec5a9e6823761c3b92ad93ea341db92ece67f4ef4ceb84194ae6926c3d014b2d59781f02e0b32f9a611222cb9a5850c6957cb8079ae64e0832a1f05e5d1a3c572f9d08f1437f76bb3b83b52967c3d48c3576848891c9658d4959eb80656d26cdba0810037c8a18318ff122f8aa8985c773cb317efa2f557f1c3896bcb162df5d87681bb787e7813aa2dea3b0c564d646a92861f444ca1407efbac3d12432cbb70a1d0eaffb11741d3718fedee2b83036189a6fc45a52f74fa487c18fd264a7945f6c9e44b011f5d86613f1939b19f4f4fdf53234057be3f005ad64eebf3c8ffb58cb40956c4336df01d4424b706a0e561d601708d12485e21bcb6d799d8d1d044b400064ec0944501406e70253947006cabbdb2dd6bd8cee4497653d9113a44d4de9b68d4c526fca0b9b0c18fe50fb917fdd9a914fb816108a73a6b3fff9e654e69c9cfe02b05c6c1b9d15c4e65cf31018b8100d784633ee1888eee3572aafa6f189ea22d0
+SIG: 627e7ca7e34ed6331d62b9541c1ea9a9292be7b0a65d805e266b5122272a82db7d765acc7e2a290d685804922f91ed04a3c382c03ff21a1768f584413c4e5f00
+
+PRIV: fc0c32c5eb6c71ea08dc2b300cbcef18fdde3ea20f68f21733237b4ddaab900e47c37d8a080857eb8777a6c0a9a5c927303faf5c320953b5de48e462e12d0062
+PUB: 47c37d8a080857eb8777a6c0a9a5c927303faf5c320953b5de48e462e12d0062
+MESSAGE: a7b1e2db6bdd96b3d51475603537a76b42b04d7ebd24fe515a887658e4a352e22109335639a59e2534811f4753b70209d0e4698e9d926088826c14689681ea00fa3a2fcaa0047ced3ef287e6172502b215e56497614d86b4cb26bcd77a2e172509360ee58893d01c0d0fb4d4abfe4dbd8d2a2f54190fa2f731c1ceac6829c3ddc9bfb2ffd70c57ba0c2b22d2326fbfe7390db8809f73547ff47b86c36f2bf7454e678c4f1c0fa870bd0e30bbf3278ec8d0c5e9b64aff0af64babc19b70f4cf9a41cb8f95d3cde24f456ba3571c8f021d38e591dec05cb5d1ca7b48f9da4bd734b069a9fd106500c1f408ab7fe8e4a6e6f3ed64da0ed24b01e33df8475f95fa9ed71d04dd30b3cd823755a3401bf5afae10ee7e18ec6fe637c3793fd434b48d7145130447e00299101052558b506554ec9c399f62941c3f414cbc352caa345b930adecfaddac91ee53d1451a65e06201026325de07c931f69bba868a7c87ee23c604ec6794332917dfe2c5b69669b659706917f71eddf96
+SIG: 6887c6e2b98a82af5ee3dfa7ca2cb25d9c10745620a82956acba85cb57c8ec24279fa42f092359a1b6bbeafba050f14b6288209e6ef7bc1e0a2b872c1138f305
+
+PRIV: a8d73d639a23cc6a967ef31bcabb5d063e53e1eab8fcc7cab9bc3a17fde9c2f88daa9f4c8b1a44691bf44521f2f7ca45dc7fc61f6a4ce6f98faa41c2a74977d1
+PUB: 8daa9f4c8b1a44691bf44521f2f7ca45dc7fc61f6a4ce6f98faa41c2a74977d1
+MESSAGE: fd1fac3d53313b11acd29f5a83ac11896dab2530fa47865b2295c0d99dd67c36ed8e5fa549150c794c5549efb5c1d69114d5d607b23285b7212afaab57846a54ae67b9e880e07b6586607cecf6d4eed516a3a75511fe367d88eb871e6d71b7d6aa1367a01421b1088fc2d75e44954b73625c52da8a3a183c60be9da6050f59a453caa53520593671728d431877bfaac913a765fb6a56b75290b2a8aaac34afb9217ba1b0d5850ba0fdabf80969def0feee794ceb60614e3368e63ef20e4c32d341ec9b0328ea9fe139207ed7a626ff08943b415233db7cfcc845c9b63121d4ed52ec3748ab6a1f36b2103c7dc7e9303acea4ba8af7a3e07184fb491e891ede84f0dc41cadc3973028e879acd2031afc29a16092868e2c7f539fc1b792edab195a25ab9830661346b39ef53915de4af52c421eaf172e9da76a08c283a52df907f705d7e8599c5baae0c2af380c1bb46f93484a03f28374324b278992b50b7afa02552cafa503f034f8d866e9b720271dd68ccb685a85fffd1
+SIG: c4dcef1a2453939b364b340250c3129431431d5ba3f47670ab07ce680c69bf28b678627c76a6360fc40dc109aa7dea371b825e46134f624572182acf3957e70f
+
+PRIV: 79c7dcb7d59a8df6b2b2ba0413059d89680995c20e916da01b8f067dc60cdeb4298743c73918bd556b28f8d4824a09b814752a7aeae7ee04875c53f4d6b108d9
+PUB: 298743c73918bd556b28f8d4824a09b814752a7aeae7ee04875c53f4d6b108d9
+MESSAGE: 5fe202f5b33b7788810d2508a13b3114d69b8596e6eacda05a04a2eb597fa3279c208b5a5b65daacb699f144e1d660e78e139b578331abec5c3c35334454f03e832c8d6e2984df5d450ecb5d33582a78808a9c78f26ebcd1244ef52e3fa6dca115c1f0cb56e38eae0e5b39f5fd863dffd0b2fb5b958f2d739db312fc667a17b031c4c9f8c5a2ad577984cc4146c437580efd2152173fe0d5782cc2ae9831a8d9a04177256018ff7631e0b0d8a99cb28f008b320421e27a74c31359188663456d85e098c1ebd281701097b6ae5a871e5ccc02058a501416cb91c12cef5be6f1914370e563f1a1b2aa41f4b8ee84cd32a1d509e529787d14a445438d807ecd620e2fa26de0da6426864784d4a28f54103e609283b99ee9b2b699c980bbb7882c3ea68ddc90802ac232f2c8e84291987bf3c5240921b59cfa214969317673d0be7f34b1ca0e15ea73c7175401ce550be106b49e62f8db68695e740e0f3a3556a19f3c8e6b91ac1cc23e863fcd0f0d9eb7047aa631e0d2eb9bcc6b
+SIG: 7b7cbe44c771e4371bae13b0722babcc1064155732962f407cba2acd35381d42210bece822f4681121fd4dab745a1f3077922fba1a78045b712902baccac660e
+
+PRIV: b9ced0412593fefed95e94ac965e5b23ff9d4b0e797db02bf497994d3b793e60c1629a723189959337f5535201e5d395ba0a03ea8c17660d0f8b6f6e6404bb12
+PUB: c1629a723189959337f5535201e5d395ba0a03ea8c17660d0f8b6f6e6404bb12
+MESSAGE: 555bb39c1899d57cabe428064c2d925f5fc4cf7059b95fb89a8e9e3a7e426c6c922d9e4d76984ea2383cabb4f2befd89c1f20eaa8a00dbe787cfa70ae2ae6aa90331cbbe580fa5a02184ed05e6c8e89d576af28aeeaf7c4e2500f358a00971a0a75920e854849bf332142975404f598c32e96982043d992bcd1a4fe819bb5634ad03467afc4ce05073f88ba1ba4ae8653a04665cf3f71690fe13343885bc5ebc0e5e62d882f43b7c68900ac9438bf4a81ce90169ec129ee63e2c675a1a5a67e27cc798c48cc23f51078f463b3b7cc14e3bcfd2e9b82c75240934cbdc50c4308f282f193122995606f40135100a291c55afdf8934eb8b61d81421674124dec3b88f9a73110a9e616f5b826b9d343f3ac0e9d7bdf4fd8b648b40f0098b3897a3a1cd65a64570059b8bc5c6743883074c88623c1f5a88c58969e21c692aca236833d3470b3eb09815e1138e9d0650c390eee977422193b00918be8a97cc6199b451b05b5730d1d13358cf74610678f7ac7f7895cc2efc456e03873b
+SIG: f1b797ded8a6942b12626848340fb719fcddafd98f33e2992d357bfdd35933c7ac561e5b2f939464338c5666854ca885c4d046eb2c54e48a1b5ed266ad34de05
+
+PRIV: 81da168f02d46bb87cda845da43f8a6cba2c016878d6f49c6f061a60f155a04aaff86e98093ca4c71b1b804c5fe451cfdf868250dea30345fa4b89bb09b6a53b
+PUB: aff86e98093ca4c71b1b804c5fe451cfdf868250dea30345fa4b89bb09b6a53b
+MESSAGE: 6bc6726a34a64aae76ab08c92b179e54ff5d2e65eb2c6c659ae8703cc245cbc2cf45a12b22c468ae61fd9a6627ad0626c9b1e5af412cb483eaee1db11b29f0a510c13e38020e09ae0eee762537a3e9d1a0c7b033d097fdc1f4f82629a9de9ef38da1cf96a940357d5f2e0e7e8dbc29db728a1e6aad876e5e053113d06420272b87cf0c40dfe03a544de96c7aea13ba0029b57b48d99dcc6a650492d78c4cdd1b28e1a115a7e3e7a7cb21333d4ff80858dfb67782c16354b8716596560d7d8e389eb15a052a0bf5d16eb54fb3e4973ad4984e72a187f5347d5b262c32b1647e42b6a53837096cc78c2a05ce1c6e12493a03f1a667584cb97f4fcd57ee944c65b7eed25f7ae0f3f6cede173fdfacf5af1db143730d18096664914ba4cfc6966f392022781c66a9417ca2680b51f63e4fba424ecfdbc6a2f01787d0e7484f8a8ab390aeaa6d1f7ed325d82feaa1692a4984fae43da87329b045da8f0a4f56b695aa935de152ce0385153720979a2b7006d405fcb0fba09e23b85fd19b
+SIG: 4aaca947e3f22cc8b8588ee030ace8f6b5f5711c2974f20cc18c3b655b07a5bc1366b59a1708032d12cae01ab794f8cbcc1a330874a75035db1d69422d2fc00c
+
+PRIV: af2e60da0f29bb1614fc3f193cc353331986b73f3f9a0aec9421b9473d6a4b6ac8bfe2835822199c6127b806fabeef0cb9ff59f3c81ff0cb89c556f55106af6a
+PUB: c8bfe2835822199c6127b806fabeef0cb9ff59f3c81ff0cb89c556f55106af6a
+MESSAGE: 7dbb77b88bda94f344416a06b096566c6e8b393931a8243a6cab75c361fde7dc536aec40cded83296a89e8c3bef7d787cfc49401a7b9183f138d5000619ff073c05e2f841d6008358f10a2da7dcfac3d4d70c20d2ec34c7b6d5cd1a734d6bbb11c5fd8d2bce32ac810ef82b4188aa8ea3cfc3032233dc0e2600e9db6e18bc22b10044a31c15baceaf5554de89d2a3466807f244414d080ff2963956c6e83c8e144ed0066088b476ddcb564403447d9159f9089aba2b4d5575c4d8ae66fc8690e7349ed40832e6369c024563ec493bfcc0fc9ac787ac841397fe133167283d80c42f006a99d39e82979da3fa9334bd9ede0d14b41b7466bcebbe8171bc804a645d3723274a1b92bf82fd993358744de92441903d436fd47f23d40052a3829367f202f0553b5e49b76c5e03fa6ce7c3cf5eeb21de967bec4dd355925384ebf96697e823762bac4d43a767c241a4cef724a970d00ff3a8ab3b83eed840075c74e90f306e330013260962161e9d0910de183622ce9a6b8d5144280550fc7
+SIG: 50f9f941a8da9f6240f76d2fa3b06dd6b2292ed32d1c05218097d34d8a19dfe553f76ae3c6b4a2ed20852128461540decf418f52d38e64037eec7771bd1afe00
+
+PRIV: 605f90b53d8e4a3b48b97d745439f2a0807d83b8502e8e2979f03e8d376ac9feaa3fae4cfa6f6bfd14ba0afa36dcb1a2656f36541ad6b3e67f1794b06360a62f
+PUB: aa3fae4cfa6f6bfd14ba0afa36dcb1a2656f36541ad6b3e67f1794b06360a62f
+MESSAGE: 3bcdcac292ac9519024aaecee2b3e999ff5d3445e9f1eb60940f06b91275b6c5db2722ed4d82fe89605226530f3e6b0737b308cde8956184944f388a80042f6cba274c0f7d1192a0a96b0da6e2d6a61b76518fbee555773a414590a928b4cd545fccf58172f35857120eb96e75c5c8ac9ae3add367d51d34ac403446360ec10f553ea9f14fb2b8b78cba18c3e506b2f04097063a43b2d36431cce02caf11c5a4db8c821752e52985d5af1bfbf4c61572e3fadae3ad424acd81662ea5837a1143b9669391d7b9cfe230cffb3a7bb03f6591c25a4f01c0d2d4aca3e74db1997d3739c851f0327db919ff6e77f6c8a20fdd3e1594e92d01901ab9aef194fc893e70d78c8ae0f480001a515d4f9923ae6278e8927237d05db23e984c92a683882f57b1f1882a74a193ab6912ff241b9ffa662a0d47f29205f084dbde845baaeb5dd36ae6439a437642fa763b57e8dbe84e55813f0151e97e5b9de768b234b8db15c496d4bfcfa1388788972bb50ce030bc6e0ccf4fa7d00d343782f6ba8de0
+SIG: dd0212e63288cbe14a4569b4d891da3c7f92727c5e7f9a801cf9d6827085e7095b669d7d45f882ca5f0745dccd24d87a57181320191e5b7a47c3f7f2dccbd707
+
+PRIV: 9e2c3d189838f4dd52ef0832886874c5ca493983ddadc07cbc570af2ee9d6209f68d3b81e73557ee1f08bd2d3f46a4718256a0f3cd8d2e03eb8fe882aab65c69
+PUB: f68d3b81e73557ee1f08bd2d3f46a4718256a0f3cd8d2e03eb8fe882aab65c69
+MESSAGE: 19485f5238ba82eadf5eff14ca75cd42e5d56fea69d5718cfb5b1d40d760899b450e66884558f3f25b7c3de9afc4738d7ac09da5dd4689bbfac07836f5e0be432b1ddcf1b1a075bc9815d0debc865d90bd5a0c5f5604d9b46ace816c57694ecc3d40d8f84df0ede2bc4d577775a027f725de0816f563fa88f88e077720ebb6ac02574604819824db7474d4d0b22cd1bc05768e0fb867ca1c1a7b90b34ab7a41afc66957266ac0c915934aaf31c0cf6927a4f03f23285e6f24afd5813849bb08c203ac2d0336dcbf80d77f6cf7120edfbcdf181db107ec8e00f32449c1d3f5c049a92694b4ea2c6ebe5e2b0f64b5ae50ad3374d246b3270057e724a27cf263b633ab65ecb7f5c266b8007618b10ac9ac83db0febc04fd863d9661ab6e58494766f71b9a867c5a7a4555f667c1af2e54588f162a41ce756407cc4161d607b6e0682980934caa1bef036f7330d9eef01ecc553583fee5994e533a46ca916f60f8b961ae01d20f7abf0df6141b604de733c636b42018cd5f1d1ef4f84cee40fc
+SIG: 38a31b6b465084738262a26c065fe5d9e2886bf9dd35cde05df9bad0cc7db401c750aa19e66090bce25a3c721201e60502c8c10454346648af065eab0ee7d80f
+
+PRIV: 31010d1d67eb616348e84792b92d5dc128553cb52f6368159fe7b816cd0e7c37266543d96787ca901fcff06e6e434491ae0970880a5a187d535edb19db5cabeb
+PUB: 266543d96787ca901fcff06e6e434491ae0970880a5a187d535edb19db5cabeb
+MESSAGE: 39f89a5e7aa530b5463d498f8035b9909d55da527cdbd4de6d228379f089e608a9207a2c5b9c42051a60c8ca3fb97a1c06cd747d9d0739970ceb88ce526f971140ea2ec21f090ba075bf8975faa508b1cc10efa494dc172e6d3d3f3f75dc8e0e96f05c0cccb2f96e911cfa7a2c82c9845018bb1f9d75f82e3dfe1139347b2ac058b014ac93760c90f5567ab5c4eba04b49fb09ddadd305be511dfe05c96ebc86fd67b5d0ab57d85f4fe5e2f0fa9d88a68f0f6b6bc8bb944eb3c0b17557e55d5ea187d922a42813e69057c9b6a7f75e49921b7079e58f8a63719ee3e1ad10cf0e8a70c4f1540218b70494bd029ee02ff9727a7d85d377919ec4051479b70f7cd6767723fe42c1c7899c2b7c1f702dd6b4d13b672d488f34a0e969db79cc2cb2524a948a8de4c5b623ecd90d6e82d97033c125637d1cd8c84803d8fbc012846ffe484f6c02149258f9462fa1e99c307dd0062fe0b6f11eee40c2629ef7c0f6a5107259ea5b9ffb6f29f12c32f7b5228cabc986ab66450af9dcc3da09d0e0b9a4
+SIG: 7b1eb677c3e5e6a8b4ba69fcb7f6b1870e42a8d58958a35c674e2db82107481c4c7b37f0f689d39d9f51e181b17b1108c15a3e27b29df3a4315dcc4faf122205
+
+PRIV: 8ff2398cd51f51d4c2c57869a2218b8486822031f400729f4ac4d5909c48bafea5a88704b68677be3d16c3dc0052cfee6e2b30e08609059d4cba52c6d96061fb
+PUB: a5a88704b68677be3d16c3dc0052cfee6e2b30e08609059d4cba52c6d96061fb
+MESSAGE: 993953e47a341188bc592942e1557af29546e4e9368e2f1a5ee9806e2baf66b6190191fc5d2b7e47de37ff054fb2bbb1f031684ada5d607adda3d65433122fa904e0456faa84109bbc517f8ad39660876382adcfed0f7620cf1164622eacd91eb37a8596462ebe9ebe26bdc1e32cc34ad46fb1cea420e73c31215408e6d35425f44a829b132f631a3f6dd4b873a000667e19eb22fffd5903aaa7d4c8fdf21953c3c6178f5f8cb2aa6bff92894ead835888df060a3c9043026e0e2cef275497e7d105df3b644a98f26bf00105c99413ee0af8851954d65ceb8d79ad3071b8bb87f0b19743d2556ffd9819830b6eebf7ecc7e045661f43570ce9fdbbe2d252406fa90d04236f222c429ec16b1287224ada1a532161ae8b481bcab8d47afb3ed0445b3060fd6759179856f4085c1e585fd7c1409799af693cf427bd1d3dc10b5ae3447a8d2a18dc3a12a6860b22175dd5eb53a0950432e2d7aefece8af0ade3d8567743de43690f2d253723c5d7e48bd30d2937593701cecde9154b7665cb611d7d
+SIG: 417a647829c92898e520ff5311daa0a139cd8fffcb25a18e6d9b50cb52cbc35424c39ebbb5d5ac6a6d63f1f53c4df212f7025a8aaef8e36493c874c3ce341a0e
+
+PRIV: ef816c8f5ec34ef41f68831d90cd29e52de8973782d003ee4edada2ada2691d647f9b363a88a45053a05bb72160852bfe8f7dfefc2f37283de346752caf092cc
+PUB: 47f9b363a88a45053a05bb72160852bfe8f7dfefc2f37283de346752caf092cc
+MESSAGE: 9593c35cdec535bebb6965da68eab0b646bffcfbd04883bc4cef90d5d01f018c63c9b0ddfb3cef5e786284d5218caaaf060e9288952f16301ed8a4c1bcee256356a0c8bda359fbaa2782b10c86d18e20f7a0ec99b27a0b4dbefc0a262a3bf68fe81444dcae5f693eb0f16e6ee03f8fcbf3a3398146d20ec4d2657761fd0320fee7ea703c49a6a543bc9bba911e7925038710e8c36552d476d6027f58b2c52ba51ad65ea4f039c78f96b889102bb4bdd69b68e9c3d45b5176a2d82b0b95dc321016370dae30c3936515db0464c41774301c74e42d89b8bf4b9c19ed554b12febac0f60ddb3219ccc5603531dbf2eb5f293425d72ccefa0c7f144aba89347b296be87ff18994b4a0c70c930f059303b5dd4c8fe1e6bbc3cd68c6c0d84246dc6e6140a2abd1780b13f1594a6019d1778b7cbb3a3e3a34bfae7297f0b3edc376941c32352a4be314b84a9d8d6d7f1f38a0ad3798020aa2a331a402be9c704484744a730cbdedcb904b6fde708fbd14bfdc29efd461d1d0b5825de0bc79422b69a2722f
+SIG: 65c5d10ea7bfdbb38d55364a9968f82b548224dff3363b2ddcf585163dea27dc63b0563eb1a8dfbee951d3c9b33fcd6bbf0921c3abb21786b229069bd9ca000a
+
+PRIV: 45eb0c4dfafa2a7690ef579c095456ceedcd32f0b6144d0c380f87fb744a0b1ffc85632c98384b5f9682aed9cd664cf1f48e588be2d568e5c734494df4c712b8
+PUB: fc85632c98384b5f9682aed9cd664cf1f48e588be2d568e5c734494df4c712b8
+MESSAGE: 6f66d847405a03d7bd6f8d2897dbdf04e76d7df2d9470a4996b7dd6db88500f8f4f83e960e219a2486e24545add13614550414d827c41a9b08318daf01b15214c64a4266cbf8a5717ada3e62c26729073e16ddbd66f2d520e1e09935de05e4db11c396d477010aec66aafb762e69238d0b9e76b452454bf9e451e76ac79e6990d41b932bc32917093783c91bc9cf0bbe3b514070a1e692ff34fd06b66ea11f39e10af933ee96d8e9b677cb03737e7964eeaa725f121207f9c1b26a96c616df7cb7caef47bda901368ff2ea586e422e65bf21a691bdd2c13e67fff58cfbfed81782049dafa0f727df88623f2f7e8f262daf939542a187b8720a9b6b2b09890e54876b28a43874abbe3bfa981f8138b772c5d51736885f86acac2215a0b010dfc2c6b150845d4f8296252586a3e115f303c3d8a582e20fd2d43f6c446e5d00280ec179823b7fb4c1b0feb94eb4ef1707f5184e3b52461a7562d1f307cb751cdbbf6eae49ffae91862358e74e9548822b8a049fec6bf4c7a99cabbe09206577b657e31f
+SIG: 55851de8e1092f78944f6c6dd95bf07e2dbc8df7f57ad576829b978e3af58a7a8e94ed4dccbc0182467edf0bad4bae7ca84aa9a0c17c61a9e0ddff1d7525d704
+
+PRIV: 709d2e199006f5369a7a0bdd34e74dc784be33880ea3c5dd10ed5c94451e797206f989202ba2cbc9c150be611262aca00c45f012f89fbaf89f8ceccba0b1934a
+PUB: 06f989202ba2cbc9c150be611262aca00c45f012f89fbaf89f8ceccba0b1934a
+MESSAGE: 62f003140fa09e0387d187a0ff96c4563df9f4e28c2282c0183ac3eede1312354921f780fca5361d3068d29949630b7530cd5914ace0468d014b6f53d839b82e38817dbf2d8392c3ce3424eab86a24d804c7acb1ce7acfe0a1cda4393924283105da4a7741196e027550047f85b7a0a01d454124efc0e299f0ef9ad14350543053482261528baa56e65999ac802c00a336267c635106b26403c19f391d53bd82861d6d48a4380b3043aa91d649536881204eccb0de20d43e5a3755b7f600916eccae42a0c9053b462d9417a13d67d778264a896e8eaf90baf66d29e5438a716781123a89fa9b8beef91d965af2f4a1a5bd5d2e2aaf46d5c94b7709cdd38d05feee4bfb76a359077c16bc4be9116e69001271cda565bc19bf47d4f986bd9c0d184cd8a3520ca1bdb4b505aaf7cb4ec9f94789779d30714e79116dd5019d59b28b17dad96f4e2155ad9c61274addc6b638109504e9ed19f4eda5377762648c4098224e3391043e4c2ad591654c9e7f974efdf0b0504b6fa5f646cecf44cd372412372505
+SIG: 629bf97b0c78ee6a9c8759fbea28224e27abbb6cbe4dea5bb797e6e0fe80c913f953e3a9b623352d13acf4ce6250fb029a1e198d72bd5e7402e60e9e48ca3501
+
+PRIV: 5151617421aadc9c95a442b45e7ff6de06a2c733b85bd789fbad414ee3c91add14941d559761b30ab0a86d47e0f7d1896b33784527c80af41cb84810cbff9dbf
+PUB: 14941d559761b30ab0a86d47e0f7d1896b33784527c80af41cb84810cbff9dbf
+MESSAGE: 216e9d40bcdc3b2650188d121c9f8ef29e914facd022fe01b90ed11225f2eb93538e5fcee5ab8045e9199aa76a16bdd0616805660e247fecd7e22821b69b1f8e8a58ac3fb85691d75d5957a1daf53ff9ee6476d7c4bc541e6ad38e3a34ea90fc52a48b9399f92d17c9bb0d7fc3104c55d0efb4ea5b831ff9490b3f79f4d9d699594b741566f2b50a8fc78cc403fa40f5abb6638a32f449a8b3ef029c402f46931ad2bd3e8e683108714c989ae21689e9c444b9f55b81119bb5035bcf73e97ce43a2218c7bc3e430d1e814f34dee057265d3194b9f43875d8381f525f78576e64ce692584faa30fb743a12d1b77614d2e10a6b856b52be27cdb630ba1f0d3a6f8ea9844542e584ea0a2777527d0c52aca949aacda45ad83d16d5c83d663adb79cad6f3e39e990fe282a14c353aa2379d7f06adab74cea021b8983a57f1d0cf703292eb05ece89c53f3a1265610e0c1ea8ddd444d1ffd6bc3d03f0a6e4d0df5c5b8dc1f95d9f5558b118afe6bea0f6c2931363f03ab34e757d49364174f658efbbf38dc177
+SIG: fae4773b334460c77bf01ec6366c4fe61c0cab57d8a4b03909c619e11ee3461c13fa21576f63870e423dd04181e4a7013a7524f246fe33853c674162a7815104
+
+PRIV: 38bed445556de74482bf5fec0506f9af330b151e50d4774dfe8591d7b7e0276b4c0f9c49a42f4047bfe6885551c5e4b856cf771a67af3f89dbf602f9db9220f3
+PUB: 4c0f9c49a42f4047bfe6885551c5e4b856cf771a67af3f89dbf602f9db9220f3
+MESSAGE: 0ff0031df0beeff3710c6b763f9b8ec81719bfa1528ce46519adf3d3412d93fb188fd497d5d17091c0f0345960dd0eb0c09fc4005173665d4d97f95c13828bc76b3492b87a4b64253c8b5fa47aa75fa3b86d5abeea8de5959a602289136f60a69b309e773b2255cde19ed2a2e199c33db11c16ade08a319750b851d92c692924fc9859be523431cbe78ec092db1129210ebbeaa7c2a2c000eeb105ca0301a48f3e45fdfb15b275cbab83ca5c99d737a585320e9e3b317179bd86467fa9694fcdb2ac6ad36ed7144843dbc34e423d35afd7d8972a1c43c199a191abd6ceba4936d395c995a3eb13cb057f88a9dc9490fe98845ee5d26a89fb642a2a516dc3056c54d3637213363a8628a42a395d942b954a89e8ef7a744d8ae5adac88c616efaa90e2077205a60baffede5c87bb14dead306229495f698f3e490616966b1636387d0d86183f945b24a9dcfccf4d36722cd12ebb6bd8e78325752afa2b1abd13c4bdbcadd170869136826242acfb721de5ff27ba8aa0c018b225ed3404803ce9fa2d508d8944
+SIG: f702d0d463282fc7fd5f8f9029b89c626cafd83450c3bb9dd8f6589f0c4b4b71f649ea212e5e33487c59c168ea3ad83150f1fcdfe8c53eba65adc2023c25830f
+
+PRIV: 055460b32dd04d7f4b2311a89807e073fd556565a4771857d882794130a2fe5d260f8fed4bba30b9e12ad8523fbb6f57f0a7a882550061f1da46fbd8ea442221
+PUB: 260f8fed4bba30b9e12ad8523fbb6f57f0a7a882550061f1da46fbd8ea442221
+MESSAGE: 7407f96ee3e79c69d36ce1f64e4f188655ea68b947e7e2be97b05ebc6d4439e950276ef3f0e6a03dd48b24f66929b49c1580eb468807e1e7a25eb9b94da340c53f984f8b81603efb61047bf3f14b686d9798003d2f68589a79ebfad54409c71c90ff67c11fbd76cc72c2d145f458e42f88b75d250eadcafe66bf37ffc837b62ff006685b7f85a9d875fc078c82e61fe35d1922527a551dab62f9e477499146bad912203e664c417c3679c02d872abac0032f8cc77f77bfe54d3326fdee9276a48ea4eb251350406882d08c830e7649fe6854558a7513ab2d8d2ac3e5ced8a808d2aee454779edabd1aa63bb19f718f470bdc8451cd9b294941e3497063b1e39b6ca184562fe838cbfeee922de24ddfcf9882c5e615b11bf904817fbd647139db80b4e8feb37f11e1852d7e876db9cb63c94d7ee34192f7200b5bc77a0311ae43b806ebd4c2896c53f58f7ebc1625cb20d7107ef9db0da28788523de991ef6c5866b18d8de83a954d3281e06dbf27c4f2382e08cd0e0f6ebae3f961b77fce5a95a9b0621b756f
+SIG: 23f4f1627fbabd7891d7d8489631c7231d22de71864e262ab4da84ea8a13a60feac4dcfb1812f1200444b775f121d7266d755ce9b6a9ad796559c0a26b516d02
+
+PRIV: e9f6d31b936942c526e0f9ec4f5a7ac25fa789e0c434bcd9199d720c743c84c432126d26e28231c5b585b13f43a01c6fe542946b07d3a91e57d281523f5cb45c
+PUB: 32126d26e28231c5b585b13f43a01c6fe542946b07d3a91e57d281523f5cb45c
+MESSAGE: e88133f3d17642d5c22779a85316ba0df34c792b4efee49ed7dd93ca3322ef47c72e5b2e4595c77800434b60719adf54e4c1a34c89fa1e27ee8d35a0921f9755ac4a77a6c1684ea0f5c8ee5f759ce59bfe8315800a67aa6c64ddfaac92eabe6c2c613779784b3affafcc620f2a6dc5cb8d8dc7d74aa4d79494678494e5e6394c433c14809ff40c9a592d0d694a81103b44531e1f48bc13965d15af8bf3340488f8cd58f09ae1a6616bf85ac9de7e0c6696aa2f1bec15e17a44da4a84edb4ec6d77247788ba0de3ae12a155cbedc0da2f568eef0b75a877ea5b0c2c0d4bf2c61d468a46faadfaece35fc263a9be9987f4f7f78f05c707784378c7b8f7daf9ac3a122aad39a1677966da9ef286c9e062c4f439ad0bddea26e54b2f7388e238b2a64928450d34564c5a447e7afbbedd1085f1f24c11ae084322d1a32cf8aa473941f00d56b1618213cab3900aa606463d9f800e926f9f42d4b082d8c5ec3a4a025b45f9aadc8bcbd17091b3da49e9453dc55e89b5b5fe6b31f5eddad10b6601572568d8e205d3251a
+SIG: 7e3b1c4c716c808e90b974458915f3b2239c42077119fe270788fae520578bd7da6488044132e1bef23e3b23c34d9c1862744f28fcaecda6cac0fd72b93b6a0f
+
+PRIV: 6bf4caaabb96854a38a572f4ce6c7838f7e750118c73f2723582618e2307f83808126373d056f00e54b8d43d77c35f5f919833e90d8aafd6c8246d27917ad091
+PUB: 08126373d056f00e54b8d43d77c35f5f919833e90d8aafd6c8246d27917ad091
+MESSAGE: 4776e9d60085481fa537bf295bdabd8b1cf632a8cd40bce6bd325c129f977000e88468ebf2dc158ac0f207212db00fb60b8ec8bae229372e9a6b01530a7ed1bc9d389ec8913f59030d5b54af56ae1ccc28f37cc96a8e53204e92a677766adfaada99b0281f867f61ac9ff7d972ee3ed427d72faae75d4aec01b5ffc37061b6f0f7e5714c4cf30d5b731b0746065f19e4c8922dde642f80fe24a3c8dcb2e5f1c266e2af6c37decf55a2baa54f0d5cf0839370c3e0b4e77a4f36bbb3162014933a4a4ebcae8c60961ac6dcf134f30828d31402ae74e7e8513c9d2ad8ee46b7a9d53a1f87ebfce04f461bded1749b6fc4c4f25793525692d7a0e426c84e06082cc3e6abb51368370cbb106c7a0897f66d92c9739cff9f2706d6a2980ecea3ac4945f0f47e656bd9637777e853d2a839104327dc049ebc34f049d6c2f80eca99db7b418424acef752260d2d427949323997cd9617edf50d441d0088b1d47912e35cf542315265829f383f45860d3b45e735bb2f8586dcf58db4f2acfb4a68853a96eed7b89769d365613
+SIG: d2113f80d6cf928486a250a679d6e74b35ea9d26061fa94d769e1a8fbfa0a734227f55537e4ebff59336db141cf5d6d482a0711f1e9fc72ff70956a11b4fb909
+
+PRIV: 5d9585736ab209b0abe8bf74aca4eea4f6d1650b532550a223e044580f8e20dee77729edfd2144b2b12078765417fa21f1594f09b269e9b6706802b4f3bdfe85
+PUB: e77729edfd2144b2b12078765417fa21f1594f09b269e9b6706802b4f3bdfe85
+MESSAGE: 08693591e6c58a5ead9c85fe8ec58508f81a3467636c2d34fcc1f466e5c6dafdc37c35cbee35589c6997e2b15448132744e5a1e131bb49bf5c2563f87ead3efe01e88cbf24cc1769c78cdfc167e378215b15859c7a28ece70e188fa330267d3fc57b4ace6c1520ec67875067fd33be86f4a1967afb3eb164c797cf28d8072aa69d82afa38374f8e5797c4c28471b7d69f5b9c7b4acdbc19f3c5c5d400808a982a47837aed1b3841d69890eeb31494e10e3e513d12d0ca686c7ce651778092703fef0dcc0214077dfb361251bdea4364dd41b97bceb0fb1475a50e4708f47f7878c74401e9771cc3fceace89169981aa77250850090d181d8358ebba65e290acb0352bece8c579832a601551816d1c05621ccbbee0fbe39ea2f195393199e69c234c2fb1c37e474840860ce609161fcfce2869574be0d38f95e20f4f8725247b9627b46e834905101ac12b934cbf87cb2d190d2f51490a82c4e810eddb81f956a9f36bda497bca506a49ee9cd47fda5b7f2b884a3648cadd12ab61898ada46ecc970f81dc9f876845db
+SIG: e7b08e1d5809fdd8529443d65ada5dd655ea55b5415a011393be7071676486d358e8d2a460ebe075b0e701b24c9e3ab5f2b033592d4de3b7f37fd541f6920909
+
+PRIV: 60b142f165114143ca30a604fef51c686436aa1b9afdb266b3e398ccb3c4d855eaf6c5a76ca99bf7306498888c3b7a1feae98bf8988d7f2e1547f8f53a4528aa
+PUB: eaf6c5a76ca99bf7306498888c3b7a1feae98bf8988d7f2e1547f8f53a4528aa
+MESSAGE: 1815dee1173b78264720d35b7cc2454a000a65fff214e2473e20bc83f3ecde9c04c1e0696ce6e55519dd2a75ce0464bf601adc381e793ecb9f8ce7ab87b6ca2a3e410f639069451978d14873d3390fab8623969713c3dfcd58d86d124073761ee09a652a48767f9646cb726ac454ac9a1bc5faed3026b703982bc2b1e0758210e1d62519230eb2b2f4a486bc55168560c4363df5ff5adfda11ac7ef51b18196c94337c07aef117990f770c0f1e8c0f88eb6ffc40e8ed7c3a80a632db1e7f63b63096e2ac49e57792b31143e2f4faabceae66b27471681c36fc1139007f9b548cdc6e3b8fbbdaba7a8adb843431238bb461ba24f6e09f62c72d6377b4048cb0134c25a5411a20bfcfc13e48d80e36bfb0da7e0185d33f1928636e15dee0e5df8992a16572b13ea8f7cf85cae32d529f66e8f6d2fb2ad0bbfe7199169b2567ba00c781b20a48e1d70df9fa3119cd7e5bbe58884b0b51218940fa815f85625fa203471cee8084780eb0b9356f9f3d4f6df740301d707ef1ffb3519e3f90b8064b98e70f375d071426881718
+SIG: a621f084ea1a36ef812a9755c9afbb53dadaae6b3a53fa8344ca40d3612a268a35fed0fd398ab75bcd639c547937c94155ab1a7a3467dd4bfddfacab1655e908
+
+PRIV: 734ba47033c6140232dd4a7a14f1a7743eefe9070bad9662491630cc9d28c1f32fa5df3026d60742e2aff6b57842c7126846c8a7bbe9266efa7b3f2398c357ea
+PUB: 2fa5df3026d60742e2aff6b57842c7126846c8a7bbe9266efa7b3f2398c357ea
+MESSAGE: 5d3c659810c3fea52a6df3861e5cdc5b703cc1cef48558c61d8c51d0edea5a1479cfe5063d82ded9ca681e5748887c40ecfb9e1a9a8b7f8509d10776461c3923399693a78189089178d5aabd15f8c846642be47d6d4caf13824edcefb809868fa72ddf035c4de8ef0a9c832264f66f012761ce6955bc3c416e93e29188025ebbb13a553258c1d7c499c9a4aeb10bb36f61d1bb4cec5ae55d175722b9a9696df881951e35200b9653cf6ed4b3d15de087a9d1c319fce8582156bebf3fc91e0e610ff7a15308fd1d2c6069fbbb2947d3110731d245ae2963014bd76dea42db125cecc493c8e9091a76646577729aed4966fce9699fe12e367d665df9e95a9193e1133e143af92f82b66ac7764e5033178690521809a7107d8ae9b88e0ed1f35b1719901b930ad0e1cbce7fb30267b1155204f605f525e49de2988ea7f74be8815177fd976a1bcc126d9c9c135c5b4276d38019c34aefb7a0220f7f5aeff380aed627b070c2c9e21533bb35c08e394c85ae25e6862942599c65dbae5977a584a88180e0c8c71e5a8409e04ef7
+SIG: 9bd074d1d0bd28001baf7d2d4e82435df08c4264d8cbb1c381183c2f01223f79f94923ca178cac75564e16c7f56079088f7ed885de4d509fbc78f438fba3f607
+
+PRIV: 45e34d0ef4c196fa6d572b6b1774b5218f7c3291304c13500df7070d90e8039e13a7304dff423359177abafa5e6508d26769ca99cf8af45c383f3ff634406003
+PUB: 13a7304dff423359177abafa5e6508d26769ca99cf8af45c383f3ff634406003
+MESSAGE: 3d9ed5c64b75e135df2f5e85300d90f21b363935e2817556fc9311751ba7535477dec8356ec385efb82b414062f35bb6d3edeafde305f9900a25e9813c9ee0237d46409650cdcdb5dfa2301a8e2647f8d3819d86f7b7e3070d33440f82c4054b1ab5edebeb27f95b3c4c6fdd468f21600f03b3494da200bab9293c38d02fc44048e52ff5fd0f7217a04d4ce912a180d1628f368280b6892672e8ff98d4629ac28b60c02a301e6c6026c1b9e9ef21cf0392df225008d5a0e0284b282631ad1710f811615697066c98296519948a7cfed5aeeb454ee7a61cc271bd3d499be17df09d3a0e790ee6b9bd99e1b919bed4a063b8d1a34f1afd2e952b9dfefd770969c8b2fc37977abb0fee6317253a23ecc97578168973334c8f91763ab97f29c49baeee7b35f3ae7f5cd3a4a6e697ef255a3c2ec0c752a3396f69f663ca1fc2b332dfe6c0faf78afe9c68d99571e8e896c5093085e9863a27648a9e58f3a9a84cbbfe2b41ca3633dd5cf6e82cb77cecacad8d78b353f48db42d99c36bcad170ea9e98abb2788c33a3c706268f3631
+SIG: b42c1f925f4baccd129efb109db354aca31c6898f4f451294749a26a6da1677bd3a5c04119e35f47319f20cfdfc08bb4528b21009e00bd41ebc0f46863bed10b
+
+PRIV: 888ce2ecceda9ca2b948ac1443c2aedd7595aacf36edaf27255bde7a6991dcc0016e572b4f98417c6ee297abd784ea48226ff4fbf0050a5ade8806e7046d3ba3
+PUB: 016e572b4f98417c6ee297abd784ea48226ff4fbf0050a5ade8806e7046d3ba3
+MESSAGE: 5c801a8e664e7660760a25a5e1431a62159fc3f3aa713780ae7cbce23b8564782799bf2be4817ee2921965bab7e1d44833824c1628d42dcee3e46ae42b2816d0a432a1ab0bd21fcf30adb63d8dd76569544343d0035c760522ca68bea72c404edda1e9095ec90f3325681c6de0f4c12d1afbcba2c7871a1b1e1f19c35b0bed9ec2a87c043d36d819396bd5d099e1aa090391297c733f65a8c5d2120c67635316fab25b4d4847a45fc3f76f2e2426dbee4629975062fce14e2189dba27fb1ded2453f001debfaa899c11660612d2ce2ad2f762ea5dee7e71e58adcdcefa79e8e8b27fc4ccf89aabf176b5d34f82dd15d889f9f087dc9ae8a42a72f3b83583616e170637cd1adf38aa6551cbacca3602bdc7ae210c4a446b3af8db2720e549bbedb8bed215ae00f19da29d8fb0b642d27b2d88575f0ee84f3d129eb774d20f537a1c0fdcf717bdebcfe47f8331a341864346fa6a1c6bbfd178819e387a0d5499a68e81cc9f82ad39e31e4dfe71952d5ea5cc8052a3ceed1751f59dc7ecc9742fad144e18dda8d0582e74e39ca8c4
+SIG: 99d83f148a236ebbef1cad88cb3c7694f4986c9250e21c3603a0d941bff199cf77d6ce99efdb20533188d68ad133de033a1fb3468abb706d2b8b4fbac08dfe03
+
+PRIV: 617390857dc10cdf82b5c94261f58ce2d44aa2f57d298f08a2d6c74d28147daf89e0c3e0a0f130d1916e0e3849b7286fa2e3ac4c17bd1f716ee5a72f0257fb8d
+PUB: 89e0c3e0a0f130d1916e0e3849b7286fa2e3ac4c17bd1f716ee5a72f0257fb8d
+MESSAGE: 1fd9e7453eaffd7c9b54055622dde170dd58b71cb945de75351d5fceb1f536bde25158f03786155f953dc207a1708f90d95b15aca0aee3097fdcaae85e4ab1c2cdb705c53e6c2ed21a994b304a75caf2ce4fc7d61f561e74e297397e2cde5cc69056940343aa81375d0af18d17d2f34c0a71dcf1de3c4fc488a14c5fa6b3337a3174b1da7958fb00bd5955148221427c60dba04117c80d2488656dbd5343de891287b50ef4df9825eda76b4977f3acd4ab6d3102fa56878306cd76561491bcfdaa1da567e677f7f03bae5dbf4426c3c4a6c3d082f9178b2efdd2bd49eee97ef4dcf3f0f51bbdeffe5ae6601e28019518f827f02e51f6679b8715978bec3e69d577156dd719959371baf034219fbbd17a2369a8541490f6a02013e33e74f4769be37aefa4defb6bfb3f351c2a261482c2fbec49f85f8445456e8f5a474030cd72d095ef6a622030e1e43a0c5debb034731d2f5e8e4ba3990f077d0c162649d1fa3ea4fe1e81d74aa849e21b059d966cbad4c493ca10bafe7a69243e3c0a6ebfd13d697906303392ba65d4fe06b6a5
+SIG: 63e90a6afbbbb0ee696bfb56efd679d68a9851a8947640a97f41f68edfeadd216ed8698e2e43c820c9044caa7adaab5b76762b681831a9f760476a8443c43c06
+
+PRIV: 877d017436369ec2453fed46e977d6acc3a7be60d31395ad6e7ea9e07480e4c94e65422fed334a55e8b673893eba7c181dd724dda002817b0bae28acdc3f7fc0
+PUB: 4e65422fed334a55e8b673893eba7c181dd724dda002817b0bae28acdc3f7fc0
+MESSAGE: 4ed3f5bdbd41d0e3b0a8a7fc3752eea496d6141678cbfe06757f61e1a168d761b6da83052f7994950d24626f004fbe9b8c9562e0c955fb3b5c08fd2d3d258393a349030c8e156205b40483038be1959f1cba490a87fe13899e4f3752063b68fe3e1c5071f7db0002f01494b4a3ee2e07992bdd200db4316629ee8a95ca347f0b28d6402a6da8b53e6b32581c3691e11ae9b6e0f0494894e649a92d03eb49c4d6833fa1f54f8dcd91d06936a6e62d491e2cea46dd07d9f02d3254b850bc9749f258a61ad3b9cc24b03287331b85a24143aaf8fcccac5f18bfc72dec75c0233516aa6e4589c78c665a186ed902091df97b0d04e83a2d74d789891aea2cacf813fffb5efaf78dbcd7af54ef55c77b1c4c8ace9e9278adc23d76c779d64b3bbbd1fb33b09836ea64a71e4711e89e8da0f709213342176ae22c6e7852c3973b60d9f98889b442aa48d7bfdfdef64c36c586c4fb2ad2e27ebe479f6d722f069fd6106b0d08975d5f721547c3b9c52f9fc5f45bb45b5b632188e80626518a79056bdc4ee1d2be6c6542a21fadea92c6dfb776
+SIG: 7688f3f2401eacaf2dd88e170ff1c4d7e94822a77f6b550b569e82152bbbb434057e01230b05ce58ee1dee5226b5c7cdbe5a8ade3b9465f59aed74145d14330c
+
+PRIV: 4f0b3607d70b0f2698327ef4f1982c5b4b94be78f50c76f43bd642f1f0ede39b942b43089fd031cec0f99e5e550d65307fb6c3e793449fb390ff730fffd7c74b
+PUB: 942b43089fd031cec0f99e5e550d65307fb6c3e793449fb390ff730fffd7c74b
+MESSAGE: 9f700a1d2560f69d9bc105bc83bff539e4258c0248602013a959b978a19cc273280d90c0178089578b50518e06ad1eab790ffe710c63d78887a95569144f3e58a8837f93dd516fcddd22bc97a7f14411d424b2e8e9aa7c280119ad94ce92533fc7fea6c66248644ac3e1beef2553a6f61e91b9379b0fe0c68b40681455b311f40df0c97f53fc954242c375e7708d61bad9f51296247274fa01a7328fa5009d9995f501ae8683552b11a49d2638116723b1319450a90138d278cd9512b80ca5792ed16c683bef92ec87884c9f07f137dc47a13146e511065c2e1b4b80efde88ae12e29431beb7aee365c16d80506b99afa6a1406edb061766875832dba473e519dd7018f402eb1bb3014b7cee4f02e980b1b17127e7d25dfe0c168c5344f1c90044f827707dca03070e4c43cc460047ff62870f075f34591816e4d07ee302e7b2c2ca9255a35e8adec03530e86a13b1bdfa1498813098f9ba59f8187abcafe21ba09d7c4aaa1ad10a2f28334ab53996147c2459c01b6a10839e0301123d91a35ced7af89afbac7d9cf8ac9a38ceebef83
+SIG: f396a11f2f03c61439684f79001bd4f346a348dcf1d3beb2d3bfe33ea73a5ad4eb97506acfbffb784e77548189cd599f8ccf17355dde80e75024ef2a78d5fa03
+
+PRIV: b8a0010c784d8d002a31da11d022d30188a4197a1d5f14ea4c0dab29a2e406688bdc63e50bede13c91a41e4b4b7857b9e553f484e3c1ec167dc04c281ea86622
+PUB: 8bdc63e50bede13c91a41e4b4b7857b9e553f484e3c1ec167dc04c281ea86622
+MESSAGE: 5c6ccb298be216808b811e56d972f456b69ad39594eee354701ca6b3e38d1f41a359e5512af98a3a0873265fe5191f4f2ecaf66bee75a3ac0b71a4ddf2a759ebdddbd88a6a1c6fd0fcf7d7cb92a84e3307b4a4f98c710abf4f553dee74f652d2ac64bc30f72bf4354ef7e806a19071a051bcfcfb27e37fddd41eceaec1758e94695c670ef4c5a5902178329db9585c65ef0fa3cd62449bb20b1f13aecfdd1c6cf78c51f568ce9fb85259aad05b38c6b485f6b86076928ddb4e2036f45e7b9c6a7ff24ae1776030e2576825019ab463ebf7103a33072033eacbb5b503f53266afb82f9b2454b8dc057d84f30d9d2cb7c3a31a7dbdfba5b8e49231c231396c47ca042c8e48a1a5e3ec9afe4020595390f9990dfb874e0825ae9ae5e752af63af6fd3e787e75e8d8dc4c66302277ac01b30a18a56cb82c8a7ebdc915b7153255a1fedc492e49660262bb249780d173e1fd20d18c4f6b0b69aa2eca024bf3c80d7d5962cc4a129a7943b27f33cc799a36045541275a2cdb92a40e485ba8b737a04b43d29c3e25f76cb3d93a6b94461f88f5696
+SIG: b3f6cf4c0e0f9074ff2c2c47e163202f1e9d6ee117cf757633e4abe74423aa70008ada1509ec1dc117c1c230e9b23786f3d0f29b73aa284536e9580106a8a70c
+
+PRIV: efc86cbe40363abfbb2a4b1fcce5fd6084da96e7e814de71aadf9a618f30362522f295cee727d28d2b9317153e7d9412da1065c1b16ae2a251dd1fb431c62b01
+PUB: 22f295cee727d28d2b9317153e7d9412da1065c1b16ae2a251dd1fb431c62b01
+MESSAGE: 9e4fa45dc026710f6bef4ed0f07c544b0bb0d88fa79e7177d8448bc209d71cfe9743c10af0c9937d72e1819e5b531d661c58c63141ce8662c8839e664db79e16c54d113abb02a75bdf11b3453d071825bc415741e99483546b8e1e6819de53017092e4ef871f1ca0d3508f937828a4667db11ffff9416eebb94bf9b84d654603094834a99ca70b90f562a86823624dfe9cb2f9e88c173f13464d4ce255f222db50dd63ab42465734e75295c064b64cc3f15e6237e37f33d615f7c243e4ba308960cfd4393402525500bb7902970b3931d48b35666a2d4d2ab08fa12af366a004346c9dd93d39fb1b7340f104e51fedbb533605b5ff39cf6d59513f12856dcfa198d793b0fc875cdea0741f1455746d8a19c3e9d928f0021b01c25131811e48c3c75c6f41422a8810c6c81f35b454eeae8cd17cf3f2e6f0bcd9f290984f496578623ab8e2738d2d10840eb91d101cb4a23722b72e3dd185440c3b9f44d46a393a34c187a20d610bb698c50531741efe96323512329800772a408065a7ef8e4e4105eb1f5bf6d3fd6b217fd836d89f53b96f45
+SIG: f8818310228ca76111524ce94bfcb0246ea63508cee9306592b2f77548edefcf76bd1454508ea715042cec169cea5115ab54235cb1097b10702aa38378028e0c
+
+PRIV: 33556c60de2f2c9a9303b99add378592060505f8e49861085a4b15f072a7ef28231ec8cd845859f69961275119dbe4f715e5ec5aa98bb8741675b3c2d0c89fee
+PUB: 231ec8cd845859f69961275119dbe4f715e5ec5aa98bb8741675b3c2d0c89fee
+MESSAGE: 96af540ea2b1923f5fd0aad321ac032070c2d65ba13d164e75c3469758fcf31bb31655cb3a721f9cb34be2c90c77eb65be37f606d32a917a4cb9a709ac0705229930ef6eb6fdb0fa3c0fd3a90ce171674ee3ed06354bafc3c7075467a57445b80385640447902be39262894b1f64fea58287dc322d19875972a7c8be91d31f021c70eb682fdf11a10f8f582a126e064794838c69fdf64f5b6e8ba59d48b4384f8e9fb5c087cc7738295cd32344ba3b697ee6b6a8b78ee7a9575c97972a4d1bb18486f9037a0f3c6f471a90f86498dbc0df5232c07e8c01b690bee75302992a7a36fb4437c25a8bf5e34cf7d5b55572c700a079848d381364f9946a91eb1603ff3de5ebdd523bd92564818e237a53e8f522deaa2c29b897e961586e100ed0fc0ad70d160934e694027e5c957920bc0546e901be39a84535597e1f280c222267abe97f41205d8171820dd2faafc0699419321a9160f69b99fd41180945b62d2dd105cc7bbe821d28605e098edfa8b2309aeb0534e756377f59937c67463fd87c8b92ab58119cf4ce6c665af572fbae1de4a2cc71
+SIG: e06a7a414457bbbef2bac3775ccad087dacb1fa4bf938894e8c929118e09e678dd19938bc88f43ed0f7d31cc6a0e602c4e4d1fee33d41e74a119fa2d1e4e340f
+
+PRIV: 7a5c74314e1183334a4b6226b9a82d70fc2a124e3f87db6a2283ee05b68e34e0beae7d3dd97c67f6273bfaa066131fed8ace7f535fe6464e65791c7e5398576c
+PUB: beae7d3dd97c67f6273bfaa066131fed8ace7f535fe6464e65791c7e5398576c
+MESSAGE: 98bac6724755912992adc2a48b5442376f2d927997a040fb98efe544eb0c8e1866b9616e298d3360316ed976bd946a411fdd3a6b625c0c1a37af0f41cf6569a7884ab8467491a987df3ea7a0b7ebc4692569a34ce3a2ea3503495b2c02d49d7d7db579d13a82cf0cf7a9547a6eaebe68e7267d45a60b8d4772455228cca4036e282e1a1216f34cef7ea68f938270bdb04293c885d005f9f7e638a8b4ead2626c0945174ff2a3e2d6e15a4c0338c09e1260f0928ca9d3499824f3fedc4785da49c5c34a56855e241facc6347a399ddcac4399a8b158198c151461a3b189e58ec1f7efcf2ab2031fb17b6f035ba1f092e9eee2e92c2d6cc2032287f854b41e70fc61c8d11a2e4f0708f02eebd02e8c7e8c7b38a57bfa1a745f3a86c23909f6f89ab16ce7e1813c1d20147f31b4cf2ad0b606fb17e5ac1ab51ef4a7d8093cee9a655f471dc5b146bd1b93e540a3d3d3e2de8105911c10d6ab5ff79c2d06027f7a54561f2071414bd330a8785442251c810e232f83c367f0be7799a93f5238f7f17b5be829fd89123c04833af8b77e5a4363047ceca7
+SIG: c2ab1f6f5114a84f218502582c567b37a8bdbcdf6340fa4622873be89106f0a90b4829505f72129df0ab3d8513268774a34df3ad21ce254b464488addd6c9b04
+
+PRIV: da8006adc492ca5dc86c2959437a75deb6120ff787d2ecb9c20c30b52c26bc41ff113bf0aa58d546f2385d444ecb7888f8caba43a174a89fd6065f2b7dc17bf0
+PUB: ff113bf0aa58d546f2385d444ecb7888f8caba43a174a89fd6065f2b7dc17bf0
+MESSAGE: 3eb4324dbc0149d2e7d6df632bb0cbe9a9f6dfa83e227fc07bde1b577b3611fb921c9f8313f068e6295d4913a8196be530f6a01f57c09c028491444b784720e909ea1fb69c1c1dd6304400327b7731b33cc46deb046cdab6ad1b53f1749a0c65cb9a7e376ffa02230f536584aea243c639103adbba764321649d7e0126f82e0b4fd9dcb86c731cbcc517f2016841e916bcd5fde871dc098cd913dc546284d1b2165c63e88f32a2789a500856371b50d22fb8c87d1a3caedcdfd01ee5f870a53c284181d632ec66d48b6bdd5646ac39c9e75338a520212062bc3466ef5c58765570b905f63a93d07f8f1baac3526b016da799f3e9e03a4f7f81355e0f7a76f30a42b807322051b71c626a7a296d75b9d9d1a23bcb13c9ef48a912dc057325d3bcfb3f9fadaf0c249b102aeb854aa3631e34f69ad90c2ab2ed33bacc40b9ed1037fae67cdf799d5a9b43785961127d62f8e0bc1589fd1a06fca2aea7cfc012cbf7b5b207ddc4e677d8ae4aec100045ce36c00b74d1d28250791236dc5dcc1ed313c8c246172666f75217437c6034acd64198cd96df2a
+SIG: 1f5375dcb3ad2baaff956d8554ecb424176be9a6eb9ea54e814e0a73df2a5d848ada26ba8e1805cd51c5e16950c1ff7d4d2764daa6f4c7502fb865cbe55aaf0b
+
+PRIV: a284e26b97e538839c808d45bde6f012a354454aef81caa8c55914624f2b7d665ae46e34695efaf463a4208fc4e35b81f2c63593238a56f2444b850f058c3c5c
+PUB: 5ae46e34695efaf463a4208fc4e35b81f2c63593238a56f2444b850f058c3c5c
+MESSAGE: 9ebfe910b50a5cb719d95b961e5905f00ec7943b55468ab5956692017645b366071f8fbb77eb49ec73ea7d64511405b90de22db98c3eae39c4039c7a133430e8010bdd39a00fd1a528b113dae149cfad3ae340da27dcc507782ecd8929237517afe7463eca2473c7acf6f7aa04efc9f266ae7b6d63bb8cc2a438b344827f0713d1f1736f0cbb65b99353f20355fa0230d4fa707328a8662654e83ad0530a10f9a69e17c099e1e2b5db18e5f6f1dceda5883e8cab79701a5e9089562ed153ad08c674f097c28e4d16633e092969a8f0bdac54527c0ee03bc200e5be612e3d1eabd87091101b4962afa07b310806992f373076d76a58185118137c9d26ee2cd4c618c18283dd19f0e7a089ee37305b6b9518a78d8098436ef62be7d699808acecf67939d61b3e02937cd8c5f1e746d4274334bc9c37fdcba234c166fd712893f3a040832ec5425e57d80f11ef9ca5fbcd6c147fbbf5e2fae746e0ddb605867e3bd050483c3cd1329abe57a60bf88898dc7e80ede0f4517de8fc807e888b621a00f663084ff94b99996628f3b11690a60f0918cb5c9a7ef
+SIG: bf110e2e9cecbc31fa3e0c2438cd1f4321f92cd287005a48528addf76cad8d88bb22719ef91b139562a1511838682674faa9ff7e7ade6c9d573f845036d18905
+
+PRIV: cc97a96301ceed0f922731b685bad8ad4f06207be340f5a44fd187f29903ec20eb563a7bce12db97f1891d0f610bebd55101a3125ca8dbb50b25a6b5050d3784
+PUB: eb563a7bce12db97f1891d0f610bebd55101a3125ca8dbb50b25a6b5050d3784
+MESSAGE: b9ea3b3df7187ea415a3c335e0834e10f440915b2ad41c71f255d6950a4e9120e4d494fd9e672ce53206fdc417d865897b47ac1054e1ca1068195232d4297435e44e1224e66a912d9d7d182946ff5a9f085bb8ba19c54d16b586a9b30461b6773b93950311e1619886f5a5b3f111aaad094bae31c48f1941080968bd0277bb6fa92eebf324b192df5cc969516c78c7b2d12159b4d1c8eb03160c4cd1907f62ed4b854c569ecc481c08e636f44ed7c390e58b5937d2906b2817bc3769dad9da1b0f79391b55942063055da0d6f249a3e452baddaa032998d7f73398ccd0151bfc92c5e2fdfa9b14855e6b0d3746dce248e219672987252ec747df2747fd3fbd8b714c882d707ee302a904950c34754f85350e1aa3f8ea6293cf01f717cefb6b83a22126df5c4f5698aafd06a2244ad7d01f34017ca0ece6f21040048aba6ca4aeb04325b9402bcd43ab130a105788ac3d7b7da01ea9426dd0ea1933a8189933a6c0c6cd648ea316a7469a5fdc6e7c934d9186586097b55dd51ac487bb80ed11d4df8d33626bbce95e4f13bd49922f00c920223f4cbf93cb
+SIG: ffbdd3244181cdf6034f4a450fdd95dee4971a933f8be022bb0a4106aef39af3055b721881c9b54d1e99b9409096fbe6dc2c9966e3679964bd7ef4c808cabf01
+
+PRIV: 679e3e34773abe4ae25cae7d07ccd0eb3b0ec0a35d570257d62570de58ea251618acffce253b27259579ed9924f479cae312167bcd876edba88b5d1d73c43dbe
+PUB: 18acffce253b27259579ed9924f479cae312167bcd876edba88b5d1d73c43dbe
+MESSAGE: fb2b648ebb16688244f78b2ee9a273599d56b6198900d438a9e99c191425c72bec4f235847e18e47f57c3cb396655f778921f908580e8e83c96c108b20dd416678021bca259b98518fabb2d3532e4851d9d52add2542c0cb3efa3857a17e512438bc0ec4762e2f9baba429c03e99bec4038e6b0ca42bff5b233b24c333b4caead2de374a87b2ab5d80d6e49e4456329d51ae973bc83d7862f3d315e514481b12854a9dfc09e7d14f0d022c0ba3022578eba8f874deba4aa8c833f2b132861d4d51e50fe9aa4b787bd2f051aac50c375390cbbcfba2002b80ad00cdc12980f8ba8bcb7064afc04d5c4682c1029b10a6d45fe6ecd704245faf598c4659597c5d68a192cc1cd4fa45e84b549e8e5e67daa879ae5a520a6b5550519876a562ac49c6db0aa76ec69bb64dd6b5e1a3af2e131e722e7cdd05be34b5fcc6259aa124ccf814cf5b500d176be28ebc40bb21f03e24ccc131e0f41daa1ca02e6b00c9c53fad1248614e940d4b237760ab7569a767b7515dd2d623e57a2841b7d2441cf43049e4698d2f9c9eae7b2910f6ad65edf9cb2bdbd9b29f606e0d
+SIG: 1a51022628ccbb88eae9b21773c3f830b7b6e5bc36c9903ce70fbcf459d6a1ed8a1dceff5b19269ebf5a6fd3d8958860f554461f0e9fc0e29af9b1fb1744a80b
+
+PRIV: 9bfa60923a43ed0c24e2f12f5b86a0716329f93d4d8d3e06238002893278c19afb1c00687781b55b893d6b2f4f49cf5f73d2903c316d1eee75991d983a1868c0
+PUB: fb1c00687781b55b893d6b2f4f49cf5f73d2903c316d1eee75991d983a1868c0
+MESSAGE: a99028b0f4a3aa5e79abef6c0df4a783ef470f1a29ba51eba00f6214e840fe19e5b6dc6021ab599bb2ee3699576015d79a7939af823535b630e3938c723f6e0b9229d46bb3379acdba587c238567e3d89bc3bd3519b727fc694fff1118bf22c8bc8bc82c4df7f5ad38de05fe9f762999ecaa795f3ae630a9a316d26dce9f1568ffa3f22b0295214020b3d3f5337c149568192218132a90709279c01d23baefa669e1c4e42038173f1319c212da144f1c4ea4c52c005cbc0b5bc283e74483a0dca69279deb17ae5b29cfafa7d0063f4e1bc93537efd937e58a8aca737228f937ff2a741890e96c5725da11b45c413a9bbb4180a419987bbf046bfd346295d62f081c76daf2b0e1eb4f6712feebe6f0a92e358e7ddb85896507c340a01f68d1b0f085778b7c44b014aa6673e501796959a17a688db0959058488a7112572f23cf9cdb53b5eb4b45f5953ba0c0c690f86bd75e89a047bebaf847c1dfc345a4f3c7d3beec98b84b0219003e819f5c2adb45f8717903d1f5bd5d71914c56fcabc7a290f9c41699c95584d6a3a16340cb17baa1fc5e5467af7ac3221
+SIG: 55f202efb2a57be8b4e4fd894dcc11a4fc5f8276618ef5cd34a4495adb016a298e6480a35cfc53edb25ff1499fc532a33061cc01a250458aa5e4f7f16f51440d
+
+PRIV: 6e3af45e66e22890c3f3c934f523a4d69427976e6e52625f8bad558993963219e097364e76ff9f2e1d167f6b20c1bc5830085e7ec993c138f8b1b2175637e741
+PUB: e097364e76ff9f2e1d167f6b20c1bc5830085e7ec993c138f8b1b2175637e741
+MESSAGE: 5cfc2f4b559f8205b39102087617f4d86c7ce6cb251e5f89601dfc88ed28e8d7a670ec0087d2ea5d893021c7044da2899a22d776fe90170e51c203250690d37a294555e74af9234cbf1ad8f22cee8974828a0d09e9554b71ee3bcf880ab98325f706272194eb2e80c701d441b5f8668561b88849f827af703ab0954105fd3c54b3f6ec5493596d0e3bc67818048310c4a3e0c556bc80675f201f9bb9c6538a41d99aa40c886fc431467218d819c23e78498aed0613fa6f973e2211df9fb87f44116f3fe4c26d6cb2fa334c87f78c08ca8c9b9041d83a1230677e0af788598a42e44cfdf6964a4ee80e38402ba67c73a581e552baa2282425cb2ca17ca92edfbf98299102fba761b9b71a5452141bb9c18dd95febc2a782de9ceec08bd2ee3f7f0c1bd8946dba99cf9ea086abafd37c9ca60213f0de17c61ff9c391c9818ed5cd8571778b7dcc13224962386fb8ca14f861e99f3b18edac8a5f130f7bfcd45d045d0ff34c81572a512363d6530f93813e5fb10e9cb8338a7f93800491006f4463e89f0ed4530e5f12df674f598904780ad0812b1e3521fcd0f83e
+SIG: 26ba562e8a4065708207c25e239b780aee38794cf983a37acbb9d557a65ceed3c0da47d17f3e8b8f4eeb1b65a2c182ea6f29623b63bb0f1c72592683b126b901
+
+PRIV: 5f1f271844d9ed5a6a6f209a21408daea470f6fd53ba6479d7407105b7de4d656085d7fb5a9b2ed806c1fd30a2afde760961f7a36b48f4875246e615a2bd9928
+PUB: 6085d7fb5a9b2ed806c1fd30a2afde760961f7a36b48f4875246e615a2bd9928
+MESSAGE: eed6b4475dc263bd2207fe9d41d48282b713f680f2e037384f18b4bf224347f5e4c4b060b808d412eaabcf733dc39a40c6bda0505ce71fa823bd1b1794847678dc034e7999c16369340bc60c64d09bb9187b2e326055a053f8e505ea4196861471622db0e46f0f8954d8a1f07332da4d8ac55712626009912f8a15a9cd63a74a03c92f246cb63cc73f92e51dad1bc9715b1ed3fe5f2e1b2959b9b71e0e37360eb29536cf797147fab10864d6146c36b82335a0ce931408479c7ede484ff73e2dbfffc6c9227e16d7a23f4d90f15584514c39594e17bfbb295de9d62adadb589dbbe0b06dc8dac5b3bf517b24c1837b39472a6dd38931ffbbff5b763638805b4e22321f7afe92cdf502fb63d109ddcd9e4051ad6f45598532be179523710851d3931e887d02c345c79c489fc106a4ae162f7df71ab90b751da7038a6df7616cfc11887e21068fb9e33be566402be504f3fc2742b881509bd4fe6a0fc722649883f8cb655598a15a1d4c229dd86b5caeb711a028defd431154bba46b48172a4d8cbd45bc90aaf874b6085fa284f5fed655ad6fa17d67b3b9a796fa3e
+SIG: 319bb4deb2178112241b3fb8f46e105c3b8e4ef721eb200d762ef363e2716f2a89f80b5b9e89970890a09892ad6a58808b477e943b3cfa77774a3645bc745f03
+
+PRIV: 048ac9ec3ecb30a3b1bfda9b3b79a48c0793b490879e3c8a5e23ee2babcd9b7c946c186feafc3580a58ddd526ff229c04720250f4cf6bde0271eef9b12b1c3f3
+PUB: 946c186feafc3580a58ddd526ff229c04720250f4cf6bde0271eef9b12b1c3f3
+MESSAGE: d68be8ef7b4c7a4289f2b18b16ade97f4e4fa16452976afb581693380cc54de38a07587f32e2d4549f26595fee2393bd062e9b00bae72498e4148c8b882a8840e15b585c82b5c0defb233518409916615deb3a55a5f84e6b3aab93844de3b1e4d86e09f889ac71c324eb12d0fbd861cc31229540e843a34f8d5be47c0ec0d23df43e06813fca309439904c167d1043c0dcd444b004be1ff27b7862b00eba9433b94b0fcdc67521da0c1d5358636c78f530431164dde20a1cf164f51e29b8e63eacdecc869b41392c667664d91680d9ac516af548f09e60564e814e36e0b563dbae55c627ffc14158a56d8eb3609e174381b21de4ba82344466dd577f4d1103c43c27fb83cb833d87afdf7412b4090909b1dde264daddce967f496bf6f17112bf351e417db5953b13b8f0fcccbf30f5bcf376861c12ef20eec89ed23cf384ee78dc6eb40fd5811a7b23927c13e7dc5da3a921b883a9b2b1155970fb0da7d2993dcdfd4343642a9d5a6347e43c193b5793e4453ac1537aa3d04dc9f774e840934881d78a39ba250438c507250eed2f6e07cc953f783d6b72b1cc619981
+SIG: 2ecf5b8a59a8e27d25890a2aa32f4a0673275d539b174afa7b2cebf2e76280dffc338ede85ac8f614039560e2806d9e1e3cf9cce2ceb7874ffe1a7e80cdef40b
+
+PRIV: 2f057d20b1678531611f48f003b7d22eba5dbbd7e2dd41b7c79d09071f85e993620fc4eaa34d787df675ccbf7e893204828db92ead17a1165ac7fa1ab42719d8
+PUB: 620fc4eaa34d787df675ccbf7e893204828db92ead17a1165ac7fa1ab42719d8
+MESSAGE: 6e35f6eaa2bfee06ea6f2b2f7ab15fa97c5180958af2e90af918adfb3db8323f447c7bf26dc534997c38b7fc977f642de288cdf253071cacf3564e3b8ed6dce57ddfba9ff783bad2e76df124828fc1031acfadf01a44d41b42161ad9060301c1af1928b9e5b73b9bd21cac60a842b504dc3cc311c522e3bb048bf221444f53ceb08e77e948590e94ed98f1b604cb9eadc93bbe7431c1149b23193ff93e8569f113e1684d8976ecae6f09e0103614be418a472ef55bb8890d72b341cdd7505b50a45522ab63ed791ce8f82feddd7a620a4f6fb1d2fb0ed0c4560d78446d83b3d1b1bb56b366d196020d0624b1fbdb75ce735dd43e8e8df163c44e236993dca341f5132d825d0a4e393a19d38f61e11e0cf392cb9b646ea23c58099824dd8d9fbe26a49e33b23df80607abf19715799c19acc722ed9bcf94a0c29ad24b78b0b035b3241c64cd86edeac810e66745694b5eb1625060edf2d949de0d34f522df2dc60ae694a193f3b82c1d6f83a0cbb840f46c49a3d7d1cf06deaf96c64f8f9e17bd9ad512ae6309c486d9e2a78dceeca473a0421dd1b643c78754271b53ce
+SIG: 30df7b0b1c04fb1efa3517e928d6d57c2ca0d07f4e04ffb1f08b4792c5937dd271ccabdc00dce850afe50af5990f224e8420a681d95f9f7f515afec102efd10e
+
+PRIV: 3a3d27970fe2acb6951edd5ca90dda0fc6dd229c0a56df6eb11a9c54d242dbbf564f0dc3dc4720e68e44dd16711e049e6112000098fa62a1b98c288042f7c3bd
+PUB: 564f0dc3dc4720e68e44dd16711e049e6112000098fa62a1b98c288042f7c3bd
+MESSAGE: 4374f61c2cd88a3b8972249bfa79b36ab69e3ed484cc60e5d9541fa7686cf4eed1210c5d0dcf42dd25972501909193ca76ae6eb7f471d8bd0d5fb5a6b431bc3de0e0318d50514524de87c4b83005dfb41245fb1af79b84a97b83d3cac7ad7a53364e2e9b21c97b769bdc57f0703116168380f3cc883689eb4a7fa3b26dbe12bc28f8c40381af64df4b5361d174cf75acbd46428740b0d1322d32bbe94845215966ae588777a8c05336e352306d49278d328e496db65e9ecf6ce6405ed1c893490bc48c13a134e1fb6e80debe6d32fce6ef74783c8d77980a441a26aeb4fd83cc855352cedc188f5279ce211f744a40b23ce7ff24437a1dd3373ec5b290da1f94f43a07a3ffea5b5f67b52c196185bce9e9a858257fcd7a8ebaf9040ed091face5a155aa447fa15e12122d25e8fc36eaee2137c7b3aa30b7e3ff6cc86b6dcb9eaf49c9576f0f462008439cb1a3aba013e897a0faf994cb7d59ede5774bb144774f73ca30e6414a7cc7c74b20c51a1404ddc419ef7624593e9bcfb37c0a762eab68faca5863443e16edb759dbc8788732b9e4f59c11192c3fcc872af55f32d
+SIG: 22eb8ea0507349b6a0ace25cf9180cb08e0357b04502905fbe69b4e21b2bd94e22cfbdb851ae716a5c253c70d5e2b24ea78f35bc213292543d94e14110b24106
+
+PRIV: 06d498318da456242b9c3b9ab6d532a128fce044f53882682e9262149c165288413517aa63200a17173209a4b3e78ab9383cb4e39efd6794c46a2d13fafa99c0
+PUB: 413517aa63200a17173209a4b3e78ab9383cb4e39efd6794c46a2d13fafa99c0
+MESSAGE: 3fe30ecd55077a6e50df54bb1bf1248bea4063e3fa755f65fcd1159ee046efd0eb5f2fbb38b5c00947c97dc879b36b9e536192286086d0dc12053610386174a7c56f22a85b73ff208c5944f393236c32415809da036e73cad8fc3c30378064a76afa930a3baae9aa357061a8c5e8e756a9cecf94b72df43facd88fa49cb4948c6368318a6b1e5cff52e587ecdfaefdb69081f28c2d13bf8eab81dbaa5e3728c4317fb793dd196bca0fe54a6c242cf26e2d129ba0d82a2c3a45bc8d1dfd6f54f8da4f5189c91ac214fdabf4c597381b2e5c40cc71fa7051cf2ea93906a37d57df12d5c7e5cd77c907e442566315bae51a2222d62e3f42d1767882637d66a1d5305ab4010a0e49c57def69dcea839e1b76a41135ba952cc424950e8d3aac19e1d93de7757c15ff9997b3d2a8613cd9a164781d1be331799fa6109cef614305a1958f62903c8c9ea0b23ba706d49c54baccc1e63cb4bf14785fc7b062a9800349bdb0bb927260b677b60f10e62c8780f3ebb5eb6ff0360263d457ab52fd1125c9ce046a95d89d287350c804cfd4ff2b2ddd18a9e13519f20b4d1e051af624640f
+SIG: 8250f76dc599c5128787e4f6d3da23173330ce3320dba959bd714cc8cc07c67945d63e75662c075e267460ab7bf561f24faae3b41dbf676899191e3b02b5af0a
+
+PRIV: 8e8e1db5b1102e22a95c47af3661469f000a33f13b8b87b115d2452a411f6f3956d7b3169a95c22998ec937925bd7cad13cc65808cd5d34a6c4da870eaf32364
+PUB: 56d7b3169a95c22998ec937925bd7cad13cc65808cd5d34a6c4da870eaf32364
+MESSAGE: b24634fbdd1b7661315d9dc153ba90d66a88622a4158f8bcff25ba9c29e65f297f8e60311800b7331b69fc20c9f85bb7c184bd4086b3a9f9a27102b62362bdb4fa5b201594250fc628fd2e0e0d1be03dcf818c6094c4c29121cb2bf6d908ed8aab427c3771c0c95f0ac1469a0810b603a470282e5980a60729197fe6c20ef681cd1b96932d2058f896ea7416422a7e541f224a5f04253080741c5d4e3eb039db6ba051b4ca5417ce8afdc70214ba4dcc85b623d11e681c6009aee4e6130a83edd0d2c99fb0647e11ede7301ae56b59904ef7025732cde038801ec7e8d90a9a1bba047fe628351b3b89d0bc5ae665a700891f09ebeec05591842adfcc25adc3c71c1ebc4a312e5471be67253b0e9428b0cae37645a0f7ecb89dd79fbd9be2875433667ae07d74a7983c4cea601e72e975c21df993e7fa22a9fabd45455d45e37031558e13a7a4f5f497ea78fb7399f8838c0fd5de4ebb66db290f43a4867d505309f1c1bc27e9fabcbba71302fc1204715ce3fcb0905bfa411c9d1c9ab4a39954e50b8e0cf736c10289563bdfa967553c36cd9e555bc8cc56be594847de9f26f9
+SIG: f6ee5e13cfaa362c8971d5a4a879a7e36966525ccd86c5a48cba08d913ece1a79c4cd146b8e9c65125fbadf17bac1cabcde8fd17cfd68fa1f9c44ea61c08a405
+
+PRIV: 3884b8b79abfd3be6c13985eb859ab743f157cd9deb81b2fe97ea4d6173e46f5bd7fd9a8def13a542ed2f2fb048886885ba9b5ce59cb7019fb54667986eebc26
+PUB: bd7fd9a8def13a542ed2f2fb048886885ba9b5ce59cb7019fb54667986eebc26
+MESSAGE: 12adafe30eaf2b9c7203ca5d44b97ffed4bf6517a49988e4e676c8e314adbdbe23d8f2d3e2b081a7024fa525ab5aae26e60057c101e8f368d3addb9376c4682c1f4224d7f149a8474bb9a8f663ef210e9572ce829da388d8aae72a467141adc153473be3653baaa64b5b1e2e30683f6f06dac2784d5bbf0d082aab47305ed8a8efd0886ce63a179315225d1e4d4ffcf1f24ac2f464cf5ed3a8b6d3998454f1c02cdbf0a444ee2b59ddbe0a174a0d937fa62865088ac647499957d281c6949803a5fbdfdd0dd9e91b6976861f3c5f2126f39aac935be09f4b9715bd4f0d5c55df73a6b9f2c0ad26ce49d822bf85bfa2346f3165b03859a71c3d2a7b86db6e9f2e5d7b169a910eeb7ef38fbdfbbec43a9a25f04bc3acfd3b0691542ab6de9db6f03058f9584024f9918edecd90fbb85735d6dcec5bd593ae63e2cc96553599a310f8f2009ba95371196b4d5b80e7559637f22926778be5e1ccef5126e2443fa939c2a53dddb04961eefd34e538cd8d7f0bec2bff1ef0d3a4bdd358317637f42d595538c1122251a94e963d1f81e7b9aeb164f95da9a4ed7529b845ebc961b27b5c19
+SIG: f4206fcd34502441d54a73323f33a5dbb4c98557319f21246f260ffbbe5844886db567f4b63c47943dbb78fc35657d7c04d4feb042ff8536f672925c319efb09
+
+PRIV: ecd519f287ad395052b0b30deac341d2a9df13d6567c891c813a0c9ca52e871e8ee94c588e0b343585fc6748fd1b54b5770c64e9937a56357a48d44ae2f51824
+PUB: 8ee94c588e0b343585fc6748fd1b54b5770c64e9937a56357a48d44ae2f51824
+MESSAGE: aa71be5f557e10c9fb5f091a3a274453947c07a0e25b26f9509224541dff76f4d96effd0d5a41d319bc9321a86667d55cf49432fb5c3e715388f3f106c9174b1610c8f3075d5931c290099385ce9249e235128e907c53390036fbf5da968f8d012336958de90c5e8e6b1016ad43fb57c8e288dafe14e90e64b63791e5cbe557e02df8ac9370642a71faf851075e5565f6f9a267f4f6b454ce4c5474810b804844dda38392939719793246aa47454b9b0e82e9803c09935d0027f3995cca9713069bb31027f7b2af12fe5feec7eeb06843d8296ec5682262a07dae747ed7bc821ec17018d899fd167b36a7e3773b427499d99dc583bbe4b429afa6a26593953f943e4673bdd0d2a844256131603cd0903256f334d4f8ec82de115b6ca5338c75c8baa44b4ba963c7c78510d8de9b2a5852f42f3463c685fb3a6da61a8e0892662d6a250fcaa6fef74d450fc457b9871d08bb5be3011294ac888fce215d535c3b1a43bb47efe3ad25da159191aed55195469c59093ffb24f65d60c4020bfbe647ff5db7ab8a01d5e487b0b1b64ef25da156db142e6ad872a4dc1ee9ba668465265379e
+SIG: e8f51be73fc4e0235aa153a2e1b354e9c5d2d33a11ae0e333478de1d8e6c4456d2e250824c3246ca0e8d6ae3e16677a97344144108c13b959e1daf51cf0fe501
+
+PRIV: 193f3c630f0c855b529f34a44e944970f4a6972e6c3859359c2e0c8762ba9eaf3256f2c82e7c801201210140569faf18507e60338c2cc4118bb1ce605b0ebe61
+PUB: 3256f2c82e7c801201210140569faf18507e60338c2cc4118bb1ce605b0ebe61
+MESSAGE: 98623f651698085bde02762e8c3321f14da1619b5c3f7c1a568e8c26ff0c62fdcc412475912eb8e8c4b0d30918b8ffeef3509315e58da359cdc2f26bebfb5703953be16b8f3beb1e54a1abee0aebe24e64dbe873402e156f37dfc168eaf8a114ce08a6795d3f64f5151e9a8b8275cc7b49a6b8d8a66b6d4b7632ef80740dc1c1b0a38d1a28f7c1b29fa44541c1aad354d4590c231dae687a2a8fed09e8c1ebbfcc38f347bf06d94577e49ad139f710ed8bb1fd07663c0320846fbb455ab837ef964ae7d4eceea45fd7bd8d509f821e6eb027494efd8dd8e992b88698eec2ebc5e03025be789c18013f201f77aa2d34f5686460e43fb489e08776f98bcde2ceeb9d4fafdffe0375604371ec32f46b81fec474382908e9d250a0ba2780a7d6df407bd2b1eb126748d72511b9b069eb1cd44270f29fe84b9a717751831d04c2818e408f22789376c61c2ca45e32e788ead3a7536bf09da8af4703902f5516a020d89263e93701a2565eef1270418925f35a288e327bab628ac2f0248cfbca3482e265d1621cc343c31f65493f064bad0d7602460715fa486f29426346af53e333b75f5905
+SIG: b12510ac5f2f6d33360cddc67291d6c270fd9ee62dc086b38d932d26473fe9a24efbd4248867ea7e915a30c5bfb3b8b19aa01aa2febf0dac6cfd6638a2ba7e0c
+
+PRIV: a88ad0048d38c44cebe735ea3802ca576e37121c7d4d760dfd88de1663064abb14dd8bb306803e5a758ed68ad21d07d88161d50f1c74713777da1209afbaea0b
+PUB: 14dd8bb306803e5a758ed68ad21d07d88161d50f1c74713777da1209afbaea0b
+MESSAGE: 2ce8bca26178913b1676e90ffefd945bc561982660e2a75d482ff30aaba1ba43f82d2e6b909ec10fc09789ff5cf32a5180b601ea80fadece6d7e7baeef481dc6979e2f658ae0f6d8e416b93298f7d34031bb76f716ed991a16d09a582e58ba4003ac17be8b4469e1a889b2fbb2289e98af1c6d5bbee77756713c0778b0dc446a1f6c48c4d40818ec799905f069bc95341657ca5d02b7a539a13a02cd0376a50e8343c0dc20346de5275b1dcd4ad7af725131ac75e954825d30eaa57a68bb98dfc41cafe5710556647b387d9b7fd4e47651e5138050798f6d40f4ee7120b58f74da94d73cacbfd393d1347388ee00b79b8dbfeb57814121bdda60c627dce147d4d568d79052e97b9a5f3eb5407cc46461a55e18a960d8094a5fea48b6937529cc4ec919cdbedf9185456dc00e8d98ad1537ee10a057f4eec4b81dc60392fc9188d3e561785965092e44317f2a48e36605fc583fc173b05db9dcbc7557d06487390fbbba77af3a014e1ac35139caa1c53a8d17347f178e1c54d0f52b40e91042c93e7e481d792e288fc27e4c2fcf111fe97d9e2337d2fc1c3098f06684a31d55ebf362c027
+SIG: 1341a148da4593c88ebc5a58821eef77f92186390ff633e76207084e7874ccf0eb1f9ec70a3a3f96b58934bcb061ff920124f7e580fa2b0b279583adf9232d0c
+
+PRIV: 3f59d6a018f50a822117e5b473609e30cd64920ca1c2750dcb09eaab807a3eac457d0e59c11f348f3bfbdd3f327de78c0a7577c0aeef42d4c1e56700d108808b
+PUB: 457d0e59c11f348f3bfbdd3f327de78c0a7577c0aeef42d4c1e56700d108808b
+MESSAGE: 7d103a6c6ba2d09087eef2254c1c903f067695a54c4515e4d13bc1fbfb54d6e7a167349c14809976da04a7e58d96b40aac3b2bdd14b9b50322bb11645f05e5e978bc7fbd02492ef88f87d668280fd708373207ff670fcda97df8485d5e46dc3bd04347f4d7527eab2718f7d93d132ba7758218894e75a7deabe693335ba0dc73bf26c288bfe9be8a736d75e5e0eaa7bbe8d0b77abdd5146e0fc9b30db9f07cf4bf36260a1f41410331f8b47c6b38338c6dc9e801ffe1d585f9b7fc31e9778bca3027c232c074cb18e5b72997005ffeee4bf37c8f874b1b246a6345415dacaca7075a60443ac3319236e23cf6b7544740807052114984b8d8f7e857dcc6faec8869cf96b997dfa9af9184ad623f1d90b8ca759b448eabfce18c17cfdf9a3e3312e63e5f084cea904c1c909913cc4b19d044a3720034973c7384949bd6f9ba9256f98cd394c566da83c31180109f16d10347b7e3e9dd6be3bd3c77ff1a7996a078dcf89dcdce2d1b615695f4cc9f8f4f2a08804641bca82662ce88faa53145b6a45955aec8cc2af81cccb5d7c64f9ece1c9983326484a1e5ece4ce36544d63735f7776f21a20
+SIG: d7425ea194a6715c452ec4f6d6c76e6dd374d3ca7ae7a11995d02b942d4a31870dd734c12fca89a8eb0213eb139c14a87a6a33e818603b2e313023fa58737d0e
+
+PRIV: a1212b34dbca63b7093612d05dab7b4cc8f7b676a934ad01f659851b3bb44e4eba2fccea9a080591be71268d7e951f250dedc00416e5f3f908db6cc571254925
+PUB: ba2fccea9a080591be71268d7e951f250dedc00416e5f3f908db6cc571254925
+MESSAGE: 07c37c46be3c68d05689577aa64a932b906446b29baf12f6174a6b42bbaefd1f1f373e0bccc473ddfcee1a7f21b96a6260ef0aa1f2d8b2959e71d12c953358a2774cc5e6f379a313e435ed69dfd6d4a59adee3cc7ec4bacbdbb3fee5430b73f6051a6096c60e9bc92cc8fa059fac2a93ef7007d64fbe50064964d5a0ad601175cd9caba453f9103b25485545d301f03c5f9f9478bdf9d414bf1dca3b1c1d9daa9971f9e617fbfaf5b02a7fbd5d4fb894c0975c54592b49a0fc85dd0853f30c51502d98fc1ab85a17cc58961aae9764570ba5cbdbc96dfceb8d11da53364b4025fe0b8ba8a353ad23686720169fe973432ffe291a4b11dedda0aac79a5e42620a64587d2059e787013b40ceec599208f66ed0ca6e1be9092ec27db216ee6dadfebc21705bc4a85aee577e57d239af586efeec22cf38d1cfb3cd74dd0d9a3381aa81e6a297e39b819137ad27d475e2bf54aa426dc29c4ca8176df343137a2d79d12ef9aa7be1cf6775e5d8a4430a85c33db61cd2f35187b4f6ea9ebdd753d1c4ef72471159ff07b77870906496249d4278e3f3ca6bcbf37a265b896539190f9a31f1e7b4b65cd1
+SIG: fa93ed6595bc958dc042ce1645167b79e8f6734c46f80f631fd5484908f5e51a22427ee686f564ff982f6ef4d2ca1f0ca5624910cdd63c11a3c2b16d40973c07
+
+PRIV: d9682086fe7dda30b87111060193d847566ab94cfd9c97ab6b43e7a8d3f793828b0b1372d88733ef7233f6379790d1e46e1e07e9d3fb8b0be252ed04c5fa163d
+PUB: 8b0b1372d88733ef7233f6379790d1e46e1e07e9d3fb8b0be252ed04c5fa163d
+MESSAGE: e8814be124be3c63cc9adb03af493d442ff20d8b200b20cd249367f417f9a9d893fbbbe85a642be2701d1d1b3cd48a85cf58f159a197273143a578f42e8bcc8b6240f93271900538ffc187c0afc8dbcc492bcd679baaef3af5088434a94586f94b49970bba18f5ea0ebf0d27ee482aa83ad0dd0ee609df59d37f818b2c8d7c15f0f6f544dd4c7e7cb3a16724324f77d58948f8475a60d53e5bd510c17137c99e1cfa515af9bc85569d212a21190729f2817de8c46915e021df70ff6d60215f614fc21139904df3b292b749dc4dea02518b62d15862c92d2a4c996701cdecaed84ab628ee984fc111eecb59e48444efc0d456e2c852518441c3db7630ddd5156249a28730983838ae59ac4cc7110fd6de68101ea5b2ff69fd364e3c9448defefe175bcbe117cc11b4ff7549c33e1025b6b592048a8e31969e818dcc188bb19d7a2440a3baba4eb1b81c45679db46b31bcde7776757d9931ec2063fc6f1fcd761ecc57a7d030a85ea273ef1825b05092ab9645359a444ff7d166b575fac298308d9faa68463d1d0f7b7df8a51c6815d37159adc0b593224a818321d7219f09686cfc952259718dfc
+SIG: 1793e497eb521ca74e35d14a63868cbe9499da2f21b4eb5260340fca3c1feca78dbe5b14ac10f3fa76fa2e71e4c91461aa75977e5e70792670ef7ff0e6a28708
+
+PRIV: b52b249a7aeae0fbd94ffcf9a9fde10de61c3f4cbda14b289fe01f82707334ca735163bfcfd54f9d352e1c2f3c0170c95c1842ccc7421623ae0496980cee791c
+PUB: 735163bfcfd54f9d352e1c2f3c0170c95c1842ccc7421623ae0496980cee791c
+MESSAGE: 1d445e8ee36f6e1064ee1281e6b4a4cec50a91c2b667c8305d1e9a5f7b73a3445882581fb0c11e64f6ee92e811f9f2d6c59c6344be7691d116dda493cade51c0ce77372b61a7c4fbb633401333cbf71372ad2f044e992ac035f5879c053004f8223f237a24a409b7894f6ad518e046b8a84c3f4c6260e6169fd944d57fbcf9ba2775f2d60ed772c46ccd63c850b80d587c5208dfb1a25878c02dece3e602e9632fc3c2c79b25ab41034c6e26b869255357a686781dfe6e644beba9b627da1fcb5ec0be497cf188e1ef1af0601bf16b2911fd9ff34f0e97ac95a7fe2cf90ea6ced33ccb0ed1ef2d4160efb07c591a5cb16c70ca1694fb36f2ca19eba52be3d4ad895abcada4b36f0261d65f59e0cfd2a6148a8892ddbb45810db3bf4a9e26e92c15ea2618cfeeb462d8628f254f54d2af27113bab4f9a7d06791811942bdc32f845922d7b2ddba959140928f8c28d98b44e1d19b97fd39cc0f9a5236d349fc835ac492192462e40ac629bebffd2eba72d2788b244bb777ad0f7b7f96f23412399fc1d87a1d087ba089027eabbc05edafee43379e893291331b460bfa7332e0842ec2573393de95306
+SIG: 6f48a9f7f0fa192b66d12175a333612303e180b9fab18edabebcdf6674fdfcc53607089bf980ce35894c2f9babdc4438667ab3297a6248ec0269faa99c724807
+
+PRIV: 782a93efe0ef06cb2534330efd0e9684e9969b5258123e490239bf24bf9f6523942fa1406ee2683e29377e49f7ba757cf50ef0723707d4403d2862257045de87
+PUB: 942fa1406ee2683e29377e49f7ba757cf50ef0723707d4403d2862257045de87
+MESSAGE: 46a4e319a670ac993994a53300c3f79144c2f7fec1116eeeb3621c76ac35da79dbff6e189ca9dbfc9abbda054847b2971b02facebbe926d469eb0a860389ac744162bf6fb13b42cb9bb8c9d72607138e7800121ee0cd633ed535c7ae5f4060bbdd271c9d110abff5e060ea6ee83890b1e92a9256d7b2ba982a3114bb6deffee2696f0a2f9c21aaa5b2defa11aab7076de6e57e86f284bb67f5a49ee685921032c95b74e7e3eac723f175af082c858e0dfa01728c38fbbb4c83581f81ace6c63c6bdaac5620eb9a568e7ebb7b72b3d1a164ef524e7b9f00799ab086715976c14d0df65f7b96bf9ebcda7feeef113422001a03a7633df5e49939a121db899d9b8ac2db4fad0c30cf0b8bdbc9e9802a797c8238e46511ff24068cadcff2448cc0bff92769223348d45d6b6f2c8f1593388c0bbbf44b6ddb50b98cd7f09c730f7de4d008156cb3cde0cab3ad0a58a83954e234a0a8a04b573c9a8e9b929ed38b8b228bf55a3c6e2c6b51f682652fbb708e74640e3313e17b4694d7fdf0111f90608c1b5af422dcdecad9ddb7f50d1bf5bc6378ccaffc3201e6c787b48c443ba240d9d50ff6c0e9df7f1a5b
+SIG: 93e7405a4044510166c8ac264ce3b5ba6665d68bad458712dc93c2c390568d7402ef7d57f549b8a1042f7f69a679aa855f34f801d57d79895deb8deadb352308
+
+PRIV: 6fe7bcf7a684423de1076fd76da783423373b381329efd6157424ec4b2655a947740e91afe45324f8bb990ca2a341279ddaf232c3bb415f178b6092fba195fec
+PUB: 7740e91afe45324f8bb990ca2a341279ddaf232c3bb415f178b6092fba195fec
+MESSAGE: 0baf0ad440612b4c5a136c3a42be1ca2b7c319862a44a9fd50c4ee73541c5e6457efa81825b6dd4a72194a2968688bd49e5a8f4c04dbafc2e7884c0c70c208d4e954cd1675da8e74c65c497cf9dc69424965bdcba5de52936f925f62e201f99505d3777beb3c2e08b2ec9a873e5a9c21fb4a2f3e861f3cf4d6b5dcd1c88bcd9163539ac62cd0659f4ef232c2ce57fc77f90285eb350169edc6a806ff50f61c7e0beeebecec63bfc9d3983f5bb4b261c746471fcbf2892c6108970b68db5e43c4504ddae2d0ffffa28b6759ae1128e16f66d492ad61e3722c960f88692be81a9f412890ffa346e702c867dfa259703b73f525074f3227c49cec1b645a103bd4471f33f9f1bac327d7917861d0ad91abee60222ea2a3c8cac052ae9a2cbd90855d733d5319133f9541bd0b61f0995268351e2863c1ca2ca51e3c976383f5c4c11ff410036fd51d5ac56b023ce9029c620f22557019ad9b4264ed4d71b434f4a4d17a7d5769fa1e14a69f7ae419ccf5947f8c7682697116c2405f5a1959c54b48f0872f596ed45964488ddec12bdb636d0b349e749eb66092ff4511fba59b5962cb93cc85515cc86ab0c6b2
+SIG: 9914cc50fef0935efb89b3d64e3c1c3412aed659b90166222c0d13ec1ce3a68ae6281b7efd9d4ec64b82e73e14479f03fbac8fa3abdb41ea4215c4a4d4949d09
+
+PRIV: dda48a0d15a29eba9a76305d360e466e72d8040efe2e89c04b6461315a9b8bf44f5cc36a809416b58e15d24cc57968cb573b76ad90887a8ef36cde7eca400fcc
+PUB: 4f5cc36a809416b58e15d24cc57968cb573b76ad90887a8ef36cde7eca400fcc
+MESSAGE: f5ac19b81f2111a0db0ae30d1513ed343e7f57f7f77d65b8ac7ce3a601174baed9bfa136035976f516d5a870f45db1919f1eb1cbecbe88ec32d191e9248821a7e7681fe3abec11584bdb33de1b4ca94891eb66dcb8539ac41163736ccfd69abb83814dd38cd60381318728052a25cb665471058650ccc75756dbee688ab826ecad4ad5a7db57e8f65f1b64abff82dd53334b797ac40228dd817f239d3ee804a19aeac8cfe33eb657ec9ce923d6b388914cfba2e72bfc2bc3d6f985c0d97534db958eede57b16491ffb755c1a58d78ab377faec0d311818e899260e3ebd1ccd29246fa82d0b76622b2c4bc52f549fee72a30f554f331f36d2a74d999ec10a08294f002b4361e590279c2fb1bda4312ccb24d75282ce7c061a0ca5520c74f6f6333b18c4b541cb6c51e01575ba80512ffa7ce0accd22d14027c53aba1f7437835f1114d68e3acf3ff8de94c8e4ef6d3ab312c91d02970157508f54a5816f467a214e9b1284300289e65f365a610a8ea284666cfe5518e435bccd21627501c725f0b8eb5725e0e06e0cef5db201b48ec91ebf878dd57ce8dac7334848a1bc82c18b065955e4f59be3398594dc
+SIG: ce71bc82d531d0f93b57bfdc2f7316cf404ee09af88f33bf806c7cad6b8ffa366236ba74e75c15096ddaa6e3a62a8f5eb1c8c3f6b6c94a6a349fc7c0cbfb190d
+
+PRIV: ec57b941adf3ca13e77a780577cfd0df5b49edc85351052da34e99f8a9bf32082859c071978a04b7f5407b6d22401a78efd0394bb966b9a04da6b5ef819de3fa
+PUB: 2859c071978a04b7f5407b6d22401a78efd0394bb966b9a04da6b5ef819de3fa
+MESSAGE: d2bcbd1bc361ab32c66d72fd48a8e227dc6b8d6b150848ba715ff47dd35c8e49381bb4e2933f42cd26b75b14d9c0039282b62b8556aaa11cd691e828382be306889fc9205137b169d3bf17b7f37693fce286039f03809d7d9d98c8fde46f1101942a279c516706f50191a9112f6a24630e1a26c321e46c9ccc85b6ef942f353a642b9e7ef998c0fce2d3a75b999eeb77f31f9b0813a97e3014c3a86e2558734621a3066dae35845031e35665f1922907dbb739786a8b7658ab60276f2d921d1a51230fc74d19e80184a4f10e9e834abc9a36c429726bc055dc8c063f0eca9c61a8a970bd4bb5f424ee4d04bfc295e3bb1f34becbd9920fe2e77fcf36763f32fc9cfd5e465979c167cabf5a1244b491fc06b8946419046ba516c5b233c414ddefb6da04f2e13daff7a9a0c02a518ede57ad9521de64eddf6f49a9670f632d3f7d42425207d053604fe39d13b9f52c8bc292b0076ea42a560056df25de51ad35881d08543224d7fa5d70b8603ef23ce06339d6cd09e22a95749e50dfbd3b8ad69fd30496b984d1c0a199c8594805f38ba44631a2c59eadc6554d19f9bc98366dfdec2a121d0e4814d2cd3f5871
+SIG: 118e1462126b45b8c6803523755c56dfc4e123e4acbb66ba0ba6fe3e053da4119f5719295e0c82ac64d7c5cb1ac898df263ddfd360f3008d91018b26f6a1730a
+
+PRIV: cbfd91d7695c1f270f69246ab3df90edb21401101ca7f8f26c6d00f4dcb7233e513879cf79d2f46df4b85a5c0949eb2116abf981735a303164cbd85adf20b752
+PUB: 513879cf79d2f46df4b85a5c0949eb2116abf981735a303164cbd85adf20b752
+MESSAGE: 264a933f7d0aecbac13eef644b0b53dd53a1280904100dbc1ab87b51148998f9da0b3a0a6337f5e3486c2b7e548d211259397aaa194ee4695bf98c2d5f4487699f7397e5d3a7e6d5f628fbd05497c556a50a4d05e2b712cdbc351068e42af19538901b8825310e343e1a17a1867dde0eb47ddab456d316f3521554937bf808ae4e4bc1c3c5b4756e4a165ad9e8827f5316f748cac6998ed2d2104f268407c135e62f26a922460eab6d851639a00e5f08b34765ea0244f475bbfeac183e3b5bd1aab798522798a08ec6bf2257d4692f5b03cdd0a2133de970603e3251475aad8d934af6b2bfc7a650b91bdec143f8ad254cfa506bbff28a03beb659ef5e5ddffe76e23230c4ccd46310b37dd91fa6aa68167f62a55c8a69f9ed1ec6cdb144dd81ab0bcbd62643420bcae67869f64c0b169f3cdf3c905895b7d35b6fafda25ccf23c3d10de32e7f271e300d39597da8f843722ef08364a5f7a105b9655172df7c82d7374f98264c9cdccb496f2e10fd8262fb1a9a9965b0b841ac0d0e9c1a3d9493ea7aa600205b8f900be0d7abb4d98a06583d2295c276318be28d421982dedd5bfc33b8865d94ef747d626af99
+SIG: f336137dfe6f42a6669b55f74b80b3035a040367f90656fcef0a644c52272ddc39273cd7726010ebcd8a30a05201ab70b8ff97d0288a2cb94cbc49020647390b
+
+PRIV: 51a4197ab7686f82f6003a0c32f39d0f2e47555f4e9f8deee75bcb1bd1ef69e506386df86b61f1f8f4dc45b73edaa841920968bbd131cc5ca1c5294eeed5c8ba
+PUB: 06386df86b61f1f8f4dc45b73edaa841920968bbd131cc5ca1c5294eeed5c8ba
+MESSAGE: 2aedb7e82f1fe4ce469ada48345d006d1b3bff40eb21867f51fce965640c409ec13ad4d52f891bd79066d6b4d944ca868d8986d242b57eccc4c4a488291b159c8de4392be4b86febaa75eac5d22d3c4f8d6bef79adb9b92b4914d5ea07c7f021e2c29f58d07be8a084100bc152d51ca897d7c131644d0895322e9440a8339e1aa390a7f4fcb51ddfb6df48aaf5676337d87ddd85b1d925e1a9c29fe0818f514ef72f747a674946476907a7ca99e9db8d209641057a7f44a317b90974bc86f9617a968a76a6b8387cf5853e608190c1a79f1e1d686e0de22db6cd9aeb8532c5c85cc90b5a018579f28e502a770a4ec675263d0dd781b4fa53c9dbf8098d57b33ae2afbaeb3e68266ad9aab7174ba68c6479883992670ccf3e5ac6a17e65e31e1fdc85e269c80935ef574f20d239568486e7d94a4f724ab7006098b24f3f61587691435c7f29ce4e5ca71b2b1874556433a358c8c5ef3c880843030c2d13d51b78c9bf1a8824e62e111844396f5af2e25c3126ef3626e26efafacf99830aa41212332f378a167233a0b42213afe36d83dc4582a79693b9d571a57712a08b8566d361ac902647afc886603e24283efb
+SIG: 2c072969ff4719212a121938b506c602995b4d02a22e6198d6e87dd6ae076225ac70bb25ef8c0ee81eb6fe953df6b1815949e8ed0506cb012e873cd36cd09b0a
+
+PRIV: b1119c36118b7a065a195bfb8b79a5c287e09bd287c2daac5e6b01164c5d737f88f218ecba99e770ed214a8d01a92a10400acaf1f6eed420067e136ee2c0c670
+PUB: 88f218ecba99e770ed214a8d01a92a10400acaf1f6eed420067e136ee2c0c670
+MESSAGE: 8816b1eb206d5f6dcc2e4cc391d23209006de935e318152e93fc8c2cf08e26432bad9adb3203d898df0a2e7f1f83dc2f3ed3205bec8efcfd31adc1aca5755db9bd4efe54cc17073077de4a3fdd11996e84b6a052f034b41099226c9c272eae12528f16581b91b812850c207144dbff3e850cca848ec2b1dd164744d7b59337d7e3efef008162e680bd4a0899ced60b171f8cbeb48c5158df6cbfdb26240881bd58ebb8b6a079587279679cb5ad82f371b53c8013804c35596c887e436d23926f994e09d98fbb8ce2704174ef38b68262a7f1a712da0ef0dec639606814b3bdcaf253ff31c48e8a752c111bd7101031cc3d38efb0c9c7f19c59081584a0e015ee7c75b10a4c51ff543a30e52d5f94d8188c6b08e9df1e84a4e2c807170ac124a771b99465a0d38b1f1c6330403c82543582c5bb61b220de1b9e0ef69bdae26023181ba4cc077a5f0d425732ace132ae0c6ff0bb18baea83e8877afbe650fe0bd02093f00a7b5365728dcb66fbb881f592945058a5b350665af91c557a547250ad295e68b4fb72457cfb9d5ea1a7b2a39c9ab7d7ace0af5d51669cb6c2c4c07b2256d10e5ffc6b97c660006313c4eb8d
+SIG: 24ec1e54fc7e722d37551d02cf135d33f5d3ff535773e02991ee85ffd3aa29997f9c464470197fee81dce110609f870b27c18dfbcfd9320548525e93148e2205
+
+PRIV: cbb587514e0a34ffc34cbc04f28c9b4f6465f1eb225cca19b864876daef37d7f6b705d4677d2d849b6744b1ebed167dbcbf645924b1ff2e6360794bdd0e09788
+PUB: 6b705d4677d2d849b6744b1ebed167dbcbf645924b1ff2e6360794bdd0e09788
+MESSAGE: bdf7d17c706796efd3489559b527b1c0584b9022c9cbda3aac5146da340d9cea69f916037cd21b3eb1104348880fd5c5b7c65ff820f7499346016951cb715d8df2b41c88cd3c66105458b7b590c21c1ae2f6ea9ddea7470f25e02027d171e0e574a2bb21642f8f9da508e21d8e7335b5ace5935299407bd1b01bdd1423133ef045234e701f55549434ade94a60be1e1406ca5c758c36799ce1703084476e484fb1740530aee84266d07adfb4cc689f3265133a59cdf992fbb9a4b12defbe241ddbf65d12b2fbddfc05af0fb8de42080775bad29c6b0459841cbb648a9a95e48d6e36ac514480a3deb4b36554d8da620808ae9d47329710d20aaa6e5d7f547d81ad30f84c0e3d239cde5b169d9ddf294832d67a8060ba329c4ef39be94ac46434dd2185931d1231f9b6df878a5af0831e0e9d8a08d08069ded6a961ef7f39fad501ffd17d6d9b7c654653c1f58fcee1a6cd803d2aef166c78ef5514a3276d6998dc7c09a3fa982e427c785aa6a9e256f7ba72d5a6ba33eb46f1f9fe9be2bfc14109f64773c00c063b4d5cb4f4f8a0beca92a9a016c4f540feea9c3a31e313bbcbc2ff5eca9967857f5f8a909a29d7f20d
+SIG: 1274d6f356eb641472b6b9e5b3ce65d2654e6cb87d3a83fb49d0f7da9c44be2b532604465f6089d680d2d94b0edd2b6b2b805c5e84c379efc059673d31007a09
+
+PRIV: 8bde3ff61a16995ab9d539f6053219081bcaea1d458ec33684fc1c01fb565bfacd9d782a356e847b7a04c885a9b0907cc33ba97ad5390d4ea5fee5eb198d08b3
+PUB: cd9d782a356e847b7a04c885a9b0907cc33ba97ad5390d4ea5fee5eb198d08b3
+MESSAGE: a1f40ec5807e7a27069a43b1aebff583ef037028c02c859525eb8fa4c3ba95a901ff3aed78c4f87752fb795522f5bf715be7e3defac10fcf17e3fa5c54b20089a472333327252ec945718fb455e3f27ccfdef823d12d406e62a4aeba3cb9d1c61b2b17e49e200a8418f935f26eeb57602c7aa3b3a24f7e6238d3e08d2d609f2eada0332bc8cb12916cb03b0d4f9cd602002586d3e4cc7e0e0381c045ad2e1ee28298ae7fcf0c10f212808565296f158d2c32e8cb28156581af52bfc3470c3c9582138d2255e8426d648ca237d7aad2856f171638558241d8ae3f62ba92db596568edee3ec0ef370f83626aa0445af08f967863660e8fba5a41c8e8ede1c960514a14687a4a81e776ae0e8e777fb0f250d51a83b55f8c1ffdd78df3bdc97ff177afeca046c72d72af924ad0d0ab2bfc11b7f4abded51c3987a8bb94d640c8710e5fc9a4190e8a008363d7419cea17c40dea20ea5156029f3debf05241918f54af5039e2c4cf2ca2e139f60e45cc65595cdf54a67d92b6ac66fc0c5a290495ca57b07ef5750d05f57d87d0c228f7e4e15ad0ba0178730f951c697583481c66cbfcd48032544aa8d50908304bd81940308706
+SIG: 7464df0b67eb90b4b73ff082ad0d60ebfe0660dae97069b52c3727223bf70e29e48711a2bbb438f5f8d8a33bb9c48fe7b628fa8a542ff0b5ae36269d4007a505
+
+PRIV: da59bbc523404f07646add7908294977e46645bc8a38bad2809641a23de3b15ab22c0f21aa1c2d45f4b2e56cc9b5e02f9e31a2eaa367ecb482f874cbd8e9fe34
+PUB: b22c0f21aa1c2d45f4b2e56cc9b5e02f9e31a2eaa367ecb482f874cbd8e9fe34
+MESSAGE: 097106c3624d774dde2551e0c27e19504e6518cc86369ab26ff810969e7de24abc68b4b53f11d945d49ef078eb4f6ba6bf257ff7b608afdcb30a5c59a756fd77a6c1247f6f2a41100d99fc5206af3bcc6de1d3e4968e28fba0123f6045a1b54d693a42bdfa071b2b914b3c3c0c29b2593d07e8bdc86ca42ac555b7dcd9439df9fbd4bbec730d6327bfae4fc41ed498b4f04a0eb14cee608283aaa6e6aa46676bc88aed5d9939037aad4915661af94bb5f6e653a2cac123287073270e0b13fda1dd4871af6a92f992f539df881712fefb038540d41191123b6b3b4b6ff87ffc929a6be53c6cef02f48f2f0cf2fe64a45fd66025cc2d7ee55ebe2316c000855661165e2a5ba41afc2097957b6fe4c55221204b6fc1f317dd3ba13cac39924026bdb66be4542268875631d277f210107a33767f6d9596e25742d7a90ea791ea4bc9ee84a67fd328b80f791ede96d89663e937f0b755baa9d52bda210cee1db339ff1d3c4b000b653b9bde338049af84364e2177f80dd51e2a1672ee555d6317589f6f1d5abe6c2877358bf94b0b808ff857363fbfbe32e97337e4b8a8c221a9e75962a8dc9b5a3d7ca5f9c9b61c73c1469a72bd
+SIG: 1472459cbbae2cf21ce44a15bae9fc85dca40b8182da7d52cbf56ed538d18e03477c140a3ddd0efba43c96aa92f5f9bcdf3481286ce762a7e2bd1e779ba99b0d
+
+PRIV: 40ea82da41fd15b06ffeb99cd616dc6bc8c1b21477ea239466088e2849bf10165910e580bf412c31a87451d9ddf32b3ab713f9e4a22c590c641c14a5dfbbe0d7
+PUB: 5910e580bf412c31a87451d9ddf32b3ab713f9e4a22c590c641c14a5dfbbe0d7
+MESSAGE: a06c4e02b83ab7e191ad818cb8187b52a8da004fe838db333c4e02548db6bdf791444642e57fdbc8594e59d7023280bbae82986f399805434bb072c8a27a2dcd5aa62f065bc58b0621fcd365f6cdbf4d57d577d91150301fa48f182f87e8dca7ce45a7d64845ff434d1bab0534ccc83aa0974e88b38fc2508cefcbbc82135b73b384c80eccb8a09e2873cc07129021d81ce129a9df65e613410af950197dbf9afc28edc4e65c3e84da40d2ef841b886bc44719a5d59db2c6dc776401c895e2b3c83783d7817bba68baff59470d6015bba8d975f0eb712f3b8902912805523aa71c90499de689d31ae44e210b8446f2484727cc491b92a8e8b199d628e1df79a28c561e5a7d882e30787d08fb2d5196ba61196309b3bf0c5824a3548c700003fe9913befe12223150012685e90720e9ec6bc4db607425aec531c4fa36086d3b9be391a3f04635a8077a447a16a6fd89afbb9a72d0d355cb0b22d562f43f59d4e37128b3e2d906c8ae23d0aa599c70d3778a076c1a39728f1d6937bd48b978740850566138d34852b63075e89a8e2280edba6f4ee8f61511e9b768e95c78d197b693b109e88818b486a9dfdb74b4c5550acdfbd5
+SIG: d298fcc9a8ecb76a98d4a71dfb01d276ab2d9670a95bab34cf1d8364516d1ebdb23903460215307125afd09c758e981a452da95c0ac2c0b958c6917e6874190d
+
+PRIV: 28bb81a17d4584754d52818cd0f1f21baa777e695844a15122ac05344dddc027d5f61d519944d13b84bfa7cd67cb0bea4ef2281efa461f22ade4ba882d11b252
+PUB: d5f61d519944d13b84bfa7cd67cb0bea4ef2281efa461f22ade4ba882d11b252
+MESSAGE: 92e84c7a55b0bea03e17cfb65f7085ce3f445b1542bae997de5f092a24ff243380286d137091a598f35e6dae1a1c648f5a494c819dfb240652ff908381f32d70bc513100aca16fe7220295b1c71835f16d9310a9d27a04a980ace297d5af3f7cb7c78b24997ccb41f54ecbab507eb73ea6a3ed470e49590509f5d1e6032a2605db87f4a9b9ec91602583f14e2fe1bdb900ecb8971196b55c0d433489f26be9ca157cbd56572887ba859f39674a8e0ca08f2dbb0f27073551d0b1990685178b1ae9e7885499143d9d72c8571d11e0d85bf58df94e2a74d9b6846557f9125ca0944ce5718d2cbae1672ba02b847c17a6f6b445634d2f0175a75cf6883c62e5b521c57141f218b2fb0994b372a716c4a217434beab75740b8e91c622187d03c85da001e00247312a465225f5d6af232064a427d3018700ded774b9026777a5275fc04754606c86600297bf7b71aaff8b9a746677a3662f3750e81b50166f6237000051ffa15868defdf090057722ae229964a4ea085e0dbc04ce1997722c5bb65d2b47ecb746fd83a9f6a69c81545a9b502f5e76d3130c5afcb1c9af99d918740837ce89d7cd213fef2fd062ce8850f69659e4ad327
+SIG: 9ce45a07dbd28d3f6f1b35630a3fd56f1d548f84ffb1c6ae64b21498ae38e596916e77f79905e609fb1ae0da36138a80f242122167068092cc605796c5669e06
+
+PRIV: 24bfd4fc45d5093585678101cf563ab8011fd6430de155f2a425f0633ee3b7cd9cf5c5fc0ccfaeb28a08ba67707b18dc84ea0698ffbdbc169a09c28123e6c2ac
+PUB: 9cf5c5fc0ccfaeb28a08ba67707b18dc84ea0698ffbdbc169a09c28123e6c2ac
+MESSAGE: ba54128f45be2001dbb060d5dcc47144997415d4294f6eba8dceba4f6cf2234683c4265f88032205296e9b27d68506232d57b688407648f87ceb342052bde9d0065542ff1715c942027e67482af4bc278ff71966fb3f62a2a5323cb1b4bae1e7b8fedcbc73ea05b4076421b0b4fae8bc3337416a17fe124e7ee465ebb38d8792306429d8279a1bd54c37bee8f9c85eebe3afd1f64489d4e53ac5f50657bb6ffb97120744b75d47c6226d5a9c9c264ee3e6a6ded05062ca1006669118454550010919c2633cf086950345e514af3843148e5c64352e69037dfe60d4a8eab3eb8cb54bd39af2f353d5ded2e2bc8b11c09f612e128c6efa41f6eb2c958087be34c6335a43005d11a9d3b5a529c2d1b0642f77afdd8c6b1d6fb2a9dcb65f42f4eca8ea9a054058be8613667610e3eed8d1df0739eca171954117989d1b12189ab57904aa960b0ca85541746385efa985be9d97b5a9029989a9c71498dfabdb813681f57e276b64db491b8f082a885145469a531b7f9f04ca0a2c2f8dff20ccb99c2861f54e5eafa962cc53eaf18d3d5e50d337af485f19975f05930700a8a7253f11f184130d0aee70969d96fe08f216951d9dced52388
+SIG: dc935b60fde44359af8f50ed7f919f483ce3f24e2320c55ba92f3e7617c19bfb54701903ff183b42cbedfef0875f42b12875d36a0aeec73ffd09509d92b28b0d
+
+PRIV: 2fc2f9b2050ad7d139273e93e2a0451c7b5cce57599aa6b08d3edc5bb07590c8ffe5a17880d718cc7988c2fd9825b03b93450ac1deb8fbd1f1bf3b8f87805954
+PUB: ffe5a17880d718cc7988c2fd9825b03b93450ac1deb8fbd1f1bf3b8f87805954
+MESSAGE: dc1297990cc027d56d1fee265c09bcf207a9583e6bab8d32478228e0bc305b9818154c338ceec34b04c4ade7ac61dcb09bfac8ade00d1f29de317060b8a4daf1987de409ca2c3fe4380088073ccf485e9a69516b5bbb4130f20be69b2dd6a9b465159cca1ac88b328b80c51b66af7f4c50f6228772f28734693ce4805a4163dff14b4d039811ee3fce65935444a6ea9a72d78b915c9c3b766c60b7e0329e43c9c57ede94b91525ce5a075a7297219772ef3c029649b586a95a73bbdf16d8fc20368de4ba44de1064be5826b376be31a86ca478a52efb98f1fa333157719bd6e0da80ed68d0efeafee5a13bcc3b457525258f1f7e031f7b403a461506927b1e6c7d4a0c8d84b5f3dd0eb8bdb13edc2b514a81d088eb077a52c8a831861feee8110e41a325dce206b2d67d25f90ef57e0fde709f3e5a39c04eed31e57c193b283e2da7279ee3f1eed482b3bbcd373902c1df811ac33e1de06429e8f8443f602019650bdc2ee8d7f650036a7a22b8fd88517511229c729a3269b3a3e8fc72b01b5a4b3e33f5272f3ad21629d08b1f717935e9e104add2f0f2033432bec82e2121d98c9c1a58e0daba25536a1be8e5088347f4a14e48d8e3
+SIG: 7aff162a3c0d28dff41715a974af07ecac2132fc18bc43a198fe664659050da19ae22758d52c9cbb94f1358bb02610a8a351c2116279e7245adf69675dfd360a
+
+PRIV: 8afe33a0c08aa3487a97df9f01f05b23277df0bb7e4ce39522aec3d17816e467d004370e6edc34b3e8818667216f5b226b0ff75a58484c8616e1a866444cab57
+PUB: d004370e6edc34b3e8818667216f5b226b0ff75a58484c8616e1a866444cab57
+MESSAGE: 86fb741f1b9708929195031aa1645fb709a8ae323fff85e5470194452e11b7b1279194b5e2427ce23e1d749c3ddf910b017e4f2dff86dbe482c91bd994e8493f2e6824bba3bc7d7a845f217ae9760b3cd00226d9ff2616d452751a90c3d0d3c36d4ab4b2520f67288171bd3a34b2eacae8d44c1e153dda1f90bcd3595dad37713b8d340156ea90a4e135951ba7169ac175578b81e97a541ab9bfb76328798d7d631c14df2ad613e9c6e1147a0e84062ddba035859d46bade5fadd9b32b43dad483c6b8023b32391e51ef1520c68c6191326c494423080c623dc4ad0aa074748d826c29644c38986a77002f0cab9068e6c9ec73cc2e0c584b80e0bc375721f7a8fc35317a5e240e8c66092fb6305b012c70e17aeaff13386d5e28d06430ca585b0c85b274e7fcbb63e3423a982579e5a64a0262c41908e55dbe43dac1e5cc1bb7298be428720a12e3b072559ec2675d457aaf8f13252e28aad63c1513f5f239564d363c8505ffa4e50f6648c1cb82bba852bff0acb030cbe73f059dd87bbd7318c5586e708618a4f4c9f3bec3f4f07c609eebb24ba878c6bf1e4f2d0fd1450ab94e31755217786fb15182760ffbe5a267cbe998a4ff90a2
+SIG: 63a8aeac025f2dde9a73286e56c2d62dcb79a241ba0b2e2dbaca8752ed2fc8cc7ab8e6600b67645fb5e818a4e82c29180a6b2c3f58d099cb635ce52bdc157004
+
+PRIV: 6dc7ccf329378e8131b6defcd89370301068946336b0b762ac5ea51487dbd39e04e90d275e79df5f2b6ef4a31505aac05a69459baf2c581b3ce3db29f0f1fc14
+PUB: 04e90d275e79df5f2b6ef4a31505aac05a69459baf2c581b3ce3db29f0f1fc14
+MESSAGE: 20cebbe98401ac8934c3e65a5738cb0ec0cdc75fdb09dc96312894b187c0a46d2c38f4855be3eeccdcdcc56d926a8c08ce6e748e2a858f53532e7e5fc5f7014c8c6f86310cc26efef30ae525a5157940ab535ed8e403112b08e35e2bb3dd91a9ae8f772d2aff37d8c40d2b5cc887a6f15050a0f5bcf0360c3a9d12d5918655edc3c13c86ba6f4a2fa3bfcd405ed38f871cf7dff0f75daf2c321084ee9fa81211adb105b25c2288f0f2f7f93ef656b2de190122e7a4bfd4a1bd9893a8485b509ff0bc46cc961051c1db5a12490c7e741922ccc0a665496470276f69c7b77098c1e670af6b9f851252996875eb8035a817fa9be07f2be0bbb12025e0565414c817e9421ac700373893862f24cb165f9a271a64fd2305c6672c46767f8f075be5d2d4079bfadc3956288b0215605311b5bf32f0037b7c5ad502013e82ae3419d9d8f39c545b5888f47106c94d5fd6084d26034a99f5dcbf26a84eb4ee149c62a0410d8c707b1a9b071f74ed23932585072ce6cbd33d4d54ee917916f5dfc64d26a498018438b455739345dd60ae0f4750625915cc829ab6822d6f05f6d2bda0a7bf5601e9a2ed6de960371d17e6f43709c9678ca743adfbdb45
+SIG: 04509db003a1a6ed3fbcec21ac44ec10cc06d79f2714960882170316275df80423a1c1a112d881fc24d2812526079058aa8b608bfc6b5e57632240c636d6eb00
+
+PRIV: ccae07d2a021fe3e6ee23836a711b97b04e0a441f169607572731cb08c269488a32265e5328a4f49cf06b467a98b9f9d5b997b85dfb7523ca6a0a1d627d32891
+PUB: a32265e5328a4f49cf06b467a98b9f9d5b997b85dfb7523ca6a0a1d627d32891
+MESSAGE: a4bf8297d0dc5e4c92bd00ad5b9c09b1238b503d619116ef74260378349a9282b41f3f4676a6215e3ce6d02238480a96043b2942b3feed12620b1fa97f7703b3eb683c1601bd2f51825c450df4fd1f33b0bf9c23c03223789e06e24cf136d3b557403a66981f4b777dcfe890d2ba96da4a4742aeeddd6a611d05fc215694a5d89a5de6760b1d9415155044c049cb02291a1514faa2e77d2ae33d44585bdac6365bf481d9c97833937eab636ed65742a0d5973b24d54089b2daf084d5414765105e4eca14aaadd1053338a8470505232e4ac633345c5cdee1e4653d1d93583af11854b1d9b65fc20281838c56df1148f35ccf9bfe2f3f80ab73f5b791cbed2d920644cf0316f0cb5d3662b9120647da56afbeb47a952953bc1a37de857e4b39fd92b632b85159f46cd05b6abc2338d4632d48e9a178860de8f65d9bc23f24507b7c5629e0bdaac067c476c9c3941d86f788944d744852a61da716f95f3b04f0783a562941bcdda439590fd186b2a8ebf19a5a7e4f4a3aaab7a87a434524fbc9799c9931eb8ce4e34e99b608cac94ab7e74495668df136185f487d9fbcb6605ad725345403ec57f3f6db364a87f38fea4b4c271552e9f2e4a1be
+SIG: 0eec754105447f97d4a9cd246c7eede3fd069018f0d01a41dfabca3e90a741835ea4a9d682342267b250fc1c8c547c89632d9f689af536c7929004ded0d96f09
+
+PRIV: db5d5f41fddd6768709747ab8239bb4f42a31d34b4fa88824d94bf78d314926403858ce6b2d24079eead66ca0dfe772ecda9af4d46bc9b5edfdc286b95fe9716
+PUB: 03858ce6b2d24079eead66ca0dfe772ecda9af4d46bc9b5edfdc286b95fe9716
+MESSAGE: 67ee03de45c3e7030db5246ee5b51bf298bba3e4d0934937fc12d9a629604c53c070e30d611999a9cddaf2d9acda6a9f67202b352369d48260eebce0e78e4d5ae54f677521f84a7be0017fab278b2b57275efc5fa57c617186fc1ba49edfbd3308634878d864f2da1583ca8d56ce9fae77c462039abc32d0539c0a60b7bbba5029e9329d275683d9c4ce77d0b908ade98b0e32b4420d9aee2cc10e4be922f9572582dd8967141c1d402e215f20aee0a890e2368e406dea11bd11177f2e038aa2f1a0dff51a128d955d5e5f8d5d0009aaa82440a96864d6c697f910d1df230f467f0e02a2e02bf9e45da95f255410cc5aab8d85f449a5de99aabd44fd763ec14629f3dbab1a247bffb7174648e43b9fb1eb0df5e4109b7a88e05512b20865bad39f9ea79d52f5188e7ca5194405bfb1a09727617f3f6c88192008edbc0c6585dbf261f149dffb593d42716e5a5777f5462beeb1e9a56a2c76e6cb735117cc1183a38d1e00b303d174aa9cf5c731b2c70edd79cc5dc96f4018f1d71d7198bbb7d134cd2ff8c15f9a04280db26a8fa9997eb86b133c022eda15d8ad5e77cc9f62615960bac2f9bbc3ebbd198f72c572b97156fa7fa229a98014e170
+SIG: 5b3d0da7102355486be4d69cfd65886c9d9c8738b293cafb23b2104bfdac8d7d01298eeb18fde3ded6491d41b419cc663752c4e67dbe8986833d20e4ef34180b
+
+PRIV: 7f048dfcc2650cda59491d4ce2b2533aecc89cc4b336885194b7ad917db5cd1408001b5d40958bcb270beea9baba3387e3a4b900fc42275657c6c691a2e264f2
+PUB: 08001b5d40958bcb270beea9baba3387e3a4b900fc42275657c6c691a2e264f2
+MESSAGE: 917519cdb33519680bcae04faa790771ce7d1397c345f1b03dd7625776f3f195809932618b1c64acd93ad000ead09654a33d14f748b46b67aae0ff12df3cc163280f47cedc16a8579034e49884296772ecbdbb71ca29c166233533c8de54012b412ca13cc258f7c5465d83422f524e4c05f806313478319fd143cf5088e69837697d3615d80a7fa7e7443fca65e753ac1b11d8eff3476636ae02d7a20f4b2388dad684002f5ce957caddd2053d0ed533132a81ca19bb080bd43be932028cb5f6b964f008b5b1c1c5993bc9b5485b22bbef701f0a26a3e675ea31122bbae91d864b54d895afdc79ca58d4fe449213353b149f3143b5144d747c5b4697479ae68528485384044aa2c99ba4b17b184e94982269bde2de0b17705d0bfc46d6906a90edefe89195de6bb8f3fb6a374186c7cd086d13d1b3525a3994dc8020e1a00554ac8a82d6047c5bff5e7f12450f4865da161e1a021fd9be8bd33a32bb54a4ddf874512e74b5cfd3fc3cd9ac11edd878433668e3fcc782b97b6d905adb0ebec42c9254ac90f35822c00f97ff3f0c7c39ed3c7cb3920f5608bb45838bb242a52a8637d7cecdcf489fa183b45451c6c9fcbbbf914f5f7e6b223bcb4675
+SIG: 583370971d24652ad213c42615911938fa9aa3d9b7196940e6eb08151200c7b6729d1eff8f4f0904074dab3ddda6af1e4e562b7d6220c1a562683beab268f80e
+
+PRIV: 9feb3df88c494a99849c6fca194201477a2fa7564e29fb06cb44c1154e8cea3ac35628ca6ee28ec1c239ddc5bba2a9e09e4846816b143c74dfa2aec1f62551b6
+PUB: c35628ca6ee28ec1c239ddc5bba2a9e09e4846816b143c74dfa2aec1f62551b6
+MESSAGE: 95fb7581bd25ffd442c3ae38a19bea7349c7b7683ba6767e148f0afc15373f67c16d471781202e6da8054ed7fb9ee204cc0f63c210a670a5f9ced4294588196330d31b8e8392bef6b48fe3c92078fae11284b4c3ba20d937e2719de7bf67c00669ad23e61384ebdf8c6e60735428c084fe217fdb4709ccb6083fc0ae4a05273eef739023d34bb73f662dacdf110b6dbd3e74fc1491e8c96596075fae5c36aabe2a0a53052bf77c4462438063aa7bc0c50ab920c9eb288671560ca5ba7af44a53db2e2ff43ca56069ea5517cb214e76faa53dbda100003c4f6175414041be74de22ce155d2281b6f4035be39841afdb96dd89aa808e6865bae62d6bedd919d3e86510b9fa5fedd1977c4131b2b86e0f48d7215eb13d5498ca5d2368f81895ed855a527124657ec9539efe3b2499a3b0b338262f26340e22554c79f4fad2b4e419c70bc1a2107d206456b6368781be4b5e2c54da42d336040fb7ba49c32d752321adcd92986e78bedb226ceac50292089bb579027f702217745afe06a5be136b3998a3604c9ff2acd6fa3f3f71633d3102fbf03047c5486f84c4dc2447d863796383d55f08c981fd4dd7dc1cb72b8ba4435af6abdd74e6f6e6798f1ae2
+SIG: a1c2607835bec1a1d87872fd8ee488d0ae9ed23d49fd6786fc4996725e49b3262118babb4834877c7f78fbeac02df40ab091b8b420dc9951381e3bcda0670502
+
+PRIV: bff68955dd6ae0e8ba85ab0d0cdaf04a9f5befd5ef6014f49994a78363dc17f70ad9493af80b15f07a521ccd674fe9e5212a4a28c17c74f6605ffef78a4aed72
+PUB: 0ad9493af80b15f07a521ccd674fe9e5212a4a28c17c74f6605ffef78a4aed72
+MESSAGE: d8f5650aa3581c4d39bd1b8afc96c1ad7c4bf723426f9d7fabd1a5c8ac1d2fe54a971fac765e05af6e407d7269bab661b3432292a484f952c11095bbd20a15d77c41f8f3731a504d518ee10cd006c96ee57372de5bea348ec8ba159162170c63e970f1c7a3465a3d592e1d56c6540fbdb60228e340909646320c95f25698cd4896bdff58e2561e3b3d9a73b89747912a1cf467d63e41455fda77477f46fe6937bb0e79d92ccd52e82dba908a05a57c7ecf49554ab44c0b718e3bdd5fc0bf7070d9c58f860591c18bca8b3a9a148a06548e0f01602b1e6f686037c94ff732e155d52d5b0b44703b3d11163e3f56e3b9c1b86476e4dcbfc53fa05984e8c75dd21843cf96f9e494abbae7184aa42736633e3811aeff402b2fcb7d7f702e447241e22a58842fd6d0c03d33ff5b8c792200e173daa7b217e4b2f4433e6c020acce501b9323aa0241144434b08e9d2469139ff67342208900546200fd971a65dbd6db6c21e3ef9172abba1ea9ea2a249addf1a1eaa3ce11938b13e30913cd0dad491fcbb3285ea378b8ef9227f3fa80b586ecfeae137066f8448acdfb78d6d3e9ef4a6b362df4241ad9ae253b8e1597d656e000cea447a02fa4933328609bba0
+SIG: 9319eef740633ada1af0e137644c61fb3e11ba4b01d3c6f25392dc9367872a23be56310d312efcb91bdbab78a75e576ebe9081972415f562db41baf5e2338b07
+
+PRIV: 1ba919c066bb56e640c3335968e1d1b5bcc093383e2d7cf8b5fff5c61ec47a77804c90bdc2b3618b01f075e041fa971b83c5b6cfa3b6b3974f3fa43599beacab
+PUB: 804c90bdc2b3618b01f075e041fa971b83c5b6cfa3b6b3974f3fa43599beacab
+MESSAGE: 87c5c75d8ad07d52acd781d1bb95f78c70e21c2dd66f7aa44234152f98234d128358a8aee98ea903a77b441db1447ae6ff3432ddd4570f7f58036122c1fdcc93cb21573739c19ccaa411508e08de2606f3d8f2db89df6a44a46133d57018462627e22f57ef36d1de024de3d4ae41b752df4821155934b447b2effe512487521be0356832a74ce0e2d8301b79f93175e8b6b961b1df637d8acadc884543c6864f8025ececec7c6e4fe0fecfc40dcd95e8d6ab93ce25595384436b598b73c74b03d49ed5002c0f858cfd9d0df61ede937cc41659d6708b96fc5aaadee109e2a68846baf2c246dfcf3d27c28bd1371e35fc9412631442ee75f38c6e4958070a74f6e6a220f75c7280eab4737d97e37882f3624811675f16caf60cb944bce92e75884c56483c61f26b6371b1b51237621a06543eb4abea7becc4fc31dbb5475b3deb9bb3c8992387104830c6072afe1af244bf681a40329c9b37772b09c5e88e78f7dffbc04549ffa13b4144ddfa538fc4b3300540ad830215e25f11446d289f33122c2c880de3da71c453d7e88f7ca4ea3d1255e82f4bc9e5533dc401c33040e16940b2cf9cf21feaca1c2c6c33337cf75e1884b483bf801536d304089115a0
+SIG: 503eb7ed6de1b776c952f255bbd4bcfb0e48bc70c2cc2f1f72bf6881479040c47524ec542ae13f6005ca5016b58b736a50898dd0569d4d38ad298630d68adb0b
+
+PRIV: 9b36247c17710e95261a7d702f57fe81f2971117a50c87920193b386d494ca9729ae39f273e35fb3f611da091600650efbc4fc4d1e7b4c76aced5a83f82634f3
+PUB: 29ae39f273e35fb3f611da091600650efbc4fc4d1e7b4c76aced5a83f82634f3
+MESSAGE: e8d9d53ba27e98edd55df3c6b245eacddc8a40e3efb007bc918ec5a869178a170bb4a635b7f8f742e37ad45d14a74344a6b522830a522106eb960daf192dc1e0fd70f16160e122516892d0e2abd0d4ae0f0d2e5adcc99ad55302e251b3e7a4d0cb33774a497049905c33de1fbbc1ad2b6c645295fe416b4d12b232efe0a33cd2ad8732eba1c3cb0eaeb0b2a57fa03ec567ca29210bf6ff9542a766f496fe68058aa983806cbe7ab10a47920bac8248818e54a41551c9a0959e8994cac60fc868ad48b5a24d5f24a7a5a3fd90b847e817ad3dd5d0d6f8de2d204f642483bd53585a92ef925415a9b38fbbf07fc0f35e707569cf488b205453ce5433eba6fde8781af72b52bfbcab85ead385d9d3175e21ad3373ad535cf0e357ed6b5383ef3829a9d5095b87dc9aadbe0ca7abadf33ec3b6ffd6eb94afdcc12e8d66a6fc05acf97368db0f69565dcd8fef4d1e49d7dd4ac053c218f5240c812d4ebba440dc54cacddb1c39329e5bd0c3c80dc3259a80f059f94679aa0794ca0115cc62af25e124cb8a9d4160eace6d22c7b1c44544f81142a19ebb02a9bda6429c50e783db4a07f0219e857c8d3c5655a582831c8eabc3f19b59ad8d2c714adeaf4039d5cf70
+SIG: 035970a672e93f87eb42cc396f6ea7e1b3dd5c5951572826d1075a15c2d7e454df195b51aae8dc61ef7ab895485f64e5989573d98a062e67ae7356fe5c9e3b0f
+
+PRIV: 6fede7396c462033189acd23d2f9d02b68898d35f3a01a798fc24d488de93a78b34062060b2c20076a98fea939b3b3a50451a5f49f8351c0ad7591dbbebb130f
+PUB: b34062060b2c20076a98fea939b3b3a50451a5f49f8351c0ad7591dbbebb130f
+MESSAGE: 5abcc14b9d8578de08321de0d415e3d40e9de31e1888137475ce62bc6fbee8fdd03b9d47c7b88bbceb804444490bf6a3ccb7a273261e24004ea67cefa3d5d173576d01e38f76c1e0e515083c97e79914acf2be4160ef9360bbe986b36e9ff93346b0e70691d934e47f8a503fa933ab2a50426947cda8e810c9ebe3b36982f09aee6092739fa2358b613c7f129db0dcbe368bee52f2f7f1dfe3d2434605b5afcf256071717d924fd0803bbd0dd1f9555ce834dac781df4cc7aa19e7f11da9fb99cb9e6b9e1e6fb4f7e8dcb2236c28aeb6cbc55a130e03c1b17a991cca1b794e6c13732d5b0a66f6eba860ecb98555aa4c218d112b116bce238295de142741f687be0b2487f58ffc5c12a0a519f1e23793242ef857ed398a20699d4351453fc2f092762abde34f4da2dbe0ce2aabaf6bc4c0159f3fe1aea16a036f7eaecd629538f3e0eed83c9a4dc1abc238f90daaf489fd61b34d937b6f4607a788baa82061943dbab26c1d384d8d49f99348800bf361f871f5d6cda18f689918cec31ad158f1863d13ffac5405c162c32de06e32994cc4106f95bb4fffdbefe7d629ec7797394609fdbfeadb46927370a11fb38471540f951b93c6eb238668dc006c21660ba2
+SIG: 88a83e2012d209ca03b8ebf6de5bb7ef4ccb5e3df5cac78954aa694930e4de82544ef5083c4892db9f05d77bf63f4fdfce15a4d1c3f85bae8077062bec0e7b07
+
+PRIV: d559580134ab050aca446ea7750ef6b371d92d7645ec7635fe7851100bc4e51ede5020cd21a8b32339decbedff24664d9580326327aedf09c5ec6b3fe5405226
+PUB: de5020cd21a8b32339decbedff24664d9580326327aedf09c5ec6b3fe5405226
+MESSAGE: 6842e3190a110eee96c507d4bcb4c548c3a0ed7b1a8ed77dd93b38613b23c73e830b205e62651921ad8296b08d1e1008ad78f2996e3c7f38032e467cffecd77b8525e243cec021f85296afd545d7be1a62568bb0cfcdb90d614ed798bfb7efc655326816a61082251df01613aac88efcea1e0ea2961b8f921ebe1558dee83374a0113a78c55857ce2055bb2c48badbd3d8f4cb19734d00d0604b619073020d72a99a1923e6160a09946567fd4bda66442ef5a7360786d178dae44922f350ce2edc6af73d1bd80dc03ec3ca7005f4109d10c6d4f7d8fa61735110f8dbaedf91a0bad7d7fb5c04d706373c15c645063ff4b4fbd2d559b0afad432d4c496cd8abfea286fa675dc076726ec522b3a3c2f47aecc539f48a792169c4cc8cd41cd2cb6b63ddbc19373ac9691c2bc2f78f22603d5513715a16d4574e7acc4bea6dcd8ca7f19865a49d3664a210dfad290774b10b7188f255b3be4dc8fa86f8da3f73a4e7c929951df30fe66a17c8cee23e4f2ed2063f0b02ab40372cbe54b9a708df7c48a06566d39b19434c6c766987b3ebb00675f44c4b3c1e9f4504e7a9270589c0d0f4cb734235a58ef074cf9decf3601aeeca9f1d8e356cb2db5fce79cbc36143f34b
+SIG: 6fcb1ac9290ab767d59b598c9a24ecdb6c05bb023ec36014a40d908ef0dc378a4528b3760d889a79174e21cae35df45d427ba6ea812bddca16e35a69b5e79f0a
+
+PRIV: 9d4ce975547876636fea25437c2880c9aa8ee6b270d1b2da197c8d7f95e7dcccbde4993c030477c35890aae82bb5087e914e64b94ffc64e2d7a5a7c919e2d902
+PUB: bde4993c030477c35890aae82bb5087e914e64b94ffc64e2d7a5a7c919e2d902
+MESSAGE: ea0fa32a4a288811301b9ee533fa351fdfbf6bc1d0555a7402767a3a9198558f74bba7031857995b9f326226f1dd5df107b06342203eb8d40c5f1dc95b4f3f88975aa24af8769e2670c46671bebb7a0f1b7568729aee477e8988af9c749f3202708171fd94b337ae67ed21a6c44174014b0b0eb5ba71c277978d488c24c4a7841309846b4e30a4fbbcfc45078d7e14014114b1ac64f7c33c9ac25ea5626c2c819fbaa2a4de8a2bf5f1365d6b70407e8094f99197ce1f0c35e11a98fbe372414ea2064a3a12d1cd5c8df8fc0e79f5b770b58f477f91976ca0139895120e246baab5a026f2d39c687dc0788334b5c626d52cdebe05eaf30864b413eebdc5581ef00d439276e52f479c9c05b116395826b60490b3ce700cc0027f61e46ca2f6fbc2c9de2e800806550afb06d4a08eac7a758e24582a4d6d428b433d365fc31d4444607afb64f15e370794005a3a2244e666d5d4c38ad2009c769a51cdbf738d235942f412d07feeb73b3657d0b0c91cb5940bad6a706e14edcdc34225b1c1f38b1abecb2adcaf819155a94fe190fd556822d559d9c470854d3a43bfb868dadd6e443d98ee87e4d8284f5cf3a6dafaf295b902836c640511e610ae7d0cb1b1d3d6079fe6
+SIG: be17444cd465a87a971df84eb102f9c7a626a7c4ff7aea51d32c81353d5dbc07393ca03db897d1ff09945c4d91d98c9d91acbdc7cc7f34144d4d69eb04d81f0c
+
+PRIV: 0273868232f5be48592cfa05134e8d5554ed1f9a57bc7e3982a330c57e5a7f3af172208782db66d466cbe4f4417f6fc477b7349f2a98db56c03a47227546bc5a
+PUB: f172208782db66d466cbe4f4417f6fc477b7349f2a98db56c03a47227546bc5a
+MESSAGE: f7a1d4614cc64a3bc48f00c6276304f34d4dfd15e0617b93ccef126c5c638c9d9953aabb7df42df4e0aaa7eac96a4b38c7ba758d860c90d05e3d14e479e545f319b0e5a85ad8f0991b43d6e49c24fa060e3e5df95c98d9451ab833e12aa97f404611bba359496265a6db11917d0da5c6a702d0b102de36dd0c98df5b54806ce626bb96374475f68a6060eb350a7d2aae3204b3dfdf9f1e31be81f7170f8a1b9385413ff8f6881e10c1e8da4c88afb50639ab44887aca2abeecedf110d2958c13fd3390d1b96a762d16ce196920ce85f6c415bed545b1445302a6f001eb8d00e97c751887868d481a0b1e4dfa04b6f761086ee8e697b019e017104bafb98fca242e334c6f18f1db5b6f295f05c559361c6831dabc42c2110703f9d1f64e12ddf26a8679854e9f8ef8479e1f12c35447aac02ea7f242e58632cf2fd063fe665070445b80f3dc6a3303bba96e05fa88eec201c5c2d00ca81b8da6969d0a4dd0483b3477d325a71facd6fa2209b48cb4f6525da73c9c05b2d9789b01448e1527e56a09a9bc6136d9837243c2077b925bbb933f8fb1daac963398c5802aeda3bbca8ae3b8f4a9a871f7ea8e2c0ce898c566217b5c06ff55ff9f4fe78398ae7973641eafb521
+SIG: 15e8d8dc7d5d25359d6a10d04ee41918a9c9df4c87be269fa832434d5301db022481bfa395a3e3466f9554ceee0532a8183a0d0550e7d1abe99fc694c6ff9301
+
+PRIV: 336a83b55abf4c02e25e540329b5275843c2ecb8df69395b5a5e241bd0d8c10ddd60569844570c9f0a82643f446478b5ac6fc542214231a7ca656a92b5fdaa54
+PUB: dd60569844570c9f0a82643f446478b5ac6fc542214231a7ca656a92b5fdaa54
+MESSAGE: 9afee8ab482010e29264b406d9b49453d1ce6d550939072182863e4665284ab05d86258e0623b18754c4785238f697f075adfb9e1d31a42e85934ec071ddddecc2e6c2f61334a79526788b4952190716906dde17fba556eea4c8b59727514f6f5615a19ca36da358fae6a6c54f7f4b7a929e31ba7cc71bde7882fa9ffd87300136409caf3ca64eefea616aed58da5dfbf28b668ec1cccffcef6e2e14f8109e9cbf76cfa414f91ac00f48e93eada385dd3d5c16e1a39ea3dd55c761fca361b428f516c05e694fe5c3c345cd94457187a8e604b200a1a0f937ae89f4d6b5421dffcf7ca15f2e2c25378a4113233f7613f4570aa4b909a9135eae4c7b9ead458007ae17126a11d145258af9563db2f7e8925431878b0eeca8affc01ac5913bf5bac4fa3a857c54cc8906d6af77de6b9326b6506151099e87e99b1e819c6fbe082688f34b803d588e416d853169765d62f7e0bdf72c5cd66669a0335562336735e7efb734a2fada327f858bec602d0da08eba4479e7f6dc4def6e4ebdbb730ee91a33445cadc9df52c825ad36149cefbc51ab102033530814bafa7e87961b06367ff896f08ae334a9b1aad703da686706c11a04943ea75e12992dcf6106e372077cd0311029f
+SIG: d263f56d59cb9b2896a947267c2ed78a945bac5abdbf3c14dc3ad092b2308cb9315c464942a0a20b2024511d766e85c936499a149cd0bbb209150a1643265200
+
+PRIV: 88409172618b490393db27d960171cbc187eaf4dd8b320b3d2f824980043718fce2e7c5839ef5632a123dc373dc14b1f0505766e9675407604ca7cf54e8d44b2
+PUB: ce2e7c5839ef5632a123dc373dc14b1f0505766e9675407604ca7cf54e8d44b2
+MESSAGE: fb3e82f11bc286267e123817ad8864e077d9f7a8e7a163ac7eeaf93d55dd111de8083b66b53ce7bc771fc5071a2d7ac2f85d6fc6adcfcec446e16aa1046df37209ad7a29cf9665b439a54d6f8d942f89bdaa56f2f11260cc95993038b0e8fbdb3214f142e6c90b61a1d2b142076206af30ac35784a6dc15a1e79251a8c7731a1c53978038f8d76d70c6c1cdf529fbdb84d1507dcffdd42873dfa6a8fe6bd6f7fd29c80e4b2f933d2b6c9e62c9457e665472655059b63b618e2a9a8e5b9e41c3646173a892b8e6d4bcad6a62a6fccd3455890b58ec2681a95cc9776a9fce83c54a9ef312a331959c7ef3f79ee576eb7b79469c9234b1eaef609884708fe4bb0efac662da871ba61ddabb3fcbdeb8f635657dd9a5d7311e639a824858b9a9868d3f9384da612c7f2e771a46bd2624c99ea2b6ccbca996c1d9c375554f2a551619ce6d5e6e4d6b844a4dbea83ba732331fcf46572c1fb0e257ce1041b265df02e690a92814bbf3b5ecac69ee998766a02b0d2f908b3c15f952699616f2c07d589198989e6056c16319aab6cf8771902c078046a88b2570c13bc5edeba2ed1e3ba131daf94e6891862bb3de7d1063fe405307a5cd975693e9d58e17c690eeef4a2603cafc68c2b
+SIG: 93b6e29d63945d5c427387d006c7f0b01956a95fc0436ed42b46d0f17b5bb193ea8c0ebbf3d6d13bb539e35c91f3f0f9fa3414a0223c9060bac83653c6fcd906
+
+PRIV: e571189b5cd9e788302de3919d850c227dcbb615022e568bdaeb37ac5b2939c5edda890f42dd5fbc7316a5fadfbec38556f23f51b8efd2625437f6b5069f1ee5
+PUB: edda890f42dd5fbc7316a5fadfbec38556f23f51b8efd2625437f6b5069f1ee5
+MESSAGE: b62c867ad6227435bfa6dab830684e38d196e1f861aade0fd6a7699b6d60901fefb2d799c35c6f3d8bb94deee834403981866bab84946ae9476c75e9f1d3602b42cb2db437bff33a775822f0d6a257d4b75400eba5b8abb314b71fc6b46f8a34e861a9a62abf33de8482f63f9d7169e773a2dcebee03705dac117fd1499b68e7414f51ff9437f253a1d9901ec3b0bba86965a19383655487b58010f804909de1ffb2212c0252ddd9bf2a56ac46bd59c0c34dd59e46598b6babd4e5f3fffde55e48dab0398c22af9e26baddf77275e5f017b35a9b8f8435f9631936b391cb95d7adf35d1d8545a0fd066412d508967bbe9a20245a269e3be2777117e75fbac170dba352be69b254d353b3b2cb3b7e21b721aa9fe044f8916b4b2a6f8c28f8abe66ac92b91323ac73afd93dfbeeaeef26d19bd9f67e99d48cd2ad2d3e55e45d24d54b50f44a39b90e242ebe9b42bebdb230c470bdfde1bc7721c3120008477393dcc2e15fd22b251feb0e18b02883c078aee4fb760655a671dc7b8aadb9a562420a3c2efa2d342e1e0099d951b42242984f594e6914fe282b1ee128735984ef93a669e6ecba26c9fcb9f09f09256645617f1392d35908917cb8d29e0897c7503cddd5de1959686
+SIG: 7f797a31715d7c356f8f1f783700aa9974bb936d661661ad968c7cde1ac9e767be56a2dd49b9230e90110c67c0ed187cb7e75c3053ece844984d296f0d85cb07
+
+PRIV: 371744ab63c115613929a343709bb019b7357dff72d2a149f1d0f71d3a201efee58abfad4a13859f0acb05d0e47d59638f7b1b4936100b988d61e6e70e22667d
+PUB: e58abfad4a13859f0acb05d0e47d59638f7b1b4936100b988d61e6e70e22667d
+MESSAGE: c219de1e8d7ad8df08c49377396fe7c1f2d57bd2170633a00d708faadee180ceba92849a7778506cbb366875bf9124701894cecdb3385147d0671843922a649aff7c435eb5a9c74927503072d0067978716dc80be1545a2dbf5a1c38536e12bd7720c1965d3803a4e8aa55765192a13b705ca1059ded0e806362fc5bbe6c76a1c9674bb853790f7e90af00753e00436da48cd082ead64fddb689890162082f8482924f33acd604640f69927352b43f64402d27a883fa6b72aa70d241dffaa1701a25cf1079358260793875f76a2978e9f9f9d68634eb3f5f01bde1ce49e5921252f949f082795e4eafed7be5b49a9f95edbb4a13532e3f3b3be62e2652231253a20c1d5477e8f4bc57ed76fa19eaf03a11bba429b6496ce76246170e043bc14f2d2f703d968f1deb09388715c37cb4752da8d464e348e0313c8993e24133a7c545284e3c9c907d01b260c4883f9cb3e3dc5b6f7fb6d75536365f2132eaeddab570e7273afac0bff5c9fc0b820f2078e0336052e1fe7bdec86674d0998ec78da1c3f34751f886727695f35eca1304b14734766ab05c1186306ded9db3eef65d3c0456cdae8181afee04b296c6722a88c7ef3088d26f7fe74bc89cf5285c688f027b7e68600486af
+SIG: 5eae4ac72af0174ab256527b7cd337a0e5482e615af068db21dae35a64640742604df73fd4ca02ed9515a5608d73195230fadca7b426f02a2fbfd02061af3600
+
+PRIV: 498b6ee6492d53231b3532d193578ba75d6a894e2e530034e21ab8ad8d2c0d1fd124665b28facd2d17946a04dfe3d129a4561a2b24eb326d84b62b422e44dbcf
+PUB: d124665b28facd2d17946a04dfe3d129a4561a2b24eb326d84b62b422e44dbcf
+MESSAGE: 0498a59b87cdae28695547e10863bce804d97de0ac8008f3d5fb652c1757419fdc9e0f9736f4c59a34f21cfc74599fa788fcc10c6730c7df8c3d2c1b6a786d1230b65585719d1cb5c490359b94435d6dd671f54d6e9a19b9b5aaad7e0f233f8797df997828d88cd92ef089ef7dbf1e95277894a2f7c2fd0c8e4dfdfa6d3d14589ff01916dbf9ddd811c2f5e01e94298990a145a6cfc26895614c7c963fef308a4e3856c32dd3e359bc56d2cca496ad199ff1a568d6430ac5cd208e0e2d07803ca523e0d813ad3733ab50bdcadcb988aee758ea50439bf38ee649997604f151c602c82900a8205d8f6f670c8684bf5abb5f75ff29a37eb9bf8105199fbbfb4707e162e64c715270f853e648b0aa26fea0f6db562896bf424a9ffcb292fae85b76cefb8bd5a4b3ce1fb39bd2a50d0c9e6d933e167ff629b8a494f2a9b774eb303c781ea02aff1a8afadc2465cc616968015ed6a5a33c3120b945ed5351981e32fb9fb96b2212dcf8fe9ac56e3cf41dc524f800631020b025919178ce074eef078d6842012a276efa628db54058d1eb5b5b705f1e1818d2df5164baabb0c61956ecdb8c706e562fc4fd64052870530ae425b221f89dd6f90dab882e763e7a7ffa141bbaa8bf7a3f21b0
+SIG: 112f5c6d3bcb3dd99346d32ad69cbfac3e653bef29c68a33f43231f66cea1d0a195427d6e10c0e77c5d55fe2794287ee32e5e22bafbbd8052ad3606b90f94505
+
+PRIV: cefcfcd1cff4d8910749279131830b1da19dfc5245f78ca68b8c3c1b622b45511d394abd1b4ed1aedf966a60efd3ff882140a7e56b428374ecb443289a9c7f00
+PUB: 1d394abd1b4ed1aedf966a60efd3ff882140a7e56b428374ecb443289a9c7f00
+MESSAGE: 5ec94ed06fc1257ae9c183ce56271207aca37a23fdb4b0e74ac9307a1bb112e05ed5a5d047c93109e2e59477b03378346422de36714c2961bb9736a513ca3671c603a68c2be7317b1b52a076dae2aff7bc88cd5eea0aa268faaadae539c938bb4fd4b6069b1945eb6af0c9e6c8aa5ee4a4af37e90c67e248e8d27bd7f9589c4d30e905651baf45364fa049957ea5d9b7146ca68204e5e973d0f1c91a1c4bded66115028a71114f0f4f851bd115faeb954e3f71a01470b2481a0098d99f9d74898c8ba0287cc7834155214173d1fcbafcfe9b08250384439476055883833816c9524cfd5744aaa259db7ebd3a6aa20b5a6546dadefd140668eb0eccb5f668db9fc62983df980850c9d19882a17550d5dca3542cd36003a0d03cffb04575a3e8e1d07015c7b30eca9115cd2b72e46dfddf6a4dda1faa2dbdc89000d433f6ec9adc46146d939f32121b99b28983d98b9dde8c3f6e5779f2b0700cb023db13de656e0aed1da2d5c6ba2652343648ad420f6ab9e55a97482a1a22b3bc2ee598629abad9547edb5ff790990564bd871f81b24b12f2bf8dbdfe7a88375fad9ccbd9fc0ba1d3bba5e3c4813c18a0348aad83fb1b82689054d99b4600dd1760d0dcce44757467bec1946406d530
+SIG: 7d83ff66ec79307b1c0c093fda3968a96cf6044f5c802888584018845e7caf2a135ac6f1677e84d22e458e227e4f930209919bc11b12f7aaf2b8c94302d64200
+
+PRIV: d107cf26f527db71a206e41d17955321013225bb20f93e12df3dc7399e720ca3186bf453c95dc0a2fd589a78e2c80040b3f6ddf9a6f8681d146036cf2146e8fc
+PUB: 186bf453c95dc0a2fd589a78e2c80040b3f6ddf9a6f8681d146036cf2146e8fc
+MESSAGE: 78eb9e13789928a74f360141728ede98389685c836b91fafbf1a7e8c19cfbe21bd3c3d6c6ed83c409ef693f1d735da3fa466497e19f38e30fba2a1023785459070e6e92c1cb7c9bd0c9ba61220157866c3bed2b01e6e6b9b8dd3f0c47c02f181346a0a9b9b5d3d7e18a94d6956855e16e8eaaaab71b10302f35bd8fb1f9b5847304160324926645b0582c2f2f1533a24281461514241db2850ef31c5763b2e3d4fb18fc6d8c1d7e52f7c13392c17e27019ff60008e431f1714370bc0efd9452a61f5c56488d91a185037f1f647f72fa785010d5d78f0a11587ccf66b8088e0e635fff3774193b2edeffd92d6e8a0321128ae64cdb862e631e2ee5ba0da44bbd589dc392b5a113b86a727a8ddb698a334cc668b39b1cde199b88837ca5f00f553f89c622834273641d39bc10c6a24e1eb42587542f03fc1627524ed6b749391f11028706c42364425b2caf20180e1b802c744b49b7bcd9bf7b15c23a0bf1c6965960d341554e1966b6ef82fcfbbe41d1e09d741e309254446777f13c29a67b8bdebc5f7f04d160d60e332e3d0441a0f2f7b192c3e2bdf6dadec2a424f88669806236ee04dea692bd8bb6f91ca0682ece349142575358b9b7be70600b3cb81e1456ba0799fdc01ffd68623
+SIG: 8071d97f324f10358f13ac8c61d424b4f300dd0419571c39e40d99aea5f03140e62ab4c97127ab33e98269966ae1d4557e459bf7f597b313f351a20122f0660e
+
+PRIV: af7ea8e41c8937a4ec475ad81371a171d3d0f9fd7519a04c751ed4ad8ff8fef915dfc71585bac71ef20f374987c555a3f2f07d6b9c787066c10d63cf06e02ab0
+PUB: 15dfc71585bac71ef20f374987c555a3f2f07d6b9c787066c10d63cf06e02ab0
+MESSAGE: 05f2263f0245ecb9faeb14e57aca436668308c8125df3116c4ee20501d0cde701b366e2b50a1c5edf484144ce16bfb1f7d26dc4275ea9732e264ba4d4a362b40275ba47377dbc332cb65e2f4c8853894aa878a4c175dc5b3b2a757ff3c8d7de660973b89dadf076e2e4fc76239b7bc752a229d44e000ceb667104cb0746bfcf59d69603ae7fc1bcf11d2e33f61dc497ec1b0bd5e4f1dbef435f2f291f30b00a85e833946c8b10484e4abd7d60bdbb1fe6dff5807a53bb89382153013b70ca08efc91b7e9fc5b5dbbb6af123b57be2e140fc471a45d89fa8284cc27e0a1fe771f55598bbdcf068d506dad0a592179ceca39ee9526f9e4fe47bf2bb14fb1486a677d4d7b99a520545676a0f1fa809049aa2414ae7b817d9a036e5c157886e8341d4e819c092a3b48b3606b03acb727c6c2217d0af30121546a94af6b49caa2a8c9b1786fa0c2a524ec7a023e924b5f8a89a53780c7f8781c5b8e869430caa0e6d0437967e3aed44f45c901cbcf1026fbbd4e3dd9a091ecf8b34f7dd5038e543dc7eb6ad5494efb145cf63ec0d355bb8e172f455d8a6b13dacaaddbc56e47de3cf762a1a738ef092f1436680467b5cd82e9e36e2d2b6842b3bd5dce77180ddaf0b643378e698599dd47f5cdbb
+SIG: c0f1739167274bf91831c74beb645af790459b28bb3f21325365130f409acb66df1d223759a9758e08fd7253737484e285a6fb47404abe2eba5ef249fd025c0a
+
+PRIV: 0c57cbfcebde10ede02d1cb01df360d41f2e66a50443d58b5d4f0828c9a18bb7c4d761ba189971b9462c61bf46a765f88e2ecaa5bf2211220afb00ac657f7ce5
+PUB: c4d761ba189971b9462c61bf46a765f88e2ecaa5bf2211220afb00ac657f7ce5
+MESSAGE: 337703243ab5b4e4d3481ee8dd1f4494507174412658a93988b5c30403a7b7ed8522ceb46fa1ee02753a874ef0675d397c575da0b08caa8cee3393784d0f0db8459837af90b9056df4e38e417f3ad2eb1a100ef207ce2ca6c610018021661e307099f2b7c4ae875991140bdd3f0f99ad2c5d55aacb84cc1cdcd579e08072b6951fd45ed289ac9ff7f0986ac88a4fbb9dc9203d9baf180c90edf937258c9d0a6d48e220f72d250c7f2c777eaa7fb9fa11d50a5798772f9fd976b00599f1f0276f3a2e4d988ae92125467a8dedb7a16f9e3a56e8d00662b3eb67a35b9b60e73bd935077ee238df8f6e833b9a5523386826c1f2917b1c3ec98e0a5fde89c48b1d446da5d0c885fef0e374bff30a997c7bafd5e743c85d0c6aaa6ef10a061211a2327c6d84eb747a56e9bf60fcd5b553b798834d0c5ccadb9d4b54e7237d12c679c193a287bb2f511cd4ee2a2d8549b44b21c11fbe5723381c6c5f784687fd90cebc5b495af9e414f2961b06a1c8433b9aa3292bcff4241c227167f8d1de054ba33ad81da3eb3ec6e40a6e26854af349540171b75d75fb9a8d12937827fd594d317b7a8d9f1c2fcabda56375568c3e9e514c2efffc3878363dcfad9fd95436b022e8772a88cb71e803bf90381962
+SIG: 8af7bbe01b8ab93951d16fca05a9c967d1c52c974bea151ea72e4cebaa20cc783bb61d8d69385cac5bc6d72dbd162beef1fcb5dd0e0a08b48ca0b9f6d9a9880c
+
+PRIV: fe7172278364194bcfefb4783142b79f59d5fd978b1e47c314d78d4cb3f61c8a2e82cce47910c7e2a79bc1f419dc3c3df54f23291fc8193e8258ccd2fd38d548
+PUB: 2e82cce47910c7e2a79bc1f419dc3c3df54f23291fc8193e8258ccd2fd38d548
+MESSAGE: 23509451a059969f2b4bdfcee5388957e9456d1fc0cd857e4f4d3c25a4155d5ee91c2053d558062eea6827950de863bc9c3df9672cde8ba741744ebbddb45ec1f4284570fd0aacd07ea58c581be2afc95ae444e678edc2a02439f387cec982ea3a44814a8a302bb3bfe8228d58de039debdf7c2a7eddb4e71ca474f94f7e2bd89dc65b1610733c91fff89bd499f40154a6198fdf5ec7ad3722d925b292196c429499075be0c5b6da9c090c0791a7019eb5e7366be6ce58ab2f04fecd9127c42718047bf47030691521312c0877aa3f36cc5fbc9caae0fde3945d2a868ee2502a3833208eb850a163cfcbf6da9ee6ad9fe067fe241986fe4436d6ae4edc61561938e2a33f4a33db63f69d3f1a8850ed40028869164103488fb795cd82ca067fe1b4897caa49a7ca9a80f3a8151fd13bbb7ff350e8579f565dc1c4a9ca938d27b15b3f858ef45d3dd78b2c358635356315f55a97528ecfec5d11a5b721503107faa406c17034e601474b3b60cf48692e269261158fc353d4df4274381357790b7756087b00cc79e3b9d28a3f2439febf199e64a8b37c91b5a4334e3354e8faf3a361e856c54bdaa43bfdcd6ee6c9f9679588f6069950832348aacba2bfeebacaa2071ddc7d77898ef0f68793cd25
+SIG: f6c2a4296b9a3407c6d7a5679dae8666b503d1a17eacf71df493791b8ff0c0aa8eed36b327a29ab7828f46f22de868b628b1cfd501e8599fa31693b15f61080f
+
+PRIV: a951e4e6ba9f1f0b354831c986942448faede37e11b0f247da2706dceef73ac730362014974bf75c8495c2e271e713d57384384d0a5da88edeea79279c0c58ec
+PUB: 30362014974bf75c8495c2e271e713d57384384d0a5da88edeea79279c0c58ec
+MESSAGE: 20577dcac89174885eedb062489cd512fa72863ec5438e31e95878b75ce2772aee6290a0ba3c8f642c1d0ef55da8d5bc1484f83bb9876c7a8c0b6b609b94d112a06fc83ce8d2c1e08ed6c735e57b244aad6ecf7075363d565ba47865695c8423510909e0a3db4b61ed7aa67a7471331e83a0c58b8220a6245f65661549c1a12d4c0d50c326fb94917cbd07be51e83fe8bb3e46ca01b0a260daaf1d6abe3703d6a925113bb4d57ea1a48b4c7dbdaa03eea814a4b5f02e1dfb545cc623fe17a3bb18e4373f5f7ec2fb5217d23e4fed54a772e11323e730aad7efca8c464400e7679055fcc125a876ef7b8b9de186e229a7abf191d0c56d91815f67872e957bfbc7634aac403576a58f427bdbb30e8c4b6fc6c447741024ebb503a5a9025124a4887f825a43ee940f210a1bd5ae4f6732d60f95f2b83201c4c6dfe279412d7502a5211f8f48f800db30fc3776c4ed3a38bb4634822c98a6d6dd3233be60e42cca45a3163cc84e9e8da647c0711bc4c6ccd65aa1e972c07404d103e74bcc31a7e2c3eea5ac9257ab428947ab3dd3fb153d90694a4073373c4dd9ceb131154fe877473fd996f424f33e316e4eb02b8c7513be6998e516cbba54d94cd0a435e0ffcc2c0a8ef72b630ec24781066aa5efb9
+SIG: 0278c86a15208d9be5b1e1574761861b8af72ae08d40cdcbec354e65a9c3d0a06b5fcbb297d09bef397462395986c3093eeb22644c003c3078178cdf674e990a
+
+PRIV: 38a9b2d49ba8b82f301a5772cea0efc2218455c8b218b22cbaa2aad2d7ad3b359df5ea1f78f810a521774602bbba4942f0459238966c8bcd21900afbf3d84293
+PUB: 9df5ea1f78f810a521774602bbba4942f0459238966c8bcd21900afbf3d84293
+MESSAGE: 1778167c49b3a44d4a5ba838b7388553b1e13d36ea4f86d30242e1a822a3bbaff5cea63e2ae2a4635be236fef2b8135d14fb621c0bb773c9c17753f80926eb55d0f115bd09a885d844b818c9f04489a331bb5e032b8e58cda36949c5a8d08b55bb8de965e1f90d3b9cfeecfc6ad9a4ee5cb4047e9450acdc64640166a8c069ea849aebddac1ae4afec91ddd17fa5553fa87c56f7e51ec1cd6b5cc23351d057a4ce4a8923c8ae6ac7a8afdcc0881c0e74ebb024ef7296162cb93c68e50bbb074e651ac87dac9ea59d4c3fbf0fe379f3e97a24566ecae54303bcfb6f0cc9f15f6639430e66b19a427849fdfff833df02689e9de44006c903c559183459b9f4a97f54a0f2a28df7b0e9deeda8239d7b516977f5e7d6971b4502e9885f750af8d1a6669e25e77d5f327c77c87a86e0a1872bc96a76060f5f8a0c40cc973bfc7fe6ed9bca78f884e6a2828b94d489d32a0fd337e69db83fb8789afd4e8ef54c22a78c2587468b9ae071bae3b202d3183ad5f0f8e842e5a8de85bfff49e03c8381bca7fd4278ddccaf0134fb5593a395a77a5cbd434593bc4ad0ff4b8400ec674c4ecaf1d57754be0cb2fa9a6441a9abad7b42197ad82e50827e4a4245573a8f0ef87f58228a2867f4b3b834b6635037940a
+SIG: e19e62ac539a9ca251d12d4c71055b0a3f581d19f2682e672404c78ac1f12bbefc91519276a5cbe16f520cf7a7f687a240f0329157c59f50026a58dcdc50fc08
+
+PRIV: 9a1717873689a03c112dd6b4d76ae73b89b416a598ceec209e27961e7bb1ee8aeecad1e0e4b863291881a8c241db9ccfffe4e55d8b5a42f307b4436acd0649a6
+PUB: eecad1e0e4b863291881a8c241db9ccfffe4e55d8b5a42f307b4436acd0649a6
+MESSAGE: e26580470901a07ab0931aa23829802ce04da59fdc2f773bc567f1e65b4f2e2d4a1a6aec1f54158adfce9b099790b503a13d22097ae23ebccf923f3bb1986d6e49111a8cf0d4eb8236bfe0d7c9e93a5efc7feb8e6a9cd1b8d921efa21e449ff49e06c1ccfea31f93e033c3c2a54ddb0f653a09fbd18a70b56315f193e7be56e5168f59563821d4bc3bbb0eaa2048286bbeee5aa3f3e7536cf2b750fd322602bb3847ceca39b75474322d76b1de80fa2eadba152d6f8f020d4d931c53f0a2801224d35deb6ec13b014873e689903607de96d9b7a743a887d2f48daf2ed2eefb202abf6082796981123b966e936dcf3483e2d24d694ecb865fbeb6969f347027fb8b175d24a4c045c0bb4ab5e02ddcbe77d4756c46d137b094473a02307a108340acad9d03bae8403af199cb75cae3162f3815813cc68bf2a5e499e594921149f3bbd214da5137e756521559dc80d9a4b74a0f4943022c7cd5fca42315e0bceeae9069615ce67a04382412313a31d67b346c329ad82e742c0a6ce0a6a02454c113e52022f3cc03fda691ebdfe14c53c8ce5ca9b932ca1a386e3eb4e90a4dc6e8ad8533b5af1aaef5003128655ca64f67fcd97c6ac803002404900bc0fae98463bcc31409f9981748789ade2d07783bc32b
+SIG: 1af8be095538965800d8eff6d723d028d65d0e9c6eb5e9d125bb3b1783f11ef7079a49a807e27ef1260be26a3b231d03b2ae151e49f6f189f15b1c83eab01c02
+
+PRIV: 43bd924db8156008c6b3994a8130d427d514db8a613b84dfb0b8e0de6ac306761b3461c269d5b0062d5df6fa654a2586f647a0684218a06e5e2f7badfb394131
+PUB: 1b3461c269d5b0062d5df6fa654a2586f647a0684218a06e5e2f7badfb394131
+MESSAGE: 6184e6480c42e96cc877269b16371545ff9523c45ea88e76a1348c68ae7f318b088fe4610928239185b6b55bfa0f43644c4a4c97c56ed77d08b1f4aad2f4aa069994abeca96b7bf81b8064ea4350d8a8b02297a51308b61c57c8f1873c6f97007aca3180429e730a6643f28733547bcf7b9adfe327e85736bd04af7f1d9f4fb84a7f3affdf4e22b574ecb4bc8836b10b8453aeaa5c1bf132248b826cc5230f75e075fac9f037561136e00643d08253e7ad652f702c0d15b6d7d48aa6f8e9b5f5cc146e3f156fb2522751c3710041bd922f37a50377e028b0c4e4bc3465d7c84af6a5fb427acb3b41378b102bda46d8f6f203a5ffcf395d435e93458a0b0a4c2e7782fafe119f769f67058c6677f6d10d9cf5cb8748e1805798ed233f6f930eee0e5075bc58b97af9177fda75d53708beb04dc4f19a43e768074609f14065f48fdad5077ce109bacc357174a6b7956f6e7f32e38415be526370fa58c3c0b31f51e6cd4b2cf27f8bcbc21259d9e5c3b5c2946a9fc1b00d9d15c3b7d80bfd9d05db91d249d3e42d8956682044548d83bda8d5cc9212442f30b45cf4aead80cce9b3512c39c5c737d3f8d747afbab265af5eeef8ca9362ec76e943b0a0d7a39f3db11eca14458a7b592e5e4ff2275dd48b2853
+SIG: d2a05d88d9d543d94d57ec88ae55681750f20b9be9c1e918cdaf457767f2948dd629e94f068edcf3d9927e330234badc3a02fa5ad3d9d85e948cb0b0cb3cd70a
+
+PRIV: 8fb086206dd95a2621f598560ccb281f8273c8fc72e23611089baac89d3c3c7820276ef479f4d4523ab77420d424e8819c33c83779ed80c7f666e8f4403f94d7
+PUB: 20276ef479f4d4523ab77420d424e8819c33c83779ed80c7f666e8f4403f94d7
+MESSAGE: f02903ed4266e849a4485205954fffa8a108c323b7e3f84331043514e48556ab019497233a5a127bff3cd7c97086becef538b3f339d7d06e532dc7325e597ae357f816dea42a6a22c79d22074a2e1ad8023c424b7e096e5ad8897b05ef7d00d30a04aaf2981eddff2b347f1e27e20aabbe7e7a9544978e092b00cce420aba06187374ffbb37b4c22d75f04e57590f610a27347286c298312a6c9b1bdf24fbda8513c4f8356ccf757068ffc11bc65113783a5dde7722faf4ceb19fbb62f40702e2c6e6a8bb49ef40446450c4c59a2990944da4744f6ee770b930c246669813ce5a9f5a47dd80388981bfcc3a56b5be2c4c7e659a2e9182dec0aaafe9031aa3954d4fe7c431196a561a5b78eaba64f3db1b586c53b16f679a84921a642c260e4653a61de108ebde6f7053afa2cb3f3668ede121020dd1bace8418aebac3a5bd5142f105ac26fe49e5fb140c19b22d54a6291dfc954670247881646874defad814995519f6260e9774a8d185c37881b4f2543c4b63fbf1985016ab41c4d728cbc90b3ab876267bed41d0c0902f6b50e8fa906fc4788f7b820467306e0fe9e036a0a00f804f91c3ca718b95ff6d9e2204bc3161bf70fcc17b2964b56bc612e29402d96f50986514bc7d831d58e42793786d5806f
+SIG: a9305e001600d597d05ef671699bf09f0dcc0c44475d3ca31e7ff1bffedc0c67daa1f3b76a035948c59cd87f82453a40950a1c9703c2e7d9280e7303966da301
+
+PRIV: afa1b846c210b52300e97696f81b8ea774d1df12e612527c55747f29c1937396b609566bbd1947bd7afaceb14389e836227169215fab66851aa5d70d6e2e3b89
+PUB: b609566bbd1947bd7afaceb14389e836227169215fab66851aa5d70d6e2e3b89
+MESSAGE: 4cac1b1f4bd48284dcc9afc8b5955b64b436db704b0335d9755cc1f97477f8d323cb6410ef146ab8a9efb9526d8b62e3bbad1f7295f47ba9f0de958f8ec9b77ab42232437ed974856444cd22e20be35e91813bff4b016f810d0f61d89f6b614db33f34bd09985b593fe3e06e065b7bc6cd39d55c2cfbec7b6d59c0b37dd1d0d35135ab1d1b04f2f30c2f04f4ba2b36582738081cf59190f528363db944ed612931d1d514c6214f9ab92abb1833926183ac52fba2a4551e20e4c0ac959a49ddb167a381e0241d40c086e90e52aca017258975dbab2ba451ee539a718f076a58709c6697418d9c6f13e4d391368bf0e8bd8f2932dd95ceaf7aaca1241147d341a3acd08dc32905483572b89a80cc47231468ab8de359dd525a6257cf196c2ecb82fa8a78aa3a851c7c96ca25bf7ca3dcf3ca21453d0dfd3323d5a422dec84316102f684c359f226bb53779c0b9950939281ef79a58c011993eace085497afa4daf64c9687b0a11aa116cfa7b03936241a5567b646e7e42e9fb592405b8fa3c0a821fc3121b45b1753cec9a83947d211a45499bd63790b87f01472fe566d87696efedbb74ed00048c384ba7f027b3aa4298dc4110349fedf52a96cd05d08bd635771ed4510738d8f07a6021244d1903579a3ea739
+SIG: 98b0c6313cecaf7c82cbdeb3d0280641c61a060f65e563aa93ce18300a9b58272dc8680b485e8cd11cf80fdca868fab365378384a142727f2f844f87cfdf1905
+
+PRIV: c85913a6877877131001623ccda9cdc12b9d4043b8a83793c44696632cd6421c9cc67c6948f7bf6e556d0849d3b8d203457a7b61549b36681d754f1dc0841e96
+PUB: 9cc67c6948f7bf6e556d0849d3b8d203457a7b61549b36681d754f1dc0841e96
+MESSAGE: 91b5009e83d0f6103399c2d3feec0084973a305bf4176ec782537560472db187a11b4dcb4b2ffb7f0644feb394b28e5bfe97247c4a4a231cf6e916bf99344ccda88a7f5d831d6de3d563dd102eaeb108c5bdce44e0632d17e6fa55b18067df2fa8d200a9869f6aff920c51d46a1ced2d903b1d9b6b075facbf91cd05eb41ad811a8ef40d9118261012c72b8979f15153dbb8561293da9f8b77c8ff14f75387536f0036d1713a72ce8c35b1062f2c6732aebf32936799b51c2cbcd6572413e7dfaab8641a02c150237381cf7a14e22c74c6c20009de7d3b7e69cd1b4584ac2c01babaf973c56b3814bb0089720e41968106cf26509d4aa546fcad5534af303ffca42b16ae6c93ee06bc3cace12e4ec718844bd30d2224cc486d106d1c456bfa165ea0120fab3df2c5ab3a523bbfa789deed44032ab0be86eb7cc09cdb7c07aa948dd5277c3df1d9d1843567dec84f9288e085b05ae4b8af2cea5d9a184d50bef85550c836613d5d3af5f9c2928e6a89660fa62719ebff773e46b77e34bc0470da4d2cdbc7071da758c4d39fe65201c88aaa8e6603d0bbe7c3e9b2d9e41b634682092f147341ad6d667f20c64e81a68d629467a54dd86e1ce12c560a6f9b64512d6f3886cbb9f37c37eb3985c8ac38dd6682f48fe1
+SIG: 01fccfdb1fb6888b0310a913170f7e366816daebe7650d72513d9506e66f7d62208a49ece0af1871497f4541ef605bde711c9e0a1205ef48f26c03dc1ad4af03
+
+PRIV: fa1e11dc8364208d8e1cb66a361be7e84c5e368166587d4fdb06aced7f62e17c4d8e6f4b3415df6cedabfb295c1984fd419923c6ac41764e32d22daf372c50fc
+PUB: 4d8e6f4b3415df6cedabfb295c1984fd419923c6ac41764e32d22daf372c50fc
+MESSAGE: 294e63bacccb801bbf04c1f19d0aee16f5650a6e8eea6fe41110663ec01532bd4960a527f15eca4af2f4e6b7b0fc340cf97aa234e92cf7d69d50e4009c2496e3ed4d9aff000f9e185275b817d26a0bab69b7f7ee1ea30daec8bcee387ae46b4b299c27bdc06eea63f24dbee955a6c0969037eef91c34321e3c5c972fde993183b7d23f6e019c3e0cac7589ae4a1521af87ea42df8c22c2270ec23d6d140f9cf6d4d52fac1b9d6c8939ef8131cb62a035c5261538bcdfd6db419a55ef9fe5d7a5ac44579de700858d74a3434844f28342c565892722e27f407d7f17b74a5934be915b20c2400643235f8ab5795f324e33c50644a04033542cb3816d770fa899e7311c14301c1bd0f5aa60a2eb3165680c720e1efa8096fc25d2779275f1842b2db53b4da0ad3e59c07540c28460cec1fdd3cdb7a3478b91a9caf9ac891cdf3aeaeeca9a9656ac1307259922fca74c5cc69f7e25c6bf587973a4b7d3e3ac0635b0db22a0093a79076881c71736ee1d4d45f8ed2d29a0671a64e6ca2f7a5ef404b1edeb842034f571b699bc59e5a37df02054e8482bf1e7b77d8e8397da15d89d7355a5dce86b1683a9ac4e406c08a94a6eb00e5ae16d96722972e5c50c7bee4a84d0697bbe67ceb7ef295f06aaea5abba44466be0f67
+SIG: e857db087e28d6750bf54e53797251d8439989576c12da2d9c811a14877c3bd46c4efab861a10eebe7da04c0b0b445c7a390a50c13de36f3a3c7ae0157022c0e
+
+PRIV: 24a914ceb499e375e5c66777c1ed2043be56549d5e502a844710364042ba9acb20d21ee764b1f35f94568200d63bd5828aca8c5d3e9047d23f478b925295fa2e
+PUB: 20d21ee764b1f35f94568200d63bd5828aca8c5d3e9047d23f478b925295fa2e
+MESSAGE: 3ff9f66fa2646ec66a1bf933c2b4cc0fbf912b4d6db50534257f97d01e698d05485747de2544e9f5a4a4a075388cf4400ab89b0353ce86198202db3a903767b879a2af9daa155843111af15a2bc35efe41bcc92c8207e00113b04f1303007949ffb6ce8df4b0b34248fedf5d9cb2cee94b812ed58ece2a0ce0454cf14c20e49e09fe664d6e25762e87895932cd5cd32eb6a3abb38ee163078c133e93588791dbf6af499a31ea4453bbcc7a85e406c9848a664052f11113fbb4ffa760dee4c261e396942491119da29a33582f821d4125e0b4162f28beb066031a652d05749aa7244dd4f3d3bb15d268328d6a02fce2501815257f8ad5af4ecbe7cb8ae9661e344f9072318791f3e859091121e08aefca8982eaaf66259d9de4f46a31e716dc033d0f95d1fa936b6c6079b137dd1158d1def113018c73f8ebb9807e0f7415404ea9c78544ace7ce463cd1d1c57e31f4091bc091804cbcddad0e15a40ca91acbe1c6224ed13cafb4df2c84ac9f0c3c9b546007d9dd6e524c467072563d4ac0d700cc1bf30febb334313dae5761745ec0a5e9e8815025958f00fa2e58060d7e9a5f2b727f48699f929c8459930892573f784fef5692518b5ca268e2a73ebead6ebdeb7ec24eac92aa7dcb41b598bd6eff3632d069726291
+SIG: 3ae0cc7bca8d73be83a9b809b13338c12706aaef75c4d1a478178f9dc565514c7529e298043ea78d21a5a09dd04f10ae87441e5686a933c92c75548427ad3a03
+
+PRIV: 5532e09b937ffd3d5f4c1d9f1ffcded26ee74d4da075264844690bd9c86139945093969f377bec3e35f59efda01ab4186c5d2a36740cf022675e01096b1a3f0a
+PUB: 5093969f377bec3e35f59efda01ab4186c5d2a36740cf022675e01096b1a3f0a
+MESSAGE: add4d7a9ce3f63d1f946e8679065545d8c7bf0a2cc3a4c00b8f142f0945ae362c4c9462a7576a4059d57861662884bd80b96d90d279a952eda952d37d4f95cf0d70da98f4fbaca39e169f9d945d41f872397bbdd5701454303d77d31e86348271da40a1b8f1e57c36fcd803e14fa17716c5631efa01d3a795dc20b2bde36ab73ff6a2d533bc15cce22328713c3c9ccd072c3e450d7f22c0c9f94919752cbfe45ee655d1b53676593cdb448704102631caaa976952eaa1f6c2e876564e420f0c646a0f88365f76415b4085f60a338b29c51633e540f0bf32d4087e7d0fb685be88c7595dc531c99b489584560ad8234b18e39a107cf5d842dabd421e77d26ea5e0f1405ce35fe792714eb4ee1a8017648ac1ae739a33d7b1e089105d1e5add27a62ce64154570340af9eb14e7fdfc2f9a2c2fcfcdac3cc4227763f4d629497479f849216e5d90ec16dfa36b72517f7b5486baee7fda4450c352cffbbae73926c843224f8ce44b38dae53f3ead21890b52a7801075291684fd5910ed86ad33e8a007f6c3f85c16b209293740184f5890874d431cd4e0ea4087c49c3471d789c813c6dc9a78699363a1d87197d3b92c0286689311823f4df22ce8035e75732cdea7f5621f67db0e2a4ca6616193221c0aa3d6de50d85282ee
+SIG: d527ff0d4a219d61f418121206a54ae4985854a310482744486e4d130a7de97c319df8372c82828c936e6a8afd9c5de1828573d8261ae9365b8f237676182402
+
+PRIV: eb36511009d37a9c46c4d1374d0bbd0d9981e78cee7d188c5aab983ec239e10cb1cc212b4521bbe7b19a7693878a558440eec36205d8439d040a46a9902fbf55
+PUB: b1cc212b4521bbe7b19a7693878a558440eec36205d8439d040a46a9902fbf55
+MESSAGE: ba2466e56c1df77f22b6f0241fc7952ae9bc24756419a9446dd2b49e2cb9df594e5b6c77a95aa5fbd9dc57fec83962c7751eebb4ba218253f916a922a5139663e3203e3be482be379ca151c463d9ada21446135f356994fa5449f084478f5bb4f5ba6145c5158eb7b1c43c32ebea25e09c900f01ef91e92f88c03c76504ace9646016ffc2789559d0f3cc9d00fb61bdc6af7d3940f302e588e04f79f7b3d4b91a5d193a4f8222bfeb69bf0347d98ad81ef99d130ebc7b36b0783394eea92a38ddd5e7480d2add4e4def53eb99c449bff94e4718b09f2ea9b1f2b886594a95c33a69e0333154e440ab34b7b6c1134d8179b6f0c56251a9ad8e1b6b0f9b8a5c97081a7f8fd05d0b0affc82dbddc8b0c0ab7e833f300626d4b973b3f60feac55571e89cda0f2b441ed2faa669a70d556cb48f9b1d1cbce32ede5d166b1143e264b11ea327681cb559edd13c364bd2baf1fd54bb781807bd59c868b0e4795a779e67f0bd0d14b5a6b9e440b57a5823328b59affbd027eda7dd785079c5f02b5e32890b038730986a39a5a9834a3fed868b6f45cbdd28acb2709aff556263864f9ae1e757b3278c288dbe2932825712773e431f7c29329857fdaea798ed93920893631402e6b13bab62b4855461edb94620f2d1751865f445c466
+SIG: 9f583724de552eae82f254ac6e2ed483ec1a07346266735c490920690c1e3fb2a9e9a34194ed6473733b300d4f23c9aec0da5a2022054ca43885a15a2984320e
+
+PRIV: 7dbc81902e4eaab3077540f559995c387403cac306d486e959c5eb59e431c0a8e03066139082f613448bdbc27fe53aa3f88994c31ddce002e36bbb2963df3ec8
+PUB: e03066139082f613448bdbc27fe53aa3f88994c31ddce002e36bbb2963df3ec8
+MESSAGE: dff798b1557b17085a0634371ded5ddf7a5acb996ef9035475e6826336f64ad8b84b882e30badec2b4a711998752f4a1574bc1f89d4325cf2b39861044dd03691e71d07768b5933a3052cc7c81d571a9de061dc19026c2f1e701f2dcf26a88d3401bc99fb81559dca76d8a31a92044a273587d622a08d1cce61c8f948a34ded1acb318881c9b49f6f37c30a65d495b02d5429e7ab4040d8bebeb78794ff736d1511031a6d67a22cdf341b980811c9d775fb19c6478f05ed98430103ea24c0f414d4cc07d860b72dc542ff22d83845a42f8ba45ca7ff3aab0b1e7de2b1094deac08d16eee01969f91bc16fec29ccc061c54db5345ba64842dacc99ee7729468d80a3f095583d8e8012408519d582cc3ff9a2eb7aebaa22db81ffc78ee90ef4ec589dcce87118dab31a6328e409ad5059a5132c82df3cefe2e4014e476f04c3a7018e45267ec5018ecd7bff1dda9267e90666b6b1417e89ddacb5085943befc7ad2f4df5f1ee0af9431aeeb6b24a5515b93dbcf68640f7daf8c961e567d7534900205c3df2184b6ac2da961c4c1d2bc49b4ea96b8154ffd4efffdc5e55a7119cb8af429e85105dffd41fe4a2ebba48168aa05fa7df27c4298735ff868f1496beb4b2ed0b8980c75ffd939ddd1a17e44a44fe3b02795339b08c8d
+SIG: 5b7f652f08f229fda1b0bd759377b3fb726c1b9c9a10ef63426d352dd0869bd54d876c3092f1cd411c3757d3c6b6ea942aa70c3aaeb4217a4c7364d18e76e50f
+
+PRIV: 91b095c8a999e03f3ed749cd9f2faacc0076c3b477a87ab5ccd6631738767446dad174d359daecca9c6b389ba096452ab5ca91e6383c6d042a284ece16ba97b6
+PUB: dad174d359daecca9c6b389ba096452ab5ca91e6383c6d042a284ece16ba97b6
+MESSAGE: 9b0d8b00299852d68bbf497fe603961a485466a99a5484005db73d4e4bad814e8574efd54d648bd5c91ae8483c54b2f998b02e1abd6f401a25526843a5f2a23a97bd589d1f7e1ab14915b1e359a396d352c360ae6584325ae4bb7d624f61255c5c7bf0a67acab46c3b57b34534c0ee8431d260576606cbd84d8d1839e73da6fe4b0b8b78f0f958827c2f1d93ba7a346dcc75cb563dffde26f997598e8b5c2f1617c6fefc9be4b28b5401b0006413a251690d1203aaae4f6d8a3fb21f24009ab3bff13737a8a7e6646c02732d9ec5a4a510469e2d299e4cc1ad6480a482aa956f89ddcccc64a136fb15b876b6ecd88c7c86a4dfc60e666207c604167d163440ca9ab9cf87a5e0f7bbc5517de4dee876c037f8cc9d959c8ff5dbe944ff54cd91a771e29231f8b5f17d61de904c955fe2025dc52ed480fb3cc90f232459c607ef7e2adb52c7482becd67ad2149a4128f984038b58aa90176782393604aac74c18209a3d6a78630c01955a7cece5da8384da3baf63aa2ddf5963fae05ba3b81c6a03d86a00ef78edb4184fdc89b1d6bfeb310fd1b5fcce1e219524a3cfb2e972577f06b1dddeba00865dae4979000c008ad99f3b638cceb8e8c7a0f998d34d92143d81c0e1c096a925ceba65c43003ee18d494d003e9c61f77d65759
+SIG: 64ee9efdb0c2601a835f418520641e436c7dd47c333d9fc30cfbb9e390fe764530654708b40b03581899a9ac870efd766ffbb4637152f8ff277964fe35425209
+
+PRIV: 8c568b310ace7d1f0edecefd603a884000544c792565d481c3d3e06e2d82ca965fa6e267c766736841411072d1983d1900acf01d48c3ce11770b26f78da979f7
+PUB: 5fa6e267c766736841411072d1983d1900acf01d48c3ce11770b26f78da979f7
+MESSAGE: b59f5fe9bb4ecff9289594721f2647047b0da5e0e4941bbe57c5b722b476723f0ac5970b4111f893bcaa411f28fceb4f585a2a7187018a904b70ef8fe1f6569a54d00ada37b69cb5e9c9d26c16a903518148e04a1b936a32329c94ee1a8fb6b591892c3aff00bf6e44dd0a762babe89d7060c17b90390d23bf9d360a293b8308383086916e1182b1ba4336f001b8d20deae9a029f7e85397a9ae5cf3ca10c7f3875588b8ffabb063c00ca26f580f69edc527a1accf4f41397b33766bcf6d55eb8de081a48c981d05c066617b80d8f6f5e60e59dd9b930bc4d04586403bb868df75933bdd86230e447036c175a10de9bb39953dcb1966a1f11912078e358f48c5b209a636c7f783f4d36a93ad2cc2e3244519078e99de1d5158b3961e0fc5a4f260c25f45f5e8585e601db08ba058d2909a1bf4995f4813460d369503c6873685ebcd3330a130b75f2365fb2a5a34ea63d958a2a867e90552d2cec8c390084be0c108b0fd2d83cb9284db5b842cbb5d0c3f6f1e2603c9c30c0f6a9b118e1a143a15e319fd1b607152b7cc0547497954c1f729199d0b23e53865403b0ad680e9b45369a6aa38d6685abd397f07fbca40627ecaf8d8d30133a6d9d5af009192751c9c45f77c0bc011268800bf552512730e69973c5bf362ab164894bf
+SIG: debdd8e5d3112fd77b394aa0e36e9426bac91df126fa9c317cea7c9d45957cdd96a45ae3ad760413ee1205afd71a29f9c3cb586cd2d7cd1e93bc1652fc34dc04
+
+PRIV: 3d09afcee3c432fdfb6bdcead54e3da5b1b4165c50d6d310b7fad787b444d680b0d9028c4d1487d293ed585a76bc94fffbafe2c65d980c494e141e4810a35cb9
+PUB: b0d9028c4d1487d293ed585a76bc94fffbafe2c65d980c494e141e4810a35cb9
+MESSAGE: 767165caae0e578f16537e1750be7de87a789a51ff2de11838f564e2580b2391362d2868a5a4708af15d2e2db7b9be39c16adcc1200b34e6b4d4027ddffc1a2a3595e29e855ec5261b20bd55c428b01309badb59e2ca3edb967fc2f4bac0729ddf54fb6c20057bdda9e7af7cbfc092fba865fd3275b9d3bcb0c346b951d170ac9aa650a86df49855d48a1b37ce56c9f27389f5c8b15f5c2c900c4f107c064f603e4f867ef2e9c10a1b74210e6b89bb011793aa85ded43b51b749ba7f70287b6bc1b89434db8b8c8b5d73b214b41e36b528005bfbfe002e21b1006fb9d24babd72106d093e3c7093b3138aea719d69479084647498cd6c9bbb744509cd7da8dd61a627100f03c21e750acb3fcf4631d7c0f618154d2e5fa6656fb76f74c24795047bbce4579eb110643fa98e1f776ca76d7a2b7b7b8678173c773f4be7e182fd24dd76291ac67d9f26a28c5e3cb025c6813a378b383224642b4aefad0c76a6579517b8f360797dd22613ee682b179381950fb71609a5fb5494d2d57dcb00f26d1e72956f4d6672830e05c01b3779677c07ea00953c6b8f0dc204c8dbdccb381bc01b89c5c261db189ab1f54e46bc3edc4de5ad4f0eb29c0a120e437cd8f37ac67d48c7f0e730278708f02b54aee62b72952bc1c0eb437ca8bd5655437
+SIG: 89739fe441ca0ced08a6eb5796e9bdda0e74fb473528fd4907edb659aab44d3343229046716368faf88e85c1644af66ff2dcaf0b17ac93ca13819f3f241dd300
+
+PRIV: 41c1a2df9369cdc927164aa5adf7757136abe51395604266334cc5460ad5683e40557834cce8e043580a4272a8804d4f926e88cb10d1df0c5e28b9b67e1b63da
+PUB: 40557834cce8e043580a4272a8804d4f926e88cb10d1df0c5e28b9b67e1b63da
+MESSAGE: b64b14ba77d239e6f81abe060accef85f0442b650c44015efc43a0aa2ba10bf48d3018b1953ddfffbcda5bf3bbe0b6b3e4b0d9a32c6b725bbb231e0a2704471ee8bc1d594f5c54226f5dd9dfa163cfc1452c61f93e4f8139ab4ce4476f07ec933661eae91b6d500bf508ac63e4baaf1ffc8f0007d802e005f1b4fc1c88bee4d5e9e76384f5a7043bd660cce71f3b67f01f6ab844298531aac73a39d045370088855005a09c6d04238ea478dfacad1e6b22b2be4c46b0d59b1eba1f060bf7da5d1566cf1fdb5c543a33926af63f01a0db86e1a6711c473dc795ab283c8d93facfb5701fa2f2f6bb99f9b7e3749b071d58607be44a7089bcb503ec1495b5feedb399961fd3677d7493eaa3b3e9cc5e3642f40d47de9bfee7c20b0e519c4eb4a40f4da446ed6ac7aaca053e759c97dabe0a8ec2f58e7f2f9b2072762f9f794a6a4e36060b8872bd2c18d06a85c2c141a78293773ee8cfbf154b9930cd39da31b497e737a7750c90a13f5aaa147cd0dc4311f2e34941252ef198b0c1f50827e56c9f16f595aced6d2a69346531495a6499774d360766ca9be5ed8881c0db26ed7c5e6ff3a4f9b73cd8b654640dc96bf43bd426a0f28c9b25fa704d62ff0288fcceffaaebd3ea3097bcbbd778420ebc520a417730a1b5b3b8c96cda9f4e177d
+SIG: b8b2752a097196c289849d78f811d9a62fc767278f0c46628b521f62ed2759d74462a175da22403f15020445cae06da3ed61cca6203b7006362a0e198963d20e
+
+PRIV: a00611489467122c4c164bfb6a616e6a619b9f83c4367206b85d3fbec38cd62c57ab58babb41dc0da0bcd506059aac9f46eca91cd35a61f1ba049a9ac227f3d9
+PUB: 57ab58babb41dc0da0bcd506059aac9f46eca91cd35a61f1ba049a9ac227f3d9
+MESSAGE: 34db02ed7512bf8c67d359e7203a2ea441e20e729766c15aa00fa249a3518fc29ef8905aa5b4670958c6a460d77b3a80efcb473859bbaff862223eee52fe58acfd3315f150f3c6c27ff48fca76552f98f6585b5e793308bf5976bad6ee327b4a7a313214b9ae04b9651b63cd8d9f5b3bec689e0fd000dd501770dd0e99b8f99eafa09c396a245a4a96e56896a29b24190b1ef11063f39b63ee3a586b07627dd3500c4e170b835dc0ec236fa5a35c44184707565c4a50662d8dbccfff7f9a7a68d021b4af64d532b7c3d2747418c2d717bb6aca6b58747ae4dd5641d826f79a8a315c38211a538a929e5b451f623f4fcbbcacdb86c8752ea13a617ab414ab653eb2e68d5420df7c6df92438168dcf9c066581dfe7b2c468194a23707de4659bd67eb634ff024741c5fc8698fd4dc41fe5dfc6299b7a08e6ffca37109c0210c8f94ea2d3ddc977ffc0b3794fe6ba4337c7aab434a68ac665484ea8243a84b79aa181ee6ab5aa37a32d879725edc018f8552181816d7d272ca8818a7b92e6ee4454d1f7828dd8afba1a790364b4ff28d84e028597353ebbef24837bc319e1ae8f2b0b6a851b489c3e170eef53e065f7032653cd6b46d8e57e4e111b789ba950c4230aba35e569e06615403407bce0369aaab4eafaef0cae109ac4cb838fb6c1
+SIG: c771ba0a3d3c4a7b064bd51ad05c9ff27fd326610fbfa09183039e5edf35472dded8fc2275bbcc5df1bf129860c01a2c1311da602fbaffc8b79c249c9cc95502
+
+PRIV: de1634f3460e02898db53298d6d3821c60853adee2d7f3e8edd8b0239a48cfaf9dc1465b3383f37de00ea2d3c70f2c8fac815f0172029c3f579579c984a5895e
+PUB: 9dc1465b3383f37de00ea2d3c70f2c8fac815f0172029c3f579579c984a5895e
+MESSAGE: d10c3e4de7fa2989dba87537e00593d0eed4d75ee65846dab1498b4749d64f40e34b5911c5ce3b53a7e37d2d02bb0dae38ed962a4edc86c00207bee9a8e456eccae8bdf4d87a76746014201af6caffe10566f08d10daaf077160f011feaca25b9c1f6eca9fc53314a80547951754355525257d09a7fdad5bc321b72aa28d1e02d8696d4f9eb0ad3b2196f8bcfaeb1d6148287a3faefef91a7a3e0609c28ce59d0ca14d0b3050dd4f096b7bc2513988ba212128d5026daaa7188846db21c5c1d179ab9487c1a5bd346588127c20398d362d4c759cfab2a677750b9e45676a1e7e092ef02edbf278fb19a58e9bf6c9e996e24edad73f3ce31fa04b6d8533436bf80b4b2f805ed91e7fcda3bc2bab3b2bb157158af0ea8e3f0731dfad459d2e79b6d3715fe7bf1eafc5397593208857e57b7feb2f7387943a8e0913470c161aef4fe205d3637f23177ff26304a4f64eba3fe6f7f272d234a67206a388ddd0366e894eaa4bb05d73a475f1b34ca222bbce1685b1b56e034e43b3c40e81fff79682c19f32aa3f2a895c0709f9f74a4d59d3a49029ecfcb283082b067f1a0d9505750fd867321999484249efa725f52c94c7596206a911f3f505d63f0313254bd445f05be3996b58fe1819af87352e7f0a2ca320d9cc00a5fe77ad41640d50be8436
+SIG: d20506eb846923a0b16ff82fb2c3923b00c1b3bcc6e2f6482fba24807521e8e0223f692e62eac993f498f67102a04fd1acf9c7e3888d857c9a080b8af6361006
+
+PRIV: c738ef5f0935281ba625fa4014d4a4d0be7e28fed779a9cf658e21dba43cebc195799faf706d195e544c76cafddf09d02d1beafc42c9d6c9ead4c1845587d39e
+PUB: 95799faf706d195e544c76cafddf09d02d1beafc42c9d6c9ead4c1845587d39e
+MESSAGE: 168d0bc5598be02f5443bfe7dfb8829985ca5d282af9cf1b1482602f243d486bd82ba039a0750909e9b3c7d4d5f8b8baf45718af0311854f4d1c7837f31d8ee68d3558e7e51e0c646a4a637596ee90057b01ed0a17daa3950b81ab47ae8b94c17d40746913c46ba1478bfca51b167628fc3ee1e22f2f19d6d8daf93df6540cedb7a859d1a2ba5911ba71766e8b7fce0c0e8663616d0180697d78ce3040d438131982f3f8112acca29ae53e539ff8c9ec4106d132f402018518308485f2aa6c9e8d1e62fed60cb249457db33c6fd1fe07445361f08194a2b5a057cb03cc754e5c7d4a7eea53a7f7d207cacca5e68cafa969a3521dbb810399a17f328ee767cf55926b2bd5f029549d3b464579c42655265398472e1c77cc8dd9aff187f7ac34dd456ace999a736ecca6d405d4922c779c600c47b84c9c1df5e5f8ed3b2811d351339113f8453cca4c4411688cb0388258ebbd1872b83610042249494ed560d4cda6a68455d957e806dd0bdd83004c4ca80774b8a0a1665866f17085014eadb3eae7382fa870deb29dd8c931b53019625740e28392f38575c0e2a9e504fc35bd95df56439a898230a2398cd2225c766ef36f12ae7e49b30a9c0aad469d5895bbf721cc0ff51d840c802d4a7eefba84fe5205a2c2f14011922dde561456f79e6161
+SIG: f44371e6c3391639d457ed14648184809411e80a3201f8811670e500fcad92f300aabf7fc68e440191e881d6c3474efd6d28f09dc44312fcfcb82701ba3c290a
+
+PRIV: 5fea38739c61ca83bf7b4ad175a2117627b971a634a305a84fa57fecb8035624ddd14b0fc06768d5104c50764bfd3b952352a34007c50d5ddd224ff51afcdf9c
+PUB: ddd14b0fc06768d5104c50764bfd3b952352a34007c50d5ddd224ff51afcdf9c
+MESSAGE: 1013c60a73953549e5ed105bdea150b91e60ec39200d43721304bfc8ec439d39609613c2d878044a9da01b26d86d6d65db93d91a137e9c4808a97d4ef286a903f3f1382cc6d1294216b9fafc013c86b9ff68b55a50ea3766e61dc1ce38348e91d62ce732c152d766b9335c68d6cad77be2b4a0cd50b9a1ec632ba55648a6e7e11a14c06853c02aec4809bd147a5ddd9fbc3be9f0c8158d84ab6795d771b42b1814a17a3c7a6ca0f4a8f7b3a0db1c73ba13b16400dfecbd03d216650e4d69704a707246444d5791fa273752f59cb5ae9fd416a5186613d66afdbd1ce691a87bd7d8b67190e9ac687062a080d2ec39fe76ed8335058251872839e85eb62f18ece187caba55b5f7d5edcade01cdc543cc677e50238b89c5635ad5c8fc220f5e0be1bc667d20989753a6d616fa69f8b12940b8ca9e2c48577132d8691b053779a152cbacff3b8b1bd7af692e56c73bbae4634776cfc213c99b9ae458df1befc8c877742664b0a0bb1f6915c8dae3b3f55dd75aba6a3bcc4176b4e3ba03d0c1c04c3c6408778b2b8e5a8a3eb52ed32a7428c00a98a589d8ca9390a210f4a7ac004fa1fe4c6da694f12276e320b41b0b59f75d264a396d450b631ab353f1612709e7a2e6a50d01cb110e53040546dd3b1e11d25732813aa76be5e81fcf7a5773f6815bbd
+SIG: f4e274823f2c396f3a329486aa6410c5ff19266f0770fd04fb14a7602d2b69a4a2b00928e9e1d92389f8033359ed6fb2146467aa154cba597dec6a84173f8d07
+
+PRIV: 60f9a14cce5d43fd9aab4ee8cc8379d575949152693bf29a6790b035e42a44debd4a70740d5acabe49f9a2152082fa2025330e6440437f1d047f313de490dca5
+PUB: bd4a70740d5acabe49f9a2152082fa2025330e6440437f1d047f313de490dca5
+MESSAGE: dd7f44f9eb728ab48de54ecde6b6184bd5ddd8707545a0129f2e905905b55d3e7fd57e28485d258148f6605e2377d5b267d2eaf4cd4b46e454962219868232b6f41f88a797f9cdd5c39ada51a641214fb9db2c2a9b5a5b16e303575318b625cca970b74348727902a1cf268bd16e107113161c8cbc99303c2b9f235541a7b31e433120feba14febe4bcb0f5b936c7edddd0ecfc72c8d38f64cdb6cfc2910bc29a521c50a51abcbc2aabf789de822cb04f5728fee153dd5501b2db59c59f50cab17c29216d66951019e145b36fd7e841bfbb0a328554b44dd7ef51468c3d5b7d3a1f7b9def58d8cf9d9bcafe92c86cf6d6119e98dba6f38ea57e322ddc9c2198d4bbc3b94ea1329db0d458e01c7081b33925a3e287f599a858c50c3a8f18cc2aa634df63e7f10e403adeab2f41db5578790c3b4f041a8b7a4f69cd6e06215df8201ae5b3e1d1d25a0a39bfc3d041a2f98213ef4141245792a76f06d4de25f6467a0e56f2f5cf69400d22117de7b46149554b70c75b9f99484a4f6f035ad3f10e3753cb14f4f398dcf6a64d10cf6c4fac07c91193cc0f54f0de58c6343e9caaa6b4f475ef91a59e083f9f211f5bc8e7e4516b45cf06bf50beb8fc4ab579d86d4a4190eeac748d06e0852c4b9ba8cfc50dd0a037a7bad7fad55af309a5f13d4c91ed3e0
+SIG: 72f54bb8bdd17e9e422cd339631dd39f57355015d4cbd15acab7542efd784a321c1f6125764c0d154045b32e70dc2e03fbfe1117468ac3e73127b5fac8d42102
+
+PRIV: a39053c5c58bf31d462b27a620b0b37b8052c6b1c4102b6145663aa15e9787183642ac2a3280dce52ad8dfcfd3709436edc4e7e4ae1b452d9b220780b08679fa
+PUB: 3642ac2a3280dce52ad8dfcfd3709436edc4e7e4ae1b452d9b220780b08679fa
+MESSAGE: f65540d3abeb1ee5ea987062c1b579516d3c29c39cbc6b09d60e18fe274c2befe0f5fe7dbd57c2d5835229bb754ec4341394765776d6a9178c4e6a312cd74bdbaca0e88270628cd84100f472b075f93692830122f00f9bd91ac582836c8bfa714aa48e977003556e1b696df328ef584f413f8ab614760699c4d147c3eea1da0435835c9bf7ad54606f0213eb74a1b476141506ae2cd124cd51d66e7e7e579560576305c5fbe8430be3ebebaacba3f9989dd7d199f5a455a50cdb3755037e1a70674a4fef40b4a3aaf7bd3c95b1ab41bb206211c3a1276d3e37d8a3a5c3d5d0f36ef5b4f3de26b7f20f6b2900716dcc22ab734ebaf1e8d00020e5f019551653b9c2f70a4038dfb2f12d25d6d84e79073a6548fe15e4828fe5de83ac3d8d98b7daf92710482c37f7bd2431a8114c6137657bb177882d8a3c76babf1c671a7055365fe90866167a2d1dbc870be83b3601f09d4a317ae254cac9f98dcc7aead9224cd9c9d8a200abc80a2dd108af28fd46ad7080ae741b50054b9b9a9201efb7838bc4c5c2cc3d76ba0fcc49c46e792c26292b7d0312aff955a9f8edf0c696a70a614f3553ad3869bfde48d26a4d367b6cec057e62a4e548554b48b53ecda790ba7a0ab2e3de587bdc22b02f5947634d73099f547db22ec1bbf82343f9a2ca38bce4eb59be
+SIG: f7383e966cb2309deedf860100183aaefac672ca16d5419cd6422ca70e16b3976f5f165afc2786117c868234ba1109ede031f8979b50e567358bd4f8bd958202
+
+PRIV: e0c29df4de45c47539e0896b3a59bc3de6b802fd14dbdc9f25e717ac82c328f3a69002b0f5ef354ce3b2d6b8d8ba70ab778432b22f144dc9c2eb92d99d99dd2a
+PUB: a69002b0f5ef354ce3b2d6b8d8ba70ab778432b22f144dc9c2eb92d99d99dd2a
+MESSAGE: 6a37cb4c749c583590c8d849bce3fa657f10009190cad9be41ede19bf2fdb3c562a6101f27bd37f223cab13ced245a1cedf852f551f857aad9727f62c967c0a921df116f48a80a6040b3c723ab5cb594c4507a3d20cd60514e22164a82b74f19dcfdd83c57bc3652375517414af5d18e0a64ccab36699768d07cf40b7063a83e43d5f607964b1bf0840a45ad50abf83dbc849f40e5b4cfb6a3347b29fec50774046a4b50041032aa4d567e8564b3eed1642040682dd8ae7d7179286cf6e1853dc87d27c3e9e60fa47cf8cb2da0181d53eec40614b07331a4fb7028086d0b1ce2e1115b73a162c527bdd7cab5335b863d108be047bdbca112cc6e776bb453c317314388bb9653efb4444bf5cf1ec8da23b711ba71796c0ae02ba1dcc838455078c3897f07e9e13b76e49274c2e207506b00a0b558883aa122b667db9d670508606a3f54320636cd19f973917fb1875f4363e220f1e12398cc6afd79094743338456813a5826ad3f1aba7cd7beab1fe183859c0cc9ef40a5eab912caf515a8d4c3b93d641b7ab3e76b16c12971ace88ff33e5a1ed9b44e45db8f3085dbf070b256b0d7512ee1069432603d73095db8749ca547963bd71a8a684ab8516b146c4187176386afdf6cb1368a3dd8fcb2cfff77056aaf7823f800b266acce72bf643c6d0c28f0ab
+SIG: bb3b8c5c27591fd8b9c5ba489d6b6ee5b0fb4a7b0de51f1639afc673d0e5f75e313aa7e1d0009081dbca7435b687ccd12f64f74a386e772b9e24781b925c8c0c
+
+PRIV: 198b5fd1c03827e0994ad5bfee9b5b7be9966c9c3a267e4d7430343767403c676682c6f1a866b49b2f8ee97f2e532fa91666bf38da1b4dd65543a1777794cbee
+PUB: 6682c6f1a866b49b2f8ee97f2e532fa91666bf38da1b4dd65543a1777794cbee
+MESSAGE: 3fdaa15c46f25143db972079d7013c7f69a136f45f3f6ba2ced8b828468eb3daa6b50b4f8d3380fec64a0343be116f6f83b6ee64cc4c1b1d08d54fd42029e4285cfc6c6dd5cd181ab533ffcd411f23a1003da94ec9340e2ec71199d678540d5182e139ffcbc505a170b8f07f4a7e694ca92f58320c0a078564ce9de99b0fa8e66b0d822e467a5aeb83567996a48b89db25cade6457794e5414d67e9d4ab7cd6cc2058bb7a513abd709f4caf24bb67ce1c03ab62dbdfe309ec7db0fa3ea7aae8236f259b922d4536115a63bc89acb2051d09e731cbb0df157d9d345bd9109973c2b594f148efc6f3377de5163b7f69869ffef853eaefeb402e23529594fbd65ca05fe4062c529d8e321abc05200cac1e839e87b1fd3fdf021d68cbb3a4142b69cc3af6f632edd65b83f5aa4cb17da5b6ba3fc03edb17c2a3cb5b04836e7660e63c8a0483e243983371dfa9839f9164ad4da0d5953655e3a9518e136da745737c79243c355fc125cbdcc76aec92216846c4574f4f7f298bcde54fd2444ad3025955c100315de5a4e27c333a00284b2f702fdd3de22ac6c240dbc14bf71e62d131b62f2db992473f2f913f60c916ecf57df5f3f021fb330834395b79472caff19fcfa0a271795c76d69b4db3f85b8d2e5c3441965484dcc39aba59b701274f7fc425246856069
+SIG: f454f35b18538f877e5d614a76b5276a27fc0b433f215dc4e963b3f047694c780c515c6ef6fe2db4b009009bc2733aec4fd46e615357cc0bcc9f1f7fc21e3c02
+
+PRIV: 4392f7d4fbd68fe154e4ba38ad5207612a0648556056c39ac116ad468f89bd2dcbeaef41acac02bf1f780ce934aabd631364b369567be1be28e3906f9db120fa
+PUB: cbeaef41acac02bf1f780ce934aabd631364b369567be1be28e3906f9db120fa
+MESSAGE: cf1709dc9a0867ee908721b136cb93a84229e83b46204777ca8194d08b7a3ca9c912eb243e5bdabfeed352349d20be801b722af0892238e72edf190e6361f57572781ad3c2590b197357641c805383baa1d4972f76c65448532c110834a0baa8f48863e166b706653708cd4057d3a4f9fcb2ceb4120001277d38c43847d822822b777c2bb4da4015a1c24d416d5062a8718491d855aaa5dbf5579c164d8e524a9f2fa3f22eb09861ffe6ad659fe36eb40431222c22d7137a6cabca8db786e39d81f661afde4e39589b4db4d3c51ca53590a14e115d0afc3a877b839a9638bece80c32c19e51b7532024845f76cfe9bfb2ac05130f6758bf7fe993aa93aa272e4e6bd0c75c14099d43e652a223e5bcd64c362d4b8f4b95e016f9350c7fa74e653525d08011558b2c6e9bf4fdf9dbd5ef9b09bbc846afc2bcbc86c4ccc315f6d1ccd489b0cf8ed0d93f2f532a426265c590ba3a59023347d819d9b281ef85310b05316d46c8a8c0365d068a8708664ea4d77ac0cd150a65a56586babd34b74365bb8fe3e6187262284d64432e4c81ea4c0e57c1d71ae980c7f4d1d871032e188bbf9d1758cdc1dff989f2d1288fef4e205e99e7cbf2cc324b8c93046f476c59d3d0a59db6fe37382dc79c5ec16056ab3934a52f7d2880d0471a377b6a8ae84d56ac22d1d54551c
+SIG: 86e7ccf06e79362d40cdb7fb75a98978bbd334a1db7590367d60849bd53e2fb1a4bdae590d1f47b5490d8702e7c1a87268b8ee9db612de7bdc2e38fa6deb7e05
+
+PRIV: 0bea98abe7d63f158390ee668aa050e84a25d2893e49fc83f079f9bba6a55a7522192ec0d32ef9835665a61bc88bcf4e1604637921152c116af503365bf6be42
+PUB: 22192ec0d32ef9835665a61bc88bcf4e1604637921152c116af503365bf6be42
+MESSAGE: c178e38d4e83ed2be57ce1c3ab64253a8171e610008181fbfc6d752269f7f1c5a9ec62cb27f19ad99ce1f5116a363d96fdc5a42f358b6dbe7cabdfc9f60718e4012c1bb1f842c5560811ba8374a0637747ff92eac21ca65ddeaf43e9989b7de2d432520afee364ecfba4da669ad4893d0bf69f9f81e7df69657be22b92069745f216c242ccd46d02d35616e16c755e0e37f961a6f3637752534f6dfab8805ab759a032a4e7e4c81953325a2f686bb69a029ce4e03becb3605637c5a65b52e331c26c926ed4711a504d3733bb53c97b80eafe4e75ddd9f415362888c3d4d37bae0e63fa11bf755666437d72f58c91d7a2f8cb619b7620a070b26b18b4d50184c5818712110e36d3e2830f6a8576ba57f9cccb8fff4028bf8ef9cb814825bbca827d649547bf6f2bef931704ca7f6df15f780155ed46eaa7ca7d72e22434ca0483bfb2f7902dc787f617eb9bd41ed4520adfd430948c710805a73c1ba5492e96484c4baa7da24c7435c46a052bf3515d33e42dcef517caa45f36c879121078c688dd10d76656a119762b6a834136fa1f8a643224b9224c543cf0470b3f8ee017d620dbdcc84d985154e9d1ae80e5f14387b88a0f6a5c35905aa57fb3abeb0ea6eccddb004474633cc483b56b8a8e20e8f2e09e979aa09893087875c6b117b5f13847ad8fc05604c4
+SIG: 7eb3139b880fdf66376a2090818840049767c837f3ad0036b141667052b33609817ca5e240ed8cdf3ccf3aee29274534594db0b4ccc5c6e5bba3280b873f2901
+
+PRIV: c25878b0d1e0925c8f5f04a1e5799080963c413a1399c118afb1687c797f483913ac2cad41908c255f671f93934ae5d7be325346725c8b40dc39ea80d70ddf34
+PUB: 13ac2cad41908c255f671f93934ae5d7be325346725c8b40dc39ea80d70ddf34
+MESSAGE: 6856cc7144b6bddcc4b58954d1a2e7101d6584b5d5e719a0aea0fbbdf221c2a2aacbacdc4020c5c8ce681ff7381acd607b0f5239692335700655be2d94c53d7b5148e92a2bc16338c2f4c1a7d1c595af622c240ce579a5e0f5b651bf562518cec8aa2ce4b4aadb1f2fda6cf6295bc37803b5377dab65c9b9a2949fdd49bf9ddc8f96d260ff951bf8e8ccf9827e6869c44bfd973358cefdb010db5e1fe5dbd9f5d2b2ca393c17d446f637059e692d7a91aadcc7689f5f9e1b3052175d9b6b208f9026787fdb66783f45372a24946b1bd1687bf0cfcc8174ebe4d32e43284fc78d7844de0fa22e2065e07528baabaf015cb34d629c3596ad040de31c5620eb266defa7533ac0401998e5673a754365047debfcf7e137a20d16cdd6a5521982f444cfc3429397c641bd7e74a770bb11fcb29483e337bae5169ee82da9a91adf3af67cd814c2825d29018ef035ea86f8de4c7563aaf66e0c75d17ca68f49f0758ec2d9c5179d01aaed7d4515e91a222b0b06fbde4f07a7d9df2de3bcae37ca2c8460c2a6b3749e9bda36d08e66bcc356b390434b4a18cfa45af557dca3d857ff3ad347cfb07e2358c2acfd5cd53b3b0ea2a41ee5c0802fd473db5f30526334da41eb4bc7518383898a0b7507ad4ca289d66c5e2eb75cf255dff312cb1e04eebeb47f2930b90d5e002eb0
+SIG: 06f55198b4191914b74306f38e381316eac40b5b5adb8a312464f67175ecf612e0147b1cef46c2518750a5606bb03bc6467bb9321514f69dcbebce8f69058002
+
+PRIV: 0b2ec62763f687593135da1961ef29a288089696d944b265a5f96893cd2d8225c1e234fa8bc96d268e7aad028b03f0a911b697715db3a21c2fc7df48ecda8875
+PUB: c1e234fa8bc96d268e7aad028b03f0a911b697715db3a21c2fc7df48ecda8875
+MESSAGE: a83434c68693d5fced91bda10213fcd50c48920b90cee9b73a9c61081a0974933f4fdb0a67e671f8351b0ed5ec0fe7b5fb0c87586fe582ffb1bfa2db5fcedd3302428234b2bb0e726dedf45b13a70cd35ab3e299d13f34503508278c4458eea5b7351b05836bdad5b05f60e445fc65737ae27d2e52df9c39e5da0286392d08fff7ecb7066820fc90fc8a44d5616561c50b52714702302bca5874de85dba045045f9f0e604eb86d6d7fbd775f72ea493b2c4ef7c3be16db2ca7e4d8bd79eb20cfb5f0f6f05336b75cc86d219f3b8f2e91ba7d52b64fdd6a6664f04f2fbab758cdf984168691c32f53e8616b49f76ab7b192b900903082cc89656a9705804cc9b9288a3e42170984f8dc454e0864b9341672686a178c060050178a36c6d906b2ce070d8faaacd9a58c794a5ea4108b4a485c65811c2dca2ee7bb10bffff75d4586b990f43763a16fbc0b48ae1fafb08a9a36fa4326845dba5ba2fbd32bbf66505c5e8657ed0107e3e16144ef31fa6aae72e774097483f5480aa45540568fd08cba0d577768004f58ae9b95be374ed7f0299fe721275e476e0b9ab72dc06ea328384e39bf3ac331c625484312cd9b06b15a2954d33e7aaba6be2261886ca811db96b1143d06dd6e0f3cba7a1ae9b94eaf67771bb2d24e2f94de9c470fcde7bfdb32f410198b5aa9698e32
+SIG: ff701f34b3594de3b80045f429e5e32dd88d6051d4195f1685be783766e80119368f56b3749725b913f1223f87fb0fb24d9dfa0841d6a0e2eb1fddf775c2d205
+
+PRIV: 8960d7bee8c6b39ca5934d7cddd16f16b3663e6e03e833c057e2181e4597cb6843409095d4f50f5eddbd5cd4d2012298cb41a40e99492d5a2db08be5377ea183
+PUB: 43409095d4f50f5eddbd5cd4d2012298cb41a40e99492d5a2db08be5377ea183
+MESSAGE: 308d84c7a5f786e563e5c1ea57aab5e555c00997749d15aee35439efa645da2c3967703115c6c63ed7f94785c5478f38467b86e7626e8fffa4d51a2dc45e6df2a35cec99555eabc9f7a93e2e2b689459b4e0c92b351562c417b1997113754ea59e4a91510728ff3071a2bbd1f465a687f67dae955615031a8ad551fe738a260bbc446b48dca1d979051ab5840832e19d473b666217a9183980d6b27e3d3c76d93665ba2393e6ab1a42c3904d4025932d601a202a59a4c49fdb77f0e02868247de5afdfaa1b894208ac00d77c6bb54c6b2a73a47657e44c85137963b57521af20976248eb261482147cdf7a145c3643e29e0588bfdae6a082904853ce5a10d24970ebdfb7f59d5efdd6a5e7e0d287971c846acd54d84dd45468a4110bab6ef8d9a5b4b2426788900b7e1adfe0624344f98fe59ef8a1e6c405b344eb97bb204773744b6a2d8c6e65d17cea07de03b7f0fe49f1a55c33d5f15ce55df7c9561b251c6ac807a92553e1ce917012dccfd69e7dbd038c7eeecae98623f18fbb650e2218a0bc0fff43a75a116448bb7362f527ee6bc8e10761cccf9bcfc0d000f2127b4cc19211d095a0bdaa4e4be4519e6c8445eab9b3144a45cab9996135bf7f75a78d22275900f4ce1f0a9eac136364103062893dad4390422b77e5f5d1d94d7029c6097b35ca64a7a476fcc7
+SIG: 7213dd4a79fd54dec0c548ef42e6cae015be77802bf515cd2582768f72f563ebb2da36af4aaeac56bbffc9932c2e24ec95daff00a5f7a0acab9c8bd3c23bb40c
+
+PRIV: ef6b9b51fd4f8586ca62658e042fc09a83b943033526ffc326c65eb3a5fb594b1d6eece805e0887821876b7ed6ed5b0714d646fbecda38764f94c8155e61d004
+PUB: 1d6eece805e0887821876b7ed6ed5b0714d646fbecda38764f94c8155e61d004
+MESSAGE: a8f3f19665de2390d5cc52b064b4851273677486d8f5563bb7c95fa94db3356161ee622221f10cbb1fa195aac7231ea716d74b46b37bc85a70dba3dfaa1675217b351199e74a971028f729b7ae2b74ae8c6b3a0679c3e3296802844ad5bba343f6f9f7c4661b4a29b44f17e89e114fb220e984cd980e94c3d2bf9873e0605c92301744a3035ef046bad2666b5c63ebecf93cc140291946c0fa170340ce395092deed79841352fbfee03a927eb458f2a633ed3271652f5b0f9960cdf9015d56fdabd89ee71e259af6eb514b4c1bd4a666f5b5a35c90f35b149457af2944dd0aa8d9b542283a7e5412b775e421d2126f89bebc3ca37f73071621f1321eee52e9690486a33cd7ff9c9967fb65ee4e907b6b852211473d21e9d91a93362ac761760e8c7bbea486c3d605f9e11b86136819a7ab3f32f13ffca16817fed197ff880b4d6d9a808f7f878763a045728df72faaa963e4cb1c09cc2b2da920280c8366b7d18bf8972df16cc23448fbe6b2e6e16cbbf0745129854053189637ce115d2398433c15d6f116a205334824af282fa758494c47868ea8f4dfadc705e861aad2eb8ef3dbbed2a4569e15834a760cce0cbbc84b289e779b988346b9069c744c97ab2bf42b086d2fb0a411f5ce99f0819a3086b4fe9d96c7c9908dce28df1ddd30f3501ddaf78110734f9dcdfec3
+SIG: 71d171071cd0fea1c6a9cfad1f7fd835e85ff906778bc6345a4dec4313ecc2bff755a717ebd912a5e02840ac073842f9bfcaa58913e260e3c73393d36685c70e
+
+PRIV: bad47cd4bd89849067cce1e63c3d91e9b787aea8584edb07f3451ef67e7bd79bab0ce9ba1d29bdfb85a0e66b76b5e2e05ff732569e4375ccd75098e9e71d17bf
+PUB: ab0ce9ba1d29bdfb85a0e66b76b5e2e05ff732569e4375ccd75098e9e71d17bf
+MESSAGE: b5a61e19e4863e0bb5f3fab6c4970d878596895521fa1e7f678cafa2de53322fd458a98aa6e35805429f651291b95bd9950e155f3ada0b609159a4abda5990c04bc2e764422fb49ef42f12529ff6f6a82029ff0185662e658f83c546eed09f06b5a68e857cdad0eb9ec4eecbfd88f34bc80990f8644a9bfdde1d9f3a90d557a8b828d5ce06a64e3b238582bb4cbeba30edc49e8122c55e95badcf502cc567869c09e9f46c6ff3f6878986b1de00b72a1858046fcd3a6e9cdaf5b073c56f2025063a2d178bd4c1e8cbc1e6e671aa97fb2cb4cc8a62c20be41c776372c8e7be63b482e6c63fa85d7cffbc1b2820bae1fc128343a1e20fcf1bc3502eee81358cc9a74c72af63530f96a25a604648ff570df1eb89d1fddbab28679ba2e9b41977e9a9c1caecdbfc361a1dd055ec51620a9bbdbbaf718c9cc136d2007710399536d13332485ec38879785e0c9ce9915a80251373990a59bce440326031ab1b458bfa5b8a4793da4ee11ab7af20de2a118c9ae521a417b68207fc885e109d8463e9f022787cc730db0b1faaed257bed901710885b74e994f54f6f2aeb64f0f60b59efbf2e3bb6515424603a113c0b8a31ba3c1e9a9b8118c87ec6949b75f49627ea7b1328889391104d4f4a3892cf00f26a73cda2a40f9b7157afc40667f4a04f647dbf93906b84c9a35164e1bc902
+SIG: e5724a1dd463a97d1222c518c4925d322202d10f04cd078e771e0fb3951dbc1493a234460754c3aae3df93008dbbfb310c99592bede735a4aeab0323a1210d0e
+
+PRIV: caba8e0533113a4be173408ba83c0db74260802f9186c391402655acde6015cb2d7bef6164c279fa1028a9788e3e8ee8ac15edcf92a5855062952310b4684547
+PUB: 2d7bef6164c279fa1028a9788e3e8ee8ac15edcf92a5855062952310b4684547
+MESSAGE: 2413a32bca5ce6e230e565eb858493d5d04e6d2e2a7ab1f89a3b423311676bfa93c67daafd1cfc7109e040bac52cbfe07c28280bb6acf6e3a31073dab2965378dd77f61fe9247135c1a631b79ad668c9ea1cd4112d8d3a064cc21df32aeac7dd718b091fb6915b8bc063bb5815c376e01476312a2e5433417a7a9315d65999b02ff464a474a597e53988773670eca46a6e26cf96e9488e9e6344bc783ddfb535e76bb3b9a603ff4c59c7dbe2d8b6198d5b24490b4ea96c95959ffbf3d8218e760daf20e01e2f36c84bb097115abddee92bed82d16b15a9e192e9893ac638461df507207b0cf595884d8a99fb9c7045f9bff7b73f00ca3fd595a5cec292adb458bd9463be1204d01678d2f4389b8720115fa597c402b4ff694b71ce4f3d330d5e2f3c3ad6d96a9b3439230fc53a44794cda595557c406ca1589bc7be81e2d79636033253fa7bdd600c67fc55936bd96ce0428c3eb97bad1de0a5fbb9b675157de5f18bc62a7c22c9483e2802e679b5b8f89db0fc37f7c7150ad5ac8722ceb999b2435e6997217092336ef1c8a2292dab9a46ff8a9e10d3355765cac9d6598770f4f01ea639125fd031609dd1a507d96280c7d01a3ee987e9b210ec8744cd48c74f8afee961e8ef221f826a1fe6e7df0cb15ad7c7ef4a91f9d0f4c2e1bdea635d275fac8c4bc0601f490dbdbc734
+SIG: ec35ec32c8a4008827e178492b3b8bee22a4954fc6b25f4f225dd7ed23698900de8156756a8edc35c51d10f82b830a2a659676eac911f960244766e0c3c60705
+
+PRIV: 9bf3fbc7308b46f6036bade0c3ca199fac662b07f103bf75181d52ba6a58be052f6ac6fc33bc060c1dc3cb9d1a2b9115845addb16c4b84be37ed33adb3b3d3a8
+PUB: 2f6ac6fc33bc060c1dc3cb9d1a2b9115845addb16c4b84be37ed33adb3b3d3a8
+MESSAGE: d65e36a6a38195ecb91de3c848b51f639245fa2baba8a6f85947159dec0ed3fae80c5a0f8c66ff24793c89c0c687543bc633547a1f37f730d97012ebbdc7ac339c4890c0856bbfe2ba29b25a7aa6b089c033fecb76db62dd3c00f6421b9e76dd0ea366eb2d4a052ee6cc736e3819191d5ad7a66d2be042cc6539e5f35652b155a727f3888d93f93a9102598f7538a9ab7c777eec79426a6075d6f38d64c485520f6413ff4d358a8a9cbdab01adf4db02adaea26494d1f5d617637f277f8b0e6e7e61e2eeccdd337de2baf0ca264c14c8cb8368000b9c714385f413737d6816e212cae2aecfffc32fd16d46c3ecee6ab074c0d768bdfe99b86cbbc8df9c47cd586d465871268d4a9d1c877236ab78f8859c114e251cabc4be0f8bc25d148c5f543e290745d11803e49f5b53193fe39969c039b3f249b32f2b8598b6acf4ed64d5752bb772ff4ee00ce0f85ecbb4cfc4ce07daf2809868c2903b781e12a274105f06181029e47f2bfb21f49480aa1e444715c0b9ff07ead88975d93585d2ff424832a9783d94906a60f877ae1c85ff15317badca1e61317433c7ce96279b678ec9d174dd0870080b234154f626a53462cfd547842eab8705605b8ee885729ee78d1833aa43f55ac22731989fdeda7dc5fa9c01985f2661e6c7326d346e6db27e6f921fae7c93a2170e10dd0c460bdc
+SIG: 0c3136e01f9bcd99e10d3d124b0cdb0772bec18a864be81bd1daa44d818c3d470dfaa8ab6e9a761cf03f93ef9cc78291096ed6d10c08fa2fba3bac04dde20f0c
+
+PRIV: 64e89304a335e903cb36c0bdf1a6412ef368468006b73d3d2d61cb030cc5f8d1a180ef3a661c3c479d5f69807c902748e35e7f725121e37a5d91b8bec88d83a6
+PUB: a180ef3a661c3c479d5f69807c902748e35e7f725121e37a5d91b8bec88d83a6
+MESSAGE: 2f51074d981bdafafb02a40fe826c45f3171c1b3184d8c260b82b8411fc625cb02ccfe755dc29dc7895bf759e61b2450da1a656a38d4f70d2ee748c518c6420306e5f01ec7a0ffe0e9dceb93f6c077b12662881584f98ce6ab945f87fc6d123c45d6cdfd8237a1ce3635b623a79d020df44c74b89ac14a321fbf33a8c0a2559fea1c2b156076b813908f842ebe4c2b949089e52b1ae40dc6e4b2abbc439a0bf72369679aab6f4c00018be147f7c0a67b9679ee88a53819c49f7b675e30a8b5af39661ee8db21010411294968f88e5d604d0d88d76a7e4864fad3a56f5f624ba1b34ea9cb720850aad3bd4f0a882a7d25fbec2bb7ca86da616da96c1562c6d6a1abcc641e1b58b2c178e1c3bc8a3b36ec9e144dd2e75b0bc8c08ccb0d6e3427b0322b3d6ab93f3f60b9cc5b61dad02385a14949f9b87a8e3af1e0e0fab7a9a928c753fc6110444af7ccaf8027ed641b9ed87fa5d8e1f76cae465d57a70dad9ebfdd3ce7576ac4de89d98f42e282ad87ad6a5042577cbbbc4d951e2a8676fedc8cb1b1bdf76c3a38846385a85aa24706c20a8b38465fe2ae0e41f78e614b8e9642fe2471a9015747db976e0c7848c23ff3f417cb05a8d5ef40130adf855c998a62104d7e2fb7c0f9aa2a496075623ced2c0f7eec10147ff9608a8a042ef98117459b93837fd1b8d5ef03978eada74cac
+SIG: 92eb4454814001ecfc18025d6421f64645a5bcbb5cb8fd85c14d772617c503e8be7d3bcf117f5e6801d1c3b96f9090a66ddc67f8cf8ff0f1c125b16b15e2ce07
+
+PRIV: 6f634387ca2c0cb167a740d6afd89e2a28f5307184e81cba3c037046a5ede23c011f2a9a111c38f3490cad1685be78eceedc6fac4a3221301c69c84b1ec7b3a7
+PUB: 011f2a9a111c38f3490cad1685be78eceedc6fac4a3221301c69c84b1ec7b3a7
+MESSAGE: 865c20a94ac3f2e3bd5cb85bec9d33726671fe01f9c537017d59c8d5106e43360bf76fc06186705980c8a87ba3633a4a170426ecc0defb6db2670f5f592533774cda50052ae597d48deacc2637063bfd519f2e79bac81775beccb1ab2f5b39712e2e829469b75a2d2dbd08aa6d24723404b25eb948a4834c55246c8079a82ec64354e8c2388f8c5a616b3cdc371e6263fabc9f6099219e861585fe82a67d610dd1eb5c81c96b5cb354a689fd8aac8db76c433f0cb0b31cf1d855b6a30a3d2a212e9b4f7d7afe619951f98d2f1ba2c101085ba81f49b36037cd6457a7eaa8f4f3bedf68d09fc9fa25a9d754db65360285412d1a6da53788905fcf4efa8a80cd86ca48b845633d8c31c2ae06f16c4c6bbbe9cd1afb59e101be50e03535dd8a65e45bba46d45cb14badfc8e93ab5267f4e492ab1f9a95e61fcab81cbf2bd867a3ec7b4baa189a0f08567075596129dcf9ff1c502d3279e8aa6ce56eaf134582a9e430a5aa8ca10c3da8bc793d0256ad19aea7149f0ea7ea95facfac1c5cfd29d7a3fe1a417975739e14da8edc819900472ca8c69716328e8a299f974edff741aabc1c074a761b3ec8761dda2e7eed7af33ef00409849d415497c5ed5dfaa2259a31d076398170b2d9d210208b4a4c7db8c626d1c533562a1f95489f9819e4985fc4e1d1a707be5e82b005481d86377f424e
+SIG: fd17c618cdbb5d459ea2aca886f0512c623251284aae3a83eb5d7f60da1d9b2ba083c455a5e2583a3cba736e7b961ba19c1cc8dd90745da82a15dfc662e8e10d
+
+PRIV: 4b2e1ae60fa5d383baba54edc168b9b05e0d05ee9c181321dbfddd198395915436c020b18552345619ef8837eb8d5494840e85f46809343b4d6f406125da557d
+PUB: 36c020b18552345619ef8837eb8d5494840e85f46809343b4d6f406125da557d
+MESSAGE: fab98b2bbf86aeb05086812a4b0049a1042abb76df9cd2908755706303efedb1ad21e8bc8d7562349e1e98ce0d752f4b3d99e677368bd08c78fe7425ec3b560e383bd42af6499886c35add80a5828b61d6644d7dc443ba2c06f9bad2eccb983d24458f6ada1b10bb5b77172c5cdd56d273d1e41010b25cf48a7d58d7255702ac12f2a6fe2918466395f460d15236d035ae9410ca86c4605128299faaf09015f1adee7768ee1a8f8ca06d10dd7f95c46fa10253065f9d6f90295908809fd779571be29e0ae66e0bcbdeb7913d2bbb76ac302f3452c55ef199a48eceb0e3596c7b4c0386dae7101ea244a33c4cdc830672df83655b35338052307b94d223cab1af69e07f78e58cbb0cb3c5351e3a6b0c4a927f7562c598d2d3df90569f61db1a3cb0140b56ea02cf7745fbeec2028673d67f1ec5f7daf9715f754a9d8ed46a7a63ef722ee0d5899331b63c974fa880429435767f96254ef46c9968f3fedaafeaf3e8f45634b54f5e0a5fc2d2373ab9e98d9acfe3697e642a18e0dfd9fbc2f094866d401f0a4ca2a456edf6a1a77b9c296c3922067eb3d5a5ca0a77f430e4c8611d8f05a1baac1635ef7ba83dfc69d301949856be4d2c8ab61de29cf39250c5794cbf5750cda95d0468afa2b7f23dba4ef5f5295a3bf4140018b7ed061884444f5bb1b7d239312dd739999536c684456ea06b
+SIG: 2220119e83d69a6a3eed95fa166d1d1128a3f232ca1b78bc94b4d476c4779443614b8772aa2232cb0720a055eb71d8407f3ab19baa1d962c052c84c0bd589608
+
+PRIV: b216cebf878024c20dfc86ce4b37bdc47aa28f29203b5b44925065d993a259fec36edbb6254a913f08fe259e238780638f72ec0b3007264bcc60a9e81ee9298f
+PUB: c36edbb6254a913f08fe259e238780638f72ec0b3007264bcc60a9e81ee9298f
+MESSAGE: 9c8717cc86fe02480bfd9e922bd76bffee2170c4cb1b13df834ac01d45006086297f1b8a26f2ba674d33e1d162f19367feba97352b7df2e75b309d4b6f8b07cc0eb6777e81e268e02d07f2a08f8f39d5a8320bfc01fc8c9227d2cf05e12891ff4de885a1c93371a0910ba53392aff9ba2eed9a2055977ec4157bd65b34df79372f4d50edbc48924353cfa1692319d88a7a5bb726254c209291e9b1d2c1a6c8236398109c59ed42a0ac9e7633c520734eccfea4fea95a47a8f0a068b4275000439cc97c57871e105cc0790e9dcc9c25d5af7063ffd05c4f3780e7bca4c456d0170da709fc6cb3faa72bdcf562908ae9340aef4d0c8b91f0fbccbcf1cd898b1c716f4f1474c3aa316242abdf6368e57a247ff2fd5ce23d187f694f11e38dfbfbc3d9db20903b4ebb449b9049ee020f6e2f508e8b2b165bad7464dbdd178cbd423233765d371e7ae1c3e878cdb5b824b20cb309867c0e473c067e6744008527b6bc076d077f4867622aeed1c253dbde7c6a76c7015962fb73391698600bb318ffa7b0136ee4ccb07daaf01f40ff9c194f98681f9faef8b6f9e99f95df0080da8966a8ba7a9474c537b92df9799e2fd16f788dad7a7bcc745226e1e6371f52ebcdbd144044ddfe632dfc0a43d3a450923170ebc7ae219e50e078a511bc12ef14cd14b5309f38abd65db2b2a7af2243b229c9fd2e
+SIG: b7389ee78dd9763f9d2892912edcbe3e8a236b8bdc25f44b9cfdc8c47cd58168ab56eb0402a5bd752ac8f4978d2ea2b65d2fa85265966b9f57227ef4a59ae009
+
+PRIV: afcecea92439e44a43ed61b673043dcbc4e360f2f30cd07896cda20cb988d4e3d231f69235a2e3a1dd5f6c2a9aaf20c03454b9a29f4e3a29ab94689d0d723e50
+PUB: d231f69235a2e3a1dd5f6c2a9aaf20c03454b9a29f4e3a29ab94689d0d723e50
+MESSAGE: 0b05f89ebb3397947687afbef0ede87cf3810676277037521d952a3bbbbdc8565988a095d8d4f6f59be572d3d821dd789977ef77a2fd7110ceeed9f3756ed8e188267b97a30ef8957c78aea3a2963deca61860545e0c40824881ebb1db10f607e10ddbddce400ea236ba4745aa99a05641976766789ed0da7db55fdab459ebd4b441a6282f7cfd5a20ea06effa335955e5fd29181671bc92c00052f7f75c39277c9a43b787ac9fb1516e996232a509774d1dc21d8c0513f7844b0a5b5f18957581f99044a14223ccda8a284de12fd424265fe57b270215f8fa9ff2bea517934e4800a47d346fb6c361cfbabeffabd9c4164f45156e245c977edb473642c3940be5ad6fd1a7119a7b18e98d6dc843e0d254c93d0146d18e5c62ede1490f89a605eb454f974778cfae20932e95477bd03bcdb97d5bcb76335942e92ee668f231e69c570ac5446d0f774066737fdf49f10ceb1b52d6d8a4639846a3373a7c6f3b4b3159fe2e7af7eee2f0df172d94d255d017651da3009005e5eac3176c09389ee40d70383bd37117eca083598a1801f592d057186e568e247c252be4b14f723ab7ddb97ae9768c2682fd63acc300779fe04e2b88874751346c9e0f97a2a216772ff9625c33bd7e29fed8003a08dbd33b5d17899c943c25e95ad754fb632e047c112af7f7ceba72362e1a3ddd2935aaf7f818a27c
+SIG: a65545cf3df456b28d83a6d94c036a19d0d29fb065edc27e5e93a1f40279897e1c6f25959a725ababc87cf2ae727f3467b79570e902711917191d9cb0d2d660c
+
+PRIV: b834c6e0facbff580dd3b23753959a4c2154c219521b3d27035d071f6599bd02d1c384715e3b3d02c13e090605534c7db740da2aa560f53200a3ced8beae8cf8
+PUB: d1c384715e3b3d02c13e090605534c7db740da2aa560f53200a3ced8beae8cf8
+MESSAGE: 6cf147b1605528a36be75716a14b420bcf067c03f1cfe9c4402f14987fbfc9d3ecc3ccf4f8d2d03a55900b8dc79af3b6e77436f69b1417ad4b68fd44e5e333ed90ea7943fbd1122609ec8ff6bb25e42e9914f5920fc72c4d013b6a9685c996fbd8352aafb184c22d9e47871a5280e4ab7dd6a5cfd10a5994a200f670e0b622a9394d4793d0a420e7d8806cb127c7ac690d45a2e94166cea672bcd982b0e9baad56312d2570ddde7e0b9e7f47136f0481d00f66a2aaca4d1b09d7ce6c5a98a76b68cd97d5793968d667073f8217f9054735340f9b149c0dce845b099e88d0709680f0f77603ff0a2331c558fc36d5f24da9a62d69af5190d21b5c857a1e08f014c6d456468665a7f845c66f9111f9c098c68940efcd87b657070cb9164bc9743aceb7439a0d01c0062a11af2e11349397f5d152872b13c5ab32f51cc58f1475ec82ac671561dcbd343cfb3c5f78d0fc73053c6004b0a4ca3f2043ff4b0c54275c4fcb9cadc6baabe57b1d5acd531e972ef9335136cd1d65512ba1f5b6ccc4b66b4250aafa2967dd4211a2742e0f177d8f4063899f61815cbe6d8fbfcdf74812bd40cc10084e46a99ac128058eaf16a49a24b6ae228ecf0109c52dfc06e37d6a333bcb24aba312164c6c0290485d251280538ce9541c0916640e36d6929dcd9588eb99577f5f6d82bcbb198826267e49f5daff2c0d
+SIG: 0f19b7066d5792328a9800d9d4f8f67d5b089b541226a167dacd439fa485b0025a5dc7f2c7e23fc4a5c6869e7619d356399700c93650e89cd25b90fb9925e304
+
+PRIV: 2269a5d8f7ac2cd9048f5f49e349e5c435a159b319fe3b30bfac8d0d505943f41c817943dc39c24b01da38a487b175482460c609e4726349a9aa7aea9bc0fb34
+PUB: 1c817943dc39c24b01da38a487b175482460c609e4726349a9aa7aea9bc0fb34
+MESSAGE: 7153d4d9e641aa61920db0ff4bd537a6d6130a396554cc94537698f9cad16b99eebefa5f2776f2feaff6bd9a6904120c67e0883f6b96bbbb195e95aec753b699bab3d03944c13c72fc84e3f2cbf6296f645549111c93fae1a759bfcd16fc09e60bb9785535ad27da244ef2f857f2de99a6e92188890e452c7f5b9e3a4b968e11743b6fc7faf1275e5360a5468941797894d770fa7da364a337302239fe83ae0b0d084aa12acdc63462524e0eb10fefe81ba96f71f275f3449a3f8db21d58749a38853d39b0ad8e69891bd204dfca8f6c239dc9a0ac27f54db4238d4706df11d607369dc7f704da1d39f2e82af8c283d220c12431f56d803069b4acb77081c031ae3319fc77fca7845097fd727ad0d080895bba23e873d2def8cdc216c3eed61b08761bb9ebce0282cf502aaf6ce7e8c058637958c3ea1b72fe6e8df8d37ac055db6992587fabbdc467f52475644f918863af620492f34680f2056cbcab75e2323626c094759c0e0e99ef19759527250646ad760120ba386699d53934f956b8bbc7395bb496ceb2dd223c7b501b92d36a95f8f0a02eb5ba4dddf166b9b95b4a59e72a30c63cf21e6085751923d54b30281e52a09618e6f023ba0a21675e7f989b8991588c96c2b56a78f5d2945a7baeb6a0c1bbd5d95af3ee830f5809c794a15ab4b5f89dd2be2dfdcd8fe0520fda2b3f02a1ac0155
+SIG: be0fb3308a076a61a4a92a97f6ac55327190e1341d6dd410d86b41bdaf2d3374093ef720bdb77feb7014e0f77d3b809623c7ca53e2ae4b097113e96db77a2d08
+
+PRIV: e965b3f257356685c98b42b964a253fc495399cc94b099c2445fc81c759c68e5689f5410c8e0f4d37bc07c85d7cce6c9b63601f9bdafecaa448a5eed64afc8c6
+PUB: 689f5410c8e0f4d37bc07c85d7cce6c9b63601f9bdafecaa448a5eed64afc8c6
+MESSAGE: 6f20a9ad27e30dac76b30d4c19a5bd6dfd6d049213f4becdd963d72b8b2dad687b003808201d50f7dd6e599ef58ceb6068c545ed99b9e763f9b0ec1db5fcbd7d490a121ecec6bba1eb5edbd6de85364707c55e300c8b16bb2530f70898136689c988591d5391d9cc347d7931061a9b7696e2c9f35bc0d304a81c2cf954d9c3a88a22e1d67bbe0a85308477f62918c25db504e4762f0e3b4246007908ac701779006b77d72510edc69e17d0f6394c77e5551875a446f81233415d0a91a0460b51c413d644e850f8557281c46699e53b22a7c73b068ea38652cff3b0a7b8ba30971eab18fdbbd8739ee1ee0cd5cbfb7d5d41757b6331271fb7809751e203513c9970f66d91bc0ce062f4fcb28be0a699867b79594c6458a0d307acac91f413c4615877dc53e1b018da5cfce1b63f40be1e55274c4374cdfc21524499a683a231adef779d1921440e5d3fdbd5033dc983cfc931abe638c35d5a95869e9fe3d93eb90bd1861f855ce1f608b7bcad6b5e1bd97edc95ed5ddcbcb715d919f5ff77df2da438f7a3a98286dbd5b6e043fc7372f69704f09d865530f4f0edd3300f185b6d73d8716d32d32b1c9ac2ddf4f902d3f216d35a33f368095ded10be94bb53d6f256560fac2f4af0edf5c5c702143777126e7de32d07493932662129ba0e7fc7cfb36fd2ca531646e8cd2211854fc510af3b1e8cafde7a
+SIG: 8d2bc4e1cd256aad8a151dec010dc93a5e5cca58298dec49cbc9c4717b5cfb5460d430be726b0f302cbd926beea19aa3c93aeb452a44f6007af49adf2f05bb04
+
+PRIV: bc3b1e0bf8d69ea5b4cbbf10bb33fc955adcbe13fc20af8a10872ce9df39d6bdaccd2628155919bbc7f9d86f91dafec35c711a78c79ad360eddb88fa8a180b2d
+PUB: accd2628155919bbc7f9d86f91dafec35c711a78c79ad360eddb88fa8a180b2d
+MESSAGE: 4c73e04abe0819de1f84d70541eb1bb61c4f42920e1f2d1d9e6281a8a2e8b3eb45537d83969027f99ef0ea27ca085b13f9db480f00c02f3fd7429dd567708953bbf3b9e8e2c6ac4d321ff8f9e4a3154723085a54e9c9573cc7350c09f8973f948b08730373597a5fd0349821ae0a3cd6c84992b189128f3490987e1e9ad4f6574ca538fdfd83284c1eb0953f24c08f74932d4364dbbef922542440dae80424a92eaef27c1889bd08c44f9df03a3af30dffb48fae445e625f4d9265cf387a1da35fe4c231504535db72ea81a186805f856ebe6a6a65241432530fe6c960c5f9be6c22957060304e9dd8efbc1e482e7ddbd8af03bf2382899c986d916611e4f27ae52f817ef01b6a141fe4f685d94dc8cd52830043934587704c1e642e8fe56be6d6b85bf4a6feb2b6858f1f007f99d39ea04c9fe5fa7ef1b91f495ed0e7fa4213dd68cea42b6729f95031907e27c44098094386fabfb04ab9b4de3d6861de462312c59b27c76f7b6a4fc71ea0d5daf6b7320521a67e5cb37504976ad73dae2d649feb75e2eadd3401a7f2f36e16dfbfbdb2af5716cba1bce20cd47ce1c1d7be00697001fbbeb4915aa6e5393b5ab20e0f31f5119149a2cb4c4d452c8156113ac7824f84f09aeb81202e8dd3dac0aa89399b5a38b1e218301960a37d52632eeaefe3687455464288eb17d9e19a3a72ed9de32c17be79a3b9
+SIG: 6ef7f0e91f2cc6715f8e5a98574b4400c261a643e0545ff26747f8e1739899d76640b6451c43c1d03a4775b54fcf9bce18ed3fccad338b7764024fdfa2de8201
+
+PRIV: 10718fa6e2d7f6ed38fd66cb6dbfa087e8f1e8a8a24fab58d79d7954b8720c3e870d4f666d06fda9f9511b58602eec050d754ea6d8e79cdd19f601c477df1aa0
+PUB: 870d4f666d06fda9f9511b58602eec050d754ea6d8e79cdd19f601c477df1aa0
+MESSAGE: 41259b6eef13d6ffe33cdde799b995c40be782cf978440b66be51c440582abd42f526696bb3cb92265b1ed0e4bba764cae2839830a252635dc80ce5f73d521b3d6ff03ac30e198ad20567e75a34fa825ebf9841508da84cd674236ca7b43de3564c94ab079408fd94137ce3f90a5dd5d3ac39a05ec86715a8f025e4539a7640ab88836f4efbabd5e1652c49ea21613acfe343a880ee5a42f2f9134ef4e3716b16d134a9c4c71c39b3c1a857d3c89439783eef1edd71bf4492d05fd18673a5242ff4187b9de47ad4968da49dba5a6092e95ea27ddfc7448dcf5972d9d228d63e5291ba6e6fbd07e3241f9366ca4976bb04b22d01f0dbae794fa9c1d9029f88a83602b0e0ec55e22c37b201125cadb5341ef73f6da1abbe2b1c475f0750345b1be4259d8c28531ffe7788667c410dac339918c869b00ab80f20bf7990d366f9b3d5e8eb2f48d7ed0e64b85dc9fe3bb998b1eecd1231e902d2d152e09da2d2592bdb32c8cd2e2c489496b2980c03dbb09ec7f8a4ea2c7020f2a0faa657cd6ced48d6da27864cf5e97eea9b3c2f0f34abf8d87bd2adeb60c7272fc4306d955bdc8023d7d3dc2f3dafe9ebe8a8d138965a7f6ce93517cd2099663f67c34552176ddb595ac6ea5609febcf24c7d69d412709e578670a21ac8afccb8bf2b18ff3af7de21dc71d50d60d37b6ed729db04beff7d34b2920d87551ce15
+SIG: e1659186f1f76fe43ac8a11703360fbeff53b5e57b5974aaa08e2575579c27084cf6802e7c206347314475b603197494e7d61fe4b1ee7b78e18d94469352df0c
+
+PRIV: c1d4724c6cb1bc6723b2b43034278b3c5b48fed7f8a3cc2318033e7552047351c27e392e7c3664b9061ea76d2575dd7c41eaf1da3a65f3a986e0a57f6c40c17e
+PUB: c27e392e7c3664b9061ea76d2575dd7c41eaf1da3a65f3a986e0a57f6c40c17e
+MESSAGE: deee99d7a77d4300c17aec1ab323c571c6e9e73a43491a3c7888b76fc03ec43d07af42a05a2aa322d00c8560acef314106b10b9bd12654357ffa26f2390050da63d668c9e2df548f87639e096a35853f82e761fd711d2a265438f5d4db5e32775708150da6cb686a2b4ca211d7f00dc0abcb2ca150e791116a10a5efcff3514dab8ed80a7092c3a015152cb25d9f86ec0d1ca67ddab44d64eeb1f931bfab2ab188956c743db4814808c5cde1b0745b3edd340eb03ffcc80a78f3db310f4f5c20009fc0279c2c1bcb3cedf990bd0e20c6f9fb7515ad6e933b07e99da6ac32b97141187ef63bdb1062e37220a4dcd419d6244cdcc34ea41d0bcbc3138b1d54aefc0190e30b187db073aa7d6cfe04bd3fd2ac00313e3ddd64a181935ca4b8b2a85d36bc27d97b7626767b93ee38def8b6b2c8da9b00263614342faa9d3e738d2713c45ffbeef8c84bcdbc8da4309c8445530f5c617dc866251f548950a14f075aa3117f96e41f899dbe7340b1d90a1352d3b8fb41b79f16a82bc2e4a193b8a7232400996b73b1fc00b2ec1c667577f82824d39fb7f6e7692dcd97b1d8ce94083ca197e9a5d40fadff0b9ac57e9de761c156e6d31d52c332d513e9f58697dcbdd80a5e42c551702c3de7beccc3db845b1a04c8cbd41695ea7428abba89e0dce3e3d9e70230ae9147c2b88559dc695d6809a51ccbc1dd9e089c585f
+SIG: d37a6ec82ed45ca9b4855de9cb942564e883ff70a79b8e712d5f604ec8974de5363ac849cbab28e7aeeff28ed3f2d14b608b3146c2efe0735ad815c7d75a1a01
+
+PRIV: 37c070d4a53b13be760635110d1bd4f01920225afabec576faaec910f2926d1a0aa85f2ab1dff895d1fad0c119f2bf57126aab601c528d37698e97702d35f525
+PUB: 0aa85f2ab1dff895d1fad0c119f2bf57126aab601c528d37698e97702d35f525
+MESSAGE: 10c646447f81ad94d015d86d0d98b2452dca60a47ab35264035e33a0942b954e3e23b91d8123b8593c6af7c8d3ecd290e0e5ee36fd4e53b7be633a6cf027a5ac3f0f679eb1bdd210a38ea6e48b0558e303010af474e7f6df2a4e457699fc38e36938b05ffcaa1b694e32f3d1b2cc5d00cf256f12184c873e519089ec1df15b0dc76e7bfe90780df58136fe597fce894ca563e08efa0f2d4d208bede9a874882873d251baf019fe46d1d6504b3bcd243b795351f34d2e7606aa975528ee50d59efb6ee6992a89b2426956c2ca4247e0df0129852983e9767a8eed1bc7335ffca8d0289f04807f67ca7da971f58db8b9bc9fdbe4f83cfe9a00f1ca584798bc71d851ff7cd6c51b8990aaba4d38b416b92240dfb70ee3c12b5e731057762ef90823fbf683ca06d05c20d3ae2b97a83ebe70ae17afff9d16609d546d8d3c74bc281884894f3d49e083f10ae7c11c1dca0effefcfa6e0f1535081fac3a2819fd2e3265527182ae9d391b232bb7542e68455cd267760db652d19e22fb2ed11cd1305ba8d98c1ebf2d1969b24d64f3e319af74e092006d2a3ff744872a20ebf18d17748ab7110805096ea136bce2f968b205e650b803c531d06775ae5ceea28bb92e9a0edec8951ce2009a88ee1b64d9b9e89f69051203384210a102a44d2d6703173b68507dceadd3bf6510df2a5cefd9c80e4f385b2f9e6215813ed32
+SIG: 9da60cc4a64d07dee1346bd3d3010995ce2738208ab35b34c2a8fd1787ae3a1e207fe784525154fae4f5794cd8503045fea85cf77fd92f6a70cd0c5a52c0810e
+
+PRIV: 1126496a582ce58d3d618dd8a3933547aa7a8a30fb54063b8dfdd31671c6c73de10229c623fa8ad8982c3e4c36ff52df0f219b57915b6e980e5fe72ea0962e22
+PUB: e10229c623fa8ad8982c3e4c36ff52df0f219b57915b6e980e5fe72ea0962e22
+MESSAGE: 6a4b52d730ddab829b2a179590cbd4c372498e9f439977c0a10dc13c0ae1736eaaff063371434fd0da80360ec5890607d2fae1c9a2e1ab0b7f3d667f5b1b9c418f18b10c9e6fd669d3ebec168efef44163e577a2ebd0f2cb768f80c23188e86069e4d10f410306cedd7a341a61e0f4f3bc25041bc2f922ed073e1e2f1b709c579d10630f33071754d707894a1c62190de18882c564dc4c01dc545dd8966404ed78fa3267a9469f63b6120abb65f9b3ba3eee28d79c2eb4e7020cc6987dfc5c29672f8c0fa3e690d584fe000c64f352610179621bfd5ff3eb30d18f1a0250416db93b1c1e93cf8a3646517560d1cc8fff822b51ef27b200e987b592390753453ef138bd3d29db7cb1b5f45e4795b89c53f49704192752237c6ab274849f9594ee9777f6efe70483129d067f97199d9ae36090703864f7ca4750a6f3b6ff83824c910484394d1e2eceba18446fe4e994ce07433a740ddd05f0e396d482894e6f14acf7b97bae6c7eb88703039fa785d60a3af78b13243a4f88dde1d998617f2e3fa7eafc2f435dd4ac1ea9c238407aa09b4eea8ed434927b406674ac270458cfb3bf29c347f94559613179b9502192321b88e9af0a90e9a4ab9eddaae382e3734d1415ebe32499c34e6fdeaf15b0d9787985e08dfe495460c54f6743d81ff16881e5e30c51f4b092373783f12423c3e1ae8591130a269980caa1cb5c
+SIG: b30eb56ca9b120bf849a3a9d56af033de8a590c9e1240c1e36dbc6cf0a71b78a11ec143fb9959a8f25b57711d6a90a67e01be3a4da2b69394869bb8d64b87e0f
+
+PRIV: 9c167aff3b1b788f133d422de8ca9a64316409f9e35bfe22032ec417ae9abc6defb534f0d47c068e77b28a906d95ad8d213a4d4fc1c70542f01e596d57b5f019
+PUB: efb534f0d47c068e77b28a906d95ad8d213a4d4fc1c70542f01e596d57b5f019
+MESSAGE: 68ac0fc2b607ba38e377fae845c808c8f9fa614eb1f31158a9620a937d3e301e85acaa69144bc349a39dfb582041c4a197ae99b4d4d59b7a2ca3d16228b5591cbf57c18a781efd19193c47b16c6023a3a8ba3d668f05a37f1e83b0d7febdd10f63e48ef7a20e015b1c6725d4c300a986c60e3a115469c8e52ba05b51c05d0af40d89fd9ed76f36950aee3c7819898a903cfe0361a91c69100b495141e86ee79d63d17403fb1a1629ef63cb7e9d2720cbfff0002b190bcdc26794124dd38d42bcaa7175405eb0bbcf8e37d65d05a37195b479371fa2bbbb167d91cee88235dd72ea88fc73ce3ce43d33b715f25f192ec215dac124899c5e7586e86340d8cbe53735defbe02e4cc9fde69fb9794d1db72b98c0f19766ee5138bbfa78909aa299b4913c499deaf54b4841d5044829984936700dcf92f36542b2fc7e86441b9925f5d0b78c17a85cfcfcb20b0fd751349c27463abde4d27df74265288713f96dea013b945521808b4996b1b2dc0338b6d236efd6d2b27dafda46ec5fa32b965e8bb5e8bb61bd966edeb774681e0ea8c17b8c99fa7d660f0f66c9bc6d95cbd7dc094724098eb05191b53a3df6566b9c90e0d7dff2943848b61a20d48c22b6d3c958e293d709c8f48110230ff51918562877daf6d920c85a82e07c451fe7ae9759c0a77e97bb298b5d0592a41d08f67a4ed5a1bb41e937b6a68aeb38fd5be9
+SIG: c9ae67fd6415dcbab292fab394ca6c3b7d90ca244dc6a7764e74fd202bf4b2905bd2030e6beb914c3c238db371b1cba6d9261aa392ec871a4b8b12fe9c1c970e
+
+PRIV: e9948805eb341b2867479c668fd3532c309941c0ad4cb2e54231756e6a1bdecb5447a8e34d6a640002d8d60bcf1ddc711e4c465c94c34b50bdef358960ff81f1
+PUB: 5447a8e34d6a640002d8d60bcf1ddc711e4c465c94c34b50bdef358960ff81f1
+MESSAGE: 91cffd7eb1cf6bd4756bce6a30af9dfba26ddd1cce0394c194a3e39cc3d1cbc221b7eb70bea18d29c267457176a3c9e53c18e47d10a67c464505197702e6b2470d38869db5174b158f9992e4435d02246f540258dedd3ce33df582555a681fb76ecaccb1c2989b177e3b7e454aaa529de59bf5a03123d571df2e7f7cb830805c58b74a653bac0e5a888e08dc2236d6cd496aa06d0d67cf3b335e218c49dedad82fc1be9ef20cac61905c30eb132d739b16ca8a8c906619c0e0d8b33985327e36f3d4b8fda387c186cc50443104db761f7ff9301270204a713e58902101fad000ce931647c577fdec148dca95cdc08918ebed037c60332fadf088f036083ebc92e173b7ddcc30c493f27e69cd17a20d30b78f83a72e4f5a747d86d96c5e1bb7a438166204013e2164d6aabc0d562f54015c365c80445607145e5692ee34f6353077fab7452d88ce3eb01d2b3797dc91b341a3a726301516baae18e851f74dfbdf0866bb2376867de55231e362c472c52116544cd4f81e93571c4ec820e7e653f4e21be0a942576c9de91e7d1251683d859de448f822dcf3d2cf55ede2f9c71b6063d1373061f8f5936b698d1384e65459ea2bc26ec96775ef425207432dda0ac1fe28526c5e4559349c3d8df9918230f4044683cc2c1b858d141ab8d0805bb9336067522aa89c810f3eaa7ac2d8dd28c3751225a19ecec8bcca52439946
+SIG: d3dc62d6ce9c766f2abaf9a7fbe09d6bdb07a4747b56080db09beb4a4e804a70d7ddf4119475c7be834f31956f4a71dad029cdf2363dd0365ce22dc27f078003
+
+PRIV: b01753efa73bb3de7aa778be7afcbff66a5d3e2c2f8b5aa2b048844050996965d0cc6cf109c999fbf6d16f471fafd0232b0a68d4c46406ec7545dbaba8194158
+PUB: d0cc6cf109c999fbf6d16f471fafd0232b0a68d4c46406ec7545dbaba8194158
+MESSAGE: 684e612f27eead0d34844cc81ba911c28aaf6d66e71229e8cc3462f7c7a050daa30cb74471150f07dad459b5a91358476c0598255d8a642dd7c0802811bd88e4cac597efe41ebd96cd0f3b5ce72db4be1a3dbd6b84f5446e3da600d3b1d2b460a009bd31cacd98a91518ce33e9a703d404288736ccc43103fc69e67974f31652fa3dadef3337f6c897a3d201303c8f03597b4a87c98f291ccd58a3f1e898332aa5993b47fcb5ddaa1c0868b643742d0e4a4b9cd427038b3b74999bc89ac3484c0ca13f25aae8e78ae1ccee6218accab81a4f694f5324a347629d49b55e4037504a9acc8df58c6841dddcd4fc4347f7b6f1fd9de0564577e6f329ed951a0a6b9124ff63e22eb36d3a8863bc1bf69cea24c605967e7d8948953f27d5c4c75f0849f872a3e3d16d422fa5a11e1b9a74df6f38b90f277d81fce8437a14d99d2bef189d7cac83ddc61377ed348b3c4fc09ec2b9005925d04a71e26d641667bdf549294331c6ea01cd5c0bd1b6a7ecfda20b0f1929582b74697cb262c3927d6b223f4b5f3043aa6eb4571a78e9da11c2b36f64552580caa7b5fa6b90f929e0162e608d1240d7242cd2f47025c03debe059b1dc94770232bc6765148480bb1d9f50da1ee6448cf9c88b19dd459932c06ed811c4a64a12d5938bd1c757bcfaeaee8933fe5fff21763de740482bcf1ba59afdc8fcf873c3d507bb394e32e45f736519
+SIG: 16b7421227ae09130685cbb1a0c60aa57a5e1afe1bbe6bacea0c281bcc8998e6824a772c3208a6b6b4d236695505c9be82700cf93a783985a39e16e377a7410e
+
+PRIV: 4f4b20d899366f2f23ee628f229b236cf80f43ba183177c97ee34829546f1742c94576641f4a893cdfcee7b39fc21929b86b349976d7b0a46d39a588bcfe4357
+PUB: c94576641f4a893cdfcee7b39fc21929b86b349976d7b0a46d39a588bcfe4357
+MESSAGE: db8ef02e3033e6b96a56cab05082fb4695f4a1c916250dd75173f430a10c9468817709d37623346ae8245b42bda0da6b60462ccfdfc75a9ab994e66c9ab9fecdd8599610910affe4f10215cb280bf8f9f2700a444796dae93e06c6bea7d8b4fe1301baa79ccec769368feb2442c7de84f095e6b3bff63d388cbafb2b9809dc38e9b12ebd039c0a57f4d522e91ec8d1f2b8d23a4a0ae059af85393bb0a15f749110f6774a1fd731a6ec213e4ff435daab546d31ed9ec3b6d8cc2edacebf4facc5566556eea92e5b3f2542239b25e28012dd4ef40072eebf83ed2a255181f3a442189d68c6c609f4dfdf3db7d67d087a2fcd6d2dc50bbfed8bfbbfcb74d3c41f02a87865b13b8efcf5c3581257be0aa913f60c370527bde11a475c136a17c5eefeb03f5bff28693ed841e8ed1f7c29102f5599dd444009bcea6a92d5574152458e0caf8a36aa72b5dc4908a6461c9b741453005c8fbcc68113ae184208ee14b835480c6efafed18a76000b38e5858290f4d51f52f096cbe490e1eb5cacb226ec495a55a7fa457843d57fab67f8be7e209334785bdd665d7b63e4daf57b6e78928b603c8c0f9bc85464733b61273ef9e2b8a0cd7c3bf8ee0a6872e34d5a27a625e35eaf7ff5440b8b141af704df70c9c18623bd11209513192505105cd7bcfa5f0d919da706948fbe1f761f315846aa3b4813dd9ba3d81b9204e5409c0382b6eb
+SIG: 0f80ff5d17488fe26f93c543b04ed959b5f0643fc61c7f2c3bc60132ba9c6210c8b250ea5e84d07b01de68bc174414eeeb31fdc2ba6823e231e312a91ededd02
diff --git a/src/crypto/curve25519/internal.h b/src/crypto/curve25519/internal.h
new file mode 100644
index 0000000..27994b7
--- /dev/null
+++ b/src/crypto/curve25519/internal.h
@@ -0,0 +1,45 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#ifndef OPENSSL_HEADER_CURVE25519_INTERNAL_H
+#define OPENSSL_HEADER_CURVE25519_INTERNAL_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+#if defined(OPENSSL_X86_64) && !defined(OPENSSL_SMALL) && \
+ !defined(OPENSSL_WINDOWS) && !defined(OPENSSL_NO_ASM)
+#define BORINGSSL_X25519_X86_64
+
+void x25519_x86_64(uint8_t out[32], const uint8_t scalar[32],
+ const uint8_t point[32]);
+#endif
+
+
+#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM)
+#define BORINGSSL_X25519_NEON
+
+/* x25519_NEON is defined in asm/x25519-arm.S. */
+void x25519_NEON(uint8_t out[32], const uint8_t scalar[32],
+ const uint8_t point[32]);
+#endif
+
+
+#if defined(__cplusplus)
+} /* extern C */
+#endif
+
+#endif /* OPENSSL_HEADER_CURVE25519_INTERNAL_H */
diff --git a/src/crypto/curve25519/x25519-x86_64.c b/src/crypto/curve25519/x25519-x86_64.c
new file mode 100644
index 0000000..9776c75
--- /dev/null
+++ b/src/crypto/curve25519/x25519-x86_64.c
@@ -0,0 +1,225 @@
+#include <openssl/curve25519.h>
+
+#include <string.h>
+
+#include "internal.h"
+
+
+#if defined(BORINGSSL_X25519_X86_64)
+
+typedef struct { uint64_t v[5]; } fe25519;
+
+/* These functions are defined in asm/x25519-x86_64.S */
+void x25519_x86_64_work_cswap(fe25519 *, uint64_t);
+void x25519_x86_64_mul(fe25519 *out, const fe25519 *a, const fe25519 *b);
+void x25519_x86_64_square(fe25519 *out, const fe25519 *a);
+void x25519_x86_64_freeze(fe25519 *);
+void x25519_x86_64_ladderstep(fe25519 *work);
+
+static void fe25519_setint(fe25519 *r, unsigned v) {
+ r->v[0] = v;
+ r->v[1] = 0;
+ r->v[2] = 0;
+ r->v[3] = 0;
+ r->v[4] = 0;
+}
+
+/* Assumes input x being reduced below 2^255 */
+static void fe25519_pack(unsigned char r[32], const fe25519 *x) {
+ fe25519 t;
+ t = *x;
+ x25519_x86_64_freeze(&t);
+
+ r[0] = (uint8_t)(t.v[0] & 0xff);
+ r[1] = (uint8_t)((t.v[0] >> 8) & 0xff);
+ r[2] = (uint8_t)((t.v[0] >> 16) & 0xff);
+ r[3] = (uint8_t)((t.v[0] >> 24) & 0xff);
+ r[4] = (uint8_t)((t.v[0] >> 32) & 0xff);
+ r[5] = (uint8_t)((t.v[0] >> 40) & 0xff);
+ r[6] = (uint8_t)((t.v[0] >> 48));
+
+ r[6] ^= (uint8_t)((t.v[1] << 3) & 0xf8);
+ r[7] = (uint8_t)((t.v[1] >> 5) & 0xff);
+ r[8] = (uint8_t)((t.v[1] >> 13) & 0xff);
+ r[9] = (uint8_t)((t.v[1] >> 21) & 0xff);
+ r[10] = (uint8_t)((t.v[1] >> 29) & 0xff);
+ r[11] = (uint8_t)((t.v[1] >> 37) & 0xff);
+ r[12] = (uint8_t)((t.v[1] >> 45));
+
+ r[12] ^= (uint8_t)((t.v[2] << 6) & 0xc0);
+ r[13] = (uint8_t)((t.v[2] >> 2) & 0xff);
+ r[14] = (uint8_t)((t.v[2] >> 10) & 0xff);
+ r[15] = (uint8_t)((t.v[2] >> 18) & 0xff);
+ r[16] = (uint8_t)((t.v[2] >> 26) & 0xff);
+ r[17] = (uint8_t)((t.v[2] >> 34) & 0xff);
+ r[18] = (uint8_t)((t.v[2] >> 42) & 0xff);
+ r[19] = (uint8_t)((t.v[2] >> 50));
+
+ r[19] ^= (uint8_t)((t.v[3] << 1) & 0xfe);
+ r[20] = (uint8_t)((t.v[3] >> 7) & 0xff);
+ r[21] = (uint8_t)((t.v[3] >> 15) & 0xff);
+ r[22] = (uint8_t)((t.v[3] >> 23) & 0xff);
+ r[23] = (uint8_t)((t.v[3] >> 31) & 0xff);
+ r[24] = (uint8_t)((t.v[3] >> 39) & 0xff);
+ r[25] = (uint8_t)((t.v[3] >> 47));
+
+ r[25] ^= (uint8_t)((t.v[4] << 4) & 0xf0);
+ r[26] = (uint8_t)((t.v[4] >> 4) & 0xff);
+ r[27] = (uint8_t)((t.v[4] >> 12) & 0xff);
+ r[28] = (uint8_t)((t.v[4] >> 20) & 0xff);
+ r[29] = (uint8_t)((t.v[4] >> 28) & 0xff);
+ r[30] = (uint8_t)((t.v[4] >> 36) & 0xff);
+ r[31] = (uint8_t)((t.v[4] >> 44));
+}
+
+static void fe25519_unpack(fe25519 *r, const uint8_t x[32]) {
+ r->v[0] = x[0];
+ r->v[0] += (uint64_t)x[1] << 8;
+ r->v[0] += (uint64_t)x[2] << 16;
+ r->v[0] += (uint64_t)x[3] << 24;
+ r->v[0] += (uint64_t)x[4] << 32;
+ r->v[0] += (uint64_t)x[5] << 40;
+ r->v[0] += ((uint64_t)x[6] & 7) << 48;
+
+ r->v[1] = x[6] >> 3;
+ r->v[1] += (uint64_t)x[7] << 5;
+ r->v[1] += (uint64_t)x[8] << 13;
+ r->v[1] += (uint64_t)x[9] << 21;
+ r->v[1] += (uint64_t)x[10] << 29;
+ r->v[1] += (uint64_t)x[11] << 37;
+ r->v[1] += ((uint64_t)x[12] & 63) << 45;
+
+ r->v[2] = x[12] >> 6;
+ r->v[2] += (uint64_t)x[13] << 2;
+ r->v[2] += (uint64_t)x[14] << 10;
+ r->v[2] += (uint64_t)x[15] << 18;
+ r->v[2] += (uint64_t)x[16] << 26;
+ r->v[2] += (uint64_t)x[17] << 34;
+ r->v[2] += (uint64_t)x[18] << 42;
+ r->v[2] += ((uint64_t)x[19] & 1) << 50;
+
+ r->v[3] = x[19] >> 1;
+ r->v[3] += (uint64_t)x[20] << 7;
+ r->v[3] += (uint64_t)x[21] << 15;
+ r->v[3] += (uint64_t)x[22] << 23;
+ r->v[3] += (uint64_t)x[23] << 31;
+ r->v[3] += (uint64_t)x[24] << 39;
+ r->v[3] += ((uint64_t)x[25] & 15) << 47;
+
+ r->v[4] = x[25] >> 4;
+ r->v[4] += (uint64_t)x[26] << 4;
+ r->v[4] += (uint64_t)x[27] << 12;
+ r->v[4] += (uint64_t)x[28] << 20;
+ r->v[4] += (uint64_t)x[29] << 28;
+ r->v[4] += (uint64_t)x[30] << 36;
+ r->v[4] += ((uint64_t)x[31] & 127) << 44;
+}
+
+static void fe25519_invert(fe25519 *r, const fe25519 *x) {
+ fe25519 z2;
+ fe25519 z9;
+ fe25519 z11;
+ fe25519 z2_5_0;
+ fe25519 z2_10_0;
+ fe25519 z2_20_0;
+ fe25519 z2_50_0;
+ fe25519 z2_100_0;
+ fe25519 t;
+ int i;
+
+ /* 2 */ x25519_x86_64_square(&z2, x);
+ /* 4 */ x25519_x86_64_square(&t, &z2);
+ /* 8 */ x25519_x86_64_square(&t, &t);
+ /* 9 */ x25519_x86_64_mul(&z9, &t, x);
+ /* 11 */ x25519_x86_64_mul(&z11, &z9, &z2);
+ /* 22 */ x25519_x86_64_square(&t, &z11);
+ /* 2^5 - 2^0 = 31 */ x25519_x86_64_mul(&z2_5_0, &t, &z9);
+
+ /* 2^6 - 2^1 */ x25519_x86_64_square(&t, &z2_5_0);
+ /* 2^20 - 2^10 */ for (i = 1; i < 5; i++) { x25519_x86_64_square(&t, &t); }
+ /* 2^10 - 2^0 */ x25519_x86_64_mul(&z2_10_0, &t, &z2_5_0);
+
+ /* 2^11 - 2^1 */ x25519_x86_64_square(&t, &z2_10_0);
+ /* 2^20 - 2^10 */ for (i = 1; i < 10; i++) { x25519_x86_64_square(&t, &t); }
+ /* 2^20 - 2^0 */ x25519_x86_64_mul(&z2_20_0, &t, &z2_10_0);
+
+ /* 2^21 - 2^1 */ x25519_x86_64_square(&t, &z2_20_0);
+ /* 2^40 - 2^20 */ for (i = 1; i < 20; i++) { x25519_x86_64_square(&t, &t); }
+ /* 2^40 - 2^0 */ x25519_x86_64_mul(&t, &t, &z2_20_0);
+
+ /* 2^41 - 2^1 */ x25519_x86_64_square(&t, &t);
+ /* 2^50 - 2^10 */ for (i = 1; i < 10; i++) { x25519_x86_64_square(&t, &t); }
+ /* 2^50 - 2^0 */ x25519_x86_64_mul(&z2_50_0, &t, &z2_10_0);
+
+ /* 2^51 - 2^1 */ x25519_x86_64_square(&t, &z2_50_0);
+ /* 2^100 - 2^50 */ for (i = 1; i < 50; i++) { x25519_x86_64_square(&t, &t); }
+ /* 2^100 - 2^0 */ x25519_x86_64_mul(&z2_100_0, &t, &z2_50_0);
+
+ /* 2^101 - 2^1 */ x25519_x86_64_square(&t, &z2_100_0);
+ /* 2^200 - 2^100 */ for (i = 1; i < 100; i++) {
+ x25519_x86_64_square(&t, &t);
+ }
+ /* 2^200 - 2^0 */ x25519_x86_64_mul(&t, &t, &z2_100_0);
+
+ /* 2^201 - 2^1 */ x25519_x86_64_square(&t, &t);
+ /* 2^250 - 2^50 */ for (i = 1; i < 50; i++) { x25519_x86_64_square(&t, &t); }
+ /* 2^250 - 2^0 */ x25519_x86_64_mul(&t, &t, &z2_50_0);
+
+ /* 2^251 - 2^1 */ x25519_x86_64_square(&t, &t);
+ /* 2^252 - 2^2 */ x25519_x86_64_square(&t, &t);
+ /* 2^253 - 2^3 */ x25519_x86_64_square(&t, &t);
+
+ /* 2^254 - 2^4 */ x25519_x86_64_square(&t, &t);
+
+ /* 2^255 - 2^5 */ x25519_x86_64_square(&t, &t);
+ /* 2^255 - 21 */ x25519_x86_64_mul(r, &t, &z11);
+}
+
+static void mladder(fe25519 *xr, fe25519 *zr, const uint8_t s[32]) {
+ fe25519 work[5];
+
+ work[0] = *xr;
+ fe25519_setint(work + 1, 1);
+ fe25519_setint(work + 2, 0);
+ work[3] = *xr;
+ fe25519_setint(work + 4, 1);
+
+ int i, j;
+ uint8_t prevbit = 0;
+
+ j = 6;
+ for (i = 31; i >= 0; i--) {
+ while (j >= 0) {
+ const uint8_t bit = 1 & (s[i] >> j);
+ const uint64_t swap = bit ^ prevbit;
+ prevbit = bit;
+ x25519_x86_64_work_cswap(work + 1, swap);
+ x25519_x86_64_ladderstep(work);
+ j -= 1;
+ }
+ j = 7;
+ }
+
+ *xr = work[1];
+ *zr = work[2];
+}
+
+void x25519_x86_64(uint8_t out[32], const uint8_t scalar[32],
+ const uint8_t point[32]) {
+ uint8_t e[32];
+ memcpy(e, scalar, sizeof(e));
+
+ e[0] &= 248;
+ e[31] &= 127;
+ e[31] |= 64;
+
+ fe25519 t;
+ fe25519 z;
+ fe25519_unpack(&t, point);
+ mladder(&t, &z, e);
+ fe25519_invert(&z, &z);
+ x25519_x86_64_mul(&t, &t, &z);
+ fe25519_pack(out, &t);
+}
+
+#endif /* BORINGSSL_X25519_X86_64 */
diff --git a/src/crypto/curve25519/x25519_test.cc b/src/crypto/curve25519/x25519_test.cc
new file mode 100644
index 0000000..85ee4a2
--- /dev/null
+++ b/src/crypto/curve25519/x25519_test.cc
@@ -0,0 +1,128 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <openssl/curve25519.h>
+
+
+static bool TestX25519() {
+ /* Taken from
+ * https://tools.ietf.org/html/draft-irtf-cfrg-curves-11#section-5.2 */
+ static const uint8_t kScalar1[32] = {
+ 0xa5, 0x46, 0xe3, 0x6b, 0xf0, 0x52, 0x7c, 0x9d, 0x3b, 0x16, 0x15,
+ 0x4b, 0x82, 0x46, 0x5e, 0xdd, 0x62, 0x14, 0x4c, 0x0a, 0xc1, 0xfc,
+ 0x5a, 0x18, 0x50, 0x6a, 0x22, 0x44, 0xba, 0x44, 0x9a, 0xc4,
+ };
+ static const uint8_t kPoint1[32] = {
+ 0xe6, 0xdb, 0x68, 0x67, 0x58, 0x30, 0x30, 0xdb, 0x35, 0x94, 0xc1,
+ 0xa4, 0x24, 0xb1, 0x5f, 0x7c, 0x72, 0x66, 0x24, 0xec, 0x26, 0xb3,
+ 0x35, 0x3b, 0x10, 0xa9, 0x03, 0xa6, 0xd0, 0xab, 0x1c, 0x4c,
+ };
+
+ uint8_t out[32];
+ X25519(out, kScalar1, kPoint1);
+
+ static const uint8_t kExpected1[32] = {
+ 0xc3, 0xda, 0x55, 0x37, 0x9d, 0xe9, 0xc6, 0x90, 0x8e, 0x94, 0xea,
+ 0x4d, 0xf2, 0x8d, 0x08, 0x4f, 0x32, 0xec, 0xcf, 0x03, 0x49, 0x1c,
+ 0x71, 0xf7, 0x54, 0xb4, 0x07, 0x55, 0x77, 0xa2, 0x85, 0x52,
+ };
+ if (memcmp(kExpected1, out, sizeof(out)) != 0) {
+ fprintf(stderr, "X25519 test one failed.\n");
+ return false;
+ }
+
+ static const uint8_t kScalar2[32] = {
+ 0x4b, 0x66, 0xe9, 0xd4, 0xd1, 0xb4, 0x67, 0x3c, 0x5a, 0xd2, 0x26,
+ 0x91, 0x95, 0x7d, 0x6a, 0xf5, 0xc1, 0x1b, 0x64, 0x21, 0xe0, 0xea,
+ 0x01, 0xd4, 0x2c, 0xa4, 0x16, 0x9e, 0x79, 0x18, 0xba, 0x0d,
+ };
+ static const uint8_t kPoint2[32] = {
+ 0xe5, 0x21, 0x0f, 0x12, 0x78, 0x68, 0x11, 0xd3, 0xf4, 0xb7, 0x95,
+ 0x9d, 0x05, 0x38, 0xae, 0x2c, 0x31, 0xdb, 0xe7, 0x10, 0x6f, 0xc0,
+ 0x3c, 0x3e, 0xfc, 0x4c, 0xd5, 0x49, 0xc7, 0x15, 0xa4, 0x93,
+ };
+
+ X25519(out, kScalar2, kPoint2);
+
+ static const uint8_t kExpected2[32] = {
+ 0x95, 0xcb, 0xde, 0x94, 0x76, 0xe8, 0x90, 0x7d, 0x7a, 0xad, 0xe4,
+ 0x5c, 0xb4, 0xb8, 0x73, 0xf8, 0x8b, 0x59, 0x5a, 0x68, 0x79, 0x9f,
+ 0xa1, 0x52, 0xe6, 0xf8, 0xf7, 0x64, 0x7a, 0xac, 0x79, 0x57,
+ };
+ if (memcmp(kExpected2, out, sizeof(out)) != 0) {
+ fprintf(stderr, "X25519 test two failed.\n");
+ return false;
+ }
+
+ return true;
+}
+
+static bool TestX25519SmallOrder() {
+ static const uint8_t kSmallOrderPoint[32] = {
+ 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3,
+ 0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32,
+ 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8,
+ };
+
+ uint8_t out[32], private_key[32];
+ memset(private_key, 0x11, sizeof(private_key));
+
+ if (X25519(out, private_key, kSmallOrderPoint)) {
+ fprintf(stderr, "X25519 returned success with a small-order input.\n");
+ return false;
+ }
+
+ return true;
+}
+
+static bool TestX25519Iterated() {
+ /* Taken from
+ * https://tools.ietf.org/html/draft-irtf-cfrg-curves-11#section-5.2 */
+ uint8_t scalar[32] = {9}, point[32] = {9}, out[32];
+
+ unsigned i;
+ for (i = 0; i < 1000; i++) {
+ X25519(out, scalar, point);
+ memcpy(point, scalar, sizeof(point));
+ memcpy(scalar, out, sizeof(scalar));
+ }
+
+ static const uint8_t kExpected[32] = {
+ 0x68, 0x4c, 0xf5, 0x9b, 0xa8, 0x33, 0x09, 0x55, 0x28, 0x00, 0xef,
+ 0x56, 0x6f, 0x2f, 0x4d, 0x3c, 0x1c, 0x38, 0x87, 0xc4, 0x93, 0x60,
+ 0xe3, 0x87, 0x5f, 0x2e, 0xb9, 0x4d, 0x99, 0x53, 0x2c, 0x51,
+ };
+
+ if (memcmp(kExpected, scalar, sizeof(kExpected)) != 0) {
+ fprintf(stderr, "Iterated X25519 test failed\n");
+ return false;
+ }
+
+ return true;
+}
+
+int main(int argc, char **argv) {
+ if (!TestX25519() ||
+ !TestX25519Iterated() ||
+ !TestX25519SmallOrder()) {
+ return 1;
+ }
+
+ printf("PASS\n");
+ return 0;
+}
diff --git a/src/crypto/des/internal.h b/src/crypto/des/internal.h
index 91559ff..00b4558 100644
--- a/src/crypto/des/internal.h
+++ b/src/crypto/des/internal.h
@@ -202,24 +202,7 @@ how to use xors :-) I got it to its final state.
#define ITERATIONS 16
#define HALF_ITERATIONS 8
-#if defined(_MSC_VER)
-#define ROTATE(a, n) (_lrotr(a, n))
-#elif defined(__ICC)
-#define ROTATE(a, n) (_rotr(a, n))
-#elif defined(__GNUC__) && __GNUC__ >= 2 && !defined(OPENSSL_NO_ASM) && \
- !defined(__STRICT_ANSI__) && \
- (defined(OPENSSL_X86) || defined(OPENSSL_X86_64))
-#define ROTATE(a, n) \
- ({ \
- unsigned int ret; \
- asm("rorl %1,%0" : "=r"(ret) : "I"(n), "0"(a) : "cc"); \
- ret; \
- })
-#endif
-
-#ifndef ROTATE
#define ROTATE(a, n) (((a) >> (n)) + ((a) << (32 - (n))))
-#endif
#if defined(__cplusplus)
diff --git a/src/crypto/dh/dh.c b/src/crypto/dh/dh.c
index a88520d..bf6196c 100644
--- a/src/crypto/dh/dh.c
+++ b/src/crypto/dh/dh.c
@@ -85,11 +85,7 @@ DH *DH_new(void) {
CRYPTO_MUTEX_init(&dh->method_mont_p_lock);
dh->references = 1;
- if (!CRYPTO_new_ex_data(&g_ex_data_class, dh, &dh->ex_data)) {
- CRYPTO_MUTEX_cleanup(&dh->method_mont_p_lock);
- OPENSSL_free(dh);
- return NULL;
- }
+ CRYPTO_new_ex_data(&dh->ex_data);
return dh;
}
@@ -239,11 +235,16 @@ int DH_generate_key(DH *dh) {
int ok = 0;
int generate_new_key = 0;
unsigned l;
- BN_CTX *ctx;
+ BN_CTX *ctx = NULL;
BN_MONT_CTX *mont = NULL;
BIGNUM *pub_key = NULL, *priv_key = NULL;
BIGNUM local_priv;
+ if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) {
+ OPENSSL_PUT_ERROR(DH, DH_R_MODULUS_TOO_LARGE);
+ goto err;
+ }
+
ctx = BN_CTX_new();
if (ctx == NULL) {
goto err;
@@ -443,11 +444,11 @@ DH *DHparams_dup(const DH *dh) {
return ret;
}
-int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
int index;
- if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, new_func,
- dup_func, free_func)) {
+ if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func,
+ free_func)) {
return -1;
}
return index;
diff --git a/src/crypto/dh/dh_test.cc b/src/crypto/dh/dh_test.cc
index 16a5ae0..c117bd4 100644
--- a/src/crypto/dh/dh_test.cc
+++ b/src/crypto/dh/dh_test.cc
@@ -68,7 +68,6 @@
#include "internal.h"
#include "../test/scoped_types.h"
-#include "../test/stl_compat.h"
static bool RunBasicTests();
@@ -167,7 +166,7 @@ static bool RunBasicTests() {
printf("\n");
std::vector<uint8_t> key1(DH_size(a.get()));
- int ret = DH_compute_key(bssl::vector_data(&key1), b->pub_key, a.get());
+ int ret = DH_compute_key(key1.data(), b->pub_key, a.get());
if (ret < 0) {
return false;
}
@@ -180,7 +179,7 @@ static bool RunBasicTests() {
printf("\n");
std::vector<uint8_t> key2(DH_size(b.get()));
- ret = DH_compute_key(bssl::vector_data(&key2), a->pub_key, b.get());
+ ret = DH_compute_key(key2.data(), a->pub_key, b.get());
if (ret < 0) {
return false;
}
@@ -458,17 +457,17 @@ static bool RunRFC5114Tests() {
std::vector<uint8_t> Z2(DH_size(dhB.get()));
/* Work out shared secrets using both sides and compare
* with expected values. */
- int ret1 = DH_compute_key(bssl::vector_data(&Z1), dhB->pub_key, dhA.get());
- int ret2 = DH_compute_key(bssl::vector_data(&Z2), dhA->pub_key, dhB.get());
+ int ret1 = DH_compute_key(Z1.data(), dhB->pub_key, dhA.get());
+ int ret2 = DH_compute_key(Z2.data(), dhA->pub_key, dhB.get());
if (ret1 < 0 || ret2 < 0) {
fprintf(stderr, "DH_compute_key error RFC5114 set %u\n", i + 1);
return false;
}
if (static_cast<size_t>(ret1) != td->Z_len ||
- memcmp(bssl::vector_data(&Z1), td->Z, td->Z_len) != 0 ||
+ memcmp(Z1.data(), td->Z, td->Z_len) != 0 ||
static_cast<size_t>(ret2) != td->Z_len ||
- memcmp(bssl::vector_data(&Z2), td->Z, td->Z_len) != 0) {
+ memcmp(Z2.data(), td->Z, td->Z_len) != 0) {
fprintf(stderr, "Test failed RFC5114 set %u\n", i + 1);
return false;
}
diff --git a/src/crypto/dh/params.c b/src/crypto/dh/params.c
index 6b30036..7e8102a 100644
--- a/src/crypto/dh/params.c
+++ b/src/crypto/dh/params.c
@@ -55,182 +55,169 @@
#include <openssl/bn.h>
#include "internal.h"
+#include "../bn/internal.h"
-#if BN_BITS2 == 32
-#define TOBN(lo, hi) lo, hi
-#elif BN_BITS2 == 64
-#define TOBN(lo, hi) ((BN_ULONG)hi << 32 | lo)
-#else
-#error "unsupported BN_BITS2"
-#endif
-
static const BN_ULONG dh1024_160_p[] = {
- TOBN(0x2E4A4371, 0xDF1FB2BC), TOBN(0x6D4DA708, 0xE68CFDA7),
- TOBN(0x365C1A65, 0x45BF37DF), TOBN(0x0DC8B4BD, 0xA151AF5F),
- TOBN(0xF55BCCC0, 0xFAA31A4F), TOBN(0xE5644738, 0x4EFFD6FA),
- TOBN(0x219A7372, 0x98488E9C), TOBN(0x90C4BD70, 0xACCBDD7D),
- TOBN(0xD49B83BF, 0x24975C3C), TOBN(0xA9061123, 0x13ECB4AE),
- TOBN(0x2EE652C0, 0x9838EF1E), TOBN(0x75A23D18, 0x6073E286),
- TOBN(0x52D23B61, 0x9A6A9DCA), TOBN(0xFB06A3C6, 0x52C99FBC),
- TOBN(0xAE5D54EC, 0xDE92DE5E), TOBN(0xA080E01D, 0xB10B8F96),
+ TOBN(0xDF1FB2BC, 0x2E4A4371), TOBN(0xE68CFDA7, 0x6D4DA708),
+ TOBN(0x45BF37DF, 0x365C1A65), TOBN(0xA151AF5F, 0x0DC8B4BD),
+ TOBN(0xFAA31A4F, 0xF55BCCC0), TOBN(0x4EFFD6FA, 0xE5644738),
+ TOBN(0x98488E9C, 0x219A7372), TOBN(0xACCBDD7D, 0x90C4BD70),
+ TOBN(0x24975C3C, 0xD49B83BF), TOBN(0x13ECB4AE, 0xA9061123),
+ TOBN(0x9838EF1E, 0x2EE652C0), TOBN(0x6073E286, 0x75A23D18),
+ TOBN(0x9A6A9DCA, 0x52D23B61), TOBN(0x52C99FBC, 0xFB06A3C6),
+ TOBN(0xDE92DE5E, 0xAE5D54EC), TOBN(0xB10B8F96, 0xA080E01D),
};
static const BN_ULONG dh1024_160_g[] = {
- TOBN(0x22B3B2E5, 0x855E6EEB), TOBN(0xF97C2A24, 0x858F4DCE),
- TOBN(0x18D08BC8, 0x2D779D59), TOBN(0x8E73AFA3, 0xD662A4D1),
- TOBN(0x69B6A28A, 0x1DBF0A01), TOBN(0x7A091F53, 0xA6A24C08),
- TOBN(0x63F80A76, 0x909D0D22), TOBN(0xB9A92EE1, 0xD7FBD7D3),
- TOBN(0x9E2749F4, 0x5E91547F), TOBN(0xB01B886A, 0x160217B4),
- TOBN(0x5504F213, 0x777E690F), TOBN(0x5C41564B, 0x266FEA1E),
- TOBN(0x14266D31, 0xD6406CFF), TOBN(0x58AC507F, 0xF8104DD2),
- TOBN(0xEFB99905, 0x6765A442), TOBN(0xC3FD3412, 0xA4D1CBD5),
+ TOBN(0x855E6EEB, 0x22B3B2E5), TOBN(0x858F4DCE, 0xF97C2A24),
+ TOBN(0x2D779D59, 0x18D08BC8), TOBN(0xD662A4D1, 0x8E73AFA3),
+ TOBN(0x1DBF0A01, 0x69B6A28A), TOBN(0xA6A24C08, 0x7A091F53),
+ TOBN(0x909D0D22, 0x63F80A76), TOBN(0xD7FBD7D3, 0xB9A92EE1),
+ TOBN(0x5E91547F, 0x9E2749F4), TOBN(0x160217B4, 0xB01B886A),
+ TOBN(0x777E690F, 0x5504F213), TOBN(0x266FEA1E, 0x5C41564B),
+ TOBN(0xD6406CFF, 0x14266D31), TOBN(0xF8104DD2, 0x58AC507F),
+ TOBN(0x6765A442, 0xEFB99905), TOBN(0xA4D1CBD5, 0xC3FD3412),
};
static const BN_ULONG dh1024_160_q[] = {
- TOBN(0x49462353, 0x64B7CB9D), TOBN(0x8ABA4E7D, 0x81A8DF27), 0xF518AA87,
+ TOBN(0x64B7CB9D, 0x49462353), TOBN(0x81A8DF27, 0x8ABA4E7D), 0xF518AA87,
};
static const BN_ULONG dh2048_224_p[] = {
- TOBN(0x0C10E64F, 0x0AC4DFFE), TOBN(0x4E71B81C, 0xCF9DE538),
- TOBN(0xFFA31F71, 0x7EF363E2), TOBN(0x6B8E75B9, 0xE3FB73C1),
- TOBN(0x4BA80A29, 0xC9B53DCF), TOBN(0x16E79763, 0x23F10B0E),
- TOBN(0x13042E9B, 0xC52172E4), TOBN(0xC928B2B9, 0xBE60E69C),
- TOBN(0xB9E587E8, 0x80CD86A1), TOBN(0x98C641A4, 0x315D75E1),
- TOBN(0x44328387, 0xCDF93ACC), TOBN(0xDC0A486D, 0x15987D9A),
- TOBN(0x1FD5A074, 0x7310F712), TOBN(0xDE31EFDC, 0x278273C7),
- TOBN(0x415D9330, 0x1602E714), TOBN(0xBC8985DB, 0x81286130),
- TOBN(0x70918836, 0xB3BF8A31), TOBN(0xB9C49708, 0x6A00E0A0),
- TOBN(0x8BBC27BE, 0xC6BA0B2C), TOBN(0xED34DBF6, 0xC9F98D11),
- TOBN(0xB6C12207, 0x7AD5B7D0), TOBN(0x55B7394B, 0xD91E8FEF),
- TOBN(0xEFDA4DF8, 0x9037C9ED), TOBN(0xAD6AC212, 0x6D3F8152),
- TOBN(0x1274A0A6, 0x1DE6B85A), TOBN(0x309C180E, 0xEB3D688A),
- TOBN(0x7BA1DF15, 0xAF9A3C40), TOBN(0xF95A56DB, 0xE6FA141D),
- TOBN(0xB61D0A75, 0xB54B1597), TOBN(0x683B9FD1, 0xA20D64E5),
- TOBN(0x9559C51F, 0xD660FAA7), TOBN(0x9123A9D0, 0xAD107E1E),
+ TOBN(0x0AC4DFFE, 0x0C10E64F), TOBN(0xCF9DE538, 0x4E71B81C),
+ TOBN(0x7EF363E2, 0xFFA31F71), TOBN(0xE3FB73C1, 0x6B8E75B9),
+ TOBN(0xC9B53DCF, 0x4BA80A29), TOBN(0x23F10B0E, 0x16E79763),
+ TOBN(0xC52172E4, 0x13042E9B), TOBN(0xBE60E69C, 0xC928B2B9),
+ TOBN(0x80CD86A1, 0xB9E587E8), TOBN(0x315D75E1, 0x98C641A4),
+ TOBN(0xCDF93ACC, 0x44328387), TOBN(0x15987D9A, 0xDC0A486D),
+ TOBN(0x7310F712, 0x1FD5A074), TOBN(0x278273C7, 0xDE31EFDC),
+ TOBN(0x1602E714, 0x415D9330), TOBN(0x81286130, 0xBC8985DB),
+ TOBN(0xB3BF8A31, 0x70918836), TOBN(0x6A00E0A0, 0xB9C49708),
+ TOBN(0xC6BA0B2C, 0x8BBC27BE), TOBN(0xC9F98D11, 0xED34DBF6),
+ TOBN(0x7AD5B7D0, 0xB6C12207), TOBN(0xD91E8FEF, 0x55B7394B),
+ TOBN(0x9037C9ED, 0xEFDA4DF8), TOBN(0x6D3F8152, 0xAD6AC212),
+ TOBN(0x1DE6B85A, 0x1274A0A6), TOBN(0xEB3D688A, 0x309C180E),
+ TOBN(0xAF9A3C40, 0x7BA1DF15), TOBN(0xE6FA141D, 0xF95A56DB),
+ TOBN(0xB54B1597, 0xB61D0A75), TOBN(0xA20D64E5, 0x683B9FD1),
+ TOBN(0xD660FAA7, 0x9559C51F), TOBN(0xAD107E1E, 0x9123A9D0),
};
static const BN_ULONG dh2048_224_g[] = {
- TOBN(0x191F2BFA, 0x84B890D3), TOBN(0x2A7065B3, 0x81BC087F),
- TOBN(0xF6EC0179, 0x19C418E1), TOBN(0x71CFFF4C, 0x7B5A0F1C),
- TOBN(0x9B6AA4BD, 0xEDFE72FE), TOBN(0x94B30269, 0x81E1BCFE),
- TOBN(0x8D6C0191, 0x566AFBB4), TOBN(0x409D13CD, 0xB539CCE3),
- TOBN(0x5F2FF381, 0x6AA21E7F), TOBN(0x770589EF, 0xD9E263E4),
- TOBN(0xD19963DD, 0x10E183ED), TOBN(0x150B8EEB, 0xB70A8137),
- TOBN(0x28C8F8AC, 0x051AE3D4), TOBN(0x0C1AB15B, 0xBB77A86F),
- TOBN(0x16A330EF, 0x6E3025E3), TOBN(0xD6F83456, 0x19529A45),
- TOBN(0x118E98D1, 0xF180EB34), TOBN(0x50717CBE, 0xB5F6C6B2),
- TOBN(0xDA7460CD, 0x09939D54), TOBN(0x22EA1ED4, 0xE2471504),
- TOBN(0x521BC98A, 0xB8A762D0), TOBN(0x5AC1348B, 0xF4D02727),
- TOBN(0x1999024A, 0xC1766910), TOBN(0xA8D66AD7, 0xBE5E9001),
- TOBN(0x620A8652, 0xC57DB17C), TOBN(0x00C29F52, 0xAB739D77),
- TOBN(0xA70C4AFA, 0xDD921F01), TOBN(0x10B9A6F0, 0xA6824A4E),
- TOBN(0xCFE4FFE3, 0x74866A08), TOBN(0x89998CAF, 0x6CDEBE7B),
- TOBN(0x8FFDAC50, 0x9DF30B5C), TOBN(0x4F2D9AE3, 0xAC4032EF),
+ TOBN(0x84B890D3, 0x191F2BFA), TOBN(0x81BC087F, 0x2A7065B3),
+ TOBN(0x19C418E1, 0xF6EC0179), TOBN(0x7B5A0F1C, 0x71CFFF4C),
+ TOBN(0xEDFE72FE, 0x9B6AA4BD), TOBN(0x81E1BCFE, 0x94B30269),
+ TOBN(0x566AFBB4, 0x8D6C0191), TOBN(0xB539CCE3, 0x409D13CD),
+ TOBN(0x6AA21E7F, 0x5F2FF381), TOBN(0xD9E263E4, 0x770589EF),
+ TOBN(0x10E183ED, 0xD19963DD), TOBN(0xB70A8137, 0x150B8EEB),
+ TOBN(0x051AE3D4, 0x28C8F8AC), TOBN(0xBB77A86F, 0x0C1AB15B),
+ TOBN(0x6E3025E3, 0x16A330EF), TOBN(0x19529A45, 0xD6F83456),
+ TOBN(0xF180EB34, 0x118E98D1), TOBN(0xB5F6C6B2, 0x50717CBE),
+ TOBN(0x09939D54, 0xDA7460CD), TOBN(0xE2471504, 0x22EA1ED4),
+ TOBN(0xB8A762D0, 0x521BC98A), TOBN(0xF4D02727, 0x5AC1348B),
+ TOBN(0xC1766910, 0x1999024A), TOBN(0xBE5E9001, 0xA8D66AD7),
+ TOBN(0xC57DB17C, 0x620A8652), TOBN(0xAB739D77, 0x00C29F52),
+ TOBN(0xDD921F01, 0xA70C4AFA), TOBN(0xA6824A4E, 0x10B9A6F0),
+ TOBN(0x74866A08, 0xCFE4FFE3), TOBN(0x6CDEBE7B, 0x89998CAF),
+ TOBN(0x9DF30B5C, 0x8FFDAC50), TOBN(0xAC4032EF, 0x4F2D9AE3),
};
static const BN_ULONG dh2048_224_q[] = {
- TOBN(0xB36371EB, 0xBF389A99), TOBN(0x4738CEBC, 0x1F80535A),
- TOBN(0x99717710, 0xC58D93FE), 0x801C0D34,
+ TOBN(0xBF389A99, 0xB36371EB), TOBN(0x1F80535A, 0x4738CEBC),
+ TOBN(0xC58D93FE, 0x99717710), 0x801C0D34,
};
static const BN_ULONG dh2048_256_p[] = {
- TOBN(0x1E1A1597, 0xDB094AE9), TOBN(0xD7EF09CA, 0x693877FA),
- TOBN(0x6E11715F, 0x6116D227), TOBN(0xC198AF12, 0xA4B54330),
- TOBN(0xD7014103, 0x75F26375), TOBN(0x54E710C3, 0xC3A3960A),
- TOBN(0xBD0BE621, 0xDED4010A), TOBN(0x89962856, 0xC0B857F6),
- TOBN(0x71506026, 0xB3CA3F79), TOBN(0xE6B486F6, 0x1CCACB83),
- TOBN(0x14056425, 0x67E144E5), TOBN(0xA41825D9, 0xF6A167B5),
- TOBN(0x96524D8E, 0x3AD83477), TOBN(0x51BFA4AB, 0xF13C6D9A),
- TOBN(0x35488A0E, 0x2D525267), TOBN(0xCAA6B790, 0xB63ACAE1),
- TOBN(0x81B23F76, 0x4FDB70C5), TOBN(0x12307F5C, 0xBC39A0BF),
- TOBN(0xB1E59BB8, 0xB941F54E), TOBN(0xD45F9088, 0x6C5BFC11),
- TOBN(0x4275BF7B, 0x22E0B1EF), TOBN(0x5B4758C0, 0x91F9E672),
- TOBN(0x6BCF67ED, 0x5A8A9D30), TOBN(0x97517ABD, 0x209E0C64),
- TOBN(0x830E9A7C, 0x3BF4296D), TOBN(0x34096FAA, 0x16C3D911),
- TOBN(0x61B2AA30, 0xFAF7DF45), TOBN(0xD61957D4, 0xE00DF8F1),
- TOBN(0x435E3B00, 0x5D2CEED4), TOBN(0x660DD0F2, 0x8CEEF608),
- TOBN(0x65195999, 0xFFBBD19C), TOBN(0xB4B6663C, 0x87A8E61D),
+ TOBN(0xDB094AE9, 0x1E1A1597), TOBN(0x693877FA, 0xD7EF09CA),
+ TOBN(0x6116D227, 0x6E11715F), TOBN(0xA4B54330, 0xC198AF12),
+ TOBN(0x75F26375, 0xD7014103), TOBN(0xC3A3960A, 0x54E710C3),
+ TOBN(0xDED4010A, 0xBD0BE621), TOBN(0xC0B857F6, 0x89962856),
+ TOBN(0xB3CA3F79, 0x71506026), TOBN(0x1CCACB83, 0xE6B486F6),
+ TOBN(0x67E144E5, 0x14056425), TOBN(0xF6A167B5, 0xA41825D9),
+ TOBN(0x3AD83477, 0x96524D8E), TOBN(0xF13C6D9A, 0x51BFA4AB),
+ TOBN(0x2D525267, 0x35488A0E), TOBN(0xB63ACAE1, 0xCAA6B790),
+ TOBN(0x4FDB70C5, 0x81B23F76), TOBN(0xBC39A0BF, 0x12307F5C),
+ TOBN(0xB941F54E, 0xB1E59BB8), TOBN(0x6C5BFC11, 0xD45F9088),
+ TOBN(0x22E0B1EF, 0x4275BF7B), TOBN(0x91F9E672, 0x5B4758C0),
+ TOBN(0x5A8A9D30, 0x6BCF67ED), TOBN(0x209E0C64, 0x97517ABD),
+ TOBN(0x3BF4296D, 0x830E9A7C), TOBN(0x16C3D911, 0x34096FAA),
+ TOBN(0xFAF7DF45, 0x61B2AA30), TOBN(0xE00DF8F1, 0xD61957D4),
+ TOBN(0x5D2CEED4, 0x435E3B00), TOBN(0x8CEEF608, 0x660DD0F2),
+ TOBN(0xFFBBD19C, 0x65195999), TOBN(0x87A8E61D, 0xB4B6663C),
};
static const BN_ULONG dh2048_256_g[] = {
- TOBN(0x6CC41659, 0x664B4C0F), TOBN(0xEF98C582, 0x5E2327CF),
- TOBN(0xD4795451, 0xD647D148), TOBN(0x90F00EF8, 0x2F630784),
- TOBN(0x1DB246C3, 0x184B523D), TOBN(0xCDC67EB6, 0xC7891428),
- TOBN(0x0DF92B52, 0x7FD02837), TOBN(0x64E0EC37, 0xB3353BBB),
- TOBN(0x57CD0915, 0xECD06E15), TOBN(0xDF016199, 0xB7D2BBD2),
- TOBN(0x052588B9, 0xC8484B1E), TOBN(0x13D3FE14, 0xDB2A3B73),
- TOBN(0xD182EA0A, 0xD052B985), TOBN(0xE83B9C80, 0xA4BD1BFF),
- TOBN(0xFB3F2E55, 0xDFC967C1), TOBN(0x767164E1, 0xB5045AF2),
- TOBN(0x6F2F9193, 0x1D14348F), TOBN(0x428EBC83, 0x64E67982),
- TOBN(0x82D6ED38, 0x8AC376D2), TOBN(0xAAB8A862, 0x777DE62A),
- TOBN(0xE9EC144B, 0xDDF463E5), TOBN(0xC77A57F2, 0x0196F931),
- TOBN(0x41000A65, 0xA55AE313), TOBN(0xC28CBB18, 0x901228F8),
- TOBN(0x7E8C6F62, 0xBC3773BF), TOBN(0x0C6B47B1, 0xBE3A6C1B),
- TOBN(0xAC0BB555, 0xFF4FED4A), TOBN(0x77BE463F, 0x10DBC150),
- TOBN(0x1A0BA125, 0x07F4793A), TOBN(0x21EF2054, 0x4CA7B18F),
- TOBN(0x60EDBD48, 0x2E775066), TOBN(0x73134D0B, 0x3FB32C9B),
+ TOBN(0x664B4C0F, 0x6CC41659), TOBN(0x5E2327CF, 0xEF98C582),
+ TOBN(0xD647D148, 0xD4795451), TOBN(0x2F630784, 0x90F00EF8),
+ TOBN(0x184B523D, 0x1DB246C3), TOBN(0xC7891428, 0xCDC67EB6),
+ TOBN(0x7FD02837, 0x0DF92B52), TOBN(0xB3353BBB, 0x64E0EC37),
+ TOBN(0xECD06E15, 0x57CD0915), TOBN(0xB7D2BBD2, 0xDF016199),
+ TOBN(0xC8484B1E, 0x052588B9), TOBN(0xDB2A3B73, 0x13D3FE14),
+ TOBN(0xD052B985, 0xD182EA0A), TOBN(0xA4BD1BFF, 0xE83B9C80),
+ TOBN(0xDFC967C1, 0xFB3F2E55), TOBN(0xB5045AF2, 0x767164E1),
+ TOBN(0x1D14348F, 0x6F2F9193), TOBN(0x64E67982, 0x428EBC83),
+ TOBN(0x8AC376D2, 0x82D6ED38), TOBN(0x777DE62A, 0xAAB8A862),
+ TOBN(0xDDF463E5, 0xE9EC144B), TOBN(0x0196F931, 0xC77A57F2),
+ TOBN(0xA55AE313, 0x41000A65), TOBN(0x901228F8, 0xC28CBB18),
+ TOBN(0xBC3773BF, 0x7E8C6F62), TOBN(0xBE3A6C1B, 0x0C6B47B1),
+ TOBN(0xFF4FED4A, 0xAC0BB555), TOBN(0x10DBC150, 0x77BE463F),
+ TOBN(0x07F4793A, 0x1A0BA125), TOBN(0x4CA7B18F, 0x21EF2054),
+ TOBN(0x2E775066, 0x60EDBD48), TOBN(0x3FB32C9B, 0x73134D0B),
};
static const BN_ULONG dh2048_256_q[] = {
- TOBN(0x64F5FBD3, 0xA308B0FE), TOBN(0x1EB3750B, 0x99B1A47D),
- TOBN(0x40129DA2, 0xB4479976), TOBN(0xA709A097, 0x8CF83642),
+ TOBN(0xA308B0FE, 0x64F5FBD3), TOBN(0x99B1A47D, 0x1EB3750B),
+ TOBN(0xB4479976, 0x40129DA2), TOBN(0x8CF83642, 0xA709A097),
};
/* dh1024_safe_prime_1 is hard-coded in Apache httpd 2.2,
* modules/ssl/ssl_engine_dh.c. */
static const BN_ULONG dh1024_safe_prime_1[] = {
- TOBN(0x24218EB3, 0xE7393E0F), TOBN(0xE2BD68B0, 0x7DE0F4D6),
- TOBN(0x88AEAA74, 0x07DD62DB), TOBN(0x9DDD3305, 0x10EA9FCC),
- TOBN(0x74087D15, 0xA7DBCA78), TOBN(0x78045B07, 0xDAE88600),
- TOBN(0x1AAD3B72, 0x33168A46), TOBN(0x7BEDDCFD, 0xFF590137),
- TOBN(0x7A635E81, 0xFE324A46), TOBN(0x420B2A29, 0x5AC179BA),
- TOBN(0x177E16D5, 0x13B4B4D7), TOBN(0x639C72FB, 0x849F912E),
- TOBN(0x98BCE951, 0xB88174CB), TOBN(0xA45F520B, 0x0C84D239),
- TOBN(0x4AFD0AD5, 0x36D693D3), TOBN(0xCBBBDC19, 0xD67DE440),
+ TOBN(0xE7393E0F, 0x24218EB3), TOBN(0x7DE0F4D6, 0xE2BD68B0),
+ TOBN(0x07DD62DB, 0x88AEAA74), TOBN(0x10EA9FCC, 0x9DDD3305),
+ TOBN(0xA7DBCA78, 0x74087D15), TOBN(0xDAE88600, 0x78045B07),
+ TOBN(0x33168A46, 0x1AAD3B72), TOBN(0xFF590137, 0x7BEDDCFD),
+ TOBN(0xFE324A46, 0x7A635E81), TOBN(0x5AC179BA, 0x420B2A29),
+ TOBN(0x13B4B4D7, 0x177E16D5), TOBN(0x849F912E, 0x639C72FB),
+ TOBN(0xB88174CB, 0x98BCE951), TOBN(0x0C84D239, 0xA45F520B),
+ TOBN(0x36D693D3, 0x4AFD0AD5), TOBN(0xD67DE440, 0xCBBBDC19),
};
/* dh1024_safe_prime_2 is hard-coded in nginx,
* src/event/ngx_event_openssl.c. */
static const BN_ULONG dh1024_safe_prime_2[] = {
- TOBN(0xCFE16B9B, 0x071DF045), TOBN(0x146757DA, 0x88D0F65D),
- TOBN(0x58FAFD49, 0x4A63AB1E), TOBN(0xEF9EA027, 0x35D8CECE),
- TOBN(0x70CC9A50, 0x25ECE662), TOBN(0x81DC2CA7, 0xF29BA5DF),
- TOBN(0xF7D36CC8, 0x8F68B076), TOBN(0xA757E304, 0x60E91A92),
- TOBN(0x9BE67780, 0x87A2BC04), TOBN(0xA5FDF1D2, 0xBEECA565),
- TOBN(0x922614C5, 0x5CCBBAA8), TOBN(0xE710800C, 0x6C030276),
- TOBN(0x0FB3504C, 0x08EED4EB), TOBN(0x68B42D4B, 0xD958A3F5),
- TOBN(0x80E9CFDB, 0x7C43FCF5), TOBN(0xD8467490, 0xBBBC2DCA),
+ TOBN(0x071DF045, 0xCFE16B9B), TOBN(0x88D0F65D, 0x146757DA),
+ TOBN(0x4A63AB1E, 0x58FAFD49), TOBN(0x35D8CECE, 0xEF9EA027),
+ TOBN(0x25ECE662, 0x70CC9A50), TOBN(0xF29BA5DF, 0x81DC2CA7),
+ TOBN(0x8F68B076, 0xF7D36CC8), TOBN(0x60E91A92, 0xA757E304),
+ TOBN(0x87A2BC04, 0x9BE67780), TOBN(0xBEECA565, 0xA5FDF1D2),
+ TOBN(0x5CCBBAA8, 0x922614C5), TOBN(0x6C030276, 0xE710800C),
+ TOBN(0x08EED4EB, 0x0FB3504C), TOBN(0xD958A3F5, 0x68B42D4B),
+ TOBN(0x7C43FCF5, 0x80E9CFDB), TOBN(0xBBBC2DCA, 0xD8467490),
};
/* dh1024_safe_prime_3 is offered as a parameter by several high-traffic sites,
* including mozilla.org, as of Jan 2015. */
static const BN_ULONG dh1024_safe_prime_3[] = {
- TOBN(0x349E721B, 0x671746AE), TOBN(0xD75E93B2, 0x258A0655),
- TOBN(0x25592EB6, 0xD425E6FB), TOBN(0xBF7CDD9A, 0x0C46AB04),
- TOBN(0x28968680, 0x0AD0BC99), TOBN(0xD0B7EB49, 0xF53907FB),
- TOBN(0xEBC85C1D, 0x202EABB3), TOBN(0x364D8C71, 0x3129C693),
- TOBN(0x2D46F195, 0x53728351), TOBN(0x8C76CC85, 0xDF326DD6),
- TOBN(0x9188E24E, 0xF898B3F9), TOBN(0x2855DFD2, 0x95EFB13C),
- TOBN(0x7B2241FE, 0x1F5DAC48), TOBN(0x99A13D9F, 0x117B6BF7),
- TOBN(0x3A3468C7, 0x0F97CDDA), TOBN(0x74A8297B, 0xC9BBF5F7)};
+ TOBN(0x671746AE, 0x349E721B), TOBN(0x258A0655, 0xD75E93B2),
+ TOBN(0xD425E6FB, 0x25592EB6), TOBN(0x0C46AB04, 0xBF7CDD9A),
+ TOBN(0x0AD0BC99, 0x28968680), TOBN(0xF53907FB, 0xD0B7EB49),
+ TOBN(0x202EABB3, 0xEBC85C1D), TOBN(0x3129C693, 0x364D8C71),
+ TOBN(0x53728351, 0x2D46F195), TOBN(0xDF326DD6, 0x8C76CC85),
+ TOBN(0xF898B3F9, 0x9188E24E), TOBN(0x95EFB13C, 0x2855DFD2),
+ TOBN(0x1F5DAC48, 0x7B2241FE), TOBN(0x117B6BF7, 0x99A13D9F),
+ TOBN(0x0F97CDDA, 0x3A3468C7), TOBN(0xC9BBF5F7, 0x74A8297B)};
/* dh1024_safe_prime_4 is hard-coded in Apache httpd 2.0,
* modules/ssl/ssl_engine_dh.c. */
static const BN_ULONG dh1024_safe_prime_4[] = {
- TOBN(0x0DD5C86B, 0x5085E21F), TOBN(0xD823C650, 0x871538DF),
- TOBN(0x262E56A8, 0x125136F7), TOBN(0x839EB5DB, 0x974E9EF1),
- TOBN(0x1B13A63C, 0xEA9BAD99), TOBN(0x3D76E05E, 0x6044CF02),
- TOBN(0x1BAC9B5C, 0x611EBBBE), TOBN(0x4E5327DF, 0x3E371D79),
- TOBN(0x061CBC05, 0x000E6EDD), TOBN(0x20129B48, 0x2F971F3C),
- TOBN(0x3048D5A2, 0xA6EF09C4), TOBN(0xCBD523A6, 0xFA15A259),
- TOBN(0x4A79A770, 0x2A206490), TOBN(0x51BB055E, 0x91B78182),
- TOBN(0xBDD4798E, 0x7CF180C3), TOBN(0x495BE32C, 0xE6969D3D)};
+ TOBN(0x5085E21F, 0x0DD5C86B), TOBN(0x871538DF, 0xD823C650),
+ TOBN(0x125136F7, 0x262E56A8), TOBN(0x974E9EF1, 0x839EB5DB),
+ TOBN(0xEA9BAD99, 0x1B13A63C), TOBN(0x6044CF02, 0x3D76E05E),
+ TOBN(0x611EBBBE, 0x1BAC9B5C), TOBN(0x3E371D79, 0x4E5327DF),
+ TOBN(0x000E6EDD, 0x061CBC05), TOBN(0x2F971F3C, 0x20129B48),
+ TOBN(0xA6EF09C4, 0x3048D5A2), TOBN(0xFA15A259, 0xCBD523A6),
+ TOBN(0x2A206490, 0x4A79A770), TOBN(0x91B78182, 0x51BB055E),
+ TOBN(0x7CF180C3, 0xBDD4798E), TOBN(0xE6969D3D, 0x495BE32C)};
static const BN_ULONG bn_two_data[] = {2};
-#define STATIC_BIGNUM(x) \
- { \
- (BN_ULONG *) x, sizeof(x) / sizeof(BN_ULONG), \
- sizeof(x) / sizeof(BN_ULONG), 0, BN_FLG_STATIC_DATA \
- }
-
struct standard_parameters {
BIGNUM p, q, g;
};
@@ -260,7 +247,7 @@ static const BIGNUM dh1024_safe_prime[] = {
STATIC_BIGNUM(dh1024_safe_prime_4)
};
-BIGNUM bn_two = STATIC_BIGNUM(bn_two_data);
+static BIGNUM bn_two = STATIC_BIGNUM(bn_two_data);
static DH *get_standard_parameters(const struct standard_parameters *params,
const ENGINE *engine) {
diff --git a/src/crypto/digest/md32_common.h b/src/crypto/digest/md32_common.h
index d213476..9db8c54 100644
--- a/src/crypto/digest/md32_common.h
+++ b/src/crypto/digest/md32_common.h
@@ -51,12 +51,12 @@
#include <openssl/base.h>
+#include <assert.h>
#if defined(__cplusplus)
extern "C" {
#endif
-#define asm __asm__
/* This is a generic 32-bit "collector" for message digest algorithms. It
* collects input character stream into chunks of 32-bit values and invokes the
@@ -74,14 +74,15 @@ extern "C" {
*
* typedef struct <name>_state_st {
* uint32_t h[<chaining length> / sizeof(uint32_t)];
- * uint32_t Nl,Nh;
- * uint32_t data[HASH_CBLOCK / sizeof(uint32_t)];
- * unsigned int num
+ * uint32_t Nl, Nh;
+ * uint8_t data[HASH_CBLOCK];
+ * unsigned num;
* ...
* } <NAME>_CTX;
*
* <chaining length> is the output length of the hash in bytes, before
- * any truncation (e.g. 64 for SHA-224 and SHA-256, 128 for SHA-384 and SHA-512).
+ * any truncation (e.g. 64 for SHA-224 and SHA-256, 128 for SHA-384 and
+ * SHA-512).
*
* |HASH_UPDATE| must be defined as the name of the "Update" function to
* generate.
@@ -133,220 +134,189 @@ extern "C" {
#error "HASH_BLOCK_DATA_ORDER must be defined!"
#endif
-/*
- * Engage compiler specific rotate intrinsic function if available.
- */
-#undef ROTATE
-# if defined(_MSC_VER)
-# define ROTATE(a,n) _lrotl(a,n)
-# elif defined(__ICC)
-# define ROTATE(a,n) _rotl(a,n)
-# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM)
- /*
- * Some GNU C inline assembler templates. Note that these are
- * rotates by *constant* number of bits! But that's exactly
- * what we need here...
- * <appro@fy.chalmers.se>
- */
-# if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
-# define ROTATE(a,n) ({ register uint32_t ret; \
- asm ( \
- "roll %1,%0" \
- : "=r"(ret) \
- : "I"(n), "0"((uint32_t)(a)) \
- : "cc"); \
- ret; \
- })
-# endif /* OPENSSL_X86 || OPENSSL_X86_64 */
-# endif /* COMPILER */
-
-#ifndef ROTATE
-#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
+#ifndef HASH_MAKE_STRING
+#error "HASH_MAKE_STRING must be defined!"
#endif
#if defined(DATA_ORDER_IS_BIG_ENDIAN)
-#ifndef PEDANTIC
-# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM)
-# if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
- /*
- * This gives ~30-40% performance improvement in SHA-256 compiled
- * with gcc [on P4]. Well, first macro to be frank. We can pull
- * this trick on x86* platforms only, because these CPUs can fetch
- * unaligned data without raising an exception.
- */
-# define HOST_c2l(c,l) ({ uint32_t r=*((const uint32_t *)(c)); \
- asm ("bswapl %0":"=r"(r):"0"(r)); \
- (c)+=4; (l)=r; })
-# define HOST_l2c(l,c) ({ uint32_t r=(l); \
- asm ("bswapl %0":"=r"(r):"0"(r)); \
- *((uint32_t *)(c))=r; (c)+=4; r; })
-# elif defined(__aarch64__)
-# if defined(__BYTE_ORDER__)
-# if defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
-# define HOST_c2l(c,l) ({ uint32_t r; \
- asm ("rev %w0,%w1" \
- :"=r"(r) \
- :"r"(*((const uint32_t *)(c))));\
- (c)+=4; (l)=r; })
-# define HOST_l2c(l,c) ({ uint32_t r; \
- asm ("rev %w0,%w1" \
- :"=r"(r) \
- :"r"((uint32_t)(l))); \
- *((uint32_t *)(c))=r; (c)+=4; r; })
-# elif defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__
-# define HOST_c2l(c,l) (void)((l)=*((const uint32_t *)(c)), (c)+=4)
-# define HOST_l2c(l,c) (*((uint32_t *)(c))=(l), (c)+=4, (l))
-# endif
-# endif
-# endif
-# endif
-#endif
+#if !defined(PEDANTIC) && defined(__GNUC__) && __GNUC__ >= 2 && \
+ !defined(OPENSSL_NO_ASM)
+#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
+/* The first macro gives a ~30-40% performance improvement in SHA-256 compiled
+ * with gcc on P4. This can only be done on x86, where unaligned data fetches
+ * are possible. */
+#define HOST_c2l(c, l) \
+ (void)({ \
+ uint32_t r = *((const uint32_t *)(c)); \
+ __asm__("bswapl %0" : "=r"(r) : "0"(r)); \
+ (c) += 4; \
+ (l) = r; \
+ })
+#define HOST_l2c(l, c) \
+ (void)({ \
+ uint32_t r = (l); \
+ __asm__("bswapl %0" : "=r"(r) : "0"(r)); \
+ *((uint32_t *)(c)) = r; \
+ (c) += 4; \
+ r; \
+ })
+#elif defined(__aarch64__) && defined(__BYTE_ORDER__)
+#if defined(__ORDER_LITTLE_ENDIAN__) && \
+ __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#define HOST_c2l(c, l) \
+ (void)({ \
+ uint32_t r; \
+ __asm__("rev %w0, %w1" : "=r"(r) : "r"(*((const uint32_t *)(c)))); \
+ (c) += 4; \
+ (l) = r; \
+ })
+#define HOST_l2c(l, c) \
+ (void)({ \
+ uint32_t r; \
+ __asm__("rev %w0, %w1" : "=r"(r) : "r"((uint32_t)(l))); \
+ *((uint32_t *)(c)) = r; \
+ (c) += 4; \
+ r; \
+ })
+#elif defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#define HOST_c2l(c, l) (void)((l) = *((const uint32_t *)(c)), (c) += 4)
+#define HOST_l2c(l, c) (*((uint32_t *)(c)) = (l), (c) += 4, (l))
+#endif /* __aarch64__ && __BYTE_ORDER__ */
+#endif /* ARCH */
+#endif /* !PEDANTIC && GNUC && !NO_ASM */
#ifndef HOST_c2l
-#define HOST_c2l(c,l) (void)(l =(((uint32_t)(*((c)++)))<<24), \
- l|=(((uint32_t)(*((c)++)))<<16), \
- l|=(((uint32_t)(*((c)++)))<< 8), \
- l|=(((uint32_t)(*((c)++))) ))
+#define HOST_c2l(c, l) \
+ (void)(l = (((uint32_t)(*((c)++))) << 24), \
+ l |= (((uint32_t)(*((c)++))) << 16), \
+ l |= (((uint32_t)(*((c)++))) << 8), l |= (((uint32_t)(*((c)++)))))
#endif
+
#ifndef HOST_l2c
-#define HOST_l2c(l,c) (*((c)++)=(uint8_t)(((l)>>24)&0xff), \
- *((c)++)=(uint8_t)(((l)>>16)&0xff), \
- *((c)++)=(uint8_t)(((l)>> 8)&0xff), \
- *((c)++)=(uint8_t)(((l) )&0xff), \
- l)
+#define HOST_l2c(l, c) \
+ (void)(*((c)++) = (uint8_t)(((l) >> 24) & 0xff), \
+ *((c)++) = (uint8_t)(((l) >> 16) & 0xff), \
+ *((c)++) = (uint8_t)(((l) >> 8) & 0xff), \
+ *((c)++) = (uint8_t)(((l)) & 0xff))
#endif
#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
- /* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */
-# define HOST_c2l(c,l) (void)((l)=*((const uint32_t *)(c)), (c)+=4)
-# define HOST_l2c(l,c) (*((uint32_t *)(c))=(l), (c)+=4, l)
-#endif
+/* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */
+#define HOST_c2l(c, l) (void)((l) = *((const uint32_t *)(c)), (c) += 4)
+#define HOST_l2c(l, c) (void)(*((uint32_t *)(c)) = (l), (c) += 4, l)
+#endif /* OPENSSL_X86 || OPENSSL_X86_64 */
#ifndef HOST_c2l
-#define HOST_c2l(c,l) (void)(l =(((uint32_t)(*((c)++))) ), \
- l|=(((uint32_t)(*((c)++)))<< 8), \
- l|=(((uint32_t)(*((c)++)))<<16), \
- l|=(((uint32_t)(*((c)++)))<<24))
-#endif
-#ifndef HOST_l2c
-#define HOST_l2c(l,c) (*((c)++)=(uint8_t)(((l) )&0xff), \
- *((c)++)=(uint8_t)(((l)>> 8)&0xff), \
- *((c)++)=(uint8_t)(((l)>>16)&0xff), \
- *((c)++)=(uint8_t)(((l)>>24)&0xff), \
- l)
+#define HOST_c2l(c, l) \
+ (void)(l = (((uint32_t)(*((c)++)))), l |= (((uint32_t)(*((c)++))) << 8), \
+ l |= (((uint32_t)(*((c)++))) << 16), \
+ l |= (((uint32_t)(*((c)++))) << 24))
#endif
+#ifndef HOST_l2c
+#define HOST_l2c(l, c) \
+ (void)(*((c)++) = (uint8_t)(((l)) & 0xff), \
+ *((c)++) = (uint8_t)(((l) >> 8) & 0xff), \
+ *((c)++) = (uint8_t)(((l) >> 16) & 0xff), \
+ *((c)++) = (uint8_t)(((l) >> 24) & 0xff))
#endif
-int HASH_UPDATE (HASH_CTX *c, const void *data_, size_t len)
- {
- const uint8_t *data=data_;
- uint8_t *p;
- uint32_t l;
- size_t n;
-
- if (len==0) return 1;
-
- l=(c->Nl+(((uint32_t)len)<<3))&0xffffffffUL;
- /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
- * Wei Dai <weidai@eskimo.com> for pointing it out. */
- if (l < c->Nl) /* overflow */
- c->Nh++;
- c->Nh+=(uint32_t)(len>>29); /* might cause compiler warning on 16-bit */
- c->Nl=l;
-
- n = c->num;
- if (n != 0)
- {
- p=(uint8_t *)c->data;
-
- if (len >= HASH_CBLOCK || len+n >= HASH_CBLOCK)
- {
- memcpy (p+n,data,HASH_CBLOCK-n);
- HASH_BLOCK_DATA_ORDER (c->h,p,1);
- n = HASH_CBLOCK-n;
- data += n;
- len -= n;
- c->num = 0;
- memset (p,0,HASH_CBLOCK); /* keep it zeroed */
- }
- else
- {
- memcpy (p+n,data,len);
- c->num += (unsigned int)len;
- return 1;
- }
- }
-
- n = len/HASH_CBLOCK;
- if (n > 0)
- {
- HASH_BLOCK_DATA_ORDER (c->h,data,n);
- n *= HASH_CBLOCK;
- data += n;
- len -= n;
- }
-
- if (len != 0)
- {
- p = (uint8_t *)c->data;
- c->num = (unsigned int)len;
- memcpy (p,data,len);
- }
- return 1;
- }
-
-
-void HASH_TRANSFORM (HASH_CTX *c, const uint8_t *data)
- {
- HASH_BLOCK_DATA_ORDER (c->h,data,1);
- }
-
-
-int HASH_FINAL (uint8_t *md, HASH_CTX *c)
- {
- uint8_t *p = (uint8_t *)c->data;
- size_t n = c->num;
-
- p[n] = 0x80; /* there is always room for one */
- n++;
-
- if (n > (HASH_CBLOCK-8))
- {
- memset (p+n,0,HASH_CBLOCK-n);
- n=0;
- HASH_BLOCK_DATA_ORDER (c->h,p,1);
- }
- memset (p+n,0,HASH_CBLOCK-8-n);
-
- p += HASH_CBLOCK-8;
-#if defined(DATA_ORDER_IS_BIG_ENDIAN)
- (void)HOST_l2c(c->Nh,p);
- (void)HOST_l2c(c->Nl,p);
+#endif /* DATA_ORDER */
+
+int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len) {
+ const uint8_t *data = data_;
+
+ if (len == 0) {
+ return 1;
+ }
+
+ uint32_t l = c->Nl + (((uint32_t)len) << 3);
+ if (l < c->Nl) {
+ /* Handle carries. */
+ c->Nh++;
+ }
+ c->Nh += (uint32_t)(len >> 29);
+ c->Nl = l;
+
+ size_t n = c->num;
+ if (n != 0) {
+ if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) {
+ memcpy(c->data + n, data, HASH_CBLOCK - n);
+ HASH_BLOCK_DATA_ORDER(c->h, c->data, 1);
+ n = HASH_CBLOCK - n;
+ data += n;
+ len -= n;
+ c->num = 0;
+ /* Keep |c->data| zeroed when unused. */
+ memset(c->data, 0, HASH_CBLOCK);
+ } else {
+ memcpy(c->data + n, data, len);
+ c->num += (unsigned)len;
+ return 1;
+ }
+ }
+
+ n = len / HASH_CBLOCK;
+ if (n > 0) {
+ HASH_BLOCK_DATA_ORDER(c->h, data, n);
+ n *= HASH_CBLOCK;
+ data += n;
+ len -= n;
+ }
+
+ if (len != 0) {
+ c->num = (unsigned)len;
+ memcpy(c->data, data, len);
+ }
+ return 1;
+}
+
+
+void HASH_TRANSFORM(HASH_CTX *c, const uint8_t *data) {
+ HASH_BLOCK_DATA_ORDER(c->h, data, 1);
+}
+
+
+int HASH_FINAL(uint8_t *md, HASH_CTX *c) {
+ /* |c->data| always has room for at least one byte. A full block would have
+ * been consumed. */
+ size_t n = c->num;
+ assert(n < HASH_CBLOCK);
+ c->data[n] = 0x80;
+ n++;
+
+ /* Fill the block with zeros if there isn't room for a 64-bit length. */
+ if (n > (HASH_CBLOCK - 8)) {
+ memset(c->data + n, 0, HASH_CBLOCK - n);
+ n = 0;
+ HASH_BLOCK_DATA_ORDER(c->h, c->data, 1);
+ }
+ memset(c->data + n, 0, HASH_CBLOCK - 8 - n);
+
+ /* Append a 64-bit length to the block and process it. */
+ uint8_t *p = c->data + HASH_CBLOCK - 8;
+#if defined(DATA_ORDER_IS_BIG_ENDIAN)
+ HOST_l2c(c->Nh, p);
+ HOST_l2c(c->Nl, p);
#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
- (void)HOST_l2c(c->Nl,p);
- (void)HOST_l2c(c->Nh,p);
-#endif
- p -= HASH_CBLOCK;
- HASH_BLOCK_DATA_ORDER (c->h,p,1);
- c->num=0;
- memset (p,0,HASH_CBLOCK);
-
-#ifndef HASH_MAKE_STRING
-#error "HASH_MAKE_STRING must be defined!"
-#else
- HASH_MAKE_STRING(c,md);
+ HOST_l2c(c->Nl, p);
+ HOST_l2c(c->Nh, p);
#endif
+ assert(p == c->data + HASH_CBLOCK);
+ HASH_BLOCK_DATA_ORDER(c->h, c->data, 1);
+ c->num = 0;
+ memset(c->data, 0, HASH_CBLOCK);
- return 1;
- }
+ HASH_MAKE_STRING(c, md);
+ return 1;
+}
#if defined(__cplusplus)
-} /* extern C */
+} /* extern C */
#endif
-#endif /* OPENSSL_HEADER_MD32_COMMON_H */
+#endif /* OPENSSL_HEADER_MD32_COMMON_H */
diff --git a/src/crypto/dsa/dsa.c b/src/crypto/dsa/dsa.c
index ceffd1a..ebe55e8 100644
--- a/src/crypto/dsa/dsa.c
+++ b/src/crypto/dsa/dsa.c
@@ -98,12 +98,7 @@ DSA *DSA_new(void) {
dsa->references = 1;
CRYPTO_MUTEX_init(&dsa->method_mont_p_lock);
-
- if (!CRYPTO_new_ex_data(&g_ex_data_class, dsa, &dsa->ex_data)) {
- CRYPTO_MUTEX_cleanup(&dsa->method_mont_p_lock);
- OPENSSL_free(dsa);
- return NULL;
- }
+ CRYPTO_new_ex_data(&dsa->ex_data);
return dsa;
}
@@ -541,10 +536,6 @@ redo:
goto err;
}
- ret = DSA_SIG_new();
- if (ret == NULL) {
- goto err;
- }
/* Redo if r or s is zero as required by FIPS 186-3: this is
* very unlikely. */
if (BN_is_zero(r) || BN_is_zero(s)) {
@@ -554,11 +545,15 @@ redo:
}
goto redo;
}
+ ret = DSA_SIG_new();
+ if (ret == NULL) {
+ goto err;
+ }
ret->r = r;
ret->s = s;
err:
- if (!ret) {
+ if (ret == NULL) {
OPENSSL_PUT_ERROR(DSA, reason);
BN_free(r);
BN_free(s);
@@ -864,11 +859,11 @@ err:
return ret;
}
-int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
int index;
- if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, new_func,
- dup_func, free_func)) {
+ if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func,
+ free_func)) {
return -1;
}
return index;
diff --git a/src/crypto/ec/asm/p256-x86_64-asm.pl b/src/crypto/ec/asm/p256-x86_64-asm.pl
index e203d46..361a84b 100644
--- a/src/crypto/ec/asm/p256-x86_64-asm.pl
+++ b/src/crypto/ec/asm/p256-x86_64-asm.pl
@@ -67,10 +67,6 @@ $code.=<<___;
.Lpoly:
.quad 0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001
-# 2^512 mod P precomputed for NIST P256 polynomial
-.LRR:
-.quad 0x0000000000000003, 0xfffffffbffffffff, 0xfffffffffffffffe, 0x00000004fffffffd
-
.LOne:
.long 1,1,1,1,1,1,1,1
.LTwo:
@@ -91,7 +87,6 @@ my ($r_ptr,$a_ptr,$b_ptr)=("%rdi","%rsi","%rdx");
$code.=<<___;
-.globl ecp_nistz256_mul_by_2
.type ecp_nistz256_mul_by_2,\@function,2
.align 64
ecp_nistz256_mul_by_2:
@@ -134,224 +129,6 @@ ecp_nistz256_mul_by_2:
.size ecp_nistz256_mul_by_2,.-ecp_nistz256_mul_by_2
################################################################################
-# void ecp_nistz256_div_by_2(uint64_t res[4], uint64_t a[4]);
-.globl ecp_nistz256_div_by_2
-.type ecp_nistz256_div_by_2,\@function,2
-.align 32
-ecp_nistz256_div_by_2:
- push %r12
- push %r13
-
- mov 8*0($a_ptr), $a0
- mov 8*1($a_ptr), $a1
- mov 8*2($a_ptr), $a2
- mov $a0, $t0
- mov 8*3($a_ptr), $a3
- lea .Lpoly(%rip), $a_ptr
-
- mov $a1, $t1
- xor $t4, $t4
- add 8*0($a_ptr), $a0
- mov $a2, $t2
- adc 8*1($a_ptr), $a1
- adc 8*2($a_ptr), $a2
- mov $a3, $t3
- adc 8*3($a_ptr), $a3
- adc \$0, $t4
- xor $a_ptr, $a_ptr # borrow $a_ptr
- test \$1, $t0
-
- cmovz $t0, $a0
- cmovz $t1, $a1
- cmovz $t2, $a2
- cmovz $t3, $a3
- cmovz $a_ptr, $t4
-
- mov $a1, $t0 # a0:a3>>1
- shr \$1, $a0
- shl \$63, $t0
- mov $a2, $t1
- shr \$1, $a1
- or $t0, $a0
- shl \$63, $t1
- mov $a3, $t2
- shr \$1, $a2
- or $t1, $a1
- shl \$63, $t2
- shr \$1, $a3
- shl \$63, $t4
- or $t2, $a2
- or $t4, $a3
-
- mov $a0, 8*0($r_ptr)
- mov $a1, 8*1($r_ptr)
- mov $a2, 8*2($r_ptr)
- mov $a3, 8*3($r_ptr)
-
- pop %r13
- pop %r12
- ret
-.size ecp_nistz256_div_by_2,.-ecp_nistz256_div_by_2
-
-################################################################################
-# void ecp_nistz256_mul_by_3(uint64_t res[4], uint64_t a[4]);
-.globl ecp_nistz256_mul_by_3
-.type ecp_nistz256_mul_by_3,\@function,2
-.align 32
-ecp_nistz256_mul_by_3:
- push %r12
- push %r13
-
- mov 8*0($a_ptr), $a0
- xor $t4, $t4
- mov 8*1($a_ptr), $a1
- add $a0, $a0 # a0:a3+a0:a3
- mov 8*2($a_ptr), $a2
- adc $a1, $a1
- mov 8*3($a_ptr), $a3
- mov $a0, $t0
- adc $a2, $a2
- adc $a3, $a3
- mov $a1, $t1
- adc \$0, $t4
-
- sub \$-1, $a0
- mov $a2, $t2
- sbb .Lpoly+8*1(%rip), $a1
- sbb \$0, $a2
- mov $a3, $t3
- sbb .Lpoly+8*3(%rip), $a3
- test $t4, $t4
-
- cmovz $t0, $a0
- cmovz $t1, $a1
- cmovz $t2, $a2
- cmovz $t3, $a3
-
- xor $t4, $t4
- add 8*0($a_ptr), $a0 # a0:a3+=a_ptr[0:3]
- adc 8*1($a_ptr), $a1
- mov $a0, $t0
- adc 8*2($a_ptr), $a2
- adc 8*3($a_ptr), $a3
- mov $a1, $t1
- adc \$0, $t4
-
- sub \$-1, $a0
- mov $a2, $t2
- sbb .Lpoly+8*1(%rip), $a1
- sbb \$0, $a2
- mov $a3, $t3
- sbb .Lpoly+8*3(%rip), $a3
- test $t4, $t4
-
- cmovz $t0, $a0
- cmovz $t1, $a1
- mov $a0, 8*0($r_ptr)
- cmovz $t2, $a2
- mov $a1, 8*1($r_ptr)
- cmovz $t3, $a3
- mov $a2, 8*2($r_ptr)
- mov $a3, 8*3($r_ptr)
-
- pop %r13
- pop %r12
- ret
-.size ecp_nistz256_mul_by_3,.-ecp_nistz256_mul_by_3
-
-################################################################################
-# void ecp_nistz256_add(uint64_t res[4], uint64_t a[4], uint64_t b[4]);
-.globl ecp_nistz256_add
-.type ecp_nistz256_add,\@function,3
-.align 32
-ecp_nistz256_add:
- push %r12
- push %r13
-
- mov 8*0($a_ptr), $a0
- xor $t4, $t4
- mov 8*1($a_ptr), $a1
- mov 8*2($a_ptr), $a2
- mov 8*3($a_ptr), $a3
- lea .Lpoly(%rip), $a_ptr
-
- add 8*0($b_ptr), $a0
- adc 8*1($b_ptr), $a1
- mov $a0, $t0
- adc 8*2($b_ptr), $a2
- adc 8*3($b_ptr), $a3
- mov $a1, $t1
- adc \$0, $t4
-
- sub 8*0($a_ptr), $a0
- mov $a2, $t2
- sbb 8*1($a_ptr), $a1
- sbb 8*2($a_ptr), $a2
- mov $a3, $t3
- sbb 8*3($a_ptr), $a3
- test $t4, $t4
-
- cmovz $t0, $a0
- cmovz $t1, $a1
- mov $a0, 8*0($r_ptr)
- cmovz $t2, $a2
- mov $a1, 8*1($r_ptr)
- cmovz $t3, $a3
- mov $a2, 8*2($r_ptr)
- mov $a3, 8*3($r_ptr)
-
- pop %r13
- pop %r12
- ret
-.size ecp_nistz256_add,.-ecp_nistz256_add
-
-################################################################################
-# void ecp_nistz256_sub(uint64_t res[4], uint64_t a[4], uint64_t b[4]);
-.globl ecp_nistz256_sub
-.type ecp_nistz256_sub,\@function,3
-.align 32
-ecp_nistz256_sub:
- push %r12
- push %r13
-
- mov 8*0($a_ptr), $a0
- xor $t4, $t4
- mov 8*1($a_ptr), $a1
- mov 8*2($a_ptr), $a2
- mov 8*3($a_ptr), $a3
- lea .Lpoly(%rip), $a_ptr
-
- sub 8*0($b_ptr), $a0
- sbb 8*1($b_ptr), $a1
- mov $a0, $t0
- sbb 8*2($b_ptr), $a2
- sbb 8*3($b_ptr), $a3
- mov $a1, $t1
- sbb \$0, $t4
-
- add 8*0($a_ptr), $a0
- mov $a2, $t2
- adc 8*1($a_ptr), $a1
- adc 8*2($a_ptr), $a2
- mov $a3, $t3
- adc 8*3($a_ptr), $a3
- test $t4, $t4
-
- cmovz $t0, $a0
- cmovz $t1, $a1
- mov $a0, 8*0($r_ptr)
- cmovz $t2, $a2
- mov $a1, 8*1($r_ptr)
- cmovz $t3, $a3
- mov $a2, 8*2($r_ptr)
- mov $a3, 8*3($r_ptr)
-
- pop %r13
- pop %r12
- ret
-.size ecp_nistz256_sub,.-ecp_nistz256_sub
-
-################################################################################
# void ecp_nistz256_neg(uint64_t res[4], uint64_t a[4]);
.globl ecp_nistz256_neg
.type ecp_nistz256_neg,\@function,2
@@ -406,24 +183,6 @@ my ($poly1,$poly3)=($acc6,$acc7);
$code.=<<___;
################################################################################
-# void ecp_nistz256_to_mont(
-# uint64_t res[4],
-# uint64_t in[4]);
-.globl ecp_nistz256_to_mont
-.type ecp_nistz256_to_mont,\@function,2
-.align 32
-ecp_nistz256_to_mont:
-___
-$code.=<<___ if ($addx);
- mov \$0x80100, %ecx
- and OPENSSL_ia32cap_P+8(%rip), %ecx
-___
-$code.=<<___;
- lea .LRR(%rip), $b_org
- jmp .Lmul_mont
-.size ecp_nistz256_to_mont,.-ecp_nistz256_to_mont
-
-################################################################################
# void ecp_nistz256_mul_mont(
# uint64_t res[4],
# uint64_t a[4],
diff --git a/src/crypto/ec/ec.c b/src/crypto/ec/ec.c
index 4891daa..827cc57 100644
--- a/src/crypto/ec/ec.c
+++ b/src/crypto/ec/ec.c
@@ -525,8 +525,6 @@ void EC_GROUP_free(EC_GROUP *group) {
group->meth->group_finish(group);
}
- ec_pre_comp_free(group->pre_comp);
-
EC_POINT_free(group->generator);
BN_free(&group->order);
BN_free(&group->cofactor);
@@ -547,8 +545,6 @@ int ec_group_copy(EC_GROUP *dest, const EC_GROUP *src) {
return 1;
}
- ec_pre_comp_free(dest->pre_comp);
- dest->pre_comp = ec_pre_comp_dup(src->pre_comp);
dest->mont_data = src->mont_data;
if (src->generator != NULL) {
@@ -617,12 +613,16 @@ const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) {
return group->generator;
}
+const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group) {
+ assert(!BN_is_zero(&group->order));
+ return &group->order;
+}
+
int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) {
- if (!BN_copy(order, &group->order)) {
+ if (BN_copy(order, EC_GROUP_get0_order(group)) == NULL) {
return 0;
}
-
- return !BN_is_zero(order);
+ return 1;
}
int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
@@ -645,21 +645,6 @@ unsigned EC_GROUP_get_degree(const EC_GROUP *group) {
return ec_GFp_simple_group_get_degree(group);
}
-int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) {
- if (group->meth->precompute_mult != NULL) {
- return group->meth->precompute_mult(group, ctx);
- }
-
- return 1; /* nothing to do, so report success */
-}
-
-int EC_GROUP_have_precompute_mult(const EC_GROUP *group) {
- if (group->pre_comp != NULL) {
- return 1;
- }
- return 0;
-}
-
EC_POINT *EC_POINT_new(const EC_GROUP *group) {
EC_POINT *ret;
@@ -856,39 +841,23 @@ int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) {
}
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() */
-
- const EC_POINT *points[1];
- const BIGNUM *scalars[1];
-
- points[0] = point;
- scalars[0] = p_scalar;
-
- return EC_POINTs_mul(group, r, g_scalar, (point != NULL && p_scalar != NULL),
- points, scalars, ctx);
-}
-
-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) {
- if (group->meth != r->meth) {
- OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
+ const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx) {
+ /* Previously, this function set |r| to the point at infinity if there was
+ * nothing to multiply. But, nobody should be calling this function with
+ * nothing to multiply in the first place. */
+ if ((g_scalar == NULL && p_scalar == NULL) ||
+ ((p == NULL) != (p_scalar == NULL))) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
- size_t i;
- for (i = 0; i < num; i++) {
- if (points[i]->meth != r->meth) {
- break;
- }
- }
- if (i != num) {
+ if (group->meth != r->meth ||
+ (p != NULL && group->meth != p->meth)) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
+ return group->meth->mul(group, r, g_scalar, p, p_scalar, ctx);
}
int ec_point_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
diff --git a/src/crypto/ec/ec_asn1.c b/src/crypto/ec/ec_asn1.c
index 7c4be07..a085be5 100644
--- a/src/crypto/ec/ec_asn1.c
+++ b/src/crypto/ec/ec_asn1.c
@@ -329,6 +329,11 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const uint8_t **inp, long len) {
goto err;
}
+ if (BN_cmp(ret->priv_key, EC_GROUP_get0_order(ret->group)) >= 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER);
+ goto err;
+ }
+
EC_POINT_free(ret->pub_key);
ret->pub_key = EC_POINT_new(ret->group);
if (ret->pub_key == NULL) {
diff --git a/src/crypto/ec/ec_key.c b/src/crypto/ec/ec_key.c
index 0defa98..d3bf4c6 100644
--- a/src/crypto/ec/ec_key.c
+++ b/src/crypto/ec/ec_key.c
@@ -104,24 +104,18 @@ EC_KEY *EC_KEY_new_method(const ENGINE *engine) {
ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
ret->references = 1;
- if (!CRYPTO_new_ex_data(&g_ex_data_class, ret, &ret->ex_data)) {
- goto err1;
- }
+ CRYPTO_new_ex_data(&ret->ex_data);
if (ret->ecdsa_meth && ret->ecdsa_meth->init && !ret->ecdsa_meth->init(ret)) {
- goto err2;
+ CRYPTO_free_ex_data(&g_ex_data_class, ret, &ret->ex_data);
+ if (ret->ecdsa_meth) {
+ METHOD_unref(ret->ecdsa_meth);
+ }
+ OPENSSL_free(ret);
+ return NULL;
}
return ret;
-
-err2:
- CRYPTO_free_ex_data(&g_ex_data_class, ret, &ret->ex_data);
-err1:
- if (ret->ecdsa_meth) {
- METHOD_unref(ret->ecdsa_meth);
- }
- OPENSSL_free(ret);
- return NULL;
}
EC_KEY *EC_KEY_new_by_curve_name(int nid) {
@@ -249,7 +243,15 @@ int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group) {
/* TODO(fork): duplicating the group seems wasteful but see
* |EC_KEY_set_conv_form|. */
key->group = EC_GROUP_dup(group);
- return (key->group == NULL) ? 0 : 1;
+ if (key->group == NULL) {
+ return 0;
+ }
+ /* XXX: |BN_cmp| is not constant time. */
+ if (key->priv_key != NULL &&
+ BN_cmp(key->priv_key, EC_GROUP_get0_order(group)) >= 0) {
+ return 0;
+ }
+ return 1;
}
const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key) {
@@ -257,6 +259,12 @@ const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key) {
}
int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) {
+ /* XXX: |BN_cmp| is not constant time. */
+ if (key->group != NULL &&
+ BN_cmp(priv_key, EC_GROUP_get0_order(key->group)) >= 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER);
+ return 0;
+ }
BN_clear_free(key->priv_key);
key->priv_key = BN_dup(priv_key);
return (key->priv_key == NULL) ? 0 : 1;
@@ -286,17 +294,9 @@ void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform) {
key->conv_form = cform;
}
-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);
-}
-
int EC_KEY_check_key(const EC_KEY *eckey) {
int ok = 0;
BN_CTX *ctx = NULL;
- const BIGNUM *order = NULL;
EC_POINT *point = NULL;
if (!eckey || !eckey->group || !eckey->pub_key) {
@@ -310,10 +310,8 @@ int EC_KEY_check_key(const EC_KEY *eckey) {
}
ctx = BN_CTX_new();
- point = EC_POINT_new(eckey->group);
- if (ctx == NULL ||
- point == NULL) {
+ if (ctx == NULL) {
goto err;
}
@@ -322,19 +320,11 @@ int EC_KEY_check_key(const EC_KEY *eckey) {
OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE);
goto err;
}
- /* testing whether pub_key * order is the point at infinity */
/* TODO(fork): can this be skipped if the cofactor is one or if we're about
* to check the private key, below? */
- order = &eckey->group->order;
- if (BN_is_zero(order)) {
- OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER);
- goto err;
- }
- if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) {
- OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
- goto err;
- }
- if (!EC_POINT_is_at_infinity(eckey->group, point)) {
+ if (eckey->group->meth->check_pub_key_order != NULL &&
+ !eckey->group->meth->check_pub_key_order(eckey->group, eckey->pub_key,
+ ctx)) {
OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER);
goto err;
}
@@ -342,11 +332,14 @@ int EC_KEY_check_key(const EC_KEY *eckey) {
* check if generator * priv_key == pub_key
*/
if (eckey->priv_key) {
- if (BN_cmp(eckey->priv_key, order) >= 0) {
+ /* XXX: |BN_cmp| is not constant time. */
+ if (BN_cmp(eckey->priv_key, EC_GROUP_get0_order(eckey->group)) >= 0) {
OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER);
goto err;
}
- if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, NULL, NULL, ctx)) {
+ point = EC_POINT_new(eckey->group);
+ if (point == NULL ||
+ !EC_POINT_mul(eckey->group, point, eckey->priv_key, NULL, NULL, ctx)) {
OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
@@ -415,8 +408,7 @@ err:
int EC_KEY_generate_key(EC_KEY *eckey) {
int ok = 0;
- BN_CTX *ctx = NULL;
- BIGNUM *priv_key = NULL, *order = NULL;
+ BIGNUM *priv_key = NULL;
EC_POINT *pub_key = NULL;
if (!eckey || !eckey->group) {
@@ -424,14 +416,6 @@ int EC_KEY_generate_key(EC_KEY *eckey) {
return 0;
}
- order = BN_new();
- ctx = BN_CTX_new();
-
- if (order == NULL ||
- ctx == NULL) {
- goto err;
- }
-
if (eckey->priv_key == NULL) {
priv_key = BN_new();
if (priv_key == NULL) {
@@ -441,10 +425,7 @@ int EC_KEY_generate_key(EC_KEY *eckey) {
priv_key = eckey->priv_key;
}
- if (!EC_GROUP_get_order(eckey->group, order, ctx)) {
- goto err;
- }
-
+ const BIGNUM *order = EC_GROUP_get0_order(eckey->group);
do {
if (!BN_rand_range(priv_key, order)) {
goto err;
@@ -460,7 +441,7 @@ int EC_KEY_generate_key(EC_KEY *eckey) {
pub_key = eckey->pub_key;
}
- if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx)) {
+ if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, NULL)) {
goto err;
}
@@ -470,23 +451,21 @@ int EC_KEY_generate_key(EC_KEY *eckey) {
ok = 1;
err:
- BN_free(order);
if (eckey->pub_key == NULL) {
EC_POINT_free(pub_key);
}
if (eckey->priv_key == NULL) {
BN_free(priv_key);
}
- BN_CTX_free(ctx);
return ok;
}
-int EC_KEY_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+int EC_KEY_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
CRYPTO_EX_dup *dup_func,
CRYPTO_EX_free *free_func) {
int index;
- if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, new_func,
- dup_func, free_func)) {
+ if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func,
+ free_func)) {
return -1;
}
return index;
diff --git a/src/crypto/ec/ec_montgomery.c b/src/crypto/ec/ec_montgomery.c
index 3715e0c..1d4113d 100644
--- a/src/crypto/ec/ec_montgomery.c
+++ b/src/crypto/ec/ec_montgomery.c
@@ -74,24 +74,6 @@
#include "internal.h"
-const EC_METHOD *EC_GFp_mont_method(void) {
- static const EC_METHOD ret = {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_point_get_affine_coordinates,
- ec_wNAF_mul /* XXX: Not constant time. */,
- ec_wNAF_precompute_mult,
- ec_GFp_mont_field_mul,
- ec_GFp_mont_field_sqr,
- ec_GFp_mont_field_encode,
- ec_GFp_mont_field_decode,
- ec_GFp_mont_field_set_to_one};
-
- return &ret;
-}
-
int ec_GFp_mont_group_init(EC_GROUP *group) {
int ok;
@@ -256,3 +238,43 @@ int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r,
}
return 1;
}
+
+static int ec_GFp_mont_check_pub_key_order(const EC_GROUP *group,
+ const EC_POINT* pub_key,
+ BN_CTX *ctx) {
+ EC_POINT *point = EC_POINT_new(group);
+ int ret = 0;
+
+ if (point == NULL ||
+ !ec_wNAF_mul(group, point, NULL, pub_key, EC_GROUP_get0_order(group),
+ ctx) ||
+ !EC_POINT_is_at_infinity(group, point)) {
+ goto err;
+ }
+
+ ret = 1;
+
+err:
+ EC_POINT_free(point);
+ return ret;
+}
+
+const EC_METHOD *EC_GFp_mont_method(void) {
+ static const EC_METHOD ret = {
+ 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_point_get_affine_coordinates,
+ ec_wNAF_mul /* XXX: Not constant time. */,
+ ec_GFp_mont_check_pub_key_order,
+ ec_GFp_mont_field_mul,
+ ec_GFp_mont_field_sqr,
+ ec_GFp_mont_field_encode,
+ ec_GFp_mont_field_decode,
+ ec_GFp_mont_field_set_to_one,
+ };
+
+ return &ret;
+}
diff --git a/src/crypto/ec/ec_test.cc b/src/crypto/ec/ec_test.cc
index 3f45bd0..2088e72 100644
--- a/src/crypto/ec/ec_test.cc
+++ b/src/crypto/ec/ec_test.cc
@@ -23,7 +23,6 @@
#include <openssl/mem.h>
#include "../test/scoped_types.h"
-#include "../test/stl_compat.h"
// kECKeyWithoutPublic is an ECPrivateKey with the optional publicKey field
@@ -80,7 +79,7 @@ static ScopedEC_KEY DecodeECPrivateKey(const uint8_t *in, size_t in_len) {
static bool EncodeECPrivateKey(std::vector<uint8_t> *out, EC_KEY *key) {
int len = i2d_ECPrivateKey(key, NULL);
out->resize(len);
- uint8_t *outp = bssl::vector_data(out);
+ uint8_t *outp = out->data();
return i2d_ECPrivateKey(key, &outp) == len;
}
diff --git a/src/crypto/ec/internal.h b/src/crypto/ec/internal.h
index b6b5d52..bcc0e37 100644
--- a/src/crypto/ec/internal.h
+++ b/src/crypto/ec/internal.h
@@ -95,13 +95,22 @@ struct ec_method_st {
int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *,
BIGNUM *x, BIGNUM *y, BN_CTX *);
- /* used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult,
- * EC_POINT_have_precompute_mult
- * (default implementations are used if the 'mul' pointer is 0): */
- int (*mul)(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
- size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
- BN_CTX *);
- int (*precompute_mult)(EC_GROUP *group, BN_CTX *);
+ /* Computes |r = g_scalar*generator + p_scalar*p| if |g_scalar| and |p_scalar|
+ * are both non-null. Computes |r = g_scalar*generator| if |p_scalar| is null.
+ * Computes |r = p_scalar*p| if g_scalar is null. At least one of |g_scalar|
+ * and |p_scalar| must be non-null, and |p| must be non-null if |p_scalar| is
+ * non-null. */
+ int (*mul)(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
+ const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx);
+
+ /* |check_pub_key_order| checks that the public key is in the proper subgroup
+ * by checking that |pub_key*group->order| is the point at infinity. This may
+ * be NULL for |EC_METHOD|s specialized for prime-order curves (i.e. with
+ * cofactor one), as this check is not necessary for such curves (See section
+ * A.3 of the NSA's "Suite B Implementer's Guide to FIPS 186-3
+ * (ECDSA)"). */
+ int (*check_pub_key_order)(const EC_GROUP *group, const EC_POINT *pub_key,
+ BN_CTX *ctx);
/* internal functions */
@@ -121,10 +130,6 @@ struct ec_method_st {
const EC_METHOD* EC_GFp_mont_method(void);
-struct ec_pre_comp_st;
-void ec_pre_comp_free(struct ec_pre_comp_st *pre_comp);
-void *ec_pre_comp_dup(struct ec_pre_comp_st *pre_comp);
-
struct ec_group_st {
const EC_METHOD *meth;
@@ -133,7 +138,6 @@ struct ec_group_st {
int curve_name; /* optional NID for named curve */
- struct ec_pre_comp_st *pre_comp;
const BN_MONT_CTX *mont_data; /* data for ECDSA inverse */
/* The following members are handled by the method functions,
@@ -170,10 +174,8 @@ int ec_group_copy(EC_GROUP *dest, const EC_GROUP *src);
* a built-in group. */
const BN_MONT_CTX *ec_group_get_mont_data(const EC_GROUP *group);
-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_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
+ const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx);
/* method functions in simple.c */
int ec_GFp_simple_group_init(EC_GROUP *);
diff --git a/src/crypto/ec/oct.c b/src/crypto/ec/oct.c
index 365dc3d..e39337d 100644
--- a/src/crypto/ec/oct.c
+++ b/src/crypto/ec/oct.c
@@ -90,18 +90,10 @@ static size_t ec_GFp_simple_point2oct(const EC_GROUP *group,
}
if (EC_POINT_is_at_infinity(group, point)) {
- /* encodes to a single 0 octet */
- if (buf != NULL) {
- if (len < 1) {
- OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL);
- return 0;
- }
- buf[0] = 0;
- }
- return 1;
+ OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
+ goto err;
}
-
/* ret := required output buffer length */
field_len = BN_num_bytes(&group->field);
ret =
@@ -117,7 +109,7 @@ static size_t ec_GFp_simple_point2oct(const EC_GROUP *group,
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL) {
- return 0;
+ goto err;
}
}
@@ -193,25 +185,13 @@ static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
form = buf[0];
y_bit = form & 1;
form = form & ~1U;
- if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) &&
- (form != POINT_CONVERSION_UNCOMPRESSED)) {
- OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
- return 0;
- }
- if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) {
+ if ((form != POINT_CONVERSION_COMPRESSED &&
+ form != POINT_CONVERSION_UNCOMPRESSED) ||
+ (form == POINT_CONVERSION_UNCOMPRESSED && y_bit)) {
OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
return 0;
}
- if (form == 0) {
- if (len != 1) {
- OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
- return 0;
- }
-
- return EC_POINT_set_to_infinity(group, point);
- }
-
field_len = BN_num_bytes(&group->field);
enc_len =
(form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
@@ -261,12 +241,6 @@ static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
}
}
- /* test required by X9.62 */
- if (!EC_POINT_is_on_curve(group, point, ctx)) {
- OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE);
- goto err;
- }
-
ret = 1;
err:
diff --git a/src/crypto/ec/p224-64.c b/src/crypto/ec/p224-64.c
index bcc4158..e026fc4 100644
--- a/src/crypto/ec/p224-64.c
+++ b/src/crypto/ec/p224-64.c
@@ -106,7 +106,7 @@ static const felem_bytearray nistp224_curve_params[5] = {
* The reason for this is so that we can clock bits into four different
* locations when doing simple scalar multiplies against the base point,
* and then another four locations using the second 16 elements. */
-static const felem gmul[2][16][3] = {
+static const felem g_pre_comp[2][16][3] = {
{{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
{{0x3280d6115c1d21, 0xc1d356c2112234, 0x7f321390b94a03, 0xb70e0cbd6bb4bf},
{0xd5819985007e34, 0x75a05a07476444, 0xfb4c22dfe6cd43, 0xbd376388b5f723},
@@ -937,8 +937,7 @@ static char get_bit(const felem_bytearray in, unsigned i) {
static void batch_mul(felem x_out, felem y_out, felem z_out,
const felem_bytearray scalars[],
const unsigned num_points, const u8 *g_scalar,
- const int mixed, const felem pre_comp[][17][3],
- const felem g_pre_comp[2][16][3]) {
+ const int mixed, const felem pre_comp[][17][3]) {
int i, skip;
unsigned num;
unsigned gen_mul = (g_scalar != NULL);
@@ -1122,12 +1121,16 @@ static void make_points_affine(size_t num, felem points[/*num*/][3],
(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) {
+ const BIGNUM *g_scalar, const EC_POINT *p_,
+ const BIGNUM *p_scalar_, BN_CTX *ctx) {
+ /* TODO: This function used to take |points| and |scalars| as arrays of
+ * |num| elements. The code below should be simplified to work in terms of
+ * |p_| and |p_scalar_|. */
+ size_t num = p_ != NULL ? 1 : 0;
+ const EC_POINT **points = p_ != NULL ? &p_ : NULL;
+ BIGNUM const *const *scalars = p_ != NULL ? &p_scalar_ : NULL;
+
int ret = 0;
int j;
unsigned i;
@@ -1140,11 +1143,8 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
felem *tmp_felems = NULL;
felem_bytearray tmp;
unsigned num_bytes;
- int have_pre_comp = 0;
size_t num_points = num;
felem x_in, y_in, z_in, x_out, y_out, z_out;
- const felem(*g_pre_comp)[16][3] = NULL;
- EC_POINT *generator = NULL;
const EC_POINT *p = NULL;
const BIGNUM *p_scalar = NULL;
@@ -1164,35 +1164,6 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
goto err;
}
- if (scalar != NULL) {
- /* try to use the standard precomputation */
- g_pre_comp = &gmul[0];
- generator = EC_POINT_new(group);
- if (generator == NULL) {
- goto err;
- }
- /* get the generator from precomputation */
- 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])) {
- OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
- goto err;
- }
- if (!ec_point_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 */
- have_pre_comp = 1;
- } else {
- /* we don't have valid precomputation:
- * treat the generator as a random point */
- num_points = num_points + 1;
- }
- }
-
if (num_points > 0) {
if (num_points >= 3) {
/* unless we precompute multiples for just one or two points,
@@ -1200,7 +1171,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
mixed = 1;
}
secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray));
- pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(felem));
+ pre_comp = OPENSSL_malloc(num_points * sizeof(felem[17][3]));
if (mixed) {
tmp_felems = OPENSSL_malloc((num_points * 17 + 1) * sizeof(felem));
}
@@ -1219,7 +1190,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
if (i == num) {
/* the generator */
p = EC_GROUP_get0_generator(group);
- p_scalar = scalar;
+ p_scalar = g_scalar;
} else {
/* the i^th point */
p = points[i];
@@ -1227,7 +1198,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
}
if (p_scalar != NULL && p != NULL) {
- /* reduce scalar to 0 <= scalar < 2^224 */
+ /* reduce g_scalar to 0 <= g_scalar < 2^224 */
if (BN_num_bits(p_scalar) > 224 || BN_is_negative(p_scalar)) {
/* this is an unusual input, and we don't guarantee
* constant-timeness */
@@ -1272,31 +1243,25 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
}
}
- /* the scalar for the generator */
- if (scalar != NULL && have_pre_comp) {
+ if (g_scalar != NULL) {
memset(g_secret, 0, sizeof(g_secret));
- /* reduce scalar to 0 <= scalar < 2^224 */
- if (BN_num_bits(scalar) > 224 || BN_is_negative(scalar)) {
+ /* reduce g_scalar to 0 <= g_scalar < 2^224 */
+ if (BN_num_bits(g_scalar) > 224 || BN_is_negative(g_scalar)) {
/* this is an unusual input, and we don't guarantee constant-timeness */
- if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) {
+ if (!BN_nnmod(tmp_scalar, g_scalar, &group->order, ctx)) {
OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
num_bytes = BN_bn2bin(tmp_scalar, tmp);
} else {
- num_bytes = BN_bn2bin(scalar, tmp);
+ num_bytes = BN_bn2bin(g_scalar, tmp);
}
flip_endian(g_secret, tmp, num_bytes);
- /* do the multiplication with generator precomputation */
- batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets,
- num_points, g_secret, mixed, (const felem(*)[17][3])pre_comp,
- g_pre_comp);
- } else {
- /* do the multiplication without generator precomputation */
- batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets,
- num_points, NULL, mixed, (const felem(*)[17][3])pre_comp, NULL);
}
+ batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets,
+ num_points, g_scalar != NULL ? g_secret : NULL, mixed,
+ (const felem(*)[17][3])pre_comp);
/* reduce the output to its unique minimal representation */
felem_contract(x_in, x_out);
@@ -1312,7 +1277,6 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
err:
BN_CTX_end(ctx);
- EC_POINT_free(generator);
BN_CTX_free(new_ctx);
OPENSSL_free(secrets);
OPENSSL_free(pre_comp);
@@ -1328,7 +1292,7 @@ const EC_METHOD *EC_GFp_nistp224_method(void) {
ec_GFp_nistp224_group_set_curve,
ec_GFp_nistp224_point_get_affine_coordinates,
ec_GFp_nistp224_points_mul,
- 0 /* precompute_mult */,
+ 0 /* check_pub_key_order */,
ec_GFp_simple_field_mul,
ec_GFp_simple_field_sqr,
0 /* field_encode */,
diff --git a/src/crypto/ec/p256-64.c b/src/crypto/ec/p256-64.c
index 2adcd6b..32852dd 100644
--- a/src/crypto/ec/p256-64.c
+++ b/src/crypto/ec/p256-64.c
@@ -1312,8 +1312,8 @@ static void point_add_small(smallfelem x3, smallfelem y3, smallfelem z3,
*
* Tables for other points have table[i] = iG for i in 0 .. 16. */
-/* gmul is the table of precomputed base points */
-static const smallfelem gmul[2][16][3] = {
+/* g_pre_comp is the table of precomputed base points */
+static const smallfelem g_pre_comp[2][16][3] = {
{{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
{{0xf4a13945d898c296, 0x77037d812deb33a0, 0xf8bce6e563a440f2,
0x6b17d1f2e12c4247},
@@ -1505,8 +1505,7 @@ static char get_bit(const felem_bytearray in, int i) {
static void batch_mul(felem x_out, felem y_out, felem z_out,
const felem_bytearray scalars[],
const unsigned num_points, const u8 *g_scalar,
- const int mixed, const smallfelem pre_comp[][17][3],
- const smallfelem g_pre_comp[2][16][3]) {
+ const int mixed, const smallfelem pre_comp[][17][3]) {
int i, skip;
unsigned num, gen_mul = (g_scalar != NULL);
felem nq[3], ftmp;
@@ -1598,11 +1597,6 @@ static void batch_mul(felem x_out, felem y_out, felem z_out,
felem_assign(z_out, nq[2]);
}
-/* Precomputation for the group generator. */
-typedef struct {
- smallfelem g_pre_comp[2][16][3];
-} NISTP256_PRE_COMP;
-
/******************************************************************************/
/*
* OPENSSL EC_METHOD FUNCTIONS
@@ -1707,12 +1701,16 @@ static void make_points_affine(size_t num, smallfelem points[][3],
(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) {
+ const BIGNUM *g_scalar, const EC_POINT *p_,
+ const BIGNUM *p_scalar_, BN_CTX *ctx) {
+ /* TODO: This function used to take |points| and |scalars| as arrays of
+ * |num| elements. The code below should be simplified to work in terms of |p|
+ * and |p_scalar|. */
+ size_t num = p_ != NULL ? 1 : 0;
+ const EC_POINT **points = p_ != NULL ? &p_ : NULL;
+ BIGNUM const *const *scalars = p_ != NULL ? &p_scalar_ : NULL;
+
int ret = 0;
int j;
int mixed = 0;
@@ -1724,12 +1722,9 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
smallfelem *tmp_smallfelems = NULL;
felem_bytearray tmp;
unsigned i, num_bytes;
- int have_pre_comp = 0;
size_t num_points = num;
smallfelem x_in, y_in, z_in;
felem x_out, y_out, z_out;
- const smallfelem(*g_pre_comp)[16][3] = NULL;
- EC_POINT *generator = NULL;
const EC_POINT *p = NULL;
const BIGNUM *p_scalar = NULL;
@@ -1748,34 +1743,6 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
goto err;
}
- if (scalar != NULL) {
- /* try to use the standard precomputation */
- g_pre_comp = &gmul[0];
- generator = EC_POINT_new(group);
- if (generator == NULL) {
- goto err;
- }
- /* get the generator from precomputation */
- 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])) {
- OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
- goto err;
- }
- if (!ec_point_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 */
- have_pre_comp = 1;
- } else {
- /* we don't have valid precomputation: treat the generator as a
- * random point. */
- num_points++;
- }
- }
-
if (num_points > 0) {
if (num_points >= 3) {
/* unless we precompute multiples for just one or two points,
@@ -1783,7 +1750,7 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
mixed = 1;
}
secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray));
- pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(smallfelem));
+ pre_comp = OPENSSL_malloc(num_points * sizeof(smallfelem[17][3]));
if (mixed) {
tmp_smallfelems =
OPENSSL_malloc((num_points * 17 + 1) * sizeof(smallfelem));
@@ -1802,14 +1769,14 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
if (i == num) {
/* we didn't have a valid precomputation, so we pick the generator. */
p = EC_GROUP_get0_generator(group);
- p_scalar = scalar;
+ p_scalar = g_scalar;
} else {
/* the i^th point */
p = points[i];
p_scalar = scalars[i];
}
if (p_scalar != NULL && p != NULL) {
- /* reduce scalar to 0 <= scalar < 2^256 */
+ /* reduce g_scalar to 0 <= g_scalar < 2^256 */
if (BN_num_bits(p_scalar) > 256 || BN_is_negative(p_scalar)) {
/* this is an unusual input, and we don't guarantee
* constant-timeness. */
@@ -1851,32 +1818,25 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
}
}
- /* the scalar for the generator */
- if (scalar != NULL && have_pre_comp) {
+ if (g_scalar != NULL) {
memset(g_secret, 0, sizeof(g_secret));
- /* reduce scalar to 0 <= scalar < 2^256 */
- if (BN_num_bits(scalar) > 256 || BN_is_negative(scalar)) {
+ /* reduce g_scalar to 0 <= g_scalar < 2^256 */
+ if (BN_num_bits(g_scalar) > 256 || BN_is_negative(g_scalar)) {
/* this is an unusual input, and we don't guarantee
* constant-timeness. */
- if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) {
+ if (!BN_nnmod(tmp_scalar, g_scalar, &group->order, ctx)) {
OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
num_bytes = BN_bn2bin(tmp_scalar, tmp);
} else {
- num_bytes = BN_bn2bin(scalar, tmp);
+ num_bytes = BN_bn2bin(g_scalar, tmp);
}
flip_endian(g_secret, tmp, num_bytes);
- /* do the multiplication with generator precomputation */
- batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets,
- num_points, g_secret, mixed, (const smallfelem(*)[17][3])pre_comp,
- g_pre_comp);
- } else {
- /* do the multiplication without generator precomputation */
- batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets,
- num_points, NULL, mixed, (const smallfelem(*)[17][3])pre_comp,
- NULL);
}
+ batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets,
+ num_points, g_scalar != NULL ? g_secret : NULL, mixed,
+ (const smallfelem(*)[17][3])pre_comp);
/* reduce the output to its unique minimal representation */
felem_contract(x_in, x_out);
@@ -1892,7 +1852,6 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
err:
BN_CTX_end(ctx);
- EC_POINT_free(generator);
BN_CTX_free(new_ctx);
OPENSSL_free(secrets);
OPENSSL_free(pre_comp);
@@ -1908,7 +1867,7 @@ const EC_METHOD *EC_GFp_nistp256_method(void) {
ec_GFp_simple_group_copy, ec_GFp_nistp256_group_set_curve,
ec_GFp_nistp256_point_get_affine_coordinates,
ec_GFp_nistp256_points_mul,
- 0 /* precompute_mult */,
+ 0 /* check_pub_key_order */,
ec_GFp_simple_field_mul, ec_GFp_simple_field_sqr,
0 /* field_encode */, 0 /* field_decode */, 0 /* field_set_to_one */
};
diff --git a/src/crypto/ec/p256-x86_64.c b/src/crypto/ec/p256-x86_64.c
index 09816ad..2f7023d 100644
--- a/src/crypto/ec/p256-x86_64.c
+++ b/src/crypto/ec/p256-x86_64.c
@@ -22,6 +22,7 @@
#include <openssl/ec.h>
+#include <assert.h>
#include <stdint.h>
#include <string.h>
@@ -37,18 +38,13 @@
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
!defined(OPENSSL_SMALL)
-#if BN_BITS2 != 64
-#define TOBN(hi, lo) lo, hi
-#else
-#define TOBN(hi, lo) ((BN_ULONG)hi << 32 | lo)
-#endif
#if defined(__GNUC__)
-#define ALIGN32 __attribute((aligned(32)))
+#define ALIGN(x) __attribute((aligned(x)))
#elif defined(_MSC_VER)
-#define ALIGN32 __declspec(align(32))
+#define ALIGN(x) __declspec(align(x))
#else
-#define ALIGN32
+#define ALIGN(x)
#endif
#define ALIGNPTR(p, N) ((uint8_t *)p + N - (size_t)p % N)
@@ -69,21 +65,6 @@ typedef P256_POINT_AFFINE PRECOMP256_ROW[64];
/* Functions implemented in assembly */
-/* Modular mul by 2: res = 2*a mod P */
-void ecp_nistz256_mul_by_2(BN_ULONG res[P256_LIMBS],
- const BN_ULONG a[P256_LIMBS]);
-/* Modular div by 2: res = a/2 mod P */
-void ecp_nistz256_div_by_2(BN_ULONG res[P256_LIMBS],
- const BN_ULONG a[P256_LIMBS]);
-/* Modular mul by 3: res = 3*a mod P */
-void ecp_nistz256_mul_by_3(BN_ULONG res[P256_LIMBS],
- const BN_ULONG a[P256_LIMBS]);
-/* Modular add: res = a+b mod P */
-void ecp_nistz256_add(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS],
- const BN_ULONG b[P256_LIMBS]);
-/* Modular sub: res = a-b mod P */
-void ecp_nistz256_sub(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS],
- const BN_ULONG b[P256_LIMBS]);
/* Modular neg: res = -a mod P */
void ecp_nistz256_neg(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS]);
/* Montgomery mul: res = a*b*2^-256 mod P */
@@ -96,9 +77,6 @@ void ecp_nistz256_sqr_mont(BN_ULONG res[P256_LIMBS],
/* Convert a number from Montgomery domain, by multiplying with 1 */
void ecp_nistz256_from_mont(BN_ULONG res[P256_LIMBS],
const BN_ULONG in[P256_LIMBS]);
-/* Convert a number to Montgomery domain, by multiplying with 2^512 mod P*/
-void ecp_nistz256_to_mont(BN_ULONG res[P256_LIMBS],
- const BN_ULONG in[P256_LIMBS]);
/* Functions that perform constant time access to the precomputed tables */
void ecp_nistz256_select_w5(P256_POINT *val, const P256_POINT *in_t, int index);
void ecp_nistz256_select_w7(P256_POINT_AFFINE *val,
@@ -153,48 +131,6 @@ static void copy_conditional(BN_ULONG dst[P256_LIMBS],
}
}
-static BN_ULONG is_zero(BN_ULONG in) {
- in |= (0 - in);
- in = ~in;
- in &= BN_MASK2;
- in >>= BN_BITS2 - 1;
- return in;
-}
-
-static BN_ULONG is_equal(const BN_ULONG a[P256_LIMBS],
- const BN_ULONG b[P256_LIMBS]) {
- BN_ULONG res;
-
- res = a[0] ^ b[0];
- res |= a[1] ^ b[1];
- res |= a[2] ^ b[2];
- res |= a[3] ^ b[3];
- if (P256_LIMBS == 8) {
- res |= a[4] ^ b[4];
- res |= a[5] ^ b[5];
- res |= a[6] ^ b[6];
- res |= a[7] ^ b[7];
- }
-
- return is_zero(res);
-}
-
-static BN_ULONG is_one(const BN_ULONG a[P256_LIMBS]) {
- BN_ULONG res;
-
- res = a[0] ^ ONE[0];
- res |= a[1] ^ ONE[1];
- res |= a[2] ^ ONE[2];
- res |= a[3] ^ ONE[3];
- if (P256_LIMBS == 8) {
- res |= a[4] ^ ONE[4];
- res |= a[5] ^ ONE[5];
- res |= a[6] ^ ONE[6];
- }
-
- return is_zero(res);
-}
-
void ecp_nistz256_point_double(P256_POINT *r, const P256_POINT *a);
void ecp_nistz256_point_add(P256_POINT *r, const P256_POINT *a,
const P256_POINT *b);
@@ -296,113 +232,117 @@ static int ecp_nistz256_bignum_to_field_elem(BN_ULONG out[P256_LIMBS],
return 1;
}
-/* r = sum(scalar[i]*point[i]) */
-static void ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r,
- const BIGNUM **scalar,
- const EC_POINT **point, int num,
- BN_CTX *ctx) {
+/* r = p * p_scalar */
+static int ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r,
+ const EC_POINT *p, const BIGNUM *p_scalar,
+ BN_CTX *ctx) {
+ assert(p != NULL);
+ assert(p_scalar != NULL);
+
static const unsigned kWindowSize = 5;
static const unsigned kMask = (1 << (5 /* kWindowSize */ + 1)) - 1;
- void *table_storage = OPENSSL_malloc(num * 16 * sizeof(P256_POINT) + 64);
- uint8_t(*p_str)[33] = OPENSSL_malloc(num * 33 * sizeof(uint8_t));
- const BIGNUM **scalars = OPENSSL_malloc(num * sizeof(BIGNUM *));
-
- if (table_storage == NULL ||
- p_str == NULL ||
- scalars == NULL) {
- OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
- goto err;
- }
+ /* A |P256_POINT| is (3 * 32) = 96 bytes, and the 64-byte alignment should
+ * add no more than 63 bytes of overhead. Thus, |table| should require
+ * ~1599 ((96 * 16) + 63) bytes of stack space. */
+ ALIGN(64) P256_POINT table[16];
+ uint8_t p_str[33];
- P256_POINT(*table)[16] = (void *)ALIGNPTR(table_storage, 64);
- int i;
- for (i = 0; i < num; i++) {
- P256_POINT *row = table[i];
+ int ret = 0;
+ BN_CTX *new_ctx = NULL;
+ int ctx_started = 0;
- if (BN_num_bits(scalar[i]) > 256 || BN_is_negative(scalar[i])) {
- BIGNUM *mod = BN_CTX_get(ctx);
- if (mod == NULL) {
+ if (BN_num_bits(p_scalar) > 256 || BN_is_negative(p_scalar)) {
+ if (ctx == NULL) {
+ new_ctx = BN_CTX_new();
+ if (new_ctx == NULL) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
-
- if (!BN_nnmod(mod, scalar[i], &group->order, ctx)) {
- OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
- goto err;
- }
- scalars[i] = mod;
- } else {
- scalars[i] = scalar[i];
+ ctx = new_ctx;
}
-
- int j;
- for (j = 0; j < scalars[i]->top * BN_BYTES; j += BN_BYTES) {
- BN_ULONG d = scalars[i]->d[j / BN_BYTES];
-
- p_str[i][j + 0] = d & 0xff;
- p_str[i][j + 1] = (d >> 8) & 0xff;
- p_str[i][j + 2] = (d >> 16) & 0xff;
- p_str[i][j + 3] = (d >>= 24) & 0xff;
- if (BN_BYTES == 8) {
- d >>= 8;
- p_str[i][j + 4] = d & 0xff;
- p_str[i][j + 5] = (d >> 8) & 0xff;
- p_str[i][j + 6] = (d >> 16) & 0xff;
- p_str[i][j + 7] = (d >> 24) & 0xff;
- }
+ BN_CTX_start(ctx);
+ ctx_started = 1;
+ BIGNUM *mod = BN_CTX_get(ctx);
+ if (mod == NULL) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (!BN_nnmod(mod, p_scalar, &group->order, ctx)) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
+ goto err;
}
+ p_scalar = mod;
+ }
- for (; j < 33; j++) {
- p_str[i][j] = 0;
+ int j;
+ for (j = 0; j < p_scalar->top * BN_BYTES; j += BN_BYTES) {
+ BN_ULONG d = p_scalar->d[j / BN_BYTES];
+
+ p_str[j + 0] = d & 0xff;
+ p_str[j + 1] = (d >> 8) & 0xff;
+ p_str[j + 2] = (d >> 16) & 0xff;
+ p_str[j + 3] = (d >>= 24) & 0xff;
+ if (BN_BYTES == 8) {
+ d >>= 8;
+ p_str[j + 4] = d & 0xff;
+ p_str[j + 5] = (d >> 8) & 0xff;
+ p_str[j + 6] = (d >> 16) & 0xff;
+ p_str[j + 7] = (d >> 24) & 0xff;
}
+ }
- /* table[0] is implicitly (0,0,0) (the point at infinity), therefore it is
- * not stored. All other values are actually stored with an offset of -1 in
- * table. */
+ for (; j < 33; j++) {
+ p_str[j] = 0;
+ }
- if (!ecp_nistz256_bignum_to_field_elem(row[1 - 1].X, &point[i]->X) ||
- !ecp_nistz256_bignum_to_field_elem(row[1 - 1].Y, &point[i]->Y) ||
- !ecp_nistz256_bignum_to_field_elem(row[1 - 1].Z, &point[i]->Z)) {
- OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE);
- goto err;
- }
+ /* table[0] is implicitly (0,0,0) (the point at infinity), therefore it is
+ * not stored. All other values are actually stored with an offset of -1 in
+ * table. */
+ P256_POINT *row = table;
- ecp_nistz256_point_double(&row[2 - 1], &row[1 - 1]);
- ecp_nistz256_point_add(&row[3 - 1], &row[2 - 1], &row[1 - 1]);
- ecp_nistz256_point_double(&row[4 - 1], &row[2 - 1]);
- ecp_nistz256_point_double(&row[6 - 1], &row[3 - 1]);
- ecp_nistz256_point_double(&row[8 - 1], &row[4 - 1]);
- ecp_nistz256_point_double(&row[12 - 1], &row[6 - 1]);
- ecp_nistz256_point_add(&row[5 - 1], &row[4 - 1], &row[1 - 1]);
- ecp_nistz256_point_add(&row[7 - 1], &row[6 - 1], &row[1 - 1]);
- ecp_nistz256_point_add(&row[9 - 1], &row[8 - 1], &row[1 - 1]);
- ecp_nistz256_point_add(&row[13 - 1], &row[12 - 1], &row[1 - 1]);
- ecp_nistz256_point_double(&row[14 - 1], &row[7 - 1]);
- ecp_nistz256_point_double(&row[10 - 1], &row[5 - 1]);
- ecp_nistz256_point_add(&row[15 - 1], &row[14 - 1], &row[1 - 1]);
- ecp_nistz256_point_add(&row[11 - 1], &row[10 - 1], &row[1 - 1]);
- ecp_nistz256_point_add(&row[16 - 1], &row[15 - 1], &row[1 - 1]);
+ if (!ecp_nistz256_bignum_to_field_elem(row[1 - 1].X, &p->X) ||
+ !ecp_nistz256_bignum_to_field_elem(row[1 - 1].Y, &p->Y) ||
+ !ecp_nistz256_bignum_to_field_elem(row[1 - 1].Z, &p->Z)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE);
+ goto err;
}
+ ecp_nistz256_point_double(&row[2 - 1], &row[1 - 1]);
+ ecp_nistz256_point_add(&row[3 - 1], &row[2 - 1], &row[1 - 1]);
+ ecp_nistz256_point_double(&row[4 - 1], &row[2 - 1]);
+ ecp_nistz256_point_double(&row[6 - 1], &row[3 - 1]);
+ ecp_nistz256_point_double(&row[8 - 1], &row[4 - 1]);
+ ecp_nistz256_point_double(&row[12 - 1], &row[6 - 1]);
+ ecp_nistz256_point_add(&row[5 - 1], &row[4 - 1], &row[1 - 1]);
+ ecp_nistz256_point_add(&row[7 - 1], &row[6 - 1], &row[1 - 1]);
+ ecp_nistz256_point_add(&row[9 - 1], &row[8 - 1], &row[1 - 1]);
+ ecp_nistz256_point_add(&row[13 - 1], &row[12 - 1], &row[1 - 1]);
+ ecp_nistz256_point_double(&row[14 - 1], &row[7 - 1]);
+ ecp_nistz256_point_double(&row[10 - 1], &row[5 - 1]);
+ ecp_nistz256_point_add(&row[15 - 1], &row[14 - 1], &row[1 - 1]);
+ ecp_nistz256_point_add(&row[11 - 1], &row[10 - 1], &row[1 - 1]);
+ ecp_nistz256_point_add(&row[16 - 1], &row[15 - 1], &row[1 - 1]);
+
BN_ULONG tmp[P256_LIMBS];
- ALIGN32 P256_POINT h;
+ ALIGN(32) P256_POINT h;
unsigned index = 255;
- unsigned wvalue = p_str[0][(index - 1) / 8];
+ unsigned wvalue = p_str[(index - 1) / 8];
wvalue = (wvalue >> ((index - 1) % 8)) & kMask;
- ecp_nistz256_select_w5(r, table[0], booth_recode_w5(wvalue) >> 1);
+ ecp_nistz256_select_w5(r, table, booth_recode_w5(wvalue) >> 1);
while (index >= 5) {
- for (i = (index == 255 ? 1 : 0); i < num; i++) {
+ if (index != 255) {
unsigned off = (index - 1) / 8;
- wvalue = p_str[i][off] | p_str[i][off + 1] << 8;
+ wvalue = p_str[off] | p_str[off + 1] << 8;
wvalue = (wvalue >> ((index - 1) % 8)) & kMask;
wvalue = booth_recode_w5(wvalue);
- ecp_nistz256_select_w5(&h, table[i], wvalue >> 1);
+ ecp_nistz256_select_w5(&h, table, wvalue >> 1);
ecp_nistz256_neg(tmp, h.Y);
copy_conditional(h.Y, tmp, (wvalue & 1));
@@ -420,217 +360,166 @@ static void ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r,
}
/* Final window */
- for (i = 0; i < num; i++) {
- wvalue = p_str[i][0];
- wvalue = (wvalue << 1) & kMask;
+ wvalue = p_str[0];
+ wvalue = (wvalue << 1) & kMask;
- wvalue = booth_recode_w5(wvalue);
+ wvalue = booth_recode_w5(wvalue);
- ecp_nistz256_select_w5(&h, table[i], wvalue >> 1);
+ ecp_nistz256_select_w5(&h, table, wvalue >> 1);
- ecp_nistz256_neg(tmp, h.Y);
- copy_conditional(h.Y, tmp, wvalue & 1);
+ ecp_nistz256_neg(tmp, h.Y);
+ copy_conditional(h.Y, tmp, wvalue & 1);
- ecp_nistz256_point_add(r, r, &h);
- }
+ ecp_nistz256_point_add(r, r, &h);
-err:
- OPENSSL_free(table_storage);
- OPENSSL_free(p_str);
- OPENSSL_free((BIGNUM**) scalars);
-}
-
-/* Coordinates of G, for which we have precomputed tables */
-const static BN_ULONG def_xG[P256_LIMBS] = {
- TOBN(0x79e730d4, 0x18a9143c), TOBN(0x75ba95fc, 0x5fedb601),
- TOBN(0x79fb732b, 0x77622510), TOBN(0x18905f76, 0xa53755c6),
-};
-
-const static BN_ULONG def_yG[P256_LIMBS] = {
- TOBN(0xddf25357, 0xce95560a), TOBN(0x8b4ab8e4, 0xba19e45c),
- TOBN(0xd2e88688, 0xdd21f325), TOBN(0x8571ff18, 0x25885d85)
-};
+ ret = 1;
-/* ecp_nistz256_is_affine_G returns one if |generator| is the standard, P-256
- * generator. */
-static int ecp_nistz256_is_affine_G(const EC_POINT *generator) {
- return (generator->X.top == P256_LIMBS) && (generator->Y.top == P256_LIMBS) &&
- (generator->Z.top == (P256_LIMBS - P256_LIMBS / 8)) &&
- is_equal(generator->X.d, def_xG) && is_equal(generator->Y.d, def_yG) &&
- is_one(generator->Z.d);
+err:
+ if (ctx_started) {
+ BN_CTX_end(ctx);
+ }
+ BN_CTX_free(new_ctx);
+ return ret;
}
-/* r = scalar*G + sum(scalars[i]*points[i]) */
static int ecp_nistz256_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) {
+ const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
+ const EC_POINT *p_, const BIGNUM *p_scalar, BN_CTX *ctx) {
+ assert((p_ != NULL) == (p_scalar != NULL));
+
static const unsigned kWindowSize = 7;
static const unsigned kMask = (1 << (7 /* kWindowSize */ + 1)) - 1;
- int ret = 0, no_precomp_for_generator = 0, p_is_infinity = 0;
- ALIGN32 union {
+ ALIGN(32) union {
P256_POINT p;
P256_POINT_AFFINE a;
} t, p;
- if (scalar == NULL && num == 0) {
- return EC_POINT_set_to_infinity(group, r);
- }
+ int ret = 0;
+ BN_CTX *new_ctx = NULL;
+ int ctx_started = 0;
/* Need 256 bits for space for all coordinates. */
- bn_wexpand(&r->X, P256_LIMBS);
- bn_wexpand(&r->Y, P256_LIMBS);
- bn_wexpand(&r->Z, P256_LIMBS);
+ if (bn_wexpand(&r->X, P256_LIMBS) == NULL ||
+ bn_wexpand(&r->Y, P256_LIMBS) == NULL ||
+ bn_wexpand(&r->Z, P256_LIMBS) == NULL) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
r->X.top = P256_LIMBS;
r->Y.top = P256_LIMBS;
r->Z.top = P256_LIMBS;
- const EC_POINT *generator = NULL;
- if (scalar) {
- generator = EC_GROUP_get0_generator(group);
- if (generator == NULL) {
- OPENSSL_PUT_ERROR(EC, EC_R_UNDEFINED_GENERATOR);
- goto err;
- }
-
- if (ecp_nistz256_is_affine_G(generator)) {
- if (BN_num_bits(scalar) > 256 || BN_is_negative(scalar)) {
- BIGNUM *tmp_scalar = BN_CTX_get(ctx);
- if (tmp_scalar == NULL) {
+ if (g_scalar != NULL) {
+ if (BN_num_bits(g_scalar) > 256 || BN_is_negative(g_scalar)) {
+ if (ctx == NULL) {
+ new_ctx = BN_CTX_new();
+ if (new_ctx == NULL) {
goto err;
}
-
- if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) {
- OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
- goto err;
- }
- scalar = tmp_scalar;
+ ctx = new_ctx;
}
-
- uint8_t p_str[33] = {0};
- int i;
- for (i = 0; i < scalar->top * BN_BYTES; i += BN_BYTES) {
- BN_ULONG d = scalar->d[i / BN_BYTES];
-
- p_str[i + 0] = d & 0xff;
- p_str[i + 1] = (d >> 8) & 0xff;
- p_str[i + 2] = (d >> 16) & 0xff;
- p_str[i + 3] = (d >>= 24) & 0xff;
- if (BN_BYTES == 8) {
- d >>= 8;
- p_str[i + 4] = d & 0xff;
- p_str[i + 5] = (d >> 8) & 0xff;
- p_str[i + 6] = (d >> 16) & 0xff;
- p_str[i + 7] = (d >> 24) & 0xff;
- }
+ BN_CTX_start(ctx);
+ ctx_started = 1;
+ BIGNUM *tmp_scalar = BN_CTX_get(ctx);
+ if (tmp_scalar == NULL) {
+ goto err;
}
- for (; i < (int) sizeof(p_str); i++) {
- p_str[i] = 0;
+ if (!BN_nnmod(tmp_scalar, g_scalar, &group->order, ctx)) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
+ goto err;
}
+ g_scalar = tmp_scalar;
+ }
- /* First window */
- unsigned wvalue = (p_str[0] << 1) & kMask;
- unsigned index = kWindowSize;
-
- wvalue = booth_recode_w7(wvalue);
+ uint8_t p_str[33] = {0};
+ int i;
+ for (i = 0; i < g_scalar->top * BN_BYTES; i += BN_BYTES) {
+ BN_ULONG d = g_scalar->d[i / BN_BYTES];
- const PRECOMP256_ROW *const precomputed_table =
- (const PRECOMP256_ROW *)ecp_nistz256_precomputed;
- ecp_nistz256_select_w7(&p.a, precomputed_table[0], wvalue >> 1);
+ p_str[i + 0] = d & 0xff;
+ p_str[i + 1] = (d >> 8) & 0xff;
+ p_str[i + 2] = (d >> 16) & 0xff;
+ p_str[i + 3] = (d >>= 24) & 0xff;
+ if (BN_BYTES == 8) {
+ d >>= 8;
+ p_str[i + 4] = d & 0xff;
+ p_str[i + 5] = (d >> 8) & 0xff;
+ p_str[i + 6] = (d >> 16) & 0xff;
+ p_str[i + 7] = (d >> 24) & 0xff;
+ }
+ }
- ecp_nistz256_neg(p.p.Z, p.p.Y);
- copy_conditional(p.p.Y, p.p.Z, wvalue & 1);
+ for (; i < (int) sizeof(p_str); i++) {
+ p_str[i] = 0;
+ }
- memcpy(p.p.Z, ONE, sizeof(ONE));
+ /* First window */
+ unsigned wvalue = (p_str[0] << 1) & kMask;
+ unsigned index = kWindowSize;
- for (i = 1; i < 37; i++) {
- unsigned off = (index - 1) / 8;
- wvalue = p_str[off] | p_str[off + 1] << 8;
- wvalue = (wvalue >> ((index - 1) % 8)) & kMask;
- index += kWindowSize;
+ wvalue = booth_recode_w7(wvalue);
- wvalue = booth_recode_w7(wvalue);
+ const PRECOMP256_ROW *const precomputed_table =
+ (const PRECOMP256_ROW *)ecp_nistz256_precomputed;
+ ecp_nistz256_select_w7(&p.a, precomputed_table[0], wvalue >> 1);
- ecp_nistz256_select_w7(&t.a, precomputed_table[i], wvalue >> 1);
+ ecp_nistz256_neg(p.p.Z, p.p.Y);
+ copy_conditional(p.p.Y, p.p.Z, wvalue & 1);
- ecp_nistz256_neg(t.p.Z, t.a.Y);
- copy_conditional(t.a.Y, t.p.Z, wvalue & 1);
+ memcpy(p.p.Z, ONE, sizeof(ONE));
- ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a);
- }
- } else {
- p_is_infinity = 1;
- no_precomp_for_generator = 1;
- }
- } else {
- p_is_infinity = 1;
- }
+ for (i = 1; i < 37; i++) {
+ unsigned off = (index - 1) / 8;
+ wvalue = p_str[off] | p_str[off + 1] << 8;
+ wvalue = (wvalue >> ((index - 1) % 8)) & kMask;
+ index += kWindowSize;
- if (no_precomp_for_generator) {
- /* Without a precomputed table for the generator, it has to be handled like
- * a normal point. */
- const BIGNUM **new_scalars;
- const EC_POINT **new_points;
+ wvalue = booth_recode_w7(wvalue);
- /* Bound |num| so that all the possible overflows in the following can be
- * excluded. */
- if (0xffffff < num) {
- OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
- return 0;
- }
+ ecp_nistz256_select_w7(&t.a, precomputed_table[i], wvalue >> 1);
- new_scalars = OPENSSL_malloc((num + 1) * sizeof(BIGNUM *));
- if (new_scalars == NULL) {
- OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
- return 0;
- }
+ ecp_nistz256_neg(t.p.Z, t.a.Y);
+ copy_conditional(t.a.Y, t.p.Z, wvalue & 1);
- new_points = OPENSSL_malloc((num + 1) * sizeof(EC_POINT *));
- if (new_points == NULL) {
- OPENSSL_free((BIGNUM**) new_scalars);
- OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
- return 0;
+ ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a);
}
-
- memcpy((BIGNUM**) new_scalars, scalars, num * sizeof(BIGNUM *));
- new_scalars[num] = scalar;
- memcpy((EC_POINT**) new_points, points, num * sizeof(EC_POINT *));
- new_points[num] = generator;
-
- scalars = new_scalars;
- points = new_points;
- num++;
}
- if (num) {
+ const int p_is_infinity = g_scalar == NULL;
+ if (p_scalar != NULL) {
P256_POINT *out = &t.p;
if (p_is_infinity) {
out = &p.p;
}
- ecp_nistz256_windowed_mul(group, out, scalars, points, num, ctx);
+ if (!ecp_nistz256_windowed_mul(group, out, p_, p_scalar, ctx)) {
+ goto err;
+ }
if (!p_is_infinity) {
ecp_nistz256_point_add(&p.p, &p.p, out);
}
}
- if (no_precomp_for_generator) {
- OPENSSL_free((BIGNUM **) scalars);
- OPENSSL_free((EC_POINT **) points);
- }
-
memcpy(r->X.d, p.p.X, sizeof(p.p.X));
memcpy(r->Y.d, p.p.Y, sizeof(p.p.Y));
memcpy(r->Z.d, p.p.Z, sizeof(p.p.Z));
+
+ /* Not constant-time, but we're only operating on the public output. */
bn_correct_top(&r->X);
bn_correct_top(&r->Y);
bn_correct_top(&r->Z);
+ r->Z_is_one = BN_is_one(&r->Z);
ret = 1;
err:
+ if (ctx_started) {
+ BN_CTX_end(ctx);
+ }
+ BN_CTX_free(new_ctx);
return ret;
}
@@ -659,7 +548,10 @@ static int ecp_nistz256_get_affine(const EC_GROUP *group, const EC_POINT *point,
ecp_nistz256_mul_mont(x_aff, z_inv2, point_x);
if (x != NULL) {
- bn_wexpand(x, P256_LIMBS);
+ if (bn_wexpand(x, P256_LIMBS) == NULL) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
x->top = P256_LIMBS;
ecp_nistz256_from_mont(x->d, x_aff);
bn_correct_top(x);
@@ -668,7 +560,10 @@ static int ecp_nistz256_get_affine(const EC_GROUP *group, const EC_POINT *point,
if (y != NULL) {
ecp_nistz256_mul_mont(z_inv3, z_inv3, z_inv2);
ecp_nistz256_mul_mont(y_aff, z_inv3, point_y);
- bn_wexpand(y, P256_LIMBS);
+ if (bn_wexpand(y, P256_LIMBS) == NULL) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
y->top = P256_LIMBS;
ecp_nistz256_from_mont(y->d, y_aff);
bn_correct_top(y);
@@ -686,7 +581,7 @@ const EC_METHOD *EC_GFp_nistz256_method(void) {
ec_GFp_mont_group_set_curve,
ecp_nistz256_get_affine,
ecp_nistz256_points_mul,
- 0, /* precompute_mult */
+ 0 /* check_pub_key_order */,
ec_GFp_mont_field_mul,
ec_GFp_mont_field_sqr,
ec_GFp_mont_field_encode,
diff --git a/src/crypto/ec/simple.c b/src/crypto/ec/simple.c
index 7e611eb..cef0e94 100644
--- a/src/crypto/ec/simple.c
+++ b/src/crypto/ec/simple.c
@@ -76,25 +76,6 @@
#include "internal.h"
-const EC_METHOD *EC_GFp_simple_method(void) {
- static const EC_METHOD ret = {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_point_get_affine_coordinates,
- 0 /* mul */,
- 0 /* precompute_mult */,
- ec_GFp_simple_field_mul,
- ec_GFp_simple_field_sqr,
- 0 /* field_encode */,
- 0 /* field_decode */,
- 0 /* field_set_to_one */};
-
- return &ret;
-}
-
-
/* Most method functions in this file are designed to work with non-trivial
* representations of field elements if necessary (see ecp_mont.c): while
* standard modular addition and subtraction are used, the field_mul and
diff --git a/src/crypto/ec/wnaf.c b/src/crypto/ec/wnaf.c
index 4aaffd9..ba2257c 100644
--- a/src/crypto/ec/wnaf.c
+++ b/src/crypto/ec/wnaf.c
@@ -80,65 +80,8 @@
/* This file implements the wNAF-based interleaving multi-exponentation method
* (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp>);
- * for multiplication with precomputation, we use wNAF splitting
- * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp>).
* */
-/* structure for precomputed multiples of the generator */
-typedef struct ec_pre_comp_st {
- size_t blocksize; /* block size for wNAF splitting */
- size_t numblocks; /* max. number of blocks for which we have precomputation */
- size_t w; /* window size */
- EC_POINT **points; /* array with pre-calculated multiples of generator:
- * 'num' pointers to EC_POINT objects followed by a NULL */
- size_t num; /* numblocks * 2^(w-1) */
- CRYPTO_refcount_t references;
-} EC_PRE_COMP;
-
-static EC_PRE_COMP *ec_pre_comp_new(void) {
- EC_PRE_COMP *ret = NULL;
-
- ret = (EC_PRE_COMP *)OPENSSL_malloc(sizeof(EC_PRE_COMP));
- if (!ret) {
- OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
- return ret;
- }
- ret->blocksize = 8; /* default */
- ret->numblocks = 0;
- ret->w = 4; /* default */
- ret->points = NULL;
- ret->num = 0;
- ret->references = 1;
- return ret;
-}
-
-void *ec_pre_comp_dup(EC_PRE_COMP *pre_comp) {
- if (pre_comp == NULL) {
- return NULL;
- }
-
- CRYPTO_refcount_inc(&pre_comp->references);
- return pre_comp;
-}
-
-void ec_pre_comp_free(EC_PRE_COMP *pre_comp) {
- if (pre_comp == NULL ||
- !CRYPTO_refcount_dec_and_test_zero(&pre_comp->references)) {
- return;
- }
-
- if (pre_comp->points) {
- EC_POINT **p;
-
- for (p = pre_comp->points; *p != NULL; p++) {
- EC_POINT_free(*p);
- }
- OPENSSL_free(pre_comp->points);
- }
- OPENSSL_free(pre_comp);
-}
-
-
/* Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'.
* This is an array r[] of values that are either zero or odd with an
* absolute value less than 2^w satisfying
@@ -281,21 +224,12 @@ err:
? 2 \
: 1))
-/* Compute
- * \sum scalars[i]*points[i],
- * also including
- * 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 ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
+ const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx) {
BN_CTX *new_ctx = NULL;
const EC_POINT *generator = NULL;
EC_POINT *tmp = NULL;
- size_t totalnum;
- size_t blocksize = 0, numblocks = 0; /* for wNAF splitting */
- size_t pre_points_per_block = 0;
+ size_t total_num;
size_t i, j;
int k;
int r_is_inverted = 0;
@@ -307,30 +241,9 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
size_t num_val;
EC_POINT **val = NULL; /* precomputation */
EC_POINT **v;
- EC_POINT ***val_sub =
- NULL; /* pointers to sub-arrays of 'val' or 'pre_comp->points' */
- const EC_PRE_COMP *pre_comp = NULL;
- int num_scalar = 0; /* flag: will be set to 1 if 'scalar' must be treated like
- * other scalars,
- * i.e. precomputation is not available */
+ EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' */
int ret = 0;
- if (group->meth != r->meth) {
- OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
- return 0;
- }
-
- if ((scalar == NULL) && (num == 0)) {
- return EC_POINT_set_to_infinity(group, r);
- }
-
- for (i = 0; i < num; i++) {
- if (group->meth != points[i]->meth) {
- OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
- return 0;
- }
- }
-
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL) {
@@ -338,52 +251,31 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
}
}
- if (scalar != NULL) {
+ /* TODO: This function used to take |points| and |scalars| as arrays of
+ * |num| elements. The code below should be simplified to work in terms of |p|
+ * and |p_scalar|. */
+ size_t num = p != NULL ? 1 : 0;
+ const EC_POINT **points = p != NULL ? &p : NULL;
+ const BIGNUM **scalars = p != NULL ? &p_scalar : NULL;
+
+ total_num = num;
+
+ if (g_scalar != NULL) {
generator = EC_GROUP_get0_generator(group);
if (generator == NULL) {
OPENSSL_PUT_ERROR(EC, EC_R_UNDEFINED_GENERATOR);
goto err;
}
- /* look if we can use precomputed multiples of generator */
-
- pre_comp = group->pre_comp;
-
- if (pre_comp && pre_comp->numblocks &&
- (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) == 0)) {
- blocksize = pre_comp->blocksize;
-
- /* determine maximum number of blocks that wNAF splitting may yield
- * (NB: maximum wNAF length is bit length plus one) */
- numblocks = (BN_num_bits(scalar) / blocksize) + 1;
-
- /* we cannot use more blocks than we have precomputation for */
- if (numblocks > pre_comp->numblocks) {
- numblocks = pre_comp->numblocks;
- }
-
- pre_points_per_block = (size_t)1 << (pre_comp->w - 1);
-
- /* check that pre_comp looks sane */
- if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) {
- OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- } else {
- /* can't use precomputation */
- pre_comp = NULL;
- numblocks = 1;
- num_scalar = 1; /* treat 'scalar' like 'num'-th element of 'scalars' */
- }
+ ++total_num; /* treat 'g_scalar' like 'num'-th element of 'scalars' */
}
- totalnum = num + numblocks;
- wsize = OPENSSL_malloc(totalnum * sizeof wsize[0]);
- wNAF_len = OPENSSL_malloc(totalnum * sizeof wNAF_len[0]);
- wNAF = OPENSSL_malloc((totalnum + 1) *
+ wsize = OPENSSL_malloc(total_num * sizeof wsize[0]);
+ wNAF_len = OPENSSL_malloc(total_num * sizeof wNAF_len[0]);
+ wNAF = OPENSSL_malloc((total_num + 1) *
sizeof wNAF[0]); /* includes space for pivot */
- val_sub = OPENSSL_malloc(totalnum * sizeof val_sub[0]);
+ val_sub = OPENSSL_malloc(total_num * sizeof val_sub[0]);
/* Ensure wNAF is initialised in case we end up going to err. */
if (wNAF) {
@@ -398,15 +290,15 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
/* num_val will be the total number of temporarily precomputed points */
num_val = 0;
- for (i = 0; i < num + num_scalar; i++) {
+ for (i = 0; i < total_num; i++) {
size_t bits;
- bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar);
+ bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(g_scalar);
wsize[i] = EC_window_bits_for_scalar_size(bits);
num_val += (size_t)1 << (wsize[i] - 1);
wNAF[i + 1] = NULL; /* make sure we always have a pivot */
wNAF[i] =
- compute_wNAF((i < num ? scalars[i] : scalar), wsize[i], &wNAF_len[i]);
+ compute_wNAF((i < num ? scalars[i] : g_scalar), wsize[i], &wNAF_len[i]);
if (wNAF[i] == NULL) {
goto err;
}
@@ -415,110 +307,8 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
}
}
- if (numblocks) {
- /* we go here iff scalar != NULL */
-
- if (pre_comp == NULL) {
- if (num_scalar != 1) {
- OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- /* we have already generated a wNAF for 'scalar' */
- } else {
- signed char *tmp_wNAF = NULL;
- size_t tmp_len = 0;
-
- if (num_scalar != 0) {
- OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
- /* use the window size for which we have precomputation */
- wsize[num] = pre_comp->w;
- tmp_wNAF = compute_wNAF(scalar, wsize[num], &tmp_len);
- if (!tmp_wNAF) {
- goto err;
- }
-
- if (tmp_len <= max_len) {
- /* One of the other wNAFs is at least as long
- * as the wNAF belonging to the generator,
- * so wNAF splitting will not buy us anything. */
-
- numblocks = 1; /* don't use wNAF splitting */
- totalnum = num + numblocks;
- wNAF[num] = tmp_wNAF;
- wNAF[num + 1] = NULL;
- wNAF_len[num] = tmp_len;
- /* pre_comp->points starts with the points that we need here: */
- val_sub[num] = pre_comp->points;
- } else {
- /* don't include tmp_wNAF directly into wNAF array
- * - use wNAF splitting and include the blocks */
-
- signed char *pp;
- EC_POINT **tmp_points;
-
- if (tmp_len < numblocks * blocksize) {
- /* possibly we can do with fewer blocks than estimated */
- numblocks = (tmp_len + blocksize - 1) / blocksize;
- if (numblocks > pre_comp->numblocks) {
- OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
- OPENSSL_free(tmp_wNAF);
- goto err;
- }
- totalnum = num + numblocks;
- }
-
- /* split wNAF in 'numblocks' parts */
- pp = tmp_wNAF;
- tmp_points = pre_comp->points;
-
- for (i = num; i < totalnum; i++) {
- if (i < totalnum - 1) {
- wNAF_len[i] = blocksize;
- if (tmp_len < blocksize) {
- OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
- OPENSSL_free(tmp_wNAF);
- goto err;
- }
- tmp_len -= blocksize;
- } else {
- /* last block gets whatever is left
- * (this could be more or less than 'blocksize'!) */
- wNAF_len[i] = tmp_len;
- }
-
- wNAF[i + 1] = NULL;
- wNAF[i] = OPENSSL_malloc(wNAF_len[i]);
- if (wNAF[i] == NULL) {
- OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
- OPENSSL_free(tmp_wNAF);
- goto err;
- }
- memcpy(wNAF[i], pp, wNAF_len[i]);
- if (wNAF_len[i] > max_len) {
- max_len = wNAF_len[i];
- }
-
- if (*tmp_points == NULL) {
- OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
- OPENSSL_free(tmp_wNAF);
- goto err;
- }
- val_sub[i] = tmp_points;
- tmp_points += pre_points_per_block;
- pp += blocksize;
- }
- OPENSSL_free(tmp_wNAF);
- }
- }
- }
-
- /* All points we precompute now go into a single array 'val'.
- * 'val_sub[i]' is a pointer to the subarray for the i-th point,
- * or to a subarray of 'pre_comp->points' if we already have precomputation.
- */
+ /* All points we precompute now go into a single array 'val'. 'val_sub[i]' is
+ * a pointer to the subarray for the i-th point. */
val = OPENSSL_malloc((num_val + 1) * sizeof val[0]);
if (val == NULL) {
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
@@ -528,7 +318,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
/* allocate points for precomputation */
v = val;
- for (i = 0; i < num + num_scalar; i++) {
+ for (i = 0; i < total_num; i++) {
val_sub[i] = v;
for (j = 0; j < ((size_t)1 << (wsize[i] - 1)); j++) {
*v = EC_POINT_new(group);
@@ -553,7 +343,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
* val_sub[i][2] := 5 * points[i]
* ...
*/
- for (i = 0; i < num + num_scalar; i++) {
+ for (i = 0; i < total_num; i++) {
if (i < num) {
if (!EC_POINT_copy(val_sub[i][0], points[i])) {
goto err;
@@ -587,7 +377,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
goto err;
}
- for (i = 0; i < totalnum; i++) {
+ for (i = 0; i < total_num; i++) {
if (wNAF_len[i] > (size_t)k) {
int digit = wNAF[i][k];
int is_neg;
@@ -657,192 +447,3 @@ err:
OPENSSL_free(val_sub);
return ret;
}
-
-
-/* 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().
- *
- * 'pre_comp->points' is an array of multiples of the generator
- * of the following form:
- * points[0] = generator;
- * points[1] = 3 * generator;
- * ...
- * points[2^(w-1)-1] = (2^(w-1)-1) * generator;
- * points[2^(w-1)] = 2^blocksize * generator;
- * points[2^(w-1)+1] = 3 * 2^blocksize * generator;
- * ...
- * points[2^(w-1)*(numblocks-1)-1] = (2^(w-1)) * 2^(blocksize*(numblocks-2)) *
- *generator
- * points[2^(w-1)*(numblocks-1)] = 2^(blocksize*(numblocks-1)) *
- *generator
- * ...
- * 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) {
- const EC_POINT *generator;
- EC_POINT *tmp_point = NULL, *base = NULL, **var;
- BN_CTX *new_ctx = NULL;
- 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;
-
- /* if there is an old EC_PRE_COMP object, throw it away */
- ec_pre_comp_free(group->pre_comp);
- group->pre_comp = NULL;
-
- generator = EC_GROUP_get0_generator(group);
- if (generator == NULL) {
- OPENSSL_PUT_ERROR(EC, EC_R_UNDEFINED_GENERATOR);
- return 0;
- }
-
- pre_comp = ec_pre_comp_new();
- if (pre_comp == NULL) {
- return 0;
- }
-
- if (ctx == NULL) {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL) {
- goto err;
- }
- }
-
- BN_CTX_start(ctx);
- order = BN_CTX_get(ctx);
- if (order == NULL) {
- goto err;
- }
-
- if (!EC_GROUP_get_order(group, order, ctx)) {
- goto err;
- }
- if (BN_is_zero(order)) {
- OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_ORDER);
- goto err;
- }
-
- bits = BN_num_bits(order);
- /* The following parameters mean we precompute (approximately)
- * one point per bit.
- *
- * TBD: The combination 8, 4 is perfect for 160 bits; for other
- * bit lengths, other parameter combinations might provide better
- * efficiency.
- */
- blocksize = 8;
- w = 4;
- if (EC_window_bits_for_scalar_size(bits) > w) {
- /* let's not make the window too small ... */
- w = EC_window_bits_for_scalar_size(bits);
- }
-
- numblocks = (bits + blocksize - 1) /
- blocksize; /* max. number of blocks to use for wNAF splitting */
-
- pre_points_per_block = (size_t)1 << (w - 1);
- num = pre_points_per_block *
- numblocks; /* number of points to compute and store */
-
- points = OPENSSL_malloc(sizeof(EC_POINT *) * (num + 1));
- if (!points) {
- OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- var = points;
- var[num] = NULL; /* pivot */
- for (i = 0; i < num; i++) {
- if ((var[i] = EC_POINT_new(group)) == NULL) {
- OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- }
-
- if (!(tmp_point = EC_POINT_new(group)) || !(base = EC_POINT_new(group))) {
- OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- if (!EC_POINT_copy(base, generator)) {
- goto err;
- }
-
- /* do the precomputation */
- for (i = 0; i < numblocks; i++) {
- size_t j;
-
- if (!EC_POINT_dbl(group, tmp_point, base, ctx)) {
- goto err;
- }
-
- if (!EC_POINT_copy(*var++, base)) {
- goto err;
- }
-
- for (j = 1; j < pre_points_per_block; j++, var++) {
- /* calculate odd multiples of the current base point */
- if (!EC_POINT_add(group, *var, tmp_point, *(var - 1), ctx)) {
- goto err;
- }
- }
-
- if (i < numblocks - 1) {
- /* get the next base (multiply current one by 2^blocksize) */
- size_t k;
-
- if (blocksize <= 2) {
- OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
- if (!EC_POINT_dbl(group, base, tmp_point, ctx)) {
- goto err;
- }
- for (k = 2; k < blocksize; k++) {
- if (!EC_POINT_dbl(group, base, base, ctx)) {
- goto err;
- }
- }
- }
- }
-
- if (!EC_POINTs_make_affine(group, num, points, ctx)) {
- goto err;
- }
-
- pre_comp->blocksize = blocksize;
- pre_comp->numblocks = numblocks;
- pre_comp->w = w;
- pre_comp->points = points;
- points = NULL;
- pre_comp->num = num;
-
- group->pre_comp = pre_comp;
- pre_comp = NULL;
-
- ret = 1;
-
-err:
- if (ctx != NULL) {
- BN_CTX_end(ctx);
- }
- BN_CTX_free(new_ctx);
- ec_pre_comp_free(pre_comp);
- if (points) {
- EC_POINT **p;
-
- for (p = points; *p != NULL; p++) {
- EC_POINT_free(*p);
- }
- OPENSSL_free(points);
- }
- EC_POINT_free(tmp_point);
- EC_POINT_free(base);
- return ret;
-}
diff --git a/src/crypto/ecdsa/ecdsa.c b/src/crypto/ecdsa/ecdsa.c
index a718cf8..16760ed 100644
--- a/src/crypto/ecdsa/ecdsa.c
+++ b/src/crypto/ecdsa/ecdsa.c
@@ -143,7 +143,7 @@ int ECDSA_do_verify(const uint8_t *digest, size_t digest_len,
const ECDSA_SIG *sig, EC_KEY *eckey) {
int ret = 0;
BN_CTX *ctx;
- BIGNUM *order, *u1, *u2, *m, *X;
+ BIGNUM *u1, *u2, *m, *X;
EC_POINT *point = NULL;
const EC_GROUP *group;
const EC_POINT *pub_key;
@@ -167,21 +167,16 @@ int ECDSA_do_verify(const uint8_t *digest, size_t digest_len,
return 0;
}
BN_CTX_start(ctx);
- order = BN_CTX_get(ctx);
u1 = BN_CTX_get(ctx);
u2 = BN_CTX_get(ctx);
m = BN_CTX_get(ctx);
X = BN_CTX_get(ctx);
- if (order == NULL || u1 == NULL || u2 == NULL || m == NULL || X == NULL) {
+ if (u1 == NULL || u2 == NULL || m == NULL || X == NULL) {
OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
goto err;
}
- if (!EC_GROUP_get_order(group, order, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
- goto err;
- }
-
+ const BIGNUM *order = EC_GROUP_get0_order(group);
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) {
@@ -229,7 +224,7 @@ int ECDSA_do_verify(const uint8_t *digest, size_t digest_len,
ret = (BN_ucmp(u1, sig->r) == 0);
err:
- BN_CTX_end(ctx);
+ BN_CTX_end(ctx);
BN_CTX_free(ctx);
EC_POINT_free(point);
return ret;
@@ -239,7 +234,7 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
BIGNUM **rp, const uint8_t *digest,
size_t digest_len) {
BN_CTX *ctx = NULL;
- BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL;
+ BIGNUM *k = NULL, *r = NULL, *X = NULL;
EC_POINT *tmp_point = NULL;
const EC_GROUP *group;
int ret = 0;
@@ -260,9 +255,8 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
k = BN_new(); /* this value is later returned in *kinvp */
r = BN_new(); /* this value is later returned in *rp */
- order = BN_new();
X = BN_new();
- if (!k || !r || !order || !X) {
+ if (k == NULL || r == NULL || X == NULL) {
OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -271,10 +265,8 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
goto err;
}
- if (!EC_GROUP_get_order(group, order, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
- goto err;
- }
+
+ const BIGNUM *order = EC_GROUP_get0_order(group);
do {
/* If possible, we'll include the private key and message digest in the k
@@ -360,7 +352,6 @@ err:
if (ctx_in == NULL) {
BN_CTX_free(ctx);
}
- BN_free(order);
EC_POINT_free(tmp_point);
BN_clear_free(X);
return ret;
@@ -374,7 +365,7 @@ ECDSA_SIG *ECDSA_do_sign_ex(const uint8_t *digest, size_t digest_len,
const BIGNUM *in_kinv, const BIGNUM *in_r,
EC_KEY *eckey) {
int ok = 0;
- BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL, *order = NULL;
+ BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL;
const BIGNUM *ckinv;
BN_CTX *ctx = NULL;
const EC_GROUP *group;
@@ -401,16 +392,15 @@ ECDSA_SIG *ECDSA_do_sign_ex(const uint8_t *digest, size_t digest_len,
}
s = ret->s;
- if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||
- (tmp = BN_new()) == NULL || (m = BN_new()) == NULL) {
+ if ((ctx = BN_CTX_new()) == NULL ||
+ (tmp = BN_new()) == NULL ||
+ (m = BN_new()) == NULL) {
OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
goto err;
}
- if (!EC_GROUP_get_order(group, order, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
- goto err;
- }
+ const BIGNUM *order = EC_GROUP_get0_order(group);
+
if (!digest_to_bn(m, digest, digest_len, order)) {
goto err;
}
@@ -464,7 +454,6 @@ err:
BN_CTX_free(ctx);
BN_clear_free(m);
BN_clear_free(tmp);
- BN_free(order);
BN_clear_free(kinv);
return ret;
}
diff --git a/src/crypto/ecdsa/ecdsa_asn1.c b/src/crypto/ecdsa/ecdsa_asn1.c
index f2d7c36..3fee191 100644
--- a/src/crypto/ecdsa/ecdsa_asn1.c
+++ b/src/crypto/ecdsa/ecdsa_asn1.c
@@ -78,17 +78,7 @@ size_t ECDSA_size(const EC_KEY *key) {
return 0;
}
- BIGNUM *order = BN_new();
- if (order == NULL) {
- return 0;
- }
- if (!EC_GROUP_get_order(group, order, NULL)) {
- BN_clear_free(order);
- return 0;
- }
-
- group_order_size = BN_num_bytes(order);
- BN_clear_free(order);
+ group_order_size = BN_num_bytes(EC_GROUP_get0_order(group));
}
return ECDSA_SIG_max_len(group_order_size);
diff --git a/src/crypto/ecdsa/ecdsa_test.cc b/src/crypto/ecdsa/ecdsa_test.cc
index b916509..a0c8fbd 100644
--- a/src/crypto/ecdsa/ecdsa_test.cc
+++ b/src/crypto/ecdsa/ecdsa_test.cc
@@ -63,7 +63,6 @@
#include <openssl/rand.h>
#include "../test/scoped_types.h"
-#include "../test/stl_compat.h"
enum Api {
kEncodedApi,
@@ -118,9 +117,8 @@ static bool TestTamperedSig(FILE *out, Api api, const uint8_t *digest,
size_t buf_len = 2 * bn_len;
std::vector<uint8_t> raw_buf(buf_len);
// Pad the bignums with leading zeroes.
- if (!BN_bn2bin_padded(bssl::vector_data(&raw_buf), bn_len, ecdsa_sig->r) ||
- !BN_bn2bin_padded(bssl::vector_data(&raw_buf) + bn_len, bn_len,
- ecdsa_sig->s)) {
+ if (!BN_bn2bin_padded(raw_buf.data(), bn_len, ecdsa_sig->r) ||
+ !BN_bn2bin_padded(raw_buf.data() + bn_len, bn_len, ecdsa_sig->s)) {
return false;
}
@@ -129,18 +127,16 @@ static bool TestTamperedSig(FILE *out, Api api, const uint8_t *digest,
uint8_t dirt = raw_buf[11] ? raw_buf[11] : 1;
raw_buf[offset] ^= dirt;
// Now read the BIGNUMs back in from raw_buf.
- if (BN_bin2bn(bssl::vector_data(&raw_buf), bn_len, ecdsa_sig->r) == NULL ||
- BN_bin2bn(bssl::vector_data(&raw_buf) + bn_len, bn_len,
- ecdsa_sig->s) == NULL ||
+ if (BN_bin2bn(raw_buf.data(), bn_len, ecdsa_sig->r) == NULL ||
+ BN_bin2bn(raw_buf.data() + bn_len, bn_len, ecdsa_sig->s) == NULL ||
!VerifyECDSASig(api, digest, digest_len, ecdsa_sig, eckey, 0)) {
return false;
}
// Sanity check: Undo the modification and verify signature.
raw_buf[offset] ^= dirt;
- if (BN_bin2bn(bssl::vector_data(&raw_buf), bn_len, ecdsa_sig->r) == NULL ||
- BN_bin2bn(bssl::vector_data(&raw_buf) + bn_len, bn_len,
- ecdsa_sig->s) == NULL ||
+ if (BN_bin2bn(raw_buf.data(), bn_len, ecdsa_sig->r) == NULL ||
+ BN_bin2bn(raw_buf.data() + bn_len, bn_len, ecdsa_sig->s) == NULL ||
!VerifyECDSASig(api, digest, digest_len, ecdsa_sig, eckey, 1)) {
return false;
}
@@ -180,12 +176,8 @@ static bool TestBuiltin(FILE *out) {
fprintf(out, " failed\n");
return false;
}
- ScopedBIGNUM order(BN_new());
- if (!order || !EC_GROUP_get_order(group.get(), order.get(), NULL)) {
- fprintf(out, " failed\n");
- return false;
- }
- if (BN_num_bits(order.get()) < 160) {
+ const BIGNUM *order = EC_GROUP_get0_order(group.get());
+ if (BN_num_bits(order) < 160) {
// Too small to test.
fprintf(out, " skipped\n");
continue;
@@ -221,8 +213,7 @@ static bool TestBuiltin(FILE *out) {
// Create a signature.
unsigned sig_len = ECDSA_size(eckey.get());
std::vector<uint8_t> signature(sig_len);
- if (!ECDSA_sign(0, digest, 20, bssl::vector_data(&signature), &sig_len,
- eckey.get())) {
+ if (!ECDSA_sign(0, digest, 20, signature.data(), &sig_len, eckey.get())) {
fprintf(out, " failed\n");
return false;
}
@@ -230,32 +221,32 @@ static bool TestBuiltin(FILE *out) {
fprintf(out, ".");
fflush(out);
// Verify the signature.
- if (!ECDSA_verify(0, digest, 20, bssl::vector_data(&signature),
- signature.size(), eckey.get())) {
+ if (!ECDSA_verify(0, digest, 20, signature.data(), signature.size(),
+ eckey.get())) {
fprintf(out, " failed\n");
return false;
}
fprintf(out, ".");
fflush(out);
// Verify the signature with the wrong key.
- if (ECDSA_verify(0, digest, 20, bssl::vector_data(&signature),
- signature.size(), wrong_eckey.get())) {
+ if (ECDSA_verify(0, digest, 20, signature.data(), signature.size(),
+ wrong_eckey.get())) {
fprintf(out, " failed\n");
return false;
}
fprintf(out, ".");
fflush(out);
// Verify the signature using the wrong digest.
- if (ECDSA_verify(0, wrong_digest, 20, bssl::vector_data(&signature),
- signature.size(), eckey.get())) {
+ if (ECDSA_verify(0, wrong_digest, 20, signature.data(), signature.size(),
+ eckey.get())) {
fprintf(out, " failed\n");
return false;
}
fprintf(out, ".");
fflush(out);
// Verify a truncated signature.
- if (ECDSA_verify(0, digest, 20, bssl::vector_data(&signature),
- signature.size() - 1, eckey.get())) {
+ if (ECDSA_verify(0, digest, 20, signature.data(), signature.size() - 1,
+ eckey.get())) {
fprintf(out, " failed\n");
return false;
}
@@ -263,10 +254,10 @@ static bool TestBuiltin(FILE *out) {
fflush(out);
// Verify a tampered signature.
ScopedECDSA_SIG ecdsa_sig(ECDSA_SIG_from_bytes(
- bssl::vector_data(&signature), signature.size()));
+ signature.data(), signature.size()));
if (!ecdsa_sig ||
!TestTamperedSig(out, kEncodedApi, digest, 20, ecdsa_sig.get(),
- eckey.get(), order.get())) {
+ eckey.get(), order)) {
fprintf(out, " failed\n");
return false;
}
@@ -305,7 +296,7 @@ static bool TestBuiltin(FILE *out) {
fflush(out);
// Verify a tampered signature.
if (!TestTamperedSig(out, kRawApi, digest, 20, ecdsa_sig.get(), eckey.get(),
- order.get())) {
+ order)) {
fprintf(out, " failed\n");
return false;
}
@@ -327,8 +318,8 @@ static bool TestECDSA_SIG_max_len(size_t order_len) {
return false;
}
std::vector<uint8_t> bytes(order_len, 0xff);
- if (!BN_bin2bn(bssl::vector_data(&bytes), bytes.size(), sig->r) ||
- !BN_bin2bn(bssl::vector_data(&bytes), bytes.size(), sig->s)) {
+ if (!BN_bin2bn(bytes.data(), bytes.size(), sig->r) ||
+ !BN_bin2bn(bytes.data(), bytes.size(), sig->s)) {
return false;
}
/* Serialize it. */
diff --git a/src/crypto/err/asn1.errordata b/src/crypto/err/asn1.errordata
index 55342a0..b1b0437 100644
--- a/src/crypto/err/asn1.errordata
+++ b/src/crypto/err/asn1.errordata
@@ -48,41 +48,40 @@ ASN1,146,INVALID_TIME_FORMAT
ASN1,147,INVALID_UNIVERSALSTRING_LENGTH
ASN1,148,INVALID_UTF8STRING
ASN1,149,LIST_ERROR
-ASN1,150,MALLOC_FAILURE
-ASN1,151,MISSING_ASN1_EOS
-ASN1,152,MISSING_EOC
-ASN1,153,MISSING_SECOND_NUMBER
-ASN1,154,MISSING_VALUE
-ASN1,155,MSTRING_NOT_UNIVERSAL
-ASN1,156,MSTRING_WRONG_TAG
-ASN1,157,NESTED_ASN1_ERROR
-ASN1,158,NESTED_ASN1_STRING
-ASN1,159,NON_HEX_CHARACTERS
-ASN1,160,NOT_ASCII_FORMAT
-ASN1,161,NOT_ENOUGH_DATA
-ASN1,162,NO_MATCHING_CHOICE_TYPE
-ASN1,163,NULL_IS_WRONG_LENGTH
-ASN1,164,OBJECT_NOT_ASCII_FORMAT
-ASN1,165,ODD_NUMBER_OF_CHARS
-ASN1,166,SECOND_NUMBER_TOO_LARGE
-ASN1,167,SEQUENCE_LENGTH_MISMATCH
-ASN1,168,SEQUENCE_NOT_CONSTRUCTED
-ASN1,169,SEQUENCE_OR_SET_NEEDS_CONFIG
-ASN1,170,SHORT_LINE
-ASN1,171,STREAMING_NOT_SUPPORTED
-ASN1,172,STRING_TOO_LONG
-ASN1,173,STRING_TOO_SHORT
-ASN1,174,TAG_VALUE_TOO_HIGH
-ASN1,175,TIME_NOT_ASCII_FORMAT
-ASN1,176,TOO_LONG
-ASN1,177,TYPE_NOT_CONSTRUCTED
-ASN1,178,TYPE_NOT_PRIMITIVE
-ASN1,179,UNEXPECTED_EOC
-ASN1,180,UNIVERSALSTRING_IS_WRONG_LENGTH
-ASN1,181,UNKNOWN_FORMAT
-ASN1,182,UNKNOWN_TAG
-ASN1,183,UNSUPPORTED_ANY_DEFINED_BY_TYPE
-ASN1,184,UNSUPPORTED_PUBLIC_KEY_TYPE
-ASN1,185,UNSUPPORTED_TYPE
-ASN1,186,WRONG_TAG
-ASN1,187,WRONG_TYPE
+ASN1,150,MISSING_ASN1_EOS
+ASN1,151,MISSING_EOC
+ASN1,152,MISSING_SECOND_NUMBER
+ASN1,153,MISSING_VALUE
+ASN1,154,MSTRING_NOT_UNIVERSAL
+ASN1,155,MSTRING_WRONG_TAG
+ASN1,156,NESTED_ASN1_ERROR
+ASN1,157,NESTED_ASN1_STRING
+ASN1,158,NON_HEX_CHARACTERS
+ASN1,159,NOT_ASCII_FORMAT
+ASN1,160,NOT_ENOUGH_DATA
+ASN1,161,NO_MATCHING_CHOICE_TYPE
+ASN1,162,NULL_IS_WRONG_LENGTH
+ASN1,163,OBJECT_NOT_ASCII_FORMAT
+ASN1,164,ODD_NUMBER_OF_CHARS
+ASN1,165,SECOND_NUMBER_TOO_LARGE
+ASN1,166,SEQUENCE_LENGTH_MISMATCH
+ASN1,167,SEQUENCE_NOT_CONSTRUCTED
+ASN1,168,SEQUENCE_OR_SET_NEEDS_CONFIG
+ASN1,169,SHORT_LINE
+ASN1,170,STREAMING_NOT_SUPPORTED
+ASN1,171,STRING_TOO_LONG
+ASN1,172,STRING_TOO_SHORT
+ASN1,173,TAG_VALUE_TOO_HIGH
+ASN1,174,TIME_NOT_ASCII_FORMAT
+ASN1,175,TOO_LONG
+ASN1,176,TYPE_NOT_CONSTRUCTED
+ASN1,177,TYPE_NOT_PRIMITIVE
+ASN1,178,UNEXPECTED_EOC
+ASN1,179,UNIVERSALSTRING_IS_WRONG_LENGTH
+ASN1,180,UNKNOWN_FORMAT
+ASN1,181,UNKNOWN_TAG
+ASN1,182,UNSUPPORTED_ANY_DEFINED_BY_TYPE
+ASN1,183,UNSUPPORTED_PUBLIC_KEY_TYPE
+ASN1,184,UNSUPPORTED_TYPE
+ASN1,185,WRONG_TAG
+ASN1,186,WRONG_TYPE
diff --git a/src/crypto/err/ssl.errordata b/src/crypto/err/ssl.errordata
index 0b30b13..3766bb9 100644
--- a/src/crypto/err/ssl.errordata
+++ b/src/crypto/err/ssl.errordata
@@ -7,137 +7,111 @@ SSL,105,BAD_DH_P_LENGTH
SSL,106,BAD_DIGEST_LENGTH
SSL,107,BAD_ECC_CERT
SSL,108,BAD_ECPOINT
-SSL,109,BAD_HANDSHAKE_LENGTH
-SSL,110,BAD_HANDSHAKE_RECORD
-SSL,111,BAD_HELLO_REQUEST
-SSL,112,BAD_LENGTH
-SSL,113,BAD_PACKET_LENGTH
-SSL,114,BAD_RSA_ENCRYPT
-SSL,115,BAD_SIGNATURE
-SSL,116,BAD_SRTP_MKI_VALUE
-SSL,117,BAD_SRTP_PROTECTION_PROFILE_LIST
-SSL,118,BAD_SSL_FILETYPE
-SSL,119,BAD_WRITE_RETRY
-SSL,120,BIO_NOT_SET
-SSL,121,BN_LIB
-SSL,272,BUFFER_TOO_SMALL
-SSL,122,CANNOT_SERIALIZE_PUBLIC_KEY
-SSL,123,CA_DN_LENGTH_MISMATCH
-SSL,124,CA_DN_TOO_LONG
-SSL,125,CCS_RECEIVED_EARLY
-SSL,126,CERTIFICATE_VERIFY_FAILED
-SSL,127,CERT_CB_ERROR
-SSL,128,CERT_LENGTH_MISMATCH
-SSL,129,CHANNEL_ID_NOT_P256
-SSL,130,CHANNEL_ID_SIGNATURE_INVALID
-SSL,131,CIPHER_CODE_WRONG_LENGTH
-SSL,132,CIPHER_OR_HASH_UNAVAILABLE
-SSL,133,CLIENTHELLO_PARSE_FAILED
-SSL,134,CLIENTHELLO_TLSEXT
-SSL,135,CONNECTION_REJECTED
-SSL,136,CONNECTION_TYPE_NOT_SET
-SSL,137,COOKIE_MISMATCH
-SSL,284,CUSTOM_EXTENSION_CONTENTS_TOO_LARGE
-SSL,285,CUSTOM_EXTENSION_ERROR
-SSL,138,D2I_ECDSA_SIG
-SSL,139,DATA_BETWEEN_CCS_AND_FINISHED
-SSL,140,DATA_LENGTH_TOO_LONG
-SSL,141,DECODE_ERROR
-SSL,142,DECRYPTION_FAILED
-SSL,143,DECRYPTION_FAILED_OR_BAD_RECORD_MAC
-SSL,144,DH_PUBLIC_VALUE_LENGTH_IS_WRONG
-SSL,145,DIGEST_CHECK_FAILED
-SSL,146,DTLS_MESSAGE_TOO_BIG
-SSL,147,ECC_CERT_NOT_FOR_SIGNING
-SSL,148,EMPTY_SRTP_PROTECTION_PROFILE_LIST
-SSL,276,EMS_STATE_INCONSISTENT
-SSL,149,ENCRYPTED_LENGTH_TOO_LONG
-SSL,281,ERROR_ADDING_EXTENSION
-SSL,150,ERROR_IN_RECEIVED_CIPHER_LIST
-SSL,282,ERROR_PARSING_EXTENSION
-SSL,151,EVP_DIGESTSIGNFINAL_FAILED
-SSL,152,EVP_DIGESTSIGNINIT_FAILED
-SSL,153,EXCESSIVE_MESSAGE_SIZE
-SSL,154,EXTRA_DATA_IN_MESSAGE
-SSL,271,FRAGMENT_MISMATCH
-SSL,155,GOT_A_FIN_BEFORE_A_CCS
-SSL,156,GOT_CHANNEL_ID_BEFORE_A_CCS
-SSL,157,GOT_NEXT_PROTO_BEFORE_A_CCS
-SSL,158,GOT_NEXT_PROTO_WITHOUT_EXTENSION
-SSL,159,HANDSHAKE_FAILURE_ON_CLIENT_HELLO
-SSL,160,HANDSHAKE_RECORD_BEFORE_CCS
-SSL,161,HTTPS_PROXY_REQUEST
-SSL,162,HTTP_REQUEST
-SSL,163,INAPPROPRIATE_FALLBACK
-SSL,164,INVALID_COMMAND
-SSL,165,INVALID_MESSAGE
-SSL,166,INVALID_SSL_SESSION
-SSL,167,INVALID_TICKET_KEYS_LENGTH
-SSL,168,LENGTH_MISMATCH
-SSL,169,LIBRARY_HAS_NO_CIPHERS
-SSL,170,MISSING_DH_KEY
-SSL,171,MISSING_ECDSA_SIGNING_CERT
-SSL,283,MISSING_EXTENSION
-SSL,172,MISSING_RSA_CERTIFICATE
-SSL,173,MISSING_RSA_ENCRYPTING_CERT
-SSL,174,MISSING_RSA_SIGNING_CERT
-SSL,175,MISSING_TMP_DH_KEY
-SSL,176,MISSING_TMP_ECDH_KEY
-SSL,177,MIXED_SPECIAL_OPERATOR_WITH_GROUPS
-SSL,178,MTU_TOO_SMALL
-SSL,286,NEGOTIATED_BOTH_NPN_AND_ALPN
-SSL,179,NESTED_GROUP
-SSL,180,NO_CERTIFICATES_RETURNED
-SSL,181,NO_CERTIFICATE_ASSIGNED
-SSL,182,NO_CERTIFICATE_SET
-SSL,183,NO_CIPHERS_AVAILABLE
-SSL,184,NO_CIPHERS_PASSED
-SSL,185,NO_CIPHERS_SPECIFIED
-SSL,186,NO_CIPHER_MATCH
-SSL,187,NO_COMPRESSION_SPECIFIED
-SSL,188,NO_METHOD_SPECIFIED
-SSL,189,NO_P256_SUPPORT
-SSL,190,NO_PRIVATE_KEY_ASSIGNED
-SSL,191,NO_RENEGOTIATION
-SSL,192,NO_REQUIRED_DIGEST
-SSL,193,NO_SHARED_CIPHER
-SSL,194,NO_SHARED_SIGATURE_ALGORITHMS
-SSL,195,NO_SRTP_PROFILES
-SSL,196,NULL_SSL_CTX
-SSL,197,NULL_SSL_METHOD_PASSED
-SSL,198,OLD_SESSION_CIPHER_NOT_RETURNED
-SSL,273,OLD_SESSION_VERSION_NOT_RETURNED
-SSL,274,OUTPUT_ALIASES_INPUT
-SSL,199,PACKET_LENGTH_TOO_LONG
-SSL,200,PARSE_TLSEXT
-SSL,201,PATH_TOO_LONG
-SSL,202,PEER_DID_NOT_RETURN_A_CERTIFICATE
-SSL,203,PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE
-SSL,204,PROTOCOL_IS_SHUTDOWN
-SSL,205,PSK_IDENTITY_NOT_FOUND
-SSL,206,PSK_NO_CLIENT_CB
-SSL,207,PSK_NO_SERVER_CB
-SSL,208,READ_BIO_NOT_SET
-SSL,209,READ_TIMEOUT_EXPIRED
-SSL,210,RECORD_LENGTH_MISMATCH
-SSL,211,RECORD_TOO_LARGE
-SSL,212,RENEGOTIATE_EXT_TOO_LONG
-SSL,213,RENEGOTIATION_ENCODING_ERR
-SSL,214,RENEGOTIATION_MISMATCH
-SSL,215,REQUIRED_CIPHER_MISSING
-SSL,275,RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION
-SSL,277,RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION
-SSL,216,SCSV_RECEIVED_WHEN_RENEGOTIATING
-SSL,217,SERVERHELLO_TLSEXT
-SSL,218,SESSION_ID_CONTEXT_UNINITIALIZED
-SSL,219,SESSION_MAY_NOT_BE_CREATED
-SSL,220,SIGNATURE_ALGORITHMS_ERROR
-SSL,280,SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER
-SSL,221,SRTP_COULD_NOT_ALLOCATE_PROFILES
-SSL,222,SRTP_PROTECTION_PROFILE_LIST_TOO_LONG
-SSL,223,SRTP_UNKNOWN_PROTECTION_PROFILE
-SSL,224,SSL3_EXT_INVALID_SERVERNAME
-SSL,225,SSL3_EXT_INVALID_SERVERNAME_TYPE
+SSL,109,BAD_HANDSHAKE_RECORD
+SSL,110,BAD_HELLO_REQUEST
+SSL,111,BAD_LENGTH
+SSL,112,BAD_PACKET_LENGTH
+SSL,113,BAD_RSA_ENCRYPT
+SSL,114,BAD_SIGNATURE
+SSL,115,BAD_SRTP_MKI_VALUE
+SSL,116,BAD_SRTP_PROTECTION_PROFILE_LIST
+SSL,117,BAD_SSL_FILETYPE
+SSL,118,BAD_WRITE_RETRY
+SSL,119,BIO_NOT_SET
+SSL,120,BN_LIB
+SSL,121,BUFFER_TOO_SMALL
+SSL,122,CA_DN_LENGTH_MISMATCH
+SSL,123,CA_DN_TOO_LONG
+SSL,124,CCS_RECEIVED_EARLY
+SSL,125,CERTIFICATE_VERIFY_FAILED
+SSL,126,CERT_CB_ERROR
+SSL,127,CERT_LENGTH_MISMATCH
+SSL,128,CHANNEL_ID_NOT_P256
+SSL,129,CHANNEL_ID_SIGNATURE_INVALID
+SSL,130,CIPHER_OR_HASH_UNAVAILABLE
+SSL,131,CLIENTHELLO_PARSE_FAILED
+SSL,132,CLIENTHELLO_TLSEXT
+SSL,133,CONNECTION_REJECTED
+SSL,134,CONNECTION_TYPE_NOT_SET
+SSL,135,CUSTOM_EXTENSION_ERROR
+SSL,136,DATA_LENGTH_TOO_LONG
+SSL,137,DECODE_ERROR
+SSL,138,DECRYPTION_FAILED
+SSL,139,DECRYPTION_FAILED_OR_BAD_RECORD_MAC
+SSL,140,DH_PUBLIC_VALUE_LENGTH_IS_WRONG
+SSL,141,DH_P_TOO_LONG
+SSL,142,DIGEST_CHECK_FAILED
+SSL,143,DTLS_MESSAGE_TOO_BIG
+SSL,144,ECC_CERT_NOT_FOR_SIGNING
+SSL,145,EMS_STATE_INCONSISTENT
+SSL,146,ENCRYPTED_LENGTH_TOO_LONG
+SSL,147,ERROR_ADDING_EXTENSION
+SSL,148,ERROR_IN_RECEIVED_CIPHER_LIST
+SSL,149,ERROR_PARSING_EXTENSION
+SSL,150,EXCESSIVE_MESSAGE_SIZE
+SSL,151,EXTRA_DATA_IN_MESSAGE
+SSL,152,FRAGMENT_MISMATCH
+SSL,153,GOT_NEXT_PROTO_WITHOUT_EXTENSION
+SSL,154,HANDSHAKE_FAILURE_ON_CLIENT_HELLO
+SSL,155,HTTPS_PROXY_REQUEST
+SSL,156,HTTP_REQUEST
+SSL,157,INAPPROPRIATE_FALLBACK
+SSL,158,INVALID_COMMAND
+SSL,159,INVALID_MESSAGE
+SSL,160,INVALID_SSL_SESSION
+SSL,161,INVALID_TICKET_KEYS_LENGTH
+SSL,162,LENGTH_MISMATCH
+SSL,163,LIBRARY_HAS_NO_CIPHERS
+SSL,164,MISSING_EXTENSION
+SSL,165,MISSING_RSA_CERTIFICATE
+SSL,166,MISSING_TMP_DH_KEY
+SSL,167,MISSING_TMP_ECDH_KEY
+SSL,168,MIXED_SPECIAL_OPERATOR_WITH_GROUPS
+SSL,169,MTU_TOO_SMALL
+SSL,170,NEGOTIATED_BOTH_NPN_AND_ALPN
+SSL,171,NESTED_GROUP
+SSL,172,NO_CERTIFICATES_RETURNED
+SSL,173,NO_CERTIFICATE_ASSIGNED
+SSL,174,NO_CERTIFICATE_SET
+SSL,175,NO_CIPHERS_AVAILABLE
+SSL,176,NO_CIPHERS_PASSED
+SSL,177,NO_CIPHER_MATCH
+SSL,178,NO_COMPRESSION_SPECIFIED
+SSL,179,NO_METHOD_SPECIFIED
+SSL,180,NO_P256_SUPPORT
+SSL,181,NO_PRIVATE_KEY_ASSIGNED
+SSL,182,NO_RENEGOTIATION
+SSL,183,NO_REQUIRED_DIGEST
+SSL,184,NO_SHARED_CIPHER
+SSL,185,NULL_SSL_CTX
+SSL,186,NULL_SSL_METHOD_PASSED
+SSL,187,OLD_SESSION_CIPHER_NOT_RETURNED
+SSL,188,OLD_SESSION_VERSION_NOT_RETURNED
+SSL,189,OUTPUT_ALIASES_INPUT
+SSL,190,PARSE_TLSEXT
+SSL,191,PATH_TOO_LONG
+SSL,192,PEER_DID_NOT_RETURN_A_CERTIFICATE
+SSL,193,PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE
+SSL,194,PROTOCOL_IS_SHUTDOWN
+SSL,195,PSK_IDENTITY_NOT_FOUND
+SSL,196,PSK_NO_CLIENT_CB
+SSL,197,PSK_NO_SERVER_CB
+SSL,198,READ_TIMEOUT_EXPIRED
+SSL,199,RECORD_LENGTH_MISMATCH
+SSL,200,RECORD_TOO_LARGE
+SSL,201,RENEGOTIATION_ENCODING_ERR
+SSL,202,RENEGOTIATION_MISMATCH
+SSL,203,REQUIRED_CIPHER_MISSING
+SSL,204,RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION
+SSL,205,RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION
+SSL,206,SCSV_RECEIVED_WHEN_RENEGOTIATING
+SSL,207,SERVERHELLO_TLSEXT
+SSL,208,SESSION_ID_CONTEXT_UNINITIALIZED
+SSL,209,SESSION_MAY_NOT_BE_CREATED
+SSL,210,SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER
+SSL,211,SRTP_COULD_NOT_ALLOCATE_PROFILES
+SSL,212,SRTP_UNKNOWN_PROTECTION_PROFILE
+SSL,213,SSL3_EXT_INVALID_SERVERNAME
SSL,1042,SSLV3_ALERT_BAD_CERTIFICATE
SSL,1020,SSLV3_ALERT_BAD_RECORD_MAC
SSL,1045,SSLV3_ALERT_CERTIFICATE_EXPIRED
@@ -150,12 +124,9 @@ SSL,1047,SSLV3_ALERT_ILLEGAL_PARAMETER
SSL,1041,SSLV3_ALERT_NO_CERTIFICATE
SSL,1010,SSLV3_ALERT_UNEXPECTED_MESSAGE
SSL,1043,SSLV3_ALERT_UNSUPPORTED_CERTIFICATE
-SSL,226,SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION
-SSL,227,SSL_HANDSHAKE_FAILURE
-SSL,228,SSL_SESSION_ID_CALLBACK_FAILED
-SSL,229,SSL_SESSION_ID_CONFLICT
-SSL,230,SSL_SESSION_ID_CONTEXT_TOO_LONG
-SSL,231,SSL_SESSION_ID_HAS_BAD_LENGTH
+SSL,214,SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION
+SSL,215,SSL_HANDSHAKE_FAILURE
+SSL,216,SSL_SESSION_ID_CONTEXT_TOO_LONG
SSL,1049,TLSV1_ALERT_ACCESS_DENIED
SSL,1050,TLSV1_ALERT_DECODE_ERROR
SSL,1021,TLSV1_ALERT_DECRYPTION_FAILED
@@ -174,44 +145,36 @@ SSL,1113,TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE
SSL,1111,TLSV1_CERTIFICATE_UNOBTAINABLE
SSL,1112,TLSV1_UNRECOGNIZED_NAME
SSL,1110,TLSV1_UNSUPPORTED_EXTENSION
-SSL,232,TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER
-SSL,233,TLS_ILLEGAL_EXPORTER_LABEL
-SSL,234,TLS_INVALID_ECPOINTFORMAT_LIST
-SSL,235,TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST
-SSL,236,TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG
-SSL,237,TOO_MANY_EMPTY_FRAGMENTS
-SSL,278,TOO_MANY_WARNING_ALERTS
-SSL,238,UNABLE_TO_FIND_ECDH_PARAMETERS
-SSL,239,UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS
-SSL,279,UNEXPECTED_EXTENSION
-SSL,240,UNEXPECTED_GROUP_CLOSE
-SSL,241,UNEXPECTED_MESSAGE
-SSL,242,UNEXPECTED_OPERATOR_IN_GROUP
-SSL,243,UNEXPECTED_RECORD
-SSL,244,UNINITIALIZED
-SSL,245,UNKNOWN_ALERT_TYPE
-SSL,246,UNKNOWN_CERTIFICATE_TYPE
-SSL,247,UNKNOWN_CIPHER_RETURNED
-SSL,248,UNKNOWN_CIPHER_TYPE
-SSL,249,UNKNOWN_DIGEST
-SSL,250,UNKNOWN_KEY_EXCHANGE_TYPE
-SSL,251,UNKNOWN_PROTOCOL
-SSL,252,UNKNOWN_SSL_VERSION
-SSL,253,UNKNOWN_STATE
-SSL,254,UNPROCESSED_HANDSHAKE_DATA
-SSL,255,UNSAFE_LEGACY_RENEGOTIATION_DISABLED
-SSL,256,UNSUPPORTED_CIPHER
-SSL,257,UNSUPPORTED_COMPRESSION_ALGORITHM
-SSL,258,UNSUPPORTED_ELLIPTIC_CURVE
-SSL,259,UNSUPPORTED_PROTOCOL
-SSL,260,UNSUPPORTED_SSL_VERSION
-SSL,261,USE_SRTP_NOT_NEGOTIATED
-SSL,262,WRONG_CERTIFICATE_TYPE
-SSL,263,WRONG_CIPHER_RETURNED
-SSL,264,WRONG_CURVE
-SSL,265,WRONG_MESSAGE_TYPE
-SSL,266,WRONG_SIGNATURE_TYPE
-SSL,267,WRONG_SSL_VERSION
-SSL,268,WRONG_VERSION_NUMBER
-SSL,269,X509_LIB
-SSL,270,X509_VERIFICATION_SETUP_PROBLEMS
+SSL,217,TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST
+SSL,218,TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG
+SSL,219,TOO_MANY_EMPTY_FRAGMENTS
+SSL,220,TOO_MANY_WARNING_ALERTS
+SSL,221,UNABLE_TO_FIND_ECDH_PARAMETERS
+SSL,222,UNEXPECTED_EXTENSION
+SSL,223,UNEXPECTED_MESSAGE
+SSL,224,UNEXPECTED_OPERATOR_IN_GROUP
+SSL,225,UNEXPECTED_RECORD
+SSL,226,UNINITIALIZED
+SSL,227,UNKNOWN_ALERT_TYPE
+SSL,228,UNKNOWN_CERTIFICATE_TYPE
+SSL,229,UNKNOWN_CIPHER_RETURNED
+SSL,230,UNKNOWN_CIPHER_TYPE
+SSL,231,UNKNOWN_DIGEST
+SSL,232,UNKNOWN_KEY_EXCHANGE_TYPE
+SSL,233,UNKNOWN_PROTOCOL
+SSL,234,UNKNOWN_SSL_VERSION
+SSL,235,UNKNOWN_STATE
+SSL,236,UNSAFE_LEGACY_RENEGOTIATION_DISABLED
+SSL,237,UNSUPPORTED_CIPHER
+SSL,238,UNSUPPORTED_COMPRESSION_ALGORITHM
+SSL,239,UNSUPPORTED_ELLIPTIC_CURVE
+SSL,240,UNSUPPORTED_PROTOCOL
+SSL,241,WRONG_CERTIFICATE_TYPE
+SSL,242,WRONG_CIPHER_RETURNED
+SSL,243,WRONG_CURVE
+SSL,244,WRONG_MESSAGE_TYPE
+SSL,245,WRONG_SIGNATURE_TYPE
+SSL,246,WRONG_SSL_VERSION
+SSL,247,WRONG_VERSION_NUMBER
+SSL,248,X509_LIB
+SSL,249,X509_VERIFICATION_SETUP_PROBLEMS
diff --git a/src/crypto/evp/evp.c b/src/crypto/evp/evp.c
index 5822379..afe5c38 100644
--- a/src/crypto/evp/evp.c
+++ b/src/crypto/evp/evp.c
@@ -60,7 +60,6 @@
#include <string.h>
#include <openssl/bio.h>
-#include <openssl/dh.h>
#include <openssl/dsa.h>
#include <openssl/ec.h>
#include <openssl/err.h>
@@ -73,10 +72,6 @@
#include "../internal.h"
-extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meth;
-extern const EVP_PKEY_ASN1_METHOD ec_asn1_meth;
-extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meth;
-
EVP_PKEY *EVP_PKEY_new(void) {
EVP_PKEY *ret;
@@ -235,15 +230,22 @@ int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key) {
return EVP_PKEY_assign(pkey, EVP_PKEY_RSA, key);
}
-RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) {
+RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) {
if (pkey->type != EVP_PKEY_RSA) {
OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_RSA_KEY);
return NULL;
}
- RSA_up_ref(pkey->pkey.rsa);
return pkey->pkey.rsa;
}
+RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) {
+ RSA *rsa = EVP_PKEY_get0_RSA(pkey);
+ if (rsa != NULL) {
+ RSA_up_ref(rsa);
+ }
+ return rsa;
+}
+
int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) {
if (EVP_PKEY_assign_DSA(pkey, key)) {
DSA_up_ref(key);
@@ -256,15 +258,22 @@ int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key) {
return EVP_PKEY_assign(pkey, EVP_PKEY_DSA, key);
}
-DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey) {
+DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey) {
if (pkey->type != EVP_PKEY_DSA) {
OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DSA_KEY);
return NULL;
}
- DSA_up_ref(pkey->pkey.dsa);
return pkey->pkey.dsa;
}
+DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey) {
+ DSA *dsa = EVP_PKEY_get0_DSA(pkey);
+ if (dsa != NULL) {
+ DSA_up_ref(dsa);
+ }
+ return dsa;
+}
+
int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) {
if (EVP_PKEY_assign_EC_KEY(pkey, key)) {
EC_KEY_up_ref(key);
@@ -277,34 +286,20 @@ int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) {
return EVP_PKEY_assign(pkey, EVP_PKEY_EC, key);
}
-EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) {
+EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey) {
if (pkey->type != EVP_PKEY_EC) {
OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_EC_KEY_KEY);
return NULL;
}
- EC_KEY_up_ref(pkey->pkey.ec);
return pkey->pkey.ec;
}
-int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key) {
- if (EVP_PKEY_assign_DH(pkey, key)) {
- DH_up_ref(key);
- return 1;
- }
- return 0;
-}
-
-int EVP_PKEY_assign_DH(EVP_PKEY *pkey, DH *key) {
- return EVP_PKEY_assign(pkey, EVP_PKEY_DH, key);
-}
-
-DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey) {
- if (pkey->type != EVP_PKEY_DH) {
- OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DH_KEY);
- return NULL;
+EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) {
+ EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey);
+ if (ec_key != NULL) {
+ EC_KEY_up_ref(ec_key);
}
- DH_up_ref(pkey->pkey.dh);
- return pkey->pkey.dh;
+ return ec_key;
}
int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) {
diff --git a/src/crypto/evp/evp_ctx.c b/src/crypto/evp/evp_ctx.c
index a8e71fe..9e038cd 100644
--- a/src/crypto/evp/evp_ctx.c
+++ b/src/crypto/evp/evp_ctx.c
@@ -66,9 +66,6 @@
#include "internal.h"
-extern const EVP_PKEY_METHOD rsa_pkey_meth;
-extern const EVP_PKEY_METHOD ec_pkey_meth;
-
static const EVP_PKEY_METHOD *const evp_methods[] = {
&rsa_pkey_meth,
&ec_pkey_meth,
diff --git a/src/crypto/evp/evp_extra_test.cc b/src/crypto/evp/evp_extra_test.cc
index bd70040..fe7a002 100644
--- a/src/crypto/evp/evp_extra_test.cc
+++ b/src/crypto/evp/evp_extra_test.cc
@@ -16,6 +16,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <utility>
#include <vector>
#include <openssl/bytestring.h>
@@ -233,6 +234,85 @@ static const uint8_t kExamplePSSCert[] = {
0x8c, 0x16,
};
+// kBadPSSCert is an example RSA-PSS certificate with bad parameters.
+static const uint8_t kBadPSSCert[] = {
+ 0x30, 0x82, 0x03, 0x76, 0x30, 0x82, 0x02, 0x3a, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x09, 0x00, 0xd7, 0x30, 0x64, 0xbc, 0x9f, 0x12, 0xfe, 0xc3,
+ 0x30, 0x3e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x0a, 0x30, 0x31, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48,
+ 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06,
+ 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x04,
+ 0x02, 0x02, 0x00, 0xde, 0x30, 0x27, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03,
+ 0x55, 0x04, 0x03, 0x0c, 0x1c, 0x54, 0x65, 0x73, 0x74, 0x20, 0x49, 0x6e,
+ 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x50, 0x53, 0x53, 0x20, 0x63, 0x65,
+ 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x1e, 0x17,
+ 0x0d, 0x31, 0x35, 0x31, 0x31, 0x30, 0x34, 0x31, 0x36, 0x30, 0x32, 0x33,
+ 0x35, 0x5a, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x32, 0x30, 0x34, 0x31, 0x36,
+ 0x30, 0x32, 0x33, 0x35, 0x5a, 0x30, 0x27, 0x31, 0x25, 0x30, 0x23, 0x06,
+ 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1c, 0x54, 0x65, 0x73, 0x74, 0x20, 0x49,
+ 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x50, 0x53, 0x53, 0x20, 0x63,
+ 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x82,
+ 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+ 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82,
+ 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc4, 0xda, 0x33, 0xb5, 0x87,
+ 0xa9, 0x50, 0x80, 0x18, 0x02, 0x00, 0xfb, 0x32, 0xf5, 0x29, 0x6b, 0xef,
+ 0x01, 0x24, 0xeb, 0x86, 0x5a, 0xbe, 0xd5, 0xe3, 0xdd, 0x3b, 0xbc, 0x2c,
+ 0xad, 0x65, 0xf6, 0x2a, 0x26, 0x28, 0x4d, 0x8a, 0xc9, 0x61, 0x39, 0xf1,
+ 0x84, 0xb9, 0xe7, 0xd3, 0x0a, 0xc7, 0xa8, 0x0a, 0x6d, 0xef, 0xd9, 0xcb,
+ 0x20, 0x11, 0xbb, 0x71, 0xf4, 0xa1, 0xc9, 0x9a, 0x85, 0x1c, 0xe6, 0x3f,
+ 0x23, 0x39, 0x58, 0x3c, 0xc5, 0x6d, 0xfa, 0x03, 0xe8, 0xdb, 0xdd, 0xe0,
+ 0xc3, 0xde, 0x85, 0x76, 0xce, 0x49, 0x06, 0xc8, 0xe1, 0x8e, 0x4c, 0x86,
+ 0x9c, 0xec, 0xab, 0xf4, 0xe5, 0x27, 0xb4, 0x5a, 0xaf, 0xc4, 0x36, 0xd3,
+ 0x20, 0x81, 0x54, 0xee, 0x8f, 0x48, 0x77, 0x10, 0xf8, 0x79, 0xd6, 0xaa,
+ 0x8d, 0x1b, 0xfe, 0x7d, 0xe8, 0x15, 0x13, 0xe0, 0x7b, 0xf6, 0x90, 0xe4,
+ 0xe2, 0xcd, 0x2e, 0x8e, 0xc9, 0x3a, 0x75, 0x42, 0xed, 0x0a, 0x0f, 0x51,
+ 0xb2, 0xdd, 0x2e, 0x70, 0x61, 0x68, 0xd7, 0xd9, 0xab, 0xf9, 0xbe, 0xe4,
+ 0x75, 0xb7, 0xe7, 0xf2, 0x96, 0x7b, 0xd9, 0x93, 0x43, 0x24, 0xfb, 0x9e,
+ 0x55, 0xda, 0xd4, 0x01, 0x6c, 0x3d, 0xa2, 0x59, 0x7a, 0xd5, 0x47, 0x18,
+ 0x7e, 0x4e, 0xf9, 0x5d, 0xda, 0xcb, 0x93, 0xa2, 0x65, 0x2f, 0x8d, 0x46,
+ 0xad, 0x81, 0xdc, 0xf0, 0xa9, 0x5f, 0x5d, 0xfe, 0x37, 0x80, 0x64, 0x2a,
+ 0x41, 0xfa, 0xe9, 0x1e, 0x48, 0x38, 0x22, 0x1d, 0x9c, 0x23, 0xa5, 0xad,
+ 0xda, 0x78, 0x45, 0x18, 0x0c, 0xeb, 0x95, 0xca, 0x2b, 0xcc, 0xb9, 0x62,
+ 0x40, 0x85, 0x09, 0x44, 0x88, 0x4c, 0xf2, 0x1e, 0x08, 0x80, 0x37, 0xe9,
+ 0x06, 0x96, 0x8f, 0x75, 0x54, 0x0b, 0xa9, 0x2d, 0xa9, 0x15, 0xb5, 0xda,
+ 0xe5, 0xe4, 0x23, 0xaa, 0x2c, 0x89, 0xc1, 0xa9, 0x36, 0xbc, 0x9f, 0x02,
+ 0x03, 0x01, 0x00, 0x01, 0xa3, 0x50, 0x30, 0x4e, 0x30, 0x1d, 0x06, 0x03,
+ 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2b, 0x75, 0xf3, 0x43, 0x78,
+ 0xa0, 0x65, 0x2d, 0xe4, 0xb6, 0xf3, 0x07, 0x04, 0x38, 0x21, 0xaf, 0xb6,
+ 0xe1, 0x5f, 0x7b, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
+ 0x30, 0x16, 0x80, 0x14, 0x2b, 0x75, 0xf3, 0x43, 0x78, 0xa0, 0x65, 0x2d,
+ 0xe4, 0xb6, 0xf3, 0x07, 0x04, 0x38, 0x21, 0xaf, 0xb6, 0xe1, 0x5f, 0x7b,
+ 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01,
+ 0x01, 0xff, 0x30, 0x31, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+ 0x01, 0x01, 0x0a, 0x30, 0x24, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60,
+ 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x0d, 0x30, 0x0b,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0xa2,
+ 0x04, 0x02, 0x02, 0x00, 0xde, 0x03, 0x82, 0x01, 0x01, 0x00, 0x08, 0xc1,
+ 0xb6, 0x6f, 0x74, 0x94, 0x6c, 0x60, 0x75, 0xd8, 0xdc, 0xe1, 0x7b, 0xbf,
+ 0x9d, 0xb5, 0xd7, 0x14, 0x75, 0x6c, 0xdb, 0x35, 0x5c, 0x1e, 0xff, 0xe6,
+ 0xa8, 0xe6, 0x68, 0x42, 0x41, 0x81, 0xf6, 0xbf, 0xc1, 0x56, 0x02, 0xdb,
+ 0xc6, 0x11, 0xeb, 0x15, 0x9d, 0xa9, 0x1c, 0x61, 0x25, 0x6d, 0x46, 0x0f,
+ 0x7e, 0x27, 0xdd, 0x4b, 0xdc, 0xed, 0x07, 0xbd, 0xde, 0xd5, 0xde, 0x09,
+ 0xf8, 0xfd, 0xbd, 0xa3, 0x4c, 0x81, 0xa9, 0xf7, 0x78, 0xff, 0x01, 0x80,
+ 0x73, 0xf2, 0x40, 0xf2, 0xa8, 0x27, 0xe8, 0x00, 0x04, 0x3b, 0xf5, 0xe7,
+ 0xa6, 0x58, 0x45, 0x79, 0x34, 0x49, 0x42, 0xd2, 0xd9, 0x56, 0x5e, 0xf9,
+ 0x0a, 0x41, 0xd7, 0x81, 0x41, 0x94, 0x77, 0x78, 0x7e, 0x00, 0x3b, 0xca,
+ 0xb5, 0xc0, 0x6e, 0x5b, 0xd7, 0x52, 0x52, 0x77, 0x1a, 0x52, 0xb8, 0x0d,
+ 0x29, 0x1f, 0x2e, 0xfe, 0x1f, 0xf6, 0xb0, 0xc1, 0xb7, 0xf1, 0x15, 0x98,
+ 0x0f, 0x30, 0x5d, 0x74, 0x2f, 0xfa, 0xe9, 0x84, 0xda, 0xde, 0xbe, 0xca,
+ 0x91, 0x55, 0x1f, 0x5b, 0xbc, 0xaa, 0x45, 0x07, 0xc4, 0x2e, 0x21, 0x8a,
+ 0x75, 0xc9, 0xbe, 0x6e, 0x39, 0x53, 0x10, 0xcb, 0x2f, 0x4b, 0xe1, 0x21,
+ 0x1e, 0xea, 0x7d, 0x0b, 0x36, 0xe9, 0xa0, 0x2c, 0x76, 0x17, 0x1f, 0x69,
+ 0x34, 0xfb, 0x45, 0x63, 0x7c, 0x84, 0x39, 0xb4, 0x21, 0x98, 0xbd, 0x49,
+ 0xca, 0x80, 0x91, 0x5a, 0xa0, 0x44, 0xef, 0x91, 0xb3, 0x14, 0xf6, 0xd1,
+ 0x6a, 0x2b, 0xb1, 0xe5, 0x4a, 0x44, 0x92, 0x7b, 0x3e, 0x8b, 0x7b, 0x6b,
+ 0x90, 0x6b, 0x2c, 0x67, 0x3b, 0x0e, 0xb9, 0x5a, 0x87, 0x35, 0x33, 0x59,
+ 0x94, 0x2f, 0x7e, 0xf6, 0x13, 0xc7, 0x22, 0x87, 0x3d, 0x50, 0xc9, 0x80,
+ 0x40, 0xda, 0x35, 0xbc, 0x62, 0x16, 0xdc, 0xd5, 0x95, 0xa1, 0xe1, 0x9b,
+ 0x68, 0x9f,
+};
+
// kExampleRSAKeyPKCS8 is kExampleRSAKeyDER encoded in a PKCS #8
// PrivateKeyInfo.
static const uint8_t kExampleRSAKeyPKCS8[] = {
@@ -342,6 +422,22 @@ static const uint8_t kExampleBadECKeyDER2[] = {
0x07,
};
+// kInvalidPrivateKey is an invalid private key. See
+// https://rt.openssl.org/Ticket/Display.html?id=4131.
+static const uint8_t kInvalidPrivateKey[] = {
+ 0x30, 0x39, 0x02, 0x01, 0x02, 0x30, 0x09, 0x06, 0x01, 0x38, 0x08,
+ 0x04, 0x69, 0x30, 0x30, 0x80, 0x30, 0x19, 0x01, 0x02, 0x9f, 0xf8,
+ 0x8b, 0x29, 0x80, 0x30, 0xb0, 0x1b, 0x06, 0x09, 0x22, 0xbe, 0x08,
+ 0x04, 0xe9, 0x30, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x3a, 0x01, 0x80,
+ 0x09, 0x30, 0x80, 0x06, 0x01, 0x02, 0x30, 0x80, 0x30, 0x01, 0x3b,
+ 0x02, 0x00, 0x00, 0x04, 0x20, 0x30, 0x82, 0x04, 0xe9, 0x30, 0xc3,
+ 0xe8, 0x30, 0x01, 0x05, 0x30, 0x80, 0x30, 0x01, 0x3b, 0x01, 0x04,
+ 0x02, 0x02, 0xff, 0x00, 0x30, 0x29, 0x02, 0x11, 0x03, 0x29, 0x29,
+ 0x02, 0x00, 0x99, 0x30, 0x80, 0x06, 0x21, 0x02, 0x24, 0x04, 0xe8,
+ 0x30, 0x01, 0x01, 0x04, 0x30, 0x80, 0x1b, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x30, 0x01, 0xaa, 0x02, 0x86, 0xc0, 0x30, 0xdf, 0xe9, 0x80,
+};
+
static ScopedEVP_PKEY LoadExampleRSAKey() {
ScopedRSA rsa(RSA_private_key_from_bytes(kExampleRSAKeyDER,
sizeof(kExampleRSAKeyDER)));
@@ -376,16 +472,17 @@ static bool TestEVP_DigestSignInit(void) {
std::vector<uint8_t> sig;
sig.resize(sig_len);
- if (!EVP_DigestSignFinal(md_ctx.get(), bssl::vector_data(&sig), &sig_len)) {
+ if (!EVP_DigestSignFinal(md_ctx.get(), sig.data(), &sig_len)) {
return false;
}
sig.resize(sig_len);
// Ensure that the signature round-trips.
md_ctx.Reset();
- if (!EVP_DigestVerifyInit(md_ctx.get(), NULL, EVP_sha256(), NULL, pkey.get()) ||
+ if (!EVP_DigestVerifyInit(md_ctx.get(), NULL, EVP_sha256(), NULL,
+ pkey.get()) ||
!EVP_DigestVerifyUpdate(md_ctx.get(), kMsg, sizeof(kMsg)) ||
- !EVP_DigestVerifyFinal(md_ctx.get(), bssl::vector_data(&sig), sig_len)) {
+ !EVP_DigestVerifyFinal(md_ctx.get(), sig.data(), sig_len)) {
return false;
}
@@ -432,7 +529,7 @@ static bool TestAlgorithmRoundtrip(EVP_MD_CTX *md_ctx, EVP_PKEY *pkey) {
std::vector<uint8_t> sig;
sig.resize(sig_len);
- if (!EVP_DigestSignFinal(md_ctx, bssl::vector_data(&sig), &sig_len)) {
+ if (!EVP_DigestSignFinal(md_ctx, sig.data(), &sig_len)) {
return false;
}
sig.resize(sig_len);
@@ -442,8 +539,7 @@ static bool TestAlgorithmRoundtrip(EVP_MD_CTX *md_ctx, EVP_PKEY *pkey) {
if (!EVP_DigestVerifyInitFromAlgorithm(md_ctx_verify.get(), algor.get(),
pkey) ||
!EVP_DigestVerifyUpdate(md_ctx_verify.get(), kMsg, sizeof(kMsg)) ||
- !EVP_DigestVerifyFinal(md_ctx_verify.get(), bssl::vector_data(&sig),
- sig_len)) {
+ !EVP_DigestVerifyFinal(md_ctx_verify.get(), sig.data(), sig_len)) {
return false;
}
@@ -477,16 +573,52 @@ static bool TestEVP_DigestSignAlgorithm(void) {
return true;
}
-static bool TestEVP_DigestVerifyInitFromAlgorithm(void) {
- CBS cert, cert_body, tbs_cert, algorithm, signature;
- CBS_init(&cert, kExamplePSSCert, sizeof(kExamplePSSCert));
- if (!CBS_get_asn1(&cert, &cert_body, CBS_ASN1_SEQUENCE) ||
- CBS_len(&cert) != 0 ||
+static bool ParseCertificate(CBS *out_tbs_cert,
+ ScopedEVP_PKEY *out_pubkey,
+ ScopedX509_ALGOR *out_algor,
+ CBS *out_signature,
+ const CBS *in_) {
+ CBS in = *in_;
+ CBS cert_body, tbs_cert, algorithm, signature;
+ if (!CBS_get_asn1(&in, &cert_body, CBS_ASN1_SEQUENCE) ||
+ CBS_len(&in) != 0 ||
!CBS_get_any_asn1_element(&cert_body, &tbs_cert, NULL, NULL) ||
!CBS_get_asn1_element(&cert_body, &algorithm, CBS_ASN1_SEQUENCE) ||
!CBS_get_asn1(&cert_body, &signature, CBS_ASN1_BITSTRING) ||
CBS_len(&cert_body) != 0) {
- fprintf(stderr, "Failed to parse certificate\n");
+ return false;
+ }
+
+ CBS tbs_cert_copy = tbs_cert;
+ CBS tbs_cert_body, discard, spki;
+ if (!CBS_get_asn1(&tbs_cert_copy, &tbs_cert_body, CBS_ASN1_SEQUENCE) ||
+ CBS_len(&tbs_cert_copy) != 0 ||
+ !CBS_get_optional_asn1(
+ &tbs_cert_body, &discard, NULL,
+ CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) ||
+ !CBS_get_asn1(&tbs_cert_body, &discard /* serialNumber */,
+ CBS_ASN1_INTEGER) ||
+ !CBS_get_asn1(&tbs_cert_body, &discard /* signature */,
+ CBS_ASN1_SEQUENCE) ||
+ !CBS_get_any_asn1_element(&tbs_cert_body, &discard /* issuer */,
+ NULL, NULL) ||
+ !CBS_get_asn1(&tbs_cert_body, &discard /* validity */,
+ CBS_ASN1_SEQUENCE) ||
+ !CBS_get_any_asn1_element(&tbs_cert_body, &discard /* subject */,
+ NULL, NULL) ||
+ !CBS_get_asn1_element(&tbs_cert_body, &spki, CBS_ASN1_SEQUENCE)) {
+ return false;
+ }
+
+ const uint8_t *derp = CBS_data(&spki);
+ ScopedEVP_PKEY pubkey(d2i_PUBKEY(NULL, &derp, CBS_len(&spki)));
+ if (!pubkey || derp != CBS_data(&spki) + CBS_len(&spki)) {
+ return false;
+ }
+
+ derp = CBS_data(&algorithm);
+ ScopedX509_ALGOR algor(d2i_X509_ALGOR(NULL, &derp, CBS_len(&algorithm)));
+ if (!algor || derp != CBS_data(&algorithm) + CBS_len(&algorithm)) {
return false;
}
@@ -494,21 +626,28 @@ static bool TestEVP_DigestVerifyInitFromAlgorithm(void) {
// leading phase byte is just a zero.
uint8_t padding;
if (!CBS_get_u8(&signature, &padding) || padding != 0) {
- fprintf(stderr, "Invalid signature padding\n");
return false;
}
- const uint8_t *derp = CBS_data(&algorithm);
- ScopedX509_ALGOR algor(d2i_X509_ALGOR(NULL, &derp, CBS_len(&algorithm)));
- if (!algor || derp != CBS_data(&algorithm) + CBS_len(&algorithm)) {
- fprintf(stderr, "Failed to parse algorithm\n");
+ *out_tbs_cert = tbs_cert;
+ *out_pubkey = std::move(pubkey);
+ *out_algor = std::move(algor);
+ *out_signature = signature;
+ return true;
+}
+
+static bool TestEVP_DigestVerifyInitFromAlgorithm(void) {
+ CBS in, tbs_cert, signature;
+ ScopedEVP_PKEY pkey;
+ ScopedX509_ALGOR algor;
+ CBS_init(&in, kExamplePSSCert, sizeof(kExamplePSSCert));
+ if (!ParseCertificate(&tbs_cert, &pkey, &algor, &signature, &in)) {
+ fprintf(stderr, "Failed to parse certificate\n");
return false;
}
- ScopedEVP_PKEY pkey = LoadExampleRSAKey();
ScopedEVP_MD_CTX md_ctx;
- if (!pkey ||
- !EVP_DigestVerifyInitFromAlgorithm(md_ctx.get(), algor.get(),
+ if (!EVP_DigestVerifyInitFromAlgorithm(md_ctx.get(), algor.get(),
pkey.get()) ||
!EVP_DigestVerifyUpdate(md_ctx.get(), CBS_data(&tbs_cert),
CBS_len(&tbs_cert)) ||
@@ -519,8 +658,28 @@ static bool TestEVP_DigestVerifyInitFromAlgorithm(void) {
return true;
}
-static bool Testd2i_AutoPrivateKey(const uint8_t *input, size_t input_len,
- int expected_id) {
+static bool TestBadPSSParameters(void) {
+ CBS in, tbs_cert, signature;
+ ScopedEVP_PKEY pkey;
+ ScopedX509_ALGOR algor;
+ CBS_init(&in, kBadPSSCert, sizeof(kBadPSSCert));
+ if (!ParseCertificate(&tbs_cert, &pkey, &algor, &signature, &in)) {
+ fprintf(stderr, "Failed to parse certificate\n");
+ return false;
+ }
+
+ ScopedEVP_MD_CTX md_ctx;
+ if (EVP_DigestVerifyInitFromAlgorithm(md_ctx.get(), algor.get(),
+ pkey.get())) {
+ fprintf(stderr, "Unexpectedly processed bad signature parameters\n");
+ return false;
+ }
+ ERR_clear_error();
+ return true;
+}
+
+static bool TestValidPrivateKey(const uint8_t *input, size_t input_len,
+ int expected_id) {
const uint8_t *p = input;
ScopedEVP_PKEY pkey(d2i_AutoPrivateKey(NULL, &p, input_len));
if (!pkey || p != input + input_len) {
@@ -536,6 +695,42 @@ static bool Testd2i_AutoPrivateKey(const uint8_t *input, size_t input_len,
return true;
}
+static bool Testd2i_AutoPrivateKey() {
+ if (!TestValidPrivateKey(kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER),
+ EVP_PKEY_RSA)) {
+ fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyDER) failed\n");
+ return false;
+ }
+
+ if (!TestValidPrivateKey(kExampleRSAKeyPKCS8, sizeof(kExampleRSAKeyPKCS8),
+ EVP_PKEY_RSA)) {
+ fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyPKCS8) failed\n");
+ return false;
+ }
+
+ if (!TestValidPrivateKey(kExampleECKeyDER, sizeof(kExampleECKeyDER),
+ EVP_PKEY_EC)) {
+ fprintf(stderr, "d2i_AutoPrivateKey(kExampleECKeyDER) failed\n");
+ return false;
+ }
+
+ if (!TestValidPrivateKey(kExampleDSAKeyDER, sizeof(kExampleDSAKeyDER),
+ EVP_PKEY_DSA)) {
+ fprintf(stderr, "d2i_AutoPrivateKey(kExampleDSAKeyDER) failed\n");
+ return false;
+ }
+
+ const uint8_t *p = kInvalidPrivateKey;
+ ScopedEVP_PKEY pkey(d2i_AutoPrivateKey(NULL, &p, sizeof(kInvalidPrivateKey)));
+ if (pkey) {
+ fprintf(stderr, "Parsed invalid private key\n");
+ return false;
+ }
+ ERR_clear_error();
+
+ return true;
+}
+
// TestEVP_PKCS82PKEY tests loading a bad key in PKCS8 format.
static bool TestEVP_PKCS82PKEY(void) {
const uint8_t *derp = kExampleBadECKeyDER;
@@ -602,7 +797,7 @@ static bool Testd2i_PrivateKey(void) {
// Copy the input into a |malloc|'d vector to flag memory errors.
std::vector<uint8_t> copy(kExampleBadECKeyDER2, kExampleBadECKeyDER2 +
sizeof(kExampleBadECKeyDER2));
- derp = bssl::vector_data(&copy);
+ derp = copy.data();
pkey.reset(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &derp, copy.size()));
if (pkey) {
fprintf(stderr, "Imported invalid EC key #2.\n");
@@ -641,30 +836,14 @@ int main(void) {
return 1;
}
- if (!Testd2i_AutoPrivateKey(kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER),
- EVP_PKEY_RSA)) {
- fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyDER) failed\n");
- ERR_print_errors_fp(stderr);
- return 1;
- }
-
- if (!Testd2i_AutoPrivateKey(kExampleRSAKeyPKCS8, sizeof(kExampleRSAKeyPKCS8),
- EVP_PKEY_RSA)) {
- fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyPKCS8) failed\n");
+ if (!TestBadPSSParameters()) {
+ fprintf(stderr, "TestBadPSSParameters failed\n");
ERR_print_errors_fp(stderr);
return 1;
}
- if (!Testd2i_AutoPrivateKey(kExampleECKeyDER, sizeof(kExampleECKeyDER),
- EVP_PKEY_EC)) {
- fprintf(stderr, "d2i_AutoPrivateKey(kExampleECKeyDER) failed\n");
- ERR_print_errors_fp(stderr);
- return 1;
- }
-
- if (!Testd2i_AutoPrivateKey(kExampleDSAKeyDER, sizeof(kExampleDSAKeyDER),
- EVP_PKEY_DSA)) {
- fprintf(stderr, "d2i_AutoPrivateKey(kExampleDSAKeyDER) failed\n");
+ if (!Testd2i_AutoPrivateKey()) {
+ fprintf(stderr, "Testd2i_AutoPrivateKey failed\n");
ERR_print_errors_fp(stderr);
return 1;
}
diff --git a/src/crypto/evp/evp_test.cc b/src/crypto/evp/evp_test.cc
index c7ac908..7fedc15 100644
--- a/src/crypto/evp/evp_test.cc
+++ b/src/crypto/evp/evp_test.cc
@@ -78,7 +78,6 @@
#include "../test/file_test.h"
#include "../test/scoped_types.h"
-#include "../test/stl_compat.h"
// evp_test dispatches between multiple test types. PrivateKey tests take a key
@@ -179,8 +178,8 @@ static bool TestEVP(FileTest *t, void *arg) {
}
if (t->GetType() == "Verify") {
- if (!EVP_PKEY_verify(ctx.get(), bssl::vector_data(&output), output.size(),
- bssl::vector_data(&input), input.size())) {
+ if (!EVP_PKEY_verify(ctx.get(), output.data(), output.size(), input.data(),
+ input.size())) {
// ECDSA sometimes doesn't push an error code. Push one on the error queue
// so it's distinguishable from other errors.
OPENSSL_PUT_ERROR(USER, ERR_R_EVP_LIB);
@@ -191,18 +190,15 @@ static bool TestEVP(FileTest *t, void *arg) {
size_t len;
std::vector<uint8_t> actual;
- if (!key_op(ctx.get(), nullptr, &len, bssl::vector_data(&input),
- input.size())) {
+ if (!key_op(ctx.get(), nullptr, &len, input.data(), input.size())) {
return false;
}
actual.resize(len);
- if (!key_op(ctx.get(), bssl::vector_data(&actual), &len,
- bssl::vector_data(&input), input.size())) {
+ if (!key_op(ctx.get(), actual.data(), &len, input.data(), input.size())) {
return false;
}
actual.resize(len);
- if (!t->ExpectBytesEqual(bssl::vector_data(&output), output.size(),
- bssl::vector_data(&actual), len)) {
+ if (!t->ExpectBytesEqual(output.data(), output.size(), actual.data(), len)) {
return false;
}
return true;
diff --git a/src/crypto/evp/internal.h b/src/crypto/evp/internal.h
index 60881e3..aa52d53 100644
--- a/src/crypto/evp/internal.h
+++ b/src/crypto/evp/internal.h
@@ -263,6 +263,13 @@ struct evp_pkey_method_st {
int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
} /* EVP_PKEY_METHOD */;
+extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD ec_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meth;
+
+extern const EVP_PKEY_METHOD rsa_pkey_meth;
+extern const EVP_PKEY_METHOD ec_pkey_meth;
+
#if defined(__cplusplus)
} /* extern C */
diff --git a/src/crypto/evp/p_ec_asn1.c b/src/crypto/evp/p_ec_asn1.c
index c583e0f..f40b976 100644
--- a/src/crypto/evp/p_ec_asn1.c
+++ b/src/crypto/evp/p_ec_asn1.c
@@ -337,23 +337,12 @@ static int int_ec_size(const EVP_PKEY *pkey) {
}
static int ec_bits(const EVP_PKEY *pkey) {
- BIGNUM *order = BN_new();
- const EC_GROUP *group;
- int ret;
-
- if (!order) {
+ const EC_GROUP *group = EC_KEY_get0_group(pkey->pkey.ec);
+ if (group == NULL) {
ERR_clear_error();
return 0;
}
- group = EC_KEY_get0_group(pkey->pkey.ec);
- if (!EC_GROUP_get_order(group, order, NULL)) {
- ERR_clear_error();
- return 0;
- }
-
- ret = BN_num_bits(order);
- BN_free(order);
- return ret;
+ return BN_num_bits(EC_GROUP_get0_order(group));
}
static int ec_missing_parameters(const EVP_PKEY *pkey) {
@@ -387,7 +376,6 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
const char *ecstr;
size_t buf_len = 0, i;
int ret = 0, reason = ERR_R_BIO_LIB;
- BIGNUM *order = NULL;
BN_CTX *ctx = NULL;
const EC_GROUP *group;
const EC_POINT *public_key;
@@ -458,9 +446,8 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
if (!BIO_indent(bp, off, 128)) {
goto err;
}
- order = BN_new();
- if (order == NULL || !EC_GROUP_get_order(group, order, NULL) ||
- BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) {
+ const BIGNUM *order = EC_GROUP_get0_order(group);
+ if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) {
goto err;
}
@@ -482,7 +469,6 @@ err:
OPENSSL_PUT_ERROR(EVP, reason);
}
OPENSSL_free(pub_key_bytes);
- BN_free(order);
BN_CTX_free(ctx);
OPENSSL_free(buffer);
return ret;
diff --git a/src/crypto/evp/p_rsa.c b/src/crypto/evp/p_rsa.c
index cfecbfd..895d351 100644
--- a/src/crypto/evp/p_rsa.c
+++ b/src/crypto/evp/p_rsa.c
@@ -456,8 +456,6 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
}
OPENSSL_free(rctx->oaep_label);
if (p2 && p1 > 0) {
- /* TODO(fork): this seems wrong. Shouldn't it take a copy of the
- * buffer? */
rctx->oaep_label = p2;
rctx->oaep_labellen = p1;
} else {
diff --git a/src/crypto/evp/p_rsa_asn1.c b/src/crypto/evp/p_rsa_asn1.c
index f60625b..db38d5c 100644
--- a/src/crypto/evp/p_rsa_asn1.c
+++ b/src/crypto/evp/p_rsa_asn1.c
@@ -303,7 +303,7 @@ static X509_ALGOR *rsa_mgf1_decode(X509_ALGOR *alg) {
const uint8_t *p;
int plen;
- if (alg == NULL ||
+ if (alg == NULL || alg->parameter == NULL ||
OBJ_obj2nid(alg->algorithm) != NID_mgf1 ||
alg->parameter->type != V_ASN1_SEQUENCE) {
return NULL;
diff --git a/src/crypto/ex_data.c b/src/crypto/ex_data.c
index f562f17..8fa1240 100644
--- a/src/crypto/ex_data.c
+++ b/src/crypto/ex_data.c
@@ -124,14 +124,12 @@
struct crypto_ex_data_func_st {
long argl; /* Arbitary long */
void *argp; /* Arbitary void pointer */
- CRYPTO_EX_new *new_func;
CRYPTO_EX_free *free_func;
CRYPTO_EX_dup *dup_func;
};
int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class, int *out_index,
- long argl, void *argp, CRYPTO_EX_new *new_func,
- CRYPTO_EX_dup *dup_func,
+ long argl, void *argp, CRYPTO_EX_dup *dup_func,
CRYPTO_EX_free *free_func) {
CRYPTO_EX_DATA_FUNCS *funcs;
int ret = 0;
@@ -144,7 +142,6 @@ int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class, int *out_index,
funcs->argl = argl;
funcs->argp = argp;
- funcs->new_func = new_func;
funcs->dup_func = dup_func;
funcs->free_func = free_func;
@@ -230,46 +227,24 @@ static int get_func_pointers(STACK_OF(CRYPTO_EX_DATA_FUNCS) **out,
return 1;
}
-int CRYPTO_new_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, void *obj,
- CRYPTO_EX_DATA *ad) {
- STACK_OF(CRYPTO_EX_DATA_FUNCS) *func_pointers;
- size_t i;
-
+void CRYPTO_new_ex_data(CRYPTO_EX_DATA *ad) {
ad->sk = NULL;
-
- if (!get_func_pointers(&func_pointers, ex_data_class)) {
- return 0;
- }
-
- for (i = 0; i < sk_CRYPTO_EX_DATA_FUNCS_num(func_pointers); i++) {
- CRYPTO_EX_DATA_FUNCS *func_pointer =
- sk_CRYPTO_EX_DATA_FUNCS_value(func_pointers, i);
- if (func_pointer->new_func) {
- func_pointer->new_func(obj, NULL, ad, i + ex_data_class->num_reserved,
- func_pointer->argl, func_pointer->argp);
- }
- }
-
- sk_CRYPTO_EX_DATA_FUNCS_free(func_pointers);
-
- return 1;
}
int CRYPTO_dup_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, CRYPTO_EX_DATA *to,
const CRYPTO_EX_DATA *from) {
- STACK_OF(CRYPTO_EX_DATA_FUNCS) *func_pointers;
- size_t i;
-
- if (!from->sk) {
+ if (from->sk == NULL) {
/* In this case, |from| is blank, which is also the initial state of |to|,
* so there's nothing to do. */
return 1;
}
+ STACK_OF(CRYPTO_EX_DATA_FUNCS) *func_pointers;
if (!get_func_pointers(&func_pointers, ex_data_class)) {
return 0;
}
+ size_t i;
for (i = 0; i < sk_CRYPTO_EX_DATA_FUNCS_num(func_pointers); i++) {
CRYPTO_EX_DATA_FUNCS *func_pointer =
sk_CRYPTO_EX_DATA_FUNCS_value(func_pointers, i);
@@ -288,13 +263,18 @@ int CRYPTO_dup_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, CRYPTO_EX_DATA *to,
void CRYPTO_free_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, void *obj,
CRYPTO_EX_DATA *ad) {
- STACK_OF(CRYPTO_EX_DATA_FUNCS) *func_pointers;
- size_t i;
+ if (ad->sk == NULL) {
+ /* Nothing to do. */
+ return;
+ }
+ STACK_OF(CRYPTO_EX_DATA_FUNCS) *func_pointers;
if (!get_func_pointers(&func_pointers, ex_data_class)) {
+ /* TODO(davidben): This leaks memory on malloc error. */
return;
}
+ size_t i;
for (i = 0; i < sk_CRYPTO_EX_DATA_FUNCS_num(func_pointers); i++) {
CRYPTO_EX_DATA_FUNCS *func_pointer =
sk_CRYPTO_EX_DATA_FUNCS_value(func_pointers, i);
diff --git a/src/crypto/header_removed.h b/src/crypto/header_removed.h
deleted file mode 100644
index 49ee31a..0000000
--- a/src/crypto/header_removed.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* Copyright (c) 2014, Google Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
-
-/* This header is linked to under the names of several headers that have been
- * removed. It's possible to put a #error in here in order to catch that an
- * clean up older code. */
diff --git a/src/crypto/hmac/hmac.c b/src/crypto/hmac/hmac.c
index d37a249..be2dcce 100644
--- a/src/crypto/hmac/hmac.c
+++ b/src/crypto/hmac/hmac.c
@@ -129,7 +129,7 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len,
return 0;
}
} else {
- assert(key_len >= 0 && key_len <= sizeof(key_block));
+ assert(key_len <= sizeof(key_block));
memcpy(key_block, key, key_len);
key_block_len = (unsigned)key_len;
}
diff --git a/src/crypto/hmac/hmac_test.cc b/src/crypto/hmac/hmac_test.cc
index d438b70..da390ef 100644
--- a/src/crypto/hmac/hmac_test.cc
+++ b/src/crypto/hmac/hmac_test.cc
@@ -66,7 +66,6 @@
#include "../test/file_test.h"
#include "../test/scoped_types.h"
-#include "../test/stl_compat.h"
static const EVP_MD *GetDigest(const std::string &name) {
@@ -107,33 +106,28 @@ static bool TestHMAC(FileTest *t, void *arg) {
// Test using the one-shot API.
uint8_t mac[EVP_MAX_MD_SIZE];
unsigned mac_len;
- if (nullptr == HMAC(digest, bssl::vector_data(&key), key.size(),
- bssl::vector_data(&input), input.size(), mac,
- &mac_len) ||
- !t->ExpectBytesEqual(bssl::vector_data(&output), output.size(), mac,
- mac_len)) {
+ if (nullptr == HMAC(digest, key.data(), key.size(), input.data(),
+ input.size(), mac, &mac_len) ||
+ !t->ExpectBytesEqual(output.data(), output.size(), mac, mac_len)) {
t->PrintLine("One-shot API failed.");
return false;
}
// Test using HMAC_CTX.
ScopedHMAC_CTX ctx;
- if (!HMAC_Init_ex(ctx.get(), bssl::vector_data(&key), key.size(), digest,
- nullptr) ||
- !HMAC_Update(ctx.get(), bssl::vector_data(&input), input.size()) ||
+ if (!HMAC_Init_ex(ctx.get(), key.data(), key.size(), digest, nullptr) ||
+ !HMAC_Update(ctx.get(), input.data(), input.size()) ||
!HMAC_Final(ctx.get(), mac, &mac_len) ||
- !t->ExpectBytesEqual(bssl::vector_data(&output), output.size(), mac,
- mac_len)) {
+ !t->ExpectBytesEqual(output.data(), output.size(), mac, mac_len)) {
t->PrintLine("HMAC_CTX failed.");
return false;
}
// Test that an HMAC_CTX may be reset with the same key.
if (!HMAC_Init_ex(ctx.get(), nullptr, 0, digest, nullptr) ||
- !HMAC_Update(ctx.get(), bssl::vector_data(&input), input.size()) ||
+ !HMAC_Update(ctx.get(), input.data(), input.size()) ||
!HMAC_Final(ctx.get(), mac, &mac_len) ||
- !t->ExpectBytesEqual(bssl::vector_data(&output), output.size(), mac,
- mac_len)) {
+ !t->ExpectBytesEqual(output.data(), output.size(), mac, mac_len)) {
t->PrintLine("HMAC_CTX with reset failed.");
return false;
}
@@ -150,8 +144,7 @@ static bool TestHMAC(FileTest *t, void *arg) {
}
}
if (!HMAC_Final(ctx.get(), mac, &mac_len) ||
- !t->ExpectBytesEqual(bssl::vector_data(&output), output.size(), mac,
- mac_len)) {
+ !t->ExpectBytesEqual(output.data(), output.size(), mac, mac_len)) {
t->PrintLine("HMAC_CTX streaming failed.");
return false;
}
diff --git a/src/crypto/internal.h b/src/crypto/internal.h
index 713659d..bf45349 100644
--- a/src/crypto/internal.h
+++ b/src/crypto/internal.h
@@ -168,18 +168,6 @@ extern "C" {
#endif
-#if defined(_MSC_VER)
-#define OPENSSL_U64(x) x##UI64
-#else
-
-#if defined(OPENSSL_64_BIT)
-#define OPENSSL_U64(x) x##UL
-#else
-#define OPENSSL_U64(x) x##ULL
-#endif
-
-#endif /* defined(_MSC_VER) */
-
#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || defined(OPENSSL_ARM) || \
defined(OPENSSL_AARCH64)
/* OPENSSL_cpuid_setup initializes OPENSSL_ia32cap_P. */
@@ -509,8 +497,7 @@ typedef struct {
* zero otherwise. */
OPENSSL_EXPORT int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class,
int *out_index, long argl,
- void *argp, CRYPTO_EX_new *new_func,
- CRYPTO_EX_dup *dup_func,
+ void *argp, CRYPTO_EX_dup *dup_func,
CRYPTO_EX_free *free_func);
/* CRYPTO_set_ex_data sets an extra data pointer on a given object. Each class
@@ -522,11 +509,8 @@ OPENSSL_EXPORT int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int index, void *val);
* function. */
OPENSSL_EXPORT void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int index);
-/* CRYPTO_new_ex_data initialises a newly allocated |CRYPTO_EX_DATA| which is
- * embedded inside of |obj| which is of class |ex_data_class|. Returns one on
- * success and zero otherwise. */
-OPENSSL_EXPORT int CRYPTO_new_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class,
- void *obj, CRYPTO_EX_DATA *ad);
+/* CRYPTO_new_ex_data initialises a newly allocated |CRYPTO_EX_DATA|. */
+OPENSSL_EXPORT void CRYPTO_new_ex_data(CRYPTO_EX_DATA *ad);
/* CRYPTO_dup_ex_data duplicates |from| into a freshly allocated
* |CRYPTO_EX_DATA|, |to|. Both of which are inside objects of the given
diff --git a/src/crypto/md4/md4.c b/src/crypto/md4/md4.c
index 0a8ea1d..86a540b 100644
--- a/src/crypto/md4/md4.c
+++ b/src/crypto/md4/md4.c
@@ -84,13 +84,13 @@ void md4_block_data_order(uint32_t *state, const uint8_t *data, size_t num);
do { \
uint32_t ll; \
ll = (c)->h[0]; \
- (void) HOST_l2c(ll, (s)); \
+ HOST_l2c(ll, (s)); \
ll = (c)->h[1]; \
- (void) HOST_l2c(ll, (s)); \
+ HOST_l2c(ll, (s)); \
ll = (c)->h[2]; \
- (void) HOST_l2c(ll, (s)); \
+ HOST_l2c(ll, (s)); \
ll = (c)->h[3]; \
- (void) HOST_l2c(ll, (s)); \
+ HOST_l2c(ll, (s)); \
} while (0)
#define HASH_BLOCK_DATA_ORDER md4_block_data_order
@@ -103,6 +103,8 @@ void md4_block_data_order(uint32_t *state, const uint8_t *data, size_t num);
#define G(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
#define H(b, c, d) ((b) ^ (c) ^ (d))
+#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n))))
+
#define R0(a, b, c, d, k, s, t) \
{ \
a += ((k) + (t)+F((b), (c), (d))); \
diff --git a/src/crypto/md5/md5.c b/src/crypto/md5/md5.c
index f27e62d..66483b8 100644
--- a/src/crypto/md5/md5.c
+++ b/src/crypto/md5/md5.c
@@ -106,13 +106,13 @@ void md5_block_data_order(uint32_t *state, const uint8_t *data, size_t num);
do { \
uint32_t ll; \
ll = (c)->h[0]; \
- (void) HOST_l2c(ll, (s)); \
+ HOST_l2c(ll, (s)); \
ll = (c)->h[1]; \
- (void) HOST_l2c(ll, (s)); \
+ HOST_l2c(ll, (s)); \
ll = (c)->h[2]; \
- (void) HOST_l2c(ll, (s)); \
+ HOST_l2c(ll, (s)); \
ll = (c)->h[3]; \
- (void) HOST_l2c(ll, (s)); \
+ HOST_l2c(ll, (s)); \
} while (0)
#define HASH_BLOCK_DATA_ORDER md5_block_data_order
@@ -127,6 +127,8 @@ void md5_block_data_order(uint32_t *state, const uint8_t *data, size_t num);
#define H(b,c,d) ((b) ^ (c) ^ (d))
#define I(b,c,d) (((~(d)) | (b)) ^ (c))
+#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n))))
+
#define R0(a,b,c,d,k,s,t) { \
a+=((k)+(t)+F((b),(c),(d))); \
a=ROTATE(a,s); \
diff --git a/src/crypto/modes/asm/ghash-armv4.pl b/src/crypto/modes/asm/ghash-armv4.pl
index df33be5..d328822 100644
--- a/src/crypto/modes/asm/ghash-armv4.pl
+++ b/src/crypto/modes/asm/ghash-armv4.pl
@@ -140,7 +140,7 @@ $code=<<___;
.text
.code 32
-#ifdef __APPLE__
+#ifdef __clang__
#define ldrplb ldrbpl
#define ldrneb ldrbne
#endif
diff --git a/src/crypto/modes/gcm.c b/src/crypto/modes/gcm.c
index 8aac741..65451a6 100644
--- a/src/crypto/modes/gcm.c
+++ b/src/crypto/modes/gcm.c
@@ -55,7 +55,6 @@
#include <openssl/cpu.h>
#include "internal.h"
-#include "../internal.h"
#if !defined(OPENSSL_NO_ASM) && \
@@ -76,7 +75,7 @@
#define REDUCE1BIT(V) \
do { \
if (sizeof(size_t) == 8) { \
- uint64_t T = OPENSSL_U64(0xe100000000000000) & (0 - (V.lo & 1)); \
+ uint64_t T = UINT64_C(0xe100000000000000) & (0 - (V.lo & 1)); \
V.lo = (V.hi << 63) | (V.lo >> 1); \
V.hi = (V.hi >> 1) ^ T; \
} else { \
@@ -586,7 +585,7 @@ int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const uint8_t *aad, size_t len) {
}
alen += len;
- if (alen > (OPENSSL_U64(1) << 61) || (sizeof(len) == 8 && alen < len)) {
+ if (alen > (UINT64_C(1) << 61) || (sizeof(len) == 8 && alen < len)) {
return 0;
}
ctx->len.u[0] = alen;
@@ -653,7 +652,7 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const void *key,
#endif
mlen += len;
- if (mlen > ((OPENSSL_U64(1) << 36) - 32) ||
+ if (mlen > ((UINT64_C(1) << 36) - 32) ||
(sizeof(len) == 8 && mlen < len)) {
return 0;
}
@@ -813,7 +812,7 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const void *key,
#endif
mlen += len;
- if (mlen > ((OPENSSL_U64(1) << 36) - 32) ||
+ if (mlen > ((UINT64_C(1) << 36) - 32) ||
(sizeof(len) == 8 && mlen < len)) {
return 0;
}
@@ -978,7 +977,7 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const void *key,
#endif
mlen += len;
- if (mlen > ((OPENSSL_U64(1) << 36) - 32) ||
+ if (mlen > ((UINT64_C(1) << 36) - 32) ||
(sizeof(len) == 8 && mlen < len)) {
return 0;
}
@@ -1087,7 +1086,7 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const void *key,
#endif
mlen += len;
- if (mlen > ((OPENSSL_U64(1) << 36) - 32) ||
+ if (mlen > ((UINT64_C(1) << 36) - 32) ||
(sizeof(len) == 8 && mlen < len)) {
return 0;
}
diff --git a/src/crypto/obj/obj_dat.h b/src/crypto/obj/obj_dat.h
index 517dc49..bf44c6d 100644
--- a/src/crypto/obj/obj_dat.h
+++ b/src/crypto/obj/obj_dat.h
@@ -58,9 +58,9 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
-#define NUM_NID 948
-#define NUM_SN 940
-#define NUM_LN 940
+#define NUM_NID 949
+#define NUM_SN 941
+#define NUM_LN 941
#define NUM_OBJ 882
static const unsigned char lvalues[6176]={
@@ -2482,6 +2482,7 @@ static const ASN1_OBJECT kObjects[NUM_NID]={
NID_dhSinglePass_cofactorDH_sha512kdf_scheme,6,&(lvalues[6169]),0},
{"dh-std-kdf","dh-std-kdf",NID_dh_std_kdf,0,NULL,0},
{"dh-cofactor-kdf","dh-cofactor-kdf",NID_dh_cofactor_kdf,0,NULL,0},
+{"X25519","x25519",NID_x25519,0,NULL,0},
};
static const unsigned int kNIDsInShortNameOrder[NUM_SN]={
@@ -2668,6 +2669,7 @@ static const unsigned int kNIDsInShortNameOrder[NUM_SN]={
143, /* "SXNetID" */
458, /* "UID" */
0, /* "UNDEF" */
+948, /* "X25519" */
11, /* "X500" */
378, /* "X500algorithms" */
12, /* "X509" */
@@ -4364,6 +4366,7 @@ static const unsigned int kNIDsInLongNameOrder[NUM_LN]={
742, /* "wap-wsg-idm-ecid-wtls9" */
804, /* "whirlpool" */
868, /* "x121Address" */
+948, /* "x25519" */
503, /* "x500UniqueIdentifier" */
158, /* "x509Certificate" */
160, /* "x509Crl" */
diff --git a/src/crypto/obj/obj_mac.num b/src/crypto/obj/obj_mac.num
index e143ece..a0e09b8 100644
--- a/src/crypto/obj/obj_mac.num
+++ b/src/crypto/obj/obj_mac.num
@@ -945,3 +945,4 @@ dhSinglePass_cofactorDH_sha384kdf_scheme 944
dhSinglePass_cofactorDH_sha512kdf_scheme 945
dh_std_kdf 946
dh_cofactor_kdf 947
+x25519 948
diff --git a/src/crypto/obj/objects.txt b/src/crypto/obj/objects.txt
index 2757c4f..93cf53a 100644
--- a/src/crypto/obj/objects.txt
+++ b/src/crypto/obj/objects.txt
@@ -1330,3 +1330,6 @@ secg-scheme 14 3 : dhSinglePass-cofactorDH-sha512kdf-scheme
# NIDs for use with lookup tables.
: dh-std-kdf
: dh-cofactor-kdf
+
+# NID for X25519 (no corresponding OID).
+ : X25519 : x25519
diff --git a/src/crypto/pem/pem_all.c b/src/crypto/pem/pem_all.c
index 24ecc62..c9f8b6e 100644
--- a/src/crypto/pem/pem_all.c
+++ b/src/crypto/pem/pem_all.c
@@ -247,12 +247,6 @@ EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb,
return pkey_get_eckey(pktmp, key); /* will free pktmp */
}
-/* TODO(fork): remove this code? */
-/* IMPLEMENT_PEM_rw_const(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS, ECPKParameters) */
-
-
-
-
IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, ECPrivateKey)
@@ -274,8 +268,4 @@ EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb,
IMPLEMENT_PEM_write_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams)
-/* TODO(fork): remove this code? */
-/* IMPLEMENT_PEM_write_const(DHxparams, DH, PEM_STRING_DHXPARAMS, DHxparams) */
-
-
IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY)
diff --git a/src/crypto/pem/pem_lib.c b/src/crypto/pem/pem_lib.c
index 5915696..12d9674 100644
--- a/src/crypto/pem/pem_lib.c
+++ b/src/crypto/pem/pem_lib.c
@@ -188,10 +188,6 @@ static int check_pem(const char *nm, const char *name)
}
return 0;
}
- /* If reading DH parameters handle X9.42 DH format too */
- if(!strcmp(nm,PEM_STRING_DHXPARAMS) &&
- !strcmp(name,PEM_STRING_DHPARAMS)) return 1;
-
/* Permit older strings */
if(!strcmp(nm,PEM_STRING_X509_OLD) &&
diff --git a/src/crypto/pem/pem_pkey.c b/src/crypto/pem/pem_pkey.c
index c462727..cd334b4 100644
--- a/src/crypto/pem/pem_pkey.c
+++ b/src/crypto/pem/pem_pkey.c
@@ -280,11 +280,7 @@ DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u)
return NULL;
p = data;
- /* TODO(fork): remove? */
- /*if (!strcmp(nm, PEM_STRING_DHXPARAMS))
- ret = d2i_DHxparams(x, &p, len);
- else */
- ret = d2i_DHparams(x, &p, len);
+ ret = d2i_DHparams(x, &p, len);
if (ret == NULL)
OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
diff --git a/src/crypto/pkcs8/pkcs8.c b/src/crypto/pkcs8/pkcs8.c
index c097881..31a34a7 100644
--- a/src/crypto/pkcs8/pkcs8.c
+++ b/src/crypto/pkcs8/pkcs8.c
@@ -773,13 +773,14 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth,
goto err;
}
- if (OBJ_cbs2nid(&contents_type) != NID_pkcs7_data) {
+ if (OBJ_cbs2nid(&contents_type) != NID_pkcs7_data ||
+ CBS_len(&ai) > LONG_MAX) {
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
inp = CBS_data(&ai);
- algor = d2i_X509_ALGOR(NULL, &inp, CBS_len(&ai));
+ algor = d2i_X509_ALGOR(NULL, &inp, (long)CBS_len(&ai));
if (algor == NULL) {
goto err;
}
@@ -822,9 +823,14 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth,
goto err;
}
+ if (CBS_len(&wrapped_contents) > LONG_MAX) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
+ goto err;
+ }
+
/* encrypted isn't actually an X.509 signature, but it has the same
* structure as one and so |X509_SIG| is reused to store it. */
- encrypted = d2i_X509_SIG(NULL, &inp, CBS_len(&wrapped_contents));
+ encrypted = d2i_X509_SIG(NULL, &inp, (long)CBS_len(&wrapped_contents));
if (encrypted == NULL) {
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
@@ -861,8 +867,12 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth,
}
if (OBJ_cbs2nid(&cert_type) == NID_x509Certificate) {
+ if (CBS_len(&cert) > LONG_MAX) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
+ goto err;
+ }
const uint8_t *inp = CBS_data(&cert);
- X509 *x509 = d2i_X509(NULL, &inp, CBS_len(&cert));
+ X509 *x509 = d2i_X509(NULL, &inp, (long)CBS_len(&cert));
if (!x509) {
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
diff --git a/src/crypto/poly1305/poly1305_test.cc b/src/crypto/poly1305/poly1305_test.cc
index 0526075..3a72668 100644
--- a/src/crypto/poly1305/poly1305_test.cc
+++ b/src/crypto/poly1305/poly1305_test.cc
@@ -21,7 +21,6 @@
#include <openssl/poly1305.h>
#include "../test/file_test.h"
-#include "../test/stl_compat.h"
// |CRYPTO_poly1305_finish| requires a 16-byte-aligned output.
@@ -46,22 +45,22 @@ static bool TestPoly1305(FileTest *t, void *arg) {
// Test single-shot operation.
poly1305_state state;
- CRYPTO_poly1305_init(&state, bssl::vector_data(&key));
- CRYPTO_poly1305_update(&state, bssl::vector_data(&in), in.size());
+ CRYPTO_poly1305_init(&state, key.data());
+ CRYPTO_poly1305_update(&state, in.data(), in.size());
ALIGNED uint8_t out[16];
CRYPTO_poly1305_finish(&state, out);
- if (!t->ExpectBytesEqual(out, 16, bssl::vector_data(&mac), mac.size())) {
+ if (!t->ExpectBytesEqual(out, 16, mac.data(), mac.size())) {
t->PrintLine("Single-shot Poly1305 failed.");
return false;
}
// Test streaming byte-by-byte.
- CRYPTO_poly1305_init(&state, bssl::vector_data(&key));
+ CRYPTO_poly1305_init(&state, key.data());
for (size_t i = 0; i < in.size(); i++) {
CRYPTO_poly1305_update(&state, &in[i], 1);
}
CRYPTO_poly1305_finish(&state, out);
- if (!t->ExpectBytesEqual(out, 16, bssl::vector_data(&mac), mac.size())) {
+ if (!t->ExpectBytesEqual(out, 16, mac.data(), mac.size())) {
t->PrintLine("Streaming Poly1305 failed.");
return false;
}
diff --git a/src/crypto/rand/rand.c b/src/crypto/rand/rand.c
index 8b11728..892b4ba 100644
--- a/src/crypto/rand/rand.c
+++ b/src/crypto/rand/rand.c
@@ -192,7 +192,12 @@ int RAND_pseudo_bytes(uint8_t *buf, size_t len) {
return RAND_bytes(buf, len);
}
-void RAND_seed(const void *buf, int num) {}
+void RAND_seed(const void *buf, int num) {
+ /* OpenSSH calls |RAND_seed| before jailing on the assumption that any needed
+ * file descriptors etc will be opened. */
+ uint8_t unused;
+ RAND_bytes(&unused, sizeof(unused));
+}
int RAND_load_file(const char *path, long num) {
if (num < 0) { /* read the "whole file" */
diff --git a/src/crypto/rand/urandom.c b/src/crypto/rand/urandom.c
index 1cc5260..5bf5c73 100644
--- a/src/crypto/rand/urandom.c
+++ b/src/crypto/rand/urandom.c
@@ -83,11 +83,15 @@ static void init_once(void) {
int flags = fcntl(fd, F_GETFD);
if (flags == -1) {
- abort();
- }
- flags |= FD_CLOEXEC;
- if (fcntl(fd, F_SETFD, flags) == -1) {
- abort();
+ /* Native Client doesn't implement |fcntl|. */
+ if (errno != ENOSYS) {
+ abort();
+ }
+ } else {
+ flags |= FD_CLOEXEC;
+ if (fcntl(fd, F_SETFD, flags) == -1) {
+ abort();
+ }
}
urandom_fd = fd;
}
diff --git a/src/crypto/rc4/CMakeLists.txt b/src/crypto/rc4/CMakeLists.txt
index a208e96..151773a 100644
--- a/src/crypto/rc4/CMakeLists.txt
+++ b/src/crypto/rc4/CMakeLists.txt
@@ -5,7 +5,6 @@ if (${ARCH} STREQUAL "x86_64")
RC4_ARCH_SOURCES
rc4-x86_64.${ASM_EXT}
- rc4-md5-x86_64.${ASM_EXT}
)
endif()
@@ -27,5 +26,4 @@ add_library(
)
perlasm(rc4-x86_64.${ASM_EXT} asm/rc4-x86_64.pl)
-perlasm(rc4-md5-x86_64.${ASM_EXT} asm/rc4-md5-x86_64.pl)
perlasm(rc4-586.${ASM_EXT} asm/rc4-586.pl)
diff --git a/src/crypto/rc4/asm/rc4-md5-x86_64.pl b/src/crypto/rc4/asm/rc4-md5-x86_64.pl
deleted file mode 100644
index 272fa91..0000000
--- a/src/crypto/rc4/asm/rc4-md5-x86_64.pl
+++ /dev/null
@@ -1,632 +0,0 @@
-#!/usr/bin/env perl
-#
-# ====================================================================
-# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
-# project. The module is, however, dual licensed under OpenSSL and
-# CRYPTOGAMS licenses depending on where you obtain it. For further
-# details see http://www.openssl.org/~appro/cryptogams/.
-# ====================================================================
-
-# June 2011
-#
-# This is RC4+MD5 "stitch" implementation. The idea, as spelled in
-# http://download.intel.com/design/intarch/papers/323686.pdf, is that
-# since both algorithms exhibit instruction-level parallelism, ILP,
-# below theoretical maximum, interleaving them would allow to utilize
-# processor resources better and achieve better performance. RC4
-# instruction sequence is virtually identical to rc4-x86_64.pl, which
-# is heavily based on submission by Maxim Perminov, Maxim Locktyukhin
-# and Jim Guilford of Intel. MD5 is fresh implementation aiming to
-# 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
-# cycles per processed byte, less is better, for these the standalone
-# subroutines, sum of them, and stitched one:
-#
-# RC4 MD5 RC4+MD5 stitch gain
-# Opteron 6.5(*) 5.4 11.9 7.0 +70%(*)
-# Core2 6.5 5.8 12.3 7.7 +60%
-# Westmere 4.3 5.2 9.5 7.0 +36%
-# Sandy Bridge 4.2 5.5 9.7 6.8 +43%
-# Atom 9.3 6.5 15.8 11.1 +42%
-#
-# (*) rc4-x86_64.pl delivers 5.3 on Opteron, so real improvement
-# is +53%...
-
-my ($rc4,$md5)=(1,1); # what to generate?
-my $D="#" if (!$md5); # if set to "#", MD5 is stitched into RC4(),
- # but its result is discarded. Idea here is
- # 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; }
-
-my $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-
-$0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
-( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-die "can't locate x86_64-xlate.pl";
-
-open OUT,"| \"$^X\" $xlate $flavour $output";
-*STDOUT=*OUT;
-
-my ($dat,$in0,$out,$ctx,$inp,$len, $func,$nargs);
-
-if ($rc4 && !$md5) {
- ($dat,$len,$in0,$out) = ("%rdi","%rsi","%rdx","%rcx");
- $func="RC4"; $nargs=4;
-} elsif ($md5 && !$rc4) {
- ($ctx,$inp,$len) = ("%rdi","%rsi","%rdx");
- $func="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;
- # void rc4_md5_enc(
- # RC4_KEY *key, #
- # const void *in0, # RC4 input
- # void *out, # RC4 output
- # MD5_CTX *ctx, #
- # const void *inp, # MD5 input
- # size_t len); # number of 64-byte blocks
-}
-
-my @K=( 0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,
- 0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,
- 0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be,
- 0x6b901122,0xfd987193,0xa679438e,0x49b40821,
-
- 0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa,
- 0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,
- 0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,
- 0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a,
-
- 0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c,
- 0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70,
- 0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,
- 0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,
-
- 0xf4292244,0x432aff97,0xab9423a7,0xfc93a039,
- 0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1,
- 0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1,
- 0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391 );
-
-my @V=("%r8d","%r9d","%r10d","%r11d"); # MD5 registers
-my $tmp="%r12d";
-
-my @XX=("%rbp","%rsi"); # RC4 registers
-my @TX=("%rax","%rbx");
-my $YY="%rcx";
-my $TY="%rdx";
-
-my $MOD=32; # 16, 32 or 64
-
-$code.=<<___;
-.text
-.align 16
-
-.globl $func
-.type $func,\@function,$nargs
-$func:
- cmp \$0,$len
- je .Labort
- push %rbx
- push %rbp
- push %r12
- push %r13
- push %r14
- push %r15
- sub \$40,%rsp
-.Lbody:
-___
-if ($rc4) {
-$code.=<<___;
-$D#md5# mov $ctx,%r11 # reassign arguments
- mov $len,%r12
- mov $in0,%r13
- mov $out,%r14
-$D#md5# mov $inp,%r15
-___
- $ctx="%r11" if ($md5); # reassign arguments
- $len="%r12";
- $in0="%r13";
- $out="%r14";
- $inp="%r15" if ($md5);
- $inp=$in0 if (!$md5);
-$code.=<<___;
- xor $XX[0],$XX[0]
- xor $YY,$YY
-
- lea 8($dat),$dat
- mov -8($dat),$XX[0]#b
- mov -4($dat),$YY#b
-
- inc $XX[0]#b
- sub $in0,$out
- movl ($dat,$XX[0],4),$TX[0]#d
-___
-$code.=<<___ if (!$md5);
- xor $TX[1],$TX[1]
- test \$-128,$len
- jz .Loop1
- sub $XX[0],$TX[1]
- and \$`$MOD-1`,$TX[1]
- jz .Loop${MOD}_is_hot
- sub $TX[1],$len
-.Loop${MOD}_warmup:
- add $TX[0]#b,$YY#b
- movl ($dat,$YY,4),$TY#d
- movl $TX[0]#d,($dat,$YY,4)
- movl $TY#d,($dat,$XX[0],4)
- add $TY#b,$TX[0]#b
- inc $XX[0]#b
- movl ($dat,$TX[0],4),$TY#d
- movl ($dat,$XX[0],4),$TX[0]#d
- xorb ($in0),$TY#b
- movb $TY#b,($out,$in0)
- lea 1($in0),$in0
- dec $TX[1]
- jnz .Loop${MOD}_warmup
-
- mov $YY,$TX[1]
- xor $YY,$YY
- mov $TX[1]#b,$YY#b
-
-.Loop${MOD}_is_hot:
- mov $len,32(%rsp) # save original $len
- shr \$6,$len # number of 64-byte blocks
-___
- if ($D && !$md5) { # stitch in dummy MD5
- $md5=1;
- $ctx="%r11";
- $inp="%r15";
- $code.=<<___;
- mov %rsp,$ctx
- mov $in0,$inp
-___
- }
-}
-$code.=<<___;
-#rc4# add $TX[0]#b,$YY#b
-#rc4# lea ($dat,$XX[0],4),$XX[1]
- shl \$6,$len
- add $inp,$len # pointer to the end of input
- mov $len,16(%rsp)
-
-#md5# mov $ctx,24(%rsp) # save pointer to MD5_CTX
-#md5# mov 0*4($ctx),$V[0] # load current hash value from MD5_CTX
-#md5# mov 1*4($ctx),$V[1]
-#md5# mov 2*4($ctx),$V[2]
-#md5# mov 3*4($ctx),$V[3]
- jmp .Loop
-
-.align 16
-.Loop:
-#md5# mov $V[0],0*4(%rsp) # put aside current hash value
-#md5# mov $V[1],1*4(%rsp)
-#md5# mov $V[2],2*4(%rsp)
-#md5# mov $V[3],$tmp # forward reference
-#md5# mov $V[3],3*4(%rsp)
-___
-
-sub R0 {
- my ($i,$a,$b,$c,$d)=@_;
- my @rot0=(7,12,17,22);
- my $j=$i%16;
- my $k=$i%$MOD;
- my $xmm="%xmm".($j&1);
- $code.=" movdqu ($in0),%xmm2\n" if ($rc4 && $j==15);
- $code.=" add \$$MOD,$XX[0]#b\n" if ($rc4 && $j==15 && $k==$MOD-1);
- $code.=" pxor $xmm,$xmm\n" if ($rc4 && $j<=1);
- $code.=<<___;
-#rc4# movl ($dat,$YY,4),$TY#d
-#md5# xor $c,$tmp
-#rc4# movl $TX[0]#d,($dat,$YY,4)
-#md5# and $b,$tmp
-#md5# add 4*`$j`($inp),$a
-#rc4# add $TY#b,$TX[0]#b
-#rc4# movl `4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d
-#md5# add \$$K[$i],$a
-#md5# xor $d,$tmp
-#rc4# movz $TX[0]#b,$TX[0]#d
-#rc4# movl $TY#d,4*$k($XX[1])
-#md5# add $tmp,$a
-#rc4# add $TX[1]#b,$YY#b
-#md5# rol \$$rot0[$j%4],$a
-#md5# mov `$j==15?"$b":"$c"`,$tmp # forward reference
-#rc4# pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n
-#md5# add $b,$a
-___
- $code.=<<___ if ($rc4 && $j==15 && $k==$MOD-1);
- mov $YY,$XX[1]
- xor $YY,$YY # keyword to partial register
- mov $XX[1]#b,$YY#b
- lea ($dat,$XX[0],4),$XX[1]
-___
- $code.=<<___ if ($rc4 && $j==15);
- psllq \$8,%xmm1
- pxor %xmm0,%xmm2
- pxor %xmm1,%xmm2
-___
-}
-sub R1 {
- my ($i,$a,$b,$c,$d)=@_;
- my @rot1=(5,9,14,20);
- my $j=$i%16;
- my $k=$i%$MOD;
- my $xmm="%xmm".($j&1);
- $code.=" movdqu 16($in0),%xmm3\n" if ($rc4 && $j==15);
- $code.=" add \$$MOD,$XX[0]#b\n" if ($rc4 && $j==15 && $k==$MOD-1);
- $code.=" pxor $xmm,$xmm\n" if ($rc4 && $j<=1);
- $code.=<<___;
-#rc4# movl ($dat,$YY,4),$TY#d
-#md5# xor $b,$tmp
-#rc4# movl $TX[0]#d,($dat,$YY,4)
-#md5# and $d,$tmp
-#md5# add 4*`((1+5*$j)%16)`($inp),$a
-#rc4# add $TY#b,$TX[0]#b
-#rc4# movl `4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d
-#md5# add \$$K[$i],$a
-#md5# xor $c,$tmp
-#rc4# movz $TX[0]#b,$TX[0]#d
-#rc4# movl $TY#d,4*$k($XX[1])
-#md5# add $tmp,$a
-#rc4# add $TX[1]#b,$YY#b
-#md5# rol \$$rot1[$j%4],$a
-#md5# mov `$j==15?"$c":"$b"`,$tmp # forward reference
-#rc4# pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n
-#md5# add $b,$a
-___
- $code.=<<___ if ($rc4 && $j==15 && $k==$MOD-1);
- mov $YY,$XX[1]
- xor $YY,$YY # keyword to partial register
- mov $XX[1]#b,$YY#b
- lea ($dat,$XX[0],4),$XX[1]
-___
- $code.=<<___ if ($rc4 && $j==15);
- psllq \$8,%xmm1
- pxor %xmm0,%xmm3
- pxor %xmm1,%xmm3
-___
-}
-sub R2 {
- my ($i,$a,$b,$c,$d)=@_;
- my @rot2=(4,11,16,23);
- my $j=$i%16;
- my $k=$i%$MOD;
- my $xmm="%xmm".($j&1);
- $code.=" movdqu 32($in0),%xmm4\n" if ($rc4 && $j==15);
- $code.=" add \$$MOD,$XX[0]#b\n" if ($rc4 && $j==15 && $k==$MOD-1);
- $code.=" pxor $xmm,$xmm\n" if ($rc4 && $j<=1);
- $code.=<<___;
-#rc4# movl ($dat,$YY,4),$TY#d
-#md5# xor $c,$tmp
-#rc4# movl $TX[0]#d,($dat,$YY,4)
-#md5# xor $b,$tmp
-#md5# add 4*`((5+3*$j)%16)`($inp),$a
-#rc4# add $TY#b,$TX[0]#b
-#rc4# movl `4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d
-#md5# add \$$K[$i],$a
-#rc4# movz $TX[0]#b,$TX[0]#d
-#md5# add $tmp,$a
-#rc4# movl $TY#d,4*$k($XX[1])
-#rc4# add $TX[1]#b,$YY#b
-#md5# rol \$$rot2[$j%4],$a
-#md5# mov `$j==15?"\\\$-1":"$c"`,$tmp # forward reference
-#rc4# pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n
-#md5# add $b,$a
-___
- $code.=<<___ if ($rc4 && $j==15 && $k==$MOD-1);
- mov $YY,$XX[1]
- xor $YY,$YY # keyword to partial register
- mov $XX[1]#b,$YY#b
- lea ($dat,$XX[0],4),$XX[1]
-___
- $code.=<<___ if ($rc4 && $j==15);
- psllq \$8,%xmm1
- pxor %xmm0,%xmm4
- pxor %xmm1,%xmm4
-___
-}
-sub R3 {
- my ($i,$a,$b,$c,$d)=@_;
- my @rot3=(6,10,15,21);
- my $j=$i%16;
- my $k=$i%$MOD;
- my $xmm="%xmm".($j&1);
- $code.=" movdqu 48($in0),%xmm5\n" if ($rc4 && $j==15);
- $code.=" add \$$MOD,$XX[0]#b\n" if ($rc4 && $j==15 && $k==$MOD-1);
- $code.=" pxor $xmm,$xmm\n" if ($rc4 && $j<=1);
- $code.=<<___;
-#rc4# movl ($dat,$YY,4),$TY#d
-#md5# xor $d,$tmp
-#rc4# movl $TX[0]#d,($dat,$YY,4)
-#md5# or $b,$tmp
-#md5# add 4*`((7*$j)%16)`($inp),$a
-#rc4# add $TY#b,$TX[0]#b
-#rc4# movl `4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d
-#md5# add \$$K[$i],$a
-#rc4# movz $TX[0]#b,$TX[0]#d
-#md5# xor $c,$tmp
-#rc4# movl $TY#d,4*$k($XX[1])
-#md5# add $tmp,$a
-#rc4# add $TX[1]#b,$YY#b
-#md5# rol \$$rot3[$j%4],$a
-#md5# mov \$-1,$tmp # forward reference
-#rc4# pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n
-#md5# add $b,$a
-___
- $code.=<<___ if ($rc4 && $j==15);
- mov $XX[0],$XX[1]
- xor $XX[0],$XX[0] # keyword to partial register
- mov $XX[1]#b,$XX[0]#b
- mov $YY,$XX[1]
- xor $YY,$YY # keyword to partial register
- mov $XX[1]#b,$YY#b
- lea ($dat,$XX[0],4),$XX[1]
- psllq \$8,%xmm1
- pxor %xmm0,%xmm5
- pxor %xmm1,%xmm5
-___
-}
-
-my $i=0;
-for(;$i<16;$i++) { R0($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); }
-for(;$i<32;$i++) { R1($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); }
-for(;$i<48;$i++) { R2($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); }
-for(;$i<64;$i++) { R3($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); }
-
-$code.=<<___;
-#md5# add 0*4(%rsp),$V[0] # accumulate hash value
-#md5# add 1*4(%rsp),$V[1]
-#md5# add 2*4(%rsp),$V[2]
-#md5# add 3*4(%rsp),$V[3]
-
-#rc4# movdqu %xmm2,($out,$in0) # write RC4 output
-#rc4# movdqu %xmm3,16($out,$in0)
-#rc4# movdqu %xmm4,32($out,$in0)
-#rc4# movdqu %xmm5,48($out,$in0)
-#md5# lea 64($inp),$inp
-#rc4# lea 64($in0),$in0
- cmp 16(%rsp),$inp # are we done?
- jb .Loop
-
-#md5# mov 24(%rsp),$len # restore pointer to MD5_CTX
-#rc4# sub $TX[0]#b,$YY#b # correct $YY
-#md5# mov $V[0],0*4($len) # write MD5_CTX
-#md5# mov $V[1],1*4($len)
-#md5# mov $V[2],2*4($len)
-#md5# mov $V[3],3*4($len)
-___
-$code.=<<___ if ($rc4 && (!$md5 || $D));
- mov 32(%rsp),$len # restore original $len
- and \$63,$len # remaining bytes
- jnz .Loop1
- jmp .Ldone
-
-.align 16
-.Loop1:
- add $TX[0]#b,$YY#b
- movl ($dat,$YY,4),$TY#d
- movl $TX[0]#d,($dat,$YY,4)
- movl $TY#d,($dat,$XX[0],4)
- add $TY#b,$TX[0]#b
- inc $XX[0]#b
- movl ($dat,$TX[0],4),$TY#d
- movl ($dat,$XX[0],4),$TX[0]#d
- xorb ($in0),$TY#b
- movb $TY#b,($out,$in0)
- lea 1($in0),$in0
- dec $len
- jnz .Loop1
-
-.Ldone:
-___
-$code.=<<___;
-#rc4# sub \$1,$XX[0]#b
-#rc4# movl $XX[0]#d,-8($dat)
-#rc4# movl $YY#d,-4($dat)
-
- mov 40(%rsp),%r15
- mov 48(%rsp),%r14
- mov 56(%rsp),%r13
- mov 64(%rsp),%r12
- mov 72(%rsp),%rbp
- mov 80(%rsp),%rbx
- lea 88(%rsp),%rsp
-.Lepilogue:
-.Labort:
- ret
-.size $func,.-$func
-___
-
-if ($rc4 && $D) { # sole purpose of this section is to provide
- # option to use the generated module as drop-in
- # replacement for rc4-x86_64.pl for debugging
- # and testing purposes...
-my ($idx,$ido)=("%r8","%r9");
-my ($dat,$len,$inp)=("%rdi","%rsi","%rdx");
-
-$code.=<<___;
-.globl RC4_set_key
-.type RC4_set_key,\@function,3
-.align 16
-RC4_set_key:
- lea 8($dat),$dat
- lea ($inp,$len),$inp
- neg $len
- mov $len,%rcx
- xor %eax,%eax
- xor $ido,$ido
- xor %r10,%r10
- xor %r11,%r11
- jmp .Lw1stloop
-
-.align 16
-.Lw1stloop:
- mov %eax,($dat,%rax,4)
- add \$1,%al
- jnc .Lw1stloop
-
- xor $ido,$ido
- xor $idx,$idx
-.align 16
-.Lw2ndloop:
- mov ($dat,$ido,4),%r10d
- add ($inp,$len,1),$idx#b
- add %r10b,$idx#b
- add \$1,$len
- mov ($dat,$idx,4),%r11d
- cmovz %rcx,$len
- mov %r10d,($dat,$idx,4)
- mov %r11d,($dat,$ido,4)
- add \$1,$ido#b
- jnc .Lw2ndloop
-
- xor %eax,%eax
- mov %eax,-8($dat)
- mov %eax,-4($dat)
- ret
-.size RC4_set_key,.-RC4_set_key
-
-.globl RC4_options
-.type RC4_options,\@abi-omnipotent
-.align 16
-RC4_options:
- lea .Lopts(%rip),%rax
- ret
-.align 64
-.Lopts:
-.asciz "rc4(64x,int)"
-.align 64
-.size RC4_options,.-RC4_options
-___
-}
-# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-# CONTEXT *context,DISPATCHER_CONTEXT *disp)
-if ($win64) {
-my $rec="%rcx";
-my $frame="%rdx";
-my $context="%r8";
-my $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
-
- lea .Lbody(%rip),%r10
- cmp %r10,%rbx # context->Rip<.Lbody
- jb .Lin_prologue
-
- mov 152($context),%rax # pull context->Rsp
-
- lea .Lepilogue(%rip),%r10
- cmp %r10,%rbx # context->Rip>=.Lepilogue
- jae .Lin_prologue
-
- mov 40(%rax),%r15
- mov 48(%rax),%r14
- mov 56(%rax),%r13
- mov 64(%rax),%r12
- mov 72(%rax),%rbp
- mov 80(%rax),%rbx
- lea 88(%rax),%rax
-
- 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->R12
- mov %r14,232($context) # restore context->R14
- mov %r15,240($context) # restore context->R15
-
-.Lin_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
-
- 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 se_handler,.-se_handler
-
-.section .pdata
-.align 4
- .rva .LSEH_begin_$func
- .rva .LSEH_end_$func
- .rva .LSEH_info_$func
-
-.section .xdata
-.align 8
-.LSEH_info_$func:
- .byte 9,0,0,0
- .rva se_handler
-___
-}
-
-sub reg_part {
-my ($reg,$conv)=@_;
- if ($reg =~ /%r[0-9]+/) { $reg .= $conv; }
- elsif ($conv eq "b") { $reg =~ s/%[er]([^x]+)x?/%$1l/; }
- elsif ($conv eq "w") { $reg =~ s/%[er](.+)/%$1/; }
- elsif ($conv eq "d") { $reg =~ s/%[er](.+)/%e$1/; }
- return $reg;
-}
-
-$code =~ s/(%[a-z0-9]+)#([bwd])/reg_part($1,$2)/gem;
-$code =~ s/\`([^\`]*)\`/eval $1/gem;
-$code =~ s/pinsrw\s+\$0,/movd /gm;
-
-$code =~ s/#md5#//gm if ($md5);
-$code =~ s/#rc4#//gm if ($rc4);
-
-print $code;
-
-close STDOUT;
diff --git a/src/crypto/rsa/padding.c b/src/crypto/rsa/padding.c
index 5a42e24..032df2e 100644
--- a/src/crypto/rsa/padding.c
+++ b/src/crypto/rsa/padding.c
@@ -56,6 +56,7 @@
#include <openssl/rsa.h>
#include <assert.h>
+#include <limits.h>
#include <string.h>
#include <openssl/digest.h>
@@ -65,20 +66,21 @@
#include <openssl/sha.h>
#include "internal.h"
+#include "../internal.h"
/* TODO(fork): don't the check functions have to be constant time? */
-int RSA_padding_add_PKCS1_type_1(uint8_t *to, unsigned tlen,
- const uint8_t *from, unsigned flen) {
+int RSA_padding_add_PKCS1_type_1(uint8_t *to, unsigned to_len,
+ const uint8_t *from, unsigned from_len) {
unsigned j;
uint8_t *p;
- if (tlen < RSA_PKCS1_PADDING_SIZE) {
+ if (to_len < RSA_PKCS1_PADDING_SIZE) {
OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
return 0;
}
- if (flen > tlen - RSA_PKCS1_PADDING_SIZE) {
+ if (from_len > to_len - RSA_PKCS1_PADDING_SIZE) {
OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
return 0;
}
@@ -89,20 +91,20 @@ int RSA_padding_add_PKCS1_type_1(uint8_t *to, unsigned tlen,
*(p++) = 1; /* Private Key BT (Block Type) */
/* pad out with 0xff data */
- j = tlen - 3 - flen;
+ j = to_len - 3 - from_len;
memset(p, 0xff, j);
p += j;
*(p++) = 0;
- memcpy(p, from, (unsigned int)flen);
+ memcpy(p, from, (unsigned int)from_len);
return 1;
}
-int RSA_padding_check_PKCS1_type_1(uint8_t *to, unsigned tlen,
- const uint8_t *from, unsigned flen) {
+int RSA_padding_check_PKCS1_type_1(uint8_t *to, unsigned to_len,
+ const uint8_t *from, unsigned from_len) {
unsigned i, j;
const uint8_t *p;
- if (flen < 2) {
+ if (from_len < 2) {
OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_SMALL);
return -1;
}
@@ -114,7 +116,7 @@ int RSA_padding_check_PKCS1_type_1(uint8_t *to, unsigned tlen,
}
/* scan over padding data */
- j = flen - 2; /* one for leading 00, one for type. */
+ j = from_len - 2; /* one for leading 00, one for type. */
for (i = 0; i < j; i++) {
/* should decrypt to 0xff */
if (*p != 0xff) {
@@ -140,7 +142,7 @@ int RSA_padding_check_PKCS1_type_1(uint8_t *to, unsigned tlen,
}
i++; /* Skip over the '\0' */
j -= i;
- if (j > tlen) {
+ if (j > to_len) {
OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE);
return -1;
}
@@ -149,17 +151,17 @@ int RSA_padding_check_PKCS1_type_1(uint8_t *to, unsigned tlen,
return j;
}
-int RSA_padding_add_PKCS1_type_2(uint8_t *to, unsigned tlen,
- const uint8_t *from, unsigned flen) {
+int RSA_padding_add_PKCS1_type_2(uint8_t *to, unsigned to_len,
+ const uint8_t *from, unsigned from_len) {
unsigned i, j;
uint8_t *p;
- if (tlen < RSA_PKCS1_PADDING_SIZE) {
+ if (to_len < RSA_PKCS1_PADDING_SIZE) {
OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
return 0;
}
- if (flen > tlen - RSA_PKCS1_PADDING_SIZE) {
+ if (from_len > to_len - RSA_PKCS1_PADDING_SIZE) {
OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
return 0;
}
@@ -170,7 +172,7 @@ int RSA_padding_add_PKCS1_type_2(uint8_t *to, unsigned tlen,
*(p++) = 2; /* Public Key BT (Block Type) */
/* pad out with non-zero random data */
- j = tlen - 3 - flen;
+ j = to_len - 3 - from_len;
if (!RAND_bytes(p, j)) {
return 0;
@@ -187,116 +189,89 @@ int RSA_padding_add_PKCS1_type_2(uint8_t *to, unsigned tlen,
*(p++) = 0;
- memcpy(p, from, (unsigned int)flen);
+ memcpy(p, from, (unsigned int)from_len);
return 1;
}
-/* constant_time_byte_eq returns 1 if |x| == |y| and 0 otherwise. */
-static int constant_time_byte_eq(unsigned char a, unsigned char b) {
- unsigned char z = ~(a ^ b);
- z &= z >> 4;
- z &= z >> 2;
- z &= z >> 1;
-
- return z;
-}
-
-/* constant_time_select returns |x| if |v| is 1 and |y| if |v| is 0.
- * Its behavior is undefined if |v| takes any other value. */
-static int constant_time_select(int v, int x, int y) {
- return ((~(v - 1)) & x) | ((v - 1) & y);
-}
-
-/* constant_time_le returns 1 if |x| <= |y| and 0 otherwise.
- * |x| and |y| must be positive. */
-static int constant_time_le(int x, int y) {
- return ((x - y - 1) >> (sizeof(int) * 8 - 1)) & 1;
-}
-
-int RSA_message_index_PKCS1_type_2(const uint8_t *from, size_t from_len,
- size_t *out_index) {
- size_t i;
- int first_byte_is_zero, second_byte_is_two, looking_for_index;
- int valid_index, zero_index = 0;
+int RSA_padding_check_PKCS1_type_2(uint8_t *to, unsigned to_len,
+ const uint8_t *from, unsigned from_len) {
+ if (from_len == 0) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY);
+ return -1;
+ }
/* PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography
* Standard", section 7.2.2. */
if (from_len < RSA_PKCS1_PADDING_SIZE) {
/* |from| is zero-padded to the size of the RSA modulus, a public value, so
* this can be rejected in non-constant time. */
- *out_index = 0;
- return 0;
+ OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
+ return -1;
}
- first_byte_is_zero = constant_time_byte_eq(from[0], 0);
- second_byte_is_two = constant_time_byte_eq(from[1], 2);
+ unsigned first_byte_is_zero = constant_time_eq(from[0], 0);
+ unsigned second_byte_is_two = constant_time_eq(from[1], 2);
- looking_for_index = 1;
+ unsigned i, zero_index = 0, looking_for_index = ~0u;
for (i = 2; i < from_len; i++) {
- int equals0 = constant_time_byte_eq(from[i], 0);
- zero_index =
- constant_time_select(looking_for_index & equals0, i, zero_index);
+ unsigned equals0 = constant_time_is_zero(from[i]);
+ zero_index = constant_time_select(looking_for_index & equals0, (unsigned)i,
+ zero_index);
looking_for_index = constant_time_select(equals0, 0, looking_for_index);
}
/* The input must begin with 00 02. */
- valid_index = first_byte_is_zero;
+ unsigned valid_index = first_byte_is_zero;
valid_index &= second_byte_is_two;
/* We must have found the end of PS. */
valid_index &= ~looking_for_index;
/* PS must be at least 8 bytes long, and it starts two bytes into |from|. */
- valid_index &= constant_time_le(2 + 8, zero_index);
+ valid_index &= constant_time_ge(zero_index, 2 + 8);
/* Skip the zero byte. */
zero_index++;
- *out_index = constant_time_select(valid_index, zero_index, 0);
- return valid_index;
-}
-
-int RSA_padding_check_PKCS1_type_2(uint8_t *to, unsigned tlen,
- const uint8_t *from, unsigned flen) {
- size_t msg_index, msg_len;
-
- if (flen == 0) {
- OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY);
+ /* NOTE: Although this logic attempts to be constant time, the API contracts
+ * of this function and |RSA_decrypt| with |RSA_PKCS1_PADDING| make it
+ * impossible to completely avoid Bleichenbacher's attack. Consumers should
+ * use |RSA_unpad_key_pkcs1|. */
+ if (!valid_index) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR);
return -1;
}
- /* NOTE: Although |RSA_message_index_PKCS1_type_2| itself is constant time,
- * the API contracts of this function and |RSA_decrypt| with
- * |RSA_PKCS1_PADDING| make it impossible to completely avoid Bleichenbacher's
- * attack. */
- if (!RSA_message_index_PKCS1_type_2(from, flen, &msg_index)) {
+ const unsigned msg_len = from_len - zero_index;
+ if (msg_len > to_len) {
+ /* This shouldn't happen because this function is always called with
+ * |to_len| as the key size and |from_len| is bounded by the key size. */
OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR);
return -1;
}
- msg_len = flen - msg_index;
- if (msg_len > tlen) {
- /* This shouldn't happen because this function is always called with |tlen|
- * the key size and |flen| is bounded by the key size. */
- OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR);
+ if (msg_len > INT_MAX) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
return -1;
}
- memcpy(to, &from[msg_index], msg_len);
- return msg_len;
+
+ memcpy(to, &from[zero_index], msg_len);
+ return (int)msg_len;
}
-int RSA_padding_add_none(uint8_t *to, unsigned tlen, const uint8_t *from, unsigned flen) {
- if (flen > tlen) {
+int RSA_padding_add_none(uint8_t *to, unsigned to_len, const uint8_t *from,
+ unsigned from_len) {
+ if (from_len > to_len) {
OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
return 0;
}
- if (flen < tlen) {
+ if (from_len < to_len) {
OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE);
return 0;
}
- memcpy(to, from, (unsigned int)flen);
+ memcpy(to, from, (unsigned int)from_len);
return 1;
}
@@ -319,7 +294,8 @@ int PKCS1_MGF1(uint8_t *mask, unsigned len, const uint8_t *seed,
cnt[2] = (uint8_t)((i >> 8)) & 255;
cnt[3] = (uint8_t)(i & 255);
if (!EVP_DigestInit_ex(&c, dgst, NULL) ||
- !EVP_DigestUpdate(&c, seed, seedlen) || !EVP_DigestUpdate(&c, cnt, 4)) {
+ !EVP_DigestUpdate(&c, seed, seedlen) ||
+ !EVP_DigestUpdate(&c, cnt, 4)) {
goto err;
}
@@ -343,9 +319,9 @@ err:
return ret;
}
-int RSA_padding_add_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen,
- const uint8_t *from, unsigned flen,
- const uint8_t *param, unsigned plen,
+int RSA_padding_add_PKCS1_OAEP_mgf1(uint8_t *to, unsigned to_len,
+ const uint8_t *from, unsigned from_len,
+ const uint8_t *param, unsigned param_len,
const EVP_MD *md, const EVP_MD *mgf1md) {
unsigned i, emlen, mdlen;
uint8_t *db, *seed;
@@ -361,13 +337,13 @@ int RSA_padding_add_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen,
mdlen = EVP_MD_size(md);
- if (tlen < 2 * mdlen + 2) {
+ if (to_len < 2 * mdlen + 2) {
OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
return 0;
}
- emlen = tlen - 1;
- if (flen > emlen - 2 * mdlen - 1) {
+ emlen = to_len - 1;
+ if (from_len > emlen - 2 * mdlen - 1) {
OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
return 0;
}
@@ -381,12 +357,12 @@ int RSA_padding_add_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen,
seed = to + 1;
db = to + mdlen + 1;
- if (!EVP_Digest((void *)param, plen, db, NULL, md, NULL)) {
+ if (!EVP_Digest((void *)param, param_len, db, NULL, md, NULL)) {
return 0;
}
- memset(db + mdlen, 0, emlen - flen - 2 * mdlen - 1);
- db[emlen - flen - mdlen - 1] = 0x01;
- memcpy(db + emlen - flen - mdlen, from, flen);
+ memset(db + mdlen, 0, emlen - from_len - 2 * mdlen - 1);
+ db[emlen - from_len - mdlen - 1] = 0x01;
+ memcpy(db + emlen - from_len - mdlen, from, from_len);
if (!RAND_bytes(seed, mdlen)) {
return 0;
}
@@ -417,14 +393,13 @@ out:
return ret;
}
-int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen,
- const uint8_t *from, unsigned flen,
- const uint8_t *param, unsigned plen,
+int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned to_len,
+ const uint8_t *from, unsigned from_len,
+ const uint8_t *param, unsigned param_len,
const EVP_MD *md, const EVP_MD *mgf1md) {
- unsigned i, dblen, mlen = -1, mdlen;
+ unsigned i, dblen, mlen = -1, mdlen, bad, looking_for_one_byte, one_index = 0;
const uint8_t *maskeddb, *maskedseed;
uint8_t *db = NULL, seed[EVP_MAX_MD_SIZE], phash[EVP_MAX_MD_SIZE];
- int bad, looking_for_one_byte, one_index = 0;
if (md == NULL) {
md = EVP_sha1();
@@ -438,13 +413,13 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen,
/* The encoded message is one byte smaller than the modulus to ensure that it
* doesn't end up greater than the modulus. Thus there's an extra "+1" here
* compared to https://tools.ietf.org/html/rfc2437#section-9.1.1.2. */
- if (flen < 1 + 2*mdlen + 1) {
- /* 'flen' is the length of the modulus, i.e. does not depend on the
+ if (from_len < 1 + 2*mdlen + 1) {
+ /* 'from_len' is the length of the modulus, i.e. does not depend on the
* particular ciphertext. */
goto decoding_err;
}
- dblen = flen - mdlen - 1;
+ dblen = from_len - mdlen - 1;
db = OPENSSL_malloc(dblen);
if (db == NULL) {
OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
@@ -468,19 +443,19 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen,
db[i] ^= maskeddb[i];
}
- if (!EVP_Digest((void *)param, plen, phash, NULL, md, NULL)) {
+ if (!EVP_Digest((void *)param, param_len, phash, NULL, md, NULL)) {
goto err;
}
- bad = CRYPTO_memcmp(db, phash, mdlen);
- bad |= from[0];
+ bad = ~constant_time_is_zero(CRYPTO_memcmp(db, phash, mdlen));
+ bad |= ~constant_time_is_zero(from[0]);
- looking_for_one_byte = 1;
+ looking_for_one_byte = ~0u;
for (i = mdlen; i < dblen; i++) {
- int equals1 = constant_time_byte_eq(db[i], 1);
- int equals0 = constant_time_byte_eq(db[i], 0);
- one_index =
- constant_time_select(looking_for_one_byte & equals1, i, one_index);
+ unsigned equals1 = constant_time_eq(db[i], 1);
+ unsigned equals0 = constant_time_eq(db[i], 0);
+ one_index = constant_time_select(looking_for_one_byte & equals1, i,
+ one_index);
looking_for_one_byte =
constant_time_select(equals1, 0, looking_for_one_byte);
bad |= looking_for_one_byte & ~equals0;
@@ -494,7 +469,7 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen,
one_index++;
mlen = dblen - one_index;
- if (tlen < mlen) {
+ if (to_len < mlen) {
OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE);
mlen = -1;
} else {
diff --git a/src/crypto/rsa/rsa.c b/src/crypto/rsa/rsa.c
index 49ab27b..6c28ad7 100644
--- a/src/crypto/rsa/rsa.c
+++ b/src/crypto/rsa/rsa.c
@@ -96,13 +96,7 @@ RSA *RSA_new_method(const ENGINE *engine) {
rsa->references = 1;
rsa->flags = rsa->meth->flags;
CRYPTO_MUTEX_init(&rsa->lock);
-
- if (!CRYPTO_new_ex_data(&g_ex_data_class, rsa, &rsa->ex_data)) {
- CRYPTO_MUTEX_cleanup(&rsa->lock);
- METHOD_unref(rsa->meth);
- OPENSSL_free(rsa);
- return NULL;
- }
+ CRYPTO_new_ex_data(&rsa->ex_data);
if (rsa->meth->init && !rsa->meth->init(rsa)) {
CRYPTO_free_ex_data(&g_ex_data_class, rsa, &rsa->ex_data);
@@ -308,11 +302,11 @@ int RSA_supports_digest(const RSA *rsa, const EVP_MD *md) {
return 1;
}
-int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
int index;
- if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, new_func,
- dup_func, free_func)) {
+ if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func,
+ free_func)) {
return -1;
}
return index;
diff --git a/src/crypto/rsa/rsa_asn1.c b/src/crypto/rsa/rsa_asn1.c
index 6144e74..b73a0e1 100644
--- a/src/crypto/rsa/rsa_asn1.c
+++ b/src/crypto/rsa/rsa_asn1.c
@@ -108,6 +108,14 @@ static RSA *parse_public_key(CBS *cbs, int buggy) {
RSA_free(ret);
return NULL;
}
+
+ if (!BN_is_odd(ret->e) ||
+ BN_num_bits(ret->e) < 2) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS);
+ RSA_free(ret);
+ return NULL;
+ }
+
return ret;
}
diff --git a/src/crypto/rsa/rsa_impl.c b/src/crypto/rsa/rsa_impl.c
index bee7f22..b1cfaa6 100644
--- a/src/crypto/rsa/rsa_impl.c
+++ b/src/crypto/rsa/rsa_impl.c
@@ -636,7 +636,7 @@ static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) {
BIGNUM *p = NULL, *q = NULL;
/* Make sure BN_mod_inverse in Montgomery intialization uses the
- * BN_FLG_CONSTTIME flag (unless RSA_FLAG_NO_CONSTTIME is set) */
+ * BN_FLG_CONSTTIME flag. */
BN_init(&local_p);
p = &local_p;
BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
diff --git a/src/crypto/rsa/rsa_test.cc b/src/crypto/rsa/rsa_test.cc
index 57b360c..5545161 100644
--- a/src/crypto/rsa/rsa_test.cc
+++ b/src/crypto/rsa/rsa_test.cc
@@ -495,6 +495,34 @@ static const uint8_t kEstonianRSAKey[] = {
0x02, 0x03, 0x01, 0x00, 0x01,
};
+// kExponent1RSAKey is an RSAPublicKey encoded with an exponent of 1. See
+// https://crbug.com/541257
+static const uint8_t kExponent1RSAKey[] = {
+ 0x30, 0x82, 0x01, 0x08, 0x02, 0x82, 0x01, 0x01, 0x00, 0xcf, 0x86, 0x9a,
+ 0x7d, 0x5c, 0x9f, 0xbd, 0x33, 0xbb, 0xc2, 0xb1, 0x06, 0xa8, 0x3e, 0xc5,
+ 0x18, 0xf3, 0x01, 0x04, 0xdd, 0x7a, 0x38, 0x0e, 0x8e, 0x8d, 0x10, 0xaa,
+ 0xf8, 0x64, 0x49, 0x82, 0xa6, 0x16, 0x9d, 0xd9, 0xae, 0x5e, 0x7f, 0x9b,
+ 0x53, 0xcb, 0xbb, 0x29, 0xda, 0x98, 0x47, 0x26, 0x88, 0x2e, 0x1d, 0x64,
+ 0xb3, 0xbc, 0x7e, 0x96, 0x3a, 0xa7, 0xd6, 0x87, 0xf6, 0xf5, 0x3f, 0xa7,
+ 0x3b, 0xd3, 0xc5, 0xd5, 0x61, 0x3c, 0x63, 0x05, 0xf9, 0xbc, 0x64, 0x1d,
+ 0x71, 0x65, 0xf5, 0xc8, 0xe8, 0x64, 0x41, 0x35, 0x88, 0x81, 0x6b, 0x2a,
+ 0x24, 0xbb, 0xdd, 0x9f, 0x75, 0x4f, 0xea, 0x35, 0xe5, 0x32, 0x76, 0x5a,
+ 0x8b, 0x7a, 0xb5, 0x92, 0x65, 0x34, 0xb7, 0x88, 0x42, 0x5d, 0x41, 0x0b,
+ 0xd1, 0x00, 0x2d, 0x43, 0x47, 0x55, 0x60, 0x3c, 0x0e, 0x60, 0x04, 0x5c,
+ 0x88, 0x13, 0xc7, 0x42, 0x55, 0x16, 0x31, 0x32, 0x81, 0xba, 0xde, 0xa9,
+ 0x56, 0xeb, 0xdb, 0x66, 0x7f, 0x31, 0xba, 0xe8, 0x87, 0x1a, 0xcc, 0xad,
+ 0x90, 0x86, 0x4b, 0xa7, 0x6d, 0xd5, 0xc1, 0xb7, 0xe7, 0x67, 0x56, 0x41,
+ 0xf7, 0x03, 0xb3, 0x09, 0x61, 0x63, 0xb5, 0xb0, 0x19, 0x7b, 0xc5, 0x91,
+ 0xc8, 0x96, 0x5b, 0x6a, 0x80, 0xa1, 0x53, 0x0f, 0x9a, 0x47, 0xb5, 0x9a,
+ 0x44, 0x53, 0xbd, 0x93, 0xe3, 0xe4, 0xce, 0x0c, 0x17, 0x11, 0x51, 0x1d,
+ 0xfd, 0x6c, 0x74, 0xe4, 0xec, 0x2a, 0xce, 0x57, 0x27, 0xcc, 0x83, 0x98,
+ 0x08, 0x32, 0x2c, 0xd5, 0x75, 0xa9, 0x27, 0xfe, 0xaa, 0x5e, 0x48, 0xc9,
+ 0x46, 0x9a, 0x29, 0x3f, 0xe6, 0x01, 0x4d, 0x97, 0x4a, 0x70, 0xd1, 0x5d,
+ 0xf8, 0xc0, 0x0b, 0x23, 0xcb, 0xbe, 0xf5, 0x70, 0x0b, 0xc2, 0xf2, 0xc0,
+ 0x33, 0x9c, 0xc4, 0x8b, 0x39, 0x7e, 0x3d, 0xc6, 0x23, 0x39, 0x9a, 0x98,
+ 0xdd, 0x02, 0x01, 0x01,
+};
+
static bool TestRSA(const uint8_t *der, size_t der_len,
const uint8_t *oaep_ciphertext,
size_t oaep_ciphertext_len) {
@@ -845,6 +873,19 @@ static bool TestASN1() {
return true;
}
+static bool TestBadExponent() {
+ ScopedRSA rsa(RSA_public_key_from_bytes(kExponent1RSAKey,
+ sizeof(kExponent1RSAKey)));
+
+ if (rsa) {
+ fprintf(stderr, "kExponent1RSAKey parsed but should have failed.\n");
+ return false;
+ }
+
+ ERR_clear_error();
+ return true;
+}
+
int main(int argc, char *argv[]) {
CRYPTO_library_init();
@@ -867,7 +908,8 @@ int main(int argc, char *argv[]) {
kSixPrimeEncryptedMessage,
sizeof(kSixPrimeEncryptedMessage)) ||
!TestMultiPrimeKeygen() ||
- !TestASN1()) {
+ !TestASN1() ||
+ !TestBadExponent()) {
return 1;
}
diff --git a/src/crypto/sha/asm/sha1-586.pl b/src/crypto/sha/asm/sha1-586.pl
index 09fd3fc..3514273 100644
--- a/src/crypto/sha/asm/sha1-586.pl
+++ b/src/crypto/sha/asm/sha1-586.pl
@@ -121,9 +121,7 @@ for (@ARGV) { $xmm=1 if (/-DOPENSSL_IA32_SSE2/); }
# In upstream, this is controlled by shelling out to the compiler to check
# versions, but BoringSSL is intended to be used with pre-generated perlasm
# output, so this isn't useful anyway.
-#
-# TODO(davidben): Enable this after testing. $ymm goes up to 1.
-$ymm = 0;
+$ymm = 1;
$ymm = 0 unless ($xmm);
diff --git a/src/crypto/sha/asm/sha1-x86_64.pl b/src/crypto/sha/asm/sha1-x86_64.pl
index 59b1607..4895f92 100644
--- a/src/crypto/sha/asm/sha1-x86_64.pl
+++ b/src/crypto/sha/asm/sha1-x86_64.pl
@@ -96,8 +96,10 @@ die "can't locate x86_64-xlate.pl";
# versions, but BoringSSL is intended to be used with pre-generated perlasm
# output, so this isn't useful anyway.
#
-# TODO(davidben): Enable this after testing. $avx goes up to 2.
-$avx = 0;
+# TODO(davidben): Enable AVX2 code after testing by setting $avx to 2. Is it
+# necessary to disable AVX2 code when SHA Extensions code is disabled? Upstream
+# did not tie them together until after $shaext was added.
+$avx = 1;
# TODO(davidben): Consider enabling the Intel SHA Extensions code once it's
# been tested.
diff --git a/src/crypto/sha/asm/sha256-586.pl b/src/crypto/sha/asm/sha256-586.pl
index 1866d5a..fa8f264 100644
--- a/src/crypto/sha/asm/sha256-586.pl
+++ b/src/crypto/sha/asm/sha256-586.pl
@@ -72,8 +72,8 @@ for (@ARGV) { $xmm=1 if (/-DOPENSSL_IA32_SSE2/); }
# versions, but BoringSSL is intended to be used with pre-generated perlasm
# output, so this isn't useful anyway.
#
-# TODO(davidben): Enable this after testing. $avx goes up to 2.
-$avx = 0;
+# TODO(davidben): Enable AVX2 code after testing by setting $avx to 2.
+$avx = 1;
$avx = 0 unless ($xmm);
diff --git a/src/crypto/sha/asm/sha512-x86_64.pl b/src/crypto/sha/asm/sha512-x86_64.pl
index 9a0d0c4..2bc33c6 100644
--- a/src/crypto/sha/asm/sha512-x86_64.pl
+++ b/src/crypto/sha/asm/sha512-x86_64.pl
@@ -113,8 +113,10 @@ die "can't locate x86_64-xlate.pl";
# versions, but BoringSSL is intended to be used with pre-generated perlasm
# output, so this isn't useful anyway.
#
-# TODO(davidben): Enable this after testing. $avx goes up to 2.
-$avx = 0;
+# TODO(davidben): Enable AVX2 code after testing by setting $avx to 2. Is it
+# necessary to disable AVX2 code when SHA Extensions code is disabled? Upstream
+# did not tie them together until after $shaext was added.
+$avx = 1;
# TODO(davidben): Consider enabling the Intel SHA Extensions code once it's
# been tested.
diff --git a/src/crypto/sha/sha1.c b/src/crypto/sha/sha1.c
index 568706b..74e841c 100644
--- a/src/crypto/sha/sha1.c
+++ b/src/crypto/sha/sha1.c
@@ -102,21 +102,22 @@ uint8_t *SHA1(const uint8_t *data, size_t len, uint8_t *out) {
do { \
uint32_t ll; \
ll = (c)->h[0]; \
- (void) HOST_l2c(ll, (s)); \
+ HOST_l2c(ll, (s)); \
ll = (c)->h[1]; \
- (void) HOST_l2c(ll, (s)); \
+ HOST_l2c(ll, (s)); \
ll = (c)->h[2]; \
- (void) HOST_l2c(ll, (s)); \
+ HOST_l2c(ll, (s)); \
ll = (c)->h[3]; \
- (void) HOST_l2c(ll, (s)); \
+ HOST_l2c(ll, (s)); \
ll = (c)->h[4]; \
- (void) HOST_l2c(ll, (s)); \
+ HOST_l2c(ll, (s)); \
} while (0)
#define HASH_UPDATE SHA1_Update
#define HASH_TRANSFORM SHA1_Transform
#define HASH_FINAL SHA1_Final
#define HASH_BLOCK_DATA_ORDER sha1_block_data_order
+#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n))))
#define Xupdate(a, ix, ia, ib, ic, id) \
((a) = (ia ^ ib ^ ic ^ id), ix = (a) = ROTATE((a), 1))
diff --git a/src/crypto/sha/sha256.c b/src/crypto/sha/sha256.c
index 3681308..0ddacba 100644
--- a/src/crypto/sha/sha256.c
+++ b/src/crypto/sha/sha256.c
@@ -155,13 +155,13 @@ int SHA224_Final(uint8_t *md, SHA256_CTX *ctx) {
case SHA224_DIGEST_LENGTH: \
for (nn = 0; nn < SHA224_DIGEST_LENGTH / 4; nn++) { \
ll = (c)->h[nn]; \
- (void) HOST_l2c(ll, (s)); \
+ HOST_l2c(ll, (s)); \
} \
break; \
case SHA256_DIGEST_LENGTH: \
for (nn = 0; nn < SHA256_DIGEST_LENGTH / 4; nn++) { \
ll = (c)->h[nn]; \
- (void) HOST_l2c(ll, (s)); \
+ HOST_l2c(ll, (s)); \
} \
break; \
default: \
@@ -170,7 +170,7 @@ int SHA224_Final(uint8_t *md, SHA256_CTX *ctx) {
} \
for (nn = 0; nn < (c)->md_len / 4; nn++) { \
ll = (c)->h[nn]; \
- (void) HOST_l2c(ll, (s)); \
+ HOST_l2c(ll, (s)); \
} \
break; \
} \
@@ -204,6 +204,8 @@ static const uint32_t K256[64] = {
0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL};
+#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n))))
+
/* FIPS specification refers to right rotations, while our ROTATE macro
* is left one. This is why you might notice that rotation coefficients
* differ from those observed in FIPS document by 32-N... */
diff --git a/src/crypto/sha/sha512.c b/src/crypto/sha/sha512.c
index beb0f8c..6ad8d40 100644
--- a/src/crypto/sha/sha512.c
+++ b/src/crypto/sha/sha512.c
@@ -60,8 +60,6 @@
#include <openssl/mem.h>
-#include "../internal.h"
-
/* IMPLEMENTATION NOTES.
*
@@ -87,14 +85,14 @@
#endif
int SHA384_Init(SHA512_CTX *sha) {
- sha->h[0] = OPENSSL_U64(0xcbbb9d5dc1059ed8);
- sha->h[1] = OPENSSL_U64(0x629a292a367cd507);
- sha->h[2] = OPENSSL_U64(0x9159015a3070dd17);
- sha->h[3] = OPENSSL_U64(0x152fecd8f70e5939);
- sha->h[4] = OPENSSL_U64(0x67332667ffc00b31);
- sha->h[5] = OPENSSL_U64(0x8eb44a8768581511);
- sha->h[6] = OPENSSL_U64(0xdb0c2e0d64f98fa7);
- sha->h[7] = OPENSSL_U64(0x47b5481dbefa4fa4);
+ sha->h[0] = UINT64_C(0xcbbb9d5dc1059ed8);
+ sha->h[1] = UINT64_C(0x629a292a367cd507);
+ sha->h[2] = UINT64_C(0x9159015a3070dd17);
+ sha->h[3] = UINT64_C(0x152fecd8f70e5939);
+ sha->h[4] = UINT64_C(0x67332667ffc00b31);
+ sha->h[5] = UINT64_C(0x8eb44a8768581511);
+ sha->h[6] = UINT64_C(0xdb0c2e0d64f98fa7);
+ sha->h[7] = UINT64_C(0x47b5481dbefa4fa4);
sha->Nl = 0;
sha->Nh = 0;
@@ -105,14 +103,14 @@ int SHA384_Init(SHA512_CTX *sha) {
int SHA512_Init(SHA512_CTX *sha) {
- sha->h[0] = OPENSSL_U64(0x6a09e667f3bcc908);
- sha->h[1] = OPENSSL_U64(0xbb67ae8584caa73b);
- sha->h[2] = OPENSSL_U64(0x3c6ef372fe94f82b);
- sha->h[3] = OPENSSL_U64(0xa54ff53a5f1d36f1);
- sha->h[4] = OPENSSL_U64(0x510e527fade682d1);
- sha->h[5] = OPENSSL_U64(0x9b05688c2b3e6c1f);
- sha->h[6] = OPENSSL_U64(0x1f83d9abfb41bd6b);
- sha->h[7] = OPENSSL_U64(0x5be0cd19137e2179);
+ sha->h[0] = UINT64_C(0x6a09e667f3bcc908);
+ sha->h[1] = UINT64_C(0xbb67ae8584caa73b);
+ sha->h[2] = UINT64_C(0x3c6ef372fe94f82b);
+ sha->h[3] = UINT64_C(0xa54ff53a5f1d36f1);
+ sha->h[4] = UINT64_C(0x510e527fade682d1);
+ sha->h[5] = UINT64_C(0x9b05688c2b3e6c1f);
+ sha->h[6] = UINT64_C(0x1f83d9abfb41bd6b);
+ sha->h[7] = UINT64_C(0x5be0cd19137e2179);
sha->Nl = 0;
sha->Nh = 0;
@@ -185,7 +183,7 @@ int SHA512_Update(SHA512_CTX *c, const void *in_data, size_t len) {
return 1;
}
- l = (c->Nl + (((uint64_t)len) << 3)) & OPENSSL_U64(0xffffffffffffffff);
+ l = (c->Nl + (((uint64_t)len) << 3)) & UINT64_C(0xffffffffffffffff);
if (l < c->Nl) {
c->Nh++;
}
@@ -316,77 +314,91 @@ int SHA512_Final(uint8_t *md, SHA512_CTX *sha) {
#ifndef SHA512_ASM
static const uint64_t K512[80] = {
- 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f,
- 0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019,
- 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242,
- 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
- 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
- 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
- 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275,
- 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
- 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f,
- 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
- 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc,
- 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
- 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6,
- 0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001,
- 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
- 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
- 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99,
- 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
- 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc,
- 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
- 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915,
- 0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207,
- 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba,
- 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
- 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
- 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
- 0x5fcb6fab3ad6faec, 0x6c44198c4a475817};
+ UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd),
+ UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc),
+ UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019),
+ UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118),
+ UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe),
+ UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2),
+ UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1),
+ UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694),
+ UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3),
+ UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65),
+ UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483),
+ UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5),
+ UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210),
+ UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4),
+ UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725),
+ UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70),
+ UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926),
+ UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df),
+ UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8),
+ UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b),
+ UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001),
+ UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30),
+ UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910),
+ UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8),
+ UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53),
+ UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8),
+ UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb),
+ UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3),
+ UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60),
+ UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec),
+ UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9),
+ UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b),
+ UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207),
+ UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178),
+ UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6),
+ UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b),
+ UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493),
+ UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c),
+ UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a),
+ UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817),
+};
#if defined(__GNUC__) && __GNUC__ >= 2 && !defined(OPENSSL_NO_ASM)
#if defined(__x86_64) || defined(__x86_64__)
-#define ROTR(a, n) \
- ({ \
- uint64_t ret; \
- asm("rorq %1,%0" : "=r"(ret) : "J"(n), "0"(a) : "cc"); \
- ret; \
+#define ROTR(a, n) \
+ ({ \
+ uint64_t ret; \
+ __asm__("rorq %1, %0" : "=r"(ret) : "J"(n), "0"(a) : "cc"); \
+ ret; \
})
-#define PULL64(x) \
- ({ \
- uint64_t ret = *((const uint64_t *)(&(x))); \
- asm("bswapq %0" : "=r"(ret) : "0"(ret)); \
- ret; \
+#define PULL64(x) \
+ ({ \
+ uint64_t ret = *((const uint64_t *)(&(x))); \
+ __asm__("bswapq %0" : "=r"(ret) : "0"(ret)); \
+ ret; \
})
#elif(defined(__i386) || defined(__i386__))
-#define PULL64(x) \
- ({ \
- const unsigned int *p = (const unsigned int *)(&(x)); \
- unsigned int hi = p[0], lo = p[1]; \
- asm("bswapl %0; bswapl %1;" : "=r"(lo), "=r"(hi) : "0"(lo), "1"(hi)); \
- ((uint64_t)hi) << 32 | lo; \
+#define PULL64(x) \
+ ({ \
+ const unsigned int *p = (const unsigned int *)(&(x)); \
+ unsigned int hi = p[0], lo = p[1]; \
+ __asm__("bswapl %0; bswapl %1;" : "=r"(lo), "=r"(hi) : "0"(lo), "1"(hi)); \
+ ((uint64_t)hi) << 32 | lo; \
})
#elif(defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64)
-#define ROTR(a, n) \
- ({ \
- uint64_t ret; \
- asm("rotrdi %0,%1,%2" : "=r"(ret) : "r"(a), "K"(n)); \
- ret; \
+#define ROTR(a, n) \
+ ({ \
+ uint64_t ret; \
+ __asm__("rotrdi %0, %1, %2" : "=r"(ret) : "r"(a), "K"(n)); \
+ ret; \
})
#elif defined(__aarch64__)
-#define ROTR(a, n) \
- ({ \
- uint64_t ret; \
- asm("ror %0,%1,%2" : "=r"(ret) : "r"(a), "I"(n)); \
- ret; \
+#define ROTR(a, n) \
+ ({ \
+ uint64_t ret; \
+ __asm__("ror %0, %1, %2" : "=r"(ret) : "r"(a), "I"(n)); \
+ ret; \
})
#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-#define PULL64(x) \
- ({ \
- uint64_t ret; \
- asm("rev %0,%1" : "=r"(ret) : "r"(*((const uint64_t *)(&(x))))); \
- ret; \
+#define PULL64(x) \
+ ({ \
+ uint64_t ret; \
+ __asm__("rev %0, %1" : "=r"(ret) : "r"(*((const uint64_t *)(&(x))))); \
+ ret; \
})
#endif
#endif
diff --git a/src/crypto/test/file_test.cc b/src/crypto/test/file_test.cc
index 6723350..4752f04 100644
--- a/src/crypto/test/file_test.cc
+++ b/src/crypto/test/file_test.cc
@@ -22,8 +22,6 @@
#include <openssl/err.h>
-#include "stl_compat.h"
-
FileTest::FileTest(const char *path) {
file_ = fopen(path, "r");
diff --git a/src/crypto/test/scoped_types.h b/src/crypto/test/scoped_types.h
index 2ce4526..590f926 100644
--- a/src/crypto/test/scoped_types.h
+++ b/src/crypto/test/scoped_types.h
@@ -18,6 +18,8 @@
#include <stdint.h>
#include <stdio.h>
+#include <memory>
+
#include <openssl/aead.h>
#include <openssl/bio.h>
#include <openssl/bn.h>
@@ -34,8 +36,6 @@
#include <openssl/stack.h>
#include <openssl/x509.h>
-#include "stl_compat.h"
-
template<typename T, void (*func)(T*)>
struct OpenSSLDeleter {
@@ -66,11 +66,11 @@ struct FileCloser {
};
template<typename T, void (*func)(T*)>
-using ScopedOpenSSLType = bssl::unique_ptr<T, OpenSSLDeleter<T, func>>;
+using ScopedOpenSSLType = std::unique_ptr<T, OpenSSLDeleter<T, func>>;
template<typename StackType, typename T, void (*func)(T*)>
using ScopedOpenSSLStack =
- bssl::unique_ptr<StackType, OpenSSLStackDeleter<StackType, T, func>>;
+ std::unique_ptr<StackType, OpenSSLStackDeleter<StackType, T, func>>;
template<typename T, typename CleanupRet, void (*init_func)(T*),
CleanupRet (*cleanup_func)(T*)>
@@ -129,9 +129,9 @@ using ScopedEVP_MD_CTX = ScopedOpenSSLContext<EVP_MD_CTX, int, EVP_MD_CTX_init,
using ScopedHMAC_CTX = ScopedOpenSSLContext<HMAC_CTX, void, HMAC_CTX_init,
HMAC_CTX_cleanup>;
-using ScopedOpenSSLBytes = bssl::unique_ptr<uint8_t, OpenSSLFree<uint8_t>>;
-using ScopedOpenSSLString = bssl::unique_ptr<char, OpenSSLFree<char>>;
+using ScopedOpenSSLBytes = std::unique_ptr<uint8_t, OpenSSLFree<uint8_t>>;
+using ScopedOpenSSLString = std::unique_ptr<char, OpenSSLFree<char>>;
-using ScopedFILE = bssl::unique_ptr<FILE, FileCloser>;
+using ScopedFILE = std::unique_ptr<FILE, FileCloser>;
#endif // OPENSSL_HEADER_CRYPTO_TEST_SCOPED_TYPES_H
diff --git a/src/crypto/test/stl_compat.h b/src/crypto/test/stl_compat.h
deleted file mode 100644
index 1997a45..0000000
--- a/src/crypto/test/stl_compat.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/* Copyright (c) 2015, Google Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
-
-#ifndef OPENSSL_HEADER_CRYPTO_TEST_STL_COMPAT_H
-#define OPENSSL_HEADER_CRYPTO_TEST_STL_COMPAT_H
-
-#include <assert.h>
-
-#include <vector>
-
-
-// This header contains re-implementations of library functions from C++11. They
-// will be replaced with their standard counterparts once Chromium has C++11
-// library support in its toolchain.
-
-namespace bssl {
-
-// vector_data is a reimplementation of |std::vector::data| from C++11.
-template <class T>
-static T *vector_data(std::vector<T> *out) {
- return out->empty() ? nullptr : &(*out)[0];
-}
-
-template <class T>
-static const T *vector_data(const std::vector<T> *out) {
- return out->empty() ? nullptr : &(*out)[0];
-}
-
-// remove_reference is a reimplementation of |std::remove_reference| from C++11.
-template <class T>
-struct remove_reference {
- using type = T;
-};
-
-template <class T>
-struct remove_reference<T&> {
- using type = T;
-};
-
-template <class T>
-struct remove_reference<T&&> {
- using type = T;
-};
-
-// move is a reimplementation of |std::move| from C++11.
-template <class T>
-typename remove_reference<T>::type &&move(T &&t) {
- return static_cast<typename remove_reference<T>::type&&>(t);
-}
-
-// default_delete is a partial reimplementation of |std::default_delete| from
-// C++11.
-template <class T>
-struct default_delete {
- void operator()(T *t) const {
- enum { type_must_be_complete = sizeof(T) };
- delete t;
- }
-};
-
-// nullptr_t is |std::nullptr_t| from C++11.
-using nullptr_t = decltype(nullptr);
-
-// unique_ptr is a partial reimplementation of |std::unique_ptr| from C++11. It
-// intentionally does not support stateful deleters to avoid having to bother
-// with the empty member optimization.
-template <class T, class Deleter = default_delete<T>>
-class unique_ptr {
- public:
- unique_ptr() : ptr_(nullptr) {}
- unique_ptr(nullptr_t) : ptr_(nullptr) {}
- unique_ptr(T *ptr) : ptr_(ptr) {}
- unique_ptr(const unique_ptr &u) = delete;
-
- unique_ptr(unique_ptr &&u) : ptr_(nullptr) {
- reset(u.release());
- }
-
- ~unique_ptr() {
- reset();
- }
-
- unique_ptr &operator=(nullptr_t) {
- reset();
- return *this;
- }
-
- unique_ptr &operator=(unique_ptr &&u) {
- reset(u.release());
- return *this;
- }
-
- unique_ptr& operator=(const unique_ptr &u) = delete;
-
- explicit operator bool() const {
- return ptr_ != nullptr;
- }
-
- T &operator*() const {
- assert(ptr_ != nullptr);
- return *ptr_;
- }
-
- T *operator->() const {
- assert(ptr_ != nullptr);
- return ptr_;
- }
-
- T *get() const {
- return ptr_;
- }
-
- T *release() {
- T *ptr = ptr_;
- ptr_ = nullptr;
- return ptr;
- }
-
- void reset(T *ptr = nullptr) {
- if (ptr_ != nullptr) {
- Deleter()(ptr_);
- }
- ptr_ = ptr;
- }
-
- private:
- T *ptr_;
-};
-
-} // namespace bssl
-
-
-#endif // OPENSSL_HEADER_CRYPTO_TEST_STL_COMPAT_H
diff --git a/src/crypto/thread_pthread.c b/src/crypto/thread_pthread.c
index 59c4b8d..68aaab5 100644
--- a/src/crypto/thread_pthread.c
+++ b/src/crypto/thread_pthread.c
@@ -17,6 +17,7 @@
#if !defined(OPENSSL_WINDOWS) && !defined(OPENSSL_NO_THREADS)
#include <pthread.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -74,7 +75,11 @@ void CRYPTO_STATIC_MUTEX_unlock(struct CRYPTO_STATIC_MUTEX *lock) {
}
void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) {
- pthread_once(once, init);
+ if (pthread_once(once, init) != 0) {
+ fprintf(stderr,
+ "pthread_once failed. Did you link against a threading library?\n");
+ abort();
+ }
}
static pthread_mutex_t g_destructors_lock = PTHREAD_MUTEX_INITIALIZER;
diff --git a/src/crypto/x509/by_dir.c b/src/crypto/x509/by_dir.c
index 3393dfa..ae50ae1 100644
--- a/src/crypto/x509/by_dir.c
+++ b/src/crypto/x509/by_dir.c
@@ -98,7 +98,7 @@ 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,int type,X509_NAME *name,
X509_OBJECT *ret);
-X509_LOOKUP_METHOD x509_dir_lookup=
+static X509_LOOKUP_METHOD x509_dir_lookup=
{
"Load certs from files in a directory",
new_dir, /* new */
diff --git a/src/crypto/x509/by_file.c b/src/crypto/x509/by_file.c
index f1d6194..3460b57 100644
--- a/src/crypto/x509/by_file.c
+++ b/src/crypto/x509/by_file.c
@@ -68,7 +68,7 @@
static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
long argl, char **ret);
-X509_LOOKUP_METHOD x509_file_lookup=
+static X509_LOOKUP_METHOD x509_file_lookup=
{
"Load file into cache",
NULL, /* new */
diff --git a/src/crypto/x509/pkcs7.c b/src/crypto/x509/pkcs7.c
index 2087f94..9e6a52f 100644
--- a/src/crypto/x509/pkcs7.c
+++ b/src/crypto/x509/pkcs7.c
@@ -15,6 +15,7 @@
#include <openssl/x509.h>
#include <assert.h>
+#include <limits.h>
#include <openssl/bytestring.h>
#include <openssl/err.h>
@@ -114,8 +115,11 @@ int PKCS7_get_certificates(STACK_OF(X509) *out_certs, CBS *cbs) {
goto err;
}
+ if (CBS_len(&cert) > LONG_MAX) {
+ goto err;
+ }
inp = CBS_data(&cert);
- x509 = d2i_X509(NULL, &inp, CBS_len(&cert));
+ x509 = d2i_X509(NULL, &inp, (long)CBS_len(&cert));
if (!x509) {
goto err;
}
@@ -181,8 +185,11 @@ int PKCS7_get_CRLs(STACK_OF(X509_CRL) *out_crls, CBS *cbs) {
goto err;
}
+ if (CBS_len(&crl_data) > LONG_MAX) {
+ goto err;
+ }
inp = CBS_data(&crl_data);
- crl = d2i_X509_CRL(NULL, &inp, CBS_len(&crl_data));
+ crl = d2i_X509_CRL(NULL, &inp, (long)CBS_len(&crl_data));
if (!crl) {
goto err;
}
diff --git a/src/crypto/x509/x509_vfy.c b/src/crypto/x509/x509_vfy.c
index 695793e..c62a6f5 100644
--- a/src/crypto/x509/x509_vfy.c
+++ b/src/crypto/x509/x509_vfy.c
@@ -141,7 +141,6 @@ static int check_crl_chain(X509_STORE_CTX *ctx,
STACK_OF(X509) *crl_path);
static int internal_verify(X509_STORE_CTX *ctx);
-const char X509_version[]="X.509";
static int null_callback(int ok, X509_STORE_CTX *e)
@@ -205,22 +204,26 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
OPENSSL_PUT_ERROR(X509, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
return -1;
}
+ if (ctx->chain != NULL)
+ {
+ /* This X509_STORE_CTX has already been used to verify a
+ * cert. We cannot do another one. */
+ OPENSSL_PUT_ERROR(X509, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return -1;
+ }
cb=ctx->verify_cb;
/* first we make sure the chain we are going to build is
* present and that the first entry is in place */
- if (ctx->chain == NULL)
+ ctx->chain = sk_X509_new_null();
+ if (ctx->chain == NULL || !sk_X509_push(ctx->chain, ctx->cert))
{
- if ( ((ctx->chain=sk_X509_new_null()) == NULL) ||
- (!sk_X509_push(ctx->chain,ctx->cert)))
- {
- OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
- goto end;
- }
- X509_up_ref(ctx->cert);
- ctx->last_untrusted=1;
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ goto end;
}
+ X509_up_ref(ctx->cert);
+ ctx->last_untrusted = 1;
/* We use a temporary STACK so we can chop and hack at it */
if (ctx->untrusted != NULL
@@ -2093,14 +2096,14 @@ X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
return NULL;
}
-int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
{
/* This function is (usually) called only once, by
* SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c). */
int index;
if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp,
- new_func, dup_func, free_func))
+ dup_func, free_func))
{
return -1;
}
@@ -2267,19 +2270,13 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
STACK_OF(X509) *chain)
{
int ret = 1;
- int ex_data_allocated = 0;
memset(ctx, 0, sizeof(X509_STORE_CTX));
ctx->ctx=store;
ctx->cert=x509;
ctx->untrusted=chain;
- if(!CRYPTO_new_ex_data(&g_ex_data_class, ctx,
- &ctx->ex_data))
- {
- goto err;
- }
- ex_data_allocated = 1;
+ CRYPTO_new_ex_data(&ctx->ex_data);
ctx->param = X509_VERIFY_PARAM_new();
if (!ctx->param)
@@ -2363,10 +2360,7 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
return 1;
err:
- if (ex_data_allocated)
- {
- CRYPTO_free_ex_data(&g_ex_data_class, ctx, &ctx->ex_data);
- }
+ CRYPTO_free_ex_data(&g_ex_data_class, ctx, &ctx->ex_data);
if (ctx->param != NULL)
{
X509_VERIFY_PARAM_free(ctx->param);
diff --git a/src/crypto/x509/x509name.c b/src/crypto/x509/x509name.c
index 7bb3aa1..8b10fa2 100644
--- a/src/crypto/x509/x509name.c
+++ b/src/crypto/x509/x509name.c
@@ -291,19 +291,13 @@ X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
int type, unsigned char *bytes, int len)
{
- const ASN1_OBJECT *obj;
- X509_NAME_ENTRY *nentry;
-
- obj=OBJ_nid2obj(nid);
+ const ASN1_OBJECT *obj = OBJ_nid2obj(nid);
if (obj == NULL)
{
OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID);
- return(NULL);
+ return NULL;
}
- nentry = X509_NAME_ENTRY_create_by_OBJ(ne,obj,type,bytes,len);
- /* TODO(fork): remove this? */
- /* ASN1_OBJECT_free(obj); */
- return nentry;
+ return X509_NAME_ENTRY_create_by_OBJ(ne,obj,type,bytes,len);
}
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
diff --git a/src/crypto/x509/x_all.c b/src/crypto/x509/x_all.c
index d7f2d29..62b3f40 100644
--- a/src/crypto/x509/x_all.c
+++ b/src/crypto/x509/x_all.c
@@ -93,14 +93,6 @@ int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx)
x->sig_alg, x->signature, x->cert_info, ctx);
}
-/* TODO(fork)
-int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert)
- {
- return OCSP_REQ_CTX_nbio_d2i(rctx,
- (ASN1_VALUE **)pcert, ASN1_ITEM_rptr(X509));
- }
-*/
-
int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md)
{
return(ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO),x->sig_alg, NULL,
@@ -127,14 +119,6 @@ int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx)
x->crl->sig_alg, x->sig_alg, x->signature, x->crl, ctx);
}
-/* TODO(fork)
-int X509_CRL_http_nbio(OCSP_REQ_CTX *rctx, X509_CRL **pcrl)
- {
- return OCSP_REQ_CTX_nbio_d2i(rctx,
- (ASN1_VALUE **)pcrl, ASN1_ITEM_rptr(X509_CRL));
- }
-*/
-
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,
@@ -191,31 +175,6 @@ int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl)
return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl);
}
-/* TODO(fork) */
-#if 0
-#ifndef OPENSSL_NO_FP_API
-PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7)
- {
- return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS7), fp, p7);
- }
-
-int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7)
- {
- return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS7), fp, p7);
- }
-#endif
-
-PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7)
- {
- return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS7), bp, p7);
- }
-
-int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7)
- {
- return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS7), bp, p7);
- }
-#endif
-
#ifndef OPENSSL_NO_FP_API
X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req)
{
@@ -425,15 +384,6 @@ int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, unsigned char *m
return(ASN1_item_digest(ASN1_ITEM_rptr(X509_NAME),type,(char *)data,md,len));
}
-#if 0 /* TODO(fork): remove */
-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));
- }
-#endif
-
#ifndef OPENSSL_NO_FP_API
X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8)
{
diff --git a/src/crypto/x509/x_name.c b/src/crypto/x509/x_name.c
index 762756b..a1dcd16 100644
--- a/src/crypto/x509/x_name.c
+++ b/src/crypto/x509/x_name.c
@@ -120,7 +120,7 @@ ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL)
* to the external form.
*/
-const ASN1_EXTERN_FUNCS x509_name_ff = {
+static const ASN1_EXTERN_FUNCS x509_name_ff = {
NULL,
x509_name_ex_new,
x509_name_ex_free,
diff --git a/src/crypto/x509/x_x509.c b/src/crypto/x509/x_x509.c
index b8f318a..7bbe4f3 100644
--- a/src/crypto/x509/x_x509.c
+++ b/src/crypto/x509/x_x509.c
@@ -104,7 +104,7 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
ret->akid = NULL;
ret->aux = NULL;
ret->crldp = NULL;
- CRYPTO_new_ex_data(&g_ex_data_class, ret, &ret->ex_data);
+ CRYPTO_new_ex_data(&ret->ex_data);
break;
case ASN1_OP_D2I_POST:
@@ -146,12 +146,12 @@ X509 *X509_up_ref(X509 *x)
return x;
}
-int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
{
int index;
if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp,
- new_func, dup_func, free_func))
+ dup_func, free_func))
{
return -1;
}
diff --git a/src/crypto/x509v3/ext_dat.h b/src/crypto/x509v3/ext_dat.h
index 8b2c123..f1fb8ef 100644
--- a/src/crypto/x509v3/ext_dat.h
+++ b/src/crypto/x509v3/ext_dat.h
@@ -55,17 +55,17 @@
/* This file contains a table of "standard" extensions */
-extern X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku;
-extern X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info, v3_sinfo;
-extern X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id;
-extern X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate;
-extern X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, v3_freshest_crl;
-extern X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff;
-extern X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc;
-extern X509V3_EXT_METHOD v3_crl_hold, v3_pci;
-extern X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints;
-extern X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp;
-extern X509V3_EXT_METHOD v3_addr, v3_asid;
+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[], v3_alt[], 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;
/* This table will be searched using OBJ_bsearch so it *must* kept in
* order of the ext_nid values.
diff --git a/src/decrepit/cast/cast.c b/src/decrepit/cast/cast.c
index 68bcbe3..94b0710 100644
--- a/src/decrepit/cast/cast.c
+++ b/src/decrepit/cast/cast.c
@@ -62,6 +62,7 @@
#pragma warning(pop)
#endif
+#include "internal.h"
#include "../macros.h"
@@ -80,15 +81,6 @@ void CAST_ecb_encrypt(const uint8_t *in, uint8_t *out, const CAST_KEY *ks,
l2n(d[1], out);
}
-extern const uint32_t CAST_S_table0[256];
-extern const uint32_t CAST_S_table1[256];
-extern const uint32_t CAST_S_table2[256];
-extern const uint32_t CAST_S_table3[256];
-extern const uint32_t CAST_S_table4[256];
-extern const uint32_t CAST_S_table5[256];
-extern const uint32_t CAST_S_table6[256];
-extern const uint32_t CAST_S_table7[256];
-
#if defined(OPENSSL_WINDOWS) && defined(_MSC_VER)
#define ROTL(a, n) (_lrotl(a, n))
#else
diff --git a/src/decrepit/cast/cast_tables.c b/src/decrepit/cast/cast_tables.c
index a00acd8..6808aa8 100644
--- a/src/decrepit/cast/cast_tables.c
+++ b/src/decrepit/cast/cast_tables.c
@@ -56,6 +56,9 @@
#include <openssl/base.h>
+#include "internal.h"
+
+
const uint32_t CAST_S_table0[256] = {
0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3,
0x6003e540, 0xcf9fc949, 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675,
diff --git a/src/decrepit/cast/internal.h b/src/decrepit/cast/internal.h
new file mode 100644
index 0000000..15e2222
--- /dev/null
+++ b/src/decrepit/cast/internal.h
@@ -0,0 +1,81 @@
+/* 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.] */
+
+#ifndef OPENSSL_HEADER_CAST_INTERNAL_H
+#define OPENSSL_HEADER_CAST_INTERNAL_H
+
+#include <openssl/base.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+extern const uint32_t CAST_S_table0[256];
+extern const uint32_t CAST_S_table1[256];
+extern const uint32_t CAST_S_table2[256];
+extern const uint32_t CAST_S_table3[256];
+extern const uint32_t CAST_S_table4[256];
+extern const uint32_t CAST_S_table5[256];
+extern const uint32_t CAST_S_table6[256];
+extern const uint32_t CAST_S_table7[256];
+
+
+#if defined(__cplusplus)
+} /* extern C */
+#endif
+
+#endif /* OPENSSL_HEADER_CAST_INTERNAL_H */
diff --git a/src/decrepit/xts/xts.c b/src/decrepit/xts/xts.c
index 632e0f8..10a696d 100644
--- a/src/decrepit/xts/xts.c
+++ b/src/decrepit/xts/xts.c
@@ -56,12 +56,6 @@
#include "../crypto/modes/internal.h"
-#if defined(OPENSSL_X86_64) || defined(OPENSSL_X86) || defined(OPENSSL_AARCH64)
-#define STRICT_ALIGNMENT 0
-#else
-#define STRICT_ALIGNMENT 1
-#endif
-
typedef struct xts128_context {
void *key1, *key2;
block128_f block1, block2;
@@ -70,10 +64,6 @@ typedef struct xts128_context {
static size_t CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx,
const uint8_t iv[16], const uint8_t *inp,
uint8_t *out, size_t len, int enc) {
- const union {
- long one;
- char little;
- } is_endian = {1};
union {
uint64_t u[2];
uint32_t d[4];
@@ -90,22 +80,22 @@ static size_t CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx,
if (!enc && (len % 16)) len -= 16;
while (len >= 16) {
-#if defined(STRICT_ALIGNMENT)
+#if STRICT_ALIGNMENT
memcpy(scratch.c, inp, 16);
scratch.u[0] ^= tweak.u[0];
scratch.u[1] ^= tweak.u[1];
#else
- scratch.u[0] = ((unint64_t *)inp)[0] ^ tweak.u[0];
- scratch.u[1] = ((unint64_t *)inp)[1] ^ tweak.u[1];
+ scratch.u[0] = ((uint64_t *)inp)[0] ^ tweak.u[0];
+ scratch.u[1] = ((uint64_t *)inp)[1] ^ tweak.u[1];
#endif
(*ctx->block1)(scratch.c, scratch.c, ctx->key1);
-#if defined(STRICT_ALIGNMENT)
+#if STRICT_ALIGNMENT
scratch.u[0] ^= tweak.u[0];
scratch.u[1] ^= tweak.u[1];
memcpy(out, scratch.c, 16);
#else
- ((unint64_t *)out)[0] = scratch.u[0] ^= tweak.u[0];
- ((unint64_t *)out)[1] = scratch.u[1] ^= tweak.u[1];
+ ((uint64_t *)out)[0] = scratch.u[0] ^= tweak.u[0];
+ ((uint64_t *)out)[1] = scratch.u[1] ^= tweak.u[1];
#endif
inp += 16;
out += 16;
@@ -113,26 +103,12 @@ static size_t CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx,
if (len == 0) return 1;
- if (is_endian.little) {
- unsigned int carry, res;
+ unsigned int carry, res;
- res = 0x87 & (((int)tweak.d[3]) >> 31);
- carry = (unsigned int)(tweak.u[0] >> 63);
- tweak.u[0] = (tweak.u[0] << 1) ^ res;
- tweak.u[1] = (tweak.u[1] << 1) | carry;
- } else {
- size_t c;
-
- for (c = 0, i = 0; i < 16; ++i) {
- /*
- * + substitutes for |, because c is 1 bit
- */
- c += ((size_t)tweak.c[i]) << 1;
- tweak.c[i] = (uint8_t)c;
- c = c >> 8;
- }
- tweak.c[0] ^= (uint8_t)(0x87 & (0 - c));
- }
+ res = 0x87 & (((int)tweak.d[3]) >> 31);
+ carry = (unsigned int)(tweak.u[0] >> 63);
+ tweak.u[0] = (tweak.u[0] << 1) ^ res;
+ tweak.u[1] = (tweak.u[1] << 1) | carry;
}
if (enc) {
for (i = 0; i < len; ++i) {
@@ -152,33 +128,19 @@ static size_t CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx,
uint8_t c[16];
} tweak1;
- if (is_endian.little) {
- unsigned int carry, res;
-
- res = 0x87 & (((int)tweak.d[3]) >> 31);
- carry = (unsigned int)(tweak.u[0] >> 63);
- tweak1.u[0] = (tweak.u[0] << 1) ^ res;
- tweak1.u[1] = (tweak.u[1] << 1) | carry;
- } else {
- size_t c;
+ unsigned int carry, res;
- for (c = 0, i = 0; i < 16; ++i) {
- /*
- * + substitutes for |, because c is 1 bit
- */
- c += ((size_t)tweak.c[i]) << 1;
- tweak1.c[i] = (uint8_t)c;
- c = c >> 8;
- }
- tweak1.c[0] ^= (uint8_t)(0x87 & (0 - c));
- }
-#if defined(STRICT_ALIGNMENT)
+ res = 0x87 & (((int)tweak.d[3]) >> 31);
+ carry = (unsigned int)(tweak.u[0] >> 63);
+ tweak1.u[0] = (tweak.u[0] << 1) ^ res;
+ tweak1.u[1] = (tweak.u[1] << 1) | carry;
+#if STRICT_ALIGNMENT
memcpy(scratch.c, inp, 16);
scratch.u[0] ^= tweak1.u[0];
scratch.u[1] ^= tweak1.u[1];
#else
- scratch.u[0] = ((unint64_t *)inp)[0] ^ tweak1.u[0];
- scratch.u[1] = ((unint64_t *)inp)[1] ^ tweak1.u[1];
+ scratch.u[0] = ((uint64_t *)inp)[0] ^ tweak1.u[0];
+ scratch.u[1] = ((uint64_t *)inp)[1] ^ tweak1.u[1];
#endif
(*ctx->block1)(scratch.c, scratch.c, ctx->key1);
scratch.u[0] ^= tweak1.u[0];
@@ -192,13 +154,13 @@ static size_t CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx,
scratch.u[0] ^= tweak.u[0];
scratch.u[1] ^= tweak.u[1];
(*ctx->block1)(scratch.c, scratch.c, ctx->key1);
-#if defined(STRICT_ALIGNMENT)
+#if STRICT_ALIGNMENT
scratch.u[0] ^= tweak.u[0];
scratch.u[1] ^= tweak.u[1];
memcpy(out, scratch.c, 16);
#else
- ((unint64_t *)out)[0] = scratch.u[0] ^ tweak.u[0];
- ((unint64_t *)out)[1] = scratch.u[1] ^ tweak.u[1];
+ ((uint64_t *)out)[0] = scratch.u[0] ^ tweak.u[0];
+ ((uint64_t *)out)[1] = scratch.u[1] ^ tweak.u[1];
#endif
}
@@ -286,7 +248,7 @@ static int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) {
}
static const EVP_CIPHER aes_256_xts = {
- NID_aes_256_xts, 1 /* block_size */, 32 /* key_size */,
+ NID_aes_256_xts, 1 /* block_size */, 64 /* key_size (2 AES keys) */,
16 /* iv_len */, sizeof(EVP_AES_XTS_CTX),
EVP_CIPH_XTS_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_ALWAYS_CALL_INIT |
EVP_CIPH_CTRL_INIT | EVP_CIPH_CUSTOM_COPY,
diff --git a/src/include/openssl/aead.h b/src/include/openssl/aead.h
index 4f822e8..092d2f6 100644
--- a/src/include/openssl/aead.h
+++ b/src/include/openssl/aead.h
@@ -98,23 +98,15 @@ OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_gcm(void);
/* EVP_aead_aes_256_gcm is AES-256 in Galois Counter Mode. */
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_gcm(void);
+/* EVP_aead_chacha20_poly1305 is the AEAD built from ChaCha20 and
+ * Poly1305 as described in RFC 7539. */
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305(void);
+
/* EVP_aead_chacha20_poly1305_old is an AEAD built from ChaCha20 and
* Poly1305 that is used in the experimental ChaCha20-Poly1305 TLS cipher
* suites. */
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305_old(void);
-/* EVP_aead_chacha20_poly1305 is currently an alias for
- * |EVP_aead_chacha20_poly1305_old|. In the future, the RFC 7539 version will
- * take this name. */
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305(void);
-
-/* EVP_aead_chacha20_poly1305_rfc7539 is the AEAD built from ChaCha20 and
- * Poly1305 as described in RFC 7539.
- *
- * WARNING: this function is not ready yet. It will be renamed in the future to
- * drop the “_rfc7539” suffix. */
-OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305_rfc7539(void);
-
/* EVP_aead_aes_128_key_wrap is AES-128 Key Wrap mode. This should never be
* used except to interoperate with existing systems that use this mode.
*
@@ -339,6 +331,14 @@ OPENSSL_EXPORT int EVP_AEAD_CTX_get_iv(const EVP_AEAD_CTX *ctx,
const uint8_t **out_iv, size_t *out_len);
+/* Deprecated functions. */
+
+/* EVP_aead_chacha20_poly1305_rfc7539 calls |EVP_aead_chacha20_poly1305|.
+ *
+ * TODO(davidben): Remove this. */
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305_rfc7539(void);
+
+
#if defined(__cplusplus)
} /* extern C */
#endif
diff --git a/src/include/openssl/asn1.h b/src/include/openssl/asn1.h
index 08886d1..63bde18 100644
--- a/src/include/openssl/asn1.h
+++ b/src/include/openssl/asn1.h
@@ -1126,43 +1126,42 @@ OPENSSL_EXPORT int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, asn1_ps_f
#define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 147
#define ASN1_R_INVALID_UTF8STRING 148
#define ASN1_R_LIST_ERROR 149
-#define ASN1_R_MALLOC_FAILURE 150
-#define ASN1_R_MISSING_ASN1_EOS 151
-#define ASN1_R_MISSING_EOC 152
-#define ASN1_R_MISSING_SECOND_NUMBER 153
-#define ASN1_R_MISSING_VALUE 154
-#define ASN1_R_MSTRING_NOT_UNIVERSAL 155
-#define ASN1_R_MSTRING_WRONG_TAG 156
-#define ASN1_R_NESTED_ASN1_ERROR 157
-#define ASN1_R_NESTED_ASN1_STRING 158
-#define ASN1_R_NON_HEX_CHARACTERS 159
-#define ASN1_R_NOT_ASCII_FORMAT 160
-#define ASN1_R_NOT_ENOUGH_DATA 161
-#define ASN1_R_NO_MATCHING_CHOICE_TYPE 162
-#define ASN1_R_NULL_IS_WRONG_LENGTH 163
-#define ASN1_R_OBJECT_NOT_ASCII_FORMAT 164
-#define ASN1_R_ODD_NUMBER_OF_CHARS 165
-#define ASN1_R_SECOND_NUMBER_TOO_LARGE 166
-#define ASN1_R_SEQUENCE_LENGTH_MISMATCH 167
-#define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 168
-#define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 169
-#define ASN1_R_SHORT_LINE 170
-#define ASN1_R_STREAMING_NOT_SUPPORTED 171
-#define ASN1_R_STRING_TOO_LONG 172
-#define ASN1_R_STRING_TOO_SHORT 173
-#define ASN1_R_TAG_VALUE_TOO_HIGH 174
-#define ASN1_R_TIME_NOT_ASCII_FORMAT 175
-#define ASN1_R_TOO_LONG 176
-#define ASN1_R_TYPE_NOT_CONSTRUCTED 177
-#define ASN1_R_TYPE_NOT_PRIMITIVE 178
-#define ASN1_R_UNEXPECTED_EOC 179
-#define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 180
-#define ASN1_R_UNKNOWN_FORMAT 181
-#define ASN1_R_UNKNOWN_TAG 182
-#define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 183
-#define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 184
-#define ASN1_R_UNSUPPORTED_TYPE 185
-#define ASN1_R_WRONG_TAG 186
-#define ASN1_R_WRONG_TYPE 187
+#define ASN1_R_MISSING_ASN1_EOS 150
+#define ASN1_R_MISSING_EOC 151
+#define ASN1_R_MISSING_SECOND_NUMBER 152
+#define ASN1_R_MISSING_VALUE 153
+#define ASN1_R_MSTRING_NOT_UNIVERSAL 154
+#define ASN1_R_MSTRING_WRONG_TAG 155
+#define ASN1_R_NESTED_ASN1_ERROR 156
+#define ASN1_R_NESTED_ASN1_STRING 157
+#define ASN1_R_NON_HEX_CHARACTERS 158
+#define ASN1_R_NOT_ASCII_FORMAT 159
+#define ASN1_R_NOT_ENOUGH_DATA 160
+#define ASN1_R_NO_MATCHING_CHOICE_TYPE 161
+#define ASN1_R_NULL_IS_WRONG_LENGTH 162
+#define ASN1_R_OBJECT_NOT_ASCII_FORMAT 163
+#define ASN1_R_ODD_NUMBER_OF_CHARS 164
+#define ASN1_R_SECOND_NUMBER_TOO_LARGE 165
+#define ASN1_R_SEQUENCE_LENGTH_MISMATCH 166
+#define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 167
+#define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 168
+#define ASN1_R_SHORT_LINE 169
+#define ASN1_R_STREAMING_NOT_SUPPORTED 170
+#define ASN1_R_STRING_TOO_LONG 171
+#define ASN1_R_STRING_TOO_SHORT 172
+#define ASN1_R_TAG_VALUE_TOO_HIGH 173
+#define ASN1_R_TIME_NOT_ASCII_FORMAT 174
+#define ASN1_R_TOO_LONG 175
+#define ASN1_R_TYPE_NOT_CONSTRUCTED 176
+#define ASN1_R_TYPE_NOT_PRIMITIVE 177
+#define ASN1_R_UNEXPECTED_EOC 178
+#define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 179
+#define ASN1_R_UNKNOWN_FORMAT 180
+#define ASN1_R_UNKNOWN_TAG 181
+#define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 182
+#define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 183
+#define ASN1_R_UNSUPPORTED_TYPE 184
+#define ASN1_R_WRONG_TAG 185
+#define ASN1_R_WRONG_TYPE 186
#endif
diff --git a/src/include/openssl/bn.h b/src/include/openssl/bn.h
index 01115c8..6e971e4 100644
--- a/src/include/openssl/bn.h
+++ b/src/include/openssl/bn.h
@@ -253,6 +253,9 @@ OPENSSL_EXPORT size_t BN_bn2bin(const BIGNUM *in, uint8_t *out);
* returns 0. Otherwise, it returns 1. */
OPENSSL_EXPORT int BN_bn2bin_padded(uint8_t *out, size_t len, const BIGNUM *in);
+/* BN_bn2cbb_padded behaves like |BN_bn2bin_padded| but writes to a |CBB|. */
+OPENSSL_EXPORT int BN_bn2cbb_padded(CBB *out, size_t len, const BIGNUM *in);
+
/* BN_bn2hex returns an allocated string that contains a NUL-terminated, hex
* representation of |bn|. If |bn| is negative, the first char in the resulting
* string will be '-'. Returns NULL on allocation failure. */
@@ -836,11 +839,7 @@ struct bignum_st {
struct bn_mont_ctx_st {
BIGNUM RR; /* used to convert to montgomery form */
BIGNUM N; /* The modulus */
- BIGNUM Ni; /* R*(1/R mod N) - N*Ni = 1
- * (Ni is only stored for bignum algorithm) */
- BN_ULONG n0[2]; /* least significant word(s) of Ni;
- (type changed with 0.9.9, was "BN_ULONG n0;" before) */
- int ri; /* number of bits in R */
+ BN_ULONG n0[2]; /* least significant words of (R*Ri-1)/N */
};
OPENSSL_EXPORT unsigned BN_num_bits_word(BN_ULONG l);
diff --git a/src/include/openssl/bytestring.h b/src/include/openssl/bytestring.h
index 906e7e8..9193e11 100644
--- a/src/include/openssl/bytestring.h
+++ b/src/include/openssl/bytestring.h
@@ -238,13 +238,13 @@ struct cbb_buffer_st {
struct cbb_st {
struct cbb_buffer_st *base;
- /* offset is the offset from the start of |base->buf| to the position of any
- * pending length-prefix. */
- size_t offset;
/* child points to a child CBB if a length-prefix is pending. */
CBB *child;
- /* pending_len_len contains the number of bytes in a pending length-prefix,
- * or zero if no length-prefix is pending. */
+ /* offset is the number of bytes from the start of |base->buf| to this |CBB|'s
+ * pending length prefix. */
+ size_t offset;
+ /* pending_len_len contains the number of bytes in this |CBB|'s pending
+ * length-prefix, or zero if no length-prefix is pending. */
uint8_t pending_len_len;
char pending_is_asn1;
/* is_top_level is true iff this is a top-level |CBB| (as opposed to a child
@@ -292,12 +292,18 @@ OPENSSL_EXPORT int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len);
* on error. */
OPENSSL_EXPORT int CBB_flush(CBB *cbb);
-/* CBB_len returns the number of bytes written to |cbb|'s top-level |CBB|. It
- * may be compared before and after an operation to determine how many bytes
- * were written.
+/* CBB_data returns a pointer to the bytes written to |cbb|. It does not flush
+ * |cbb|. The pointer is valid until the next operation to |cbb|.
+ *
+ * To avoid unfinalized length prefixes, it is a fatal error to call this on a
+ * CBB with any active children. */
+OPENSSL_EXPORT const uint8_t *CBB_data(const CBB *cbb);
+
+/* CBB_len returns the number of bytes written to |cbb|. It does not flush
+ * |cbb|.
*
- * It is a fatal error to call this on a CBB with any active children. This does
- * not flush |cbb|. */
+ * To avoid unfinalized length prefixes, it is a fatal error to call this on a
+ * CBB with any active children. */
OPENSSL_EXPORT size_t CBB_len(const CBB *cbb);
/* CBB_add_u8_length_prefixed sets |*out_contents| to a new child of |cbb|. The
@@ -332,6 +338,17 @@ OPENSSL_EXPORT int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len);
* otherwise. */
OPENSSL_EXPORT int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len);
+/* CBB_reserve ensures |cbb| has room for |len| additional bytes and sets
+ * |*out_data| to point to the beginning of that space. It returns one on
+ * success and zero otherwise. The caller may write up to |len| bytes to
+ * |*out_data| and call |CBB_did_write| to complete the write. |*out_data| is
+ * valid until the next operation on |cbb| or an ancestor |CBB|. */
+OPENSSL_EXPORT int CBB_reserve(CBB *cbb, uint8_t **out_data, size_t len);
+
+/* CBB_did_write advances |cbb| by |len| bytes, assuming the space has been
+ * written to by the caller. It returns one on success and zero on error. */
+OPENSSL_EXPORT int CBB_did_write(CBB *cbb, size_t len);
+
/* CBB_add_u8 appends an 8-bit number from |value| to |cbb|. It returns one on
* success and zero otherwise. */
OPENSSL_EXPORT int CBB_add_u8(CBB *cbb, uint8_t value);
diff --git a/src/include/openssl/cpu.h b/src/include/openssl/cpu.h
index 19e11d0..e946304 100644
--- a/src/include/openssl/cpu.h
+++ b/src/include/openssl/cpu.h
@@ -102,10 +102,20 @@ extern uint32_t OPENSSL_ia32cap_P[4];
#if !defined(OPENSSL_STATIC_ARMCAP)
-/* CRYPTO_is_NEON_capable returns true if the current CPU has a NEON unit. Note
- * that |OPENSSL_armcap_P| also exists and contains the same information in a
- * form that's easier for assembly to use. */
-OPENSSL_EXPORT char CRYPTO_is_NEON_capable(void);
+/* CRYPTO_is_NEON_capable_at_runtime returns true if the current CPU has a NEON
+ * unit. Note that |OPENSSL_armcap_P| also exists and contains the same
+ * information in a form that's easier for assembly to use. */
+OPENSSL_EXPORT char CRYPTO_is_NEON_capable_at_runtime(void);
+
+/* CRYPTO_is_NEON_capable returns true if the current CPU has a NEON unit. If
+ * this is known statically then it returns one immediately. */
+static inline int CRYPTO_is_NEON_capable(void) {
+#if defined(__ARM_NEON__)
+ return 1;
+#else
+ return CRYPTO_is_NEON_capable_at_runtime();
+#endif
+}
/* CRYPTO_set_NEON_capable sets the return value of |CRYPTO_is_NEON_capable|.
* By default, unless the code was compiled with |-mfpu=neon|, NEON is assumed
diff --git a/src/include/openssl/curve25519.h b/src/include/openssl/curve25519.h
new file mode 100644
index 0000000..30c6470
--- /dev/null
+++ b/src/include/openssl/curve25519.h
@@ -0,0 +1,92 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#ifndef OPENSSL_HEADER_CURVE25519_H
+#define OPENSSL_HEADER_CURVE25519_H
+
+#include <openssl/base.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/* Curve25519.
+ *
+ * Curve25519 is an elliptic curve. See
+ * https://tools.ietf.org/html/draft-irtf-cfrg-curves-11. */
+
+
+/* X25519.
+ *
+ * Curve25519 is an elliptic curve. The same name is also sometimes used for
+ * the Diffie-Hellman primitive built from it but “X25519” is a more precise
+ * name for that, which is the one used here. See http://cr.yp.to/ecdh.html and
+ * https://tools.ietf.org/html/draft-irtf-cfrg-curves-11. */
+
+/* X25519_keypair sets |out_public_value| and |out_private_key| to a freshly
+ * generated, public–private key pair. */
+OPENSSL_EXPORT void X25519_keypair(uint8_t out_public_value[32],
+ uint8_t out_private_key[32]);
+
+/* X25519 writes a shared key to |out_shared_key| that is calculated from the
+ * given private key and the peer's public value. It returns one on success and
+ * zero on error.
+ *
+ * Don't use the shared key directly, rather use a KDF and also include the two
+ * public values as inputs. */
+OPENSSL_EXPORT int X25519(uint8_t out_shared_key[32],
+ const uint8_t private_key[32],
+ const uint8_t peers_public_value[32]);
+
+/* X25519_public_from_private calculates a Diffie-Hellman public value from the
+ * given private key and writes it to |out_public_value|. */
+OPENSSL_EXPORT void X25519_public_from_private(uint8_t out_public_value[32],
+ const uint8_t private_key[32]);
+
+
+/* Ed25519.
+ *
+ * Ed25519 is a signature scheme using a twisted-Edwards curve that is
+ * birationally equivalent to curve25519. */
+
+#define ED25519_PRIVATE_KEY_LEN 64
+#define ED25519_PUBLIC_KEY_LEN 32
+#define ED25519_SIGNATURE_LEN 64
+
+/* ED25519_keypair sets |out_public_key| and |out_private_key| to a freshly
+ * generated, public–private key pair. */
+OPENSSL_EXPORT void ED25519_keypair(uint8_t out_public_key[32],
+ uint8_t out_private_key[64]);
+
+/* ED25519_sign sets |out_sig| to be a signature of |message_len| bytes from
+ * |message| using |private_key|. It returns one on success or zero on
+ * error. */
+OPENSSL_EXPORT int ED25519_sign(uint8_t out_sig[64], const uint8_t *message,
+ size_t message_len,
+ const uint8_t private_key[64]);
+
+/* ED25519_verify returns one iff |signature| is a valid signature, by
+ * |public_key| of |message_len| bytes from |message|. It returns zero
+ * otherwise. */
+OPENSSL_EXPORT int ED25519_verify(const uint8_t *message, size_t message_len,
+ const uint8_t signature[64],
+ const uint8_t public_key[32]);
+
+
+#if defined(__cplusplus)
+} /* extern C */
+#endif
+
+#endif /* OPENSSL_HEADER_CURVE25519_H */
diff --git a/src/include/openssl/dh.h b/src/include/openssl/dh.h
index d781789..2c49fc8 100644
--- a/src/include/openssl/dh.h
+++ b/src/include/openssl/dh.h
@@ -193,7 +193,7 @@ OPENSSL_EXPORT int i2d_DHparams(const DH *in, unsigned char **outp);
* See |ex_data.h| for details. */
OPENSSL_EXPORT int DH_get_ex_new_index(long argl, void *argp,
- CRYPTO_EX_new *new_func,
+ CRYPTO_EX_unused *unused,
CRYPTO_EX_dup *dup_func,
CRYPTO_EX_free *free_func);
OPENSSL_EXPORT int DH_set_ex_data(DH *d, int idx, void *arg);
diff --git a/src/include/openssl/dsa.h b/src/include/openssl/dsa.h
index bd16395..2045fe7 100644
--- a/src/include/openssl/dsa.h
+++ b/src/include/openssl/dsa.h
@@ -302,7 +302,7 @@ OPENSSL_EXPORT DH *DSA_dup_DH(const DSA *dsa);
* See |ex_data.h| for details. */
OPENSSL_EXPORT int DSA_get_ex_new_index(long argl, void *argp,
- CRYPTO_EX_new *new_func,
+ CRYPTO_EX_unused *unused,
CRYPTO_EX_dup *dup_func,
CRYPTO_EX_free *free_func);
OPENSSL_EXPORT int DSA_set_ex_data(DSA *d, int idx, void *arg);
diff --git a/src/include/openssl/ec.h b/src/include/openssl/ec.h
index ac36a32..667be3b 100644
--- a/src/include/openssl/ec.h
+++ b/src/include/openssl/ec.h
@@ -120,10 +120,9 @@ OPENSSL_EXPORT int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b,
* in |group| that specifies the generator for the group. */
OPENSSL_EXPORT const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group);
-/* EC_GROUP_get_order sets |*order| to the order of |group|, if it's not
- * NULL. It returns one on success and zero otherwise. |ctx| is ignored. */
-OPENSSL_EXPORT int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order,
- BN_CTX *ctx);
+/* EC_GROUP_get0_order returns a pointer to the internal |BIGNUM| object in
+ * |group| that specifies the order of the group. */
+OPENSSL_EXPORT const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group);
/* EC_GROUP_get_cofactor sets |*cofactor| to the cofactor of |group| using
* |ctx|, if it's not NULL. It returns one on success and zero otherwise. */
@@ -146,15 +145,6 @@ OPENSSL_EXPORT int EC_GROUP_get_curve_name(const EC_GROUP *group);
* element of the field underlying |group|. */
OPENSSL_EXPORT unsigned EC_GROUP_get_degree(const EC_GROUP *group);
-/* EC_GROUP_precompute_mult precomputes multiplies of the generator in order to
- * speed up operations that involve calculating generator multiples. It returns
- * one on sucess and zero otherwise. If |ctx| is not NULL, it may be used. */
-OPENSSL_EXPORT int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
-
-/* EC_GROUP_have_precompute_mult returns one if |group| contains precomputed
- * generator multiples. */
-OPENSSL_EXPORT int EC_GROUP_have_precompute_mult(const EC_GROUP *group);
-
/* Points on elliptic curves. */
@@ -278,13 +268,6 @@ OPENSSL_EXPORT int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r,
const BIGNUM *n, const EC_POINT *q,
const BIGNUM *m, BN_CTX *ctx);
-/* EC_POINTs_mul sets r = generator*n + sum(p[i]*m[i]). It returns one on
- * success and zero otherwise. If |ctx| is not NULL, it may be used. */
-OPENSSL_EXPORT int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r,
- const BIGNUM *n, size_t num,
- const EC_POINT *p[], const BIGNUM *m[],
- BN_CTX *ctx);
-
/* Deprecated functions. */
@@ -299,6 +282,12 @@ OPENSSL_EXPORT EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p,
const BIGNUM *a,
const BIGNUM *b, BN_CTX *ctx);
+/* EC_GROUP_get_order sets |*order| to the order of |group|, if it's not
+ * NULL. It returns one on success and zero otherwise. |ctx| is ignored. Use
+ * |EC_GROUP_get0_order| instead. */
+OPENSSL_EXPORT int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order,
+ BN_CTX *ctx);
+
/* EC_GROUP_set_generator sets the generator for |group| to |generator|, which
* must have the given order and cofactor. This should only be used with
* |EC_GROUP| objects returned by |EC_GROUP_new_curve_GFp|. */
diff --git a/src/include/openssl/ec_key.h b/src/include/openssl/ec_key.h
index 1cd4e6e..afd95d6 100644
--- a/src/include/openssl/ec_key.h
+++ b/src/include/openssl/ec_key.h
@@ -154,12 +154,6 @@ OPENSSL_EXPORT point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key);
OPENSSL_EXPORT void EC_KEY_set_conv_form(EC_KEY *key,
point_conversion_form_t cform);
-/* EC_KEY_precompute_mult precomputes multiplies of the generator of the
- * underlying group in order to speed up operations that calculate generator
- * multiples. If |ctx| is not NULL, it may be used. It returns one on success
- * and zero otherwise. */
-OPENSSL_EXPORT int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx);
-
/* EC_KEY_check_key performs several checks on |key| (possibly including an
* expensive check that the public key is in the primary subgroup). It returns
* one if all checks pass and zero otherwise. If it returns zero then detail
@@ -232,7 +226,7 @@ OPENSSL_EXPORT int i2o_ECPublicKey(const EC_KEY *key, unsigned char **outp);
* These functions are wrappers. See |ex_data.h| for details. */
OPENSSL_EXPORT int EC_KEY_get_ex_new_index(long argl, void *argp,
- CRYPTO_EX_new *new_func,
+ CRYPTO_EX_unused *unused,
CRYPTO_EX_dup *dup_func,
CRYPTO_EX_free *free_func);
OPENSSL_EXPORT int EC_KEY_set_ex_data(EC_KEY *r, int idx, void *arg);
diff --git a/src/include/openssl/evp.h b/src/include/openssl/evp.h
index 6f594e5..be2ea33 100644
--- a/src/include/openssl/evp.h
+++ b/src/include/openssl/evp.h
@@ -143,31 +143,30 @@ OPENSSL_EXPORT int EVP_PKEY_type(int nid);
* The following functions get and set the underlying public key in an
* |EVP_PKEY| object. The |set1| functions take an additional reference to the
* underlying key and return one on success or zero on error. The |assign|
- * functions adopt the caller's reference. The getters return a fresh reference
- * to the underlying object. */
+ * functions adopt the caller's reference. The |get1| functions return a fresh
+ * reference to the underlying object or NULL if |pkey| is not of the correct
+ * type. The |get0| functions behave the same but return a non-owning
+ * pointer. */
OPENSSL_EXPORT int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key);
OPENSSL_EXPORT int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key);
+OPENSSL_EXPORT RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey);
OPENSSL_EXPORT RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey);
OPENSSL_EXPORT int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key);
OPENSSL_EXPORT int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key);
+OPENSSL_EXPORT DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey);
OPENSSL_EXPORT DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey);
OPENSSL_EXPORT int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key);
OPENSSL_EXPORT int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key);
+OPENSSL_EXPORT EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey);
OPENSSL_EXPORT EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey);
-OPENSSL_EXPORT int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key);
-OPENSSL_EXPORT int EVP_PKEY_assign_DH(EVP_PKEY *pkey, DH *key);
-OPENSSL_EXPORT DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey);
-
#define EVP_PKEY_NONE NID_undef
#define EVP_PKEY_RSA NID_rsaEncryption
#define EVP_PKEY_RSA2 NID_rsa
#define EVP_PKEY_DSA NID_dsa
-#define EVP_PKEY_DH NID_dhKeyAgreement
-#define EVP_PKEY_DHX NID_dhpublicnumber
#define EVP_PKEY_EC NID_X9_62_id_ecPublicKey
/* EVP_PKEY_assign sets the underlying key of |pkey| to |key|, which must be of
@@ -643,6 +642,10 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx,
/* Deprecated functions. */
+/* EVP_PKEY_DH is defined for compatibility, but it is impossible to create an
+ * |EVP_PKEY| of that type. */
+#define EVP_PKEY_DH NID_dhKeyAgreement
+
/* OpenSSL_add_all_algorithms does nothing. */
OPENSSL_EXPORT void OpenSSL_add_all_algorithms(void);
diff --git a/src/include/openssl/ex_data.h b/src/include/openssl/ex_data.h
index c0d3773..e78e070 100644
--- a/src/include/openssl/ex_data.h
+++ b/src/include/openssl/ex_data.h
@@ -121,8 +121,8 @@ extern "C" {
/* ex_data is a mechanism for associating arbitrary extra data with objects.
* For each type of object that supports ex_data, different users can be
* assigned indexes in which to store their data. Each index has callback
- * functions that are called when a new object of that type is created, freed
- * and duplicated. */
+ * functions that are called when an object of that type is freed or
+ * duplicated. */
typedef struct crypto_ex_data_st CRYPTO_EX_DATA;
@@ -142,7 +142,7 @@ typedef struct crypto_ex_data_st CRYPTO_EX_DATA;
*
* TODO(fork): this should follow the standard calling convention. */
OPENSSL_EXPORT int TYPE_get_ex_new_index(long argl, void *argp,
- CRYPTO_EX_new *new_func,
+ CRYPTO_EX_unused *unused,
CRYPTO_EX_dup *dup_func,
CRYPTO_EX_free *free_func);
@@ -160,27 +160,19 @@ OPENSSL_EXPORT void *TYPE_get_ex_data(const TYPE *t, int index);
/* Callback types. */
-/* CRYPTO_EX_new is the type of a callback function that is called whenever a
- * new object of a given class is created. For example, if this callback has
- * been passed to |SSL_get_ex_new_index| then it'll be called each time an SSL*
- * is created.
+/* CRYPTO_EX_free is a callback function that is called when an object of the
+ * class with extra data pointers is being destroyed. For example, if this
+ * callback has been passed to |SSL_get_ex_new_index| then it may be called each
+ * time an |SSL*| is destroyed.
*
- * The callback is passed the new object (i.e. the SSL*) in |parent|. The
+ * The callback is passed the new object (i.e. the |SSL*|) in |parent|. The
* arguments |argl| and |argp| contain opaque values that were given to
* |CRYPTO_get_ex_new_index|. The callback should return one on success, but
* the value is ignored.
*
- * TODO(fork): the |ptr| argument is always NULL, no? */
-typedef int CRYPTO_EX_new(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
- int index, long argl, void *argp);
-
-/* CRYPTO_EX_free is a callback function that is called when an object of the
- * class is being destroyed. See |CRYPTO_EX_new| for a discussion of the
- * arguments.
- *
- * If |CRYPTO_get_ex_new_index| was called after the creation of objects of the
- * class that this applies to then, when those those objects are destroyed,
- * this callback will be called with a NULL value for |ptr|. */
+ * This callback may be called with a NULL value for |ptr| if |parent| has no
+ * value set for this index. However, the callbacks may also be skipped entirely
+ * if no extra data pointers are set on |parent| at all. */
typedef void CRYPTO_EX_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
int index, long argl, void *argp);
@@ -190,9 +182,9 @@ typedef void CRYPTO_EX_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
* original object. When the callback returns, |*from_d| will be set as the
* data for this index in |to|.
*
- * If |CRYPTO_get_ex_new_index| was called after the creation of objects of the
- * class that this applies to then, when those those objects are copies, this
- * callback will be called with a NULL value for |*from_d|. */
+ * This callback may be called with a NULL value for |*from_d| if |from| has no
+ * value set for this index. However, the callbacks may also be skipped entirely
+ * if no extra data pointers are set on |from| at all. */
typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
void **from_d, int index, long argl, void *argp);
@@ -202,6 +194,13 @@ typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
/* CRYPTO_cleanup_all_ex_data does nothing. */
OPENSSL_EXPORT void CRYPTO_cleanup_all_ex_data(void);
+
+/* Private structures. */
+
+/* CRYPTO_EX_unused is a placeholder for an unused callback. It is aliased to
+ * int to ensure non-NULL callers fail to compile rather than fail silently. */
+typedef int CRYPTO_EX_unused;
+
struct crypto_ex_data_st {
STACK_OF(void) *sk;
};
diff --git a/src/include/openssl/md4.h b/src/include/openssl/md4.h
index e363b73..93c7af8 100644
--- a/src/include/openssl/md4.h
+++ b/src/include/openssl/md4.h
@@ -90,8 +90,8 @@ OPENSSL_EXPORT void MD4_Transform(MD4_CTX *md4, const uint8_t *block);
struct md4_state_st {
uint32_t h[4];
uint32_t Nl, Nh;
- uint32_t data[16];
- unsigned int num;
+ uint8_t data[MD4_CBLOCK];
+ unsigned num;
};
diff --git a/src/include/openssl/md5.h b/src/include/openssl/md5.h
index 87c3ba4..55162f0 100644
--- a/src/include/openssl/md5.h
+++ b/src/include/openssl/md5.h
@@ -95,8 +95,8 @@ OPENSSL_EXPORT void MD5_Transform(MD5_CTX *md5, const uint8_t *block);
struct md5_state_st {
uint32_t h[4];
uint32_t Nl, Nh;
- uint32_t data[16];
- unsigned int num;
+ uint8_t data[MD5_CBLOCK];
+ unsigned num;
};
diff --git a/src/include/openssl/obj_mac.h b/src/include/openssl/obj_mac.h
index 55e1cba..b636adc 100644
--- a/src/include/openssl/obj_mac.h
+++ b/src/include/openssl/obj_mac.h
@@ -4138,3 +4138,7 @@
#define SN_dh_cofactor_kdf "dh-cofactor-kdf"
#define NID_dh_cofactor_kdf 947
+#define SN_x25519 "X25519"
+#define LN_x25519 "x25519"
+#define NID_x25519 948
+
diff --git a/src/include/openssl/pem.h b/src/include/openssl/pem.h
index db763d5..a6687a6 100644
--- a/src/include/openssl/pem.h
+++ b/src/include/openssl/pem.h
@@ -125,11 +125,9 @@ extern "C" {
#define PEM_STRING_PKCS8 "ENCRYPTED PRIVATE KEY"
#define PEM_STRING_PKCS8INF "PRIVATE KEY"
#define PEM_STRING_DHPARAMS "DH PARAMETERS"
-#define PEM_STRING_DHXPARAMS "X9.42 DH PARAMETERS"
#define PEM_STRING_SSL_SESSION "SSL SESSION PARAMETERS"
#define PEM_STRING_DSAPARAMS "DSA PARAMETERS"
#define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY"
-#define PEM_STRING_ECPARAMETERS "EC PARAMETERS"
#define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY"
#define PEM_STRING_PARAMETERS "PARAMETERS"
#define PEM_STRING_CMS "CMS"
@@ -454,13 +452,11 @@ DECLARE_PEM_rw_const(DSAparams, DSA)
#endif
-DECLARE_PEM_rw_const(ECPKParameters, EC_GROUP)
DECLARE_PEM_rw_cb(ECPrivateKey, EC_KEY)
DECLARE_PEM_rw(EC_PUBKEY, EC_KEY)
DECLARE_PEM_rw_const(DHparams, DH)
-DECLARE_PEM_write_const(DHxparams, DH)
DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY)
diff --git a/src/include/openssl/rand.h b/src/include/openssl/rand.h
index de1bd8d..3a8e357 100644
--- a/src/include/openssl/rand.h
+++ b/src/include/openssl/rand.h
@@ -68,7 +68,8 @@ OPENSSL_EXPORT void RAND_enable_fork_unsafe_buffering(int fd);
/* RAND_pseudo_bytes is a wrapper around |RAND_bytes|. */
OPENSSL_EXPORT int RAND_pseudo_bytes(uint8_t *buf, size_t len);
-/* RAND_seed does nothing. */
+/* RAND_seed reads a single byte of random data to ensure that any file
+ * descriptors etc are opened. */
OPENSSL_EXPORT void RAND_seed(const void *buf, int num);
/* RAND_load_file returns a nonnegative number. */
diff --git a/src/include/openssl/rsa.h b/src/include/openssl/rsa.h
index e624f7c..304c555 100644
--- a/src/include/openssl/rsa.h
+++ b/src/include/openssl/rsa.h
@@ -124,8 +124,8 @@ OPENSSL_EXPORT int RSA_generate_multi_prime_key(RSA *rsa, int bits,
* It returns 1 on success or zero on error.
*
* The |padding| argument must be one of the |RSA_*_PADDING| values. If in
- * doubt, |RSA_PKCS1_PADDING| is the most common but |RSA_PKCS1_OAEP_PADDING|
- * is the most secure. */
+ * doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols but
+ * |RSA_PKCS1_PADDING| is most common. */
OPENSSL_EXPORT int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out,
size_t max_out, const uint8_t *in, size_t in_len,
int padding);
@@ -137,8 +137,14 @@ OPENSSL_EXPORT int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out,
* It returns 1 on success or zero on error.
*
* The |padding| argument must be one of the |RSA_*_PADDING| values. If in
- * doubt, |RSA_PKCS1_PADDING| is the most common but |RSA_PKCS1_OAEP_PADDING|
- * is the most secure. */
+ * doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols.
+ *
+ * Passing |RSA_PKCS1_PADDING| into this function is deprecated and insecure. If
+ * implementing a protocol using RSAES-PKCS1-V1_5, use |RSA_NO_PADDING| and then
+ * check padding in constant-time combined with a swap to a random session key
+ * or other mitigation. See "Chosen Ciphertext Attacks Against Protocols Based
+ * on the RSA Encryption Standard PKCS #1", Daniel Bleichenbacher, Advances in
+ * Cryptology (Crypto '98). */
OPENSSL_EXPORT int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out,
size_t max_out, const uint8_t *in, size_t in_len,
int padding);
@@ -147,8 +153,8 @@ OPENSSL_EXPORT int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out,
* |rsa| and writes the encrypted data to |to|. The |to| buffer must have at
* least |RSA_size| bytes of space. It returns the number of bytes written, or
* -1 on error. The |padding| argument must be one of the |RSA_*_PADDING|
- * values. If in doubt, |RSA_PKCS1_PADDING| is the most common but
- * |RSA_PKCS1_OAEP_PADDING| is the most secure.
+ * values. If in doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols but
+ * |RSA_PKCS1_PADDING| is most common.
*
* WARNING: this function is dangerous because it breaks the usual return value
* convention. Use |RSA_encrypt| instead. */
@@ -156,37 +162,25 @@ OPENSSL_EXPORT int RSA_public_encrypt(size_t flen, const uint8_t *from,
uint8_t *to, RSA *rsa, int padding);
/* RSA_private_decrypt decrypts |flen| bytes from |from| with the public key in
- * |rsa| and writes the plaintext to |to|. The |to| buffer must have at
- * least |RSA_size| bytes of space. It returns the number of bytes written, or
- * -1 on error. The |padding| argument must be one of the |RSA_*_PADDING|
- * values. If in doubt, |RSA_PKCS1_PADDING| is the most common but
- * |RSA_PKCS1_OAEP_PADDING| is the most secure.
+ * |rsa| and writes the plaintext to |to|. The |to| buffer must have at least
+ * |RSA_size| bytes of space. It returns the number of bytes written, or -1 on
+ * error. The |padding| argument must be one of the |RSA_*_PADDING| values. If
+ * in doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols. Passing
+ * |RSA_PKCS1_PADDING| into this function is deprecated and insecure. See
+ * |RSA_decrypt|.
*
* WARNING: this function is dangerous because it breaks the usual return value
* convention. Use |RSA_decrypt| instead. */
OPENSSL_EXPORT int RSA_private_decrypt(size_t flen, const uint8_t *from,
uint8_t *to, RSA *rsa, int padding);
-/* RSA_message_index_PKCS1_type_2 performs the first step of a PKCS #1 padding
- * check for decryption. If the |from_len| bytes pointed to at |from| are a
- * valid PKCS #1 message, it returns one and sets |*out_index| to the start of
- * the unpadded message. The unpadded message is a suffix of the input and has
- * length |from_len - *out_index|. Otherwise, it returns zero and sets
- * |*out_index| to zero. This function runs in time independent of the input
- * data and is intended to be used directly to avoid Bleichenbacher's attack.
- *
- * WARNING: This function behaves differently from the usual OpenSSL convention
- * in that it does NOT put an error on the queue in the error case. */
-OPENSSL_EXPORT int RSA_message_index_PKCS1_type_2(const uint8_t *from,
- size_t from_len,
- size_t *out_index);
-
/* Signing / Verification */
-/* RSA_sign signs |in_len| bytes of digest from |in| with |rsa| and writes, at
- * most, |RSA_size(rsa)| bytes to |out|. On successful return, the actual
- * number of bytes written is written to |*out_len|.
+/* RSA_sign signs |in_len| bytes of digest from |in| with |rsa| using
+ * RSASSA-PKCS1-v1_5. It writes, at most, |RSA_size(rsa)| bytes to |out|. On
+ * successful return, the actual number of bytes written is written to
+ * |*out_len|.
*
* The |hash_nid| argument identifies the hash function used to calculate |in|
* and is embedded in the resulting signature. For example, it might be
@@ -204,13 +198,14 @@ OPENSSL_EXPORT int RSA_sign(int hash_nid, const uint8_t *in,
* It returns 1 on success or zero on error.
*
* The |padding| argument must be one of the |RSA_*_PADDING| values. If in
- * doubt, |RSA_PKCS1_PADDING| is the most common. */
+ * doubt, |RSA_PKCS1_PADDING| is the most common but |RSA_PKCS1_PSS_PADDING|
+ * (via the |EVP_PKEY| interface) is preferred for new protocols. */
OPENSSL_EXPORT int RSA_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out,
size_t max_out, const uint8_t *in,
size_t in_len, int padding);
-/* RSA_verify verifies that |sig_len| bytes from |sig| are a valid, PKCS#1
- * signature of |msg_len| bytes at |msg| by |rsa|.
+/* RSA_verify verifies that |sig_len| bytes from |sig| are a valid,
+ * RSASSA-PKCS1-v1_5 signature of |msg_len| bytes at |msg| by |rsa|.
*
* The |hash_nid| argument identifies the hash function used to calculate |in|
* and is embedded in the resulting signature in order to prevent hash
@@ -231,7 +226,8 @@ OPENSSL_EXPORT int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len,
* It returns 1 on success or zero on error.
*
* The |padding| argument must be one of the |RSA_*_PADDING| values. If in
- * doubt, |RSA_PKCS1_PADDING| is the most common. */
+ * doubt, |RSA_PKCS1_PADDING| is the most common but |RSA_PKCS1_PSS_PADDING|
+ * (via the |EVP_PKEY| interface) is preferred for new protocols. */
OPENSSL_EXPORT int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out,
size_t max_out, const uint8_t *in,
size_t in_len, int padding);
@@ -240,7 +236,9 @@ OPENSSL_EXPORT int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out,
* |rsa| and writes the encrypted data to |to|. The |to| buffer must have at
* least |RSA_size| bytes of space. It returns the number of bytes written, or
* -1 on error. The |padding| argument must be one of the |RSA_*_PADDING|
- * values. If in doubt, |RSA_PKCS1_PADDING| is the most common.
+ * values. If in doubt, |RSA_PKCS1_PADDING| is the most common but
+ * |RSA_PKCS1_PSS_PADDING| (via the |EVP_PKEY| interface) is preferred for new
+ * protocols.
*
* WARNING: this function is dangerous because it breaks the usual return value
* convention. Use |RSA_sign_raw| instead. */
@@ -251,7 +249,9 @@ OPENSSL_EXPORT int RSA_private_encrypt(size_t flen, const uint8_t *from,
* public key in |rsa| and writes the plaintext to |to|. The |to| buffer must
* have at least |RSA_size| bytes of space. It returns the number of bytes
* written, or -1 on error. The |padding| argument must be one of the
- * |RSA_*_PADDING| values. If in doubt, |RSA_PKCS1_PADDING| is the most common.
+ * |RSA_*_PADDING| values. If in doubt, |RSA_PKCS1_PADDING| is the most common
+ * but |RSA_PKCS1_PSS_PADDING| (via the |EVP_PKEY| interface) is preferred for
+ * new protocols.
*
* WARNING: this function is dangerous because it breaks the usual return value
* convention. Use |RSA_verify_raw| instead. */
@@ -386,7 +386,7 @@ OPENSSL_EXPORT int RSA_private_key_to_bytes(uint8_t **out_bytes,
* See |ex_data.h| for details. */
OPENSSL_EXPORT int RSA_get_ex_new_index(long argl, void *argp,
- CRYPTO_EX_new *new_func,
+ CRYPTO_EX_unused *unused,
CRYPTO_EX_dup *dup_func,
CRYPTO_EX_free *free_func);
OPENSSL_EXPORT int RSA_set_ex_data(RSA *r, int idx, void *arg);
diff --git a/src/include/openssl/sha.h b/src/include/openssl/sha.h
index f4253ec..48a52e8f 100644
--- a/src/include/openssl/sha.h
+++ b/src/include/openssl/sha.h
@@ -98,7 +98,7 @@ OPENSSL_EXPORT uint8_t *SHA1(const uint8_t *data, size_t len, uint8_t *out);
OPENSSL_EXPORT void SHA1_Transform(SHA_CTX *sha, const uint8_t *block);
struct sha_state_st {
-#if !defined(ANDROID)
+#if defined(OPENSSL_WINDOWS)
uint32_t h[5];
#else
/* wpa_supplicant accesses |h0|..|h4| so we must support those names
@@ -115,8 +115,8 @@ struct sha_state_st {
};
#endif
uint32_t Nl, Nh;
- uint32_t data[16];
- unsigned int num;
+ uint8_t data[SHA_CBLOCK];
+ unsigned num;
};
@@ -176,8 +176,8 @@ OPENSSL_EXPORT void SHA256_Transform(SHA256_CTX *sha, const uint8_t *data);
struct sha256_state_st {
uint32_t h[8];
uint32_t Nl, Nh;
- uint32_t data[16];
- unsigned int num, md_len;
+ uint8_t data[SHA256_CBLOCK];
+ unsigned num, md_len;
};
@@ -245,7 +245,7 @@ struct sha512_state_st {
uint64_t d[16];
uint8_t p[128];
} u;
- unsigned int num, md_len;
+ unsigned num, md_len;
};
diff --git a/src/include/openssl/ssl.h b/src/include/openssl/ssl.h
index 38d838d..dcfee91 100644
--- a/src/include/openssl/ssl.h
+++ b/src/include/openssl/ssl.h
@@ -542,23 +542,6 @@ OPENSSL_EXPORT int SSL_version(const SSL *ssl);
*
* Options configure protocol behavior. */
-/* SSL_OP_LEGACY_SERVER_CONNECT allows initial connections to servers that don't
- * support the renegotiation_info extension (RFC 5746). It is on by default. */
-#define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004L
-
-/* SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER allows for record sizes |SSL3_RT_MAX_EXTRA|
- * bytes above the maximum record size. */
-#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x00000020L
-
-/* SSL_OP_TLS_D5_BUG accepts an RSAClientKeyExchange in TLS encoded as in SSL3
- * (i.e. without a length prefix). */
-#define SSL_OP_TLS_D5_BUG 0x00000100L
-
-/* SSL_OP_ALL enables the above bug workarounds that are enabled by many
- * consumers.
- * TODO(davidben): Determine which of the remaining may be removed now. */
-#define SSL_OP_ALL 0x00000BFFL
-
/* SSL_OP_NO_QUERY_MTU, in DTLS, disables querying the MTU from the underlying
* |BIO|. Instead, the MTU is configured with |SSL_set_mtu|. */
#define SSL_OP_NO_QUERY_MTU 0x00001000L
@@ -877,15 +860,16 @@ OPENSSL_EXPORT int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa);
* input DER-encoded structures. They return one on success and zero on
* failure. */
-OPENSSL_EXPORT int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len,
- const uint8_t *d);
+OPENSSL_EXPORT int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, size_t der_len,
+ const uint8_t *der);
OPENSSL_EXPORT int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *der,
- int len);
+ size_t der_len);
OPENSSL_EXPORT int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx,
- const uint8_t *d, long len);
+ const uint8_t *der,
+ size_t der_len);
OPENSSL_EXPORT int SSL_use_PrivateKey_ASN1(int type, SSL *ssl,
- const uint8_t *d, long len);
+ const uint8_t *der, size_t der_len);
OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx,
const uint8_t *der,
@@ -1051,8 +1035,18 @@ OPENSSL_EXPORT int SSL_CIPHER_is_AESGCM(const SSL_CIPHER *cipher);
/* SSL_CIPHER_is_AES128GCM returns one if |cipher| uses 128-bit AES-GCM. */
OPENSSL_EXPORT int SSL_CIPHER_is_AES128GCM(const SSL_CIPHER *cipher);
+/* SSL_CIPHER_is_AES128CBC returns one if |cipher| uses 128-bit AES in CBC
+ * mode. */
+OPENSSL_EXPORT int SSL_CIPHER_is_AES128CBC(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_is_AES256CBC returns one if |cipher| uses 256-bit AES in CBC
+ * mode. */
+OPENSSL_EXPORT int SSL_CIPHER_is_AES256CBC(const SSL_CIPHER *cipher);
+
/* SSL_CIPHER_is_CHACHA20POLY1305 returns one if |cipher| uses
- * CHACHA20_POLY1305. */
+ * CHACHA20_POLY1305. Note this includes both the
+ * draft-ietf-tls-chacha20-poly1305-04 and draft-agl-tls-chacha20poly1305-04
+ * versions. */
OPENSSL_EXPORT int SSL_CIPHER_is_CHACHA20POLY1305(const SSL_CIPHER *cipher);
/* SSL_CIPHER_is_NULL returns one if |cipher| does not encrypt. */
@@ -1067,6 +1061,9 @@ OPENSSL_EXPORT int SSL_CIPHER_is_block_cipher(const SSL_CIPHER *cipher);
/* SSL_CIPHER_is_ECDSA returns one if |cipher| uses ECDSA. */
OPENSSL_EXPORT int SSL_CIPHER_is_ECDSA(const SSL_CIPHER *cipher);
+/* SSL_CIPHER_is_ECDHE returns one if |cipher| uses ECDHE. */
+OPENSSL_EXPORT int SSL_CIPHER_is_ECDHE(const SSL_CIPHER *cipher);
+
/* SSL_CIPHER_get_min_version returns the minimum protocol version required
* for |cipher|. */
OPENSSL_EXPORT uint16_t SSL_CIPHER_get_min_version(const SSL_CIPHER *cipher);
@@ -1157,10 +1154,9 @@ OPENSSL_EXPORT int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher,
* |kEDH|, |EDH|, |kEECDH|, and |EECDH| are legacy aliases for |kDHE|, |DHE|,
* |kECDHE|, and |ECDHE|, respectively.
*
- * |MEDIUM| and |HIGH| match ciphers historically labeled by OpenSSL as
- * 'medium' and 'high', respectively.
+ * |MEDIUM| and |HIGH| match RC4-based ciphers and all others, respectively.
*
- * |FIPS| matches ciphers historically FIPS-approved in OpenSSL.
+ * |FIPS| is an alias for |HIGH|.
*
* |SSLv3| and |TLSv1| match ciphers available in TLS 1.1 or earlier.
* |TLSv1_2| matches ciphers new in TLS 1.2. This is confusing and should not
@@ -1800,48 +1796,6 @@ OPENSSL_EXPORT int SSL_CTX_set1_curves(SSL_CTX *ctx, const int *curves,
OPENSSL_EXPORT int SSL_set1_curves(SSL *ssl, const int *curves,
size_t curves_len);
-/* SSL_CTX_set_tmp_ecdh configures |ctx| to use the curve from |ecdh| as the
- * curve for ephemeral ECDH keys. For historical reasons, this API expects an
- * |EC_KEY|, but only the curve is used. It returns one on success and zero on
- * error. If unset, an appropriate curve will be chosen based on curve
- * preferences. (This is recommended.) */
-OPENSSL_EXPORT int SSL_CTX_set_tmp_ecdh(SSL_CTX *ctx, const EC_KEY *ec_key);
-
-/* SSL_set_tmp_ecdh configures |ssl| to use the curve from |ecdh| as the curve
- * for ephemeral ECDH keys. For historical reasons, this API expects an
- * |EC_KEY|, but only the curve is used. It returns one on success and zero on
- * error. If unset, an appropriate curve will be chosen based on curve
- * preferences. (This is recommended.) */
-OPENSSL_EXPORT int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key);
-
-/* SSL_CTX_set_tmp_ecdh_callback configures |ctx| to use |callback| to determine
- * the curve for ephemeral ECDH keys. |callback| should ignore |is_export| and
- * |keylength| and return an |EC_KEY| of the selected curve or NULL on
- * error. Only the curve is used, so the |EC_KEY| needn't have a generated
- * keypair.
- *
- * If the callback is unset, an appropriate curve will be chosen based on curve
- * preferences. (This is recommended.)
- *
- * WARNING: The caller does not take ownership of the resulting |EC_KEY|, so
- * |callback| must save and release the object elsewhere. */
-OPENSSL_EXPORT void SSL_CTX_set_tmp_ecdh_callback(
- SSL_CTX *ctx, EC_KEY *(*callback)(SSL *ssl, int is_export, int keylength));
-
-/* SSL_set_tmp_ecdh_callback configures |ssl| to use |callback| to determine the
- * curve for ephemeral ECDH keys. |callback| should ignore |is_export| and
- * |keylength| and return an |EC_KEY| of the selected curve or NULL on
- * error. Only the curve is used, so the |EC_KEY| needn't have a generated
- * keypair.
- *
- * If the callback is unset, an appropriate curve will be chosen based on curve
- * preferences. (This is recommended.)
- *
- * WARNING: The caller does not take ownership of the resulting |EC_KEY|, so
- * |callback| must save and release the object elsewhere. */
-OPENSSL_EXPORT void SSL_set_tmp_ecdh_callback(
- SSL *ssl, EC_KEY *(*callback)(SSL *ssl, int is_export, int keylength));
-
/* SSL_get_curve_name returns a human-readable name for the elliptic curve
* specified by the given TLS curve id, or NULL if the curve if unknown. */
OPENSSL_EXPORT const char *SSL_get_curve_name(uint16_t curve_id);
@@ -2421,6 +2375,8 @@ DECLARE_STACK_OF(SRTP_PROTECTION_PROFILE)
#define SRTP_AES128_F8_SHA1_32 0x0004
#define SRTP_NULL_SHA1_80 0x0005
#define SRTP_NULL_SHA1_32 0x0006
+#define SRTP_AEAD_AES_128_GCM 0x0007
+#define SRTP_AEAD_AES_256_GCM 0x0008
/* SSL_CTX_set_srtp_profiles enables SRTP for all SSL objects created from
* |ctx|. |profile| contains a colon-separated list of profile names. It returns
@@ -2597,7 +2553,7 @@ OPENSSL_EXPORT const char *SSL_alert_desc_string_long(int value);
OPENSSL_EXPORT int SSL_set_ex_data(SSL *ssl, int idx, void *data);
OPENSSL_EXPORT void *SSL_get_ex_data(const SSL *ssl, int idx);
OPENSSL_EXPORT int SSL_get_ex_new_index(long argl, void *argp,
- CRYPTO_EX_new *new_func,
+ CRYPTO_EX_unused *unused,
CRYPTO_EX_dup *dup_func,
CRYPTO_EX_free *free_func);
@@ -2606,14 +2562,14 @@ OPENSSL_EXPORT int SSL_SESSION_set_ex_data(SSL_SESSION *session, int idx,
OPENSSL_EXPORT void *SSL_SESSION_get_ex_data(const SSL_SESSION *session,
int idx);
OPENSSL_EXPORT int SSL_SESSION_get_ex_new_index(long argl, void *argp,
- CRYPTO_EX_new *new_func,
+ CRYPTO_EX_unused *unused,
CRYPTO_EX_dup *dup_func,
CRYPTO_EX_free *free_func);
OPENSSL_EXPORT int SSL_CTX_set_ex_data(SSL_CTX *ctx, int idx, void *data);
OPENSSL_EXPORT void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx);
OPENSSL_EXPORT int SSL_CTX_get_ex_new_index(long argl, void *argp,
- CRYPTO_EX_new *new_func,
+ CRYPTO_EX_unused *unused,
CRYPTO_EX_dup *dup_func,
CRYPTO_EX_free *free_func);
@@ -2674,13 +2630,15 @@ OPENSSL_EXPORT void SSL_set_msg_callback(
/* SSL_set_msg_callback_arg sets the |arg| parameter of the message callback. */
OPENSSL_EXPORT void SSL_set_msg_callback_arg(SSL *ssl, void *arg);
-/* SSL_CTX_set_keylog_bio sets configures all SSL objects attached to |ctx| to
- * log session material to |keylog_bio|. This is intended for debugging use
- * with tools like Wireshark. |ctx| takes ownership of |keylog_bio|.
+/* SSL_CTX_set_keylog_callback configures a callback to log key material. This
+ * is intended for debugging use with tools like Wireshark. The |cb| function
+ * should log |line| followed by a newline, synchronizing with any concurrent
+ * access to the log.
*
* The format is described in
* https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format. */
-OPENSSL_EXPORT void SSL_CTX_set_keylog_bio(SSL_CTX *ctx, BIO *keylog_bio);
+OPENSSL_EXPORT void SSL_CTX_set_keylog_callback(
+ SSL_CTX *ctx, void (*cb)(const SSL *ssl, const char *line));
enum ssl_renegotiate_mode_t {
ssl_renegotiate_never = 0,
@@ -2748,20 +2706,6 @@ OPENSSL_EXPORT void SSL_CTX_set_max_send_fragment(SSL_CTX *ctx,
OPENSSL_EXPORT void SSL_set_max_send_fragment(SSL *ssl,
size_t max_send_fragment);
-/* OPENSSL_get_big_buffer_use_count returns the total number of invalid TLS
- * records that were accepted because of |SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER|.
- *
- * TODO(davidben): Remove this when (hopefully!) the quirk is demonstrated to be
- * unnecessary. */
-OPENSSL_EXPORT uint64_t OPENSSL_get_big_buffer_use_count(void);
-
-/* OPENSSL_get_d5_bug_use_count returns the total number of invalid RSA
- * ClientKeyExchanges that were accepted because of |SSL_OP_TLS_D5_BUG|.
- *
- * TODO(davidben): Remove this when (hopefully!) the quirk is demonstrated to be
- * unnecessary. */
-OPENSSL_EXPORT uint64_t OPENSSL_get_d5_bug_use_count(void);
-
/* ssl_early_callback_ctx is passed to certain callbacks that are called very
* early on during the server handshake. At this point, much of the SSL* hasn't
* been filled out and only the ClientHello can be depended on. */
@@ -2932,7 +2876,7 @@ OPENSSL_EXPORT void SSL_set_reject_peer_renegotiations(SSL *ssl, int reject);
* freed with |OPENSSL_free|, or NULL on error.
*
* The description includes a trailing newline and has the form:
- * AES128-SHA SSLv3 Kx=RSA Au=RSA Enc=AES(128) Mac=SHA1
+ * AES128-SHA Kx=RSA Au=RSA Enc=AES(128) Mac=SHA1
*
* Consider |SSL_CIPHER_get_name| or |SSL_CIPHER_get_rfc_name| instead. */
OPENSSL_EXPORT const char *SSL_CIPHER_description(const SSL_CIPHER *cipher,
@@ -3177,9 +3121,12 @@ DECLARE_STACK_OF(SSL_COMP)
#define SSL_MODE_RELEASE_BUFFERS 0
#define SSL_MODE_SEND_CLIENTHELLO_TIME 0
#define SSL_MODE_SEND_SERVERHELLO_TIME 0
+#define SSL_OP_ALL 0
#define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0
#define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0
#define SSL_OP_EPHEMERAL_RSA 0
+#define SSL_OP_LEGACY_SERVER_CONNECT 0
+#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0
#define SSL_OP_MICROSOFT_SESS_ID_BUG 0
#define SSL_OP_MSIE_SSLV2_RSA_PADDING 0
#define SSL_OP_NETSCAPE_CA_DN_BUG 0
@@ -3196,6 +3143,7 @@ DECLARE_STACK_OF(SSL_COMP)
#define SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0
#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0
#define SSL_OP_TLS_BLOCK_PADDING_BUG 0
+#define SSL_OP_TLS_D5_BUG 0
#define SSL_OP_TLS_ROLLBACK_BUG 0
#define SSL_VERIFY_CLIENT_ONCE 0
@@ -3347,6 +3295,14 @@ OPENSSL_EXPORT const char *SSL_state_string(const SSL *ssl);
* Use |SSL_CTX_set_quiet_shutdown| instead. */
OPENSSL_EXPORT void SSL_set_shutdown(SSL *ssl, int mode);
+/* SSL_CTX_set_tmp_ecdh calls |SSL_CTX_set1_curves| with a one-element list
+ * containing |ec_key|'s curve. */
+OPENSSL_EXPORT int SSL_CTX_set_tmp_ecdh(SSL_CTX *ctx, const EC_KEY *ec_key);
+
+/* SSL_set_tmp_ecdh calls |SSL_set1_curves| with a one-element list containing
+ * |ec_key|'s curve. */
+OPENSSL_EXPORT int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key);
+
/* Private structures.
*
@@ -3363,22 +3319,20 @@ struct ssl_cipher_st {
/* id is the cipher suite value bitwise OR-d with 0x03000000. */
uint32_t id;
- /* The following are internal fields. See ssl/internal.h for their values. */
-
+ /* algorithm_* are internal fields. See ssl/internal.h for their values. */
uint32_t algorithm_mkey;
uint32_t algorithm_auth;
uint32_t algorithm_enc;
uint32_t algorithm_mac;
- uint32_t algorithm_ssl;
- uint32_t algo_strength;
uint32_t algorithm_prf;
-
- /* strength_bits is the strength of the cipher in bits. */
- int strength_bits;
- /* alg_bits is the number of bits of key material used by the algorithm. */
- int alg_bits;
};
+typedef struct ssl_ecdh_method_st SSL_ECDH_METHOD;
+typedef struct ssl_ecdh_ctx_st {
+ const SSL_ECDH_METHOD *method;
+ void *data;
+} SSL_ECDH_CTX;
+
#define SSL_MAX_SSL_SESSION_ID_LENGTH 32
#define SSL_MAX_SID_CTX_LENGTH 32
#define SSL_MAX_MASTER_KEY_LENGTH 48
@@ -3729,9 +3683,9 @@ struct ssl_ctx_st {
uint8_t *ocsp_response;
size_t ocsp_response_length;
- /* If not NULL, session key material will be logged to this BIO for debugging
- * purposes. The format matches NSS's and is readable by Wireshark. */
- BIO *keylog_bio;
+ /* keylog_callback, if not NULL, is the key logging callback. See
+ * |SSL_CTX_set_keylog_callback|. */
+ void (*keylog_callback)(const SSL *ssl, const char *line);
/* current_time_cb, if not NULL, is the function to use to get the current
* time. It sets |*out_clock| to the current time. */
@@ -3951,12 +3905,9 @@ struct ssl_st {
typedef struct ssl3_record_st {
/* type is the record type. */
uint8_t type;
- /* length is the number of unconsumed bytes of |data|. */
+ /* length is the number of unconsumed bytes in the record. */
uint16_t length;
- /* off is the number of consumed bytes of |data|. */
- uint16_t off;
- /* data is a non-owning pointer to the record contents. The total length of
- * the buffer is |off| + |length|. */
+ /* data is a non-owning pointer to the first unconsumed byte of the record. */
uint8_t *data;
} SSL3_RECORD;
@@ -3971,26 +3922,13 @@ typedef struct ssl3_buffer_st {
uint16_t cap;
} SSL3_BUFFER;
-/* TODO(davidben): This flag can probably be merged into s3->change_cipher_spec
- * to something tri-state. (Normal / Expect CCS / Between CCS and Finished). */
-#define SSL3_FLAGS_EXPECT_CCS 0x0080
-
typedef struct ssl3_state_st {
- long flags;
-
uint8_t read_sequence[8];
- int read_mac_secret_size;
- uint8_t read_mac_secret[EVP_MAX_MD_SIZE];
uint8_t write_sequence[8];
- int write_mac_secret_size;
- uint8_t write_mac_secret[EVP_MAX_MD_SIZE];
uint8_t server_random[SSL3_RANDOM_SIZE];
uint8_t client_random[SSL3_RANDOM_SIZE];
- /* flags for countermeasure against known-IV weakness */
- int need_record_splitting;
-
/* have_version is true if the connection's final version is known. Otherwise
* the version has not been negotiated yet. */
char have_version;
@@ -4006,10 +3944,9 @@ typedef struct ssl3_state_st {
SSL3_RECORD rrec; /* each decoded record goes in here */
- /* storage for Handshake protocol data received but not yet processed by
- * ssl3_read_bytes: */
- uint8_t handshake_fragment[4];
- unsigned int handshake_fragment_len;
+ /* hello_request_len is the number of bytes of HelloRequest received, possibly
+ * split over multiple records. */
+ uint8_t hello_request_len;
/* partial write - check the numbers match */
unsigned int wnum; /* number of bytes sent so far */
@@ -4027,10 +3964,6 @@ typedef struct ssl3_state_st {
* the handshake hash for TLS 1.1 and below. */
EVP_MD_CTX handshake_md5;
- /* this is set whenerver we see a change_cipher_spec message come in when we
- * are not looking for one */
- int change_cipher_spec;
-
int warn_alert;
int fatal_alert;
/* we allow one fatal and one warning alert to be outstanding, send close
@@ -4053,10 +3986,9 @@ typedef struct ssl3_state_st {
* pending handshake state here so it can be managed separately from
* established connection state in case of renegotiations. */
struct {
- /* actually only need to be 16+20 for SSLv3 and 12 for TLS */
- uint8_t finish_md[EVP_MAX_MD_SIZE * 2];
+ uint8_t finish_md[EVP_MAX_MD_SIZE];
int finish_md_len;
- uint8_t peer_finish_md[EVP_MAX_MD_SIZE * 2];
+ uint8_t peer_finish_md[EVP_MAX_MD_SIZE];
int peer_finish_md_len;
unsigned long message_size;
@@ -4064,9 +3996,6 @@ typedef struct ssl3_state_st {
/* used to hold the new cipher we are going to use */
const SSL_CIPHER *new_cipher;
- DH *dh;
-
- EC_KEY *ecdh; /* holds short lived ECDH key */
/* used when SSL_ST_FLUSH_DATA is entered */
int next_state;
@@ -4167,11 +4096,12 @@ typedef struct ssl3_state_st {
* |TLSEXT_hash_none|. */
uint8_t server_key_exchange_hash;
- /* peer_dh_tmp, on a client, is the server's DHE public key. */
- DH *peer_dh_tmp;
+ /* ecdh_ctx is the current ECDH instance. */
+ SSL_ECDH_CTX ecdh_ctx;
- /* peer_ecdh_tmp, on a client, is the server's ECDHE public key. */
- EC_KEY *peer_ecdh_tmp;
+ /* peer_key is the peer's ECDH key. */
+ uint8_t *peer_key;
+ uint16_t peer_key_len;
} tmp;
/* Connection binding to prevent renegotiation attacks */
@@ -4367,184 +4297,147 @@ OPENSSL_EXPORT int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method);
#define SSL_R_BAD_DIGEST_LENGTH 106
#define SSL_R_BAD_ECC_CERT 107
#define SSL_R_BAD_ECPOINT 108
-#define SSL_R_BAD_HANDSHAKE_LENGTH 109
-#define SSL_R_BAD_HANDSHAKE_RECORD 110
-#define SSL_R_BAD_HELLO_REQUEST 111
-#define SSL_R_BAD_LENGTH 112
-#define SSL_R_BAD_PACKET_LENGTH 113
-#define SSL_R_BAD_RSA_ENCRYPT 114
-#define SSL_R_BAD_SIGNATURE 115
-#define SSL_R_BAD_SRTP_MKI_VALUE 116
-#define SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST 117
-#define SSL_R_BAD_SSL_FILETYPE 118
-#define SSL_R_BAD_WRITE_RETRY 119
-#define SSL_R_BIO_NOT_SET 120
-#define SSL_R_BN_LIB 121
-#define SSL_R_CANNOT_SERIALIZE_PUBLIC_KEY 122
-#define SSL_R_CA_DN_LENGTH_MISMATCH 123
-#define SSL_R_CA_DN_TOO_LONG 124
-#define SSL_R_CCS_RECEIVED_EARLY 125
-#define SSL_R_CERTIFICATE_VERIFY_FAILED 126
-#define SSL_R_CERT_CB_ERROR 127
-#define SSL_R_CERT_LENGTH_MISMATCH 128
-#define SSL_R_CHANNEL_ID_NOT_P256 129
-#define SSL_R_CHANNEL_ID_SIGNATURE_INVALID 130
-#define SSL_R_CIPHER_CODE_WRONG_LENGTH 131
-#define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 132
-#define SSL_R_CLIENTHELLO_PARSE_FAILED 133
-#define SSL_R_CLIENTHELLO_TLSEXT 134
-#define SSL_R_CONNECTION_REJECTED 135
-#define SSL_R_CONNECTION_TYPE_NOT_SET 136
-#define SSL_R_COOKIE_MISMATCH 137
-#define SSL_R_D2I_ECDSA_SIG 138
-#define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED 139
-#define SSL_R_DATA_LENGTH_TOO_LONG 140
-#define SSL_R_DECODE_ERROR 141
-#define SSL_R_DECRYPTION_FAILED 142
-#define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 143
-#define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 144
-#define SSL_R_DIGEST_CHECK_FAILED 145
-#define SSL_R_DTLS_MESSAGE_TOO_BIG 146
-#define SSL_R_ECC_CERT_NOT_FOR_SIGNING 147
-#define SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST 148
-#define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 149
-#define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 150
-#define SSL_R_EVP_DIGESTSIGNFINAL_FAILED 151
-#define SSL_R_EVP_DIGESTSIGNINIT_FAILED 152
-#define SSL_R_EXCESSIVE_MESSAGE_SIZE 153
-#define SSL_R_EXTRA_DATA_IN_MESSAGE 154
-#define SSL_R_GOT_A_FIN_BEFORE_A_CCS 155
-#define SSL_R_GOT_CHANNEL_ID_BEFORE_A_CCS 156
-#define SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS 157
-#define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION 158
-#define SSL_R_HANDSHAKE_FAILURE_ON_CLIENT_HELLO 159
-#define SSL_R_HANDSHAKE_RECORD_BEFORE_CCS 160
-#define SSL_R_HTTPS_PROXY_REQUEST 161
-#define SSL_R_HTTP_REQUEST 162
-#define SSL_R_INAPPROPRIATE_FALLBACK 163
-#define SSL_R_INVALID_COMMAND 164
-#define SSL_R_INVALID_MESSAGE 165
-#define SSL_R_INVALID_SSL_SESSION 166
-#define SSL_R_INVALID_TICKET_KEYS_LENGTH 167
-#define SSL_R_LENGTH_MISMATCH 168
-#define SSL_R_LIBRARY_HAS_NO_CIPHERS 169
-#define SSL_R_MISSING_DH_KEY 170
-#define SSL_R_MISSING_ECDSA_SIGNING_CERT 171
-#define SSL_R_MISSING_RSA_CERTIFICATE 172
-#define SSL_R_MISSING_RSA_ENCRYPTING_CERT 173
-#define SSL_R_MISSING_RSA_SIGNING_CERT 174
-#define SSL_R_MISSING_TMP_DH_KEY 175
-#define SSL_R_MISSING_TMP_ECDH_KEY 176
-#define SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS 177
-#define SSL_R_MTU_TOO_SMALL 178
-#define SSL_R_NESTED_GROUP 179
-#define SSL_R_NO_CERTIFICATES_RETURNED 180
-#define SSL_R_NO_CERTIFICATE_ASSIGNED 181
-#define SSL_R_NO_CERTIFICATE_SET 182
-#define SSL_R_NO_CIPHERS_AVAILABLE 183
-#define SSL_R_NO_CIPHERS_PASSED 184
-#define SSL_R_NO_CIPHERS_SPECIFIED 185
-#define SSL_R_NO_CIPHER_MATCH 186
-#define SSL_R_NO_COMPRESSION_SPECIFIED 187
-#define SSL_R_NO_METHOD_SPECIFIED 188
-#define SSL_R_NO_P256_SUPPORT 189
-#define SSL_R_NO_PRIVATE_KEY_ASSIGNED 190
-#define SSL_R_NO_RENEGOTIATION 191
-#define SSL_R_NO_REQUIRED_DIGEST 192
-#define SSL_R_NO_SHARED_CIPHER 193
-#define SSL_R_NO_SHARED_SIGATURE_ALGORITHMS 194
-#define SSL_R_NO_SRTP_PROFILES 195
-#define SSL_R_NULL_SSL_CTX 196
-#define SSL_R_NULL_SSL_METHOD_PASSED 197
-#define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 198
-#define SSL_R_PACKET_LENGTH_TOO_LONG 199
-#define SSL_R_PARSE_TLSEXT 200
-#define SSL_R_PATH_TOO_LONG 201
-#define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 202
-#define SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE 203
-#define SSL_R_PROTOCOL_IS_SHUTDOWN 204
-#define SSL_R_PSK_IDENTITY_NOT_FOUND 205
-#define SSL_R_PSK_NO_CLIENT_CB 206
-#define SSL_R_PSK_NO_SERVER_CB 207
-#define SSL_R_READ_BIO_NOT_SET 208
-#define SSL_R_READ_TIMEOUT_EXPIRED 209
-#define SSL_R_RECORD_LENGTH_MISMATCH 210
-#define SSL_R_RECORD_TOO_LARGE 211
-#define SSL_R_RENEGOTIATE_EXT_TOO_LONG 212
-#define SSL_R_RENEGOTIATION_ENCODING_ERR 213
-#define SSL_R_RENEGOTIATION_MISMATCH 214
-#define SSL_R_REQUIRED_CIPHER_MISSING 215
-#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 216
-#define SSL_R_SERVERHELLO_TLSEXT 217
-#define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 218
-#define SSL_R_SESSION_MAY_NOT_BE_CREATED 219
-#define SSL_R_SIGNATURE_ALGORITHMS_ERROR 220
-#define SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES 221
-#define SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG 222
-#define SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE 223
-#define SSL_R_SSL3_EXT_INVALID_SERVERNAME 224
-#define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE 225
-#define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION 226
-#define SSL_R_SSL_HANDSHAKE_FAILURE 227
-#define SSL_R_SSL_SESSION_ID_CALLBACK_FAILED 228
-#define SSL_R_SSL_SESSION_ID_CONFLICT 229
-#define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG 230
-#define SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH 231
-#define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER 232
-#define SSL_R_TLS_ILLEGAL_EXPORTER_LABEL 233
-#define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST 234
-#define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 235
-#define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG 236
-#define SSL_R_TOO_MANY_EMPTY_FRAGMENTS 237
-#define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS 238
-#define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS 239
-#define SSL_R_UNEXPECTED_GROUP_CLOSE 240
-#define SSL_R_UNEXPECTED_MESSAGE 241
-#define SSL_R_UNEXPECTED_OPERATOR_IN_GROUP 242
-#define SSL_R_UNEXPECTED_RECORD 243
-#define SSL_R_UNINITIALIZED 244
-#define SSL_R_UNKNOWN_ALERT_TYPE 245
-#define SSL_R_UNKNOWN_CERTIFICATE_TYPE 246
-#define SSL_R_UNKNOWN_CIPHER_RETURNED 247
-#define SSL_R_UNKNOWN_CIPHER_TYPE 248
-#define SSL_R_UNKNOWN_DIGEST 249
-#define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 250
-#define SSL_R_UNKNOWN_PROTOCOL 251
-#define SSL_R_UNKNOWN_SSL_VERSION 252
-#define SSL_R_UNKNOWN_STATE 253
-#define SSL_R_UNPROCESSED_HANDSHAKE_DATA 254
-#define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED 255
-#define SSL_R_UNSUPPORTED_CIPHER 256
-#define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 257
-#define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE 258
-#define SSL_R_UNSUPPORTED_PROTOCOL 259
-#define SSL_R_UNSUPPORTED_SSL_VERSION 260
-#define SSL_R_USE_SRTP_NOT_NEGOTIATED 261
-#define SSL_R_WRONG_CERTIFICATE_TYPE 262
-#define SSL_R_WRONG_CIPHER_RETURNED 263
-#define SSL_R_WRONG_CURVE 264
-#define SSL_R_WRONG_MESSAGE_TYPE 265
-#define SSL_R_WRONG_SIGNATURE_TYPE 266
-#define SSL_R_WRONG_SSL_VERSION 267
-#define SSL_R_WRONG_VERSION_NUMBER 268
-#define SSL_R_X509_LIB 269
-#define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS 270
-#define SSL_R_FRAGMENT_MISMATCH 271
-#define SSL_R_BUFFER_TOO_SMALL 272
-#define SSL_R_OLD_SESSION_VERSION_NOT_RETURNED 273
-#define SSL_R_OUTPUT_ALIASES_INPUT 274
-#define SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION 275
-#define SSL_R_EMS_STATE_INCONSISTENT 276
-#define SSL_R_RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION 277
-#define SSL_R_TOO_MANY_WARNING_ALERTS 278
-#define SSL_R_UNEXPECTED_EXTENSION 279
-#define SSL_R_SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER 280
-#define SSL_R_ERROR_ADDING_EXTENSION 281
-#define SSL_R_ERROR_PARSING_EXTENSION 282
-#define SSL_R_MISSING_EXTENSION 283
-#define SSL_R_CUSTOM_EXTENSION_CONTENTS_TOO_LARGE 284
-#define SSL_R_CUSTOM_EXTENSION_ERROR 285
-#define SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN 286
+#define SSL_R_BAD_HANDSHAKE_RECORD 109
+#define SSL_R_BAD_HELLO_REQUEST 110
+#define SSL_R_BAD_LENGTH 111
+#define SSL_R_BAD_PACKET_LENGTH 112
+#define SSL_R_BAD_RSA_ENCRYPT 113
+#define SSL_R_BAD_SIGNATURE 114
+#define SSL_R_BAD_SRTP_MKI_VALUE 115
+#define SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST 116
+#define SSL_R_BAD_SSL_FILETYPE 117
+#define SSL_R_BAD_WRITE_RETRY 118
+#define SSL_R_BIO_NOT_SET 119
+#define SSL_R_BN_LIB 120
+#define SSL_R_BUFFER_TOO_SMALL 121
+#define SSL_R_CA_DN_LENGTH_MISMATCH 122
+#define SSL_R_CA_DN_TOO_LONG 123
+#define SSL_R_CCS_RECEIVED_EARLY 124
+#define SSL_R_CERTIFICATE_VERIFY_FAILED 125
+#define SSL_R_CERT_CB_ERROR 126
+#define SSL_R_CERT_LENGTH_MISMATCH 127
+#define SSL_R_CHANNEL_ID_NOT_P256 128
+#define SSL_R_CHANNEL_ID_SIGNATURE_INVALID 129
+#define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 130
+#define SSL_R_CLIENTHELLO_PARSE_FAILED 131
+#define SSL_R_CLIENTHELLO_TLSEXT 132
+#define SSL_R_CONNECTION_REJECTED 133
+#define SSL_R_CONNECTION_TYPE_NOT_SET 134
+#define SSL_R_CUSTOM_EXTENSION_ERROR 135
+#define SSL_R_DATA_LENGTH_TOO_LONG 136
+#define SSL_R_DECODE_ERROR 137
+#define SSL_R_DECRYPTION_FAILED 138
+#define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 139
+#define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 140
+#define SSL_R_DH_P_TOO_LONG 141
+#define SSL_R_DIGEST_CHECK_FAILED 142
+#define SSL_R_DTLS_MESSAGE_TOO_BIG 143
+#define SSL_R_ECC_CERT_NOT_FOR_SIGNING 144
+#define SSL_R_EMS_STATE_INCONSISTENT 145
+#define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 146
+#define SSL_R_ERROR_ADDING_EXTENSION 147
+#define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 148
+#define SSL_R_ERROR_PARSING_EXTENSION 149
+#define SSL_R_EXCESSIVE_MESSAGE_SIZE 150
+#define SSL_R_EXTRA_DATA_IN_MESSAGE 151
+#define SSL_R_FRAGMENT_MISMATCH 152
+#define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION 153
+#define SSL_R_HANDSHAKE_FAILURE_ON_CLIENT_HELLO 154
+#define SSL_R_HTTPS_PROXY_REQUEST 155
+#define SSL_R_HTTP_REQUEST 156
+#define SSL_R_INAPPROPRIATE_FALLBACK 157
+#define SSL_R_INVALID_COMMAND 158
+#define SSL_R_INVALID_MESSAGE 159
+#define SSL_R_INVALID_SSL_SESSION 160
+#define SSL_R_INVALID_TICKET_KEYS_LENGTH 161
+#define SSL_R_LENGTH_MISMATCH 162
+#define SSL_R_LIBRARY_HAS_NO_CIPHERS 163
+#define SSL_R_MISSING_EXTENSION 164
+#define SSL_R_MISSING_RSA_CERTIFICATE 165
+#define SSL_R_MISSING_TMP_DH_KEY 166
+#define SSL_R_MISSING_TMP_ECDH_KEY 167
+#define SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS 168
+#define SSL_R_MTU_TOO_SMALL 169
+#define SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN 170
+#define SSL_R_NESTED_GROUP 171
+#define SSL_R_NO_CERTIFICATES_RETURNED 172
+#define SSL_R_NO_CERTIFICATE_ASSIGNED 173
+#define SSL_R_NO_CERTIFICATE_SET 174
+#define SSL_R_NO_CIPHERS_AVAILABLE 175
+#define SSL_R_NO_CIPHERS_PASSED 176
+#define SSL_R_NO_CIPHER_MATCH 177
+#define SSL_R_NO_COMPRESSION_SPECIFIED 178
+#define SSL_R_NO_METHOD_SPECIFIED 179
+#define SSL_R_NO_P256_SUPPORT 180
+#define SSL_R_NO_PRIVATE_KEY_ASSIGNED 181
+#define SSL_R_NO_RENEGOTIATION 182
+#define SSL_R_NO_REQUIRED_DIGEST 183
+#define SSL_R_NO_SHARED_CIPHER 184
+#define SSL_R_NULL_SSL_CTX 185
+#define SSL_R_NULL_SSL_METHOD_PASSED 186
+#define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 187
+#define SSL_R_OLD_SESSION_VERSION_NOT_RETURNED 188
+#define SSL_R_OUTPUT_ALIASES_INPUT 189
+#define SSL_R_PARSE_TLSEXT 190
+#define SSL_R_PATH_TOO_LONG 191
+#define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 192
+#define SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE 193
+#define SSL_R_PROTOCOL_IS_SHUTDOWN 194
+#define SSL_R_PSK_IDENTITY_NOT_FOUND 195
+#define SSL_R_PSK_NO_CLIENT_CB 196
+#define SSL_R_PSK_NO_SERVER_CB 197
+#define SSL_R_READ_TIMEOUT_EXPIRED 198
+#define SSL_R_RECORD_LENGTH_MISMATCH 199
+#define SSL_R_RECORD_TOO_LARGE 200
+#define SSL_R_RENEGOTIATION_ENCODING_ERR 201
+#define SSL_R_RENEGOTIATION_MISMATCH 202
+#define SSL_R_REQUIRED_CIPHER_MISSING 203
+#define SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION 204
+#define SSL_R_RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION 205
+#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 206
+#define SSL_R_SERVERHELLO_TLSEXT 207
+#define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 208
+#define SSL_R_SESSION_MAY_NOT_BE_CREATED 209
+#define SSL_R_SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER 210
+#define SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES 211
+#define SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE 212
+#define SSL_R_SSL3_EXT_INVALID_SERVERNAME 213
+#define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION 214
+#define SSL_R_SSL_HANDSHAKE_FAILURE 215
+#define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG 216
+#define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 217
+#define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG 218
+#define SSL_R_TOO_MANY_EMPTY_FRAGMENTS 219
+#define SSL_R_TOO_MANY_WARNING_ALERTS 220
+#define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS 221
+#define SSL_R_UNEXPECTED_EXTENSION 222
+#define SSL_R_UNEXPECTED_MESSAGE 223
+#define SSL_R_UNEXPECTED_OPERATOR_IN_GROUP 224
+#define SSL_R_UNEXPECTED_RECORD 225
+#define SSL_R_UNINITIALIZED 226
+#define SSL_R_UNKNOWN_ALERT_TYPE 227
+#define SSL_R_UNKNOWN_CERTIFICATE_TYPE 228
+#define SSL_R_UNKNOWN_CIPHER_RETURNED 229
+#define SSL_R_UNKNOWN_CIPHER_TYPE 230
+#define SSL_R_UNKNOWN_DIGEST 231
+#define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 232
+#define SSL_R_UNKNOWN_PROTOCOL 233
+#define SSL_R_UNKNOWN_SSL_VERSION 234
+#define SSL_R_UNKNOWN_STATE 235
+#define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED 236
+#define SSL_R_UNSUPPORTED_CIPHER 237
+#define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 238
+#define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE 239
+#define SSL_R_UNSUPPORTED_PROTOCOL 240
+#define SSL_R_WRONG_CERTIFICATE_TYPE 241
+#define SSL_R_WRONG_CIPHER_RETURNED 242
+#define SSL_R_WRONG_CURVE 243
+#define SSL_R_WRONG_MESSAGE_TYPE 244
+#define SSL_R_WRONG_SIGNATURE_TYPE 245
+#define SSL_R_WRONG_SSL_VERSION 246
+#define SSL_R_WRONG_VERSION_NUMBER 247
+#define SSL_R_X509_LIB 248
+#define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS 249
#define SSL_R_SSLV3_ALERT_CLOSE_NOTIFY 1000
#define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010
#define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020
diff --git a/src/include/openssl/ssl3.h b/src/include/openssl/ssl3.h
index 0d013d5..957b740 100644
--- a/src/include/openssl/ssl3.h
+++ b/src/include/openssl/ssl3.h
@@ -231,8 +231,6 @@ extern "C" {
#define SSL_RT_MAX_CIPHER_BLOCK_SIZE 16
-#define SSL3_RT_MAX_EXTRA (16384)
-
/* Maximum plaintext length: defined by SSL/TLS standards */
#define SSL3_RT_MAX_PLAIN_LENGTH 16384
/* Maximum compression overhead: defined by SSL/TLS standards */
diff --git a/src/include/openssl/stack.h b/src/include/openssl/stack.h
index b600b43..16b9f4f 100644
--- a/src/include/openssl/stack.h
+++ b/src/include/openssl/stack.h
@@ -134,9 +134,6 @@ typedef struct stack_st {
* STACK_OF:GENERAL_NAME
* STACK_OF:GENERAL_NAMES
* STACK_OF:GENERAL_SUBTREE
- * STACK_OF:MIME_HEADER
- * STACK_OF:PKCS7_RECIP_INFO
- * STACK_OF:PKCS7_SIGNER_INFO
* STACK_OF:POLICYINFO
* STACK_OF:POLICYQUALINFO
* STACK_OF:POLICY_MAPPING
diff --git a/src/include/openssl/stack_macros.h b/src/include/openssl/stack_macros.h
index 08097af..809424c 100644
--- a/src/include/openssl/stack_macros.h
+++ b/src/include/openssl/stack_macros.h
@@ -1430,262 +1430,6 @@
copy_func), \
CHECKED_CAST(void (*)(void *), void (*)(GENERAL_SUBTREE *), free_func)))
-/* MIME_HEADER */
-#define sk_MIME_HEADER_new(comp) \
- ((STACK_OF(MIME_HEADER) *)sk_new(CHECKED_CAST( \
- stack_cmp_func, int (*)(const MIME_HEADER **a, const MIME_HEADER **b), \
- comp)))
-
-#define sk_MIME_HEADER_new_null() ((STACK_OF(MIME_HEADER) *)sk_new_null())
-
-#define sk_MIME_HEADER_num(sk) \
- sk_num(CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk))
-
-#define sk_MIME_HEADER_zero(sk) \
- sk_zero(CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk));
-
-#define sk_MIME_HEADER_value(sk, i) \
- ((MIME_HEADER *)sk_value( \
- CHECKED_CAST(_STACK *, const STACK_OF(MIME_HEADER) *, sk), (i)))
-
-#define sk_MIME_HEADER_set(sk, i, p) \
- ((MIME_HEADER *)sk_set(CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk), \
- (i), CHECKED_CAST(void *, MIME_HEADER *, p)))
-
-#define sk_MIME_HEADER_free(sk) \
- sk_free(CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk))
-
-#define sk_MIME_HEADER_pop_free(sk, free_func) \
- sk_pop_free( \
- CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk), \
- CHECKED_CAST(void (*)(void *), void (*)(MIME_HEADER *), free_func))
-
-#define sk_MIME_HEADER_insert(sk, p, where) \
- sk_insert(CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk), \
- CHECKED_CAST(void *, MIME_HEADER *, p), (where))
-
-#define sk_MIME_HEADER_delete(sk, where) \
- ((MIME_HEADER *)sk_delete( \
- CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk), (where)))
-
-#define sk_MIME_HEADER_delete_ptr(sk, p) \
- ((MIME_HEADER *)sk_delete_ptr( \
- CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk), \
- CHECKED_CAST(void *, MIME_HEADER *, p)))
-
-#define sk_MIME_HEADER_find(sk, out_index, p) \
- sk_find(CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk), (out_index), \
- CHECKED_CAST(void *, MIME_HEADER *, p))
-
-#define sk_MIME_HEADER_shift(sk) \
- ((MIME_HEADER *)sk_shift(CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk)))
-
-#define sk_MIME_HEADER_push(sk, p) \
- sk_push(CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk), \
- CHECKED_CAST(void *, MIME_HEADER *, p))
-
-#define sk_MIME_HEADER_pop(sk) \
- ((MIME_HEADER *)sk_pop(CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk)))
-
-#define sk_MIME_HEADER_dup(sk) \
- ((STACK_OF(MIME_HEADER) *)sk_dup( \
- CHECKED_CAST(_STACK *, const STACK_OF(MIME_HEADER) *, sk)))
-
-#define sk_MIME_HEADER_sort(sk) \
- sk_sort(CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk))
-
-#define sk_MIME_HEADER_is_sorted(sk) \
- sk_is_sorted(CHECKED_CAST(_STACK *, const STACK_OF(MIME_HEADER) *, sk))
-
-#define sk_MIME_HEADER_set_cmp_func(sk, comp) \
- ((int (*)(const MIME_HEADER **a, const MIME_HEADER **b))sk_set_cmp_func( \
- CHECKED_CAST(_STACK *, STACK_OF(MIME_HEADER) *, sk), \
- CHECKED_CAST(stack_cmp_func, \
- int (*)(const MIME_HEADER **a, const MIME_HEADER **b), \
- comp)))
-
-#define sk_MIME_HEADER_deep_copy(sk, copy_func, free_func) \
- ((STACK_OF(MIME_HEADER) *)sk_deep_copy( \
- CHECKED_CAST(const _STACK *, const STACK_OF(MIME_HEADER) *, sk), \
- CHECKED_CAST(void *(*)(void *), MIME_HEADER *(*)(MIME_HEADER *), \
- copy_func), \
- CHECKED_CAST(void (*)(void *), void (*)(MIME_HEADER *), free_func)))
-
-/* PKCS7_RECIP_INFO */
-#define sk_PKCS7_RECIP_INFO_new(comp) \
- ((STACK_OF(PKCS7_RECIP_INFO) *)sk_new(CHECKED_CAST( \
- stack_cmp_func, \
- int (*)(const PKCS7_RECIP_INFO **a, const PKCS7_RECIP_INFO **b), comp)))
-
-#define sk_PKCS7_RECIP_INFO_new_null() \
- ((STACK_OF(PKCS7_RECIP_INFO) *)sk_new_null())
-
-#define sk_PKCS7_RECIP_INFO_num(sk) \
- sk_num(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk))
-
-#define sk_PKCS7_RECIP_INFO_zero(sk) \
- sk_zero(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk));
-
-#define sk_PKCS7_RECIP_INFO_value(sk, i) \
- ((PKCS7_RECIP_INFO *)sk_value( \
- CHECKED_CAST(_STACK *, const STACK_OF(PKCS7_RECIP_INFO) *, sk), (i)))
-
-#define sk_PKCS7_RECIP_INFO_set(sk, i, p) \
- ((PKCS7_RECIP_INFO *)sk_set( \
- CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), (i), \
- CHECKED_CAST(void *, PKCS7_RECIP_INFO *, p)))
-
-#define sk_PKCS7_RECIP_INFO_free(sk) \
- sk_free(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk))
-
-#define sk_PKCS7_RECIP_INFO_pop_free(sk, free_func) \
- sk_pop_free( \
- CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), \
- CHECKED_CAST(void (*)(void *), void (*)(PKCS7_RECIP_INFO *), free_func))
-
-#define sk_PKCS7_RECIP_INFO_insert(sk, p, where) \
- sk_insert(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), \
- CHECKED_CAST(void *, PKCS7_RECIP_INFO *, p), (where))
-
-#define sk_PKCS7_RECIP_INFO_delete(sk, where) \
- ((PKCS7_RECIP_INFO *)sk_delete( \
- CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), (where)))
-
-#define sk_PKCS7_RECIP_INFO_delete_ptr(sk, p) \
- ((PKCS7_RECIP_INFO *)sk_delete_ptr( \
- CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), \
- CHECKED_CAST(void *, PKCS7_RECIP_INFO *, p)))
-
-#define sk_PKCS7_RECIP_INFO_find(sk, out_index, p) \
- sk_find(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), \
- (out_index), CHECKED_CAST(void *, PKCS7_RECIP_INFO *, p))
-
-#define sk_PKCS7_RECIP_INFO_shift(sk) \
- ((PKCS7_RECIP_INFO *)sk_shift( \
- CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk)))
-
-#define sk_PKCS7_RECIP_INFO_push(sk, p) \
- sk_push(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), \
- CHECKED_CAST(void *, PKCS7_RECIP_INFO *, p))
-
-#define sk_PKCS7_RECIP_INFO_pop(sk) \
- ((PKCS7_RECIP_INFO *)sk_pop( \
- CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk)))
-
-#define sk_PKCS7_RECIP_INFO_dup(sk) \
- ((STACK_OF(PKCS7_RECIP_INFO) *)sk_dup( \
- CHECKED_CAST(_STACK *, const STACK_OF(PKCS7_RECIP_INFO) *, sk)))
-
-#define sk_PKCS7_RECIP_INFO_sort(sk) \
- sk_sort(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk))
-
-#define sk_PKCS7_RECIP_INFO_is_sorted(sk) \
- sk_is_sorted(CHECKED_CAST(_STACK *, const STACK_OF(PKCS7_RECIP_INFO) *, sk))
-
-#define sk_PKCS7_RECIP_INFO_set_cmp_func(sk, comp) \
- ((int (*)(const PKCS7_RECIP_INFO **a, const PKCS7_RECIP_INFO **b)) \
- sk_set_cmp_func( \
- CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), \
- CHECKED_CAST(stack_cmp_func, int (*)(const PKCS7_RECIP_INFO **a, \
- const PKCS7_RECIP_INFO **b), \
- comp)))
-
-#define sk_PKCS7_RECIP_INFO_deep_copy(sk, copy_func, free_func) \
- ((STACK_OF(PKCS7_RECIP_INFO) *)sk_deep_copy( \
- CHECKED_CAST(const _STACK *, const STACK_OF(PKCS7_RECIP_INFO) *, sk), \
- CHECKED_CAST(void *(*)(void *), \
- PKCS7_RECIP_INFO *(*)(PKCS7_RECIP_INFO *), copy_func), \
- CHECKED_CAST(void (*)(void *), void (*)(PKCS7_RECIP_INFO *), \
- free_func)))
-
-/* PKCS7_SIGNER_INFO */
-#define sk_PKCS7_SIGNER_INFO_new(comp) \
- ((STACK_OF(PKCS7_SIGNER_INFO) *)sk_new(CHECKED_CAST( \
- stack_cmp_func, \
- int (*)(const PKCS7_SIGNER_INFO **a, const PKCS7_SIGNER_INFO **b), \
- comp)))
-
-#define sk_PKCS7_SIGNER_INFO_new_null() \
- ((STACK_OF(PKCS7_SIGNER_INFO) *)sk_new_null())
-
-#define sk_PKCS7_SIGNER_INFO_num(sk) \
- sk_num(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk))
-
-#define sk_PKCS7_SIGNER_INFO_zero(sk) \
- sk_zero(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk));
-
-#define sk_PKCS7_SIGNER_INFO_value(sk, i) \
- ((PKCS7_SIGNER_INFO *)sk_value( \
- CHECKED_CAST(_STACK *, const STACK_OF(PKCS7_SIGNER_INFO) *, sk), (i)))
-
-#define sk_PKCS7_SIGNER_INFO_set(sk, i, p) \
- ((PKCS7_SIGNER_INFO *)sk_set( \
- CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk), (i), \
- CHECKED_CAST(void *, PKCS7_SIGNER_INFO *, p)))
-
-#define sk_PKCS7_SIGNER_INFO_free(sk) \
- sk_free(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk))
-
-#define sk_PKCS7_SIGNER_INFO_pop_free(sk, free_func) \
- sk_pop_free(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk), \
- CHECKED_CAST(void (*)(void *), void (*)(PKCS7_SIGNER_INFO *), \
- free_func))
-
-#define sk_PKCS7_SIGNER_INFO_insert(sk, p, where) \
- sk_insert(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk), \
- CHECKED_CAST(void *, PKCS7_SIGNER_INFO *, p), (where))
-
-#define sk_PKCS7_SIGNER_INFO_delete(sk, where) \
- ((PKCS7_SIGNER_INFO *)sk_delete( \
- CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk), (where)))
-
-#define sk_PKCS7_SIGNER_INFO_delete_ptr(sk, p) \
- ((PKCS7_SIGNER_INFO *)sk_delete_ptr( \
- CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk), \
- CHECKED_CAST(void *, PKCS7_SIGNER_INFO *, p)))
-
-#define sk_PKCS7_SIGNER_INFO_find(sk, out_index, p) \
- sk_find(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk), \
- (out_index), CHECKED_CAST(void *, PKCS7_SIGNER_INFO *, p))
-
-#define sk_PKCS7_SIGNER_INFO_shift(sk) \
- ((PKCS7_SIGNER_INFO *)sk_shift( \
- CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk)))
-
-#define sk_PKCS7_SIGNER_INFO_push(sk, p) \
- sk_push(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk), \
- CHECKED_CAST(void *, PKCS7_SIGNER_INFO *, p))
-
-#define sk_PKCS7_SIGNER_INFO_pop(sk) \
- ((PKCS7_SIGNER_INFO *)sk_pop( \
- CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk)))
-
-#define sk_PKCS7_SIGNER_INFO_dup(sk) \
- ((STACK_OF(PKCS7_SIGNER_INFO) *)sk_dup( \
- CHECKED_CAST(_STACK *, const STACK_OF(PKCS7_SIGNER_INFO) *, sk)))
-
-#define sk_PKCS7_SIGNER_INFO_sort(sk) \
- sk_sort(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk))
-
-#define sk_PKCS7_SIGNER_INFO_is_sorted(sk) \
- sk_is_sorted(CHECKED_CAST(_STACK *, const STACK_OF(PKCS7_SIGNER_INFO) *, sk))
-
-#define sk_PKCS7_SIGNER_INFO_set_cmp_func(sk, comp) \
- ((int (*)(const PKCS7_SIGNER_INFO **a, const PKCS7_SIGNER_INFO **b)) \
- sk_set_cmp_func( \
- CHECKED_CAST(_STACK *, STACK_OF(PKCS7_SIGNER_INFO) *, sk), \
- CHECKED_CAST(stack_cmp_func, int (*)(const PKCS7_SIGNER_INFO **a, \
- const PKCS7_SIGNER_INFO **b), \
- comp)))
-
-#define sk_PKCS7_SIGNER_INFO_deep_copy(sk, copy_func, free_func) \
- ((STACK_OF(PKCS7_SIGNER_INFO) *)sk_deep_copy( \
- CHECKED_CAST(const _STACK *, const STACK_OF(PKCS7_SIGNER_INFO) *, sk), \
- CHECKED_CAST(void *(*)(void *), \
- PKCS7_SIGNER_INFO *(*)(PKCS7_SIGNER_INFO *), copy_func), \
- CHECKED_CAST(void (*)(void *), void (*)(PKCS7_SIGNER_INFO *), \
- free_func)))
-
/* POLICYINFO */
#define sk_POLICYINFO_new(comp) \
((STACK_OF(POLICYINFO) *)sk_new(CHECKED_CAST( \
diff --git a/src/include/openssl/tls1.h b/src/include/openssl/tls1.h
index 92210f6..92d2752 100644
--- a/src/include/openssl/tls1.h
+++ b/src/include/openssl/tls1.h
@@ -430,12 +430,14 @@ extern "C" {
#define TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD 0x0300CC13
#define TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD 0x0300CC14
-/* TODO(davidben): Remove these once WebRTC is no longer using them, so they
- * may point to the future RFC 7539 variant. */
+#define TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0x0300CCA8
+#define TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0x0300CCA9
+#define TLS1_CK_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0x0300CCAC
+
+/* TODO(davidben): Remove this. Historically, the CK names for CHACHA20_POLY1305
+ * were missing 'WITH' and 'SHA256'. */
#define TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305 \
- TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD
-#define TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305 \
- TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD
+ TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
/* XXX
* Inconsistency alert:
@@ -597,14 +599,25 @@ extern "C" {
#define TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256 "ECDH-RSA-AES128-GCM-SHA256"
#define TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384 "ECDH-RSA-AES256-GCM-SHA384"
+/* For convenience, the old and new CHACHA20_POLY1305 ciphers have the same
+ * name. In cipher strings, both will be selected. This is temporary and will be
+ * removed when the pre-standard construction is removed. */
#define TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_OLD \
"ECDHE-RSA-CHACHA20-POLY1305"
#define TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_OLD \
"ECDHE-ECDSA-CHACHA20-POLY1305"
-/* TODO(davidben): Remove this once QUIC has switched to the '_OLD' name. */
+#define TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 \
+ "ECDHE-RSA-CHACHA20-POLY1305"
+#define TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 \
+ "ECDHE-ECDSA-CHACHA20-POLY1305"
+#define TLS1_TXT_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 \
+ "ECDHE-PSK-CHACHA20-POLY1305"
+
+/* TODO(davidben): Remove this. Historically, the TXT names for CHACHA20_POLY1305
+ * were missing 'SHA256'. */
#define TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305 \
- TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_OLD
+ TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
#define TLS_CT_RSA_SIGN 1
#define TLS_CT_DSS_SIGN 2
diff --git a/src/include/openssl/x509.h b/src/include/openssl/x509.h
index da569e8..a5aaf31 100644
--- a/src/include/openssl/x509.h
+++ b/src/include/openssl/x509.h
@@ -618,12 +618,10 @@ OPENSSL_EXPORT int X509_signature_print(BIO *bp,X509_ALGOR *alg, ASN1_STRING *si
OPENSSL_EXPORT int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
OPENSSL_EXPORT int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx);
-/* int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert); */
OPENSSL_EXPORT int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md);
OPENSSL_EXPORT int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx);
OPENSSL_EXPORT int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md);
OPENSSL_EXPORT int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx);
-/* int X509_CRL_http_nbio(OCSP_REQ_CTX *rctx, X509_CRL **pcrl); */
OPENSSL_EXPORT int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md);
OPENSSL_EXPORT int X509_pubkey_digest(const X509 *data,const EVP_MD *type,
@@ -787,7 +785,7 @@ DECLARE_ASN1_FUNCTIONS(X509_CERT_PAIR)
* |x|. */
OPENSSL_EXPORT X509 *X509_up_ref(X509 *x);
-OPENSSL_EXPORT int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+OPENSSL_EXPORT int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
OPENSSL_EXPORT int X509_set_ex_data(X509 *r, int idx, void *arg);
OPENSSL_EXPORT void *X509_get_ex_data(X509 *r, int idx);
diff --git a/src/include/openssl/x509_vfy.h b/src/include/openssl/x509_vfy.h
index c11820b..b39ef49 100644
--- a/src/include/openssl/x509_vfy.h
+++ b/src/include/openssl/x509_vfy.h
@@ -498,7 +498,7 @@ OPENSSL_EXPORT int X509_STORE_load_locations (X509_STORE *ctx,
OPENSSL_EXPORT int X509_STORE_set_default_paths(X509_STORE *ctx);
#endif
-OPENSSL_EXPORT int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+OPENSSL_EXPORT int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
OPENSSL_EXPORT int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx,int idx,void *data);
OPENSSL_EXPORT void * X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx,int idx);
diff --git a/src/ssl/CMakeLists.txt b/src/ssl/CMakeLists.txt
index a5ad126..c82cb9b 100644
--- a/src/ssl/CMakeLists.txt
+++ b/src/ssl/CMakeLists.txt
@@ -26,6 +26,7 @@ add_library(
ssl_buffer.c
ssl_cert.c
ssl_cipher.c
+ ssl_ecdh.c
ssl_file.c
ssl_lib.c
ssl_rsa.c
diff --git a/src/ssl/d1_both.c b/src/ssl/d1_both.c
index a940af6..ee4cbc9 100644
--- a/src/ssl/d1_both.c
+++ b/src/ssl/d1_both.c
@@ -301,8 +301,9 @@ static int dtls1_write_change_cipher_spec(SSL *ssl,
}
static const uint8_t kChangeCipherSpec[1] = {SSL3_MT_CCS};
- int ret = dtls1_write_bytes(ssl, SSL3_RT_CHANGE_CIPHER_SPEC, kChangeCipherSpec,
- sizeof(kChangeCipherSpec), use_epoch);
+ int ret =
+ dtls1_write_bytes(ssl, SSL3_RT_CHANGE_CIPHER_SPEC, kChangeCipherSpec,
+ sizeof(kChangeCipherSpec), use_epoch);
if (ret <= 0) {
return ret;
}
@@ -410,17 +411,17 @@ err:
/* dtls1_is_next_message_complete returns one if the next handshake message is
* complete and zero otherwise. */
-static int dtls1_is_next_message_complete(SSL *s) {
- pitem *item = pqueue_peek(s->d1->buffered_messages);
+static int dtls1_is_next_message_complete(SSL *ssl) {
+ pitem *item = pqueue_peek(ssl->d1->buffered_messages);
if (item == NULL) {
return 0;
}
hm_fragment *frag = (hm_fragment *)item->data;
- assert(s->d1->handshake_read_seq <= frag->msg_header.seq);
+ assert(ssl->d1->handshake_read_seq <= frag->msg_header.seq);
- return s->d1->handshake_read_seq == frag->msg_header.seq &&
- frag->reassembly == NULL;
+ return ssl->d1->handshake_read_seq == frag->msg_header.seq &&
+ frag->reassembly == NULL;
}
/* dtls1_discard_fragment_body discards a handshake fragment body of length
@@ -428,11 +429,11 @@ static int dtls1_is_next_message_complete(SSL *s) {
*
* TODO(davidben): This function will go away when ssl_read_bytes is gone from
* the DTLS side. */
-static int dtls1_discard_fragment_body(SSL *s, size_t frag_len) {
+static int dtls1_discard_fragment_body(SSL *ssl, size_t frag_len) {
uint8_t discard[256];
while (frag_len > 0) {
size_t chunk = frag_len < sizeof(discard) ? frag_len : sizeof(discard);
- int ret = dtls1_read_bytes(s, SSL3_RT_HANDSHAKE, discard, chunk, 0);
+ int ret = dtls1_read_bytes(ssl, SSL3_RT_HANDSHAKE, discard, chunk, 0);
if (ret != (int) chunk) {
return 0;
}
@@ -446,12 +447,12 @@ static int dtls1_discard_fragment_body(SSL *s, size_t frag_len) {
* queue. Otherwise, it checks |msg_hdr| is consistent with the existing one. It
* returns NULL on failure. The caller does not take ownership of the result. */
static hm_fragment *dtls1_get_buffered_message(
- SSL *s, const struct hm_header_st *msg_hdr) {
+ SSL *ssl, const struct hm_header_st *msg_hdr) {
uint8_t seq64be[8];
memset(seq64be, 0, sizeof(seq64be));
seq64be[6] = (uint8_t)(msg_hdr->seq >> 8);
seq64be[7] = (uint8_t)msg_hdr->seq;
- pitem *item = pqueue_find(s->d1->buffered_messages, seq64be);
+ pitem *item = pqueue_find(ssl->d1->buffered_messages, seq64be);
hm_fragment *frag;
if (item == NULL) {
@@ -467,7 +468,7 @@ static hm_fragment *dtls1_get_buffered_message(
dtls1_hm_fragment_free(frag);
return NULL;
}
- item = pqueue_insert(s->d1->buffered_messages, item);
+ item = pqueue_insert(ssl->d1->buffered_messages, item);
/* |pqueue_insert| fails iff a duplicate item is inserted, but |item| cannot
* be a duplicate. */
assert(item != NULL);
@@ -479,7 +480,7 @@ static hm_fragment *dtls1_get_buffered_message(
/* The new fragment must be compatible with the previous fragments from
* this message. */
OPENSSL_PUT_ERROR(SSL, SSL_R_FRAGMENT_MISMATCH);
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return NULL;
}
}
@@ -487,29 +488,29 @@ static hm_fragment *dtls1_get_buffered_message(
}
/* dtls1_max_handshake_message_len returns the maximum number of bytes
- * permitted in a DTLS handshake message for |s|. The minimum is 16KB, but may
+ * permitted in a DTLS handshake message for |ssl|. The minimum is 16KB, but may
* be greater if the maximum certificate list size requires it. */
-static size_t dtls1_max_handshake_message_len(const SSL *s) {
+static size_t dtls1_max_handshake_message_len(const SSL *ssl) {
size_t max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH;
- if (max_len < s->max_cert_list) {
- return s->max_cert_list;
+ if (max_len < ssl->max_cert_list) {
+ return ssl->max_cert_list;
}
return max_len;
}
/* dtls1_process_fragment reads a handshake fragment and processes it. It
* returns one if a fragment was successfully processed and 0 or -1 on error. */
-static int dtls1_process_fragment(SSL *s) {
+static int dtls1_process_fragment(SSL *ssl) {
/* Read handshake message header. */
uint8_t header[DTLS1_HM_HEADER_LENGTH];
- int ret = dtls1_read_bytes(s, SSL3_RT_HANDSHAKE, header,
+ int ret = dtls1_read_bytes(ssl, SSL3_RT_HANDSHAKE, header,
DTLS1_HM_HEADER_LENGTH, 0);
if (ret <= 0) {
return ret;
}
if (ret != DTLS1_HM_HEADER_LENGTH) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
return -1;
}
@@ -518,30 +519,30 @@ static int dtls1_process_fragment(SSL *s) {
dtls1_get_message_header(header, &msg_hdr);
/* TODO(davidben): dtls1_read_bytes is the wrong abstraction for DTLS. There
- * should be no need to reach into |s->s3->rrec.length|. */
+ * should be no need to reach into |ssl->s3->rrec.length|. */
const size_t frag_off = msg_hdr.frag_off;
const size_t frag_len = msg_hdr.frag_len;
const size_t msg_len = msg_hdr.msg_len;
if (frag_off > msg_len || frag_off + frag_len < frag_off ||
frag_off + frag_len > msg_len ||
- msg_len > dtls1_max_handshake_message_len(s) ||
- frag_len > s->s3->rrec.length) {
+ msg_len > dtls1_max_handshake_message_len(ssl) ||
+ frag_len > ssl->s3->rrec.length) {
OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE);
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return -1;
}
- if (msg_hdr.seq < s->d1->handshake_read_seq ||
- msg_hdr.seq > (unsigned)s->d1->handshake_read_seq +
+ if (msg_hdr.seq < ssl->d1->handshake_read_seq ||
+ msg_hdr.seq > (unsigned)ssl->d1->handshake_read_seq +
kHandshakeBufferSize) {
/* Ignore fragments from the past, or ones too far in the future. */
- if (!dtls1_discard_fragment_body(s, frag_len)) {
+ if (!dtls1_discard_fragment_body(ssl, frag_len)) {
return -1;
}
return 1;
}
- hm_fragment *frag = dtls1_get_buffered_message(s, &msg_hdr);
+ hm_fragment *frag = dtls1_get_buffered_message(ssl, &msg_hdr);
if (frag == NULL) {
return -1;
}
@@ -549,7 +550,7 @@ static int dtls1_process_fragment(SSL *s) {
if (frag->reassembly == NULL) {
/* The message is already assembled. */
- if (!dtls1_discard_fragment_body(s, frag_len)) {
+ if (!dtls1_discard_fragment_body(ssl, frag_len)) {
return -1;
}
return 1;
@@ -557,11 +558,11 @@ static int dtls1_process_fragment(SSL *s) {
assert(msg_len > 0);
/* Read the body of the fragment. */
- ret = dtls1_read_bytes(s, SSL3_RT_HANDSHAKE, frag->fragment + frag_off,
+ ret = dtls1_read_bytes(ssl, SSL3_RT_HANDSHAKE, frag->fragment + frag_off,
frag_len, 0);
if (ret != (int) frag_len) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return -1;
}
dtls1_hm_fragment_mark(frag, frag_off, frag_off + frag_len);
@@ -572,7 +573,7 @@ static int dtls1_process_fragment(SSL *s) {
/* dtls1_get_message reads a handshake message of message type |msg_type| (any
* if |msg_type| == -1), maximum acceptable body length |max|. Read an entire
* handshake message. Handshake messages arrive in fragments. */
-long dtls1_get_message(SSL *s, int st1, int stn, int msg_type, long max,
+long dtls1_get_message(SSL *ssl, int st1, int stn, int msg_type, long max,
enum ssl_hash_message_t hash_message, int *ok) {
pitem *item = NULL;
hm_fragment *frag = NULL;
@@ -580,26 +581,26 @@ long dtls1_get_message(SSL *s, int st1, int stn, int msg_type, long max,
/* s3->tmp is used to store messages that are unexpected, caused
* by the absence of an optional handshake message */
- if (s->s3->tmp.reuse_message) {
+ if (ssl->s3->tmp.reuse_message) {
/* A ssl_dont_hash_message call cannot be combined with reuse_message; the
* ssl_dont_hash_message would have to have been applied to the previous
* call. */
assert(hash_message == ssl_hash_message);
- s->s3->tmp.reuse_message = 0;
- if (msg_type >= 0 && s->s3->tmp.message_type != msg_type) {
+ ssl->s3->tmp.reuse_message = 0;
+ if (msg_type >= 0 && ssl->s3->tmp.message_type != msg_type) {
al = SSL_AD_UNEXPECTED_MESSAGE;
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
goto f_err;
}
*ok = 1;
- s->init_msg = (uint8_t *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
- s->init_num = (int)s->s3->tmp.message_size;
- return s->init_num;
+ ssl->init_msg = (uint8_t *)ssl->init_buf->data + DTLS1_HM_HEADER_LENGTH;
+ ssl->init_num = (int)ssl->s3->tmp.message_size;
+ return ssl->init_num;
}
/* Process fragments until one is found. */
- while (!dtls1_is_next_message_complete(s)) {
- int ret = dtls1_process_fragment(s);
+ while (!dtls1_is_next_message_complete(ssl)) {
+ int ret = dtls1_process_fragment(ssl);
if (ret <= 0) {
*ok = 0;
return ret;
@@ -607,10 +608,10 @@ long dtls1_get_message(SSL *s, int st1, int stn, int msg_type, long max,
}
/* Read out the next complete handshake message. */
- item = pqueue_pop(s->d1->buffered_messages);
+ item = pqueue_pop(ssl->d1->buffered_messages);
assert(item != NULL);
frag = (hm_fragment *)item->data;
- assert(s->d1->handshake_read_seq == frag->msg_header.seq);
+ assert(ssl->d1->handshake_read_seq == frag->msg_header.seq);
assert(frag->reassembly == NULL);
if (frag->msg_header.msg_len > (size_t)max) {
@@ -622,10 +623,10 @@ long dtls1_get_message(SSL *s, int st1, int stn, int msg_type, long max,
size_t len;
CBB cbb;
CBB_zero(&cbb);
- if (!BUF_MEM_grow(s->init_buf,
- (size_t)frag->msg_header.msg_len +
- DTLS1_HM_HEADER_LENGTH) ||
- !CBB_init_fixed(&cbb, (uint8_t *)s->init_buf->data, s->init_buf->max) ||
+ if (!BUF_MEM_grow(ssl->init_buf, (size_t)frag->msg_header.msg_len +
+ DTLS1_HM_HEADER_LENGTH) ||
+ !CBB_init_fixed(&cbb, (uint8_t *)ssl->init_buf->data,
+ ssl->init_buf->max) ||
!CBB_add_u8(&cbb, frag->msg_header.type) ||
!CBB_add_u24(&cbb, frag->msg_header.msg_len) ||
!CBB_add_u16(&cbb, frag->msg_header.seq) ||
@@ -639,38 +640,38 @@ long dtls1_get_message(SSL *s, int st1, int stn, int msg_type, long max,
}
assert(len == (size_t)frag->msg_header.msg_len + DTLS1_HM_HEADER_LENGTH);
- s->d1->handshake_read_seq++;
+ ssl->d1->handshake_read_seq++;
/* TODO(davidben): This function has a lot of implicit outputs. Simplify the
* |ssl_get_message| API. */
- s->s3->tmp.message_type = frag->msg_header.type;
- s->s3->tmp.message_size = frag->msg_header.msg_len;
- s->init_msg = (uint8_t *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
- s->init_num = frag->msg_header.msg_len;
+ ssl->s3->tmp.message_type = frag->msg_header.type;
+ ssl->s3->tmp.message_size = frag->msg_header.msg_len;
+ ssl->init_msg = (uint8_t *)ssl->init_buf->data + DTLS1_HM_HEADER_LENGTH;
+ ssl->init_num = frag->msg_header.msg_len;
- if (msg_type >= 0 && s->s3->tmp.message_type != msg_type) {
+ if (msg_type >= 0 && ssl->s3->tmp.message_type != msg_type) {
al = SSL_AD_UNEXPECTED_MESSAGE;
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
goto f_err;
}
- if (hash_message == ssl_hash_message && !ssl3_hash_current_message(s)) {
+ if (hash_message == ssl_hash_message && !ssl3_hash_current_message(ssl)) {
goto err;
}
- if (s->msg_callback) {
- s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data,
- s->init_num + DTLS1_HM_HEADER_LENGTH, s,
- s->msg_callback_arg);
+ if (ssl->msg_callback) {
+ ssl->msg_callback(0, ssl->version, SSL3_RT_HANDSHAKE, ssl->init_buf->data,
+ ssl->init_num + DTLS1_HM_HEADER_LENGTH, ssl,
+ ssl->msg_callback_arg);
}
pitem_free(item);
dtls1_hm_fragment_free(frag);
- s->state = stn;
+ ssl->state = stn;
*ok = 1;
- return s->init_num;
+ return ssl->init_num;
f_err:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
err:
pitem_free(item);
dtls1_hm_fragment_free(frag);
@@ -678,25 +679,25 @@ err:
return -1;
}
-int dtls1_read_failed(SSL *s, int code) {
+int dtls1_read_failed(SSL *ssl, int code) {
if (code > 0) {
assert(0);
return 1;
}
- if (!dtls1_is_timer_expired(s)) {
+ if (!dtls1_is_timer_expired(ssl)) {
/* not a timeout, none of our business, let higher layers handle this. In
* fact, it's probably an error */
return code;
}
- if (!SSL_in_init(s)) {
+ if (!SSL_in_init(ssl)) {
/* done, no need to send a retransmit */
- BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ);
+ BIO_set_flags(SSL_get_rbio(ssl), BIO_FLAGS_READ);
return code;
}
- return DTLSv1_handle_timeout(s);
+ return DTLSv1_handle_timeout(ssl);
}
static uint16_t dtls1_get_queue_priority(uint16_t seq, int is_ccs) {
@@ -713,47 +714,47 @@ static uint16_t dtls1_get_queue_priority(uint16_t seq, int is_ccs) {
return seq * 2 - is_ccs;
}
-static int dtls1_retransmit_message(SSL *s, hm_fragment *frag) {
+static int dtls1_retransmit_message(SSL *ssl, hm_fragment *frag) {
/* DTLS renegotiation is unsupported, so only epochs 0 (NULL cipher) and 1
* (negotiated cipher) exist. */
- assert(s->d1->w_epoch == 0 || s->d1->w_epoch == 1);
- assert(frag->msg_header.epoch <= s->d1->w_epoch);
+ assert(ssl->d1->w_epoch == 0 || ssl->d1->w_epoch == 1);
+ assert(frag->msg_header.epoch <= ssl->d1->w_epoch);
enum dtls1_use_epoch_t use_epoch = dtls1_use_current_epoch;
- if (s->d1->w_epoch == 1 && frag->msg_header.epoch == 0) {
+ if (ssl->d1->w_epoch == 1 && frag->msg_header.epoch == 0) {
use_epoch = dtls1_use_previous_epoch;
}
/* TODO(davidben): This cannot handle non-blocking writes. */
int ret;
if (frag->msg_header.is_ccs) {
- ret = dtls1_write_change_cipher_spec(s, use_epoch);
+ ret = dtls1_write_change_cipher_spec(ssl, use_epoch);
} else {
/* Restore the message body.
* TODO(davidben): Make this less stateful. */
- memcpy(s->init_buf->data, frag->fragment,
+ memcpy(ssl->init_buf->data, frag->fragment,
frag->msg_header.msg_len + DTLS1_HM_HEADER_LENGTH);
- s->init_num = frag->msg_header.msg_len + DTLS1_HM_HEADER_LENGTH;
+ ssl->init_num = frag->msg_header.msg_len + DTLS1_HM_HEADER_LENGTH;
- dtls1_set_message_header(s, frag->msg_header.type,
+ dtls1_set_message_header(ssl, frag->msg_header.type,
frag->msg_header.msg_len, frag->msg_header.seq,
0, frag->msg_header.frag_len);
- ret = dtls1_do_handshake_write(s, use_epoch);
+ ret = dtls1_do_handshake_write(ssl, use_epoch);
}
/* TODO(davidben): Check return value? */
- (void)BIO_flush(SSL_get_wbio(s));
+ (void)BIO_flush(SSL_get_wbio(ssl));
return ret;
}
-int dtls1_retransmit_buffered_messages(SSL *s) {
- pqueue sent = s->d1->sent_messages;
+int dtls1_retransmit_buffered_messages(SSL *ssl) {
+ pqueue sent = ssl->d1->sent_messages;
piterator iter = pqueue_iterator(sent);
pitem *item;
for (item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter)) {
hm_fragment *frag = (hm_fragment *)item->data;
- if (dtls1_retransmit_message(s, frag) <= 0) {
+ if (dtls1_retransmit_message(ssl, frag) <= 0) {
return -1;
}
}
@@ -789,28 +790,28 @@ static int dtls1_buffer_change_cipher_spec(SSL *ssl, uint16_t seq) {
return 1;
}
-int dtls1_buffer_message(SSL *s) {
+int dtls1_buffer_message(SSL *ssl) {
/* this function is called immediately after a message has
* been serialized */
- assert(s->init_off == 0);
+ assert(ssl->init_off == 0);
- hm_fragment *frag = dtls1_hm_fragment_new(s->init_num, 0);
+ hm_fragment *frag = dtls1_hm_fragment_new(ssl->init_num, 0);
if (!frag) {
return 0;
}
- memcpy(frag->fragment, s->init_buf->data, s->init_num);
+ memcpy(frag->fragment, ssl->init_buf->data, ssl->init_num);
- assert(s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH ==
- (unsigned int)s->init_num);
+ assert(ssl->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH ==
+ (unsigned int)ssl->init_num);
- frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len;
- frag->msg_header.seq = s->d1->w_msg_hdr.seq;
- frag->msg_header.type = s->d1->w_msg_hdr.type;
+ frag->msg_header.msg_len = ssl->d1->w_msg_hdr.msg_len;
+ frag->msg_header.seq = ssl->d1->w_msg_hdr.seq;
+ frag->msg_header.type = ssl->d1->w_msg_hdr.type;
frag->msg_header.frag_off = 0;
- frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len;
+ frag->msg_header.frag_len = ssl->d1->w_msg_hdr.msg_len;
frag->msg_header.is_ccs = 0;
- frag->msg_header.epoch = s->d1->w_epoch;
+ frag->msg_header.epoch = ssl->d1->w_epoch;
uint16_t priority = dtls1_get_queue_priority(frag->msg_header.seq,
0 /* handshake */);
@@ -825,37 +826,37 @@ int dtls1_buffer_message(SSL *s) {
return 0;
}
- pqueue_insert(s->d1->sent_messages, item);
+ pqueue_insert(ssl->d1->sent_messages, item);
return 1;
}
-int dtls1_send_change_cipher_spec(SSL *s, int a, int b) {
- if (s->state == a) {
+int dtls1_send_change_cipher_spec(SSL *ssl, int a, int b) {
+ if (ssl->state == a) {
/* Buffer the message to handle retransmits. */
- s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
- dtls1_buffer_change_cipher_spec(s, s->d1->handshake_write_seq);
- s->state = b;
+ ssl->d1->handshake_write_seq = ssl->d1->next_handshake_write_seq;
+ dtls1_buffer_change_cipher_spec(ssl, ssl->d1->handshake_write_seq);
+ ssl->state = b;
}
- return dtls1_write_change_cipher_spec(s, dtls1_use_current_epoch);
+ return dtls1_write_change_cipher_spec(ssl, dtls1_use_current_epoch);
}
/* call this function when the buffered messages are no longer needed */
-void dtls1_clear_record_buffer(SSL *s) {
+void dtls1_clear_record_buffer(SSL *ssl) {
pitem *item;
- for (item = pqueue_pop(s->d1->sent_messages); item != NULL;
- item = pqueue_pop(s->d1->sent_messages)) {
+ for (item = pqueue_pop(ssl->d1->sent_messages); item != NULL;
+ item = pqueue_pop(ssl->d1->sent_messages)) {
dtls1_hm_fragment_free((hm_fragment *)item->data);
pitem_free(item);
}
}
/* don't actually do the writing, wait till the MTU has been retrieved */
-void dtls1_set_message_header(SSL *s, uint8_t mt, unsigned long len,
+void dtls1_set_message_header(SSL *ssl, uint8_t mt, unsigned long len,
unsigned short seq_num, unsigned long frag_off,
unsigned long frag_len) {
- struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
+ struct hm_header_st *msg_hdr = &ssl->d1->w_msg_hdr;
msg_hdr->type = mt;
msg_hdr->msg_len = len;
diff --git a/src/ssl/d1_clnt.c b/src/ssl/d1_clnt.c
index b86655c..ad5eb50 100644
--- a/src/ssl/d1_clnt.c
+++ b/src/ssl/d1_clnt.c
@@ -131,354 +131,362 @@
#include "internal.h"
-static int dtls1_get_hello_verify(SSL *s);
+static int dtls1_get_hello_verify(SSL *ssl);
-int dtls1_connect(SSL *s) {
+int dtls1_connect(SSL *ssl) {
BUF_MEM *buf = NULL;
void (*cb)(const SSL *ssl, int type, int value) = NULL;
int ret = -1;
int new_state, state, skip = 0;
- assert(s->handshake_func == dtls1_connect);
- assert(!s->server);
- assert(SSL_IS_DTLS(s));
+ assert(ssl->handshake_func == dtls1_connect);
+ assert(!ssl->server);
+ assert(SSL_IS_DTLS(ssl));
ERR_clear_error();
ERR_clear_system_error();
- if (s->info_callback != NULL) {
- cb = s->info_callback;
- } else if (s->ctx->info_callback != NULL) {
- cb = s->ctx->info_callback;
+ if (ssl->info_callback != NULL) {
+ cb = ssl->info_callback;
+ } else if (ssl->ctx->info_callback != NULL) {
+ cb = ssl->ctx->info_callback;
}
- s->in_handshake++;
+ ssl->in_handshake++;
for (;;) {
- state = s->state;
+ state = ssl->state;
- switch (s->state) {
+ switch (ssl->state) {
case SSL_ST_CONNECT:
if (cb != NULL) {
- cb(s, SSL_CB_HANDSHAKE_START, 1);
+ cb(ssl, SSL_CB_HANDSHAKE_START, 1);
}
- if (s->init_buf == NULL) {
+ if (ssl->init_buf == NULL) {
buf = BUF_MEM_new();
if (buf == NULL ||
!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
ret = -1;
goto end;
}
- s->init_buf = buf;
+ ssl->init_buf = buf;
buf = NULL;
}
- if (!ssl_init_wbio_buffer(s, 0)) {
+ if (!ssl_init_wbio_buffer(ssl, 0)) {
ret = -1;
goto end;
}
/* don't push the buffering BIO quite yet */
- s->state = SSL3_ST_CW_CLNT_HELLO_A;
- s->init_num = 0;
- s->d1->send_cookie = 0;
- s->hit = 0;
+ ssl->state = SSL3_ST_CW_CLNT_HELLO_A;
+ ssl->init_num = 0;
+ ssl->d1->send_cookie = 0;
+ ssl->hit = 0;
break;
case SSL3_ST_CW_CLNT_HELLO_A:
case SSL3_ST_CW_CLNT_HELLO_B:
- s->shutdown = 0;
- dtls1_start_timer(s);
- ret = ssl3_send_client_hello(s);
+ ssl->shutdown = 0;
+ dtls1_start_timer(ssl);
+ ret = ssl3_send_client_hello(ssl);
if (ret <= 0) {
goto end;
}
- if (s->d1->send_cookie) {
- s->state = SSL3_ST_CW_FLUSH;
- s->s3->tmp.next_state = SSL3_ST_CR_SRVR_HELLO_A;
+ if (ssl->d1->send_cookie) {
+ ssl->state = SSL3_ST_CW_FLUSH;
+ ssl->s3->tmp.next_state = SSL3_ST_CR_SRVR_HELLO_A;
} else {
- s->state = DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A;
+ ssl->state = DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A;
}
- s->init_num = 0;
+ ssl->init_num = 0;
/* turn on buffering for the next lot of output */
- if (s->bbio != s->wbio) {
- s->wbio = BIO_push(s->bbio, s->wbio);
+ if (ssl->bbio != ssl->wbio) {
+ ssl->wbio = BIO_push(ssl->bbio, ssl->wbio);
}
break;
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A:
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B:
- ret = dtls1_get_hello_verify(s);
+ ret = dtls1_get_hello_verify(ssl);
if (ret <= 0) {
goto end;
}
- if (s->d1->send_cookie) {
+ if (ssl->d1->send_cookie) {
/* start again, with a cookie */
- dtls1_stop_timer(s);
- s->state = SSL3_ST_CW_CLNT_HELLO_A;
+ dtls1_stop_timer(ssl);
+ ssl->state = SSL3_ST_CW_CLNT_HELLO_A;
} else {
- s->state = SSL3_ST_CR_SRVR_HELLO_A;
+ ssl->state = SSL3_ST_CR_SRVR_HELLO_A;
}
- s->init_num = 0;
+ ssl->init_num = 0;
break;
case SSL3_ST_CR_SRVR_HELLO_A:
case SSL3_ST_CR_SRVR_HELLO_B:
- ret = ssl3_get_server_hello(s);
+ ret = ssl3_get_server_hello(ssl);
if (ret <= 0) {
goto end;
}
- if (s->hit) {
- s->state = SSL3_ST_CR_FINISHED_A;
- if (s->tlsext_ticket_expected) {
+ if (ssl->hit) {
+ ssl->state = SSL3_ST_CR_CHANGE;
+ if (ssl->tlsext_ticket_expected) {
/* receive renewed session ticket */
- s->state = SSL3_ST_CR_SESSION_TICKET_A;
+ ssl->state = SSL3_ST_CR_SESSION_TICKET_A;
}
} else {
- s->state = SSL3_ST_CR_CERT_A;
+ ssl->state = SSL3_ST_CR_CERT_A;
}
- s->init_num = 0;
+ ssl->init_num = 0;
break;
case SSL3_ST_CR_CERT_A:
case SSL3_ST_CR_CERT_B:
- if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) {
- ret = ssl3_get_server_certificate(s);
+ if (ssl_cipher_has_server_public_key(ssl->s3->tmp.new_cipher)) {
+ ret = ssl3_get_server_certificate(ssl);
if (ret <= 0) {
goto end;
}
- if (s->s3->tmp.certificate_status_expected) {
- s->state = SSL3_ST_CR_CERT_STATUS_A;
+ if (ssl->s3->tmp.certificate_status_expected) {
+ ssl->state = SSL3_ST_CR_CERT_STATUS_A;
} else {
- s->state = SSL3_ST_VERIFY_SERVER_CERT;
+ ssl->state = SSL3_ST_VERIFY_SERVER_CERT;
}
} else {
skip = 1;
- s->state = SSL3_ST_CR_KEY_EXCH_A;
+ ssl->state = SSL3_ST_CR_KEY_EXCH_A;
}
- s->init_num = 0;
+ ssl->init_num = 0;
break;
case SSL3_ST_VERIFY_SERVER_CERT:
- ret = ssl3_verify_server_cert(s);
+ ret = ssl3_verify_server_cert(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_CR_KEY_EXCH_A;
- s->init_num = 0;
+ ssl->state = SSL3_ST_CR_KEY_EXCH_A;
+ ssl->init_num = 0;
break;
case SSL3_ST_CR_KEY_EXCH_A:
case SSL3_ST_CR_KEY_EXCH_B:
- ret = ssl3_get_server_key_exchange(s);
+ ret = ssl3_get_server_key_exchange(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_CR_CERT_REQ_A;
- s->init_num = 0;
+ ssl->state = SSL3_ST_CR_CERT_REQ_A;
+ ssl->init_num = 0;
break;
case SSL3_ST_CR_CERT_REQ_A:
case SSL3_ST_CR_CERT_REQ_B:
- ret = ssl3_get_certificate_request(s);
+ ret = ssl3_get_certificate_request(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_CR_SRVR_DONE_A;
- s->init_num = 0;
+ ssl->state = SSL3_ST_CR_SRVR_DONE_A;
+ ssl->init_num = 0;
break;
case SSL3_ST_CR_SRVR_DONE_A:
case SSL3_ST_CR_SRVR_DONE_B:
- ret = ssl3_get_server_done(s);
+ ret = ssl3_get_server_done(ssl);
if (ret <= 0) {
goto end;
}
- dtls1_stop_timer(s);
- if (s->s3->tmp.cert_req) {
- s->s3->tmp.next_state = SSL3_ST_CW_CERT_A;
+ dtls1_stop_timer(ssl);
+ if (ssl->s3->tmp.cert_req) {
+ ssl->s3->tmp.next_state = SSL3_ST_CW_CERT_A;
} else {
- s->s3->tmp.next_state = SSL3_ST_CW_KEY_EXCH_A;
+ ssl->s3->tmp.next_state = SSL3_ST_CW_KEY_EXCH_A;
}
- s->init_num = 0;
- s->state = s->s3->tmp.next_state;
+ ssl->init_num = 0;
+ ssl->state = ssl->s3->tmp.next_state;
break;
case SSL3_ST_CW_CERT_A:
case SSL3_ST_CW_CERT_B:
case SSL3_ST_CW_CERT_C:
case SSL3_ST_CW_CERT_D:
- dtls1_start_timer(s);
- ret = ssl3_send_client_certificate(s);
+ dtls1_start_timer(ssl);
+ ret = ssl3_send_client_certificate(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_CW_KEY_EXCH_A;
- s->init_num = 0;
+ ssl->state = SSL3_ST_CW_KEY_EXCH_A;
+ ssl->init_num = 0;
break;
case SSL3_ST_CW_KEY_EXCH_A:
case SSL3_ST_CW_KEY_EXCH_B:
- dtls1_start_timer(s);
- ret = ssl3_send_client_key_exchange(s);
+ dtls1_start_timer(ssl);
+ ret = ssl3_send_client_key_exchange(ssl);
if (ret <= 0) {
goto end;
}
/* For TLS, cert_req is set to 2, so a cert chain
* of nothing is sent, but no verify packet is sent */
- if (s->s3->tmp.cert_req == 1) {
- s->state = SSL3_ST_CW_CERT_VRFY_A;
+ if (ssl->s3->tmp.cert_req == 1) {
+ ssl->state = SSL3_ST_CW_CERT_VRFY_A;
} else {
- s->state = SSL3_ST_CW_CHANGE_A;
- s->s3->change_cipher_spec = 0;
+ ssl->state = SSL3_ST_CW_CHANGE_A;
}
- s->init_num = 0;
+ ssl->init_num = 0;
break;
case SSL3_ST_CW_CERT_VRFY_A:
case SSL3_ST_CW_CERT_VRFY_B:
case SSL3_ST_CW_CERT_VRFY_C:
- dtls1_start_timer(s);
- ret = ssl3_send_cert_verify(s);
+ dtls1_start_timer(ssl);
+ ret = ssl3_send_cert_verify(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_CW_CHANGE_A;
- s->init_num = 0;
- s->s3->change_cipher_spec = 0;
+ ssl->state = SSL3_ST_CW_CHANGE_A;
+ ssl->init_num = 0;
break;
case SSL3_ST_CW_CHANGE_A:
case SSL3_ST_CW_CHANGE_B:
- if (!s->hit) {
- dtls1_start_timer(s);
+ if (!ssl->hit) {
+ dtls1_start_timer(ssl);
}
- ret = dtls1_send_change_cipher_spec(s, SSL3_ST_CW_CHANGE_A,
+ ret = dtls1_send_change_cipher_spec(ssl, SSL3_ST_CW_CHANGE_A,
SSL3_ST_CW_CHANGE_B);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_CW_FINISHED_A;
- s->init_num = 0;
+ ssl->state = SSL3_ST_CW_FINISHED_A;
+ ssl->init_num = 0;
- s->session->cipher = s->s3->tmp.new_cipher;
- if (!s->enc_method->setup_key_block(s) ||
- !s->enc_method->change_cipher_state(
- s, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) {
+ ssl->session->cipher = ssl->s3->tmp.new_cipher;
+ if (!ssl->enc_method->setup_key_block(ssl) ||
+ !ssl->enc_method->change_cipher_state(
+ ssl, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) {
ret = -1;
goto end;
}
-
- dtls1_reset_seq_numbers(s, SSL3_CC_WRITE);
break;
case SSL3_ST_CW_FINISHED_A:
case SSL3_ST_CW_FINISHED_B:
- if (!s->hit) {
- dtls1_start_timer(s);
+ if (!ssl->hit) {
+ dtls1_start_timer(ssl);
}
ret =
- ssl3_send_finished(s, SSL3_ST_CW_FINISHED_A, SSL3_ST_CW_FINISHED_B,
- s->enc_method->client_finished_label,
- s->enc_method->client_finished_label_len);
+ ssl3_send_finished(ssl, SSL3_ST_CW_FINISHED_A, SSL3_ST_CW_FINISHED_B,
+ ssl->enc_method->client_finished_label,
+ ssl->enc_method->client_finished_label_len);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_CW_FLUSH;
+ ssl->state = SSL3_ST_CW_FLUSH;
- if (s->hit) {
- s->s3->tmp.next_state = SSL_ST_OK;
+ if (ssl->hit) {
+ ssl->s3->tmp.next_state = SSL_ST_OK;
} else {
/* Allow NewSessionTicket if ticket expected */
- if (s->tlsext_ticket_expected) {
- s->s3->tmp.next_state = SSL3_ST_CR_SESSION_TICKET_A;
+ if (ssl->tlsext_ticket_expected) {
+ ssl->s3->tmp.next_state = SSL3_ST_CR_SESSION_TICKET_A;
} else {
- s->s3->tmp.next_state = SSL3_ST_CR_FINISHED_A;
+ ssl->s3->tmp.next_state = SSL3_ST_CR_CHANGE;
}
}
- s->init_num = 0;
+ ssl->init_num = 0;
break;
case SSL3_ST_CR_SESSION_TICKET_A:
case SSL3_ST_CR_SESSION_TICKET_B:
- ret = ssl3_get_new_session_ticket(s);
+ ret = ssl3_get_new_session_ticket(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_CR_FINISHED_A;
- s->init_num = 0;
+ ssl->state = SSL3_ST_CR_CHANGE;
+ ssl->init_num = 0;
break;
case SSL3_ST_CR_CERT_STATUS_A:
case SSL3_ST_CR_CERT_STATUS_B:
- ret = ssl3_get_cert_status(s);
+ ret = ssl3_get_cert_status(ssl);
+ if (ret <= 0) {
+ goto end;
+ }
+ ssl->state = SSL3_ST_VERIFY_SERVER_CERT;
+ ssl->init_num = 0;
+ break;
+
+ case SSL3_ST_CR_CHANGE:
+ ret = ssl->method->ssl_read_change_cipher_spec(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_VERIFY_SERVER_CERT;
- s->init_num = 0;
+
+ if (!ssl3_do_change_cipher_spec(ssl)) {
+ ret = -1;
+ goto end;
+ }
+ ssl->state = SSL3_ST_CR_FINISHED_A;
break;
case SSL3_ST_CR_FINISHED_A:
case SSL3_ST_CR_FINISHED_B:
- s->d1->change_cipher_spec_ok = 1;
ret =
- ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A, SSL3_ST_CR_FINISHED_B);
+ ssl3_get_finished(ssl, SSL3_ST_CR_FINISHED_A, SSL3_ST_CR_FINISHED_B);
if (ret <= 0) {
goto end;
}
- dtls1_stop_timer(s);
+ dtls1_stop_timer(ssl);
- if (s->hit) {
- s->state = SSL3_ST_CW_CHANGE_A;
+ if (ssl->hit) {
+ ssl->state = SSL3_ST_CW_CHANGE_A;
} else {
- s->state = SSL_ST_OK;
+ ssl->state = SSL_ST_OK;
}
- s->init_num = 0;
+ ssl->init_num = 0;
break;
case SSL3_ST_CW_FLUSH:
- s->rwstate = SSL_WRITING;
- if (BIO_flush(s->wbio) <= 0) {
+ ssl->rwstate = SSL_WRITING;
+ if (BIO_flush(ssl->wbio) <= 0) {
ret = -1;
goto end;
}
- s->rwstate = SSL_NOTHING;
- s->state = s->s3->tmp.next_state;
+ ssl->rwstate = SSL_NOTHING;
+ ssl->state = ssl->s3->tmp.next_state;
break;
case SSL_ST_OK:
/* clean a few things up */
- ssl3_cleanup_key_block(s);
+ ssl3_cleanup_key_block(ssl);
/* Remove write buffering now. */
- ssl_free_wbio_buffer(s);
+ ssl_free_wbio_buffer(ssl);
- s->init_num = 0;
- s->s3->initial_handshake_complete = 1;
+ ssl->init_num = 0;
+ ssl->s3->initial_handshake_complete = 1;
- ssl_update_cache(s, SSL_SESS_CACHE_CLIENT);
+ ssl_update_cache(ssl, SSL_SESS_CACHE_CLIENT);
ret = 1;
if (cb != NULL) {
- cb(s, SSL_CB_HANDSHAKE_DONE, 1);
+ cb(ssl, SSL_CB_HANDSHAKE_DONE, 1);
}
/* done with handshaking */
- s->d1->handshake_read_seq = 0;
- s->d1->next_handshake_write_seq = 0;
+ ssl->d1->handshake_read_seq = 0;
+ ssl->d1->next_handshake_write_seq = 0;
goto end;
default:
@@ -488,36 +496,36 @@ int dtls1_connect(SSL *s) {
}
/* did we do anything? */
- if (!s->s3->tmp.reuse_message && !skip) {
- if ((cb != NULL) && (s->state != state)) {
- new_state = s->state;
- s->state = state;
- cb(s, SSL_CB_CONNECT_LOOP, 1);
- s->state = new_state;
+ if (!ssl->s3->tmp.reuse_message && !skip) {
+ if ((cb != NULL) && (ssl->state != state)) {
+ new_state = ssl->state;
+ ssl->state = state;
+ cb(ssl, SSL_CB_CONNECT_LOOP, 1);
+ ssl->state = new_state;
}
}
skip = 0;
}
end:
- s->in_handshake--;
+ ssl->in_handshake--;
BUF_MEM_free(buf);
if (cb != NULL) {
- cb(s, SSL_CB_CONNECT_EXIT, ret);
+ cb(ssl, SSL_CB_CONNECT_EXIT, ret);
}
return ret;
}
-static int dtls1_get_hello_verify(SSL *s) {
+static int dtls1_get_hello_verify(SSL *ssl) {
long n;
int al, ok = 0;
CBS hello_verify_request, cookie;
uint16_t server_version;
- n = s->method->ssl_get_message(
- s, DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A, DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B,
- -1,
+ n = ssl->method->ssl_get_message(
+ ssl, DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A,
+ DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B, -1,
/* Use the same maximum size as ssl3_get_server_hello. */
20000, ssl_hash_message, &ok);
@@ -525,13 +533,13 @@ static int dtls1_get_hello_verify(SSL *s) {
return n;
}
- if (s->s3->tmp.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST) {
- s->d1->send_cookie = 0;
- s->s3->tmp.reuse_message = 1;
+ if (ssl->s3->tmp.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST) {
+ ssl->d1->send_cookie = 0;
+ ssl->s3->tmp.reuse_message = 1;
return 1;
}
- CBS_init(&hello_verify_request, s->init_msg, n);
+ CBS_init(&hello_verify_request, ssl->init_msg, n);
if (!CBS_get_u16(&hello_verify_request, &server_version) ||
!CBS_get_u8_length_prefixed(&hello_verify_request, &cookie) ||
@@ -541,18 +549,18 @@ static int dtls1_get_hello_verify(SSL *s) {
goto f_err;
}
- if (CBS_len(&cookie) > sizeof(s->d1->cookie)) {
+ if (CBS_len(&cookie) > sizeof(ssl->d1->cookie)) {
al = SSL_AD_ILLEGAL_PARAMETER;
goto f_err;
}
- memcpy(s->d1->cookie, CBS_data(&cookie), CBS_len(&cookie));
- s->d1->cookie_len = CBS_len(&cookie);
+ memcpy(ssl->d1->cookie, CBS_data(&cookie), CBS_len(&cookie));
+ ssl->d1->cookie_len = CBS_len(&cookie);
- s->d1->send_cookie = 1;
+ ssl->d1->send_cookie = 1;
return 1;
f_err:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
return -1;
}
diff --git a/src/ssl/d1_lib.c b/src/ssl/d1_lib.c
index 787ad9a..7f08b06 100644
--- a/src/ssl/d1_lib.c
+++ b/src/ssl/d1_lib.c
@@ -84,15 +84,15 @@
static void get_current_time(const SSL *ssl, struct timeval *out_clock);
-int dtls1_new(SSL *s) {
+int dtls1_new(SSL *ssl) {
DTLS1_STATE *d1;
- if (!ssl3_new(s)) {
+ if (!ssl3_new(ssl)) {
return 0;
}
d1 = OPENSSL_malloc(sizeof *d1);
if (d1 == NULL) {
- ssl3_free(s);
+ ssl3_free(ssl);
return 0;
}
memset(d1, 0, sizeof *d1);
@@ -104,52 +104,52 @@ int dtls1_new(SSL *s) {
pqueue_free(d1->buffered_messages);
pqueue_free(d1->sent_messages);
OPENSSL_free(d1);
- ssl3_free(s);
+ ssl3_free(ssl);
return 0;
}
- s->d1 = d1;
+ ssl->d1 = d1;
/* Set the version to the highest version for DTLS. This controls the initial
- * state of |s->enc_method| and what the API reports as the version prior to
+ * state of |ssl->enc_method| and what the API reports as the version prior to
* negotiation.
*
* TODO(davidben): This is fragile and confusing. */
- s->version = DTLS1_2_VERSION;
+ ssl->version = DTLS1_2_VERSION;
return 1;
}
-static void dtls1_clear_queues(SSL *s) {
+static void dtls1_clear_queues(SSL *ssl) {
pitem *item = NULL;
hm_fragment *frag = NULL;
- while ((item = pqueue_pop(s->d1->buffered_messages)) != NULL) {
+ while ((item = pqueue_pop(ssl->d1->buffered_messages)) != NULL) {
frag = (hm_fragment *)item->data;
dtls1_hm_fragment_free(frag);
pitem_free(item);
}
- while ((item = pqueue_pop(s->d1->sent_messages)) != NULL) {
+ while ((item = pqueue_pop(ssl->d1->sent_messages)) != NULL) {
frag = (hm_fragment *)item->data;
dtls1_hm_fragment_free(frag);
pitem_free(item);
}
}
-void dtls1_free(SSL *s) {
- ssl3_free(s);
+void dtls1_free(SSL *ssl) {
+ ssl3_free(ssl);
- if (s == NULL || s->d1 == NULL) {
+ if (ssl == NULL || ssl->d1 == NULL) {
return;
}
- dtls1_clear_queues(s);
+ dtls1_clear_queues(ssl);
- pqueue_free(s->d1->buffered_messages);
- pqueue_free(s->d1->sent_messages);
+ pqueue_free(ssl->d1->buffered_messages);
+ pqueue_free(ssl->d1->sent_messages);
- OPENSSL_free(s->d1);
- s->d1 = NULL;
+ OPENSSL_free(ssl->d1);
+ ssl->d1 = NULL;
}
int dtls1_supports_cipher(const SSL_CIPHER *cipher) {
@@ -158,19 +158,19 @@ int dtls1_supports_cipher(const SSL_CIPHER *cipher) {
return cipher->algorithm_enc != SSL_RC4 && cipher->algorithm_enc != SSL_eNULL;
}
-void dtls1_start_timer(SSL *s) {
+void dtls1_start_timer(SSL *ssl) {
/* If timer is not set, initialize duration with 1 second */
- if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) {
- s->d1->timeout_duration = 1;
+ if (ssl->d1->next_timeout.tv_sec == 0 && ssl->d1->next_timeout.tv_usec == 0) {
+ ssl->d1->timeout_duration = 1;
}
/* Set timeout to current time */
- get_current_time(s, &s->d1->next_timeout);
+ get_current_time(ssl, &ssl->d1->next_timeout);
/* Add duration to current time */
- s->d1->next_timeout.tv_sec += s->d1->timeout_duration;
- BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
- &s->d1->next_timeout);
+ ssl->d1->next_timeout.tv_sec += ssl->d1->timeout_duration;
+ BIO_ctrl(SSL_get_rbio(ssl), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
+ &ssl->d1->next_timeout);
}
int DTLSv1_get_timeout(const SSL *ssl, struct timeval *out) {
@@ -213,11 +213,11 @@ int DTLSv1_get_timeout(const SSL *ssl, struct timeval *out) {
return 1;
}
-int dtls1_is_timer_expired(SSL *s) {
+int dtls1_is_timer_expired(SSL *ssl) {
struct timeval timeleft;
/* Get time left until timeout, return false if no timer running */
- if (!DTLSv1_get_timeout(s, &timeleft)) {
+ if (!DTLSv1_get_timeout(ssl, &timeleft)) {
return 0;
}
@@ -230,39 +230,39 @@ int dtls1_is_timer_expired(SSL *s) {
return 1;
}
-void dtls1_double_timeout(SSL *s) {
- s->d1->timeout_duration *= 2;
- if (s->d1->timeout_duration > 60) {
- s->d1->timeout_duration = 60;
+void dtls1_double_timeout(SSL *ssl) {
+ ssl->d1->timeout_duration *= 2;
+ if (ssl->d1->timeout_duration > 60) {
+ ssl->d1->timeout_duration = 60;
}
- dtls1_start_timer(s);
+ dtls1_start_timer(ssl);
}
-void dtls1_stop_timer(SSL *s) {
+void dtls1_stop_timer(SSL *ssl) {
/* Reset everything */
- s->d1->num_timeouts = 0;
- memset(&s->d1->next_timeout, 0, sizeof(struct timeval));
- s->d1->timeout_duration = 1;
- BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
- &s->d1->next_timeout);
+ ssl->d1->num_timeouts = 0;
+ memset(&ssl->d1->next_timeout, 0, sizeof(struct timeval));
+ ssl->d1->timeout_duration = 1;
+ BIO_ctrl(SSL_get_rbio(ssl), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
+ &ssl->d1->next_timeout);
/* Clear retransmission buffer */
- dtls1_clear_record_buffer(s);
+ dtls1_clear_record_buffer(ssl);
}
-int dtls1_check_timeout_num(SSL *s) {
- s->d1->num_timeouts++;
+int dtls1_check_timeout_num(SSL *ssl) {
+ ssl->d1->num_timeouts++;
/* Reduce MTU after 2 unsuccessful retransmissions */
- if (s->d1->num_timeouts > DTLS1_MTU_TIMEOUTS &&
- !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) {
- long mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0,
+ if (ssl->d1->num_timeouts > DTLS1_MTU_TIMEOUTS &&
+ !(SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) {
+ long mtu = BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0,
NULL);
if (mtu >= 0 && mtu <= (1 << 30) && (unsigned)mtu >= dtls1_min_mtu()) {
- s->d1->mtu = (unsigned)mtu;
+ ssl->d1->mtu = (unsigned)mtu;
}
}
- if (s->d1->num_timeouts > DTLS1_MAX_TIMEOUTS) {
+ if (ssl->d1->num_timeouts > DTLS1_MAX_TIMEOUTS) {
/* fail the connection, enough alerts have been sent */
OPENSSL_PUT_ERROR(SSL, SSL_R_READ_TIMEOUT_EXPIRED);
return -1;
@@ -307,21 +307,22 @@ static void get_current_time(const SSL *ssl, struct timeval *out_clock) {
#endif
}
-int dtls1_set_handshake_header(SSL *s, int htype, unsigned long len) {
- uint8_t *message = (uint8_t *)s->init_buf->data;
- const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
+int dtls1_set_handshake_header(SSL *ssl, int htype, unsigned long len) {
+ uint8_t *message = (uint8_t *)ssl->init_buf->data;
+ const struct hm_header_st *msg_hdr = &ssl->d1->w_msg_hdr;
uint8_t serialised_header[DTLS1_HM_HEADER_LENGTH];
uint8_t *p = serialised_header;
- s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
- s->d1->next_handshake_write_seq++;
+ ssl->d1->handshake_write_seq = ssl->d1->next_handshake_write_seq;
+ ssl->d1->next_handshake_write_seq++;
- dtls1_set_message_header(s, htype, len, s->d1->handshake_write_seq, 0, len);
- s->init_num = (int)len + DTLS1_HM_HEADER_LENGTH;
- s->init_off = 0;
+ dtls1_set_message_header(ssl, htype, len, ssl->d1->handshake_write_seq, 0,
+ len);
+ ssl->init_num = (int)len + DTLS1_HM_HEADER_LENGTH;
+ ssl->init_off = 0;
/* Buffer the message to handle re-xmits */
- dtls1_buffer_message(s);
+ dtls1_buffer_message(ssl);
/* Add the new message to the handshake hash. Serialize the message
* header as if it were a single fragment. */
@@ -330,11 +331,11 @@ int dtls1_set_handshake_header(SSL *s, int htype, unsigned long len) {
s2n(msg_hdr->seq, p);
l2n3(0, p);
l2n3(msg_hdr->msg_len, p);
- return ssl3_update_handshake_hash(s, serialised_header,
+ return ssl3_update_handshake_hash(ssl, serialised_header,
sizeof(serialised_header)) &&
- ssl3_update_handshake_hash(s, message + DTLS1_HM_HEADER_LENGTH, len);
+ ssl3_update_handshake_hash(ssl, message + DTLS1_HM_HEADER_LENGTH, len);
}
-int dtls1_handshake_write(SSL *s) {
- return dtls1_do_handshake_write(s, dtls1_use_current_epoch);
+int dtls1_handshake_write(SSL *ssl) {
+ return dtls1_do_handshake_write(ssl, dtls1_use_current_epoch);
}
diff --git a/src/ssl/d1_meth.c b/src/ssl/d1_meth.c
index 4dc3404..49a2595 100644
--- a/src/ssl/d1_meth.c
+++ b/src/ssl/d1_meth.c
@@ -67,6 +67,7 @@ static const SSL_PROTOCOL_METHOD DTLS_protocol_method = {
dtls1_connect,
dtls1_get_message,
dtls1_read_app_data,
+ dtls1_read_change_cipher_spec,
dtls1_read_close_notify,
dtls1_write_app_data,
dtls1_dispatch_alert,
diff --git a/src/ssl/d1_pkt.c b/src/ssl/d1_pkt.c
index 8cabdd4..f2ade3a 100644
--- a/src/ssl/d1_pkt.c
+++ b/src/ssl/d1_pkt.c
@@ -124,7 +124,7 @@
#include "internal.h"
-static int do_dtls1_write(SSL *s, int type, const uint8_t *buf,
+static int do_dtls1_write(SSL *ssl, int type, const uint8_t *buf,
unsigned int len, enum dtls1_use_epoch_t use_epoch);
/* dtls1_get_record reads a new input record. On success, it places it in
@@ -164,7 +164,6 @@ again:
SSL3_RECORD *rr = &ssl->s3->rrec;
rr->type = type;
rr->length = (uint16_t)len;
- rr->off = 0;
rr->data = out;
return 1;
@@ -190,6 +189,29 @@ int dtls1_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek) {
return dtls1_read_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf, len, peek);
}
+int dtls1_read_change_cipher_spec(SSL *ssl) {
+ uint8_t byte;
+ int ret = dtls1_read_bytes(ssl, SSL3_RT_CHANGE_CIPHER_SPEC, &byte,
+ 1 /* len */, 0 /* no peek */);
+ if (ret <= 0) {
+ return ret;
+ }
+ assert(ret == 1);
+
+ if (ssl->s3->rrec.length != 0 || byte != SSL3_MT_CCS) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ return -1;
+ }
+
+ if (ssl->msg_callback != NULL) {
+ ssl->msg_callback(0, ssl->version, SSL3_RT_CHANGE_CIPHER_SPEC, &byte, 1,
+ ssl, ssl->msg_callback_arg);
+ }
+
+ return 1;
+}
+
void dtls1_read_close_notify(SSL *ssl) {
/* Bidirectional shutdown doesn't make sense for an unordered transport. DTLS
* alerts also aren't delivered reliably, so we may even time out because the
@@ -201,44 +223,31 @@ void dtls1_read_close_notify(SSL *ssl) {
/* Return up to 'len' payload bytes received in 'type' records.
* 'type' is one of the following:
*
- * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us)
- * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us)
+ * - SSL3_RT_HANDSHAKE (when dtls1_get_message calls us)
+ * - SSL3_RT_CHANGE_CIPHER_SPEC (when dtls1_read_change_cipher_spec calls us)
+ * - SSL3_RT_APPLICATION_DATA (when dtls1_read_app_data calls us)
*
- * If we don't have stored data to work from, read a SSL/TLS record first
- * (possibly multiple records if we still don't have anything to return).
+ * If we don't have stored data to work from, read a DTLS record first (possibly
+ * multiple records if we still don't have anything to return).
*
* This function must handle any surprises the peer may have for us, such as
- * Alert records (e.g. close_notify), ChangeCipherSpec records (not really
- * a surprise, but handled as if it were), or renegotiation requests.
- * Also if record payloads contain fragments too small to process, we store
- * them until there is enough for the respective protocol (the record protocol
- * may use arbitrary fragmentation and even interleaving):
- * Change cipher spec protocol
- * just 1 byte needed, no need for keeping anything stored
- * Alert protocol
- * 2 bytes needed (AlertLevel, AlertDescription)
- * Handshake protocol
- * 4 bytes needed (HandshakeType, uint24 length) -- we just have
- * to detect unexpected Client Hello and Hello Request messages
- * here, anything else is handled by higher layers
- * Application data protocol
- * none of our business
- */
-int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) {
+ * Alert records (e.g. close_notify) and out of records. */
+int dtls1_read_bytes(SSL *ssl, int type, unsigned char *buf, int len, int peek) {
int al, i, ret;
unsigned int n;
SSL3_RECORD *rr;
void (*cb)(const SSL *ssl, int type, int value) = NULL;
- if ((type != SSL3_RT_APPLICATION_DATA && type != SSL3_RT_HANDSHAKE) ||
+ if ((type != SSL3_RT_APPLICATION_DATA && type != SSL3_RT_HANDSHAKE &&
+ type != SSL3_RT_CHANGE_CIPHER_SPEC) ||
(peek && type != SSL3_RT_APPLICATION_DATA)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return -1;
}
- if (!s->in_handshake && SSL_in_init(s)) {
+ if (!ssl->in_handshake && SSL_in_init(ssl)) {
/* type == SSL3_RT_APPLICATION_DATA */
- i = s->handshake_func(s);
+ i = ssl->handshake_func(ssl);
if (i < 0) {
return i;
}
@@ -249,24 +258,24 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) {
}
start:
- s->rwstate = SSL_NOTHING;
+ ssl->rwstate = SSL_NOTHING;
- /* s->s3->rrec.type - is the type of record
- * s->s3->rrec.data - data
- * s->s3->rrec.off - offset into 'data' for next read
- * s->s3->rrec.length - number of bytes. */
- rr = &s->s3->rrec;
+ /* ssl->s3->rrec.type - is the type of record
+ * ssl->s3->rrec.data - data
+ * ssl->s3->rrec.off - offset into 'data' for next read
+ * ssl->s3->rrec.length - number of bytes. */
+ rr = &ssl->s3->rrec;
/* Check for timeout */
- if (DTLSv1_handle_timeout(s) > 0) {
+ if (DTLSv1_handle_timeout(ssl) > 0) {
goto start;
}
/* get new packet if necessary */
if (rr->length == 0) {
- ret = dtls1_get_record(s);
+ ret = dtls1_get_record(ssl);
if (ret <= 0) {
- ret = dtls1_read_failed(s, ret);
+ ret = dtls1_read_failed(ssl, ret);
/* anything other than a timeout is an error */
if (ret <= 0) {
return ret;
@@ -278,31 +287,20 @@ start:
/* we now have a packet which can be read and processed */
- /* |change_cipher_spec is set when we receive a ChangeCipherSpec and reset by
- * ssl3_get_finished. */
- if (s->s3->change_cipher_spec && rr->type != SSL3_RT_HANDSHAKE &&
- rr->type != SSL3_RT_ALERT) {
- /* We now have an unexpected record between CCS and Finished. Most likely
- * the packets were reordered on their way. DTLS is unreliable, so drop the
- * packet and expect the peer to retransmit. */
- rr->length = 0;
- goto start;
- }
-
/* If the other end has shut down, throw anything we read away (even in
* 'peek' mode) */
- if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
+ if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN) {
rr->length = 0;
- s->rwstate = SSL_NOTHING;
+ ssl->rwstate = SSL_NOTHING;
return 0;
}
- if (type == rr->type) { /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */
- /* make sure that we are not getting application data when we
- * are doing a handshake for the first time */
- if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) &&
- (s->aead_read_ctx == NULL)) {
+ if (type == rr->type) {
+ /* Make sure that we are not getting application data when we
+ * are doing a handshake for the first time. */
+ if (SSL_in_init(ssl) && (type == SSL3_RT_APPLICATION_DATA) &&
+ (ssl->aead_read_ctx == NULL)) {
/* TODO(davidben): Is this check redundant with the handshake_func
* check? */
al = SSL_AD_UNEXPECTED_MESSAGE;
@@ -325,14 +323,13 @@ start:
n = (unsigned int)len;
}
- memcpy(buf, &(rr->data[rr->off]), n);
+ memcpy(buf, rr->data, n);
if (!peek) {
rr->length -= n;
- rr->off += n;
+ rr->data += n;
if (rr->length == 0) {
- rr->off = 0;
/* The record has been consumed, so we may now clear the buffer. */
- ssl_read_buffer_discard(s);
+ ssl_read_buffer_discard(ssl);
}
}
@@ -351,41 +348,42 @@ start:
goto f_err;
}
- if (s->msg_callback) {
- s->msg_callback(0, s->version, SSL3_RT_ALERT, &rr->data[rr->off], 2, s,
- s->msg_callback_arg);
+ if (ssl->msg_callback) {
+ ssl->msg_callback(0, ssl->version, SSL3_RT_ALERT, rr->data, 2, ssl,
+ ssl->msg_callback_arg);
}
- const uint8_t alert_level = rr->data[rr->off++];
- const uint8_t alert_descr = rr->data[rr->off++];
+ const uint8_t alert_level = rr->data[0];
+ const uint8_t alert_descr = rr->data[1];
rr->length -= 2;
+ rr->data += 2;
- if (s->info_callback != NULL) {
- cb = s->info_callback;
- } else if (s->ctx->info_callback != NULL) {
- cb = s->ctx->info_callback;
+ if (ssl->info_callback != NULL) {
+ cb = ssl->info_callback;
+ } else if (ssl->ctx->info_callback != NULL) {
+ cb = ssl->ctx->info_callback;
}
if (cb != NULL) {
uint16_t alert = (alert_level << 8) | alert_descr;
- cb(s, SSL_CB_READ_ALERT, alert);
+ cb(ssl, SSL_CB_READ_ALERT, alert);
}
if (alert_level == SSL3_AL_WARNING) {
- s->s3->warn_alert = alert_descr;
+ ssl->s3->warn_alert = alert_descr;
if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
- s->shutdown |= SSL_RECEIVED_SHUTDOWN;
+ ssl->shutdown |= SSL_RECEIVED_SHUTDOWN;
return 0;
}
} else if (alert_level == SSL3_AL_FATAL) {
char tmp[16];
- s->rwstate = SSL_NOTHING;
- s->s3->fatal_alert = alert_descr;
+ ssl->rwstate = SSL_NOTHING;
+ ssl->s3->fatal_alert = alert_descr;
OPENSSL_PUT_ERROR(SSL, SSL_AD_REASON_OFFSET + alert_descr);
BIO_snprintf(tmp, sizeof tmp, "%d", alert_descr);
ERR_add_error_data(2, "SSL alert number ", tmp);
- s->shutdown |= SSL_RECEIVED_SHUTDOWN;
- SSL_CTX_remove_session(s->ctx, s->session);
+ ssl->shutdown |= SSL_RECEIVED_SHUTDOWN;
+ SSL_CTX_remove_session(ssl->ctx, ssl->session);
return 0;
} else {
al = SSL_AD_ILLEGAL_PARAMETER;
@@ -396,89 +394,74 @@ start:
goto start;
}
- if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) {
- /* 'Change Cipher Spec' is just a single byte, so we know exactly what the
- * record payload has to look like */
- if (rr->length != 1 || rr->off != 0 || rr->data[0] != SSL3_MT_CCS) {
- al = SSL_AD_ILLEGAL_PARAMETER;
- OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC);
- goto f_err;
- }
-
+ /* Cross-epoch records are discarded, but we may receive out-of-order
+ * application data between ChangeCipherSpec and Finished or a ChangeCipherSpec
+ * before the appropriate point in the handshake. Those must be silently
+ * discarded.
+ *
+ * However, only allow the out-of-order records in the correct epoch.
+ * Application data must come in the encrypted epoch, and ChangeCipherSpec in
+ * the unencrypted epoch (we never renegotiate). Other cases fall through and
+ * fail with a fatal error. */
+ if ((rr->type == SSL3_RT_APPLICATION_DATA && ssl->aead_read_ctx != NULL) ||
+ (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC && ssl->aead_read_ctx == NULL)) {
rr->length = 0;
+ goto start;
+ }
- if (s->msg_callback) {
- s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, rr->data, 1, s,
- s->msg_callback_arg);
- }
-
- /* We can't process a CCS now, because previous handshake
- * messages are still missing, so just drop it.
- */
- if (!s->d1->change_cipher_spec_ok) {
+ if (rr->type == SSL3_RT_HANDSHAKE) {
+ if (type != SSL3_RT_APPLICATION_DATA) {
+ /* Out-of-order handshake record while looking for ChangeCipherSpec. Drop
+ * it silently. */
+ assert(type == SSL3_RT_CHANGE_CIPHER_SPEC);
+ rr->length = 0;
goto start;
}
- s->d1->change_cipher_spec_ok = 0;
-
- s->s3->change_cipher_spec = 1;
- if (!ssl3_do_change_cipher_spec(s)) {
- goto err;
- }
-
- /* do this whenever CCS is processed */
- dtls1_reset_seq_numbers(s, SSL3_CC_READ);
-
- goto start;
- }
-
- /* Unexpected handshake message. It may be a retransmitted Finished (the only
- * post-CCS message). Otherwise, it's a pre-CCS handshake message from an
- * unsupported renegotiation attempt. */
- if (rr->type == SSL3_RT_HANDSHAKE && !s->in_handshake) {
+ /* Parse the first fragment header to determine if this is a pre-CCS or
+ * post-CCS handshake record. DTLS resets handshake message numbers on each
+ * handshake, so renegotiations and retransmissions are ambiguous. */
if (rr->length < DTLS1_HM_HEADER_LENGTH) {
al = SSL_AD_DECODE_ERROR;
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HANDSHAKE_RECORD);
goto f_err;
}
struct hm_header_st msg_hdr;
- dtls1_get_message_header(&rr->data[rr->off], &msg_hdr);
+ dtls1_get_message_header(rr->data, &msg_hdr);
- /* Ignore a stray Finished from the previous handshake. */
if (msg_hdr.type == SSL3_MT_FINISHED) {
if (msg_hdr.frag_off == 0) {
/* Retransmit our last flight of messages. If the peer sends the second
* Finished, they may not have received ours. Only do this for the
* first fragment, in case the Finished was fragmented. */
- if (dtls1_check_timeout_num(s) < 0) {
+ if (dtls1_check_timeout_num(ssl) < 0) {
return -1;
}
- dtls1_retransmit_buffered_messages(s);
+ dtls1_retransmit_buffered_messages(ssl);
}
rr->length = 0;
goto start;
}
- }
- /* We already handled these. */
- assert(rr->type != SSL3_RT_CHANGE_CIPHER_SPEC && rr->type != SSL3_RT_ALERT);
+ /* Otherwise, this is a pre-CCS handshake message from an unsupported
+ * renegotiation attempt. Fall through to the error path. */
+ }
al = SSL_AD_UNEXPECTED_MESSAGE;
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD);
f_err:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
-err:
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
return -1;
}
-int dtls1_write_app_data(SSL *s, const void *buf_, int len) {
+int dtls1_write_app_data(SSL *ssl, const void *buf_, int len) {
int i;
- if (SSL_in_init(s) && !s->in_handshake) {
- i = s->handshake_func(s);
+ if (SSL_in_init(ssl) && !ssl->in_handshake) {
+ i = ssl->handshake_func(ssl);
if (i < 0) {
return i;
}
@@ -493,33 +476,33 @@ int dtls1_write_app_data(SSL *s, const void *buf_, int len) {
return -1;
}
- i = dtls1_write_bytes(s, SSL3_RT_APPLICATION_DATA, buf_, len,
+ i = dtls1_write_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf_, len,
dtls1_use_current_epoch);
return i;
}
/* Call this to write data in records of type 'type' It will return <= 0 if not
* all data has been sent or non-blocking IO. */
-int dtls1_write_bytes(SSL *s, int type, const void *buf, int len,
+int dtls1_write_bytes(SSL *ssl, int type, const void *buf, int len,
enum dtls1_use_epoch_t use_epoch) {
int i;
assert(len <= SSL3_RT_MAX_PLAIN_LENGTH);
- s->rwstate = SSL_NOTHING;
- i = do_dtls1_write(s, type, buf, len, use_epoch);
+ ssl->rwstate = SSL_NOTHING;
+ i = do_dtls1_write(ssl, type, buf, len, use_epoch);
return i;
}
-static int do_dtls1_write(SSL *s, int type, const uint8_t *buf,
+static int do_dtls1_write(SSL *ssl, int type, const uint8_t *buf,
unsigned int len, enum dtls1_use_epoch_t use_epoch) {
/* There should never be a pending write buffer in DTLS. One can't write half
* a datagram, so the write buffer is always dropped in
* |ssl_write_buffer_flush|. */
- assert(!ssl_write_buffer_is_pending(s));
+ assert(!ssl_write_buffer_is_pending(ssl));
/* If we have an alert to send, lets send it */
- if (s->s3->alert_dispatch) {
- int ret = s->method->ssl_dispatch_alert(s);
+ if (ssl->s3->alert_dispatch) {
+ int ret = ssl->method->ssl_dispatch_alert(ssl);
if (ret <= 0) {
return ret;
}
@@ -535,78 +518,61 @@ static int do_dtls1_write(SSL *s, int type, const uint8_t *buf,
return 0;
}
- size_t max_out = len + ssl_max_seal_overhead(s);
+ size_t max_out = len + ssl_max_seal_overhead(ssl);
uint8_t *out;
size_t ciphertext_len;
- if (!ssl_write_buffer_init(s, &out, max_out) ||
- !dtls_seal_record(s, out, &ciphertext_len, max_out, type, buf, len,
+ if (!ssl_write_buffer_init(ssl, &out, max_out) ||
+ !dtls_seal_record(ssl, out, &ciphertext_len, max_out, type, buf, len,
use_epoch)) {
- ssl_write_buffer_clear(s);
+ ssl_write_buffer_clear(ssl);
return -1;
}
- ssl_write_buffer_set_len(s, ciphertext_len);
+ ssl_write_buffer_set_len(ssl, ciphertext_len);
- int ret = ssl_write_buffer_flush(s);
+ int ret = ssl_write_buffer_flush(ssl);
if (ret <= 0) {
return ret;
}
return (int)len;
}
-int dtls1_dispatch_alert(SSL *s) {
+int dtls1_dispatch_alert(SSL *ssl) {
int i, j;
void (*cb)(const SSL *ssl, int type, int value) = NULL;
uint8_t buf[DTLS1_AL_HEADER_LENGTH];
uint8_t *ptr = &buf[0];
- s->s3->alert_dispatch = 0;
+ ssl->s3->alert_dispatch = 0;
memset(buf, 0x00, sizeof(buf));
- *ptr++ = s->s3->send_alert[0];
- *ptr++ = s->s3->send_alert[1];
+ *ptr++ = ssl->s3->send_alert[0];
+ *ptr++ = ssl->s3->send_alert[1];
- i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf),
+ i = do_dtls1_write(ssl, SSL3_RT_ALERT, &buf[0], sizeof(buf),
dtls1_use_current_epoch);
if (i <= 0) {
- s->s3->alert_dispatch = 1;
+ ssl->s3->alert_dispatch = 1;
} else {
- if (s->s3->send_alert[0] == SSL3_AL_FATAL) {
- (void)BIO_flush(s->wbio);
+ if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) {
+ (void)BIO_flush(ssl->wbio);
}
- if (s->msg_callback) {
- s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, 2, s,
- s->msg_callback_arg);
+ if (ssl->msg_callback) {
+ ssl->msg_callback(1, ssl->version, SSL3_RT_ALERT, ssl->s3->send_alert, 2,
+ ssl, ssl->msg_callback_arg);
}
- if (s->info_callback != NULL) {
- cb = s->info_callback;
- } else if (s->ctx->info_callback != NULL) {
- cb = s->ctx->info_callback;
+ if (ssl->info_callback != NULL) {
+ cb = ssl->info_callback;
+ } else if (ssl->ctx->info_callback != NULL) {
+ cb = ssl->ctx->info_callback;
}
if (cb != NULL) {
- j = (s->s3->send_alert[0] << 8) | s->s3->send_alert[1];
- cb(s, SSL_CB_WRITE_ALERT, j);
+ j = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1];
+ cb(ssl, SSL_CB_WRITE_ALERT, j);
}
}
return i;
}
-
-void dtls1_reset_seq_numbers(SSL *s, int rw) {
- uint8_t *seq;
- unsigned int seq_bytes = sizeof(s->s3->read_sequence);
-
- if (rw & SSL3_CC_READ) {
- seq = s->s3->read_sequence;
- s->d1->r_epoch++;
- memset(&s->d1->bitmap, 0, sizeof(DTLS1_BITMAP));
- } else {
- seq = s->s3->write_sequence;
- memcpy(s->d1->last_write_sequence, seq, sizeof(s->s3->write_sequence));
- s->d1->w_epoch++;
- }
-
- memset(seq, 0x00, seq_bytes);
-}
diff --git a/src/ssl/d1_srtp.c b/src/ssl/d1_srtp.c
index 115bd70..5dba8ef 100644
--- a/src/ssl/d1_srtp.c
+++ b/src/ssl/d1_srtp.c
@@ -133,6 +133,12 @@ const SRTP_PROTECTION_PROFILE kSRTPProfiles[] = {
{
"SRTP_AES128_CM_SHA1_32", SRTP_AES128_CM_SHA1_32,
},
+ {
+ "SRTP_AEAD_AES_128_GCM", SRTP_AEAD_AES_128_GCM,
+ },
+ {
+ "SRTP_AEAD_AES_256_GCM", SRTP_AEAD_AES_256_GCM,
+ },
{0, 0},
};
diff --git a/src/ssl/d1_srvr.c b/src/ssl/d1_srvr.c
index f1e8826..3ba9411 100644
--- a/src/ssl/d1_srvr.c
+++ b/src/ssl/d1_srvr.c
@@ -130,131 +130,131 @@
#include "internal.h"
-int dtls1_accept(SSL *s) {
+int dtls1_accept(SSL *ssl) {
BUF_MEM *buf = NULL;
void (*cb)(const SSL *ssl, int type, int value) = NULL;
uint32_t alg_a;
int ret = -1;
int new_state, state, skip = 0;
- assert(s->handshake_func == dtls1_accept);
- assert(s->server);
- assert(SSL_IS_DTLS(s));
+ assert(ssl->handshake_func == dtls1_accept);
+ assert(ssl->server);
+ assert(SSL_IS_DTLS(ssl));
ERR_clear_error();
ERR_clear_system_error();
- if (s->info_callback != NULL) {
- cb = s->info_callback;
- } else if (s->ctx->info_callback != NULL) {
- cb = s->ctx->info_callback;
+ if (ssl->info_callback != NULL) {
+ cb = ssl->info_callback;
+ } else if (ssl->ctx->info_callback != NULL) {
+ cb = ssl->ctx->info_callback;
}
- s->in_handshake++;
+ ssl->in_handshake++;
for (;;) {
- state = s->state;
+ state = ssl->state;
- switch (s->state) {
+ switch (ssl->state) {
case SSL_ST_ACCEPT:
if (cb != NULL) {
- cb(s, SSL_CB_HANDSHAKE_START, 1);
+ cb(ssl, SSL_CB_HANDSHAKE_START, 1);
}
- if (s->init_buf == NULL) {
+ if (ssl->init_buf == NULL) {
buf = BUF_MEM_new();
if (buf == NULL || !BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
ret = -1;
goto end;
}
- s->init_buf = buf;
+ ssl->init_buf = buf;
buf = NULL;
}
- s->init_num = 0;
+ ssl->init_num = 0;
- if (!ssl_init_wbio_buffer(s, 1)) {
+ if (!ssl_init_wbio_buffer(ssl, 1)) {
ret = -1;
goto end;
}
- if (!ssl3_init_handshake_buffer(s)) {
+ if (!ssl3_init_handshake_buffer(ssl)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
ret = -1;
goto end;
}
- s->state = SSL3_ST_SR_CLNT_HELLO_A;
+ ssl->state = SSL3_ST_SR_CLNT_HELLO_A;
break;
case SSL3_ST_SR_CLNT_HELLO_A:
case SSL3_ST_SR_CLNT_HELLO_B:
case SSL3_ST_SR_CLNT_HELLO_C:
case SSL3_ST_SR_CLNT_HELLO_D:
- s->shutdown = 0;
- ret = ssl3_get_client_hello(s);
+ ssl->shutdown = 0;
+ ret = ssl3_get_client_hello(ssl);
if (ret <= 0) {
goto end;
}
- dtls1_stop_timer(s);
- s->state = SSL3_ST_SW_SRVR_HELLO_A;
- s->init_num = 0;
+ dtls1_stop_timer(ssl);
+ ssl->state = SSL3_ST_SW_SRVR_HELLO_A;
+ ssl->init_num = 0;
break;
case SSL3_ST_SW_SRVR_HELLO_A:
case SSL3_ST_SW_SRVR_HELLO_B:
- dtls1_start_timer(s);
- ret = ssl3_send_server_hello(s);
+ dtls1_start_timer(ssl);
+ ret = ssl3_send_server_hello(ssl);
if (ret <= 0) {
goto end;
}
- if (s->hit) {
- if (s->tlsext_ticket_expected) {
- s->state = SSL3_ST_SW_SESSION_TICKET_A;
+ if (ssl->hit) {
+ if (ssl->tlsext_ticket_expected) {
+ ssl->state = SSL3_ST_SW_SESSION_TICKET_A;
} else {
- s->state = SSL3_ST_SW_CHANGE_A;
+ ssl->state = SSL3_ST_SW_CHANGE_A;
}
} else {
- s->state = SSL3_ST_SW_CERT_A;
+ ssl->state = SSL3_ST_SW_CERT_A;
}
- s->init_num = 0;
+ ssl->init_num = 0;
break;
case SSL3_ST_SW_CERT_A:
case SSL3_ST_SW_CERT_B:
- if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) {
- dtls1_start_timer(s);
- ret = ssl3_send_server_certificate(s);
+ if (ssl_cipher_has_server_public_key(ssl->s3->tmp.new_cipher)) {
+ dtls1_start_timer(ssl);
+ ret = ssl3_send_server_certificate(ssl);
if (ret <= 0) {
goto end;
}
- if (s->s3->tmp.certificate_status_expected) {
- s->state = SSL3_ST_SW_CERT_STATUS_A;
+ if (ssl->s3->tmp.certificate_status_expected) {
+ ssl->state = SSL3_ST_SW_CERT_STATUS_A;
} else {
- s->state = SSL3_ST_SW_KEY_EXCH_A;
+ ssl->state = SSL3_ST_SW_KEY_EXCH_A;
}
} else {
skip = 1;
- s->state = SSL3_ST_SW_KEY_EXCH_A;
+ ssl->state = SSL3_ST_SW_KEY_EXCH_A;
}
- s->init_num = 0;
+ ssl->init_num = 0;
break;
case SSL3_ST_SW_CERT_STATUS_A:
case SSL3_ST_SW_CERT_STATUS_B:
- ret = ssl3_send_certificate_status(s);
+ ret = ssl3_send_certificate_status(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_SW_KEY_EXCH_A;
- s->init_num = 0;
+ ssl->state = SSL3_ST_SW_KEY_EXCH_A;
+ ssl->init_num = 0;
break;
case SSL3_ST_SW_KEY_EXCH_A:
case SSL3_ST_SW_KEY_EXCH_B:
case SSL3_ST_SW_KEY_EXCH_C:
- alg_a = s->s3->tmp.new_cipher->algorithm_auth;
+ alg_a = ssl->s3->tmp.new_cipher->algorithm_auth;
/* Send a ServerKeyExchange message if:
* - The key exchange is ephemeral or anonymous
@@ -264,10 +264,10 @@ int dtls1_accept(SSL *s) {
* TODO(davidben): This logic is currently duplicated
* in s3_srvr.c. Fix this. In the meantime, keep them
* in sync. */
- if (ssl_cipher_requires_server_key_exchange(s->s3->tmp.new_cipher) ||
- ((alg_a & SSL_aPSK) && s->psk_identity_hint)) {
- dtls1_start_timer(s);
- ret = ssl3_send_server_key_exchange(s);
+ if (ssl_cipher_requires_server_key_exchange(ssl->s3->tmp.new_cipher) ||
+ ((alg_a & SSL_aPSK) && ssl->psk_identity_hint)) {
+ dtls1_start_timer(ssl);
+ ret = ssl3_send_server_key_exchange(ssl);
if (ret <= 0) {
goto end;
}
@@ -275,176 +275,187 @@ int dtls1_accept(SSL *s) {
skip = 1;
}
- s->state = SSL3_ST_SW_CERT_REQ_A;
- s->init_num = 0;
+ ssl->state = SSL3_ST_SW_CERT_REQ_A;
+ ssl->init_num = 0;
break;
case SSL3_ST_SW_CERT_REQ_A:
case SSL3_ST_SW_CERT_REQ_B:
- if (s->s3->tmp.cert_request) {
- dtls1_start_timer(s);
- ret = ssl3_send_certificate_request(s);
+ if (ssl->s3->tmp.cert_request) {
+ dtls1_start_timer(ssl);
+ ret = ssl3_send_certificate_request(ssl);
if (ret <= 0) {
goto end;
}
} else {
skip = 1;
}
- s->state = SSL3_ST_SW_SRVR_DONE_A;
- s->init_num = 0;
+ ssl->state = SSL3_ST_SW_SRVR_DONE_A;
+ ssl->init_num = 0;
break;
case SSL3_ST_SW_SRVR_DONE_A:
case SSL3_ST_SW_SRVR_DONE_B:
- dtls1_start_timer(s);
- ret = ssl3_send_server_done(s);
+ dtls1_start_timer(ssl);
+ ret = ssl3_send_server_done(ssl);
if (ret <= 0) {
goto end;
}
- s->s3->tmp.next_state = SSL3_ST_SR_CERT_A;
- s->state = SSL3_ST_SW_FLUSH;
- s->init_num = 0;
+ ssl->s3->tmp.next_state = SSL3_ST_SR_CERT_A;
+ ssl->state = SSL3_ST_SW_FLUSH;
+ ssl->init_num = 0;
break;
case SSL3_ST_SW_FLUSH:
- s->rwstate = SSL_WRITING;
- if (BIO_flush(s->wbio) <= 0) {
+ ssl->rwstate = SSL_WRITING;
+ if (BIO_flush(ssl->wbio) <= 0) {
ret = -1;
goto end;
}
- s->rwstate = SSL_NOTHING;
- s->state = s->s3->tmp.next_state;
+ ssl->rwstate = SSL_NOTHING;
+ ssl->state = ssl->s3->tmp.next_state;
break;
case SSL3_ST_SR_CERT_A:
case SSL3_ST_SR_CERT_B:
- if (s->s3->tmp.cert_request) {
- ret = ssl3_get_client_certificate(s);
+ if (ssl->s3->tmp.cert_request) {
+ ret = ssl3_get_client_certificate(ssl);
if (ret <= 0) {
goto end;
}
}
- s->init_num = 0;
- s->state = SSL3_ST_SR_KEY_EXCH_A;
+ ssl->init_num = 0;
+ ssl->state = SSL3_ST_SR_KEY_EXCH_A;
break;
case SSL3_ST_SR_KEY_EXCH_A:
case SSL3_ST_SR_KEY_EXCH_B:
case SSL3_ST_SR_KEY_EXCH_C:
- ret = ssl3_get_client_key_exchange(s);
+ ret = ssl3_get_client_key_exchange(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_SR_CERT_VRFY_A;
- s->init_num = 0;
+ ssl->state = SSL3_ST_SR_CERT_VRFY_A;
+ ssl->init_num = 0;
break;
case SSL3_ST_SR_CERT_VRFY_A:
case SSL3_ST_SR_CERT_VRFY_B:
- ret = ssl3_get_cert_verify(s);
+ ret = ssl3_get_cert_verify(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_SR_FINISHED_A;
- s->init_num = 0;
+ ssl->state = SSL3_ST_SR_CHANGE;
+ ssl->init_num = 0;
+ break;
+
+ case SSL3_ST_SR_CHANGE:
+ ret = ssl->method->ssl_read_change_cipher_spec(ssl);
+ if (ret <= 0) {
+ goto end;
+ }
+
+ if (!ssl3_do_change_cipher_spec(ssl)) {
+ ret = -1;
+ goto end;
+ }
+
+ ssl->state = SSL3_ST_SR_FINISHED_A;
break;
case SSL3_ST_SR_FINISHED_A:
case SSL3_ST_SR_FINISHED_B:
- s->d1->change_cipher_spec_ok = 1;
- ret =
- ssl3_get_finished(s, SSL3_ST_SR_FINISHED_A, SSL3_ST_SR_FINISHED_B);
+ ret = ssl3_get_finished(ssl, SSL3_ST_SR_FINISHED_A,
+ SSL3_ST_SR_FINISHED_B);
if (ret <= 0) {
goto end;
}
- dtls1_stop_timer(s);
- if (s->hit) {
- s->state = SSL_ST_OK;
- } else if (s->tlsext_ticket_expected) {
- s->state = SSL3_ST_SW_SESSION_TICKET_A;
+ dtls1_stop_timer(ssl);
+ if (ssl->hit) {
+ ssl->state = SSL_ST_OK;
+ } else if (ssl->tlsext_ticket_expected) {
+ ssl->state = SSL3_ST_SW_SESSION_TICKET_A;
} else {
- s->state = SSL3_ST_SW_CHANGE_A;
+ ssl->state = SSL3_ST_SW_CHANGE_A;
}
- s->init_num = 0;
+ ssl->init_num = 0;
break;
case SSL3_ST_SW_SESSION_TICKET_A:
case SSL3_ST_SW_SESSION_TICKET_B:
- ret = ssl3_send_new_session_ticket(s);
+ ret = ssl3_send_new_session_ticket(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_SW_CHANGE_A;
- s->init_num = 0;
+ ssl->state = SSL3_ST_SW_CHANGE_A;
+ ssl->init_num = 0;
break;
case SSL3_ST_SW_CHANGE_A:
case SSL3_ST_SW_CHANGE_B:
- s->session->cipher = s->s3->tmp.new_cipher;
- if (!s->enc_method->setup_key_block(s)) {
+ ssl->session->cipher = ssl->s3->tmp.new_cipher;
+ if (!ssl->enc_method->setup_key_block(ssl)) {
ret = -1;
goto end;
}
- ret = dtls1_send_change_cipher_spec(s, SSL3_ST_SW_CHANGE_A,
+ ret = dtls1_send_change_cipher_spec(ssl, SSL3_ST_SW_CHANGE_A,
SSL3_ST_SW_CHANGE_B);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_SW_FINISHED_A;
- s->init_num = 0;
+ ssl->state = SSL3_ST_SW_FINISHED_A;
+ ssl->init_num = 0;
- if (!s->enc_method->change_cipher_state(
- s, SSL3_CHANGE_CIPHER_SERVER_WRITE)) {
+ if (!ssl->enc_method->change_cipher_state(
+ ssl, SSL3_CHANGE_CIPHER_SERVER_WRITE)) {
ret = -1;
goto end;
}
-
- dtls1_reset_seq_numbers(s, SSL3_CC_WRITE);
break;
case SSL3_ST_SW_FINISHED_A:
case SSL3_ST_SW_FINISHED_B:
- ret =
- ssl3_send_finished(s, SSL3_ST_SW_FINISHED_A, SSL3_ST_SW_FINISHED_B,
- s->enc_method->server_finished_label,
- s->enc_method->server_finished_label_len);
+ ret = ssl3_send_finished(ssl, SSL3_ST_SW_FINISHED_A,
+ SSL3_ST_SW_FINISHED_B,
+ ssl->enc_method->server_finished_label,
+ ssl->enc_method->server_finished_label_len);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_SW_FLUSH;
- if (s->hit) {
- s->s3->tmp.next_state = SSL3_ST_SR_FINISHED_A;
+ ssl->state = SSL3_ST_SW_FLUSH;
+ if (ssl->hit) {
+ ssl->s3->tmp.next_state = SSL3_ST_SR_CHANGE;
} else {
- s->s3->tmp.next_state = SSL_ST_OK;
+ ssl->s3->tmp.next_state = SSL_ST_OK;
}
- s->init_num = 0;
+ ssl->init_num = 0;
break;
case SSL_ST_OK:
- ssl3_cleanup_key_block(s);
+ ssl3_cleanup_key_block(ssl);
/* remove buffering on output */
- ssl_free_wbio_buffer(s);
+ ssl_free_wbio_buffer(ssl);
- s->init_num = 0;
- s->s3->initial_handshake_complete = 1;
+ ssl->init_num = 0;
+ ssl->s3->initial_handshake_complete = 1;
- ssl_update_cache(s, SSL_SESS_CACHE_SERVER);
+ ssl_update_cache(ssl, SSL_SESS_CACHE_SERVER);
if (cb != NULL) {
- cb(s, SSL_CB_HANDSHAKE_DONE, 1);
+ cb(ssl, SSL_CB_HANDSHAKE_DONE, 1);
}
ret = 1;
/* done handshaking, next message is client hello */
- s->d1->handshake_read_seq = 0;
+ ssl->d1->handshake_read_seq = 0;
/* next message is server hello */
- s->d1->handshake_write_seq = 0;
- s->d1->next_handshake_write_seq = 0;
+ ssl->d1->handshake_write_seq = 0;
+ ssl->d1->next_handshake_write_seq = 0;
goto end;
default:
@@ -453,22 +464,22 @@ int dtls1_accept(SSL *s) {
goto end;
}
- if (!s->s3->tmp.reuse_message && !skip) {
- if (cb != NULL && s->state != state) {
- new_state = s->state;
- s->state = state;
- cb(s, SSL_CB_ACCEPT_LOOP, 1);
- s->state = new_state;
+ if (!ssl->s3->tmp.reuse_message && !skip) {
+ if (cb != NULL && ssl->state != state) {
+ new_state = ssl->state;
+ ssl->state = state;
+ cb(ssl, SSL_CB_ACCEPT_LOOP, 1);
+ ssl->state = new_state;
}
}
skip = 0;
}
end:
- s->in_handshake--;
+ ssl->in_handshake--;
BUF_MEM_free(buf);
if (cb != NULL) {
- cb(s, SSL_CB_ACCEPT_EXIT, ret);
+ cb(ssl, SSL_CB_ACCEPT_EXIT, ret);
}
return ret;
}
diff --git a/src/ssl/internal.h b/src/ssl/internal.h
index 520131e..5acb598 100644
--- a/src/ssl/internal.h
+++ b/src/ssl/internal.h
@@ -155,7 +155,7 @@
#include <winsock2.h>
#pragma warning(pop)
#else
-#include <sys/types.h>
+#include <sys/time.h>
#endif
@@ -183,6 +183,7 @@
#define SSL_AES256GCM 0x00000020L
#define SSL_CHACHA20POLY1305_OLD 0x00000040L
#define SSL_eNULL 0x00000080L
+#define SSL_CHACHA20POLY1305 0x00000100L
#define SSL_AES (SSL_AES128 | SSL_AES256 | SSL_AES128GCM | SSL_AES256GCM)
@@ -194,15 +195,6 @@
/* SSL_AEAD is set for all AEADs. */
#define SSL_AEAD 0x00000010L
-/* Bits for |algorithm_ssl| (protocol version). These denote the first protocol
- * version which introduced the cipher.
- *
- * TODO(davidben): These are extremely confusing, both in code and in
- * cipher rules. Try to remove them. */
-#define SSL_SSLV3 0x00000002L
-#define SSL_TLSV1 SSL_SSLV3
-#define SSL_TLSV1_2 0x00000004L
-
/* Bits for |algorithm_prf| (handshake digest). */
#define SSL_HANDSHAKE_MAC_DEFAULT 0x1
#define SSL_HANDSHAKE_MAC_SHA256 0x2
@@ -212,11 +204,6 @@
* one, update the table in ssl_cipher.c. */
#define SSL_MAX_DIGEST 4
-/* Bits for |algo_strength|, cipher strength information. */
-#define SSL_MEDIUM 0x00000001L
-#define SSL_HIGH 0x00000002L
-#define SSL_FIPS 0x00000004L
-
/* ssl_cipher_get_evp_aead sets |*out_aead| to point to the correct EVP_AEAD
* object for |cipher| protocol version |version|. It sets |*out_mac_secret_len|
* and |*out_fixed_iv_len| to the MAC key length and fixed IV length,
@@ -280,7 +267,7 @@ struct ssl_aead_ctx_st {
EVP_AEAD_CTX ctx;
/* fixed_nonce contains any bytes of the nonce that are fixed for all
* records. */
- uint8_t fixed_nonce[8];
+ uint8_t fixed_nonce[12];
uint8_t fixed_nonce_len, variable_nonce_len;
/* variable_nonce_included_in_record is non-zero if the variable nonce
* for a record is included as a prefix before the ciphertext. */
@@ -295,6 +282,9 @@ struct ssl_aead_ctx_st {
/* omit_version_in_ad is non-zero if the version should be omitted
* in the AEAD's ad parameter. */
char omit_version_in_ad;
+ /* xor_fixed_nonce is non-zero if the fixed nonce should be XOR'd into the
+ * variable nonce rather than prepended. */
+ char xor_fixed_nonce;
} /* SSL_AEAD_CTX */;
/* SSL_AEAD_CTX_new creates a newly-allocated |SSL_AEAD_CTX| using the supplied
@@ -517,13 +507,69 @@ int ssl3_init_handshake_hash(SSL *ssl);
void ssl3_free_handshake_buffer(SSL *ssl);
/* ssl3_free_handshake_hash releases the handshake hash. */
-void ssl3_free_handshake_hash(SSL *s);
+void ssl3_free_handshake_hash(SSL *ssl);
/* ssl3_update_handshake_hash adds |in| to the handshake buffer and handshake
* hash, whichever is enabled. It returns one on success and zero on failure. */
int ssl3_update_handshake_hash(SSL *ssl, const uint8_t *in, size_t in_len);
+/* ECDH curves. */
+
+#define SSL_CURVE_SECP256R1 23
+#define SSL_CURVE_SECP384R1 24
+#define SSL_CURVE_SECP521R1 25
+#define SSL_CURVE_ECDH_X25519 29
+
+/* An SSL_ECDH_METHOD is an implementation of ECDH-like key exchanges for
+ * TLS. */
+struct ssl_ecdh_method_st {
+ int nid;
+ uint16_t curve_id;
+ const char name[8];
+
+ /* cleanup releases state in |ctx|. */
+ void (*cleanup)(SSL_ECDH_CTX *ctx);
+
+ /* generate_keypair generates a keypair and writes the public value to
+ * |out_public_key|. It returns one on success and zero on error. */
+ int (*generate_keypair)(SSL_ECDH_CTX *ctx, CBB *out_public_key);
+
+ /* compute_secret performs a key exchange against |peer_key| and, on
+ * success, returns one and sets |*out_secret| and |*out_secret_len| to
+ * a newly-allocated buffer containing the shared secret. The caller must
+ * release this buffer with |OPENSSL_free|. Otherwise, it returns zero and
+ * sets |*out_alert| to an alert to send to the peer. */
+ int (*compute_secret)(SSL_ECDH_CTX *ctx, uint8_t **out_secret,
+ size_t *out_secret_len, uint8_t *out_alert,
+ const uint8_t *peer_key, size_t peer_key_len);
+} /* SSL_ECDH_METHOD */;
+
+/* ssl_nid_to_curve_id looks up the curve corresponding to |nid|. On success, it
+ * sets |*out_curve_id| to the curve ID and returns one. Otherwise, it returns
+ * zero. */
+int ssl_nid_to_curve_id(uint16_t *out_curve_id, int nid);
+
+/* SSL_ECDH_CTX_init sets up |ctx| for use with curve |curve_id|. It returns one
+ * on success and zero on error. */
+int SSL_ECDH_CTX_init(SSL_ECDH_CTX *ctx, uint16_t curve_id);
+
+/* SSL_ECDH_CTX_init_for_dhe sets up |ctx| for use with legacy DHE-based ciphers
+ * where the server specifies a group. It takes ownership of |params|. */
+void SSL_ECDH_CTX_init_for_dhe(SSL_ECDH_CTX *ctx, DH *params);
+
+/* SSL_ECDH_CTX_cleanup releases memory associated with |ctx|. It is legal to
+ * call it in the zero state. */
+void SSL_ECDH_CTX_cleanup(SSL_ECDH_CTX *ctx);
+
+/* The following functions call the corresponding method of
+ * |SSL_ECDH_METHOD|. */
+int SSL_ECDH_CTX_generate_keypair(SSL_ECDH_CTX *ctx, CBB *out_public_key);
+int SSL_ECDH_CTX_compute_secret(SSL_ECDH_CTX *ctx, uint8_t **out_secret,
+ size_t *out_secret_len, uint8_t *out_alert,
+ const uint8_t *peer_key, size_t peer_key_len);
+
+
/* Transport buffers. */
/* ssl_read_buffer returns a pointer to contents of the read buffer. */
@@ -688,24 +734,15 @@ void ssl_write_buffer_clear(SSL *ssl);
#define TLSEXT_CHANNEL_ID_SIZE 128
/* Check if an SSL structure is using DTLS */
-#define SSL_IS_DTLS(s) (s->method->is_dtls)
+#define SSL_IS_DTLS(ssl) (ssl->method->is_dtls)
/* See if we need explicit IV */
-#define SSL_USE_EXPLICIT_IV(s) \
- (s->enc_method->enc_flags & SSL_ENC_FLAG_EXPLICIT_IV)
+#define SSL_USE_EXPLICIT_IV(ssl) \
+ (ssl->enc_method->enc_flags & SSL_ENC_FLAG_EXPLICIT_IV)
/* See if we use signature algorithms extension and signature algorithm before
* signatures. */
-#define SSL_USE_SIGALGS(s) (s->enc_method->enc_flags & SSL_ENC_FLAG_SIGALGS)
-
-/* SSL_kRSA <- RSA_ENC | (RSA_TMP & RSA_SIGN) |
- * <- (EXPORT & (RSA_ENC | RSA_TMP) & RSA_SIGN)
- * SSL_kDH <- DH_ENC & (RSA_ENC | RSA_SIGN | DSA_SIGN)
- * SSL_kDHE <- RSA_ENC | RSA_SIGN | DSA_SIGN
- * SSL_aRSA <- RSA_ENC | RSA_SIGN
- * SSL_aDSS <- DSA_SIGN */
+#define SSL_USE_SIGALGS(ssl) (ssl->enc_method->enc_flags & SSL_ENC_FLAG_SIGALGS)
/* From RFC4492, used in encoding the curve type in ECParameters */
-#define EXPLICIT_PRIME_CURVE_TYPE 1
-#define EXPLICIT_CHAR2_CURVE_TYPE 2
#define NAMED_CURVE_TYPE 3
enum ssl_hash_message_t {
@@ -740,14 +777,6 @@ typedef struct cert_st {
DH *dh_tmp;
DH *(*dh_tmp_cb)(SSL *ssl, int is_export, int keysize);
- /* ecdh_nid, if not |NID_undef|, is the NID of the curve to use for ephemeral
- * ECDH keys. If unset, |ecdh_tmp_cb| is consulted. */
- int ecdh_nid;
- /* ecdh_tmp_cb is a callback for selecting the curve to use for ephemeral ECDH
- * keys. If NULL, a curve is selected automatically. See
- * |SSL_CTX_set_tmp_ecdh_callback|. */
- EC_KEY *(*ecdh_tmp_cb)(SSL *ssl, int is_export, int keysize);
-
/* peer_sigalgs are the algorithm/hash pairs that the peer supports. These
* are taken from the contents of signature algorithms extension for a server
* or from the CertificateRequest for a client. */
@@ -785,26 +814,27 @@ struct ssl_method_st {
struct ssl_protocol_method_st {
/* is_dtls is one if the protocol is DTLS and zero otherwise. */
char is_dtls;
- int (*ssl_new)(SSL *s);
- void (*ssl_free)(SSL *s);
- int (*ssl_accept)(SSL *s);
- int (*ssl_connect)(SSL *s);
- long (*ssl_get_message)(SSL *s, int header_state, int body_state,
+ int (*ssl_new)(SSL *ssl);
+ void (*ssl_free)(SSL *ssl);
+ int (*ssl_accept)(SSL *ssl);
+ int (*ssl_connect)(SSL *ssl);
+ long (*ssl_get_message)(SSL *ssl, int header_state, int body_state,
int msg_type, long max,
enum ssl_hash_message_t hash_message, int *ok);
- int (*ssl_read_app_data)(SSL *s, uint8_t *buf, int len, int peek);
- void (*ssl_read_close_notify)(SSL *s);
- int (*ssl_write_app_data)(SSL *s, const void *buf_, int len);
- int (*ssl_dispatch_alert)(SSL *s);
+ int (*ssl_read_app_data)(SSL *ssl, uint8_t *buf, int len, int peek);
+ int (*ssl_read_change_cipher_spec)(SSL *ssl);
+ void (*ssl_read_close_notify)(SSL *ssl);
+ int (*ssl_write_app_data)(SSL *ssl, const void *buf_, int len);
+ int (*ssl_dispatch_alert)(SSL *ssl);
/* supports_cipher returns one if |cipher| is supported by this protocol and
* zero otherwise. */
int (*supports_cipher)(const SSL_CIPHER *cipher);
/* Handshake header length */
unsigned int hhlen;
/* Set the handshake header */
- int (*set_handshake_header)(SSL *s, int type, unsigned long len);
+ int (*set_handshake_header)(SSL *ssl, int type, unsigned long len);
/* Write out handshake message */
- int (*do_write)(SSL *s);
+ int (*do_write)(SSL *ssl);
};
/* This is for the SSLv3/TLSv1.0 differences in crypto/hash stuff It is a bit
@@ -828,12 +858,12 @@ struct ssl3_enc_method {
unsigned int enc_flags;
};
-#define SSL_HM_HEADER_LENGTH(s) s->method->hhlen
-#define ssl_handshake_start(s) \
- (((uint8_t *)s->init_buf->data) + s->method->hhlen)
-#define ssl_set_handshake_header(s, htype, len) \
- s->method->set_handshake_header(s, htype, len)
-#define ssl_do_write(s) s->method->do_write(s)
+#define SSL_HM_HEADER_LENGTH(ssl) ssl->method->hhlen
+#define ssl_handshake_start(ssl) \
+ (((uint8_t *)ssl->init_buf->data) + ssl->method->hhlen)
+#define ssl_set_handshake_header(ssl, htype, len) \
+ ssl->method->set_handshake_header(ssl, htype, len)
+#define ssl_do_write(ssl) ssl->method->do_write(ssl)
/* Values for enc_flags */
@@ -933,8 +963,6 @@ typedef struct dtls1_state_st {
/* Timeout duration */
unsigned short timeout_duration;
-
- unsigned int change_cipher_spec_ok;
} DTLS1_STATE;
extern const SSL3_ENC_METHOD TLSv1_enc_data;
@@ -943,8 +971,8 @@ extern const SSL3_ENC_METHOD TLSv1_2_enc_data;
extern const SSL3_ENC_METHOD SSLv3_enc_data;
extern const SRTP_PROTECTION_PROFILE kSRTPProfiles[];
-void ssl_clear_cipher_ctx(SSL *s);
-int ssl_clear_bad_session(SSL *s);
+void ssl_clear_cipher_ctx(SSL *ssl);
+int ssl_clear_bad_session(SSL *ssl);
CERT *ssl_cert_new(void);
CERT *ssl_cert_dup(CERT *cert);
void ssl_cert_clear_certs(CERT *c);
@@ -967,14 +995,10 @@ enum ssl_session_result_t ssl_get_prev_session(
SSL *ssl, SSL_SESSION **out_session, int *out_send_ticket,
const struct ssl_early_callback_ctx *ctx);
-STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs);
-struct ssl_cipher_preference_list_st *ssl_cipher_preference_list_dup(
- struct ssl_cipher_preference_list_st *cipher_list);
+STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *ssl, const CBS *cbs);
void ssl_cipher_preference_list_free(
struct ssl_cipher_preference_list_st *cipher_list);
-struct ssl_cipher_preference_list_st *ssl_cipher_preference_list_from_ciphers(
- STACK_OF(SSL_CIPHER) *ciphers);
-struct ssl_cipher_preference_list_st *ssl_get_cipher_preferences(SSL *s);
+struct ssl_cipher_preference_list_st *ssl_get_cipher_preferences(SSL *ssl);
int ssl_cert_set0_chain(CERT *cert, STACK_OF(X509) *chain);
int ssl_cert_set1_chain(CERT *cert, STACK_OF(X509) *chain);
@@ -984,42 +1008,42 @@ void ssl_cert_set_cert_cb(CERT *cert,
int (*cb)(SSL *ssl, void *arg), void *arg);
int ssl_verify_cert_chain(SSL *ssl, STACK_OF(X509) *cert_chain);
-int ssl_add_cert_chain(SSL *s, unsigned long *l);
+int ssl_add_cert_chain(SSL *ssl, unsigned long *l);
void ssl_update_cache(SSL *ssl, int mode);
/* ssl_get_compatible_server_ciphers determines the key exchange and
* authentication cipher suite masks compatible with the server configuration
- * and current ClientHello parameters of |s|. It sets |*out_mask_k| to the key
+ * and current ClientHello parameters of |ssl|. It sets |*out_mask_k| to the key
* exchange mask and |*out_mask_a| to the authentication mask. */
-void ssl_get_compatible_server_ciphers(SSL *s, uint32_t *out_mask_k,
+void ssl_get_compatible_server_ciphers(SSL *ssl, uint32_t *out_mask_k,
uint32_t *out_mask_a);
-STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s);
+STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *ssl);
int ssl_verify_alarm_type(long type);
/* ssl_fill_hello_random fills a client_random or server_random field of length
* |len|. It returns one on success and zero on failure. */
int ssl_fill_hello_random(uint8_t *out, size_t len, int is_server);
-int ssl3_send_server_certificate(SSL *s);
-int ssl3_send_new_session_ticket(SSL *s);
-int ssl3_send_certificate_status(SSL *s);
-int ssl3_get_finished(SSL *s, int state_a, int state_b);
-int ssl3_send_change_cipher_spec(SSL *s, int state_a, int state_b);
-int ssl3_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret,
+int ssl3_send_server_certificate(SSL *ssl);
+int ssl3_send_new_session_ticket(SSL *ssl);
+int ssl3_send_certificate_status(SSL *ssl);
+int ssl3_get_finished(SSL *ssl, int state_a, int state_b);
+int ssl3_send_change_cipher_spec(SSL *ssl, int state_a, int state_b);
+int ssl3_prf(SSL *ssl, uint8_t *out, size_t out_len, const uint8_t *secret,
size_t secret_len, const char *label, size_t label_len,
const uint8_t *seed1, size_t seed1_len,
const uint8_t *seed2, size_t seed2_len);
-void ssl3_cleanup_key_block(SSL *s);
-int ssl3_do_write(SSL *s, int type);
-int ssl3_send_alert(SSL *s, int level, int desc);
-int ssl3_get_req_cert_type(SSL *s, uint8_t *p);
-long ssl3_get_message(SSL *s, int header_state, int body_state, int msg_type,
+void ssl3_cleanup_key_block(SSL *ssl);
+int ssl3_do_write(SSL *ssl, int type);
+int ssl3_send_alert(SSL *ssl, int level, int desc);
+int ssl3_get_req_cert_type(SSL *ssl, uint8_t *p);
+long ssl3_get_message(SSL *ssl, int header_state, int body_state, int msg_type,
long max, enum ssl_hash_message_t hash_message, int *ok);
/* ssl3_hash_current_message incorporates the current handshake message into the
* handshake hash. It returns one on success and zero on allocation failure. */
-int ssl3_hash_current_message(SSL *s);
+int ssl3_hash_current_message(SSL *ssl);
/* ssl3_cert_verify_hash writes the CertificateVerify hash into the bytes
* pointed to by |out| and writes the number of bytes to |*out_len|. |out| must
@@ -1027,29 +1051,29 @@ int ssl3_hash_current_message(SSL *s);
* for the hash function, otherwise the hash function depends on |pkey_type|
* and is written to |*out_md|. It returns one on success and zero on
* failure. */
-int ssl3_cert_verify_hash(SSL *s, uint8_t *out, size_t *out_len,
+int ssl3_cert_verify_hash(SSL *ssl, uint8_t *out, size_t *out_len,
const EVP_MD **out_md, int pkey_type);
-int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen);
+int ssl3_send_finished(SSL *ssl, int a, int b, const char *sender, int slen);
int ssl3_supports_cipher(const SSL_CIPHER *cipher);
-int ssl3_dispatch_alert(SSL *s);
-int ssl3_expect_change_cipher_spec(SSL *s);
+int ssl3_dispatch_alert(SSL *ssl);
int ssl3_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek);
+int ssl3_read_change_cipher_spec(SSL *ssl);
void ssl3_read_close_notify(SSL *ssl);
-int ssl3_read_bytes(SSL *s, int type, uint8_t *buf, int len, int peek);
+int ssl3_read_bytes(SSL *ssl, int type, uint8_t *buf, int len, int peek);
int ssl3_write_app_data(SSL *ssl, const void *buf, int len);
-int ssl3_write_bytes(SSL *s, int type, const void *buf, int len);
-int ssl3_final_finish_mac(SSL *s, const char *sender, int slen, uint8_t *p);
-int ssl3_cert_verify_mac(SSL *s, int md_nid, uint8_t *p);
-int ssl3_output_cert_chain(SSL *s);
+int ssl3_write_bytes(SSL *ssl, int type, const void *buf, int len);
+int ssl3_final_finish_mac(SSL *ssl, const char *sender, int slen, uint8_t *p);
+int ssl3_cert_verify_mac(SSL *ssl, int md_nid, uint8_t *p);
+int ssl3_output_cert_chain(SSL *ssl);
const SSL_CIPHER *ssl3_choose_cipher(
SSL *ssl, STACK_OF(SSL_CIPHER) *clnt,
struct ssl_cipher_preference_list_st *srvr);
-int ssl3_new(SSL *s);
-void ssl3_free(SSL *s);
-int ssl3_accept(SSL *s);
-int ssl3_connect(SSL *s);
+int ssl3_new(SSL *ssl);
+void ssl3_free(SSL *ssl);
+int ssl3_accept(SSL *ssl);
+int ssl3_connect(SSL *ssl);
/* ssl3_record_sequence_update increments the sequence number in |seq|. It
* returns one on success and zero on wraparound. */
@@ -1057,102 +1081,102 @@ int ssl3_record_sequence_update(uint8_t *seq, size_t seq_len);
int ssl3_do_change_cipher_spec(SSL *ssl);
-int ssl3_set_handshake_header(SSL *s, int htype, unsigned long len);
-int ssl3_handshake_write(SSL *s);
+int ssl3_set_handshake_header(SSL *ssl, int htype, unsigned long len);
+int ssl3_handshake_write(SSL *ssl);
-int dtls1_do_handshake_write(SSL *s, enum dtls1_use_epoch_t use_epoch);
+int dtls1_do_handshake_write(SSL *ssl, enum dtls1_use_epoch_t use_epoch);
int dtls1_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek);
+int dtls1_read_change_cipher_spec(SSL *ssl);
void dtls1_read_close_notify(SSL *ssl);
-int dtls1_read_bytes(SSL *s, int type, uint8_t *buf, int len, int peek);
-void dtls1_set_message_header(SSL *s, uint8_t mt, unsigned long len,
+int dtls1_read_bytes(SSL *ssl, int type, uint8_t *buf, int len, int peek);
+void dtls1_set_message_header(SSL *ssl, uint8_t mt, unsigned long len,
unsigned short seq_num, unsigned long frag_off,
unsigned long frag_len);
-int dtls1_write_app_data(SSL *s, const void *buf, int len);
-int dtls1_write_bytes(SSL *s, int type, const void *buf, int len,
+int dtls1_write_app_data(SSL *ssl, const void *buf, int len);
+int dtls1_write_bytes(SSL *ssl, int type, const void *buf, int len,
enum dtls1_use_epoch_t use_epoch);
-int dtls1_send_change_cipher_spec(SSL *s, int a, int b);
-int dtls1_send_finished(SSL *s, int a, int b, const char *sender, int slen);
-int dtls1_read_failed(SSL *s, int code);
-int dtls1_buffer_message(SSL *s);
-int dtls1_retransmit_buffered_messages(SSL *s);
-void dtls1_clear_record_buffer(SSL *s);
+int dtls1_send_change_cipher_spec(SSL *ssl, int a, int b);
+int dtls1_send_finished(SSL *ssl, int a, int b, const char *sender, int slen);
+int dtls1_read_failed(SSL *ssl, int code);
+int dtls1_buffer_message(SSL *ssl);
+int dtls1_retransmit_buffered_messages(SSL *ssl);
+void dtls1_clear_record_buffer(SSL *ssl);
void dtls1_get_message_header(uint8_t *data, struct hm_header_st *msg_hdr);
-void dtls1_reset_seq_numbers(SSL *s, int rw);
-int dtls1_check_timeout_num(SSL *s);
-int dtls1_set_handshake_header(SSL *s, int type, unsigned long len);
-int dtls1_handshake_write(SSL *s);
+int dtls1_check_timeout_num(SSL *ssl);
+int dtls1_set_handshake_header(SSL *ssl, int type, unsigned long len);
+int dtls1_handshake_write(SSL *ssl);
int dtls1_supports_cipher(const SSL_CIPHER *cipher);
-void dtls1_start_timer(SSL *s);
-void dtls1_stop_timer(SSL *s);
-int dtls1_is_timer_expired(SSL *s);
-void dtls1_double_timeout(SSL *s);
+void dtls1_start_timer(SSL *ssl);
+void dtls1_stop_timer(SSL *ssl);
+int dtls1_is_timer_expired(SSL *ssl);
+void dtls1_double_timeout(SSL *ssl);
unsigned int dtls1_min_mtu(void);
void dtls1_hm_fragment_free(hm_fragment *frag);
/* some client-only functions */
int ssl3_send_client_hello(SSL *ssl);
-int ssl3_get_server_hello(SSL *s);
-int ssl3_get_certificate_request(SSL *s);
-int ssl3_get_new_session_ticket(SSL *s);
-int ssl3_get_cert_status(SSL *s);
-int ssl3_get_server_done(SSL *s);
-int ssl3_send_cert_verify(SSL *s);
-int ssl3_send_client_certificate(SSL *s);
-int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey);
-int ssl3_send_client_key_exchange(SSL *s);
-int ssl3_get_server_key_exchange(SSL *s);
-int ssl3_get_server_certificate(SSL *s);
+int ssl3_get_server_hello(SSL *ssl);
+int ssl3_get_certificate_request(SSL *ssl);
+int ssl3_get_new_session_ticket(SSL *ssl);
+int ssl3_get_cert_status(SSL *ssl);
+int ssl3_get_server_done(SSL *ssl);
+int ssl3_send_cert_verify(SSL *ssl);
+int ssl3_send_client_certificate(SSL *ssl);
+int ssl_do_client_cert_cb(SSL *ssl, X509 **px509, EVP_PKEY **ppkey);
+int ssl3_send_client_key_exchange(SSL *ssl);
+int ssl3_get_server_key_exchange(SSL *ssl);
+int ssl3_get_server_certificate(SSL *ssl);
int ssl3_send_next_proto(SSL *ssl);
int ssl3_send_channel_id(SSL *ssl);
-int ssl3_verify_server_cert(SSL *s);
+int ssl3_verify_server_cert(SSL *ssl);
/* some server-only functions */
-int ssl3_get_initial_bytes(SSL *s);
-int ssl3_get_v2_client_hello(SSL *s);
-int ssl3_get_client_hello(SSL *s);
+int ssl3_get_initial_bytes(SSL *ssl);
+int ssl3_get_v2_client_hello(SSL *ssl);
+int ssl3_get_client_hello(SSL *ssl);
int ssl3_send_server_hello(SSL *ssl);
-int ssl3_send_server_key_exchange(SSL *s);
-int ssl3_send_certificate_request(SSL *s);
-int ssl3_send_server_done(SSL *s);
-int ssl3_get_client_certificate(SSL *s);
-int ssl3_get_client_key_exchange(SSL *s);
-int ssl3_get_cert_verify(SSL *s);
-int ssl3_get_next_proto(SSL *s);
-int ssl3_get_channel_id(SSL *s);
-
-int dtls1_new(SSL *s);
-int dtls1_accept(SSL *s);
-int dtls1_connect(SSL *s);
-void dtls1_free(SSL *s);
-
-long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max,
+int ssl3_send_server_key_exchange(SSL *ssl);
+int ssl3_send_certificate_request(SSL *ssl);
+int ssl3_send_server_done(SSL *ssl);
+int ssl3_get_client_certificate(SSL *ssl);
+int ssl3_get_client_key_exchange(SSL *ssl);
+int ssl3_get_cert_verify(SSL *ssl);
+int ssl3_get_next_proto(SSL *ssl);
+int ssl3_get_channel_id(SSL *ssl);
+
+int dtls1_new(SSL *ssl);
+int dtls1_accept(SSL *ssl);
+int dtls1_connect(SSL *ssl);
+void dtls1_free(SSL *ssl);
+
+long dtls1_get_message(SSL *ssl, int st1, int stn, int mt, long max,
enum ssl_hash_message_t hash_message, int *ok);
-int dtls1_dispatch_alert(SSL *s);
+int dtls1_dispatch_alert(SSL *ssl);
-int ssl_init_wbio_buffer(SSL *s, int push);
-void ssl_free_wbio_buffer(SSL *s);
+int ssl_init_wbio_buffer(SSL *ssl, int push);
+void ssl_free_wbio_buffer(SSL *ssl);
-/* tls1_prf computes the TLS PRF function for |s| as described in RFC 5246,
+/* tls1_prf computes the TLS PRF function for |ssl| as described in RFC 5246,
* section 5 and RFC 2246 section 5. It writes |out_len| bytes to |out|, using
* |secret| as the secret and |label| as the label. |seed1| and |seed2| are
* concatenated to form the seed parameter. It returns one on success and zero
* on failure. */
-int tls1_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret,
+int tls1_prf(SSL *ssl, uint8_t *out, size_t out_len, const uint8_t *secret,
size_t secret_len, const char *label, size_t label_len,
const uint8_t *seed1, size_t seed1_len,
const uint8_t *seed2, size_t seed2_len);
-int tls1_change_cipher_state(SSL *s, int which);
-int tls1_setup_key_block(SSL *s);
-int tls1_handshake_digest(SSL *s, uint8_t *out, size_t out_len);
-int tls1_final_finish_mac(SSL *s, const char *str, int slen, uint8_t *p);
-int tls1_cert_verify_mac(SSL *s, int md_nid, uint8_t *p);
-int tls1_generate_master_secret(SSL *s, uint8_t *out, const uint8_t *premaster,
+int tls1_change_cipher_state(SSL *ssl, int which);
+int tls1_setup_key_block(SSL *ssl);
+int tls1_handshake_digest(SSL *ssl, uint8_t *out, size_t out_len);
+int tls1_final_finish_mac(SSL *ssl, const char *str, int slen, uint8_t *p);
+int tls1_cert_verify_mac(SSL *ssl, int md_nid, uint8_t *p);
+int tls1_generate_master_secret(SSL *ssl, uint8_t *out, const uint8_t *premaster,
size_t premaster_len);
-int tls1_export_keying_material(SSL *s, uint8_t *out, size_t out_len,
+int tls1_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len,
const char *label, size_t label_len,
const uint8_t *context, size_t context_len,
int use_context);
@@ -1160,24 +1184,16 @@ int tls1_alert_code(int code);
int ssl3_alert_code(int code);
char ssl_early_callback_init(struct ssl_early_callback_ctx *ctx);
-int tls1_ec_curve_id2nid(uint16_t curve_id);
-int tls1_ec_nid2curve_id(uint16_t *out_curve_id, int nid);
-
-/* tls1_ec_curve_id2name returns a human-readable name for the
- * curve specified by the TLS curve id in |curve_id|. If the
- * curve is unknown, it returns NULL. */
-const char* tls1_ec_curve_id2name(uint16_t curve_id);
-/* tls1_check_curve parses ECParameters out of |cbs|, modifying it. It
- * checks the curve is one of our preferences and writes the
- * NamedCurve value to |*out_curve_id|. It returns one on success and
- * zero on error. */
-int tls1_check_curve(SSL *s, CBS *cbs, uint16_t *out_curve_id);
+/* tls1_check_curve_id returns one if |curve_id| is consistent with both our
+ * and the peer's curve preferences. Note: if called as the client, only our
+ * preferences are checked; the peer (the server) does not send preferences. */
+int tls1_check_curve_id(SSL *ssl, uint16_t curve_id);
-/* tls1_get_shared_curve returns the NID of the first preferred shared curve
- * between client and server preferences. If none can be found, it returns
- * NID_undef. */
-int tls1_get_shared_curve(SSL *s);
+/* tls1_get_shared_curve sets |*out_curve_id| to the first preferred shared
+ * curve between client and server preferences and returns one. If none may be
+ * found, it returns zero. */
+int tls1_get_shared_curve(SSL *ssl, uint16_t *out_curve_id);
/* tls1_set_curves converts the array of |ncurves| NIDs pointed to by |curves|
* into a newly allocated array of TLS curve IDs. On success, the function
@@ -1189,14 +1205,7 @@ int tls1_set_curves(uint16_t **out_curve_ids, size_t *out_curve_ids_len,
/* tls1_check_ec_cert returns one if |x| is an ECC certificate with curve and
* point format compatible with the client's preferences. Otherwise it returns
* zero. */
-int tls1_check_ec_cert(SSL *s, X509 *x);
-
-/* tls1_check_ec_tmp_key returns one if the EC temporary key is compatible with
- * client extensions and zero otherwise. */
-int tls1_check_ec_tmp_key(SSL *s);
-
-int tls1_shared_list(SSL *s, const uint8_t *l1, size_t l1len, const uint8_t *l2,
- size_t l2len, int nmatch);
+int tls1_check_ec_cert(SSL *ssl, X509 *x);
/* ssl_add_clienthello_tlsext writes ClientHello extensions to |out|. It
* returns one on success and zero on failure. The |header_len| argument is the
@@ -1205,8 +1214,8 @@ int tls1_shared_list(SSL *s, const uint8_t *l1, size_t l1len, const uint8_t *l2,
int ssl_add_clienthello_tlsext(SSL *ssl, CBB *out, size_t header_len);
int ssl_add_serverhello_tlsext(SSL *ssl, CBB *out);
-int ssl_parse_clienthello_tlsext(SSL *s, CBS *cbs);
-int ssl_parse_serverhello_tlsext(SSL *s, CBS *cbs);
+int ssl_parse_clienthello_tlsext(SSL *ssl, CBS *cbs);
+int ssl_parse_serverhello_tlsext(SSL *ssl, CBS *cbs);
#define tlsext_tick_md EVP_sha256
@@ -1220,10 +1229,11 @@ int tls_process_ticket(SSL *ssl, SSL_SESSION **out_session,
size_t ticket_len, const uint8_t *session_id,
size_t session_id_len);
-/* tls12_get_sigandhash assembles the SignatureAndHashAlgorithm corresponding to
- * |ssl|'s private key and |md|. The two-byte value is written to |p|. It
+/* tls12_add_sigandhash assembles the SignatureAndHashAlgorithm corresponding to
+ * |ssl|'s private key and |md|. The two-byte value is written to |out|. It
* returns one on success and zero on failure. */
-int tls12_get_sigandhash(SSL *ssl, uint8_t *p, const EVP_MD *md);
+int tls12_add_sigandhash(SSL *ssl, CBB *out, const EVP_MD *md);
+
int tls12_get_sigid(int pkey_type);
const EVP_MD *tls12_get_hash(uint8_t hash_alg);
@@ -1232,50 +1242,50 @@ const EVP_MD *tls12_get_hash(uint8_t hash_alg);
* one on success and zero on failure. */
int tls1_channel_id_hash(SSL *ssl, uint8_t *out, size_t *out_len);
-int tls1_record_handshake_hashes_for_channel_id(SSL *s);
+int tls1_record_handshake_hashes_for_channel_id(SSL *ssl);
-/* ssl_ctx_log_rsa_client_key_exchange logs |premaster| to |ctx|, if logging is
- * enabled. It returns one on success and zero on failure. The entry is
- * identified by the first 8 bytes of |encrypted_premaster|. */
-int ssl_ctx_log_rsa_client_key_exchange(SSL_CTX *ctx,
- const uint8_t *encrypted_premaster,
- size_t encrypted_premaster_len,
- const uint8_t *premaster,
- size_t premaster_len);
+/* ssl_log_rsa_client_key_exchange logs |premaster|, if logging is enabled for
+ * |ssl|. It returns one on success and zero on failure. The entry is identified
+ * by the first 8 bytes of |encrypted_premaster|. */
+int ssl_log_rsa_client_key_exchange(const SSL *ssl,
+ const uint8_t *encrypted_premaster,
+ size_t encrypted_premaster_len,
+ const uint8_t *premaster,
+ size_t premaster_len);
-/* ssl_ctx_log_master_secret logs |master| to |ctx|, if logging is enabled. It
+/* ssl_log_master_secret logs |master|, if logging is enabled for |ssl|. It
* returns one on success and zero on failure. The entry is identified by
* |client_random|. */
-int ssl_ctx_log_master_secret(SSL_CTX *ctx, const uint8_t *client_random,
- size_t client_random_len, const uint8_t *master,
- size_t master_len);
+int ssl_log_master_secret(const SSL *ssl, const uint8_t *client_random,
+ size_t client_random_len, const uint8_t *master,
+ size_t master_len);
-/* ssl3_can_false_start returns one if |s| is allowed to False Start and zero
+/* ssl3_can_false_start returns one if |ssl| is allowed to False Start and zero
* otherwise. */
-int ssl3_can_false_start(const SSL *s);
+int ssl3_can_false_start(const SSL *ssl);
/* ssl3_get_enc_method returns the SSL3_ENC_METHOD corresponding to
* |version|. */
const SSL3_ENC_METHOD *ssl3_get_enc_method(uint16_t version);
/* ssl3_get_max_server_version returns the maximum SSL/TLS version number
- * supported by |s| as a server, or zero if all versions are disabled. */
-uint16_t ssl3_get_max_server_version(const SSL *s);
+ * supported by |ssl| as a server, or zero if all versions are disabled. */
+uint16_t ssl3_get_max_server_version(const SSL *ssl);
-/* ssl3_get_mutual_version selects the protocol version on |s| for a client
+/* ssl3_get_mutual_version selects the protocol version on |ssl| for a client
* which advertises |client_version|. If no suitable version exists, it returns
* zero. */
-uint16_t ssl3_get_mutual_version(SSL *s, uint16_t client_version);
+uint16_t ssl3_get_mutual_version(SSL *ssl, uint16_t client_version);
/* ssl3_get_max_client_version returns the maximum protocol version configured
* for the client. It is guaranteed that the set of allowed versions at or below
* this maximum version is contiguous. If all versions are disabled, it returns
* zero. */
-uint16_t ssl3_get_max_client_version(SSL *s);
+uint16_t ssl3_get_max_client_version(SSL *ssl);
/* ssl3_is_version_enabled returns one if |version| is an enabled protocol
- * version for |s| and zero otherwise. */
-int ssl3_is_version_enabled(SSL *s, uint16_t version);
+ * version for |ssl| and zero otherwise. */
+int ssl3_is_version_enabled(SSL *ssl, uint16_t version);
/* ssl3_version_from_wire maps |wire_version| to a protocol version. For
* SSLv3/TLS, the version is returned as-is. For DTLS, the corresponding TLS
@@ -1284,16 +1294,16 @@ int ssl3_is_version_enabled(SSL *s, uint16_t version);
*
* TODO(davidben): To normalize some DTLS-specific code, move away from using
* the wire version except at API boundaries. */
-uint16_t ssl3_version_from_wire(SSL *s, uint16_t wire_version);
+uint16_t ssl3_version_from_wire(SSL *ssl, uint16_t wire_version);
-uint32_t ssl_get_algorithm_prf(SSL *s);
-int tls1_parse_peer_sigalgs(SSL *s, const CBS *sigalgs);
+uint32_t ssl_get_algorithm_prf(SSL *ssl);
+int tls1_parse_peer_sigalgs(SSL *ssl, const CBS *sigalgs);
/* tls1_choose_signing_digest returns a digest for use with |ssl|'s private key
* based on the peer's preferences the digests supported. */
const EVP_MD *tls1_choose_signing_digest(SSL *ssl);
-size_t tls12_get_psigalgs(SSL *s, const uint8_t **psigs);
+size_t tls12_get_psigalgs(SSL *ssl, const uint8_t **psigs);
/* tls12_check_peer_sigalg checks that |hash| and |signature| are consistent
* with |pkey| and |ssl|'s sent, supported signature algorithms and, if so,
@@ -1301,6 +1311,6 @@ size_t tls12_get_psigalgs(SSL *s, const uint8_t **psigs);
* returns 0 and writes an alert into |*out_alert|. */
int tls12_check_peer_sigalg(SSL *ssl, const EVP_MD **out_md, int *out_alert,
uint8_t hash, uint8_t signature, EVP_PKEY *pkey);
-void ssl_set_client_disabled(SSL *s);
+void ssl_set_client_disabled(SSL *ssl);
#endif /* OPENSSL_HEADER_SSL_INTERNAL_H */
diff --git a/src/ssl/s3_both.c b/src/ssl/s3_both.c
index 31e36c7..01a7e8c 100644
--- a/src/ssl/s3_both.c
+++ b/src/ssl/s3_both.c
@@ -130,127 +130,119 @@
#include "internal.h"
-/* ssl3_do_write sends |s->init_buf| in records of type 'type'
+/* ssl3_do_write sends |ssl->init_buf| in records of type 'type'
* (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC). It returns -1 on error, 1
* on success or zero if the transmission is still incomplete. */
-int ssl3_do_write(SSL *s, int type) {
+int ssl3_do_write(SSL *ssl, int type) {
int n;
- n = ssl3_write_bytes(s, type, &s->init_buf->data[s->init_off], s->init_num);
+ n = ssl3_write_bytes(ssl, type, &ssl->init_buf->data[ssl->init_off],
+ ssl->init_num);
if (n < 0) {
return -1;
}
- if (n == s->init_num) {
- if (s->msg_callback) {
- s->msg_callback(1, s->version, type, s->init_buf->data,
- (size_t)(s->init_off + s->init_num), s,
- s->msg_callback_arg);
+ if (n == ssl->init_num) {
+ if (ssl->msg_callback) {
+ ssl->msg_callback(1, ssl->version, type, ssl->init_buf->data,
+ (size_t)(ssl->init_off + ssl->init_num), ssl,
+ ssl->msg_callback_arg);
}
return 1;
}
- s->init_off += n;
- s->init_num -= n;
+ ssl->init_off += n;
+ ssl->init_num -= n;
return 0;
}
-int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen) {
+int ssl3_send_finished(SSL *ssl, int a, int b, const char *sender, int slen) {
uint8_t *p;
int n;
- if (s->state == a) {
- p = ssl_handshake_start(s);
+ if (ssl->state == a) {
+ p = ssl_handshake_start(ssl);
- n = s->enc_method->final_finish_mac(s, sender, slen, s->s3->tmp.finish_md);
+ n = ssl->enc_method->final_finish_mac(ssl, sender, slen,
+ ssl->s3->tmp.finish_md);
if (n == 0) {
return 0;
}
- s->s3->tmp.finish_md_len = n;
- memcpy(p, s->s3->tmp.finish_md, n);
+ ssl->s3->tmp.finish_md_len = n;
+ memcpy(p, ssl->s3->tmp.finish_md, n);
/* Log the master secret, if logging is enabled. */
- if (!ssl_ctx_log_master_secret(s->ctx, s->s3->client_random,
- SSL3_RANDOM_SIZE, s->session->master_key,
- s->session->master_key_length)) {
+ if (!ssl_log_master_secret(ssl, ssl->s3->client_random, SSL3_RANDOM_SIZE,
+ ssl->session->master_key,
+ ssl->session->master_key_length)) {
return 0;
}
/* Copy the finished so we can use it for renegotiation checks */
- if (s->server) {
+ if (ssl->server) {
assert(n <= EVP_MAX_MD_SIZE);
- memcpy(s->s3->previous_server_finished, s->s3->tmp.finish_md, n);
- s->s3->previous_server_finished_len = n;
+ memcpy(ssl->s3->previous_server_finished, ssl->s3->tmp.finish_md, n);
+ ssl->s3->previous_server_finished_len = n;
} else {
assert(n <= EVP_MAX_MD_SIZE);
- memcpy(s->s3->previous_client_finished, s->s3->tmp.finish_md, n);
- s->s3->previous_client_finished_len = n;
+ memcpy(ssl->s3->previous_client_finished, ssl->s3->tmp.finish_md, n);
+ ssl->s3->previous_client_finished_len = n;
}
- if (!ssl_set_handshake_header(s, SSL3_MT_FINISHED, n)) {
+ if (!ssl_set_handshake_header(ssl, SSL3_MT_FINISHED, n)) {
return 0;
}
- s->state = b;
+ ssl->state = b;
}
/* SSL3_ST_SEND_xxxxxx_HELLO_B */
- return ssl_do_write(s);
+ return ssl_do_write(ssl);
}
/* ssl3_take_mac calculates the Finished MAC for the handshakes messages seen
* so far. */
-static void ssl3_take_mac(SSL *s) {
+static void ssl3_take_mac(SSL *ssl) {
const char *sender;
int slen;
/* If no new cipher setup then return immediately: other functions will set
* the appropriate error. */
- if (s->s3->tmp.new_cipher == NULL) {
+ if (ssl->s3->tmp.new_cipher == NULL) {
return;
}
- if (s->state & SSL_ST_CONNECT) {
- sender = s->enc_method->server_finished_label;
- slen = s->enc_method->server_finished_label_len;
+ if (ssl->state & SSL_ST_CONNECT) {
+ sender = ssl->enc_method->server_finished_label;
+ slen = ssl->enc_method->server_finished_label_len;
} else {
- sender = s->enc_method->client_finished_label;
- slen = s->enc_method->client_finished_label_len;
+ sender = ssl->enc_method->client_finished_label;
+ slen = ssl->enc_method->client_finished_label_len;
}
- s->s3->tmp.peer_finish_md_len = s->enc_method->final_finish_mac(
- s, sender, slen, s->s3->tmp.peer_finish_md);
+ ssl->s3->tmp.peer_finish_md_len = ssl->enc_method->final_finish_mac(
+ ssl, sender, slen, ssl->s3->tmp.peer_finish_md);
}
-int ssl3_get_finished(SSL *s, int a, int b) {
+int ssl3_get_finished(SSL *ssl, int a, int b) {
int al, finished_len, ok;
long message_len;
uint8_t *p;
- message_len =
- s->method->ssl_get_message(s, a, b, SSL3_MT_FINISHED, EVP_MAX_MD_SIZE,
- ssl_dont_hash_message, &ok);
+ message_len = ssl->method->ssl_get_message(
+ ssl, a, b, SSL3_MT_FINISHED, EVP_MAX_MD_SIZE, ssl_dont_hash_message, &ok);
if (!ok) {
return message_len;
}
/* Snapshot the finished hash before incorporating the new message. */
- ssl3_take_mac(s);
- if (!ssl3_hash_current_message(s)) {
+ ssl3_take_mac(ssl);
+ if (!ssl3_hash_current_message(ssl)) {
goto err;
}
- /* If this occurs, we have missed a message.
- * TODO(davidben): Is this check now redundant with SSL3_FLAGS_EXPECT_CCS? */
- if (!s->s3->change_cipher_spec) {
- al = SSL_AD_UNEXPECTED_MESSAGE;
- OPENSSL_PUT_ERROR(SSL, SSL_R_GOT_A_FIN_BEFORE_A_CCS);
- goto f_err;
- }
- s->s3->change_cipher_spec = 0;
-
- p = s->init_msg;
- finished_len = s->s3->tmp.peer_finish_md_len;
+ p = ssl->init_msg;
+ finished_len = ssl->s3->tmp.peer_finish_md_len;
if (finished_len != message_len) {
al = SSL_AD_DECODE_ERROR;
@@ -258,134 +250,137 @@ int ssl3_get_finished(SSL *s, int a, int b) {
goto f_err;
}
- if (CRYPTO_memcmp(p, s->s3->tmp.peer_finish_md, finished_len) != 0) {
+ if (CRYPTO_memcmp(p, ssl->s3->tmp.peer_finish_md, finished_len) != 0) {
al = SSL_AD_DECRYPT_ERROR;
OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED);
goto f_err;
}
/* Copy the finished so we can use it for renegotiation checks */
- if (s->server) {
+ if (ssl->server) {
assert(finished_len <= EVP_MAX_MD_SIZE);
- memcpy(s->s3->previous_client_finished, s->s3->tmp.peer_finish_md, finished_len);
- s->s3->previous_client_finished_len = finished_len;
+ memcpy(ssl->s3->previous_client_finished, ssl->s3->tmp.peer_finish_md,
+ finished_len);
+ ssl->s3->previous_client_finished_len = finished_len;
} else {
assert(finished_len <= EVP_MAX_MD_SIZE);
- memcpy(s->s3->previous_server_finished, s->s3->tmp.peer_finish_md, finished_len);
- s->s3->previous_server_finished_len = finished_len;
+ memcpy(ssl->s3->previous_server_finished, ssl->s3->tmp.peer_finish_md,
+ finished_len);
+ ssl->s3->previous_server_finished_len = finished_len;
}
return 1;
f_err:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
err:
return 0;
}
/* for these 2 messages, we need to
- * ssl->enc_read_ctx re-init
- * ssl->s3->read_sequence zero
- * ssl->s3->read_mac_secret re-init
- * ssl->session->read_sym_enc assign
- * ssl->session->read_compression assign
- * ssl->session->read_hash assign */
-int ssl3_send_change_cipher_spec(SSL *s, int a, int b) {
- if (s->state == a) {
- *((uint8_t *)s->init_buf->data) = SSL3_MT_CCS;
- s->init_num = 1;
- s->init_off = 0;
-
- s->state = b;
+ * ssl->enc_read_ctx re-init
+ * ssl->s3->read_sequence zero
+ * ssl->s3->read_mac_secret re-init
+ * ssl->session->read_sym_enc assign
+ * ssl->session->read_compression assign
+ * ssl->session->read_hash assign */
+int ssl3_send_change_cipher_spec(SSL *ssl, int a, int b) {
+ if (ssl->state == a) {
+ *((uint8_t *)ssl->init_buf->data) = SSL3_MT_CCS;
+ ssl->init_num = 1;
+ ssl->init_off = 0;
+
+ ssl->state = b;
}
/* SSL3_ST_CW_CHANGE_B */
- return ssl3_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC);
+ return ssl3_do_write(ssl, SSL3_RT_CHANGE_CIPHER_SPEC);
}
-int ssl3_output_cert_chain(SSL *s) {
+int ssl3_output_cert_chain(SSL *ssl) {
uint8_t *p;
- unsigned long l = 3 + SSL_HM_HEADER_LENGTH(s);
+ unsigned long l = 3 + SSL_HM_HEADER_LENGTH(ssl);
- if (!ssl_add_cert_chain(s, &l)) {
+ if (!ssl_add_cert_chain(ssl, &l)) {
return 0;
}
- l -= 3 + SSL_HM_HEADER_LENGTH(s);
- p = ssl_handshake_start(s);
+ l -= 3 + SSL_HM_HEADER_LENGTH(ssl);
+ p = ssl_handshake_start(ssl);
l2n3(l, p);
l += 3;
- return ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE, l);
+ return ssl_set_handshake_header(ssl, SSL3_MT_CERTIFICATE, l);
}
/* Obtain handshake message of message type |msg_type| (any if |msg_type| == -1),
* maximum acceptable body length |max|. The first four bytes (msg_type and
- * length) are read in state |header_state|, the body is read in state |body_state|. */
-long ssl3_get_message(SSL *s, int header_state, int body_state, int msg_type,
+ * length) are read in state |header_state|, the body is read in state
+ * |body_state|. */
+long ssl3_get_message(SSL *ssl, int header_state, int body_state, int msg_type,
long max, enum ssl_hash_message_t hash_message, int *ok) {
uint8_t *p;
unsigned long l;
long n;
int al;
- if (s->s3->tmp.reuse_message) {
+ if (ssl->s3->tmp.reuse_message) {
/* A ssl_dont_hash_message call cannot be combined with reuse_message; the
* ssl_dont_hash_message would have to have been applied to the previous
* call. */
assert(hash_message == ssl_hash_message);
- s->s3->tmp.reuse_message = 0;
- if (msg_type >= 0 && s->s3->tmp.message_type != msg_type) {
+ ssl->s3->tmp.reuse_message = 0;
+ if (msg_type >= 0 && ssl->s3->tmp.message_type != msg_type) {
al = SSL_AD_UNEXPECTED_MESSAGE;
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
goto f_err;
}
*ok = 1;
- s->state = body_state;
- s->init_msg = (uint8_t *)s->init_buf->data + 4;
- s->init_num = (int)s->s3->tmp.message_size;
- return s->init_num;
+ ssl->state = body_state;
+ ssl->init_msg = (uint8_t *)ssl->init_buf->data + 4;
+ ssl->init_num = (int)ssl->s3->tmp.message_size;
+ return ssl->init_num;
}
- p = (uint8_t *)s->init_buf->data;
+ p = (uint8_t *)ssl->init_buf->data;
- if (s->state == header_state) {
- assert(s->init_num < 4);
+ if (ssl->state == header_state) {
+ assert(ssl->init_num < 4);
for (;;) {
- while (s->init_num < 4) {
- int bytes_read = ssl3_read_bytes(s, SSL3_RT_HANDSHAKE, &p[s->init_num],
- 4 - s->init_num, 0);
+ while (ssl->init_num < 4) {
+ int bytes_read = ssl3_read_bytes(
+ ssl, SSL3_RT_HANDSHAKE, &p[ssl->init_num], 4 - ssl->init_num, 0);
if (bytes_read <= 0) {
*ok = 0;
return bytes_read;
}
- s->init_num += bytes_read;
+ ssl->init_num += bytes_read;
}
static const uint8_t kHelloRequest[4] = {SSL3_MT_HELLO_REQUEST, 0, 0, 0};
- if (s->server || memcmp(p, kHelloRequest, sizeof(kHelloRequest)) != 0) {
+ if (ssl->server || memcmp(p, kHelloRequest, sizeof(kHelloRequest)) != 0) {
break;
}
/* The server may always send 'Hello Request' messages -- we are doing
* a handshake anyway now, so ignore them if their format is correct.
* Does not count for 'Finished' MAC. */
- s->init_num = 0;
+ ssl->init_num = 0;
- if (s->msg_callback) {
- s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, p, 4, s,
- s->msg_callback_arg);
+ if (ssl->msg_callback) {
+ ssl->msg_callback(0, ssl->version, SSL3_RT_HANDSHAKE, p, 4, ssl,
+ ssl->msg_callback_arg);
}
}
- /* s->init_num == 4 */
+ /* ssl->init_num == 4 */
if (msg_type >= 0 && *p != msg_type) {
al = SSL_AD_UNEXPECTED_MESSAGE;
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
goto f_err;
}
- s->s3->tmp.message_type = *(p++);
+ ssl->s3->tmp.message_type = *(p++);
n2l3(p, l);
if (l > (unsigned long)max) {
@@ -394,57 +389,57 @@ long ssl3_get_message(SSL *s, int header_state, int body_state, int msg_type,
goto f_err;
}
- if (l && !BUF_MEM_grow_clean(s->init_buf, l + 4)) {
+ if (l && !BUF_MEM_grow_clean(ssl->init_buf, l + 4)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
goto err;
}
- s->s3->tmp.message_size = l;
- s->state = body_state;
+ ssl->s3->tmp.message_size = l;
+ ssl->state = body_state;
- s->init_msg = (uint8_t *)s->init_buf->data + 4;
- s->init_num = 0;
+ ssl->init_msg = (uint8_t *)ssl->init_buf->data + 4;
+ ssl->init_num = 0;
}
/* next state (body_state) */
- p = s->init_msg;
- n = s->s3->tmp.message_size - s->init_num;
+ p = ssl->init_msg;
+ n = ssl->s3->tmp.message_size - ssl->init_num;
while (n > 0) {
- int bytes_read = ssl3_read_bytes(s, SSL3_RT_HANDSHAKE, &p[s->init_num], n,
- 0);
+ int bytes_read =
+ ssl3_read_bytes(ssl, SSL3_RT_HANDSHAKE, &p[ssl->init_num], n, 0);
if (bytes_read <= 0) {
- s->rwstate = SSL_READING;
+ ssl->rwstate = SSL_READING;
*ok = 0;
return bytes_read;
}
- s->init_num += bytes_read;
+ ssl->init_num += bytes_read;
n -= bytes_read;
}
/* Feed this message into MAC computation. */
- if (hash_message == ssl_hash_message && !ssl3_hash_current_message(s)) {
+ if (hash_message == ssl_hash_message && !ssl3_hash_current_message(ssl)) {
goto err;
}
- if (s->msg_callback) {
- s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data,
- (size_t)s->init_num + 4, s, s->msg_callback_arg);
+ if (ssl->msg_callback) {
+ ssl->msg_callback(0, ssl->version, SSL3_RT_HANDSHAKE, ssl->init_buf->data,
+ (size_t)ssl->init_num + 4, ssl, ssl->msg_callback_arg);
}
*ok = 1;
- return s->init_num;
+ return ssl->init_num;
f_err:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
err:
*ok = 0;
return -1;
}
-int ssl3_hash_current_message(SSL *s) {
+int ssl3_hash_current_message(SSL *ssl) {
/* The handshake header (different size between DTLS and TLS) is included in
* the hash. */
- size_t header_len = s->init_msg - (uint8_t *)s->init_buf->data;
- return ssl3_update_handshake_hash(s, (uint8_t *)s->init_buf->data,
- s->init_num + header_len);
+ size_t header_len = ssl->init_msg - (uint8_t *)ssl->init_buf->data;
+ return ssl3_update_handshake_hash(ssl, (uint8_t *)ssl->init_buf->data,
+ ssl->init_num + header_len);
}
/* ssl3_cert_verify_hash is documented as needing EVP_MAX_MD_SIZE because that
@@ -452,19 +447,19 @@ int ssl3_hash_current_message(SSL *s) {
OPENSSL_COMPILE_ASSERT(EVP_MAX_MD_SIZE > MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH,
combined_tls_hash_fits_in_max);
-int ssl3_cert_verify_hash(SSL *s, uint8_t *out, size_t *out_len,
+int ssl3_cert_verify_hash(SSL *ssl, uint8_t *out, size_t *out_len,
const EVP_MD **out_md, int pkey_type) {
/* For TLS v1.2 send signature algorithm and signature using
* agreed digest and cached handshake records. Otherwise, use
* SHA1 or MD5 + SHA1 depending on key type. */
- if (SSL_USE_SIGALGS(s)) {
+ if (SSL_USE_SIGALGS(ssl)) {
EVP_MD_CTX mctx;
unsigned len;
EVP_MD_CTX_init(&mctx);
if (!EVP_DigestInit_ex(&mctx, *out_md, NULL) ||
- !EVP_DigestUpdate(&mctx, s->s3->handshake_buffer->data,
- s->s3->handshake_buffer->length) ||
+ !EVP_DigestUpdate(&mctx, ssl->s3->handshake_buffer->data,
+ ssl->s3->handshake_buffer->length) ||
!EVP_DigestFinal(&mctx, out, &len)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB);
EVP_MD_CTX_cleanup(&mctx);
@@ -472,15 +467,15 @@ int ssl3_cert_verify_hash(SSL *s, uint8_t *out, size_t *out_len,
}
*out_len = len;
} else if (pkey_type == EVP_PKEY_RSA) {
- if (s->enc_method->cert_verify_mac(s, NID_md5, out) == 0 ||
- s->enc_method->cert_verify_mac(s, NID_sha1, out + MD5_DIGEST_LENGTH) ==
- 0) {
+ if (ssl->enc_method->cert_verify_mac(ssl, NID_md5, out) == 0 ||
+ ssl->enc_method->cert_verify_mac(ssl, NID_sha1,
+ out + MD5_DIGEST_LENGTH) == 0) {
return 0;
}
*out_len = MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH;
*out_md = EVP_md5_sha1();
} else if (pkey_type == EVP_PKEY_EC) {
- if (s->enc_method->cert_verify_mac(s, NID_sha1, out) == 0) {
+ if (ssl->enc_method->cert_verify_mac(ssl, NID_sha1, out) == 0) {
return 0;
}
*out_len = SHA_DIGEST_LENGTH;
diff --git a/src/ssl/s3_clnt.c b/src/ssl/s3_clnt.c
index 843403b..5f68037 100644
--- a/src/ssl/s3_clnt.c
+++ b/src/ssl/s3_clnt.c
@@ -172,37 +172,37 @@
#include "../crypto/dh/internal.h"
-int ssl3_connect(SSL *s) {
+int ssl3_connect(SSL *ssl) {
BUF_MEM *buf = NULL;
void (*cb)(const SSL *ssl, int type, int value) = NULL;
int ret = -1;
int new_state, state, skip = 0;
- assert(s->handshake_func == ssl3_connect);
- assert(!s->server);
- assert(!SSL_IS_DTLS(s));
+ assert(ssl->handshake_func == ssl3_connect);
+ assert(!ssl->server);
+ assert(!SSL_IS_DTLS(ssl));
ERR_clear_error();
ERR_clear_system_error();
- if (s->info_callback != NULL) {
- cb = s->info_callback;
- } else if (s->ctx->info_callback != NULL) {
- cb = s->ctx->info_callback;
+ if (ssl->info_callback != NULL) {
+ cb = ssl->info_callback;
+ } else if (ssl->ctx->info_callback != NULL) {
+ cb = ssl->ctx->info_callback;
}
- s->in_handshake++;
+ ssl->in_handshake++;
for (;;) {
- state = s->state;
+ state = ssl->state;
- switch (s->state) {
+ switch (ssl->state) {
case SSL_ST_CONNECT:
if (cb != NULL) {
- cb(s, SSL_CB_HANDSHAKE_START, 1);
+ cb(ssl, SSL_CB_HANDSHAKE_START, 1);
}
- if (s->init_buf == NULL) {
+ if (ssl->init_buf == NULL) {
buf = BUF_MEM_new();
if (buf == NULL ||
!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
@@ -210,124 +210,124 @@ int ssl3_connect(SSL *s) {
goto end;
}
- s->init_buf = buf;
+ ssl->init_buf = buf;
buf = NULL;
}
- if (!ssl_init_wbio_buffer(s, 0)) {
+ if (!ssl_init_wbio_buffer(ssl, 0)) {
ret = -1;
goto end;
}
/* don't push the buffering BIO quite yet */
- if (!ssl3_init_handshake_buffer(s)) {
+ if (!ssl3_init_handshake_buffer(ssl)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
ret = -1;
goto end;
}
- s->state = SSL3_ST_CW_CLNT_HELLO_A;
- s->init_num = 0;
+ ssl->state = SSL3_ST_CW_CLNT_HELLO_A;
+ ssl->init_num = 0;
break;
case SSL3_ST_CW_CLNT_HELLO_A:
case SSL3_ST_CW_CLNT_HELLO_B:
- s->shutdown = 0;
- ret = ssl3_send_client_hello(s);
+ ssl->shutdown = 0;
+ ret = ssl3_send_client_hello(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_CR_SRVR_HELLO_A;
- s->init_num = 0;
+ ssl->state = SSL3_ST_CR_SRVR_HELLO_A;
+ ssl->init_num = 0;
/* turn on buffering for the next lot of output */
- if (s->bbio != s->wbio) {
- s->wbio = BIO_push(s->bbio, s->wbio);
+ if (ssl->bbio != ssl->wbio) {
+ ssl->wbio = BIO_push(ssl->bbio, ssl->wbio);
}
break;
case SSL3_ST_CR_SRVR_HELLO_A:
case SSL3_ST_CR_SRVR_HELLO_B:
- ret = ssl3_get_server_hello(s);
+ ret = ssl3_get_server_hello(ssl);
if (ret <= 0) {
goto end;
}
- if (s->hit) {
- s->state = SSL3_ST_CR_CHANGE;
- if (s->tlsext_ticket_expected) {
+ if (ssl->hit) {
+ ssl->state = SSL3_ST_CR_CHANGE;
+ if (ssl->tlsext_ticket_expected) {
/* receive renewed session ticket */
- s->state = SSL3_ST_CR_SESSION_TICKET_A;
+ ssl->state = SSL3_ST_CR_SESSION_TICKET_A;
}
} else {
- s->state = SSL3_ST_CR_CERT_A;
+ ssl->state = SSL3_ST_CR_CERT_A;
}
- s->init_num = 0;
+ ssl->init_num = 0;
break;
case SSL3_ST_CR_CERT_A:
case SSL3_ST_CR_CERT_B:
- if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) {
- ret = ssl3_get_server_certificate(s);
+ if (ssl_cipher_has_server_public_key(ssl->s3->tmp.new_cipher)) {
+ ret = ssl3_get_server_certificate(ssl);
if (ret <= 0) {
goto end;
}
- if (s->s3->tmp.certificate_status_expected) {
- s->state = SSL3_ST_CR_CERT_STATUS_A;
+ if (ssl->s3->tmp.certificate_status_expected) {
+ ssl->state = SSL3_ST_CR_CERT_STATUS_A;
} else {
- s->state = SSL3_ST_VERIFY_SERVER_CERT;
+ ssl->state = SSL3_ST_VERIFY_SERVER_CERT;
}
} else {
skip = 1;
- s->state = SSL3_ST_CR_KEY_EXCH_A;
+ ssl->state = SSL3_ST_CR_KEY_EXCH_A;
}
- s->init_num = 0;
+ ssl->init_num = 0;
break;
case SSL3_ST_VERIFY_SERVER_CERT:
- ret = ssl3_verify_server_cert(s);
+ ret = ssl3_verify_server_cert(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_CR_KEY_EXCH_A;
- s->init_num = 0;
+ ssl->state = SSL3_ST_CR_KEY_EXCH_A;
+ ssl->init_num = 0;
break;
case SSL3_ST_CR_KEY_EXCH_A:
case SSL3_ST_CR_KEY_EXCH_B:
- ret = ssl3_get_server_key_exchange(s);
+ ret = ssl3_get_server_key_exchange(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_CR_CERT_REQ_A;
- s->init_num = 0;
+ ssl->state = SSL3_ST_CR_CERT_REQ_A;
+ ssl->init_num = 0;
break;
case SSL3_ST_CR_CERT_REQ_A:
case SSL3_ST_CR_CERT_REQ_B:
- ret = ssl3_get_certificate_request(s);
+ ret = ssl3_get_certificate_request(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_CR_SRVR_DONE_A;
- s->init_num = 0;
+ ssl->state = SSL3_ST_CR_SRVR_DONE_A;
+ ssl->init_num = 0;
break;
case SSL3_ST_CR_SRVR_DONE_A:
case SSL3_ST_CR_SRVR_DONE_B:
- ret = ssl3_get_server_done(s);
+ ret = ssl3_get_server_done(ssl);
if (ret <= 0) {
goto end;
}
- if (s->s3->tmp.cert_req) {
- s->state = SSL3_ST_CW_CERT_A;
+ if (ssl->s3->tmp.cert_req) {
+ ssl->state = SSL3_ST_CW_CERT_A;
} else {
- s->state = SSL3_ST_CW_KEY_EXCH_A;
+ ssl->state = SSL3_ST_CW_KEY_EXCH_A;
}
- s->init_num = 0;
+ ssl->init_num = 0;
break;
@@ -335,65 +335,63 @@ int ssl3_connect(SSL *s) {
case SSL3_ST_CW_CERT_B:
case SSL3_ST_CW_CERT_C:
case SSL3_ST_CW_CERT_D:
- ret = ssl3_send_client_certificate(s);
+ ret = ssl3_send_client_certificate(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_CW_KEY_EXCH_A;
- s->init_num = 0;
+ ssl->state = SSL3_ST_CW_KEY_EXCH_A;
+ ssl->init_num = 0;
break;
case SSL3_ST_CW_KEY_EXCH_A:
case SSL3_ST_CW_KEY_EXCH_B:
- ret = ssl3_send_client_key_exchange(s);
+ ret = ssl3_send_client_key_exchange(ssl);
if (ret <= 0) {
goto end;
}
/* For TLS, cert_req is set to 2, so a cert chain
* of nothing is sent, but no verify packet is sent */
- if (s->s3->tmp.cert_req == 1) {
- s->state = SSL3_ST_CW_CERT_VRFY_A;
+ if (ssl->s3->tmp.cert_req == 1) {
+ ssl->state = SSL3_ST_CW_CERT_VRFY_A;
} else {
- s->state = SSL3_ST_CW_CHANGE_A;
- s->s3->change_cipher_spec = 0;
+ ssl->state = SSL3_ST_CW_CHANGE_A;
}
- s->init_num = 0;
+ ssl->init_num = 0;
break;
case SSL3_ST_CW_CERT_VRFY_A:
case SSL3_ST_CW_CERT_VRFY_B:
case SSL3_ST_CW_CERT_VRFY_C:
- ret = ssl3_send_cert_verify(s);
+ ret = ssl3_send_cert_verify(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_CW_CHANGE_A;
- s->init_num = 0;
- s->s3->change_cipher_spec = 0;
+ ssl->state = SSL3_ST_CW_CHANGE_A;
+ ssl->init_num = 0;
break;
case SSL3_ST_CW_CHANGE_A:
case SSL3_ST_CW_CHANGE_B:
- ret = ssl3_send_change_cipher_spec(s, SSL3_ST_CW_CHANGE_A,
+ ret = ssl3_send_change_cipher_spec(ssl, SSL3_ST_CW_CHANGE_A,
SSL3_ST_CW_CHANGE_B);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_CW_FINISHED_A;
- if (s->s3->tlsext_channel_id_valid) {
- s->state = SSL3_ST_CW_CHANNEL_ID_A;
+ ssl->state = SSL3_ST_CW_FINISHED_A;
+ if (ssl->s3->tlsext_channel_id_valid) {
+ ssl->state = SSL3_ST_CW_CHANNEL_ID_A;
}
- if (s->s3->next_proto_neg_seen) {
- s->state = SSL3_ST_CW_NEXT_PROTO_A;
+ if (ssl->s3->next_proto_neg_seen) {
+ ssl->state = SSL3_ST_CW_NEXT_PROTO_A;
}
- s->init_num = 0;
+ ssl->init_num = 0;
- s->session->cipher = s->s3->tmp.new_cipher;
- if (!s->enc_method->setup_key_block(s) ||
- !s->enc_method->change_cipher_state(
- s, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) {
+ ssl->session->cipher = ssl->s3->tmp.new_cipher;
+ if (!ssl->enc_method->setup_key_block(ssl) ||
+ !ssl->enc_method->change_cipher_state(
+ ssl, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) {
ret = -1;
goto end;
}
@@ -402,162 +400,165 @@ int ssl3_connect(SSL *s) {
case SSL3_ST_CW_NEXT_PROTO_A:
case SSL3_ST_CW_NEXT_PROTO_B:
- ret = ssl3_send_next_proto(s);
+ ret = ssl3_send_next_proto(ssl);
if (ret <= 0) {
goto end;
}
- if (s->s3->tlsext_channel_id_valid) {
- s->state = SSL3_ST_CW_CHANNEL_ID_A;
+ if (ssl->s3->tlsext_channel_id_valid) {
+ ssl->state = SSL3_ST_CW_CHANNEL_ID_A;
} else {
- s->state = SSL3_ST_CW_FINISHED_A;
+ ssl->state = SSL3_ST_CW_FINISHED_A;
}
break;
case SSL3_ST_CW_CHANNEL_ID_A:
case SSL3_ST_CW_CHANNEL_ID_B:
- ret = ssl3_send_channel_id(s);
+ ret = ssl3_send_channel_id(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_CW_FINISHED_A;
+ ssl->state = SSL3_ST_CW_FINISHED_A;
break;
case SSL3_ST_CW_FINISHED_A:
case SSL3_ST_CW_FINISHED_B:
- ret =
- ssl3_send_finished(s, SSL3_ST_CW_FINISHED_A, SSL3_ST_CW_FINISHED_B,
- s->enc_method->client_finished_label,
- s->enc_method->client_finished_label_len);
+ ret = ssl3_send_finished(ssl, SSL3_ST_CW_FINISHED_A,
+ SSL3_ST_CW_FINISHED_B,
+ ssl->enc_method->client_finished_label,
+ ssl->enc_method->client_finished_label_len);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_CW_FLUSH;
+ ssl->state = SSL3_ST_CW_FLUSH;
- if (s->hit) {
- s->s3->tmp.next_state = SSL_ST_OK;
+ if (ssl->hit) {
+ ssl->s3->tmp.next_state = SSL_ST_OK;
} else {
/* This is a non-resumption handshake. If it involves ChannelID, then
* record the handshake hashes at this point in the session so that
* any resumption of this session with ChannelID can sign those
* hashes. */
- ret = tls1_record_handshake_hashes_for_channel_id(s);
+ ret = tls1_record_handshake_hashes_for_channel_id(ssl);
if (ret <= 0) {
goto end;
}
- if ((SSL_get_mode(s) & SSL_MODE_ENABLE_FALSE_START) &&
- ssl3_can_false_start(s) &&
+ if ((SSL_get_mode(ssl) & SSL_MODE_ENABLE_FALSE_START) &&
+ ssl3_can_false_start(ssl) &&
/* No False Start on renegotiation (would complicate the state
* machine). */
- !s->s3->initial_handshake_complete) {
- s->s3->tmp.next_state = SSL3_ST_FALSE_START;
+ !ssl->s3->initial_handshake_complete) {
+ ssl->s3->tmp.next_state = SSL3_ST_FALSE_START;
} else {
/* Allow NewSessionTicket if ticket expected */
- if (s->tlsext_ticket_expected) {
- s->s3->tmp.next_state = SSL3_ST_CR_SESSION_TICKET_A;
+ if (ssl->tlsext_ticket_expected) {
+ ssl->s3->tmp.next_state = SSL3_ST_CR_SESSION_TICKET_A;
} else {
- s->s3->tmp.next_state = SSL3_ST_CR_CHANGE;
+ ssl->s3->tmp.next_state = SSL3_ST_CR_CHANGE;
}
}
}
- s->init_num = 0;
+ ssl->init_num = 0;
break;
case SSL3_ST_CR_SESSION_TICKET_A:
case SSL3_ST_CR_SESSION_TICKET_B:
- ret = ssl3_get_new_session_ticket(s);
+ ret = ssl3_get_new_session_ticket(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_CR_CHANGE;
- s->init_num = 0;
+ ssl->state = SSL3_ST_CR_CHANGE;
+ ssl->init_num = 0;
break;
case SSL3_ST_CR_CERT_STATUS_A:
case SSL3_ST_CR_CERT_STATUS_B:
- ret = ssl3_get_cert_status(s);
+ ret = ssl3_get_cert_status(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_VERIFY_SERVER_CERT;
- s->init_num = 0;
+ ssl->state = SSL3_ST_VERIFY_SERVER_CERT;
+ ssl->init_num = 0;
break;
case SSL3_ST_CR_CHANGE:
- /* At this point, the next message must be entirely behind a
- * ChangeCipherSpec. */
- if (!ssl3_expect_change_cipher_spec(s)) {
+ ret = ssl->method->ssl_read_change_cipher_spec(ssl);
+ if (ret <= 0) {
+ goto end;
+ }
+
+ if (!ssl3_do_change_cipher_spec(ssl)) {
ret = -1;
goto end;
}
- s->state = SSL3_ST_CR_FINISHED_A;
+ ssl->state = SSL3_ST_CR_FINISHED_A;
break;
case SSL3_ST_CR_FINISHED_A:
case SSL3_ST_CR_FINISHED_B:
- ret =
- ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A, SSL3_ST_CR_FINISHED_B);
+ ret = ssl3_get_finished(ssl, SSL3_ST_CR_FINISHED_A,
+ SSL3_ST_CR_FINISHED_B);
if (ret <= 0) {
goto end;
}
- if (s->hit) {
- s->state = SSL3_ST_CW_CHANGE_A;
+ if (ssl->hit) {
+ ssl->state = SSL3_ST_CW_CHANGE_A;
} else {
- s->state = SSL_ST_OK;
+ ssl->state = SSL_ST_OK;
}
- s->init_num = 0;
+ ssl->init_num = 0;
break;
case SSL3_ST_CW_FLUSH:
- s->rwstate = SSL_WRITING;
- if (BIO_flush(s->wbio) <= 0) {
+ ssl->rwstate = SSL_WRITING;
+ if (BIO_flush(ssl->wbio) <= 0) {
ret = -1;
goto end;
}
- s->rwstate = SSL_NOTHING;
- s->state = s->s3->tmp.next_state;
+ ssl->rwstate = SSL_NOTHING;
+ ssl->state = ssl->s3->tmp.next_state;
break;
case SSL3_ST_FALSE_START:
/* Allow NewSessionTicket if ticket expected */
- if (s->tlsext_ticket_expected) {
- s->state = SSL3_ST_CR_SESSION_TICKET_A;
+ if (ssl->tlsext_ticket_expected) {
+ ssl->state = SSL3_ST_CR_SESSION_TICKET_A;
} else {
- s->state = SSL3_ST_CR_CHANGE;
+ ssl->state = SSL3_ST_CR_CHANGE;
}
- s->s3->tmp.in_false_start = 1;
+ ssl->s3->tmp.in_false_start = 1;
- ssl_free_wbio_buffer(s);
+ ssl_free_wbio_buffer(ssl);
ret = 1;
goto end;
case SSL_ST_OK:
/* clean a few things up */
- ssl3_cleanup_key_block(s);
+ ssl3_cleanup_key_block(ssl);
- BUF_MEM_free(s->init_buf);
- s->init_buf = NULL;
+ BUF_MEM_free(ssl->init_buf);
+ ssl->init_buf = NULL;
/* Remove write buffering now. */
- ssl_free_wbio_buffer(s);
+ ssl_free_wbio_buffer(ssl);
- const int is_initial_handshake = !s->s3->initial_handshake_complete;
+ const int is_initial_handshake = !ssl->s3->initial_handshake_complete;
- s->init_num = 0;
- s->s3->tmp.in_false_start = 0;
- s->s3->initial_handshake_complete = 1;
+ ssl->init_num = 0;
+ ssl->s3->tmp.in_false_start = 0;
+ ssl->s3->initial_handshake_complete = 1;
if (is_initial_handshake) {
/* Renegotiations do not participate in session resumption. */
- ssl_update_cache(s, SSL_SESS_CACHE_CLIENT);
+ ssl_update_cache(ssl, SSL_SESS_CACHE_CLIENT);
}
ret = 1;
- /* s->server=0; */
+ /* ssl->server=0; */
if (cb != NULL) {
- cb(s, SSL_CB_HANDSHAKE_DONE, 1);
+ cb(ssl, SSL_CB_HANDSHAKE_DONE, 1);
}
goto end;
@@ -568,22 +569,22 @@ int ssl3_connect(SSL *s) {
goto end;
}
- if (!s->s3->tmp.reuse_message && !skip) {
- if (cb != NULL && s->state != state) {
- new_state = s->state;
- s->state = state;
- cb(s, SSL_CB_CONNECT_LOOP, 1);
- s->state = new_state;
+ if (!ssl->s3->tmp.reuse_message && !skip) {
+ if (cb != NULL && ssl->state != state) {
+ new_state = ssl->state;
+ ssl->state = state;
+ cb(ssl, SSL_CB_CONNECT_LOOP, 1);
+ ssl->state = new_state;
}
}
skip = 0;
}
end:
- s->in_handshake--;
+ ssl->in_handshake--;
BUF_MEM_free(buf);
if (cb != NULL) {
- cb(s, SSL_CB_CONNECT_EXIT, ret);
+ cb(ssl, SSL_CB_CONNECT_EXIT, ret);
}
return ret;
}
@@ -735,17 +736,17 @@ err:
return -1;
}
-int ssl3_get_server_hello(SSL *s) {
+int ssl3_get_server_hello(SSL *ssl) {
STACK_OF(SSL_CIPHER) *sk;
const SSL_CIPHER *c;
- CERT *ct = s->cert;
+ CERT *ct = ssl->cert;
int al = SSL_AD_INTERNAL_ERROR, ok;
long n;
CBS server_hello, server_random, session_id;
uint16_t server_version, cipher_suite;
uint8_t compression_method;
- n = s->method->ssl_get_message(s, SSL3_ST_CR_SRVR_HELLO_A,
+ n = ssl->method->ssl_get_message(ssl, SSL3_ST_CR_SRVR_HELLO_A,
SSL3_ST_CR_SRVR_HELLO_B, SSL3_MT_SERVER_HELLO,
20000, /* ?? */
ssl_hash_message, &ok);
@@ -765,7 +766,7 @@ int ssl3_get_server_hello(SSL *s) {
return n;
}
- CBS_init(&server_hello, s->init_msg, n);
+ CBS_init(&server_hello, ssl->init_msg, n);
if (!CBS_get_u16(&server_hello, &server_version) ||
!CBS_get_bytes(&server_hello, &server_random, SSL3_RANDOM_SIZE) ||
@@ -778,55 +779,56 @@ int ssl3_get_server_hello(SSL *s) {
goto f_err;
}
- assert(s->s3->have_version == s->s3->initial_handshake_complete);
- if (!s->s3->have_version) {
- if (!ssl3_is_version_enabled(s, server_version)) {
+ assert(ssl->s3->have_version == ssl->s3->initial_handshake_complete);
+ if (!ssl->s3->have_version) {
+ if (!ssl3_is_version_enabled(ssl, server_version)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL);
- s->version = server_version;
+ ssl->version = server_version;
/* Mark the version as fixed so the record-layer version is not clamped
* to TLS 1.0. */
- s->s3->have_version = 1;
+ ssl->s3->have_version = 1;
al = SSL_AD_PROTOCOL_VERSION;
goto f_err;
}
- s->version = server_version;
- s->enc_method = ssl3_get_enc_method(server_version);
- assert(s->enc_method != NULL);
- /* At this point, the connection's version is known and s->version is
+ ssl->version = server_version;
+ ssl->enc_method = ssl3_get_enc_method(server_version);
+ assert(ssl->enc_method != NULL);
+ /* At this point, the connection's version is known and ssl->version is
* fixed. Begin enforcing the record-layer version. */
- s->s3->have_version = 1;
- } else if (server_version != s->version) {
+ ssl->s3->have_version = 1;
+ } else if (server_version != ssl->version) {
OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SSL_VERSION);
al = SSL_AD_PROTOCOL_VERSION;
goto f_err;
}
/* Copy over the server random. */
- memcpy(s->s3->server_random, CBS_data(&server_random), SSL3_RANDOM_SIZE);
-
- assert(s->session == NULL || s->session->session_id_length > 0);
- if (!s->s3->initial_handshake_complete && s->session != NULL &&
- CBS_mem_equal(&session_id, s->session->session_id,
- s->session->session_id_length)) {
- if (s->sid_ctx_length != s->session->sid_ctx_length ||
- memcmp(s->session->sid_ctx, s->sid_ctx, s->sid_ctx_length)) {
+ memcpy(ssl->s3->server_random, CBS_data(&server_random), SSL3_RANDOM_SIZE);
+
+ assert(ssl->session == NULL || ssl->session->session_id_length > 0);
+ if (!ssl->s3->initial_handshake_complete && ssl->session != NULL &&
+ CBS_mem_equal(&session_id, ssl->session->session_id,
+ ssl->session->session_id_length)) {
+ if (ssl->sid_ctx_length != ssl->session->sid_ctx_length ||
+ memcmp(ssl->session->sid_ctx, ssl->sid_ctx, ssl->sid_ctx_length)) {
/* actually a client application bug */
al = SSL_AD_ILLEGAL_PARAMETER;
OPENSSL_PUT_ERROR(SSL,
SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
goto f_err;
}
- s->hit = 1;
+ ssl->hit = 1;
} else {
/* The session wasn't resumed. Create a fresh SSL_SESSION to
* fill out. */
- s->hit = 0;
- if (!ssl_get_new_session(s, 0 /* client */)) {
+ ssl->hit = 0;
+ if (!ssl_get_new_session(ssl, 0 /* client */)) {
goto f_err;
}
/* Note: session_id could be empty. */
- s->session->session_id_length = CBS_len(&session_id);
- memcpy(s->session->session_id, CBS_data(&session_id), CBS_len(&session_id));
+ ssl->session->session_id_length = CBS_len(&session_id);
+ memcpy(ssl->session->session_id, CBS_data(&session_id),
+ CBS_len(&session_id));
}
c = SSL_get_cipher_by_value(cipher_suite);
@@ -838,15 +840,15 @@ int ssl3_get_server_hello(SSL *s) {
}
/* If the cipher is disabled then we didn't sent it in the ClientHello, so if
* the server selected it, it's an error. */
- if ((c->algorithm_mkey & ct->mask_k) ||
- (c->algorithm_auth & ct->mask_a) ||
- SSL_CIPHER_get_min_version(c) > ssl3_version_from_wire(s, s->version)) {
+ if ((c->algorithm_mkey & ct->mask_k) || (c->algorithm_auth & ct->mask_a) ||
+ SSL_CIPHER_get_min_version(c) >
+ ssl3_version_from_wire(ssl, ssl->version)) {
al = SSL_AD_ILLEGAL_PARAMETER;
OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED);
goto f_err;
}
- sk = ssl_get_ciphers_by_id(s);
+ sk = ssl_get_ciphers_by_id(ssl);
if (!sk_SSL_CIPHER_find(sk, NULL, c)) {
/* we did not say we would use this cipher */
al = SSL_AD_ILLEGAL_PARAMETER;
@@ -854,30 +856,30 @@ int ssl3_get_server_hello(SSL *s) {
goto f_err;
}
- if (s->hit) {
- if (s->session->cipher != c) {
+ if (ssl->hit) {
+ if (ssl->session->cipher != c) {
al = SSL_AD_ILLEGAL_PARAMETER;
OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);
goto f_err;
}
- if (s->session->ssl_version != s->version) {
+ if (ssl->session->ssl_version != ssl->version) {
al = SSL_AD_ILLEGAL_PARAMETER;
OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_VERSION_NOT_RETURNED);
goto f_err;
}
}
- s->s3->tmp.new_cipher = c;
+ ssl->s3->tmp.new_cipher = c;
/* Now that the cipher is known, initialize the handshake hash. */
- if (!ssl3_init_handshake_hash(s)) {
+ if (!ssl3_init_handshake_hash(ssl)) {
goto f_err;
}
/* If doing a full handshake with TLS 1.2, the server may request a client
* certificate which requires hashing the handshake transcript under a
* different hash. Otherwise, the handshake buffer may be released. */
- if (!SSL_USE_SIGALGS(s) || s->hit) {
- ssl3_free_handshake_buffer(s);
+ if (!SSL_USE_SIGALGS(ssl) || ssl->hit) {
+ ssl3_free_handshake_buffer(ssl);
}
/* Only the NULL compression algorithm is supported. */
@@ -888,7 +890,7 @@ int ssl3_get_server_hello(SSL *s) {
}
/* TLS extensions */
- if (!ssl_parse_serverhello_tlsext(s, &server_hello)) {
+ if (!ssl_parse_serverhello_tlsext(ssl, &server_hello)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT);
goto err;
}
@@ -901,10 +903,11 @@ int ssl3_get_server_hello(SSL *s) {
goto f_err;
}
- if (s->hit &&
- s->s3->tmp.extended_master_secret != s->session->extended_master_secret) {
+ if (ssl->hit &&
+ ssl->s3->tmp.extended_master_secret !=
+ ssl->session->extended_master_secret) {
al = SSL_AD_HANDSHAKE_FAILURE;
- if (s->session->extended_master_secret) {
+ if (ssl->session->extended_master_secret) {
OPENSSL_PUT_ERROR(SSL, SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION);
} else {
OPENSSL_PUT_ERROR(SSL, SSL_R_RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION);
@@ -915,16 +918,15 @@ int ssl3_get_server_hello(SSL *s) {
return 1;
f_err:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
err:
return -1;
}
-/* ssl3_check_certificate_for_cipher returns one if |leaf| is a suitable server
- * certificate type for |cipher|. Otherwise, it returns zero and pushes an error
- * on the error queue. */
-static int ssl3_check_certificate_for_cipher(X509 *leaf,
- const SSL_CIPHER *cipher) {
+/* ssl3_check_leaf_certificate returns one if |leaf| is a suitable leaf server
+ * certificate for |ssl|. Otherwise, it returns zero and pushes an error on the
+ * error queue. */
+static int ssl3_check_leaf_certificate(SSL *ssl, X509 *leaf) {
int ret = 0;
EVP_PKEY *pkey = X509_get_pubkey(leaf);
if (pkey == NULL) {
@@ -932,6 +934,7 @@ static int ssl3_check_certificate_for_cipher(X509 *leaf,
}
/* Check the certificate's type matches the cipher. */
+ const SSL_CIPHER *cipher = ssl->s3->tmp.new_cipher;
int expected_type = ssl_cipher_get_key_type(cipher);
assert(expected_type != EVP_PKEY_NONE);
if (pkey->type != expected_type) {
@@ -939,9 +942,9 @@ static int ssl3_check_certificate_for_cipher(X509 *leaf,
goto err;
}
- /* TODO(davidben): This behavior is preserved from upstream. Should key usages
- * be checked in other cases as well? */
if (cipher->algorithm_auth & SSL_aECDSA) {
+ /* TODO(davidben): This behavior is preserved from upstream. Should key
+ * usages be checked in other cases as well? */
/* This call populates the ex_flags field correctly */
X509_check_purpose(leaf, -1, 0);
if ((leaf->ex_flags & EXFLAG_KUSAGE) &&
@@ -949,6 +952,11 @@ static int ssl3_check_certificate_for_cipher(X509 *leaf,
OPENSSL_PUT_ERROR(SSL, SSL_R_ECC_CERT_NOT_FOR_SIGNING);
goto err;
}
+
+ if (!tls1_check_ec_cert(ssl, leaf)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECC_CERT);
+ goto err;
+ }
}
ret = 1;
@@ -958,7 +966,7 @@ err:
return ret;
}
-int ssl3_get_server_certificate(SSL *s) {
+int ssl3_get_server_certificate(SSL *ssl) {
int al, ok, ret = -1;
unsigned long n;
X509 *x = NULL;
@@ -967,15 +975,15 @@ int ssl3_get_server_certificate(SSL *s) {
CBS cbs, certificate_list;
const uint8_t *data;
- n = s->method->ssl_get_message(s, SSL3_ST_CR_CERT_A, SSL3_ST_CR_CERT_B,
- SSL3_MT_CERTIFICATE, (long)s->max_cert_list,
+ n = ssl->method->ssl_get_message(ssl, SSL3_ST_CR_CERT_A, SSL3_ST_CR_CERT_B,
+ SSL3_MT_CERTIFICATE, (long)ssl->max_cert_list,
ssl_hash_message, &ok);
if (!ok) {
return n;
}
- CBS_init(&cbs, s->init_msg, n);
+ CBS_init(&cbs, ssl->init_msg, n);
sk = sk_X509_new_null();
if (sk == NULL) {
@@ -998,8 +1006,9 @@ int ssl3_get_server_certificate(SSL *s) {
OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH);
goto f_err;
}
+ /* A u24 length cannot overflow a long. */
data = CBS_data(&certificate);
- x = d2i_X509(NULL, &data, CBS_len(&certificate));
+ x = d2i_X509(NULL, &data, (long)CBS_len(&certificate));
if (x == NULL) {
al = SSL_AD_BAD_CERTIFICATE;
OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
@@ -1018,27 +1027,27 @@ int ssl3_get_server_certificate(SSL *s) {
}
X509 *leaf = sk_X509_value(sk, 0);
- if (!ssl3_check_certificate_for_cipher(leaf, s->s3->tmp.new_cipher)) {
+ if (!ssl3_check_leaf_certificate(ssl, leaf)) {
al = SSL_AD_ILLEGAL_PARAMETER;
goto f_err;
}
/* NOTE: Unlike the server half, the client's copy of |cert_chain| includes
* the leaf. */
- sk_X509_pop_free(s->session->cert_chain, X509_free);
- s->session->cert_chain = sk;
+ sk_X509_pop_free(ssl->session->cert_chain, X509_free);
+ ssl->session->cert_chain = sk;
sk = NULL;
- X509_free(s->session->peer);
- s->session->peer = X509_up_ref(leaf);
+ X509_free(ssl->session->peer);
+ ssl->session->peer = X509_up_ref(leaf);
- s->session->verify_result = s->verify_result;
+ ssl->session->verify_result = ssl->verify_result;
ret = 1;
if (0) {
f_err:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
}
err:
@@ -1048,53 +1057,51 @@ err:
return ret;
}
-int ssl3_get_server_key_exchange(SSL *s) {
+int ssl3_get_server_key_exchange(SSL *ssl) {
EVP_MD_CTX md_ctx;
int al, ok;
long n, alg_k, alg_a;
EVP_PKEY *pkey = NULL;
const EVP_MD *md = NULL;
- RSA *rsa = NULL;
DH *dh = NULL;
EC_KEY *ecdh = NULL;
- BN_CTX *bn_ctx = NULL;
EC_POINT *srvr_ecpoint = NULL;
CBS server_key_exchange, server_key_exchange_orig, parameter;
/* use same message size as in ssl3_get_certificate_request() as
* ServerKeyExchange message may be skipped */
- n = s->method->ssl_get_message(s, SSL3_ST_CR_KEY_EXCH_A,
- SSL3_ST_CR_KEY_EXCH_B, -1, s->max_cert_list,
+ n = ssl->method->ssl_get_message(ssl, SSL3_ST_CR_KEY_EXCH_A,
+ SSL3_ST_CR_KEY_EXCH_B, -1, ssl->max_cert_list,
ssl_hash_message, &ok);
if (!ok) {
return n;
}
- if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE) {
- if (ssl_cipher_requires_server_key_exchange(s->s3->tmp.new_cipher)) {
+ if (ssl->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE) {
+ if (ssl_cipher_requires_server_key_exchange(ssl->s3->tmp.new_cipher)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
return -1;
}
/* In plain PSK ciphersuite, ServerKeyExchange may be omitted to send no
* identity hint. */
- if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aPSK) {
+ if (ssl->s3->tmp.new_cipher->algorithm_auth & SSL_aPSK) {
/* TODO(davidben): This should be reset in one place with the rest of the
* handshake state. */
- OPENSSL_free(s->s3->tmp.peer_psk_identity_hint);
- s->s3->tmp.peer_psk_identity_hint = NULL;
+ OPENSSL_free(ssl->s3->tmp.peer_psk_identity_hint);
+ ssl->s3->tmp.peer_psk_identity_hint = NULL;
}
- s->s3->tmp.reuse_message = 1;
+ ssl->s3->tmp.reuse_message = 1;
return 1;
}
/* Retain a copy of the original CBS to compute the signature over. */
- CBS_init(&server_key_exchange, s->init_msg, n);
+ CBS_init(&server_key_exchange, ssl->init_msg, n);
server_key_exchange_orig = server_key_exchange;
- alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
- alg_a = s->s3->tmp.new_cipher->algorithm_auth;
+ alg_k = ssl->s3->tmp.new_cipher->algorithm_mkey;
+ alg_a = ssl->s3->tmp.new_cipher->algorithm_auth;
EVP_MD_CTX_init(&md_ctx);
if (alg_a & SSL_aPSK) {
@@ -1123,7 +1130,7 @@ int ssl3_get_server_key_exchange(SSL *s) {
}
/* Save the identity hint as a C string. */
- if (!CBS_strdup(&psk_identity_hint, &s->s3->tmp.peer_psk_identity_hint)) {
+ if (!CBS_strdup(&psk_identity_hint, &ssl->s3->tmp.peer_psk_identity_hint)) {
al = SSL_AD_INTERNAL_ERROR;
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto f_err;
@@ -1132,7 +1139,6 @@ int ssl3_get_server_key_exchange(SSL *s) {
if (alg_k & SSL_kDHE) {
CBS dh_p, dh_g, dh_Ys;
-
if (!CBS_get_u16_length_prefixed(&server_key_exchange, &dh_p) ||
CBS_len(&dh_p) == 0 ||
!CBS_get_u16_length_prefixed(&server_key_exchange, &dh_g) ||
@@ -1146,84 +1152,69 @@ int ssl3_get_server_key_exchange(SSL *s) {
dh = DH_new();
if (dh == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
goto err;
}
- if ((dh->p = BN_bin2bn(CBS_data(&dh_p), CBS_len(&dh_p), NULL)) == NULL ||
- (dh->g = BN_bin2bn(CBS_data(&dh_g), CBS_len(&dh_g), NULL)) == NULL ||
- (dh->pub_key = BN_bin2bn(CBS_data(&dh_Ys), CBS_len(&dh_Ys), NULL)) ==
- NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_BN_LIB);
+ dh->p = BN_bin2bn(CBS_data(&dh_p), CBS_len(&dh_p), NULL);
+ dh->g = BN_bin2bn(CBS_data(&dh_g), CBS_len(&dh_g), NULL);
+ if (dh->p == NULL || dh->g == NULL) {
goto err;
}
- s->session->key_exchange_info = DH_num_bits(dh);
- if (s->session->key_exchange_info < 1024) {
+ ssl->session->key_exchange_info = DH_num_bits(dh);
+ if (ssl->session->key_exchange_info < 1024) {
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_DH_P_LENGTH);
goto err;
+ } else if (ssl->session->key_exchange_info > 4096) {
+ /* Overly large DHE groups are prohibitively expensive, so enforce a limit
+ * to prevent a server from causing us to perform too expensive of a
+ * computation. */
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DH_P_TOO_LONG);
+ goto err;
}
- DH_free(s->s3->tmp.peer_dh_tmp);
- s->s3->tmp.peer_dh_tmp = dh;
+
+ SSL_ECDH_CTX_init_for_dhe(&ssl->s3->tmp.ecdh_ctx, dh);
dh = NULL;
+
+ /* Save the peer public key for later. */
+ size_t peer_key_len;
+ if (!CBS_stow(&dh_Ys, &ssl->s3->tmp.peer_key, &peer_key_len)) {
+ goto err;
+ }
+ /* |dh_Ys| has a u16 length prefix, so this fits in a |uint16_t|. */
+ assert(sizeof(ssl->s3->tmp.peer_key_len) == 2 && peer_key_len <= 0xffff);
+ ssl->s3->tmp.peer_key_len = (uint16_t)peer_key_len;
} else if (alg_k & SSL_kECDHE) {
+ /* Parse the server parameters. */
+ uint8_t curve_type;
uint16_t curve_id;
- int curve_nid = 0;
- const EC_GROUP *group;
CBS point;
-
- /* Extract elliptic curve parameters and the server's ephemeral ECDH public
- * key. Check curve is one of our preferences, if not server has sent an
- * invalid curve. */
- if (!tls1_check_curve(s, &server_key_exchange, &curve_id)) {
+ if (!CBS_get_u8(&server_key_exchange, &curve_type) ||
+ curve_type != NAMED_CURVE_TYPE ||
+ !CBS_get_u16(&server_key_exchange, &curve_id) ||
+ !CBS_get_u8_length_prefixed(&server_key_exchange, &point)) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
- goto f_err;
- }
-
- curve_nid = tls1_ec_curve_id2nid(curve_id);
- if (curve_nid == 0) {
- al = SSL_AD_INTERNAL_ERROR;
- OPENSSL_PUT_ERROR(SSL, SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
+ ssl->session->key_exchange_info = curve_id;
- ecdh = EC_KEY_new_by_curve_name(curve_nid);
- s->session->key_exchange_info = curve_id;
- if (ecdh == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_EC_LIB);
- goto err;
- }
-
- group = EC_KEY_get0_group(ecdh);
-
- /* Next, get the encoded ECPoint */
- if (!CBS_get_u8_length_prefixed(&server_key_exchange, &point)) {
- al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
+ /* Ensure the curve is consistent with preferences. */
+ if (!tls1_check_curve_id(ssl, curve_id)) {
+ al = SSL_AD_ILLEGAL_PARAMETER;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
goto f_err;
}
- if (((srvr_ecpoint = EC_POINT_new(group)) == NULL) ||
- ((bn_ctx = BN_CTX_new()) == NULL)) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ /* Initialize ECDH and save the peer public key for later. */
+ size_t peer_key_len;
+ if (!SSL_ECDH_CTX_init(&ssl->s3->tmp.ecdh_ctx, curve_id) ||
+ !CBS_stow(&point, &ssl->s3->tmp.peer_key, &peer_key_len)) {
goto err;
}
-
- if (!EC_POINT_oct2point(group, srvr_ecpoint, CBS_data(&point),
- CBS_len(&point), bn_ctx)) {
- al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT);
- goto f_err;
- }
- EC_KEY_set_public_key(ecdh, srvr_ecpoint);
- EC_KEY_free(s->s3->tmp.peer_ecdh_tmp);
- s->s3->tmp.peer_ecdh_tmp = ecdh;
- ecdh = NULL;
- BN_CTX_free(bn_ctx);
- bn_ctx = NULL;
- EC_POINT_free(srvr_ecpoint);
- srvr_ecpoint = NULL;
+ /* |point| has a u8 length prefix, so this fits in a |uint16_t|. */
+ assert(sizeof(ssl->s3->tmp.peer_key_len) == 2 && peer_key_len <= 0xffff);
+ ssl->s3->tmp.peer_key_len = (uint16_t)peer_key_len;
} else if (!(alg_k & SSL_kPSK)) {
al = SSL_AD_UNEXPECTED_MESSAGE;
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
@@ -1237,13 +1228,13 @@ int ssl3_get_server_key_exchange(SSL *s) {
CBS_len(&server_key_exchange_orig) - CBS_len(&server_key_exchange));
/* ServerKeyExchange should be signed by the server's public key. */
- if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) {
- pkey = X509_get_pubkey(s->session->peer);
+ if (ssl_cipher_has_server_public_key(ssl->s3->tmp.new_cipher)) {
+ pkey = X509_get_pubkey(ssl->session->peer);
if (pkey == NULL) {
goto err;
}
- if (SSL_USE_SIGALGS(s)) {
+ if (SSL_USE_SIGALGS(ssl)) {
uint8_t hash, signature;
if (!CBS_get_u8(&server_key_exchange, &hash) ||
!CBS_get_u8(&server_key_exchange, &signature)) {
@@ -1251,10 +1242,10 @@ int ssl3_get_server_key_exchange(SSL *s) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
- if (!tls12_check_peer_sigalg(s, &md, &al, hash, signature, pkey)) {
+ if (!tls12_check_peer_sigalg(ssl, &md, &al, hash, signature, pkey)) {
goto f_err;
}
- s->s3->tmp.server_key_exchange_hash = hash;
+ ssl->s3->tmp.server_key_exchange_hash = hash;
} else if (pkey->type == EVP_PKEY_RSA) {
md = EVP_md5_sha1();
} else {
@@ -1271,9 +1262,9 @@ int ssl3_get_server_key_exchange(SSL *s) {
}
if (!EVP_DigestVerifyInit(&md_ctx, NULL, md, NULL, pkey) ||
- !EVP_DigestVerifyUpdate(&md_ctx, s->s3->client_random,
+ !EVP_DigestVerifyUpdate(&md_ctx, ssl->s3->client_random,
SSL3_RANDOM_SIZE) ||
- !EVP_DigestVerifyUpdate(&md_ctx, s->s3->server_random,
+ !EVP_DigestVerifyUpdate(&md_ctx, ssl->s3->server_random,
SSL3_RANDOM_SIZE) ||
!EVP_DigestVerifyUpdate(&md_ctx, CBS_data(&parameter),
CBS_len(&parameter)) ||
@@ -1299,12 +1290,10 @@ int ssl3_get_server_key_exchange(SSL *s) {
return 1;
f_err:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
err:
EVP_PKEY_free(pkey);
- RSA_free(rsa);
DH_free(dh);
- BN_CTX_free(bn_ctx);
EC_POINT_free(srvr_ecpoint);
EC_KEY_free(ecdh);
EVP_MD_CTX_cleanup(&md_ctx);
@@ -1315,7 +1304,7 @@ static int ca_dn_cmp(const X509_NAME **a, const X509_NAME **b) {
return X509_NAME_cmp(*a, *b);
}
-int ssl3_get_certificate_request(SSL *s) {
+int ssl3_get_certificate_request(SSL *ssl) {
int ok, ret = 0;
unsigned long n;
X509_NAME *xn = NULL;
@@ -1325,31 +1314,31 @@ int ssl3_get_certificate_request(SSL *s) {
CBS certificate_authorities;
const uint8_t *data;
- n = s->method->ssl_get_message(s, SSL3_ST_CR_CERT_REQ_A,
- SSL3_ST_CR_CERT_REQ_B, -1, s->max_cert_list,
+ n = ssl->method->ssl_get_message(ssl, SSL3_ST_CR_CERT_REQ_A,
+ SSL3_ST_CR_CERT_REQ_B, -1, ssl->max_cert_list,
ssl_hash_message, &ok);
if (!ok) {
return n;
}
- s->s3->tmp.cert_req = 0;
+ ssl->s3->tmp.cert_req = 0;
- if (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE) {
- s->s3->tmp.reuse_message = 1;
+ if (ssl->s3->tmp.message_type == SSL3_MT_SERVER_DONE) {
+ ssl->s3->tmp.reuse_message = 1;
/* If we get here we don't need the handshake buffer as we won't be doing
* client auth. */
- ssl3_free_handshake_buffer(s);
+ ssl3_free_handshake_buffer(ssl);
return 1;
}
- if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_REQUEST) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ if (ssl->s3->tmp.message_type != SSL3_MT_CERTIFICATE_REQUEST) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_MESSAGE_TYPE);
goto err;
}
- CBS_init(&cbs, s->init_msg, n);
+ CBS_init(&cbs, ssl->init_msg, n);
ca_sk = sk_X509_NAME_new(ca_dn_cmp);
if (ca_sk == NULL) {
@@ -1359,22 +1348,22 @@ int ssl3_get_certificate_request(SSL *s) {
/* get the certificate types */
if (!CBS_get_u8_length_prefixed(&cbs, &certificate_types)) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto err;
}
- if (!CBS_stow(&certificate_types, &s->s3->tmp.certificate_types,
- &s->s3->tmp.num_certificate_types)) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ if (!CBS_stow(&certificate_types, &ssl->s3->tmp.certificate_types,
+ &ssl->s3->tmp.num_certificate_types)) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
goto err;
}
- if (SSL_USE_SIGALGS(s)) {
+ if (SSL_USE_SIGALGS(ssl)) {
CBS supported_signature_algorithms;
if (!CBS_get_u16_length_prefixed(&cbs, &supported_signature_algorithms) ||
- !tls1_parse_peer_sigalgs(s, &supported_signature_algorithms)) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ !tls1_parse_peer_sigalgs(ssl, &supported_signature_algorithms)) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto err;
}
@@ -1382,7 +1371,7 @@ int ssl3_get_certificate_request(SSL *s) {
/* get the CA RDNs */
if (!CBS_get_u16_length_prefixed(&cbs, &certificate_authorities)) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_LENGTH_MISMATCH);
goto err;
}
@@ -1391,28 +1380,29 @@ int ssl3_get_certificate_request(SSL *s) {
CBS distinguished_name;
if (!CBS_get_u16_length_prefixed(&certificate_authorities,
&distinguished_name)) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_CA_DN_TOO_LONG);
goto err;
}
data = CBS_data(&distinguished_name);
- xn = d2i_X509_NAME(NULL, &data, CBS_len(&distinguished_name));
+ /* A u16 length cannot overflow a long. */
+ xn = d2i_X509_NAME(NULL, &data, (long)CBS_len(&distinguished_name));
if (xn == NULL) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
goto err;
}
if (!CBS_skip(&distinguished_name, data - CBS_data(&distinguished_name))) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
goto err;
}
if (CBS_len(&distinguished_name) != 0) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_CA_DN_LENGTH_MISMATCH);
goto err;
}
@@ -1424,9 +1414,9 @@ int ssl3_get_certificate_request(SSL *s) {
}
/* we should setup a certificate to return.... */
- s->s3->tmp.cert_req = 1;
- sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
- s->s3->tmp.ca_names = ca_sk;
+ ssl->s3->tmp.cert_req = 1;
+ sk_X509_NAME_pop_free(ssl->s3->tmp.ca_names, X509_NAME_free);
+ ssl->s3->tmp.ca_names = ca_sk;
ca_sk = NULL;
ret = 1;
@@ -1436,10 +1426,10 @@ err:
return ret;
}
-int ssl3_get_new_session_ticket(SSL *s) {
+int ssl3_get_new_session_ticket(SSL *ssl) {
int ok, al;
- long n = s->method->ssl_get_message(
- s, SSL3_ST_CR_SESSION_TICKET_A, SSL3_ST_CR_SESSION_TICKET_B,
+ long n = ssl->method->ssl_get_message(
+ ssl, SSL3_ST_CR_SESSION_TICKET_A, SSL3_ST_CR_SESSION_TICKET_B,
SSL3_MT_NEWSESSION_TICKET, 16384, ssl_hash_message, &ok);
if (!ok) {
@@ -1448,7 +1438,7 @@ int ssl3_get_new_session_ticket(SSL *s) {
CBS new_session_ticket, ticket;
uint32_t ticket_lifetime_hint;
- CBS_init(&new_session_ticket, s->init_msg, n);
+ CBS_init(&new_session_ticket, ssl->init_msg, n);
if (!CBS_get_u32(&new_session_ticket, &ticket_lifetime_hint) ||
!CBS_get_u16_length_prefixed(&new_session_ticket, &ticket) ||
CBS_len(&new_session_ticket) != 0) {
@@ -1462,17 +1452,17 @@ int ssl3_get_new_session_ticket(SSL *s) {
* negotiating the extension. The value of |tlsext_ticket_expected| is
* checked in |ssl_update_cache| so is cleared here to avoid an unnecessary
* update. */
- s->tlsext_ticket_expected = 0;
+ ssl->tlsext_ticket_expected = 0;
return 1;
}
- if (s->hit) {
+ if (ssl->hit) {
/* The server is sending a new ticket for an existing session. Sessions are
* immutable once established, so duplicate all but the ticket of the
* existing session. */
uint8_t *bytes;
size_t bytes_len;
- if (!SSL_SESSION_to_bytes_for_ticket(s->session, &bytes, &bytes_len)) {
+ if (!SSL_SESSION_to_bytes_for_ticket(ssl->session, &bytes, &bytes_len)) {
goto err;
}
SSL_SESSION *new_session = SSL_SESSION_from_bytes(bytes, bytes_len);
@@ -1483,55 +1473,55 @@ int ssl3_get_new_session_ticket(SSL *s) {
goto err;
}
- SSL_SESSION_free(s->session);
- s->session = new_session;
+ SSL_SESSION_free(ssl->session);
+ ssl->session = new_session;
}
- if (!CBS_stow(&ticket, &s->session->tlsext_tick,
- &s->session->tlsext_ticklen)) {
+ if (!CBS_stow(&ticket, &ssl->session->tlsext_tick,
+ &ssl->session->tlsext_ticklen)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
- s->session->tlsext_tick_lifetime_hint = ticket_lifetime_hint;
+ ssl->session->tlsext_tick_lifetime_hint = ticket_lifetime_hint;
/* Generate a session ID for this session based on the session ticket. We use
* the session ID mechanism for detecting ticket resumption. This also fits in
* with assumptions elsewhere in OpenSSL.*/
- if (!EVP_Digest(CBS_data(&ticket), CBS_len(&ticket), s->session->session_id,
- &s->session->session_id_length, EVP_sha256(), NULL)) {
+ if (!EVP_Digest(CBS_data(&ticket), CBS_len(&ticket), ssl->session->session_id,
+ &ssl->session->session_id_length, EVP_sha256(), NULL)) {
goto err;
}
return 1;
f_err:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
err:
return -1;
}
-int ssl3_get_cert_status(SSL *s) {
+int ssl3_get_cert_status(SSL *ssl) {
int ok, al;
long n;
CBS certificate_status, ocsp_response;
uint8_t status_type;
- n = s->method->ssl_get_message(
- s, SSL3_ST_CR_CERT_STATUS_A, SSL3_ST_CR_CERT_STATUS_B,
+ n = ssl->method->ssl_get_message(
+ ssl, SSL3_ST_CR_CERT_STATUS_A, SSL3_ST_CR_CERT_STATUS_B,
-1, 16384, ssl_hash_message, &ok);
if (!ok) {
return n;
}
- if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_STATUS) {
+ if (ssl->s3->tmp.message_type != SSL3_MT_CERTIFICATE_STATUS) {
/* A server may send status_request in ServerHello and then change
* its mind about sending CertificateStatus. */
- s->s3->tmp.reuse_message = 1;
+ ssl->s3->tmp.reuse_message = 1;
return 1;
}
- CBS_init(&certificate_status, s->init_msg, n);
+ CBS_init(&certificate_status, ssl->init_msg, n);
if (!CBS_get_u8(&certificate_status, &status_type) ||
status_type != TLSEXT_STATUSTYPE_ocsp ||
!CBS_get_u24_length_prefixed(&certificate_status, &ocsp_response) ||
@@ -1542,8 +1532,8 @@ int ssl3_get_cert_status(SSL *s) {
goto f_err;
}
- if (!CBS_stow(&ocsp_response, &s->session->ocsp_response,
- &s->session->ocsp_response_length)) {
+ if (!CBS_stow(&ocsp_response, &ssl->session->ocsp_response,
+ &ssl->session->ocsp_response_length)) {
al = SSL_AD_INTERNAL_ERROR;
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto f_err;
@@ -1551,15 +1541,15 @@ int ssl3_get_cert_status(SSL *s) {
return 1;
f_err:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
return -1;
}
-int ssl3_get_server_done(SSL *s) {
+int ssl3_get_server_done(SSL *ssl) {
int ok;
long n;
- n = s->method->ssl_get_message(s, SSL3_ST_CR_SRVR_DONE_A,
+ n = ssl->method->ssl_get_message(ssl, SSL3_ST_CR_SRVR_DONE_A,
SSL3_ST_CR_SRVR_DONE_B, SSL3_MT_SERVER_DONE,
30, /* should be very small, like 0 :-) */
ssl_hash_message, &ok);
@@ -1570,7 +1560,7 @@ int ssl3_get_server_done(SSL *s) {
if (n > 0) {
/* should contain no data */
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_LENGTH_MISMATCH);
return -1;
}
@@ -1581,415 +1571,298 @@ int ssl3_get_server_done(SSL *s) {
OPENSSL_COMPILE_ASSERT(sizeof(size_t) >= sizeof(unsigned),
SIZE_T_IS_SMALLER_THAN_UNSIGNED);
-int ssl3_send_client_key_exchange(SSL *s) {
- uint8_t *p;
- int n = 0;
- uint32_t alg_k;
- uint32_t alg_a;
- uint8_t *q;
- EVP_PKEY *pkey = NULL;
- EC_KEY *clnt_ecdh = NULL;
- const EC_POINT *srvr_ecpoint = NULL;
- EVP_PKEY *srvr_pub_pkey = NULL;
- uint8_t *encodedPoint = NULL;
- int encoded_pt_len = 0;
- BN_CTX *bn_ctx = NULL;
- unsigned int psk_len = 0;
- uint8_t psk[PSK_MAX_PSK_LEN];
+int ssl3_send_client_key_exchange(SSL *ssl) {
+ if (ssl->state == SSL3_ST_CW_KEY_EXCH_B) {
+ return ssl_do_write(ssl);
+ }
+ assert(ssl->state == SSL3_ST_CW_KEY_EXCH_A);
+
uint8_t *pms = NULL;
size_t pms_len = 0;
+ CBB cbb;
+ if (!CBB_init_fixed(&cbb, ssl_handshake_start(ssl),
+ ssl->init_buf->max - SSL_HM_HEADER_LENGTH(ssl))) {
+ goto err;
+ }
- if (s->state == SSL3_ST_CW_KEY_EXCH_A) {
- p = ssl_handshake_start(s);
-
- alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
- alg_a = s->s3->tmp.new_cipher->algorithm_auth;
-
- /* If using a PSK key exchange, prepare the pre-shared key. */
- if (alg_a & SSL_aPSK) {
- char identity[PSK_MAX_IDENTITY_LEN + 1];
- size_t identity_len;
-
- if (s->psk_client_callback == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_NO_CLIENT_CB);
- goto err;
- }
-
- memset(identity, 0, sizeof(identity));
- psk_len =
- s->psk_client_callback(s, s->s3->tmp.peer_psk_identity_hint, identity,
- sizeof(identity), psk, sizeof(psk));
- if (psk_len > PSK_MAX_PSK_LEN) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- goto err;
- } else if (psk_len == 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND);
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
- goto err;
- }
+ uint32_t alg_k = ssl->s3->tmp.new_cipher->algorithm_mkey;
+ uint32_t alg_a = ssl->s3->tmp.new_cipher->algorithm_auth;
- identity_len = OPENSSL_strnlen(identity, sizeof(identity));
- if (identity_len > PSK_MAX_IDENTITY_LEN) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- goto err;
- }
+ /* If using a PSK key exchange, prepare the pre-shared key. */
+ unsigned psk_len = 0;
+ uint8_t psk[PSK_MAX_PSK_LEN];
+ if (alg_a & SSL_aPSK) {
+ if (ssl->psk_client_callback == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_NO_CLIENT_CB);
+ goto err;
+ }
- OPENSSL_free(s->session->psk_identity);
- s->session->psk_identity = BUF_strdup(identity);
- if (s->session->psk_identity == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- goto err;
- }
+ char identity[PSK_MAX_IDENTITY_LEN + 1];
+ memset(identity, 0, sizeof(identity));
+ psk_len = ssl->psk_client_callback(
+ ssl, ssl->s3->tmp.peer_psk_identity_hint, identity, sizeof(identity),
+ psk, sizeof(psk));
+ if (psk_len == 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+ goto err;
+ }
+ assert(psk_len <= PSK_MAX_PSK_LEN);
- /* Write out psk_identity. */
- s2n(identity_len, p);
- memcpy(p, identity, identity_len);
- p += identity_len;
- n = 2 + identity_len;
+ OPENSSL_free(ssl->session->psk_identity);
+ ssl->session->psk_identity = BUF_strdup(identity);
+ if (ssl->session->psk_identity == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
}
- /* Depending on the key exchange method, compute |pms| and |pms_len|. */
- if (alg_k & SSL_kRSA) {
- RSA *rsa;
- size_t enc_pms_len;
+ /* Write out psk_identity. */
+ CBB child;
+ if (!CBB_add_u16_length_prefixed(&cbb, &child) ||
+ !CBB_add_bytes(&child, (const uint8_t *)identity,
+ OPENSSL_strnlen(identity, sizeof(identity))) ||
+ !CBB_flush(&cbb)) {
+ goto err;
+ }
+ }
- pms_len = SSL_MAX_MASTER_KEY_LENGTH;
- pms = OPENSSL_malloc(pms_len);
- if (pms == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- goto err;
- }
+ /* Depending on the key exchange method, compute |pms| and |pms_len|. */
+ if (alg_k & SSL_kRSA) {
+ pms_len = SSL_MAX_MASTER_KEY_LENGTH;
+ pms = OPENSSL_malloc(pms_len);
+ if (pms == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
- pkey = X509_get_pubkey(s->session->peer);
- if (pkey == NULL ||
- pkey->type != EVP_PKEY_RSA ||
- pkey->pkey.rsa == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- EVP_PKEY_free(pkey);
- goto err;
- }
+ EVP_PKEY *pkey = X509_get_pubkey(ssl->session->peer);
+ if (pkey == NULL) {
+ goto err;
+ }
- s->session->key_exchange_info = EVP_PKEY_bits(pkey);
- rsa = pkey->pkey.rsa;
+ RSA *rsa = EVP_PKEY_get0_RSA(pkey);
+ if (rsa == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
EVP_PKEY_free(pkey);
+ goto err;
+ }
- pms[0] = s->client_version >> 8;
- pms[1] = s->client_version & 0xff;
- if (!RAND_bytes(&pms[2], SSL_MAX_MASTER_KEY_LENGTH - 2)) {
- goto err;
- }
-
- s->session->master_key_length = SSL_MAX_MASTER_KEY_LENGTH;
-
- q = p;
- /* In TLS and beyond, reserve space for the length prefix. */
- if (s->version > SSL3_VERSION) {
- p += 2;
- n += 2;
- }
- if (!RSA_encrypt(rsa, &enc_pms_len, p, RSA_size(rsa), pms, pms_len,
- RSA_PKCS1_PADDING)) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_RSA_ENCRYPT);
- goto err;
- }
- n += enc_pms_len;
-
- /* Log the premaster secret, if logging is enabled. */
- if (!ssl_ctx_log_rsa_client_key_exchange(s->ctx, p, enc_pms_len, pms,
- pms_len)) {
- goto err;
- }
-
- /* Fill in the length prefix. */
- if (s->version > SSL3_VERSION) {
- s2n(enc_pms_len, q);
- }
- } else if (alg_k & SSL_kDHE) {
- DH *dh_srvr, *dh_clnt;
- int dh_len;
- size_t pub_len;
-
- if (s->s3->tmp.peer_dh_tmp == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- dh_srvr = s->s3->tmp.peer_dh_tmp;
-
- /* generate a new random key */
- dh_clnt = DHparams_dup(dh_srvr);
- if (dh_clnt == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
- goto err;
- }
- if (!DH_generate_key(dh_clnt)) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
- DH_free(dh_clnt);
- goto err;
- }
-
- pms_len = DH_size(dh_clnt);
- pms = OPENSSL_malloc(pms_len);
- if (pms == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- DH_free(dh_clnt);
- goto err;
- }
-
- dh_len = DH_compute_key(pms, dh_srvr->pub_key, dh_clnt);
- if (dh_len <= 0) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
- DH_free(dh_clnt);
- goto err;
- }
- pms_len = dh_len;
-
- /* send off the data */
- pub_len = BN_num_bytes(dh_clnt->pub_key);
- s2n(pub_len, p);
- BN_bn2bin(dh_clnt->pub_key, p);
- n += 2 + pub_len;
-
- DH_free(dh_clnt);
- } else if (alg_k & SSL_kECDHE) {
- const EC_GROUP *srvr_group = NULL;
- EC_KEY *tkey;
- int ecdh_len;
-
- if (s->s3->tmp.peer_ecdh_tmp == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
- tkey = s->s3->tmp.peer_ecdh_tmp;
-
- srvr_group = EC_KEY_get0_group(tkey);
- srvr_ecpoint = EC_KEY_get0_public_key(tkey);
- if (srvr_group == NULL || srvr_ecpoint == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
- clnt_ecdh = EC_KEY_new();
- if (clnt_ecdh == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- if (!EC_KEY_set_group(clnt_ecdh, srvr_group)) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_EC_LIB);
- goto err;
- }
-
- /* Generate a new ECDH key pair */
- if (!EC_KEY_generate_key(clnt_ecdh)) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB);
- goto err;
- }
-
- unsigned field_size = EC_GROUP_get_degree(srvr_group);
- if (field_size == 0) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB);
- goto err;
- }
+ ssl->session->key_exchange_info = EVP_PKEY_bits(pkey);
+ EVP_PKEY_free(pkey);
- pms_len = (field_size + 7) / 8;
- pms = OPENSSL_malloc(pms_len);
- if (pms == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- goto err;
- }
+ pms[0] = ssl->client_version >> 8;
+ pms[1] = ssl->client_version & 0xff;
+ if (!RAND_bytes(&pms[2], SSL_MAX_MASTER_KEY_LENGTH - 2)) {
+ goto err;
+ }
- ecdh_len = ECDH_compute_key(pms, pms_len, srvr_ecpoint, clnt_ecdh, NULL);
- if (ecdh_len <= 0) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB);
- goto err;
- }
- pms_len = ecdh_len;
-
- /* First check the size of encoding and allocate memory accordingly. */
- encoded_pt_len =
- EC_POINT_point2oct(srvr_group, EC_KEY_get0_public_key(clnt_ecdh),
- POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL);
-
- encodedPoint =
- (uint8_t *)OPENSSL_malloc(encoded_pt_len * sizeof(uint8_t));
- bn_ctx = BN_CTX_new();
- if (encodedPoint == NULL || bn_ctx == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ CBB child, *enc_pms = &cbb;
+ size_t enc_pms_len;
+ /* In TLS, there is a length prefix. */
+ if (ssl->version > SSL3_VERSION) {
+ if (!CBB_add_u16_length_prefixed(&cbb, &child)) {
goto err;
}
+ enc_pms = &child;
+ }
- /* Encode the public key */
- encoded_pt_len = EC_POINT_point2oct(
- srvr_group, EC_KEY_get0_public_key(clnt_ecdh),
- POINT_CONVERSION_UNCOMPRESSED, encodedPoint, encoded_pt_len, bn_ctx);
-
- *p = encoded_pt_len; /* length of encoded point */
- /* Encoded point will be copied here */
- p += 1;
- n += 1;
- /* copy the point */
- memcpy(p, encodedPoint, encoded_pt_len);
- /* increment n to account for length field */
- n += encoded_pt_len;
-
- /* Free allocated memory */
- BN_CTX_free(bn_ctx);
- bn_ctx = NULL;
- OPENSSL_free(encodedPoint);
- encodedPoint = NULL;
- EC_KEY_free(clnt_ecdh);
- clnt_ecdh = NULL;
- EVP_PKEY_free(srvr_pub_pkey);
- srvr_pub_pkey = NULL;
- } else if (alg_k & SSL_kPSK) {
- /* For plain PSK, other_secret is a block of 0s with the same length as
- * the pre-shared key. */
- pms_len = psk_len;
- pms = OPENSSL_malloc(pms_len);
- if (pms == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- memset(pms, 0, pms_len);
+ uint8_t *ptr;
+ if (!CBB_reserve(enc_pms, &ptr, RSA_size(rsa)) ||
+ !RSA_encrypt(rsa, &enc_pms_len, ptr, RSA_size(rsa), pms, pms_len,
+ RSA_PKCS1_PADDING) ||
+ /* Log the premaster secret, if logging is enabled. */
+ !ssl_log_rsa_client_key_exchange(ssl, ptr, enc_pms_len, pms, pms_len) ||
+ !CBB_did_write(enc_pms, enc_pms_len) ||
+ !CBB_flush(&cbb)) {
+ goto err;
+ }
+ } else if (alg_k & (SSL_kECDHE|SSL_kDHE)) {
+ /* Generate a keypair and serialize the public half. ECDHE uses a u8 length
+ * prefix while DHE uses u16. */
+ CBB child;
+ int child_ok;
+ if (alg_k & SSL_kECDHE) {
+ child_ok = CBB_add_u8_length_prefixed(&cbb, &child);
} else {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ child_ok = CBB_add_u16_length_prefixed(&cbb, &child);
+ }
+
+ if (!child_ok ||
+ !SSL_ECDH_CTX_generate_keypair(&ssl->s3->tmp.ecdh_ctx, &child) ||
+ !CBB_flush(&cbb)) {
goto err;
}
- /* For a PSK cipher suite, other_secret is combined with the pre-shared
- * key. */
- if (alg_a & SSL_aPSK) {
- CBB cbb, child;
- uint8_t *new_pms;
- size_t new_pms_len;
-
- CBB_zero(&cbb);
- if (!CBB_init(&cbb, 2 + psk_len + 2 + pms_len) ||
- !CBB_add_u16_length_prefixed(&cbb, &child) ||
- !CBB_add_bytes(&child, pms, pms_len) ||
- !CBB_add_u16_length_prefixed(&cbb, &child) ||
- !CBB_add_bytes(&child, psk, psk_len) ||
- !CBB_finish(&cbb, &new_pms, &new_pms_len)) {
- CBB_cleanup(&cbb);
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- OPENSSL_cleanse(pms, pms_len);
- OPENSSL_free(pms);
- pms = new_pms;
- pms_len = new_pms_len;
+ /* Compute the premaster. */
+ uint8_t alert;
+ if (!SSL_ECDH_CTX_compute_secret(&ssl->s3->tmp.ecdh_ctx, &pms, &pms_len,
+ &alert, ssl->s3->tmp.peer_key,
+ ssl->s3->tmp.peer_key_len)) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ goto err;
}
- /* The message must be added to the finished hash before calculating the
- * master secret. */
- if (!ssl_set_handshake_header(s, SSL3_MT_CLIENT_KEY_EXCHANGE, n)) {
+ /* The key exchange state may now be discarded. */
+ SSL_ECDH_CTX_cleanup(&ssl->s3->tmp.ecdh_ctx);
+ OPENSSL_free(ssl->s3->tmp.peer_key);
+ ssl->s3->tmp.peer_key = NULL;
+ } else if (alg_k & SSL_kPSK) {
+ /* For plain PSK, other_secret is a block of 0s with the same length as
+ * the pre-shared key. */
+ pms_len = psk_len;
+ pms = OPENSSL_malloc(pms_len);
+ if (pms == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
- s->state = SSL3_ST_CW_KEY_EXCH_B;
+ memset(pms, 0, pms_len);
+ } else {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
- s->session->master_key_length = s->enc_method->generate_master_secret(
- s, s->session->master_key, pms, pms_len);
- if (s->session->master_key_length == 0) {
+ /* For a PSK cipher suite, other_secret is combined with the pre-shared
+ * key. */
+ if (alg_a & SSL_aPSK) {
+ CBB pms_cbb, child;
+ uint8_t *new_pms;
+ size_t new_pms_len;
+
+ CBB_zero(&pms_cbb);
+ if (!CBB_init(&pms_cbb, 2 + psk_len + 2 + pms_len) ||
+ !CBB_add_u16_length_prefixed(&pms_cbb, &child) ||
+ !CBB_add_bytes(&child, pms, pms_len) ||
+ !CBB_add_u16_length_prefixed(&pms_cbb, &child) ||
+ !CBB_add_bytes(&child, psk, psk_len) ||
+ !CBB_finish(&pms_cbb, &new_pms, &new_pms_len)) {
+ CBB_cleanup(&pms_cbb);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
- s->session->extended_master_secret = s->s3->tmp.extended_master_secret;
OPENSSL_cleanse(pms, pms_len);
OPENSSL_free(pms);
+ pms = new_pms;
+ pms_len = new_pms_len;
}
+ /* The message must be added to the finished hash before calculating the
+ * master secret. */
+ size_t length;
+ if (!CBB_finish(&cbb, NULL, &length) ||
+ !ssl_set_handshake_header(ssl, SSL3_MT_CLIENT_KEY_EXCHANGE, length)) {
+ goto err;
+ }
+ ssl->state = SSL3_ST_CW_KEY_EXCH_B;
+
+ ssl->session->master_key_length = ssl->enc_method->generate_master_secret(
+ ssl, ssl->session->master_key, pms, pms_len);
+ if (ssl->session->master_key_length == 0) {
+ goto err;
+ }
+ ssl->session->extended_master_secret = ssl->s3->tmp.extended_master_secret;
+ OPENSSL_cleanse(pms, pms_len);
+ OPENSSL_free(pms);
+
/* SSL3_ST_CW_KEY_EXCH_B */
- return s->method->do_write(s);
+ return ssl_do_write(ssl);
err:
- BN_CTX_free(bn_ctx);
- OPENSSL_free(encodedPoint);
- EC_KEY_free(clnt_ecdh);
- EVP_PKEY_free(srvr_pub_pkey);
- if (pms) {
+ if (pms != NULL) {
OPENSSL_cleanse(pms, pms_len);
OPENSSL_free(pms);
}
return -1;
}
-int ssl3_send_cert_verify(SSL *s) {
- if (s->state == SSL3_ST_CW_CERT_VRFY_A ||
- s->state == SSL3_ST_CW_CERT_VRFY_B) {
- enum ssl_private_key_result_t sign_result;
- uint8_t *p = ssl_handshake_start(s);
- size_t signature_length = 0;
- unsigned long n = 0;
- assert(ssl_has_private_key(s));
-
- if (s->state == SSL3_ST_CW_CERT_VRFY_A) {
- uint8_t *buf = (uint8_t *)s->init_buf->data;
- const EVP_MD *md = NULL;
- uint8_t digest[EVP_MAX_MD_SIZE];
- size_t digest_length;
-
- /* Write out the digest type if need be. */
- if (SSL_USE_SIGALGS(s)) {
- md = tls1_choose_signing_digest(s);
- if (!tls12_get_sigandhash(s, p, md)) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return -1;
- }
- p += 2;
- n += 2;
- }
+int ssl3_send_cert_verify(SSL *ssl) {
+ if (ssl->state == SSL3_ST_CW_CERT_VRFY_C) {
+ return ssl_do_write(ssl);
+ }
- /* Compute the digest. */
- const int pkey_type = ssl_private_key_type(s);
- if (!ssl3_cert_verify_hash(s, digest, &digest_length, &md, pkey_type)) {
- return -1;
- }
+ CBB cbb, child;
+ if (!CBB_init_fixed(&cbb, ssl_handshake_start(ssl),
+ ssl->init_buf->max - SSL_HM_HEADER_LENGTH(ssl))) {
+ goto err;
+ }
- /* The handshake buffer is no longer necessary. */
- ssl3_free_handshake_buffer(s);
+ assert(ssl_has_private_key(ssl));
- /* Sign the digest. */
- signature_length = ssl_private_key_max_signature_len(s);
- if (p + 2 + signature_length > buf + SSL3_RT_MAX_PLAIN_LENGTH) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
- return -1;
+ const size_t max_sig_len = ssl_private_key_max_signature_len(ssl);
+ size_t sig_len;
+ enum ssl_private_key_result_t sign_result;
+ if (ssl->state == SSL3_ST_CW_CERT_VRFY_A) {
+ /* Select and write out the digest type in TLS 1.2. */
+ const EVP_MD *md = NULL;
+ if (SSL_USE_SIGALGS(ssl)) {
+ md = tls1_choose_signing_digest(ssl);
+ if (!tls12_add_sigandhash(ssl, &cbb, md)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ goto err;
}
+ }
- s->rwstate = SSL_PRIVATE_KEY_OPERATION;
- sign_result = ssl_private_key_sign(s, &p[2], &signature_length,
- signature_length, md, digest,
- digest_length);
- } else {
- if (SSL_USE_SIGALGS(s)) {
- /* The digest has already been selected and written. */
- p += 2;
- n += 2;
- }
- signature_length = ssl_private_key_max_signature_len(s);
- s->rwstate = SSL_PRIVATE_KEY_OPERATION;
- sign_result = ssl_private_key_sign_complete(s, &p[2], &signature_length,
- signature_length);
+ /* Compute the digest. In TLS 1.1 and below, the digest type is also
+ * selected here. */
+ uint8_t digest[EVP_MAX_MD_SIZE];
+ size_t digest_len;
+ if (!ssl3_cert_verify_hash(ssl, digest, &digest_len, &md,
+ ssl_private_key_type(ssl))) {
+ goto err;
}
- if (sign_result == ssl_private_key_retry) {
- s->state = SSL3_ST_CW_CERT_VRFY_B;
- return -1;
+ /* The handshake buffer is no longer necessary. */
+ ssl3_free_handshake_buffer(ssl);
+
+ /* Sign the digest. */
+ uint8_t *ptr;
+ if (!CBB_add_u16_length_prefixed(&cbb, &child) ||
+ !CBB_reserve(&child, &ptr, max_sig_len)) {
+ goto err;
}
- s->rwstate = SSL_NOTHING;
- if (sign_result != ssl_private_key_success) {
- return -1;
+ sign_result = ssl_private_key_sign(ssl, ptr, &sig_len, max_sig_len, md,
+ digest, digest_len);
+ } else {
+ assert(ssl->state == SSL3_ST_CW_CERT_VRFY_B);
+
+ /* Skip over the already written signature algorithm and retry the
+ * signature. */
+ uint8_t *ptr;
+ if ((SSL_USE_SIGALGS(ssl) && !CBB_did_write(&cbb, 2)) ||
+ !CBB_add_u16_length_prefixed(&cbb, &child) ||
+ !CBB_reserve(&child, &ptr, max_sig_len)) {
+ goto err;
}
+ sign_result =
+ ssl_private_key_sign_complete(ssl, ptr, &sig_len, max_sig_len);
+ }
- s2n(signature_length, p);
- n += signature_length + 2;
- if (!ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_VERIFY, n)) {
- return -1;
- }
- s->state = SSL3_ST_CW_CERT_VRFY_C;
+ switch (sign_result) {
+ case ssl_private_key_success:
+ ssl->rwstate = SSL_NOTHING;
+ break;
+ case ssl_private_key_failure:
+ ssl->rwstate = SSL_NOTHING;
+ goto err;
+ case ssl_private_key_retry:
+ ssl->rwstate = SSL_PRIVATE_KEY_OPERATION;
+ ssl->state = SSL3_ST_CW_CERT_VRFY_B;
+ goto err;
}
- return ssl_do_write(s);
+ size_t length;
+ if (!CBB_did_write(&child, sig_len) ||
+ !CBB_finish(&cbb, NULL, &length) ||
+ !ssl_set_handshake_header(ssl, SSL3_MT_CERTIFICATE_VERIFY, length)) {
+ goto err;
+ }
+
+ ssl->state = SSL3_ST_CW_CERT_VRFY_C;
+ return ssl_do_write(ssl);
+
+err:
+ CBB_cleanup(&cbb);
+ return -1;
}
/* ssl3_has_client_certificate returns true if a client certificate is
@@ -1998,47 +1871,47 @@ static int ssl3_has_client_certificate(SSL *ssl) {
return ssl->cert && ssl->cert->x509 && ssl_has_private_key(ssl);
}
-int ssl3_send_client_certificate(SSL *s) {
+int ssl3_send_client_certificate(SSL *ssl) {
X509 *x509 = NULL;
EVP_PKEY *pkey = NULL;
int i;
- if (s->state == SSL3_ST_CW_CERT_A) {
+ if (ssl->state == SSL3_ST_CW_CERT_A) {
/* Let cert callback update client certificates if required */
- if (s->cert->cert_cb) {
- i = s->cert->cert_cb(s, s->cert->cert_cb_arg);
+ if (ssl->cert->cert_cb) {
+ i = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
if (i < 0) {
- s->rwstate = SSL_X509_LOOKUP;
+ ssl->rwstate = SSL_X509_LOOKUP;
return -1;
}
if (i == 0) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return 0;
}
- s->rwstate = SSL_NOTHING;
+ ssl->rwstate = SSL_NOTHING;
}
- if (ssl3_has_client_certificate(s)) {
- s->state = SSL3_ST_CW_CERT_C;
+ if (ssl3_has_client_certificate(ssl)) {
+ ssl->state = SSL3_ST_CW_CERT_C;
} else {
- s->state = SSL3_ST_CW_CERT_B;
+ ssl->state = SSL3_ST_CW_CERT_B;
}
}
/* We need to get a client cert */
- if (s->state == SSL3_ST_CW_CERT_B) {
+ if (ssl->state == SSL3_ST_CW_CERT_B) {
/* If we get an error, we need to:
* ssl->rwstate=SSL_X509_LOOKUP; return(-1);
* We then get retried later */
- i = ssl_do_client_cert_cb(s, &x509, &pkey);
+ i = ssl_do_client_cert_cb(ssl, &x509, &pkey);
if (i < 0) {
- s->rwstate = SSL_X509_LOOKUP;
+ ssl->rwstate = SSL_X509_LOOKUP;
return -1;
}
- s->rwstate = SSL_NOTHING;
+ ssl->rwstate = SSL_NOTHING;
if (i == 1 && pkey != NULL && x509 != NULL) {
- s->state = SSL3_ST_CW_CERT_B;
- if (!SSL_use_certificate(s, x509) || !SSL_use_PrivateKey(s, pkey)) {
+ ssl->state = SSL3_ST_CW_CERT_B;
+ if (!SSL_use_certificate(ssl, x509) || !SSL_use_PrivateKey(ssl, pkey)) {
i = 0;
}
} else if (i == 1) {
@@ -2048,42 +1921,42 @@ int ssl3_send_client_certificate(SSL *s) {
X509_free(x509);
EVP_PKEY_free(pkey);
- if (i && !ssl3_has_client_certificate(s)) {
+ if (i && !ssl3_has_client_certificate(ssl)) {
i = 0;
}
if (i == 0) {
- if (s->version == SSL3_VERSION) {
- s->s3->tmp.cert_req = 0;
- ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_CERTIFICATE);
+ if (ssl->version == SSL3_VERSION) {
+ ssl->s3->tmp.cert_req = 0;
+ ssl3_send_alert(ssl, SSL3_AL_WARNING, SSL_AD_NO_CERTIFICATE);
return 1;
} else {
- s->s3->tmp.cert_req = 2;
+ ssl->s3->tmp.cert_req = 2;
/* There is no client certificate, so the handshake buffer may be
* released. */
- ssl3_free_handshake_buffer(s);
+ ssl3_free_handshake_buffer(ssl);
}
}
/* Ok, we have a cert */
- s->state = SSL3_ST_CW_CERT_C;
+ ssl->state = SSL3_ST_CW_CERT_C;
}
- if (s->state == SSL3_ST_CW_CERT_C) {
- if (s->s3->tmp.cert_req == 2) {
+ if (ssl->state == SSL3_ST_CW_CERT_C) {
+ if (ssl->s3->tmp.cert_req == 2) {
/* Send an empty Certificate message. */
- uint8_t *p = ssl_handshake_start(s);
+ uint8_t *p = ssl_handshake_start(ssl);
l2n3(0, p);
- if (!ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE, 3)) {
+ if (!ssl_set_handshake_header(ssl, SSL3_MT_CERTIFICATE, 3)) {
return -1;
}
- } else if (!ssl3_output_cert_chain(s)) {
+ } else if (!ssl3_output_cert_chain(ssl)) {
return -1;
}
- s->state = SSL3_ST_CW_CERT_D;
+ ssl->state = SSL3_ST_CW_CERT_D;
}
/* SSL3_ST_CW_CERT_D */
- return ssl_do_write(s);
+ return ssl_do_write(ssl);
}
int ssl3_send_next_proto(SSL *ssl) {
@@ -2117,12 +1990,6 @@ int ssl3_send_next_proto(SSL *ssl) {
return ssl_do_write(ssl);
}
-static int write_32_byte_big_endian(CBB *out, const BIGNUM *in) {
- uint8_t *ptr;
- return CBB_add_space(out, &ptr, 32) &&
- BN_bn2bin_padded(ptr, 32, in);
-}
-
int ssl3_send_channel_id(SSL *ssl) {
if (ssl->state == SSL3_ST_CW_CHANNEL_ID_B) {
return ssl_do_write(ssl);
@@ -2148,13 +2015,13 @@ int ssl3_send_channel_id(SSL *ssl) {
}
ssl->rwstate = SSL_NOTHING;
- if (EVP_PKEY_id(ssl->tlsext_channel_id_private) != EVP_PKEY_EC) {
+ EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(ssl->tlsext_channel_id_private);
+ if (ec_key == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return -1;
}
int ret = -1;
- EC_KEY *ec_key = ssl->tlsext_channel_id_private->pkey.ec;
BIGNUM *x = BN_new();
BIGNUM *y = BN_new();
ECDSA_SIG *sig = NULL;
@@ -2183,10 +2050,10 @@ int ssl3_send_channel_id(SSL *ssl) {
ssl->init_buf->max - SSL_HM_HEADER_LENGTH(ssl)) ||
!CBB_add_u16(&cbb, TLSEXT_TYPE_channel_id) ||
!CBB_add_u16_length_prefixed(&cbb, &child) ||
- !write_32_byte_big_endian(&child, x) ||
- !write_32_byte_big_endian(&child, y) ||
- !write_32_byte_big_endian(&child, sig->r) ||
- !write_32_byte_big_endian(&child, sig->s) ||
+ !BN_bn2cbb_padded(&child, 32, x) ||
+ !BN_bn2cbb_padded(&child, 32, y) ||
+ !BN_bn2cbb_padded(&child, 32, sig->r) ||
+ !BN_bn2cbb_padded(&child, 32, sig->s) ||
!CBB_finish(&cbb, NULL, &length) ||
!ssl_set_handshake_header(ssl, SSL3_MT_ENCRYPTED_EXTENSIONS, length)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
@@ -2211,15 +2078,15 @@ int ssl_do_client_cert_cb(SSL *ssl, X509 **out_x509, EVP_PKEY **out_pkey) {
return ssl->ctx->client_cert_cb(ssl, out_x509, out_pkey);
}
-int ssl3_verify_server_cert(SSL *s) {
- int ret = ssl_verify_cert_chain(s, s->session->cert_chain);
- if (s->verify_mode != SSL_VERIFY_NONE && ret <= 0) {
- int al = ssl_verify_alarm_type(s->verify_result);
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
+int ssl3_verify_server_cert(SSL *ssl) {
+ int ret = ssl_verify_cert_chain(ssl, ssl->session->cert_chain);
+ if (ssl->verify_mode != SSL_VERIFY_NONE && ret <= 0) {
+ int al = ssl_verify_alarm_type(ssl->verify_result);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_VERIFY_FAILED);
} else {
ret = 1;
- ERR_clear_error(); /* but we keep s->verify_result */
+ ERR_clear_error(); /* but we keep ssl->verify_result */
}
return ret;
diff --git a/src/ssl/s3_enc.c b/src/ssl/s3_enc.c
index aa0d717..89d861a 100644
--- a/src/ssl/s3_enc.c
+++ b/src/ssl/s3_enc.c
@@ -162,10 +162,10 @@ static const uint8_t ssl3_pad_2[48] = {
0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
};
-static int ssl3_handshake_mac(SSL *s, int md_nid, const char *sender, int len,
+static int ssl3_handshake_mac(SSL *ssl, int md_nid, const char *sender, int len,
uint8_t *p);
-int ssl3_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret,
+int ssl3_prf(SSL *ssl, uint8_t *out, size_t out_len, const uint8_t *secret,
size_t secret_len, const char *label, size_t label_len,
const uint8_t *seed1, size_t seed1_len,
const uint8_t *seed2, size_t seed2_len) {
@@ -228,13 +228,13 @@ int ssl3_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret,
return 1;
}
-void ssl3_cleanup_key_block(SSL *s) {
- if (s->s3->tmp.key_block != NULL) {
- OPENSSL_cleanse(s->s3->tmp.key_block, s->s3->tmp.key_block_length);
- OPENSSL_free(s->s3->tmp.key_block);
- s->s3->tmp.key_block = NULL;
+void ssl3_cleanup_key_block(SSL *ssl) {
+ if (ssl->s3->tmp.key_block != NULL) {
+ OPENSSL_cleanse(ssl->s3->tmp.key_block, ssl->s3->tmp.key_block_length);
+ OPENSSL_free(ssl->s3->tmp.key_block);
+ ssl->s3->tmp.key_block = NULL;
}
- s->s3->tmp.key_block_length = 0;
+ ssl->s3->tmp.key_block_length = 0;
}
int ssl3_init_handshake_buffer(SSL *ssl) {
@@ -309,20 +309,20 @@ int ssl3_update_handshake_hash(SSL *ssl, const uint8_t *in, size_t in_len) {
return 1;
}
-int ssl3_cert_verify_mac(SSL *s, int md_nid, uint8_t *p) {
- return ssl3_handshake_mac(s, md_nid, NULL, 0, p);
+int ssl3_cert_verify_mac(SSL *ssl, int md_nid, uint8_t *p) {
+ return ssl3_handshake_mac(ssl, md_nid, NULL, 0, p);
}
-int ssl3_final_finish_mac(SSL *s, const char *sender, int len, uint8_t *p) {
+int ssl3_final_finish_mac(SSL *ssl, const char *sender, int len, uint8_t *p) {
int ret, sha1len;
- ret = ssl3_handshake_mac(s, NID_md5, sender, len, p);
+ ret = ssl3_handshake_mac(ssl, NID_md5, sender, len, p);
if (ret == 0) {
return 0;
}
p += ret;
- sha1len = ssl3_handshake_mac(s, NID_sha1, sender, len, p);
+ sha1len = ssl3_handshake_mac(ssl, NID_sha1, sender, len, p);
if (sha1len == 0) {
return 0;
}
@@ -331,7 +331,7 @@ int ssl3_final_finish_mac(SSL *s, const char *sender, int len, uint8_t *p) {
return ret;
}
-static int ssl3_handshake_mac(SSL *s, int md_nid, const char *sender, int len,
+static int ssl3_handshake_mac(SSL *ssl, int md_nid, const char *sender, int len,
uint8_t *p) {
unsigned int ret;
size_t npad, n;
@@ -341,9 +341,9 @@ static int ssl3_handshake_mac(SSL *s, int md_nid, const char *sender, int len,
const EVP_MD_CTX *ctx_template;
if (md_nid == NID_md5) {
- ctx_template = &s->s3->handshake_md5;
- } else if (md_nid == EVP_MD_CTX_type(&s->s3->handshake_hash)) {
- ctx_template = &s->s3->handshake_hash;
+ ctx_template = &ssl->s3->handshake_md5;
+ } else if (md_nid == EVP_MD_CTX_type(&ssl->s3->handshake_hash)) {
+ ctx_template = &ssl->s3->handshake_hash;
} else {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_REQUIRED_DIGEST);
return 0;
@@ -362,7 +362,8 @@ static int ssl3_handshake_mac(SSL *s, int md_nid, const char *sender, int len,
if (sender != NULL) {
EVP_DigestUpdate(&ctx, sender, len);
}
- EVP_DigestUpdate(&ctx, s->session->master_key, s->session->master_key_length);
+ EVP_DigestUpdate(&ctx, ssl->session->master_key,
+ ssl->session->master_key_length);
EVP_DigestUpdate(&ctx, ssl3_pad_1, npad);
EVP_DigestFinal_ex(&ctx, md_buf, &i);
@@ -371,7 +372,8 @@ static int ssl3_handshake_mac(SSL *s, int md_nid, const char *sender, int len,
OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP);
return 0;
}
- EVP_DigestUpdate(&ctx, s->session->master_key, s->session->master_key_length);
+ EVP_DigestUpdate(&ctx, ssl->session->master_key,
+ ssl->session->master_key_length);
EVP_DigestUpdate(&ctx, ssl3_pad_2, npad);
EVP_DigestUpdate(&ctx, md_buf, i);
EVP_DigestFinal_ex(&ctx, p, &ret);
diff --git a/src/ssl/s3_lib.c b/src/ssl/s3_lib.c
index 7bf223d..64f9f8c 100644
--- a/src/ssl/s3_lib.c
+++ b/src/ssl/s3_lib.c
@@ -181,21 +181,23 @@ int ssl3_supports_cipher(const SSL_CIPHER *cipher) {
return 1;
}
-int ssl3_set_handshake_header(SSL *s, int htype, unsigned long len) {
- uint8_t *p = (uint8_t *)s->init_buf->data;
+int ssl3_set_handshake_header(SSL *ssl, int htype, unsigned long len) {
+ uint8_t *p = (uint8_t *)ssl->init_buf->data;
*(p++) = htype;
l2n3(len, p);
- s->init_num = (int)len + SSL3_HM_HEADER_LENGTH;
- s->init_off = 0;
+ ssl->init_num = (int)len + SSL3_HM_HEADER_LENGTH;
+ ssl->init_off = 0;
/* Add the message to the handshake hash. */
- return ssl3_update_handshake_hash(s, (uint8_t *)s->init_buf->data,
- s->init_num);
+ return ssl3_update_handshake_hash(ssl, (uint8_t *)ssl->init_buf->data,
+ ssl->init_num);
}
-int ssl3_handshake_write(SSL *s) { return ssl3_do_write(s, SSL3_RT_HANDSHAKE); }
+int ssl3_handshake_write(SSL *ssl) {
+ return ssl3_do_write(ssl, SSL3_RT_HANDSHAKE);
+}
-int ssl3_new(SSL *s) {
+int ssl3_new(SSL *ssl) {
SSL3_STATE *s3;
s3 = OPENSSL_malloc(sizeof *s3);
@@ -207,43 +209,41 @@ int ssl3_new(SSL *s) {
EVP_MD_CTX_init(&s3->handshake_hash);
EVP_MD_CTX_init(&s3->handshake_md5);
- s->s3 = s3;
+ ssl->s3 = s3;
/* Set the version to the highest supported version for TLS. This controls the
- * initial state of |s->enc_method| and what the API reports as the version
+ * initial state of |ssl->enc_method| and what the API reports as the version
* prior to negotiation.
*
* TODO(davidben): This is fragile and confusing. */
- s->version = TLS1_2_VERSION;
+ ssl->version = TLS1_2_VERSION;
return 1;
err:
return 0;
}
-void ssl3_free(SSL *s) {
- if (s == NULL || s->s3 == NULL) {
+void ssl3_free(SSL *ssl) {
+ if (ssl == NULL || ssl->s3 == NULL) {
return;
}
- ssl3_cleanup_key_block(s);
- ssl_read_buffer_clear(s);
- ssl_write_buffer_clear(s);
- DH_free(s->s3->tmp.dh);
- EC_KEY_free(s->s3->tmp.ecdh);
+ ssl3_cleanup_key_block(ssl);
+ ssl_read_buffer_clear(ssl);
+ ssl_write_buffer_clear(ssl);
+ SSL_ECDH_CTX_cleanup(&ssl->s3->tmp.ecdh_ctx);
+ OPENSSL_free(ssl->s3->tmp.peer_key);
- sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
- OPENSSL_free(s->s3->tmp.certificate_types);
- OPENSSL_free(s->s3->tmp.peer_ellipticcurvelist);
- OPENSSL_free(s->s3->tmp.peer_psk_identity_hint);
- DH_free(s->s3->tmp.peer_dh_tmp);
- EC_KEY_free(s->s3->tmp.peer_ecdh_tmp);
- ssl3_free_handshake_buffer(s);
- ssl3_free_handshake_hash(s);
- OPENSSL_free(s->s3->alpn_selected);
+ sk_X509_NAME_pop_free(ssl->s3->tmp.ca_names, X509_NAME_free);
+ OPENSSL_free(ssl->s3->tmp.certificate_types);
+ OPENSSL_free(ssl->s3->tmp.peer_ellipticcurvelist);
+ OPENSSL_free(ssl->s3->tmp.peer_psk_identity_hint);
+ ssl3_free_handshake_buffer(ssl);
+ ssl3_free_handshake_hash(ssl);
+ OPENSSL_free(ssl->s3->alpn_selected);
- OPENSSL_cleanse(s->s3, sizeof *s->s3);
- OPENSSL_free(s->s3);
- s->s3 = NULL;
+ OPENSSL_cleanse(ssl->s3, sizeof *ssl->s3);
+ OPENSSL_free(ssl->s3);
+ ssl->s3 = NULL;
}
int SSL_session_reused(const SSL *ssl) {
@@ -299,8 +299,8 @@ int SSL_CTX_set_tmp_ecdh(SSL_CTX *ctx, const EC_KEY *ec_key) {
OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
- ctx->cert->ecdh_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key));
- return 1;
+ int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key));
+ return SSL_CTX_set1_curves(ctx, &nid, 1);
}
int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key) {
@@ -308,8 +308,8 @@ int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key) {
OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
- ssl->cert->ecdh_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key));
- return 1;
+ int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key));
+ return SSL_set1_curves(ssl, &nid, 1);
}
int SSL_CTX_enable_tls_channel_id(SSL_CTX *ctx) {
@@ -335,8 +335,9 @@ int SSL_CTX_set1_tls_channel_id(SSL_CTX *ctx, EVP_PKEY *private_key) {
}
int SSL_set1_tls_channel_id(SSL *ssl, EVP_PKEY *private_key) {
- if (EVP_PKEY_id(private_key) != EVP_PKEY_EC ||
- EC_GROUP_get_curve_name(EC_KEY_get0_group(private_key->pkey.ec)) !=
+ EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(private_key);
+ if (ec_key == NULL ||
+ EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)) !=
NID_X9_62_prime256v1) {
OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_NOT_P256);
return 0;
@@ -446,30 +447,30 @@ int SSL_CTX_set_tlsext_ticket_key_cb(
return 1;
}
-struct ssl_cipher_preference_list_st *ssl_get_cipher_preferences(SSL *s) {
- if (s->cipher_list != NULL) {
- return s->cipher_list;
+struct ssl_cipher_preference_list_st *ssl_get_cipher_preferences(SSL *ssl) {
+ if (ssl->cipher_list != NULL) {
+ return ssl->cipher_list;
}
- if (s->version >= TLS1_1_VERSION && s->ctx != NULL &&
- s->ctx->cipher_list_tls11 != NULL) {
- return s->ctx->cipher_list_tls11;
+ if (ssl->version >= TLS1_1_VERSION && ssl->ctx != NULL &&
+ ssl->ctx->cipher_list_tls11 != NULL) {
+ return ssl->ctx->cipher_list_tls11;
}
- if (s->version >= TLS1_VERSION && s->ctx != NULL &&
- s->ctx->cipher_list_tls10 != NULL) {
- return s->ctx->cipher_list_tls10;
+ if (ssl->version >= TLS1_VERSION && ssl->ctx != NULL &&
+ ssl->ctx->cipher_list_tls10 != NULL) {
+ return ssl->ctx->cipher_list_tls10;
}
- if (s->ctx != NULL && s->ctx->cipher_list != NULL) {
- return s->ctx->cipher_list;
+ if (ssl->ctx != NULL && ssl->ctx->cipher_list != NULL) {
+ return ssl->ctx->cipher_list;
}
return NULL;
}
const SSL_CIPHER *ssl3_choose_cipher(
- SSL *s, STACK_OF(SSL_CIPHER) *clnt,
+ SSL *ssl, STACK_OF(SSL_CIPHER) *clnt,
struct ssl_cipher_preference_list_st *server_pref) {
const SSL_CIPHER *c, *ret = NULL;
STACK_OF(SSL_CIPHER) *srvr = server_pref->ciphers, *prio, *allow;
@@ -486,7 +487,7 @@ const SSL_CIPHER *ssl3_choose_cipher(
* such value exists yet. */
int group_min = -1;
- if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) {
+ if (ssl->options & SSL_OP_CIPHER_SERVER_PREFERENCE) {
prio = srvr;
in_group_flags = server_pref->in_group_flags;
allow = clnt;
@@ -496,7 +497,7 @@ const SSL_CIPHER *ssl3_choose_cipher(
allow = srvr;
}
- ssl_get_compatible_server_ciphers(s, &mask_k, &mask_a);
+ ssl_get_compatible_server_ciphers(ssl, &mask_k, &mask_a);
for (i = 0; i < sk_SSL_CIPHER_num(prio); i++) {
c = sk_SSL_CIPHER_value(prio, i);
@@ -504,7 +505,8 @@ const SSL_CIPHER *ssl3_choose_cipher(
ok = 1;
/* Check the TLS version. */
- if (SSL_CIPHER_get_min_version(c) > ssl3_version_from_wire(s, s->version)) {
+ if (SSL_CIPHER_get_min_version(c) >
+ ssl3_version_from_wire(ssl, ssl->version)) {
ok = 0;
}
@@ -540,7 +542,7 @@ const SSL_CIPHER *ssl3_choose_cipher(
return ret;
}
-int ssl3_get_req_cert_type(SSL *s, uint8_t *p) {
+int ssl3_get_req_cert_type(SSL *ssl, uint8_t *p) {
int ret = 0;
const uint8_t *sig;
size_t i, siglen;
@@ -548,7 +550,7 @@ int ssl3_get_req_cert_type(SSL *s, uint8_t *p) {
int have_ecdsa_sign = 0;
/* get configured sigalgs */
- siglen = tls12_get_psigalgs(s, &sig);
+ siglen = tls12_get_psigalgs(ssl, &sig);
for (i = 0; i < siglen; i += 2, sig += 2) {
switch (sig[1]) {
case TLSEXT_signature_rsa:
@@ -567,7 +569,7 @@ int ssl3_get_req_cert_type(SSL *s, uint8_t *p) {
/* ECDSA certs can be used with RSA cipher suites as well so we don't need to
* check for SSL_kECDH or SSL_kECDHE. */
- if (s->version >= TLS1_VERSION && have_ecdsa_sign) {
+ if (ssl->version >= TLS1_VERSION && have_ecdsa_sign) {
p[ret++] = TLS_CT_ECDSA_SIGN;
}
@@ -576,9 +578,9 @@ int ssl3_get_req_cert_type(SSL *s, uint8_t *p) {
/* If we are using default SHA1+MD5 algorithms switch to new SHA256 PRF and
* handshake macs if required. */
-uint32_t ssl_get_algorithm_prf(SSL *s) {
- uint32_t algorithm_prf = s->s3->tmp.new_cipher->algorithm_prf;
- if (s->enc_method->enc_flags & SSL_ENC_FLAG_SHA256_PRF &&
+uint32_t ssl_get_algorithm_prf(SSL *ssl) {
+ uint32_t algorithm_prf = ssl->s3->tmp.new_cipher->algorithm_prf;
+ if (ssl->enc_method->enc_flags & SSL_ENC_FLAG_SHA256_PRF &&
algorithm_prf == SSL_HANDSHAKE_MAC_DEFAULT) {
return SSL_HANDSHAKE_MAC_SHA256;
}
diff --git a/src/ssl/s3_meth.c b/src/ssl/s3_meth.c
index 01c1101..b60b5f2 100644
--- a/src/ssl/s3_meth.c
+++ b/src/ssl/s3_meth.c
@@ -67,6 +67,7 @@ static const SSL_PROTOCOL_METHOD TLS_protocol_method = {
ssl3_connect,
ssl3_get_message,
ssl3_read_app_data,
+ ssl3_read_change_cipher_spec,
ssl3_read_close_notify,
ssl3_write_app_data,
ssl3_dispatch_alert,
diff --git a/src/ssl/s3_pkt.c b/src/ssl/s3_pkt.c
index 7416d0e..4c1133c 100644
--- a/src/ssl/s3_pkt.c
+++ b/src/ssl/s3_pkt.c
@@ -122,7 +122,7 @@
#include "internal.h"
-static int do_ssl3_write(SSL *s, int type, const uint8_t *buf, unsigned len);
+static int do_ssl3_write(SSL *ssl, int type, const uint8_t *buf, unsigned len);
/* kMaxWarningAlerts is the number of consecutive warning alerts that will be
* processed. */
@@ -158,7 +158,6 @@ again:
SSL3_RECORD *rr = &ssl->s3->rrec;
rr->type = type;
rr->length = (uint16_t)len;
- rr->off = 0;
rr->data = out;
return 1;
@@ -189,18 +188,18 @@ int ssl3_write_app_data(SSL *ssl, const void *buf, int len) {
/* Call this to write data in records of type |type|. It will return <= 0 if
* not all data has been sent or non-blocking IO. */
-int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) {
+int ssl3_write_bytes(SSL *ssl, int type, const void *buf_, int len) {
const uint8_t *buf = buf_;
unsigned int tot, n, nw;
int i;
- s->rwstate = SSL_NOTHING;
- assert(s->s3->wnum <= INT_MAX);
- tot = s->s3->wnum;
- s->s3->wnum = 0;
+ ssl->rwstate = SSL_NOTHING;
+ assert(ssl->s3->wnum <= INT_MAX);
+ tot = ssl->s3->wnum;
+ ssl->s3->wnum = 0;
- if (!s->in_handshake && SSL_in_init(s) && !SSL_in_false_start(s)) {
- i = s->handshake_func(s);
+ if (!ssl->in_handshake && SSL_in_init(ssl) && !SSL_in_false_start(ssl)) {
+ i = ssl->handshake_func(ssl);
if (i < 0) {
return i;
}
@@ -226,21 +225,21 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) {
for (;;) {
/* max contains the maximum number of bytes that we can put into a
* record. */
- unsigned max = s->max_send_fragment;
+ unsigned max = ssl->max_send_fragment;
if (n > max) {
nw = max;
} else {
nw = n;
}
- i = do_ssl3_write(s, type, &buf[tot], nw);
+ i = do_ssl3_write(ssl, type, &buf[tot], nw);
if (i <= 0) {
- s->s3->wnum = tot;
+ ssl->s3->wnum = tot;
return i;
}
if (i == (int)n || (type == SSL3_RT_APPLICATION_DATA &&
- (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))) {
+ (ssl->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))) {
return tot + i;
}
@@ -249,33 +248,33 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) {
}
}
-static int ssl3_write_pending(SSL *s, int type, const uint8_t *buf,
+static int ssl3_write_pending(SSL *ssl, int type, const uint8_t *buf,
unsigned int len) {
- if (s->s3->wpend_tot > (int)len ||
- (s->s3->wpend_buf != buf &&
- !(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)) ||
- s->s3->wpend_type != type) {
+ if (ssl->s3->wpend_tot > (int)len ||
+ (ssl->s3->wpend_buf != buf &&
+ !(ssl->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)) ||
+ ssl->s3->wpend_type != type) {
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_WRITE_RETRY);
return -1;
}
- int ret = ssl_write_buffer_flush(s);
+ int ret = ssl_write_buffer_flush(ssl);
if (ret <= 0) {
return ret;
}
- return s->s3->wpend_ret;
+ return ssl->s3->wpend_ret;
}
/* do_ssl3_write writes an SSL record of the given type. */
-static int do_ssl3_write(SSL *s, int type, const uint8_t *buf, unsigned len) {
+static int do_ssl3_write(SSL *ssl, int type, const uint8_t *buf, unsigned len) {
/* If there is still data from the previous record, flush it. */
- if (ssl_write_buffer_is_pending(s)) {
- return ssl3_write_pending(s, type, buf, len);
+ if (ssl_write_buffer_is_pending(ssl)) {
+ return ssl3_write_pending(ssl, type, buf, len);
}
/* If we have an alert to send, lets send it */
- if (s->s3->alert_dispatch) {
- int ret = s->method->ssl_dispatch_alert(s);
+ if (ssl->s3->alert_dispatch) {
+ int ret = ssl->method->ssl_dispatch_alert(ssl);
if (ret <= 0) {
return ret;
}
@@ -291,47 +290,55 @@ static int do_ssl3_write(SSL *s, int type, const uint8_t *buf, unsigned len) {
return 0;
}
- size_t max_out = len + ssl_max_seal_overhead(s);
+ size_t max_out = len + ssl_max_seal_overhead(ssl);
if (max_out < len) {
OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
return -1;
}
uint8_t *out;
size_t ciphertext_len;
- if (!ssl_write_buffer_init(s, &out, max_out) ||
- !tls_seal_record(s, out, &ciphertext_len, max_out, type, buf, len)) {
+ if (!ssl_write_buffer_init(ssl, &out, max_out) ||
+ !tls_seal_record(ssl, out, &ciphertext_len, max_out, type, buf, len)) {
return -1;
}
- ssl_write_buffer_set_len(s, ciphertext_len);
+ ssl_write_buffer_set_len(ssl, ciphertext_len);
/* memorize arguments so that ssl3_write_pending can detect bad write retries
* later */
- s->s3->wpend_tot = len;
- s->s3->wpend_buf = buf;
- s->s3->wpend_type = type;
- s->s3->wpend_ret = len;
+ ssl->s3->wpend_tot = len;
+ ssl->s3->wpend_buf = buf;
+ ssl->s3->wpend_type = type;
+ ssl->s3->wpend_ret = len;
/* we now just need to write the buffer */
- return ssl3_write_pending(s, type, buf, len);
+ return ssl3_write_pending(ssl, type, buf, len);
}
-/* ssl3_expect_change_cipher_spec informs the record layer that a
- * ChangeCipherSpec record is required at this point. If a Handshake record is
- * received before ChangeCipherSpec, the connection will fail. Moreover, if
- * there are unprocessed handshake bytes, the handshake will also fail and the
- * function returns zero. Otherwise, the function returns one. */
-int ssl3_expect_change_cipher_spec(SSL *s) {
- if (s->s3->handshake_fragment_len > 0 || s->s3->tmp.reuse_message) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_UNPROCESSED_HANDSHAKE_DATA);
- return 0;
+int ssl3_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek) {
+ return ssl3_read_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf, len, peek);
+}
+
+int ssl3_read_change_cipher_spec(SSL *ssl) {
+ uint8_t byte;
+ int ret = ssl3_read_bytes(ssl, SSL3_RT_CHANGE_CIPHER_SPEC, &byte, 1 /* len */,
+ 0 /* no peek */);
+ if (ret <= 0) {
+ return ret;
}
+ assert(ret == 1);
- s->s3->flags |= SSL3_FLAGS_EXPECT_CCS;
- return 1;
-}
+ if (ssl->s3->rrec.length != 0 || byte != SSL3_MT_CCS) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ return -1;
+ }
-int ssl3_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek) {
- return ssl3_read_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf, len, peek);
+ if (ssl->msg_callback != NULL) {
+ ssl->msg_callback(0, ssl->version, SSL3_RT_CHANGE_CIPHER_SPEC, &byte, 1,
+ ssl, ssl->msg_callback_arg);
+ }
+
+ return 1;
}
void ssl3_read_close_notify(SSL *ssl) {
@@ -358,72 +365,36 @@ static int ssl3_can_renegotiate(SSL *ssl) {
* 'type' is one of the following:
*
* - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us)
- * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us)
+ * - SSL3_RT_CHANGE_CIPHER_SPEC (when ssl3_read_change_cipher_spec calls us)
+ * - SSL3_RT_APPLICATION_DATA (when ssl3_read_app_data calls us)
* - 0 (during a shutdown, no data has to be returned)
*
* If we don't have stored data to work from, read a SSL/TLS record first
* (possibly multiple records if we still don't have anything to return).
*
* This function must handle any surprises the peer may have for us, such as
- * Alert records (e.g. close_notify), ChangeCipherSpec records (not really
- * a surprise, but handled as if it were), or renegotiation requests.
- * Also if record payloads contain fragments too small to process, we store
- * them until there is enough for the respective protocol (the record protocol
- * may use arbitrary fragmentation and even interleaving):
- * Change cipher spec protocol
- * just 1 byte needed, no need for keeping anything stored
- * Alert protocol
- * 2 bytes needed (AlertLevel, AlertDescription)
- * Handshake protocol
- * 4 bytes needed (HandshakeType, uint24 length) -- we just have
- * to detect unexpected Client Hello and Hello Request messages
- * here, anything else is handled by higher layers
- * Application data protocol
- * none of our business
- */
-int ssl3_read_bytes(SSL *s, int type, uint8_t *buf, int len, int peek) {
+ * Alert records (e.g. close_notify) or renegotiation requests. */
+int ssl3_read_bytes(SSL *ssl, int type, uint8_t *buf, int len, int peek) {
int al, i, ret;
unsigned int n;
SSL3_RECORD *rr;
void (*cb)(const SSL *ssl, int type, int value) = NULL;
- if ((type && type != SSL3_RT_APPLICATION_DATA && type != SSL3_RT_HANDSHAKE) ||
+ if ((type && type != SSL3_RT_APPLICATION_DATA && type != SSL3_RT_HANDSHAKE &&
+ type != SSL3_RT_CHANGE_CIPHER_SPEC) ||
(peek && type != SSL3_RT_APPLICATION_DATA)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return -1;
}
- if (type == SSL3_RT_HANDSHAKE && s->s3->handshake_fragment_len > 0) {
- /* (partially) satisfy request from storage */
- uint8_t *src = s->s3->handshake_fragment;
- uint8_t *dst = buf;
- unsigned int k;
-
- /* peek == 0 */
- n = 0;
- while (len > 0 && s->s3->handshake_fragment_len > 0) {
- *dst++ = *src++;
- len--;
- s->s3->handshake_fragment_len--;
- n++;
- }
- /* move any remaining fragment bytes: */
- for (k = 0; k < s->s3->handshake_fragment_len; k++) {
- s->s3->handshake_fragment[k] = *src++;
- }
- return n;
- }
-
- /* Now s->s3->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. */
-
/* This may require multiple iterations. False Start will cause
- * |s->handshake_func| to signal success one step early, but the handshake
+ * |ssl->handshake_func| to signal success one step early, but the handshake
* must be completely finished before other modes are accepted.
*
* TODO(davidben): Move this check up to a higher level. */
- while (!s->in_handshake && SSL_in_init(s)) {
+ while (!ssl->in_handshake && SSL_in_init(ssl)) {
assert(type == SSL3_RT_APPLICATION_DATA);
- i = s->handshake_func(s);
+ i = ssl->handshake_func(ssl);
if (i < 0) {
return i;
}
@@ -434,17 +405,17 @@ int ssl3_read_bytes(SSL *s, int type, uint8_t *buf, int len, int peek) {
}
start:
- s->rwstate = SSL_NOTHING;
+ ssl->rwstate = SSL_NOTHING;
- /* s->s3->rrec.type - is the type of record
- * s->s3->rrec.data - data
- * s->s3->rrec.off - offset into 'data' for next read
- * s->s3->rrec.length - number of bytes. */
- rr = &s->s3->rrec;
+ /* ssl->s3->rrec.type - is the type of record
+ * ssl->s3->rrec.data - data
+ * ssl->s3->rrec.off - offset into 'data' for next read
+ * ssl->s3->rrec.length - number of bytes. */
+ rr = &ssl->s3->rrec;
/* get new packet if necessary */
if (rr->length == 0) {
- ret = ssl3_get_record(s);
+ ret = ssl3_get_record(ssl);
if (ret <= 0) {
return ret;
}
@@ -452,39 +423,21 @@ start:
/* we now have a packet which can be read and processed */
- /* |change_cipher_spec is set when we receive a ChangeCipherSpec and reset by
- * ssl3_get_finished. */
- if (s->s3->change_cipher_spec && rr->type != SSL3_RT_HANDSHAKE &&
- rr->type != SSL3_RT_ALERT) {
- al = SSL_AD_UNEXPECTED_MESSAGE;
- OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_BETWEEN_CCS_AND_FINISHED);
- goto f_err;
- }
-
- /* If we are expecting a ChangeCipherSpec, it is illegal to receive a
- * Handshake record. */
- if (rr->type == SSL3_RT_HANDSHAKE && (s->s3->flags & SSL3_FLAGS_EXPECT_CCS)) {
- al = SSL_AD_UNEXPECTED_MESSAGE;
- OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_RECORD_BEFORE_CCS);
- goto f_err;
- }
-
/* If the other end has shut down, throw anything we read away (even in
* 'peek' mode) */
- if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
+ if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN) {
rr->length = 0;
- s->rwstate = SSL_NOTHING;
+ ssl->rwstate = SSL_NOTHING;
return 0;
}
if (type != 0 && type == rr->type) {
- s->s3->warning_alert_count = 0;
+ ssl->s3->warning_alert_count = 0;
- /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */
- /* make sure that we are not getting application data when we are doing a
- * handshake for the first time */
- if (SSL_in_init(s) && type == SSL3_RT_APPLICATION_DATA &&
- s->aead_read_ctx == NULL) {
+ /* Make sure that we are not getting application data when we are doing a
+ * handshake for the first time. */
+ if (SSL_in_init(ssl) && type == SSL3_RT_APPLICATION_DATA &&
+ ssl->aead_read_ctx == NULL) {
/* TODO(davidben): Is this check redundant with the handshake_func
* check? */
al = SSL_AD_UNEXPECTED_MESSAGE;
@@ -507,14 +460,13 @@ start:
n = (unsigned int)len;
}
- memcpy(buf, &(rr->data[rr->off]), n);
+ memcpy(buf, rr->data, n);
if (!peek) {
rr->length -= n;
- rr->off += n;
+ rr->data += n;
if (rr->length == 0) {
- rr->off = 0;
/* The record has been consumed, so we may now clear the buffer. */
- ssl_read_buffer_discard(s);
+ ssl_read_buffer_discard(ssl);
}
}
@@ -523,45 +475,40 @@ start:
/* Process unexpected records. */
- if (rr->type == SSL3_RT_HANDSHAKE) {
+ if (type == SSL3_RT_APPLICATION_DATA && rr->type == SSL3_RT_HANDSHAKE) {
/* If peer renegotiations are disabled, all out-of-order handshake records
* are fatal. Renegotiations as a server are never supported. */
- if (s->server || !ssl3_can_renegotiate(s)) {
+ if (ssl->server || !ssl3_can_renegotiate(ssl)) {
al = SSL_AD_NO_RENEGOTIATION;
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION);
goto f_err;
}
- /* HelloRequests may be fragmented across multiple records. */
- const size_t size = sizeof(s->s3->handshake_fragment);
- const size_t avail = size - s->s3->handshake_fragment_len;
- const size_t todo = (rr->length < avail) ? rr->length : avail;
- memcpy(s->s3->handshake_fragment + s->s3->handshake_fragment_len,
- &rr->data[rr->off], todo);
- rr->off += todo;
- rr->length -= todo;
- s->s3->handshake_fragment_len += todo;
- if (s->s3->handshake_fragment_len < size) {
- goto start; /* fragment was too small */
- }
-
- /* Parse out and consume a HelloRequest. */
- if (s->s3->handshake_fragment[0] != SSL3_MT_HELLO_REQUEST ||
- s->s3->handshake_fragment[1] != 0 ||
- s->s3->handshake_fragment[2] != 0 ||
- s->s3->handshake_fragment[3] != 0) {
- al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HELLO_REQUEST);
- goto f_err;
+ /* This must be a HelloRequest, possibly fragmented over multiple records.
+ * Consume data from the handshake protocol until it is complete. */
+ static const uint8_t kHelloRequest[] = {SSL3_MT_HELLO_REQUEST, 0, 0, 0};
+ while (ssl->s3->hello_request_len < sizeof(kHelloRequest)) {
+ if (rr->length == 0) {
+ /* Get a new record. */
+ goto start;
+ }
+ if (rr->data[0] != kHelloRequest[ssl->s3->hello_request_len]) {
+ al = SSL_AD_DECODE_ERROR;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HELLO_REQUEST);
+ goto f_err;
+ }
+ rr->data++;
+ rr->length--;
+ ssl->s3->hello_request_len++;
}
- s->s3->handshake_fragment_len = 0;
+ ssl->s3->hello_request_len = 0;
- if (s->msg_callback) {
- s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
- s->s3->handshake_fragment, 4, s, s->msg_callback_arg);
+ if (ssl->msg_callback) {
+ ssl->msg_callback(0, ssl->version, SSL3_RT_HANDSHAKE, kHelloRequest,
+ sizeof(kHelloRequest), ssl, ssl->msg_callback_arg);
}
- if (!SSL_is_init_finished(s) || !s->s3->initial_handshake_complete) {
+ if (!SSL_is_init_finished(ssl) || !ssl->s3->initial_handshake_complete) {
/* This cannot happen. If a handshake is in progress, |type| must be
* |SSL3_RT_HANDSHAKE|. */
assert(0);
@@ -569,7 +516,7 @@ start:
goto err;
}
- if (s->renegotiate_mode == ssl_renegotiate_ignore) {
+ if (ssl->renegotiate_mode == ssl_renegotiate_ignore) {
goto start;
}
@@ -577,16 +524,16 @@ start:
* protocol, namely in HTTPS, just before reading the HTTP response. Require
* the record-layer be idle and avoid complexities of sending a handshake
* record while an application_data record is being written. */
- if (ssl_write_buffer_is_pending(s)) {
+ if (ssl_write_buffer_is_pending(ssl)) {
al = SSL_AD_NO_RENEGOTIATION;
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION);
goto f_err;
}
/* Begin a new handshake. */
- s->s3->total_renegotiations++;
- s->state = SSL_ST_CONNECT;
- i = s->handshake_func(s);
+ ssl->s3->total_renegotiations++;
+ ssl->state = SSL_ST_CONNECT;
+ i = ssl->handshake_func(ssl);
if (i < 0) {
return i;
}
@@ -609,29 +556,30 @@ start:
goto f_err;
}
- if (s->msg_callback) {
- s->msg_callback(0, s->version, SSL3_RT_ALERT, &rr->data[rr->off], 2, s,
- s->msg_callback_arg);
+ if (ssl->msg_callback) {
+ ssl->msg_callback(0, ssl->version, SSL3_RT_ALERT, rr->data, 2, ssl,
+ ssl->msg_callback_arg);
}
- const uint8_t alert_level = rr->data[rr->off++];
- const uint8_t alert_descr = rr->data[rr->off++];
+ const uint8_t alert_level = rr->data[0];
+ const uint8_t alert_descr = rr->data[1];
rr->length -= 2;
+ rr->data += 2;
- if (s->info_callback != NULL) {
- cb = s->info_callback;
- } else if (s->ctx->info_callback != NULL) {
- cb = s->ctx->info_callback;
+ if (ssl->info_callback != NULL) {
+ cb = ssl->info_callback;
+ } else if (ssl->ctx->info_callback != NULL) {
+ cb = ssl->ctx->info_callback;
}
if (cb != NULL) {
uint16_t alert = (alert_level << 8) | alert_descr;
- cb(s, SSL_CB_READ_ALERT, alert);
+ cb(ssl, SSL_CB_READ_ALERT, alert);
}
if (alert_level == SSL3_AL_WARNING) {
- s->s3->warn_alert = alert_descr;
+ ssl->s3->warn_alert = alert_descr;
if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
- s->shutdown |= SSL_RECEIVED_SHUTDOWN;
+ ssl->shutdown |= SSL_RECEIVED_SHUTDOWN;
return 0;
}
@@ -648,8 +596,8 @@ start:
goto f_err;
}
- s->s3->warning_alert_count++;
- if (s->s3->warning_alert_count > kMaxWarningAlerts) {
+ ssl->s3->warning_alert_count++;
+ if (ssl->s3->warning_alert_count > kMaxWarningAlerts) {
al = SSL_AD_UNEXPECTED_MESSAGE;
OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_WARNING_ALERTS);
goto f_err;
@@ -657,13 +605,13 @@ start:
} else if (alert_level == SSL3_AL_FATAL) {
char tmp[16];
- s->rwstate = SSL_NOTHING;
- s->s3->fatal_alert = alert_descr;
+ ssl->rwstate = SSL_NOTHING;
+ ssl->s3->fatal_alert = alert_descr;
OPENSSL_PUT_ERROR(SSL, SSL_AD_REASON_OFFSET + alert_descr);
BIO_snprintf(tmp, sizeof(tmp), "%d", alert_descr);
ERR_add_error_data(2, "SSL alert number ", tmp);
- s->shutdown |= SSL_RECEIVED_SHUTDOWN;
- SSL_CTX_remove_session(s->ctx, s->session);
+ ssl->shutdown |= SSL_RECEIVED_SHUTDOWN;
+ SSL_CTX_remove_session(ssl->ctx, ssl->session);
return 0;
} else {
al = SSL_AD_ILLEGAL_PARAMETER;
@@ -674,97 +622,54 @@ start:
goto start;
}
- if (s->shutdown & SSL_SENT_SHUTDOWN) {
+ if (ssl->shutdown & SSL_SENT_SHUTDOWN) {
/* close_notify has been sent, so discard all records other than alerts. */
rr->length = 0;
goto start;
}
- if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) {
- /* 'Change Cipher Spec' is just a single byte, so we know exactly what the
- * record payload has to look like */
- if (rr->length != 1 || rr->off != 0 || rr->data[0] != SSL3_MT_CCS) {
- al = SSL_AD_ILLEGAL_PARAMETER;
- OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC);
- goto f_err;
- }
-
- /* Check we have a cipher to change to */
- if (s->s3->tmp.new_cipher == NULL) {
- al = SSL_AD_UNEXPECTED_MESSAGE;
- OPENSSL_PUT_ERROR(SSL, SSL_R_CCS_RECEIVED_EARLY);
- goto f_err;
- }
-
- if (!(s->s3->flags & SSL3_FLAGS_EXPECT_CCS)) {
- al = SSL_AD_UNEXPECTED_MESSAGE;
- OPENSSL_PUT_ERROR(SSL, SSL_R_CCS_RECEIVED_EARLY);
- goto f_err;
- }
-
- s->s3->flags &= ~SSL3_FLAGS_EXPECT_CCS;
-
- rr->length = 0;
-
- if (s->msg_callback) {
- s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, rr->data, 1, s,
- s->msg_callback_arg);
- }
-
- s->s3->change_cipher_spec = 1;
- if (!ssl3_do_change_cipher_spec(s)) {
- goto err;
- } else {
- goto start;
- }
- }
-
- /* We already handled these. */
- assert(rr->type != SSL3_RT_CHANGE_CIPHER_SPEC && rr->type != SSL3_RT_ALERT &&
- rr->type != SSL3_RT_HANDSHAKE);
-
al = SSL_AD_UNEXPECTED_MESSAGE;
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD);
f_err:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
err:
return -1;
}
-int ssl3_do_change_cipher_spec(SSL *s) {
+int ssl3_do_change_cipher_spec(SSL *ssl) {
int i;
- if (s->state & SSL_ST_ACCEPT) {
+ if (ssl->state & SSL_ST_ACCEPT) {
i = SSL3_CHANGE_CIPHER_SERVER_READ;
} else {
i = SSL3_CHANGE_CIPHER_CLIENT_READ;
}
- if (s->s3->tmp.key_block == NULL) {
- if (s->session == NULL || s->session->master_key_length == 0) {
+ if (ssl->s3->tmp.key_block == NULL) {
+ if (ssl->session == NULL || ssl->session->master_key_length == 0) {
/* might happen if dtls1_read_bytes() calls this */
OPENSSL_PUT_ERROR(SSL, SSL_R_CCS_RECEIVED_EARLY);
return 0;
}
- s->session->cipher = s->s3->tmp.new_cipher;
- if (!s->enc_method->setup_key_block(s)) {
+ ssl->session->cipher = ssl->s3->tmp.new_cipher;
+ if (!ssl->enc_method->setup_key_block(ssl)) {
return 0;
}
}
- if (!s->enc_method->change_cipher_state(s, i)) {
+ if (!ssl->enc_method->change_cipher_state(ssl, i)) {
return 0;
}
return 1;
}
-int ssl3_send_alert(SSL *s, int level, int desc) {
+int ssl3_send_alert(SSL *ssl, int level, int desc) {
/* Map tls/ssl alert value to correct one */
- desc = s->enc_method->alert_value(desc);
- if (s->version == SSL3_VERSION && desc == SSL_AD_PROTOCOL_VERSION) {
+ desc = ssl->enc_method->alert_value(desc);
+ if (ssl->version == SSL3_VERSION && desc == SSL_AD_PROTOCOL_VERSION) {
/* SSL 3.0 does not have protocol_version alerts */
desc = SSL_AD_HANDSHAKE_FAILURE;
}
@@ -773,17 +678,17 @@ int ssl3_send_alert(SSL *s, int level, int desc) {
}
/* If a fatal one, remove from cache */
- if (level == 2 && s->session != NULL) {
- SSL_CTX_remove_session(s->ctx, s->session);
+ if (level == 2 && ssl->session != NULL) {
+ SSL_CTX_remove_session(ssl->ctx, ssl->session);
}
- s->s3->alert_dispatch = 1;
- s->s3->send_alert[0] = level;
- s->s3->send_alert[1] = desc;
- if (!ssl_write_buffer_is_pending(s)) {
+ ssl->s3->alert_dispatch = 1;
+ ssl->s3->send_alert[0] = level;
+ ssl->s3->send_alert[1] = desc;
+ if (!ssl_write_buffer_is_pending(ssl)) {
/* Nothing is being written out, so the alert may be dispatched
* immediately. */
- return s->method->ssl_dispatch_alert(s);
+ return ssl->method->ssl_dispatch_alert(ssl);
}
/* else data is still being written out, we will get written some time in the
@@ -791,35 +696,35 @@ int ssl3_send_alert(SSL *s, int level, int desc) {
return -1;
}
-int ssl3_dispatch_alert(SSL *s) {
+int ssl3_dispatch_alert(SSL *ssl) {
int i, j;
void (*cb)(const SSL *ssl, int type, int value) = NULL;
- s->s3->alert_dispatch = 0;
- i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], 2);
+ ssl->s3->alert_dispatch = 0;
+ i = do_ssl3_write(ssl, SSL3_RT_ALERT, &ssl->s3->send_alert[0], 2);
if (i <= 0) {
- s->s3->alert_dispatch = 1;
+ ssl->s3->alert_dispatch = 1;
} else {
/* Alert sent to BIO. If it is important, flush it now. If the message
* does not get sent due to non-blocking IO, we will not worry too much. */
- if (s->s3->send_alert[0] == SSL3_AL_FATAL) {
- BIO_flush(s->wbio);
+ if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) {
+ BIO_flush(ssl->wbio);
}
- if (s->msg_callback) {
- s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, 2, s,
- s->msg_callback_arg);
+ if (ssl->msg_callback) {
+ ssl->msg_callback(1, ssl->version, SSL3_RT_ALERT, ssl->s3->send_alert, 2,
+ ssl, ssl->msg_callback_arg);
}
- if (s->info_callback != NULL) {
- cb = s->info_callback;
- } else if (s->ctx->info_callback != NULL) {
- cb = s->ctx->info_callback;
+ if (ssl->info_callback != NULL) {
+ cb = ssl->info_callback;
+ } else if (ssl->ctx->info_callback != NULL) {
+ cb = ssl->ctx->info_callback;
}
if (cb != NULL) {
- j = (s->s3->send_alert[0] << 8) | s->s3->send_alert[1];
- cb(s, SSL_CB_WRITE_ALERT, j);
+ j = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1];
+ cb(ssl, SSL_CB_WRITE_ALERT, j);
}
}
diff --git a/src/ssl/s3_srvr.c b/src/ssl/s3_srvr.c
index 8cfa0e6..49a1a95 100644
--- a/src/ssl/s3_srvr.c
+++ b/src/ssl/s3_srvr.c
@@ -174,154 +174,154 @@
#include "../crypto/dh/internal.h"
-int ssl3_accept(SSL *s) {
+int ssl3_accept(SSL *ssl) {
BUF_MEM *buf = NULL;
uint32_t alg_a;
void (*cb)(const SSL *ssl, int type, int value) = NULL;
int ret = -1;
int new_state, state, skip = 0;
- assert(s->handshake_func == ssl3_accept);
- assert(s->server);
- assert(!SSL_IS_DTLS(s));
+ assert(ssl->handshake_func == ssl3_accept);
+ assert(ssl->server);
+ assert(!SSL_IS_DTLS(ssl));
ERR_clear_error();
ERR_clear_system_error();
- if (s->info_callback != NULL) {
- cb = s->info_callback;
- } else if (s->ctx->info_callback != NULL) {
- cb = s->ctx->info_callback;
+ if (ssl->info_callback != NULL) {
+ cb = ssl->info_callback;
+ } else if (ssl->ctx->info_callback != NULL) {
+ cb = ssl->ctx->info_callback;
}
- s->in_handshake++;
+ ssl->in_handshake++;
- if (s->cert == NULL) {
+ if (ssl->cert == NULL) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
return -1;
}
for (;;) {
- state = s->state;
+ state = ssl->state;
- switch (s->state) {
+ switch (ssl->state) {
case SSL_ST_ACCEPT:
if (cb != NULL) {
- cb(s, SSL_CB_HANDSHAKE_START, 1);
+ cb(ssl, SSL_CB_HANDSHAKE_START, 1);
}
- if (s->init_buf == NULL) {
+ if (ssl->init_buf == NULL) {
buf = BUF_MEM_new();
if (!buf || !BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
ret = -1;
goto end;
}
- s->init_buf = buf;
+ ssl->init_buf = buf;
buf = NULL;
}
- s->init_num = 0;
+ ssl->init_num = 0;
/* Enable a write buffer. This groups handshake messages within a flight
* into a single write. */
- if (!ssl_init_wbio_buffer(s, 1)) {
+ if (!ssl_init_wbio_buffer(ssl, 1)) {
ret = -1;
goto end;
}
- if (!ssl3_init_handshake_buffer(s)) {
+ if (!ssl3_init_handshake_buffer(ssl)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
ret = -1;
goto end;
}
- if (!s->s3->have_version) {
- s->state = SSL3_ST_SR_INITIAL_BYTES;
+ if (!ssl->s3->have_version) {
+ ssl->state = SSL3_ST_SR_INITIAL_BYTES;
} else {
- s->state = SSL3_ST_SR_CLNT_HELLO_A;
+ ssl->state = SSL3_ST_SR_CLNT_HELLO_A;
}
break;
case SSL3_ST_SR_INITIAL_BYTES:
- ret = ssl3_get_initial_bytes(s);
+ ret = ssl3_get_initial_bytes(ssl);
if (ret <= 0) {
goto end;
}
- /* ssl3_get_initial_bytes sets s->state to one of
+ /* ssl3_get_initial_bytes sets ssl->state to one of
* SSL3_ST_SR_V2_CLIENT_HELLO or SSL3_ST_SR_CLNT_HELLO_A on success. */
break;
case SSL3_ST_SR_V2_CLIENT_HELLO:
- ret = ssl3_get_v2_client_hello(s);
+ ret = ssl3_get_v2_client_hello(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_SR_CLNT_HELLO_A;
+ ssl->state = SSL3_ST_SR_CLNT_HELLO_A;
break;
case SSL3_ST_SR_CLNT_HELLO_A:
case SSL3_ST_SR_CLNT_HELLO_B:
case SSL3_ST_SR_CLNT_HELLO_C:
case SSL3_ST_SR_CLNT_HELLO_D:
- s->shutdown = 0;
- ret = ssl3_get_client_hello(s);
+ ssl->shutdown = 0;
+ ret = ssl3_get_client_hello(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_SW_SRVR_HELLO_A;
- s->init_num = 0;
+ ssl->state = SSL3_ST_SW_SRVR_HELLO_A;
+ ssl->init_num = 0;
break;
case SSL3_ST_SW_SRVR_HELLO_A:
case SSL3_ST_SW_SRVR_HELLO_B:
- ret = ssl3_send_server_hello(s);
+ ret = ssl3_send_server_hello(ssl);
if (ret <= 0) {
goto end;
}
- if (s->hit) {
- if (s->tlsext_ticket_expected) {
- s->state = SSL3_ST_SW_SESSION_TICKET_A;
+ if (ssl->hit) {
+ if (ssl->tlsext_ticket_expected) {
+ ssl->state = SSL3_ST_SW_SESSION_TICKET_A;
} else {
- s->state = SSL3_ST_SW_CHANGE_A;
+ ssl->state = SSL3_ST_SW_CHANGE_A;
}
} else {
- s->state = SSL3_ST_SW_CERT_A;
+ ssl->state = SSL3_ST_SW_CERT_A;
}
- s->init_num = 0;
+ ssl->init_num = 0;
break;
case SSL3_ST_SW_CERT_A:
case SSL3_ST_SW_CERT_B:
- if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) {
- ret = ssl3_send_server_certificate(s);
+ if (ssl_cipher_has_server_public_key(ssl->s3->tmp.new_cipher)) {
+ ret = ssl3_send_server_certificate(ssl);
if (ret <= 0) {
goto end;
}
- if (s->s3->tmp.certificate_status_expected) {
- s->state = SSL3_ST_SW_CERT_STATUS_A;
+ if (ssl->s3->tmp.certificate_status_expected) {
+ ssl->state = SSL3_ST_SW_CERT_STATUS_A;
} else {
- s->state = SSL3_ST_SW_KEY_EXCH_A;
+ ssl->state = SSL3_ST_SW_KEY_EXCH_A;
}
} else {
skip = 1;
- s->state = SSL3_ST_SW_KEY_EXCH_A;
+ ssl->state = SSL3_ST_SW_KEY_EXCH_A;
}
- s->init_num = 0;
+ ssl->init_num = 0;
break;
case SSL3_ST_SW_CERT_STATUS_A:
case SSL3_ST_SW_CERT_STATUS_B:
- ret = ssl3_send_certificate_status(s);
+ ret = ssl3_send_certificate_status(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_SW_KEY_EXCH_A;
- s->init_num = 0;
+ ssl->state = SSL3_ST_SW_KEY_EXCH_A;
+ ssl->init_num = 0;
break;
case SSL3_ST_SW_KEY_EXCH_A:
case SSL3_ST_SW_KEY_EXCH_B:
case SSL3_ST_SW_KEY_EXCH_C:
- alg_a = s->s3->tmp.new_cipher->algorithm_auth;
+ alg_a = ssl->s3->tmp.new_cipher->algorithm_auth;
/* Send a ServerKeyExchange message if:
* - The key exchange is ephemeral or anonymous
@@ -330,9 +330,9 @@ int ssl3_accept(SSL *s) {
*
* TODO(davidben): This logic is currently duplicated in d1_srvr.c. Fix
* this. In the meantime, keep them in sync. */
- if (ssl_cipher_requires_server_key_exchange(s->s3->tmp.new_cipher) ||
- ((alg_a & SSL_aPSK) && s->psk_identity_hint)) {
- ret = ssl3_send_server_key_exchange(s);
+ if (ssl_cipher_requires_server_key_exchange(ssl->s3->tmp.new_cipher) ||
+ ((alg_a & SSL_aPSK) && ssl->psk_identity_hint)) {
+ ret = ssl3_send_server_key_exchange(ssl);
if (ret <= 0) {
goto end;
}
@@ -340,33 +340,33 @@ int ssl3_accept(SSL *s) {
skip = 1;
}
- s->state = SSL3_ST_SW_CERT_REQ_A;
- s->init_num = 0;
+ ssl->state = SSL3_ST_SW_CERT_REQ_A;
+ ssl->init_num = 0;
break;
case SSL3_ST_SW_CERT_REQ_A:
case SSL3_ST_SW_CERT_REQ_B:
- if (s->s3->tmp.cert_request) {
- ret = ssl3_send_certificate_request(s);
+ if (ssl->s3->tmp.cert_request) {
+ ret = ssl3_send_certificate_request(ssl);
if (ret <= 0) {
goto end;
}
} else {
skip = 1;
}
- s->state = SSL3_ST_SW_SRVR_DONE_A;
- s->init_num = 0;
+ ssl->state = SSL3_ST_SW_SRVR_DONE_A;
+ ssl->init_num = 0;
break;
case SSL3_ST_SW_SRVR_DONE_A:
case SSL3_ST_SW_SRVR_DONE_B:
- ret = ssl3_send_server_done(s);
+ ret = ssl3_send_server_done(ssl);
if (ret <= 0) {
goto end;
}
- s->s3->tmp.next_state = SSL3_ST_SR_CERT_A;
- s->state = SSL3_ST_SW_FLUSH;
- s->init_num = 0;
+ ssl->s3->tmp.next_state = SSL3_ST_SR_CERT_A;
+ ssl->state = SSL3_ST_SW_FLUSH;
+ ssl->init_num = 0;
break;
case SSL3_ST_SW_FLUSH:
@@ -375,151 +375,149 @@ int ssl3_accept(SSL *s) {
* in PR#1939. The proposed fix doesn't completely resolve this issue
* as buggy implementations of BIO_CTRL_PENDING still exist. So instead
* we just flush unconditionally. */
- s->rwstate = SSL_WRITING;
- if (BIO_flush(s->wbio) <= 0) {
+ ssl->rwstate = SSL_WRITING;
+ if (BIO_flush(ssl->wbio) <= 0) {
ret = -1;
goto end;
}
- s->rwstate = SSL_NOTHING;
+ ssl->rwstate = SSL_NOTHING;
- s->state = s->s3->tmp.next_state;
+ ssl->state = ssl->s3->tmp.next_state;
break;
case SSL3_ST_SR_CERT_A:
case SSL3_ST_SR_CERT_B:
- if (s->s3->tmp.cert_request) {
- ret = ssl3_get_client_certificate(s);
+ if (ssl->s3->tmp.cert_request) {
+ ret = ssl3_get_client_certificate(ssl);
if (ret <= 0) {
goto end;
}
}
- s->init_num = 0;
- s->state = SSL3_ST_SR_KEY_EXCH_A;
+ ssl->init_num = 0;
+ ssl->state = SSL3_ST_SR_KEY_EXCH_A;
break;
case SSL3_ST_SR_KEY_EXCH_A:
case SSL3_ST_SR_KEY_EXCH_B:
case SSL3_ST_SR_KEY_EXCH_C:
- ret = ssl3_get_client_key_exchange(s);
+ ret = ssl3_get_client_key_exchange(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_SR_CERT_VRFY_A;
- s->init_num = 0;
+ ssl->state = SSL3_ST_SR_CERT_VRFY_A;
+ ssl->init_num = 0;
break;
case SSL3_ST_SR_CERT_VRFY_A:
case SSL3_ST_SR_CERT_VRFY_B:
- ret = ssl3_get_cert_verify(s);
+ ret = ssl3_get_cert_verify(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_SR_CHANGE;
- s->init_num = 0;
+ ssl->state = SSL3_ST_SR_CHANGE;
+ ssl->init_num = 0;
break;
- case SSL3_ST_SR_CHANGE: {
- char next_proto_neg = 0;
- char channel_id = 0;
- next_proto_neg = s->s3->next_proto_neg_seen;
- channel_id = s->s3->tlsext_channel_id_valid;
+ case SSL3_ST_SR_CHANGE:
+ ret = ssl->method->ssl_read_change_cipher_spec(ssl);
+ if (ret <= 0) {
+ goto end;
+ }
- /* At this point, the next message must be entirely behind a
- * ChangeCipherSpec. */
- if (!ssl3_expect_change_cipher_spec(s)) {
+ if (!ssl3_do_change_cipher_spec(ssl)) {
ret = -1;
goto end;
}
- if (next_proto_neg) {
- s->state = SSL3_ST_SR_NEXT_PROTO_A;
- } else if (channel_id) {
- s->state = SSL3_ST_SR_CHANNEL_ID_A;
+
+ if (ssl->s3->next_proto_neg_seen) {
+ ssl->state = SSL3_ST_SR_NEXT_PROTO_A;
+ } else if (ssl->s3->tlsext_channel_id_valid) {
+ ssl->state = SSL3_ST_SR_CHANNEL_ID_A;
} else {
- s->state = SSL3_ST_SR_FINISHED_A;
+ ssl->state = SSL3_ST_SR_FINISHED_A;
}
break;
- }
case SSL3_ST_SR_NEXT_PROTO_A:
case SSL3_ST_SR_NEXT_PROTO_B:
- ret = ssl3_get_next_proto(s);
+ ret = ssl3_get_next_proto(ssl);
if (ret <= 0) {
goto end;
}
- s->init_num = 0;
- if (s->s3->tlsext_channel_id_valid) {
- s->state = SSL3_ST_SR_CHANNEL_ID_A;
+ ssl->init_num = 0;
+ if (ssl->s3->tlsext_channel_id_valid) {
+ ssl->state = SSL3_ST_SR_CHANNEL_ID_A;
} else {
- s->state = SSL3_ST_SR_FINISHED_A;
+ ssl->state = SSL3_ST_SR_FINISHED_A;
}
break;
case SSL3_ST_SR_CHANNEL_ID_A:
case SSL3_ST_SR_CHANNEL_ID_B:
- ret = ssl3_get_channel_id(s);
+ ret = ssl3_get_channel_id(ssl);
if (ret <= 0) {
goto end;
}
- s->init_num = 0;
- s->state = SSL3_ST_SR_FINISHED_A;
+ ssl->init_num = 0;
+ ssl->state = SSL3_ST_SR_FINISHED_A;
break;
case SSL3_ST_SR_FINISHED_A:
case SSL3_ST_SR_FINISHED_B:
- ret =
- ssl3_get_finished(s, SSL3_ST_SR_FINISHED_A, SSL3_ST_SR_FINISHED_B);
+ ret = ssl3_get_finished(ssl, SSL3_ST_SR_FINISHED_A,
+ SSL3_ST_SR_FINISHED_B);
if (ret <= 0) {
goto end;
}
- if (s->hit) {
- s->state = SSL_ST_OK;
- } else if (s->tlsext_ticket_expected) {
- s->state = SSL3_ST_SW_SESSION_TICKET_A;
+ if (ssl->hit) {
+ ssl->state = SSL_ST_OK;
+ } else if (ssl->tlsext_ticket_expected) {
+ ssl->state = SSL3_ST_SW_SESSION_TICKET_A;
} else {
- s->state = SSL3_ST_SW_CHANGE_A;
+ ssl->state = SSL3_ST_SW_CHANGE_A;
}
/* If this is a full handshake with ChannelID then record the hashshake
- * hashes in |s->session| in case we need them to verify a ChannelID
+ * hashes in |ssl->session| in case we need them to verify a ChannelID
* signature on a resumption of this session in the future. */
- if (!s->hit && s->s3->tlsext_channel_id_valid) {
- ret = tls1_record_handshake_hashes_for_channel_id(s);
+ if (!ssl->hit && ssl->s3->tlsext_channel_id_valid) {
+ ret = tls1_record_handshake_hashes_for_channel_id(ssl);
if (ret <= 0) {
goto end;
}
}
- s->init_num = 0;
+ ssl->init_num = 0;
break;
case SSL3_ST_SW_SESSION_TICKET_A:
case SSL3_ST_SW_SESSION_TICKET_B:
- ret = ssl3_send_new_session_ticket(s);
+ ret = ssl3_send_new_session_ticket(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_SW_CHANGE_A;
- s->init_num = 0;
+ ssl->state = SSL3_ST_SW_CHANGE_A;
+ ssl->init_num = 0;
break;
case SSL3_ST_SW_CHANGE_A:
case SSL3_ST_SW_CHANGE_B:
- s->session->cipher = s->s3->tmp.new_cipher;
- if (!s->enc_method->setup_key_block(s)) {
+ ssl->session->cipher = ssl->s3->tmp.new_cipher;
+ if (!ssl->enc_method->setup_key_block(ssl)) {
ret = -1;
goto end;
}
- ret = ssl3_send_change_cipher_spec(s, SSL3_ST_SW_CHANGE_A,
+ ret = ssl3_send_change_cipher_spec(ssl, SSL3_ST_SW_CHANGE_A,
SSL3_ST_SW_CHANGE_B);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_SW_FINISHED_A;
- s->init_num = 0;
+ ssl->state = SSL3_ST_SW_FINISHED_A;
+ ssl->init_num = 0;
- if (!s->enc_method->change_cipher_state(
- s, SSL3_CHANGE_CIPHER_SERVER_WRITE)) {
+ if (!ssl->enc_method->change_cipher_state(
+ ssl, SSL3_CHANGE_CIPHER_SERVER_WRITE)) {
ret = -1;
goto end;
}
@@ -527,49 +525,49 @@ int ssl3_accept(SSL *s) {
case SSL3_ST_SW_FINISHED_A:
case SSL3_ST_SW_FINISHED_B:
- ret =
- ssl3_send_finished(s, SSL3_ST_SW_FINISHED_A, SSL3_ST_SW_FINISHED_B,
- s->enc_method->server_finished_label,
- s->enc_method->server_finished_label_len);
+ ret = ssl3_send_finished(ssl, SSL3_ST_SW_FINISHED_A,
+ SSL3_ST_SW_FINISHED_B,
+ ssl->enc_method->server_finished_label,
+ ssl->enc_method->server_finished_label_len);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_SW_FLUSH;
- if (s->hit) {
- s->s3->tmp.next_state = SSL3_ST_SR_CHANGE;
+ ssl->state = SSL3_ST_SW_FLUSH;
+ if (ssl->hit) {
+ ssl->s3->tmp.next_state = SSL3_ST_SR_CHANGE;
} else {
- s->s3->tmp.next_state = SSL_ST_OK;
+ ssl->s3->tmp.next_state = SSL_ST_OK;
}
- s->init_num = 0;
+ ssl->init_num = 0;
break;
case SSL_ST_OK:
/* clean a few things up */
- ssl3_cleanup_key_block(s);
+ ssl3_cleanup_key_block(ssl);
- BUF_MEM_free(s->init_buf);
- s->init_buf = NULL;
+ BUF_MEM_free(ssl->init_buf);
+ ssl->init_buf = NULL;
/* remove buffering on output */
- ssl_free_wbio_buffer(s);
+ ssl_free_wbio_buffer(ssl);
- s->init_num = 0;
+ ssl->init_num = 0;
/* If we aren't retaining peer certificates then we can discard it
* now. */
- if (s->ctx->retain_only_sha256_of_client_certs) {
- X509_free(s->session->peer);
- s->session->peer = NULL;
- sk_X509_pop_free(s->session->cert_chain, X509_free);
- s->session->cert_chain = NULL;
+ if (ssl->ctx->retain_only_sha256_of_client_certs) {
+ X509_free(ssl->session->peer);
+ ssl->session->peer = NULL;
+ sk_X509_pop_free(ssl->session->cert_chain, X509_free);
+ ssl->session->cert_chain = NULL;
}
- s->s3->initial_handshake_complete = 1;
+ ssl->s3->initial_handshake_complete = 1;
- ssl_update_cache(s, SSL_SESS_CACHE_SERVER);
+ ssl_update_cache(ssl, SSL_SESS_CACHE_SERVER);
if (cb != NULL) {
- cb(s, SSL_CB_HANDSHAKE_DONE, 1);
+ cb(ssl, SSL_CB_HANDSHAKE_DONE, 1);
}
ret = 1;
@@ -581,34 +579,35 @@ int ssl3_accept(SSL *s) {
goto end;
}
- if (!s->s3->tmp.reuse_message && !skip && cb != NULL && s->state != state) {
- new_state = s->state;
- s->state = state;
- cb(s, SSL_CB_ACCEPT_LOOP, 1);
- s->state = new_state;
+ if (!ssl->s3->tmp.reuse_message && !skip && cb != NULL &&
+ ssl->state != state) {
+ new_state = ssl->state;
+ ssl->state = state;
+ cb(ssl, SSL_CB_ACCEPT_LOOP, 1);
+ ssl->state = new_state;
}
skip = 0;
}
end:
- s->in_handshake--;
+ ssl->in_handshake--;
BUF_MEM_free(buf);
if (cb != NULL) {
- cb(s, SSL_CB_ACCEPT_EXIT, ret);
+ cb(ssl, SSL_CB_ACCEPT_EXIT, ret);
}
return ret;
}
-int ssl3_get_initial_bytes(SSL *s) {
+int ssl3_get_initial_bytes(SSL *ssl) {
/* Read the first 5 bytes, the size of the TLS record header. This is
* sufficient to detect a V2ClientHello and ensures that we never read beyond
* the first record. */
- int ret = ssl_read_buffer_extend_to(s, SSL3_RT_HEADER_LENGTH);
+ int ret = ssl_read_buffer_extend_to(ssl, SSL3_RT_HEADER_LENGTH);
if (ret <= 0) {
return ret;
}
- assert(ssl_read_buffer_len(s) == SSL3_RT_HEADER_LENGTH);
- const uint8_t *p = ssl_read_buffer(s);
+ assert(ssl_read_buffer_len(ssl) == SSL3_RT_HEADER_LENGTH);
+ const uint8_t *p = ssl_read_buffer(ssl);
/* Some dedicated error codes for protocol mixups should the application wish
* to interpret them differently. (These do not overlap with ClientHello or
@@ -629,16 +628,16 @@ int ssl3_get_initial_bytes(SSL *s) {
if ((p[0] & 0x80) && p[2] == SSL2_MT_CLIENT_HELLO &&
p[3] >= SSL3_VERSION_MAJOR) {
/* This is a V2ClientHello. */
- s->state = SSL3_ST_SR_V2_CLIENT_HELLO;
+ ssl->state = SSL3_ST_SR_V2_CLIENT_HELLO;
return 1;
}
/* Fall through to the standard logic. */
- s->state = SSL3_ST_SR_CLNT_HELLO_A;
+ ssl->state = SSL3_ST_SR_CLNT_HELLO_A;
return 1;
}
-int ssl3_get_v2_client_hello(SSL *s) {
+int ssl3_get_v2_client_hello(SSL *ssl) {
const uint8_t *p;
int ret;
CBS v2_client_hello, cipher_specs, session_id, challenge;
@@ -649,8 +648,8 @@ int ssl3_get_v2_client_hello(SSL *s) {
uint8_t random[SSL3_RANDOM_SIZE];
/* Determine the length of the V2ClientHello. */
- assert(ssl_read_buffer_len(s) >= SSL3_RT_HEADER_LENGTH);
- p = ssl_read_buffer(s);
+ assert(ssl_read_buffer_len(ssl) >= SSL3_RT_HEADER_LENGTH);
+ p = ssl_read_buffer(ssl);
msg_length = ((p[0] & 0x7f) << 8) | p[1];
if (msg_length > (1024 * 4)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE);
@@ -665,22 +664,22 @@ int ssl3_get_v2_client_hello(SSL *s) {
}
/* Read the remainder of the V2ClientHello. */
- ret = ssl_read_buffer_extend_to(s, 2 + msg_length);
+ ret = ssl_read_buffer_extend_to(ssl, 2 + msg_length);
if (ret <= 0) {
return ret;
}
- assert(ssl_read_buffer_len(s) == msg_length + 2);
- CBS_init(&v2_client_hello, ssl_read_buffer(s) + 2, msg_length);
+ assert(ssl_read_buffer_len(ssl) == msg_length + 2);
+ CBS_init(&v2_client_hello, ssl_read_buffer(ssl) + 2, msg_length);
/* The V2ClientHello without the length is incorporated into the handshake
* hash. */
- if (!ssl3_update_handshake_hash(s, CBS_data(&v2_client_hello),
+ if (!ssl3_update_handshake_hash(ssl, CBS_data(&v2_client_hello),
CBS_len(&v2_client_hello))) {
return -1;
}
- if (s->msg_callback) {
- s->msg_callback(0, SSL2_VERSION, 0, CBS_data(&v2_client_hello),
- CBS_len(&v2_client_hello), s, s->msg_callback_arg);
+ if (ssl->msg_callback) {
+ ssl->msg_callback(0, SSL2_VERSION, 0, CBS_data(&v2_client_hello),
+ CBS_len(&v2_client_hello), ssl, ssl->msg_callback_arg);
}
if (!CBS_get_u8(&v2_client_hello, &msg_type) ||
@@ -711,8 +710,8 @@ int ssl3_get_v2_client_hello(SSL *s) {
/* Write out an equivalent SSLv3 ClientHello. */
CBB_zero(&client_hello);
- if (!CBB_init_fixed(&client_hello, (uint8_t *)s->init_buf->data,
- s->init_buf->max) ||
+ if (!CBB_init_fixed(&client_hello, (uint8_t *)ssl->init_buf->data,
+ ssl->init_buf->max) ||
!CBB_add_u8(&client_hello, SSL3_MT_CLIENT_HELLO) ||
!CBB_add_u24_length_prefixed(&client_hello, &hello_body) ||
!CBB_add_u16(&hello_body, version) ||
@@ -754,19 +753,19 @@ int ssl3_get_v2_client_hello(SSL *s) {
}
/* Mark the message for "re"-use by the version-specific method. */
- s->s3->tmp.reuse_message = 1;
- s->s3->tmp.message_type = SSL3_MT_CLIENT_HELLO;
+ ssl->s3->tmp.reuse_message = 1;
+ ssl->s3->tmp.message_type = SSL3_MT_CLIENT_HELLO;
/* The handshake message header is 4 bytes. */
- s->s3->tmp.message_size = len - 4;
+ ssl->s3->tmp.message_size = len - 4;
/* Consume and discard the V2ClientHello. */
- ssl_read_buffer_consume(s, 2 + msg_length);
- ssl_read_buffer_discard(s);
+ ssl_read_buffer_consume(ssl, 2 + msg_length);
+ ssl_read_buffer_discard(ssl);
return 1;
}
-int ssl3_get_client_hello(SSL *s) {
+int ssl3_get_client_hello(SSL *ssl) {
int ok, al = SSL_AD_INTERNAL_ERROR, ret = -1;
long n;
const SSL_CIPHER *c;
@@ -781,11 +780,11 @@ int ssl3_get_client_hello(SSL *s) {
* and we get SSLv3, we will respond with TLSv1, This down switching should
* be handled by a different method. If we are SSLv3, we will respond with
* SSLv3, even if prompted with TLSv1. */
- switch (s->state) {
+ switch (ssl->state) {
case SSL3_ST_SR_CLNT_HELLO_A:
case SSL3_ST_SR_CLNT_HELLO_B:
- n = s->method->ssl_get_message(
- s, SSL3_ST_SR_CLNT_HELLO_A, SSL3_ST_SR_CLNT_HELLO_B,
+ n = ssl->method->ssl_get_message(
+ ssl, SSL3_ST_SR_CLNT_HELLO_A, SSL3_ST_SR_CLNT_HELLO_B,
SSL3_MT_CLIENT_HELLO, SSL3_RT_MAX_PLAIN_LENGTH,
ssl_hash_message, &ok);
@@ -793,18 +792,18 @@ int ssl3_get_client_hello(SSL *s) {
return n;
}
- s->state = SSL3_ST_SR_CLNT_HELLO_C;
+ ssl->state = SSL3_ST_SR_CLNT_HELLO_C;
/* fallthrough */
case SSL3_ST_SR_CLNT_HELLO_C:
case SSL3_ST_SR_CLNT_HELLO_D:
/* We have previously parsed the ClientHello message, and can't call
* ssl_get_message again without hashing the message into the Finished
* digest again. */
- n = s->init_num;
+ n = ssl->init_num;
memset(&early_ctx, 0, sizeof(early_ctx));
- early_ctx.ssl = s;
- early_ctx.client_hello = s->init_msg;
+ early_ctx.ssl = ssl;
+ early_ctx.client_hello = ssl->init_msg;
early_ctx.client_hello_len = n;
if (!ssl_early_callback_init(&early_ctx)) {
al = SSL_AD_DECODE_ERROR;
@@ -812,12 +811,12 @@ int ssl3_get_client_hello(SSL *s) {
goto f_err;
}
- if (s->state == SSL3_ST_SR_CLNT_HELLO_C &&
- s->ctx->select_certificate_cb != NULL) {
- s->state = SSL3_ST_SR_CLNT_HELLO_D;
- switch (s->ctx->select_certificate_cb(&early_ctx)) {
+ if (ssl->state == SSL3_ST_SR_CLNT_HELLO_C &&
+ ssl->ctx->select_certificate_cb != NULL) {
+ ssl->state = SSL3_ST_SR_CLNT_HELLO_D;
+ switch (ssl->ctx->select_certificate_cb(&early_ctx)) {
case 0:
- s->rwstate = SSL_CERTIFICATE_SELECTION_PENDING;
+ ssl->rwstate = SSL_CERTIFICATE_SELECTION_PENDING;
goto err;
case -1:
@@ -830,7 +829,7 @@ int ssl3_get_client_hello(SSL *s) {
/* fallthrough */;
}
}
- s->state = SSL3_ST_SR_CLNT_HELLO_D;
+ ssl->state = SSL3_ST_SR_CLNT_HELLO_D;
break;
default:
@@ -838,7 +837,7 @@ int ssl3_get_client_hello(SSL *s) {
return -1;
}
- CBS_init(&client_hello, s->init_msg, n);
+ CBS_init(&client_hello, ssl->init_msg, n);
if (!CBS_get_u16(&client_hello, &client_version) ||
!CBS_get_bytes(&client_hello, &client_random, SSL3_RANDOM_SIZE) ||
!CBS_get_u8_length_prefixed(&client_hello, &session_id) ||
@@ -850,12 +849,12 @@ int ssl3_get_client_hello(SSL *s) {
/* use version from inside client hello, not from record header (may differ:
* see RFC 2246, Appendix E, second paragraph) */
- s->client_version = client_version;
+ ssl->client_version = client_version;
/* Load the client random. */
- memcpy(s->s3->client_random, CBS_data(&client_random), SSL3_RANDOM_SIZE);
+ memcpy(ssl->s3->client_random, CBS_data(&client_random), SSL3_RANDOM_SIZE);
- if (SSL_IS_DTLS(s)) {
+ if (SSL_IS_DTLS(ssl)) {
CBS cookie;
if (!CBS_get_u8_length_prefixed(&client_hello, &cookie) ||
@@ -871,40 +870,40 @@ int ssl3_get_client_hello(SSL *s) {
*
* TODO(davidben): Clean up the order of events around ClientHello
* processing. */
- if (!s->s3->have_version) {
+ if (!ssl->s3->have_version) {
/* Select version to use */
- uint16_t version = ssl3_get_mutual_version(s, client_version);
+ uint16_t version = ssl3_get_mutual_version(ssl, client_version);
if (version == 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL);
- s->version = s->client_version;
+ ssl->version = ssl->client_version;
al = SSL_AD_PROTOCOL_VERSION;
goto f_err;
}
- s->version = version;
- s->enc_method = ssl3_get_enc_method(version);
- assert(s->enc_method != NULL);
- /* At this point, the connection's version is known and |s->version| is
+ ssl->version = version;
+ ssl->enc_method = ssl3_get_enc_method(version);
+ assert(ssl->enc_method != NULL);
+ /* At this point, the connection's version is known and |ssl->version| is
* fixed. Begin enforcing the record-layer version. */
- s->s3->have_version = 1;
- } else if (SSL_IS_DTLS(s) ? (s->client_version > s->version)
- : (s->client_version < s->version)) {
+ ssl->s3->have_version = 1;
+ } else if (SSL_IS_DTLS(ssl) ? (ssl->client_version > ssl->version)
+ : (ssl->client_version < ssl->version)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_VERSION_NUMBER);
al = SSL_AD_PROTOCOL_VERSION;
goto f_err;
}
- s->hit = 0;
+ ssl->hit = 0;
int send_new_ticket = 0;
- switch (ssl_get_prev_session(s, &session, &send_new_ticket, &early_ctx)) {
+ switch (ssl_get_prev_session(ssl, &session, &send_new_ticket, &early_ctx)) {
case ssl_session_success:
break;
case ssl_session_error:
goto err;
case ssl_session_retry:
- s->rwstate = SSL_PENDING_SESSION;
+ ssl->rwstate = SSL_PENDING_SESSION;
goto err;
}
- s->tlsext_ticket_expected = send_new_ticket;
+ ssl->tlsext_ticket_expected = send_new_ticket;
/* The EMS state is needed when making the resumption decision, but
* extensions are not normally parsed until later. This detects the EMS
@@ -913,7 +912,7 @@ int ssl3_get_client_hello(SSL *s) {
const uint8_t *ems_data;
size_t ems_len;
int have_extended_master_secret =
- s->version != SSL3_VERSION &&
+ ssl->version != SSL3_VERSION &&
SSL_early_callback_ctx_extension_get(&early_ctx,
TLSEXT_TYPE_extended_master_secret,
&ems_data, &ems_len) &&
@@ -929,34 +928,35 @@ int ssl3_get_client_hello(SSL *s) {
goto f_err;
}
- s->hit =
+ ssl->hit =
/* Only resume if the session's version matches the negotiated version:
* most clients do not accept a mismatch. */
- s->version == session->ssl_version &&
+ ssl->version == session->ssl_version &&
/* If the client offers the EMS extension, but the previous session
* didn't use it, then negotiate a new session. */
have_extended_master_secret == session->extended_master_secret;
}
- if (s->hit) {
+ if (ssl->hit) {
/* Use the new session. */
- SSL_SESSION_free(s->session);
- s->session = session;
+ SSL_SESSION_free(ssl->session);
+ ssl->session = session;
session = NULL;
- s->verify_result = s->session->verify_result;
+ ssl->verify_result = ssl->session->verify_result;
} else {
- if (!ssl_get_new_session(s, 1 /* server */)) {
+ if (!ssl_get_new_session(ssl, 1 /* server */)) {
goto err;
}
/* Clear the session ID if we want the session to be single-use. */
- if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)) {
- s->session->session_id_length = 0;
+ if (!(ssl->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)) {
+ ssl->session->session_id_length = 0;
}
}
- if (s->ctx->dos_protection_cb != NULL && s->ctx->dos_protection_cb(&early_ctx) == 0) {
+ if (ssl->ctx->dos_protection_cb != NULL &&
+ ssl->ctx->dos_protection_cb(&early_ctx) == 0) {
/* Connection rejected for DOS reasons. */
al = SSL_AD_ACCESS_DENIED;
OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
@@ -973,16 +973,16 @@ int ssl3_get_client_hello(SSL *s) {
goto f_err;
}
- ciphers = ssl_bytes_to_cipher_list(s, &cipher_suites);
+ ciphers = ssl_bytes_to_cipher_list(ssl, &cipher_suites);
if (ciphers == NULL) {
goto err;
}
/* If it is a hit, check that the cipher is in the list. */
- if (s->hit) {
+ if (ssl->hit) {
size_t j;
int found_cipher = 0;
- uint32_t id = s->session->cipher->id;
+ uint32_t id = ssl->session->cipher->id;
for (j = 0; j < sk_SSL_CIPHER_num(ciphers); j++) {
c = sk_SSL_CIPHER_value(ciphers, j);
@@ -1010,8 +1010,8 @@ int ssl3_get_client_hello(SSL *s) {
}
/* TLS extensions. */
- if (s->version >= SSL3_VERSION &&
- !ssl_parse_clienthello_tlsext(s, &client_hello)) {
+ if (ssl->version >= SSL3_VERSION &&
+ !ssl_parse_clienthello_tlsext(ssl, &client_hello)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT);
goto err;
}
@@ -1024,14 +1024,14 @@ int ssl3_get_client_hello(SSL *s) {
goto f_err;
}
- if (have_extended_master_secret != s->s3->tmp.extended_master_secret) {
+ if (have_extended_master_secret != ssl->s3->tmp.extended_master_secret) {
al = SSL_AD_INTERNAL_ERROR;
OPENSSL_PUT_ERROR(SSL, SSL_R_EMS_STATE_INCONSISTENT);
goto f_err;
}
/* Given ciphers and SSL_get_ciphers, we must pick a cipher */
- if (!s->hit) {
+ if (!ssl->hit) {
if (ciphers == NULL) {
al = SSL_AD_ILLEGAL_PARAMETER;
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHERS_PASSED);
@@ -1039,54 +1039,54 @@ int ssl3_get_client_hello(SSL *s) {
}
/* Let cert callback update server certificates if required */
- if (s->cert->cert_cb) {
- int rv = s->cert->cert_cb(s, s->cert->cert_cb_arg);
+ if (ssl->cert->cert_cb) {
+ int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
if (rv == 0) {
al = SSL_AD_INTERNAL_ERROR;
OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR);
goto f_err;
}
if (rv < 0) {
- s->rwstate = SSL_X509_LOOKUP;
+ ssl->rwstate = SSL_X509_LOOKUP;
goto err;
}
- s->rwstate = SSL_NOTHING;
+ ssl->rwstate = SSL_NOTHING;
}
- c = ssl3_choose_cipher(s, ciphers, ssl_get_cipher_preferences(s));
+ c = ssl3_choose_cipher(ssl, ciphers, ssl_get_cipher_preferences(ssl));
if (c == NULL) {
al = SSL_AD_HANDSHAKE_FAILURE;
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
goto f_err;
}
- s->s3->tmp.new_cipher = c;
+ ssl->s3->tmp.new_cipher = c;
/* Determine whether to request a client certificate. */
- s->s3->tmp.cert_request = !!(s->verify_mode & SSL_VERIFY_PEER);
+ ssl->s3->tmp.cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER);
/* Only request a certificate if Channel ID isn't negotiated. */
- if ((s->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) &&
- s->s3->tlsext_channel_id_valid) {
- s->s3->tmp.cert_request = 0;
+ if ((ssl->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) &&
+ ssl->s3->tlsext_channel_id_valid) {
+ ssl->s3->tmp.cert_request = 0;
}
/* Plain PSK forbids Certificate and CertificateRequest. */
- if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK) {
- s->s3->tmp.cert_request = 0;
+ if (ssl->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK) {
+ ssl->s3->tmp.cert_request = 0;
}
} else {
/* Session-id reuse */
- s->s3->tmp.new_cipher = s->session->cipher;
- s->s3->tmp.cert_request = 0;
+ ssl->s3->tmp.new_cipher = ssl->session->cipher;
+ ssl->s3->tmp.cert_request = 0;
}
/* Now that the cipher is known, initialize the handshake hash. */
- if (!ssl3_init_handshake_hash(s)) {
+ if (!ssl3_init_handshake_hash(ssl)) {
goto f_err;
}
/* In TLS 1.2, client authentication requires hashing the handshake transcript
* under a different hash. Otherwise, release the handshake buffer. */
- if (!SSL_USE_SIGALGS(s) || !s->s3->tmp.cert_request) {
- ssl3_free_handshake_buffer(s);
+ if (!SSL_USE_SIGALGS(ssl) || !ssl->s3->tmp.cert_request) {
+ ssl3_free_handshake_buffer(ssl);
}
/* we now have the following setup;
@@ -1095,17 +1095,15 @@ int ssl3_get_client_hello(SSL *s) {
* ciphers - the clients prefered list of ciphers
* compression - basically ignored right now
* ssl version is set - sslv3
- * s->session - The ssl session has been setup.
- * s->hit - session reuse flag
- * s->tmp.new_cipher - the new cipher to use. */
+ * ssl->session - The ssl session has been setup.
+ * ssl->hit - session reuse flag
+ * ssl->tmp.new_cipher - the new cipher to use. */
- if (ret < 0) {
- ret = -ret;
- }
+ ret = 1;
if (0) {
f_err:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
}
err:
@@ -1191,324 +1189,203 @@ int ssl3_send_certificate_status(SSL *ssl) {
return ssl_do_write(ssl);
}
-int ssl3_send_server_done(SSL *s) {
- if (s->state == SSL3_ST_SW_SRVR_DONE_A) {
- if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_DONE, 0)) {
+int ssl3_send_server_done(SSL *ssl) {
+ if (ssl->state == SSL3_ST_SW_SRVR_DONE_A) {
+ if (!ssl_set_handshake_header(ssl, SSL3_MT_SERVER_DONE, 0)) {
return -1;
}
- s->state = SSL3_ST_SW_SRVR_DONE_B;
+ ssl->state = SSL3_ST_SW_SRVR_DONE_B;
}
/* SSL3_ST_SW_SRVR_DONE_B */
- return ssl_do_write(s);
+ return ssl_do_write(ssl);
}
-int ssl3_send_server_key_exchange(SSL *s) {
- DH *dh = NULL, *dhp;
- EC_KEY *ecdh = NULL;
- uint8_t *encodedPoint = NULL;
- int encodedlen = 0;
- uint16_t curve_id = 0;
- BN_CTX *bn_ctx = NULL;
- const char *psk_identity_hint = NULL;
- size_t psk_identity_hint_len = 0;
- size_t sig_len;
- size_t max_sig_len;
- uint8_t *p, *d;
- int al, i;
- uint32_t alg_k;
- uint32_t alg_a;
- int n;
- CERT *cert;
- BIGNUM *r[4];
- int nr[4];
- BUF_MEM *buf;
- EVP_MD_CTX md_ctx;
-
- if (s->state == SSL3_ST_SW_KEY_EXCH_C) {
- return ssl_do_write(s);
+int ssl3_send_server_key_exchange(SSL *ssl) {
+ if (ssl->state == SSL3_ST_SW_KEY_EXCH_C) {
+ return ssl_do_write(ssl);
}
- if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) {
- if (!ssl_has_private_key(s)) {
- al = SSL_AD_INTERNAL_ERROR;
- goto f_err;
- }
- max_sig_len = ssl_private_key_max_signature_len(s);
- } else {
- max_sig_len = 0;
+ CBB cbb, child;
+ if (!CBB_init_fixed(&cbb, ssl_handshake_start(ssl),
+ ssl->init_buf->max - SSL_HM_HEADER_LENGTH(ssl))) {
+ goto err;
}
- EVP_MD_CTX_init(&md_ctx);
- enum ssl_private_key_result_t sign_result;
- if (s->state == SSL3_ST_SW_KEY_EXCH_A) {
- alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
- alg_a = s->s3->tmp.new_cipher->algorithm_auth;
- cert = s->cert;
+ if (ssl->state == SSL3_ST_SW_KEY_EXCH_A) {
+ /* This is the first iteration, so write parameters. */
+ uint32_t alg_k = ssl->s3->tmp.new_cipher->algorithm_mkey;
+ uint32_t alg_a = ssl->s3->tmp.new_cipher->algorithm_auth;
- buf = s->init_buf;
-
- r[0] = r[1] = r[2] = r[3] = NULL;
- n = 0;
+ /* PSK ciphers begin with an identity hint. */
if (alg_a & SSL_aPSK) {
- /* size for PSK identity hint */
- psk_identity_hint = s->psk_identity_hint;
- if (psk_identity_hint) {
- psk_identity_hint_len = strlen(psk_identity_hint);
- } else {
- psk_identity_hint_len = 0;
+ size_t len =
+ (ssl->psk_identity_hint == NULL) ? 0 : strlen(ssl->psk_identity_hint);
+ if (!CBB_add_u16_length_prefixed(&cbb, &child) ||
+ !CBB_add_bytes(&child, (const uint8_t *)ssl->psk_identity_hint,
+ len)) {
+ goto err;
}
- n += 2 + psk_identity_hint_len;
}
if (alg_k & SSL_kDHE) {
- dhp = cert->dh_tmp;
- if (dhp == NULL && s->cert->dh_tmp_cb != NULL) {
- dhp = s->cert->dh_tmp_cb(s, 0, 1024);
+ /* Determine the group to use. */
+ DH *params = ssl->cert->dh_tmp;
+ if (params == NULL && ssl->cert->dh_tmp_cb != NULL) {
+ params = ssl->cert->dh_tmp_cb(ssl, 0, 1024);
}
- if (dhp == NULL) {
- al = SSL_AD_HANDSHAKE_FAILURE;
+ if (params == NULL) {
OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_TMP_DH_KEY);
- goto f_err;
- }
-
- if (s->s3->tmp.dh != NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
goto err;
}
- dh = DHparams_dup(dhp);
+ ssl->session->key_exchange_info = DH_num_bits(params);
+
+ /* Set up DH, generate a key, and emit the public half. */
+ DH *dh = DHparams_dup(params);
if (dh == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
goto err;
}
- s->s3->tmp.dh = dh;
- if (!DH_generate_key(dh)) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
+ SSL_ECDH_CTX_init_for_dhe(&ssl->s3->tmp.ecdh_ctx, dh);
+ if (!CBB_add_u16_length_prefixed(&cbb, &child) ||
+ !BN_bn2cbb_padded(&child, BN_num_bytes(params->p), params->p) ||
+ !CBB_add_u16_length_prefixed(&cbb, &child) ||
+ !BN_bn2cbb_padded(&child, BN_num_bytes(params->g), params->g) ||
+ !CBB_add_u16_length_prefixed(&cbb, &child) ||
+ !SSL_ECDH_CTX_generate_keypair(&ssl->s3->tmp.ecdh_ctx, &child)) {
goto err;
}
-
- r[0] = dh->p;
- r[1] = dh->g;
- r[2] = dh->pub_key;
} else if (alg_k & SSL_kECDHE) {
/* Determine the curve to use. */
- int nid = NID_undef;
- if (cert->ecdh_nid != NID_undef) {
- nid = cert->ecdh_nid;
- } else if (cert->ecdh_tmp_cb != NULL) {
- /* Note: |ecdh_tmp_cb| does NOT pass ownership of the result
- * to the caller. */
- EC_KEY *template = s->cert->ecdh_tmp_cb(s, 0, 1024);
- if (template != NULL && EC_KEY_get0_group(template) != NULL) {
- nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(template));
- }
- } else {
- nid = tls1_get_shared_curve(s);
- }
- if (nid == NID_undef) {
- al = SSL_AD_HANDSHAKE_FAILURE;
+ uint16_t curve_id;
+ if (!tls1_get_shared_curve(ssl, &curve_id)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_TMP_ECDH_KEY);
- goto f_err;
- }
-
- if (s->s3->tmp.ecdh != NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- ecdh = EC_KEY_new_by_curve_name(nid);
- if (ecdh == NULL) {
- goto err;
- }
- s->s3->tmp.ecdh = ecdh;
-
- if (!EC_KEY_generate_key(ecdh)) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB);
- goto err;
- }
-
- /* We only support ephemeral ECDH keys over named (not generic) curves. */
- const EC_GROUP *group = EC_KEY_get0_group(ecdh);
- if (!tls1_ec_nid2curve_id(&curve_id, EC_GROUP_get_curve_name(group))) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_ELLIPTIC_CURVE);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
goto err;
}
-
- /* Encode the public key. First check the size of encoding and allocate
- * memory accordingly. */
- encodedlen =
- EC_POINT_point2oct(group, EC_KEY_get0_public_key(ecdh),
- POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL);
-
- encodedPoint = (uint8_t *)OPENSSL_malloc(encodedlen * sizeof(uint8_t));
- bn_ctx = BN_CTX_new();
- if (encodedPoint == NULL || bn_ctx == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- encodedlen = EC_POINT_point2oct(group, EC_KEY_get0_public_key(ecdh),
- POINT_CONVERSION_UNCOMPRESSED,
- encodedPoint, encodedlen, bn_ctx);
-
- if (encodedlen == 0) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB);
+ ssl->session->key_exchange_info = curve_id;
+
+ /* Set up ECDH, generate a key, and emit the public half. */
+ if (!SSL_ECDH_CTX_init(&ssl->s3->tmp.ecdh_ctx, curve_id) ||
+ !CBB_add_u8(&cbb, NAMED_CURVE_TYPE) ||
+ !CBB_add_u16(&cbb, curve_id) ||
+ !CBB_add_u8_length_prefixed(&cbb, &child) ||
+ !SSL_ECDH_CTX_generate_keypair(&ssl->s3->tmp.ecdh_ctx, &child)) {
goto err;
}
-
- BN_CTX_free(bn_ctx);
- bn_ctx = NULL;
-
- /* We only support named (not generic) curves in ECDH ephemeral key
- * exchanges. In this situation, we need four additional bytes to encode
- * the entire ServerECDHParams structure. */
- n += 4 + encodedlen;
-
- /* We'll generate the serverKeyExchange message explicitly so we can set
- * these to NULLs */
- r[0] = NULL;
- r[1] = NULL;
- r[2] = NULL;
- r[3] = NULL;
- } else if (!(alg_k & SSL_kPSK)) {
- al = SSL_AD_HANDSHAKE_FAILURE;
- OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
- goto f_err;
+ } else {
+ assert(alg_k & SSL_kPSK);
}
- for (i = 0; i < 4 && r[i] != NULL; i++) {
- nr[i] = BN_num_bytes(r[i]);
- n += 2 + nr[i];
- }
+ /* Otherwise, restore |cbb| from the previous iteration.
+ * TODO(davidben): When |ssl->init_buf| is gone, come up with a simpler
+ * pattern. Probably keep the |CBB| around in the handshake state. */
+ } else if (!CBB_did_write(&cbb, ssl->init_num - SSL_HM_HEADER_LENGTH(ssl))) {
+ goto err;
+ }
- if (!BUF_MEM_grow_clean(buf, n + SSL_HM_HEADER_LENGTH(s) + max_sig_len)) {
- OPENSSL_PUT_ERROR(SSL, ERR_LIB_BUF);
+ /* Add a signature. */
+ if (ssl_cipher_has_server_public_key(ssl->s3->tmp.new_cipher)) {
+ if (!ssl_has_private_key(ssl)) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
goto err;
}
- d = p = ssl_handshake_start(s);
-
- for (i = 0; i < 4 && r[i] != NULL; i++) {
- s2n(nr[i], p);
- BN_bn2bin(r[i], p);
- p += nr[i];
- }
- /* Note: ECDHE PSK ciphersuites use SSL_kECDHE and SSL_aPSK. When one of
- * them is used, the server key exchange record needs to have both the
- * psk_identity_hint and the ServerECDHParams. */
- if (alg_a & SSL_aPSK) {
- /* copy PSK identity hint (if provided) */
- s2n(psk_identity_hint_len, p);
- if (psk_identity_hint_len > 0) {
- memcpy(p, psk_identity_hint, psk_identity_hint_len);
- p += psk_identity_hint_len;
+ const size_t max_sig_len = ssl_private_key_max_signature_len(ssl);
+ size_t sig_len;
+ enum ssl_private_key_result_t sign_result;
+ if (ssl->state == SSL3_ST_SW_KEY_EXCH_A) {
+ /* This is the first iteration, so set up the signature. Sample the
+ * parameter length before adding a signature algorithm. */
+ if (!CBB_flush(&cbb)) {
+ goto err;
}
- }
-
- if (alg_k & SSL_kECDHE) {
- /* We only support named (not generic) curves. In this situation, the
- * serverKeyExchange message has:
- * [1 byte CurveType], [2 byte CurveName]
- * [1 byte length of encoded point], followed by
- * the actual encoded point itself. */
- *(p++) = NAMED_CURVE_TYPE;
- *(p++) = (uint8_t)(curve_id >> 8);
- *(p++) = (uint8_t)(curve_id & 0xff);
- *(p++) = encodedlen;
- memcpy(p, encodedPoint, encodedlen);
- p += encodedlen;
- OPENSSL_free(encodedPoint);
- encodedPoint = NULL;
- }
-
- if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) {
- /* n is the length of the params, they start at d and p points to
- * the space at the end. */
- const EVP_MD *md;
- uint8_t digest[EVP_MAX_MD_SIZE];
- unsigned int digest_length;
-
- const int pkey_type = ssl_private_key_type(s);
+ size_t params_len = CBB_len(&cbb);
/* Determine signature algorithm. */
- if (SSL_USE_SIGALGS(s)) {
- md = tls1_choose_signing_digest(s);
- if (!tls12_get_sigandhash(s, p, md)) {
- /* Should never happen */
- al = SSL_AD_INTERNAL_ERROR;
+ const EVP_MD *md;
+ if (SSL_USE_SIGALGS(ssl)) {
+ md = tls1_choose_signing_digest(ssl);
+ if (!tls12_add_sigandhash(ssl, &cbb, md)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- goto f_err;
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ goto err;
}
- p += 2;
- } else if (pkey_type == EVP_PKEY_RSA) {
+ } else if (ssl_private_key_type(ssl) == EVP_PKEY_RSA) {
md = EVP_md5_sha1();
} else {
md = EVP_sha1();
}
- if (!EVP_DigestInit_ex(&md_ctx, md, NULL) ||
- !EVP_DigestUpdate(&md_ctx, s->s3->client_random, SSL3_RANDOM_SIZE) ||
- !EVP_DigestUpdate(&md_ctx, s->s3->server_random, SSL3_RANDOM_SIZE) ||
- !EVP_DigestUpdate(&md_ctx, d, n) ||
- !EVP_DigestFinal_ex(&md_ctx, digest, &digest_length)) {
- OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP);
+ /* Compute the digest and sign it. */
+ uint8_t digest[EVP_MAX_MD_SIZE];
+ unsigned digest_len = 0;
+ EVP_MD_CTX md_ctx;
+ EVP_MD_CTX_init(&md_ctx);
+ int digest_ret =
+ EVP_DigestInit_ex(&md_ctx, md, NULL) &&
+ EVP_DigestUpdate(&md_ctx, ssl->s3->client_random, SSL3_RANDOM_SIZE) &&
+ EVP_DigestUpdate(&md_ctx, ssl->s3->server_random, SSL3_RANDOM_SIZE) &&
+ EVP_DigestUpdate(&md_ctx, CBB_data(&cbb), params_len) &&
+ EVP_DigestFinal_ex(&md_ctx, digest, &digest_len);
+ EVP_MD_CTX_cleanup(&md_ctx);
+ uint8_t *ptr;
+ if (!digest_ret ||
+ !CBB_add_u16_length_prefixed(&cbb, &child) ||
+ !CBB_reserve(&child, &ptr, max_sig_len)) {
goto err;
}
-
- sign_result = ssl_private_key_sign(s, &p[2], &sig_len, max_sig_len,
- EVP_MD_CTX_md(&md_ctx), digest,
- digest_length);
+ sign_result = ssl_private_key_sign(ssl, ptr, &sig_len, max_sig_len, md,
+ digest, digest_len);
} else {
- /* This key exchange doesn't involve a signature. */
- sign_result = ssl_private_key_success;
- sig_len = 0;
+ assert(ssl->state == SSL3_ST_SW_KEY_EXCH_B);
+
+ /* Retry the signature. */
+ uint8_t *ptr;
+ if (!CBB_add_u16_length_prefixed(&cbb, &child) ||
+ !CBB_reserve(&child, &ptr, max_sig_len)) {
+ goto err;
+ }
+ sign_result =
+ ssl_private_key_sign_complete(ssl, ptr, &sig_len, max_sig_len);
}
- } else {
- assert(s->state == SSL3_ST_SW_KEY_EXCH_B);
- /* Restore |p|. */
- p = ssl_handshake_start(s) + s->init_num - SSL_HM_HEADER_LENGTH(s);
- sign_result = ssl_private_key_sign_complete(s, &p[2], &sig_len,
- max_sig_len);
- }
- switch (sign_result) {
- case ssl_private_key_success:
- s->rwstate = SSL_NOTHING;
- break;
- case ssl_private_key_failure:
- s->rwstate = SSL_NOTHING;
- goto err;
- case ssl_private_key_retry:
- s->rwstate = SSL_PRIVATE_KEY_OPERATION;
- /* Stash away |p|. */
- s->init_num = p - ssl_handshake_start(s) + SSL_HM_HEADER_LENGTH(s);
- s->state = SSL3_ST_SW_KEY_EXCH_B;
- goto err;
+ switch (sign_result) {
+ case ssl_private_key_success:
+ ssl->rwstate = SSL_NOTHING;
+ if (!CBB_did_write(&child, sig_len)) {
+ goto err;
+ }
+ break;
+ case ssl_private_key_failure:
+ ssl->rwstate = SSL_NOTHING;
+ goto err;
+ case ssl_private_key_retry:
+ /* Discard the unfinished signature and save the state of |cbb| for the
+ * next iteration. */
+ CBB_discard_child(&cbb);
+ ssl->init_num = SSL_HM_HEADER_LENGTH(ssl) + CBB_len(&cbb);
+ ssl->rwstate = SSL_PRIVATE_KEY_OPERATION;
+ ssl->state = SSL3_ST_SW_KEY_EXCH_B;
+ goto err;
+ }
}
- if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) {
- s2n(sig_len, p);
- p += sig_len;
- }
- if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_KEY_EXCHANGE,
- p - ssl_handshake_start(s))) {
+ size_t length;
+ if (!CBB_finish(&cbb, NULL, &length) ||
+ !ssl_set_handshake_header(ssl, SSL3_MT_SERVER_KEY_EXCHANGE, length)) {
goto err;
}
- s->state = SSL3_ST_SW_KEY_EXCH_C;
-
- EVP_MD_CTX_cleanup(&md_ctx);
- return ssl_do_write(s);
+ ssl->state = SSL3_ST_SW_KEY_EXCH_C;
+ return ssl_do_write(ssl);
-f_err:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
err:
- OPENSSL_free(encodedPoint);
- BN_CTX_free(bn_ctx);
- EVP_MD_CTX_cleanup(&md_ctx);
+ CBB_cleanup(&cbb);
return -1;
}
-int ssl3_send_certificate_request(SSL *s) {
+int ssl3_send_certificate_request(SSL *ssl) {
uint8_t *p, *d;
size_t i;
int j, nl, off, n;
@@ -1516,21 +1393,21 @@ int ssl3_send_certificate_request(SSL *s) {
X509_NAME *name;
BUF_MEM *buf;
- if (s->state == SSL3_ST_SW_CERT_REQ_A) {
- buf = s->init_buf;
+ if (ssl->state == SSL3_ST_SW_CERT_REQ_A) {
+ buf = ssl->init_buf;
- d = p = ssl_handshake_start(s);
+ d = p = ssl_handshake_start(ssl);
/* get the list of acceptable cert types */
p++;
- n = ssl3_get_req_cert_type(s, p);
+ n = ssl3_get_req_cert_type(ssl, p);
d[0] = n;
p += n;
n++;
- if (SSL_USE_SIGALGS(s)) {
+ if (SSL_USE_SIGALGS(ssl)) {
const uint8_t *psigs;
- nl = tls12_get_psigalgs(s, &psigs);
+ nl = tls12_get_psigalgs(ssl, &psigs);
s2n(nl, p);
memcpy(p, psigs, nl);
p += nl;
@@ -1541,17 +1418,17 @@ int ssl3_send_certificate_request(SSL *s) {
p += 2;
n += 2;
- sk = SSL_get_client_CA_list(s);
+ sk = SSL_get_client_CA_list(ssl);
nl = 0;
if (sk != NULL) {
for (i = 0; i < sk_X509_NAME_num(sk); i++) {
name = sk_X509_NAME_value(sk, i);
j = i2d_X509_NAME(name, NULL);
- if (!BUF_MEM_grow_clean(buf, SSL_HM_HEADER_LENGTH(s) + n + j + 2)) {
+ if (!BUF_MEM_grow_clean(buf, SSL_HM_HEADER_LENGTH(ssl) + n + j + 2)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
goto err;
}
- p = ssl_handshake_start(s) + n;
+ p = ssl_handshake_start(ssl) + n;
s2n(j, p);
i2d_X509_NAME(name, &p);
n += 2 + j;
@@ -1560,33 +1437,23 @@ int ssl3_send_certificate_request(SSL *s) {
}
/* else no CA names */
- p = ssl_handshake_start(s) + off;
+ p = ssl_handshake_start(ssl) + off;
s2n(nl, p);
- if (!ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_REQUEST, n)) {
+ if (!ssl_set_handshake_header(ssl, SSL3_MT_CERTIFICATE_REQUEST, n)) {
goto err;
}
- s->state = SSL3_ST_SW_CERT_REQ_B;
+ ssl->state = SSL3_ST_SW_CERT_REQ_B;
}
/* SSL3_ST_SW_CERT_REQ_B */
- return ssl_do_write(s);
+ return ssl_do_write(ssl);
err:
return -1;
}
-static struct CRYPTO_STATIC_MUTEX g_d5_bug_lock = CRYPTO_STATIC_MUTEX_INIT;
-static uint64_t g_d5_bug_use_count = 0;
-
-uint64_t OPENSSL_get_d5_bug_use_count(void) {
- CRYPTO_STATIC_MUTEX_lock_read(&g_d5_bug_lock);
- uint64_t ret = g_d5_bug_use_count;
- CRYPTO_STATIC_MUTEX_unlock(&g_d5_bug_lock);
- return ret;
-}
-
-int ssl3_get_client_key_exchange(SSL *s) {
+int ssl3_get_client_key_exchange(SSL *ssl) {
int al;
CBS client_key_exchange;
uint32_t alg_k;
@@ -1594,30 +1461,24 @@ int ssl3_get_client_key_exchange(SSL *s) {
uint8_t *premaster_secret = NULL;
size_t premaster_secret_len = 0;
uint8_t *decrypt_buf = NULL;
- BIGNUM *pub = NULL;
- DH *dh_srvr;
-
- EC_KEY *srvr_ecdh = NULL;
- EVP_PKEY *clnt_pub_pkey = NULL;
- EC_POINT *clnt_ecpoint = NULL;
- BN_CTX *bn_ctx = NULL;
- unsigned int psk_len = 0;
+
+ unsigned psk_len = 0;
uint8_t psk[PSK_MAX_PSK_LEN];
- if (s->state == SSL3_ST_SR_KEY_EXCH_A ||
- s->state == SSL3_ST_SR_KEY_EXCH_B) {
+ if (ssl->state == SSL3_ST_SR_KEY_EXCH_A ||
+ ssl->state == SSL3_ST_SR_KEY_EXCH_B) {
int ok;
- const long n = s->method->ssl_get_message(
- s, SSL3_ST_SR_KEY_EXCH_A, SSL3_ST_SR_KEY_EXCH_B,
+ const long n = ssl->method->ssl_get_message(
+ ssl, SSL3_ST_SR_KEY_EXCH_A, SSL3_ST_SR_KEY_EXCH_B,
SSL3_MT_CLIENT_KEY_EXCHANGE, 2048 /* ??? */, ssl_hash_message, &ok);
if (!ok) {
return n;
}
}
- CBS_init(&client_key_exchange, s->init_msg, s->init_num);
- alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
- alg_a = s->s3->tmp.new_cipher->algorithm_auth;
+ CBS_init(&client_key_exchange, ssl->init_msg, ssl->init_num);
+ alg_k = ssl->s3->tmp.new_cipher->algorithm_mkey;
+ alg_a = ssl->s3->tmp.new_cipher->algorithm_auth;
/* If using a PSK key exchange, prepare the pre-shared key. */
if (alg_a & SSL_aPSK) {
@@ -1632,7 +1493,7 @@ int ssl3_get_client_key_exchange(SSL *s) {
goto f_err;
}
- if (s->psk_server_callback == NULL) {
+ if (ssl->psk_server_callback == NULL) {
OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_NO_SERVER_CB);
al = SSL_AD_INTERNAL_ERROR;
goto f_err;
@@ -1645,15 +1506,15 @@ int ssl3_get_client_key_exchange(SSL *s) {
goto f_err;
}
- if (!CBS_strdup(&psk_identity, &s->session->psk_identity)) {
+ if (!CBS_strdup(&psk_identity, &ssl->session->psk_identity)) {
al = SSL_AD_INTERNAL_ERROR;
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto f_err;
}
/* Look up the key for the identity. */
- psk_len =
- s->psk_server_callback(s, s->session->psk_identity, psk, sizeof(psk));
+ psk_len = ssl->psk_server_callback(ssl, ssl->session->psk_identity, psk,
+ sizeof(psk));
if (psk_len > PSK_MAX_PSK_LEN) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
al = SSL_AD_INTERNAL_ERROR;
@@ -1669,13 +1530,8 @@ int ssl3_get_client_key_exchange(SSL *s) {
/* Depending on the key exchange method, compute |premaster_secret| and
* |premaster_secret_len|. */
if (alg_k & SSL_kRSA) {
- CBS encrypted_premaster_secret;
- uint8_t rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH];
- uint8_t good;
- size_t decrypt_len, premaster_index, j;
- const size_t rsa_size = ssl_private_key_max_signature_len(s);
-
/* Allocate a buffer large enough for an RSA decryption. */
+ const size_t rsa_size = ssl_private_key_max_signature_len(ssl);
decrypt_buf = OPENSSL_malloc(rsa_size);
if (decrypt_buf == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
@@ -1683,265 +1539,131 @@ int ssl3_get_client_key_exchange(SSL *s) {
}
enum ssl_private_key_result_t decrypt_result;
- if (s->state == SSL3_ST_SR_KEY_EXCH_B) {
- if (!ssl_has_private_key(s) || ssl_private_key_type(s) != EVP_PKEY_RSA) {
+ size_t decrypt_len;
+ if (ssl->state == SSL3_ST_SR_KEY_EXCH_B) {
+ if (!ssl_has_private_key(ssl) ||
+ ssl_private_key_type(ssl) != EVP_PKEY_RSA) {
al = SSL_AD_HANDSHAKE_FAILURE;
OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_RSA_CERTIFICATE);
goto f_err;
}
- /* TLS and [incidentally] DTLS{0xFEFF} */
- if (s->version > SSL3_VERSION) {
- CBS copy = client_key_exchange;
+ CBS encrypted_premaster_secret;
+ if (ssl->version > SSL3_VERSION) {
if (!CBS_get_u16_length_prefixed(&client_key_exchange,
&encrypted_premaster_secret) ||
CBS_len(&client_key_exchange) != 0) {
- if (!(s->options & SSL_OP_TLS_D5_BUG)) {
- al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL,
- SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
- goto f_err;
- } else {
- CRYPTO_STATIC_MUTEX_lock_write(&g_d5_bug_lock);
- g_d5_bug_use_count++;
- CRYPTO_STATIC_MUTEX_unlock(&g_d5_bug_lock);
-
- encrypted_premaster_secret = copy;
- }
+ al = SSL_AD_DECODE_ERROR;
+ OPENSSL_PUT_ERROR(SSL,
+ SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
+ goto f_err;
}
} else {
encrypted_premaster_secret = client_key_exchange;
}
- /* Reject overly short RSA keys because we want to be sure that the buffer
- * size makes it safe to iterate over the entire size of a premaster
- * secret (SSL_MAX_MASTER_KEY_LENGTH). The actual expected size is larger
- * due to RSA padding, but the bound is sufficient to be safe. */
- if (rsa_size < SSL_MAX_MASTER_KEY_LENGTH) {
- al = SSL_AD_DECRYPT_ERROR;
- OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED);
- goto f_err;
- }
-
/* Decrypt with no padding. PKCS#1 padding will be removed as part of the
* timing-sensitive code below. */
decrypt_result = ssl_private_key_decrypt(
- s, decrypt_buf, &decrypt_len, rsa_size,
+ ssl, decrypt_buf, &decrypt_len, rsa_size,
CBS_data(&encrypted_premaster_secret),
CBS_len(&encrypted_premaster_secret));
} else {
- assert(s->state == SSL3_ST_SR_KEY_EXCH_C);
+ assert(ssl->state == SSL3_ST_SR_KEY_EXCH_C);
/* Complete async decrypt. */
decrypt_result = ssl_private_key_decrypt_complete(
- s, decrypt_buf, &decrypt_len, rsa_size);
+ ssl, decrypt_buf, &decrypt_len, rsa_size);
}
switch (decrypt_result) {
case ssl_private_key_success:
- s->rwstate = SSL_NOTHING;
+ ssl->rwstate = SSL_NOTHING;
break;
case ssl_private_key_failure:
- s->rwstate = SSL_NOTHING;
+ ssl->rwstate = SSL_NOTHING;
goto err;
case ssl_private_key_retry:
- s->rwstate = SSL_PRIVATE_KEY_OPERATION;
- s->state = SSL3_ST_SR_KEY_EXCH_C;
+ ssl->rwstate = SSL_PRIVATE_KEY_OPERATION;
+ ssl->state = SSL3_ST_SR_KEY_EXCH_C;
goto err;
}
- if (decrypt_len != rsa_size) {
- /* This should never happen, but do a check so we do not read
- * uninitialized memory. */
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- goto err;
- }
+ assert(decrypt_len == rsa_size);
- /* Remove the PKCS#1 padding and adjust |decrypt_len| as appropriate.
- * |good| will be 0xff if the premaster is acceptable and zero otherwise.
- * */
- good =
- constant_time_eq_int_8(RSA_message_index_PKCS1_type_2(
- decrypt_buf, decrypt_len, &premaster_index),
- 1);
- decrypt_len = decrypt_len - premaster_index;
-
- /* decrypt_len should be SSL_MAX_MASTER_KEY_LENGTH. */
- good &= constant_time_eq_8(decrypt_len, SSL_MAX_MASTER_KEY_LENGTH);
-
- /* Copy over the unpadded premaster. Whatever the value of
- * |decrypt_good_mask|, copy as if the premaster were the right length. It
- * is important the memory access pattern be constant. */
- premaster_secret =
- BUF_memdup(decrypt_buf + (rsa_size - SSL_MAX_MASTER_KEY_LENGTH),
- SSL_MAX_MASTER_KEY_LENGTH);
+ /* Prepare a random premaster, to be used on invalid padding. See RFC 5246,
+ * section 7.4.7.1. */
+ premaster_secret_len = SSL_MAX_MASTER_KEY_LENGTH;
+ premaster_secret = OPENSSL_malloc(premaster_secret_len);
if (premaster_secret == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
- OPENSSL_free(decrypt_buf);
- decrypt_buf = NULL;
-
- /* 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. */
- good &= constant_time_eq_8(premaster_secret[0],
- (unsigned)(s->client_version >> 8));
- good &= constant_time_eq_8(premaster_secret[1],
- (unsigned)(s->client_version & 0xff));
-
- /* 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 */
- if (!RAND_bytes(rand_premaster_secret, sizeof(rand_premaster_secret))) {
+ if (!RAND_bytes(premaster_secret, premaster_secret_len)) {
goto err;
}
- /* Now copy rand_premaster_secret over premaster_secret using
- * decrypt_good_mask. */
- for (j = 0; j < sizeof(rand_premaster_secret); j++) {
- premaster_secret[j] = constant_time_select_8(good, premaster_secret[j],
- rand_premaster_secret[j]);
- }
-
- premaster_secret_len = sizeof(rand_premaster_secret);
- } else if (alg_k & SSL_kDHE) {
- CBS dh_Yc;
- int dh_len;
-
- if (!CBS_get_u16_length_prefixed(&client_key_exchange, &dh_Yc) ||
- CBS_len(&dh_Yc) == 0 || CBS_len(&client_key_exchange) != 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG);
- al = SSL_R_DECODE_ERROR;
- goto f_err;
- }
-
- if (s->s3->tmp.dh == NULL) {
- al = SSL_AD_HANDSHAKE_FAILURE;
- OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_TMP_DH_KEY);
+ /* The smallest padded premaster is 11 bytes of overhead. Small keys are
+ * publicly invalid. */
+ if (decrypt_len < 11 + premaster_secret_len) {
+ al = SSL_AD_DECRYPT_ERROR;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED);
goto f_err;
}
- dh_srvr = s->s3->tmp.dh;
-
- pub = BN_bin2bn(CBS_data(&dh_Yc), CBS_len(&dh_Yc), NULL);
- if (pub == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_BN_LIB);
- goto err;
- }
-
- /* Allocate a buffer for the premaster secret. */
- premaster_secret = OPENSSL_malloc(DH_size(dh_srvr));
- if (premaster_secret == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- BN_clear_free(pub);
- goto err;
- }
-
- dh_len = DH_compute_key(premaster_secret, pub, dh_srvr);
- if (dh_len <= 0) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
- BN_clear_free(pub);
- goto err;
- }
-
- DH_free(s->s3->tmp.dh);
- s->s3->tmp.dh = NULL;
- BN_clear_free(pub);
- pub = NULL;
- premaster_secret_len = dh_len;
- } else if (alg_k & SSL_kECDHE) {
- int ecdh_len;
- const EC_KEY *tkey;
- const EC_GROUP *group;
- const BIGNUM *priv_key;
- CBS ecdh_Yc;
-
- /* initialize structures for server's ECDH key pair */
- srvr_ecdh = EC_KEY_new();
- if (srvr_ecdh == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- goto err;
+ /* Check the padding. See RFC 3447, section 7.2.2. */
+ size_t padding_len = decrypt_len - premaster_secret_len;
+ uint8_t good = constant_time_eq_int_8(decrypt_buf[0], 0) &
+ constant_time_eq_int_8(decrypt_buf[1], 2);
+ size_t i;
+ for (i = 2; i < padding_len - 1; i++) {
+ good &= ~constant_time_is_zero_8(decrypt_buf[i]);
}
+ good &= constant_time_is_zero_8(decrypt_buf[padding_len - 1]);
- /* Use the ephermeral values we saved when generating the ServerKeyExchange
- * msg. */
- tkey = s->s3->tmp.ecdh;
+ /* The premaster secret must begin with |client_version|. This too must be
+ * checked in constant time (http://eprint.iacr.org/2003/052/). */
+ good &= constant_time_eq_8(decrypt_buf[padding_len],
+ (unsigned)(ssl->client_version >> 8));
+ good &= constant_time_eq_8(decrypt_buf[padding_len + 1],
+ (unsigned)(ssl->client_version & 0xff));
- group = EC_KEY_get0_group(tkey);
- priv_key = EC_KEY_get0_private_key(tkey);
-
- if (!EC_KEY_set_group(srvr_ecdh, group) ||
- !EC_KEY_set_private_key(srvr_ecdh, priv_key)) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_EC_LIB);
- goto err;
+ /* Select, in constant time, either the decrypted premaster or the random
+ * premaster based on |good|. */
+ for (i = 0; i < premaster_secret_len; i++) {
+ premaster_secret[i] = constant_time_select_8(
+ good, decrypt_buf[padding_len + i], premaster_secret[i]);
}
- /* Let's get client's public key */
- clnt_ecpoint = EC_POINT_new(group);
- if (clnt_ecpoint == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- goto err;
+ OPENSSL_free(decrypt_buf);
+ decrypt_buf = NULL;
+ } else if (alg_k & (SSL_kECDHE|SSL_kDHE)) {
+ /* Parse the ClientKeyExchange. ECDHE uses a u8 length prefix while DHE uses
+ * u16. */
+ CBS peer_key;
+ int peer_key_ok;
+ if (alg_k & SSL_kECDHE) {
+ peer_key_ok = CBS_get_u8_length_prefixed(&client_key_exchange, &peer_key);
+ } else {
+ peer_key_ok =
+ CBS_get_u16_length_prefixed(&client_key_exchange, &peer_key);
}
- /* Get client's public key from encoded point in the ClientKeyExchange
- * message. */
- if (!CBS_get_u8_length_prefixed(&client_key_exchange, &ecdh_Yc) ||
- CBS_len(&client_key_exchange) != 0) {
+ if (!peer_key_ok || CBS_len(&client_key_exchange) != 0) {
al = SSL_AD_DECODE_ERROR;
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
- bn_ctx = BN_CTX_new();
- if (bn_ctx == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- if (!EC_POINT_oct2point(group, clnt_ecpoint, CBS_data(&ecdh_Yc),
- CBS_len(&ecdh_Yc), bn_ctx)) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_EC_LIB);
- goto err;
- }
-
- /* Allocate a buffer for both the secret and the PSK. */
- unsigned field_size = EC_GROUP_get_degree(group);
- if (field_size == 0) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB);
- goto err;
- }
-
- ecdh_len = (field_size + 7) / 8;
- premaster_secret = OPENSSL_malloc(ecdh_len);
- if (premaster_secret == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- /* Compute the shared pre-master secret */
- ecdh_len = ECDH_compute_key(premaster_secret, ecdh_len, clnt_ecpoint,
- srvr_ecdh, NULL);
- if (ecdh_len <= 0) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB);
- goto err;
+ /* Compute the premaster. */
+ uint8_t alert;
+ if (!SSL_ECDH_CTX_compute_secret(&ssl->s3->tmp.ecdh_ctx, &premaster_secret,
+ &premaster_secret_len, &alert,
+ CBS_data(&peer_key), CBS_len(&peer_key))) {
+ al = alert;
+ goto f_err;
}
- EVP_PKEY_free(clnt_pub_pkey);
- clnt_pub_pkey = NULL;
- EC_POINT_free(clnt_ecpoint);
- clnt_ecpoint = NULL;
- EC_KEY_free(srvr_ecdh);
- srvr_ecdh = NULL;
- BN_CTX_free(bn_ctx);
- bn_ctx = NULL;
- EC_KEY_free(s->s3->tmp.ecdh);
- s->s3->tmp.ecdh = NULL;
-
- premaster_secret_len = ecdh_len;
+ /* The key exchange state may now be discarded. */
+ SSL_ECDH_CTX_cleanup(&ssl->s3->tmp.ecdh_ctx);
} else if (alg_k & SSL_kPSK) {
/* For plain PSK, other_secret is a block of 0s with the same length as the
* pre-shared key. */
@@ -1984,40 +1706,34 @@ int ssl3_get_client_key_exchange(SSL *s) {
}
/* Compute the master secret */
- s->session->master_key_length = s->enc_method->generate_master_secret(
- s, s->session->master_key, premaster_secret, premaster_secret_len);
- if (s->session->master_key_length == 0) {
+ ssl->session->master_key_length = ssl->enc_method->generate_master_secret(
+ ssl, ssl->session->master_key, premaster_secret, premaster_secret_len);
+ if (ssl->session->master_key_length == 0) {
goto err;
}
- s->session->extended_master_secret = s->s3->tmp.extended_master_secret;
+ ssl->session->extended_master_secret = ssl->s3->tmp.extended_master_secret;
OPENSSL_cleanse(premaster_secret, premaster_secret_len);
OPENSSL_free(premaster_secret);
return 1;
f_err:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
err:
- if (premaster_secret) {
- if (premaster_secret_len) {
- OPENSSL_cleanse(premaster_secret, premaster_secret_len);
- }
+ if (premaster_secret != NULL) {
+ OPENSSL_cleanse(premaster_secret, premaster_secret_len);
OPENSSL_free(premaster_secret);
}
OPENSSL_free(decrypt_buf);
- EVP_PKEY_free(clnt_pub_pkey);
- EC_POINT_free(clnt_ecpoint);
- EC_KEY_free(srvr_ecdh);
- BN_CTX_free(bn_ctx);
return -1;
}
-int ssl3_get_cert_verify(SSL *s) {
+int ssl3_get_cert_verify(SSL *ssl) {
int al, ok, ret = 0;
long n;
CBS certificate_verify, signature;
- X509 *peer = s->session->peer;
+ X509 *peer = ssl->session->peer;
EVP_PKEY *pkey = NULL;
const EVP_MD *md = NULL;
uint8_t digest[EVP_MAX_MD_SIZE];
@@ -2028,12 +1744,12 @@ int ssl3_get_cert_verify(SSL *s) {
* CertificateVerify is required if and only if there's a client certificate.
* */
if (peer == NULL) {
- ssl3_free_handshake_buffer(s);
+ ssl3_free_handshake_buffer(ssl);
return 1;
}
- n = s->method->ssl_get_message(
- s, SSL3_ST_SR_CERT_VRFY_A, SSL3_ST_SR_CERT_VRFY_B,
+ n = ssl->method->ssl_get_message(
+ ssl, SSL3_ST_SR_CERT_VRFY_A, SSL3_ST_SR_CERT_VRFY_B,
SSL3_MT_CERTIFICATE_VERIFY, SSL3_RT_MAX_PLAIN_LENGTH,
ssl_dont_hash_message, &ok);
@@ -2053,10 +1769,10 @@ int ssl3_get_cert_verify(SSL *s) {
goto f_err;
}
- CBS_init(&certificate_verify, s->init_msg, n);
+ CBS_init(&certificate_verify, ssl->init_msg, n);
/* Determine the digest type if needbe. */
- if (SSL_USE_SIGALGS(s)) {
+ if (SSL_USE_SIGALGS(ssl)) {
uint8_t hash, signature_type;
if (!CBS_get_u8(&certificate_verify, &hash) ||
!CBS_get_u8(&certificate_verify, &signature_type)) {
@@ -2064,20 +1780,20 @@ int ssl3_get_cert_verify(SSL *s) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
- if (!tls12_check_peer_sigalg(s, &md, &al, hash, signature_type, pkey)) {
+ if (!tls12_check_peer_sigalg(ssl, &md, &al, hash, signature_type, pkey)) {
goto f_err;
}
}
/* Compute the digest. */
- if (!ssl3_cert_verify_hash(s, digest, &digest_length, &md, pkey->type)) {
+ if (!ssl3_cert_verify_hash(ssl, digest, &digest_length, &md, pkey->type)) {
goto err;
}
/* The handshake buffer is no longer necessary, and we may hash the current
* message.*/
- ssl3_free_handshake_buffer(s);
- if (!ssl3_hash_current_message(s)) {
+ ssl3_free_handshake_buffer(ssl);
+ if (!ssl3_hash_current_message(ssl)) {
goto err;
}
@@ -2106,7 +1822,7 @@ int ssl3_get_cert_verify(SSL *s) {
if (0) {
f_err:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
}
err:
@@ -2116,7 +1832,7 @@ err:
return ret;
}
-int ssl3_get_client_certificate(SSL *s) {
+int ssl3_get_client_certificate(SSL *ssl) {
int i, ok, al, ret = -1;
X509 *x = NULL;
unsigned long n;
@@ -2125,40 +1841,41 @@ int ssl3_get_client_certificate(SSL *s) {
CBS certificate_msg, certificate_list;
int is_first_certificate = 1;
- n = s->method->ssl_get_message(s, SSL3_ST_SR_CERT_A, SSL3_ST_SR_CERT_B, -1,
- (long)s->max_cert_list, ssl_hash_message, &ok);
+ n = ssl->method->ssl_get_message(ssl, SSL3_ST_SR_CERT_A, SSL3_ST_SR_CERT_B,
+ -1, (long)ssl->max_cert_list,
+ ssl_hash_message, &ok);
if (!ok) {
return n;
}
- if (s->s3->tmp.message_type == SSL3_MT_CLIENT_KEY_EXCHANGE) {
- if ((s->verify_mode & SSL_VERIFY_PEER) &&
- (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) {
+ if (ssl->s3->tmp.message_type == SSL3_MT_CLIENT_KEY_EXCHANGE) {
+ if ((ssl->verify_mode & SSL_VERIFY_PEER) &&
+ (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
al = SSL_AD_HANDSHAKE_FAILURE;
goto f_err;
}
/* If tls asked for a client cert, the client must return a 0 list */
- if (s->version > SSL3_VERSION && s->s3->tmp.cert_request) {
+ if (ssl->version > SSL3_VERSION && ssl->s3->tmp.cert_request) {
OPENSSL_PUT_ERROR(SSL,
SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST);
al = SSL_AD_UNEXPECTED_MESSAGE;
goto f_err;
}
- s->s3->tmp.reuse_message = 1;
+ ssl->s3->tmp.reuse_message = 1;
return 1;
}
- if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE) {
+ if (ssl->s3->tmp.message_type != SSL3_MT_CERTIFICATE) {
al = SSL_AD_UNEXPECTED_MESSAGE;
OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_MESSAGE_TYPE);
goto f_err;
}
- CBS_init(&certificate_msg, s->init_msg, n);
+ CBS_init(&certificate_msg, ssl->init_msg, n);
sk = sk_X509_new_null();
if (sk == NULL) {
@@ -2183,18 +1900,19 @@ int ssl3_get_client_certificate(SSL *s) {
goto f_err;
}
- if (is_first_certificate && s->ctx->retain_only_sha256_of_client_certs) {
+ if (is_first_certificate && ssl->ctx->retain_only_sha256_of_client_certs) {
/* If this is the first certificate, and we don't want to keep peer
* certificates in memory, then we hash it right away. */
SHA256_Init(&sha256);
SHA256_Update(&sha256, CBS_data(&certificate), CBS_len(&certificate));
- SHA256_Final(s->session->peer_sha256, &sha256);
- s->session->peer_sha256_valid = 1;
+ SHA256_Final(ssl->session->peer_sha256, &sha256);
+ ssl->session->peer_sha256_valid = 1;
}
is_first_certificate = 0;
+ /* A u24 length cannot overflow a long. */
data = CBS_data(&certificate);
- x = d2i_X509(NULL, &data, CBS_len(&certificate));
+ x = d2i_X509(NULL, &data, (long)CBS_len(&certificate));
if (x == NULL) {
al = SSL_AD_BAD_CERTIFICATE;
OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
@@ -2214,35 +1932,35 @@ int ssl3_get_client_certificate(SSL *s) {
if (sk_X509_num(sk) <= 0) {
/* No client certificate so the handshake buffer may be discarded. */
- ssl3_free_handshake_buffer(s);
+ ssl3_free_handshake_buffer(ssl);
/* TLS does not mind 0 certs returned */
- if (s->version == SSL3_VERSION) {
+ if (ssl->version == SSL3_VERSION) {
al = SSL_AD_HANDSHAKE_FAILURE;
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATES_RETURNED);
goto f_err;
- } else if ((s->verify_mode & SSL_VERIFY_PEER) &&
- (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) {
+ } else if ((ssl->verify_mode & SSL_VERIFY_PEER) &&
+ (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) {
/* Fail for TLS only if we required a certificate */
OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
al = SSL_AD_HANDSHAKE_FAILURE;
goto f_err;
}
} else {
- i = ssl_verify_cert_chain(s, sk);
+ i = ssl_verify_cert_chain(ssl, sk);
if (i <= 0) {
- al = ssl_verify_alarm_type(s->verify_result);
+ al = ssl_verify_alarm_type(ssl->verify_result);
OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_VERIFY_FAILED);
goto f_err;
}
}
- X509_free(s->session->peer);
- s->session->peer = sk_X509_shift(sk);
- s->session->verify_result = s->verify_result;
+ X509_free(ssl->session->peer);
+ ssl->session->peer = sk_X509_shift(sk);
+ ssl->session->verify_result = ssl->verify_result;
- sk_X509_pop_free(s->session->cert_chain, X509_free);
- s->session->cert_chain = sk;
+ sk_X509_pop_free(ssl->session->cert_chain, X509_free);
+ ssl->session->cert_chain = sk;
/* Inconsistency alert: cert_chain does *not* include the peer's own
* certificate, while we do include it in s3_clnt.c */
@@ -2252,7 +1970,7 @@ int ssl3_get_client_certificate(SSL *s) {
if (0) {
f_err:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
}
err:
@@ -2261,20 +1979,20 @@ err:
return ret;
}
-int ssl3_send_server_certificate(SSL *s) {
- if (s->state == SSL3_ST_SW_CERT_A) {
- if (!ssl3_output_cert_chain(s)) {
+int ssl3_send_server_certificate(SSL *ssl) {
+ if (ssl->state == SSL3_ST_SW_CERT_A) {
+ if (!ssl3_output_cert_chain(ssl)) {
return 0;
}
- s->state = SSL3_ST_SW_CERT_B;
+ ssl->state = SSL3_ST_SW_CERT_B;
}
/* SSL3_ST_SW_CERT_B */
- return ssl_do_write(s);
+ return ssl_do_write(ssl);
}
/* send a new session ticket (not necessarily for a new session) */
-int ssl3_send_new_session_ticket(SSL *s) {
+int ssl3_send_new_session_ticket(SSL *ssl) {
int ret = -1;
uint8_t *session = NULL;
size_t session_len;
@@ -2284,11 +2002,11 @@ int ssl3_send_new_session_ticket(SSL *s) {
EVP_CIPHER_CTX_init(&ctx);
HMAC_CTX_init(&hctx);
- if (s->state == SSL3_ST_SW_SESSION_TICKET_A) {
+ if (ssl->state == SSL3_ST_SW_SESSION_TICKET_A) {
uint8_t *p, *macstart;
int len;
unsigned int hlen;
- SSL_CTX *tctx = s->initial_ctx;
+ SSL_CTX *tctx = ssl->initial_ctx;
uint8_t iv[EVP_MAX_IV_LENGTH];
uint8_t key_name[16];
/* The maximum overhead of encrypting the session is 16 (key name) + IV +
@@ -2297,7 +2015,8 @@ int ssl3_send_new_session_ticket(SSL *s) {
16 + EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE;
/* Serialize the SSL_SESSION to be encoded into the ticket. */
- if (!SSL_SESSION_to_bytes_for_ticket(s->session, &session, &session_len)) {
+ if (!SSL_SESSION_to_bytes_for_ticket(ssl->session, &session,
+ &session_len)) {
goto err;
}
@@ -2310,7 +2029,7 @@ int ssl3_send_new_session_ticket(SSL *s) {
OPENSSL_free(session);
session = NULL;
- p = ssl_handshake_start(s);
+ p = ssl_handshake_start(ssl);
/* Emit ticket_lifetime_hint. */
l2n(0, p);
/* Emit ticket. */
@@ -2318,26 +2037,26 @@ int ssl3_send_new_session_ticket(SSL *s) {
memcpy(p, kTicketPlaceholder, placeholder_len);
p += placeholder_len;
- len = p - ssl_handshake_start(s);
- if (!ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, len)) {
+ len = p - ssl_handshake_start(ssl);
+ if (!ssl_set_handshake_header(ssl, SSL3_MT_NEWSESSION_TICKET, len)) {
goto err;
}
- s->state = SSL3_ST_SW_SESSION_TICKET_B;
- return ssl_do_write(s);
+ ssl->state = SSL3_ST_SW_SESSION_TICKET_B;
+ return ssl_do_write(ssl);
}
/* Grow buffer if need be: the length calculation is as follows:
* handshake_header_length + 4 (ticket lifetime hint) + 2 (ticket length) +
* max_ticket_overhead + * session_length */
- if (!BUF_MEM_grow(s->init_buf, SSL_HM_HEADER_LENGTH(s) + 6 +
+ if (!BUF_MEM_grow(ssl->init_buf, SSL_HM_HEADER_LENGTH(ssl) + 6 +
max_ticket_overhead + session_len)) {
goto err;
}
- p = ssl_handshake_start(s);
+ p = ssl_handshake_start(ssl);
/* Initialize HMAC and cipher contexts. If callback present it does all the
* work otherwise use generated values from parent ctx. */
if (tctx->tlsext_ticket_key_cb) {
- if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx, &hctx,
+ if (tctx->tlsext_ticket_key_cb(ssl, key_name, iv, &ctx, &hctx,
1 /* encrypt */) < 0) {
goto err;
}
@@ -2355,7 +2074,7 @@ int ssl3_send_new_session_ticket(SSL *s) {
/* Ticket lifetime hint (advisory only): We leave this unspecified for
* resumed session (for simplicity), and guess that tickets for new
* sessions will live as long as their sessions. */
- l2n(s->hit ? 0 : s->session->timeout, p);
+ l2n(ssl->hit ? 0 : ssl->session->timeout, p);
/* Skip ticket length for now */
p += 2;
@@ -2384,18 +2103,18 @@ int ssl3_send_new_session_ticket(SSL *s) {
p += hlen;
/* Now write out lengths: p points to end of data written */
/* Total length */
- len = p - ssl_handshake_start(s);
+ len = p - ssl_handshake_start(ssl);
/* Skip ticket lifetime hint */
- p = ssl_handshake_start(s) + 4;
+ p = ssl_handshake_start(ssl) + 4;
s2n(len - 6, p);
- if (!ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, len)) {
+ if (!ssl_set_handshake_header(ssl, SSL3_MT_NEWSESSION_TICKET, len)) {
goto err;
}
- s->state = SSL3_ST_SW_SESSION_TICKET_B;
+ ssl->state = SSL3_ST_SW_SESSION_TICKET_B;
}
/* SSL3_ST_SW_SESSION_TICKET_B */
- ret = ssl_do_write(s);
+ ret = ssl_do_write(ssl);
err:
OPENSSL_free(session);
@@ -2406,19 +2125,19 @@ err:
/* ssl3_get_next_proto reads a Next Protocol Negotiation handshake message. It
* sets the next_proto member in s if found */
-int ssl3_get_next_proto(SSL *s) {
+int ssl3_get_next_proto(SSL *ssl) {
int ok;
long n;
CBS next_protocol, selected_protocol, padding;
/* Clients cannot send a NextProtocol message if we didn't see the extension
* in their ClientHello */
- if (!s->s3->next_proto_neg_seen) {
+ if (!ssl->s3->next_proto_neg_seen) {
OPENSSL_PUT_ERROR(SSL, SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION);
return -1;
}
- n = s->method->ssl_get_message(s, SSL3_ST_SR_NEXT_PROTO_A,
+ n = ssl->method->ssl_get_message(ssl, SSL3_ST_SR_NEXT_PROTO_A,
SSL3_ST_SR_NEXT_PROTO_B, SSL3_MT_NEXT_PROTO,
514, /* See the payload format below */
ssl_hash_message, &ok);
@@ -2427,18 +2146,7 @@ int ssl3_get_next_proto(SSL *s) {
return n;
}
- /* s->state doesn't reflect whether ChangeCipherSpec has been received in
- * this handshake, but s->s3->change_cipher_spec does (will be reset by
- * ssl3_get_finished).
- *
- * TODO(davidben): Is this check now redundant with
- * SSL3_FLAGS_EXPECT_CCS? */
- if (!s->s3->change_cipher_spec) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS);
- return -1;
- }
-
- CBS_init(&next_protocol, s->init_msg, n);
+ CBS_init(&next_protocol, ssl->init_msg, n);
/* The payload looks like:
* uint8 proto_len;
@@ -2448,8 +2156,8 @@ int ssl3_get_next_proto(SSL *s) {
if (!CBS_get_u8_length_prefixed(&next_protocol, &selected_protocol) ||
!CBS_get_u8_length_prefixed(&next_protocol, &padding) ||
CBS_len(&next_protocol) != 0 ||
- !CBS_stow(&selected_protocol, &s->next_proto_negotiated,
- &s->next_proto_negotiated_len)) {
+ !CBS_stow(&selected_protocol, &ssl->next_proto_negotiated,
+ &ssl->next_proto_negotiated_len)) {
return 0;
}
@@ -2457,7 +2165,7 @@ int ssl3_get_next_proto(SSL *s) {
}
/* ssl3_get_channel_id reads and verifies a ClientID handshake message. */
-int ssl3_get_channel_id(SSL *s) {
+int ssl3_get_channel_id(SSL *ssl) {
int ret = -1, ok;
long n;
uint8_t channel_id_hash[EVP_MAX_MD_SIZE];
@@ -2471,8 +2179,8 @@ int ssl3_get_channel_id(SSL *s) {
BIGNUM x, y;
CBS encrypted_extensions, extension;
- n = s->method->ssl_get_message(
- s, SSL3_ST_SR_CHANNEL_ID_A, SSL3_ST_SR_CHANNEL_ID_B,
+ n = ssl->method->ssl_get_message(
+ ssl, SSL3_ST_SR_CHANNEL_ID_A, SSL3_ST_SR_CHANNEL_ID_B,
SSL3_MT_ENCRYPTED_EXTENSIONS, 2 + 2 + TLSEXT_CHANNEL_ID_SIZE,
ssl_dont_hash_message, &ok);
@@ -2482,26 +2190,16 @@ int ssl3_get_channel_id(SSL *s) {
/* Before incorporating the EncryptedExtensions message to the handshake
* hash, compute the hash that should have been signed. */
- if (!tls1_channel_id_hash(s, channel_id_hash, &channel_id_hash_len)) {
+ if (!tls1_channel_id_hash(ssl, channel_id_hash, &channel_id_hash_len)) {
return -1;
}
assert(channel_id_hash_len == SHA256_DIGEST_LENGTH);
- if (!ssl3_hash_current_message(s)) {
+ if (!ssl3_hash_current_message(ssl)) {
return -1;
}
- /* s->state doesn't reflect whether ChangeCipherSpec has been received in
- * this handshake, but s->s3->change_cipher_spec does (will be reset by
- * ssl3_get_finished).
- *
- * TODO(davidben): Is this check now redundant with SSL3_FLAGS_EXPECT_CCS? */
- if (!s->s3->change_cipher_spec) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_GOT_CHANNEL_ID_BEFORE_A_CCS);
- return -1;
- }
-
- CBS_init(&encrypted_extensions, s->init_msg, n);
+ CBS_init(&encrypted_extensions, ssl->init_msg, n);
/* EncryptedExtensions could include multiple extensions, but the only
* extension that could be negotiated is ChannelID, so there can only be one
@@ -2547,7 +2245,8 @@ int ssl3_get_channel_id(SSL *s) {
}
point = EC_POINT_new(p256);
- if (!point || !EC_POINT_set_affine_coordinates_GFp(p256, point, &x, &y, NULL)) {
+ if (!point ||
+ !EC_POINT_set_affine_coordinates_GFp(p256, point, &x, &y, NULL)) {
goto err;
}
@@ -2561,11 +2260,11 @@ int ssl3_get_channel_id(SSL *s) {
* were called. */
if (!ECDSA_do_verify(channel_id_hash, channel_id_hash_len, &sig, key)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_SIGNATURE_INVALID);
- s->s3->tlsext_channel_id_valid = 0;
+ ssl->s3->tlsext_channel_id_valid = 0;
goto err;
}
- memcpy(s->s3->tlsext_channel_id, p, 64);
+ memcpy(ssl->s3->tlsext_channel_id, p, 64);
ret = 1;
err:
diff --git a/src/ssl/ssl_aead_ctx.c b/src/ssl/ssl_aead_ctx.c
index f9001c7..8829679 100644
--- a/src/ssl/ssl_aead_ctx.c
+++ b/src/ssl/ssl_aead_ctx.c
@@ -74,17 +74,20 @@ SSL_AEAD_CTX *SSL_AEAD_CTX_new(enum evp_aead_direction_t direction,
assert(EVP_AEAD_nonce_length(aead) <= EVP_AEAD_MAX_NONCE_LENGTH);
aead_ctx->variable_nonce_len = (uint8_t)EVP_AEAD_nonce_length(aead);
if (mac_key_len == 0) {
- /* For a real AEAD, the IV is the fixed part of the nonce. */
- if (fixed_iv_len > sizeof(aead_ctx->fixed_nonce) ||
- fixed_iv_len > aead_ctx->variable_nonce_len) {
- SSL_AEAD_CTX_free(aead_ctx);
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return 0;
- }
- aead_ctx->variable_nonce_len -= fixed_iv_len;
-
+ assert(fixed_iv_len <= sizeof(aead_ctx->fixed_nonce));
memcpy(aead_ctx->fixed_nonce, fixed_iv, fixed_iv_len);
aead_ctx->fixed_nonce_len = fixed_iv_len;
+
+ if (cipher->algorithm_enc & SSL_CHACHA20POLY1305) {
+ /* The fixed nonce into the actual nonce (the sequence number). */
+ aead_ctx->xor_fixed_nonce = 1;
+ aead_ctx->variable_nonce_len = 8;
+ } else {
+ /* The fixed IV is prepended to the nonce. */
+ assert(fixed_iv_len <= aead_ctx->variable_nonce_len);
+ aead_ctx->variable_nonce_len -= fixed_iv_len;
+ }
+
/* AES-GCM uses an explicit nonce. */
if (cipher->algorithm_enc & (SSL_AES128GCM | SSL_AES256GCM)) {
aead_ctx->variable_nonce_included_in_record = 1;
@@ -176,8 +179,17 @@ int SSL_AEAD_CTX_open(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len,
/* Assemble the nonce. */
uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
size_t nonce_len = 0;
- memcpy(nonce, aead->fixed_nonce, aead->fixed_nonce_len);
- nonce_len += aead->fixed_nonce_len;
+
+ /* Prepend the fixed nonce, or left-pad with zeros if XORing. */
+ if (aead->xor_fixed_nonce) {
+ nonce_len = aead->fixed_nonce_len - aead->variable_nonce_len;
+ memset(nonce, 0, nonce_len);
+ } else {
+ memcpy(nonce, aead->fixed_nonce, aead->fixed_nonce_len);
+ nonce_len += aead->fixed_nonce_len;
+ }
+
+ /* Add the variable nonce. */
if (aead->variable_nonce_included_in_record) {
if (in_len < aead->variable_nonce_len) {
/* Publicly invalid. */
@@ -193,6 +205,15 @@ int SSL_AEAD_CTX_open(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len,
}
nonce_len += aead->variable_nonce_len;
+ /* XOR the fixed nonce, if necessary. */
+ if (aead->xor_fixed_nonce) {
+ assert(nonce_len == aead->fixed_nonce_len);
+ size_t i;
+ for (i = 0; i < aead->fixed_nonce_len; i++) {
+ nonce[i] ^= aead->fixed_nonce[i];
+ }
+ }
+
return EVP_AEAD_CTX_open(&aead->ctx, out, out_len, max_out, nonce, nonce_len,
in, in_len, ad, ad_len);
}
@@ -219,8 +240,17 @@ int SSL_AEAD_CTX_seal(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len,
/* Assemble the nonce. */
uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
size_t nonce_len = 0;
- memcpy(nonce, aead->fixed_nonce, aead->fixed_nonce_len);
- nonce_len += aead->fixed_nonce_len;
+
+ /* Prepend the fixed nonce, or left-pad with zeros if XORing. */
+ if (aead->xor_fixed_nonce) {
+ nonce_len = aead->fixed_nonce_len - aead->variable_nonce_len;
+ memset(nonce, 0, nonce_len);
+ } else {
+ memcpy(nonce, aead->fixed_nonce, aead->fixed_nonce_len);
+ nonce_len += aead->fixed_nonce_len;
+ }
+
+ /* Select the variable nonce. */
if (aead->random_variable_nonce) {
assert(aead->variable_nonce_included_in_record);
if (!RAND_bytes(nonce + nonce_len, aead->variable_nonce_len)) {
@@ -230,13 +260,14 @@ int SSL_AEAD_CTX_seal(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len,
/* When sending we use the sequence number as the variable part of the
* nonce. */
assert(aead->variable_nonce_len == 8);
- memcpy(nonce + nonce_len, ad, aead->variable_nonce_len);
+ memcpy(nonce + nonce_len, seqnum, aead->variable_nonce_len);
}
nonce_len += aead->variable_nonce_len;
/* Emit the variable nonce if included in the record. */
size_t extra_len = 0;
if (aead->variable_nonce_included_in_record) {
+ assert(!aead->xor_fixed_nonce);
if (max_out < aead->variable_nonce_len) {
OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
return 0;
@@ -251,6 +282,15 @@ int SSL_AEAD_CTX_seal(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len,
max_out -= aead->variable_nonce_len;
}
+ /* XOR the fixed nonce, if necessary. */
+ if (aead->xor_fixed_nonce) {
+ assert(nonce_len == aead->fixed_nonce_len);
+ size_t i;
+ for (i = 0; i < aead->fixed_nonce_len; i++) {
+ nonce[i] ^= aead->fixed_nonce[i];
+ }
+ }
+
if (!EVP_AEAD_CTX_seal(&aead->ctx, out, out_len, max_out, nonce, nonce_len,
in, in_len, ad, ad_len)) {
return 0;
diff --git a/src/ssl/ssl_asn1.c b/src/ssl/ssl_asn1.c
index 0ad4a11..5ec33eb 100644
--- a/src/ssl/ssl_asn1.c
+++ b/src/ssl/ssl_asn1.c
@@ -492,8 +492,12 @@ static int SSL_SESSION_parse_u32(CBS *cbs, uint32_t *out, unsigned tag,
}
static X509 *parse_x509(CBS *cbs) {
+ if (CBS_len(cbs) > LONG_MAX) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
+ return NULL;
+ }
const uint8_t *ptr = CBS_data(cbs);
- X509 *ret = d2i_X509(NULL, &ptr, CBS_len(cbs));
+ X509 *ret = d2i_X509(NULL, &ptr, (long)CBS_len(cbs));
if (ret == NULL) {
return NULL;
}
diff --git a/src/ssl/ssl_buffer.c b/src/ssl/ssl_buffer.c
index f1abc53..7fd74e4 100644
--- a/src/ssl/ssl_buffer.c
+++ b/src/ssl/ssl_buffer.c
@@ -70,8 +70,8 @@ static void clear_buffer(SSL3_BUFFER *buf) {
memset(buf, 0, sizeof(SSL3_BUFFER));
}
-OPENSSL_COMPILE_ASSERT(DTLS1_RT_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH +
- SSL3_RT_MAX_EXTRA <= 0xffff,
+OPENSSL_COMPILE_ASSERT(DTLS1_RT_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH <=
+ 0xffff,
maximum_read_buffer_too_large);
/* setup_read_buffer initializes the read buffer if not already initialized. It
@@ -90,9 +90,6 @@ static int setup_read_buffer(SSL *ssl) {
} else {
cap += SSL3_RT_HEADER_LENGTH;
}
- if (ssl->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) {
- cap += SSL3_RT_MAX_EXTRA;
- }
return setup_buffer(buf, header_len, cap);
}
@@ -131,9 +128,6 @@ static int tls_read_buffer_extend_to(SSL *ssl, size_t len) {
SSL3_BUFFER *buf = &ssl->s3->read_buffer;
if (len > buf->cap) {
- /* This may occur if |SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER| was toggled after
- * |setup_read_buffer| was called. Stay within bounds, but do not attempt to
- * recover. */
OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
return -1;
}
diff --git a/src/ssl/ssl_cert.c b/src/ssl/ssl_cert.c
index 4094b27..4952cfd 100644
--- a/src/ssl/ssl_cert.c
+++ b/src/ssl/ssl_cert.c
@@ -166,28 +166,9 @@ CERT *ssl_cert_dup(CERT *cert) {
OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
goto err;
}
- if (cert->dh_tmp->priv_key) {
- BIGNUM *b = BN_dup(cert->dh_tmp->priv_key);
- if (!b) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_BN_LIB);
- goto err;
- }
- ret->dh_tmp->priv_key = b;
- }
- if (cert->dh_tmp->pub_key) {
- BIGNUM *b = BN_dup(cert->dh_tmp->pub_key);
- if (!b) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_BN_LIB);
- goto err;
- }
- ret->dh_tmp->pub_key = b;
- }
}
ret->dh_tmp_cb = cert->dh_tmp_cb;
- ret->ecdh_nid = cert->ecdh_nid;
- ret->ecdh_tmp_cb = cert->ecdh_tmp_cb;
-
if (cert->x509 != NULL) {
ret->x509 = X509_up_ref(cert->x509);
}
diff --git a/src/ssl/ssl_cipher.c b/src/ssl/ssl_cipher.c
index e87835f..77fa8fa 100644
--- a/src/ssl/ssl_cipher.c
+++ b/src/ssl/ssl_cipher.c
@@ -155,33 +155,50 @@
/* kCiphers is an array of all supported ciphers, sorted by id. */
-const SSL_CIPHER kCiphers[] = {
+static const SSL_CIPHER kCiphers[] = {
/* The RSA ciphers */
/* Cipher 02 */
{
- SSL3_TXT_RSA_NULL_SHA, SSL3_CK_RSA_NULL_SHA, SSL_kRSA, SSL_aRSA,
- SSL_eNULL, SSL_SHA1, SSL_SSLV3, SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT, 0, 0,
+ SSL3_TXT_RSA_NULL_SHA,
+ SSL3_CK_RSA_NULL_SHA,
+ SSL_kRSA,
+ SSL_aRSA,
+ SSL_eNULL,
+ SSL_SHA1,
+ SSL_HANDSHAKE_MAC_DEFAULT,
},
/* Cipher 04 */
{
- SSL3_TXT_RSA_RC4_128_MD5, SSL3_CK_RSA_RC4_128_MD5, SSL_kRSA, SSL_aRSA,
- SSL_RC4, SSL_MD5, SSL_SSLV3, SSL_MEDIUM,
- SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
+ SSL3_TXT_RSA_RC4_128_MD5,
+ SSL3_CK_RSA_RC4_128_MD5,
+ SSL_kRSA,
+ SSL_aRSA,
+ SSL_RC4,
+ SSL_MD5,
+ SSL_HANDSHAKE_MAC_DEFAULT,
},
/* Cipher 05 */
{
- SSL3_TXT_RSA_RC4_128_SHA, SSL3_CK_RSA_RC4_128_SHA, SSL_kRSA, SSL_aRSA,
- SSL_RC4, SSL_SHA1, SSL_SSLV3, SSL_MEDIUM,
- SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
+ SSL3_TXT_RSA_RC4_128_SHA,
+ SSL3_CK_RSA_RC4_128_SHA,
+ SSL_kRSA,
+ SSL_aRSA,
+ SSL_RC4,
+ SSL_SHA1,
+ SSL_HANDSHAKE_MAC_DEFAULT,
},
/* Cipher 0A */
{
- SSL3_TXT_RSA_DES_192_CBC3_SHA, SSL3_CK_RSA_DES_192_CBC3_SHA, SSL_kRSA,
- SSL_aRSA, SSL_3DES, SSL_SHA1, SSL_SSLV3, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_DEFAULT, 112, 168,
+ SSL3_TXT_RSA_DES_192_CBC3_SHA,
+ SSL3_CK_RSA_DES_192_CBC3_SHA,
+ SSL_kRSA,
+ SSL_aRSA,
+ SSL_3DES,
+ SSL_SHA1,
+ SSL_HANDSHAKE_MAC_DEFAULT,
},
@@ -189,30 +206,46 @@ const SSL_CIPHER kCiphers[] = {
/* Cipher 2F */
{
- TLS1_TXT_RSA_WITH_AES_128_SHA, TLS1_CK_RSA_WITH_AES_128_SHA, SSL_kRSA,
- SSL_aRSA, SSL_AES128, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
+ TLS1_TXT_RSA_WITH_AES_128_SHA,
+ TLS1_CK_RSA_WITH_AES_128_SHA,
+ SSL_kRSA,
+ SSL_aRSA,
+ SSL_AES128,
+ SSL_SHA1,
+ SSL_HANDSHAKE_MAC_DEFAULT,
},
/* Cipher 33 */
{
- TLS1_TXT_DHE_RSA_WITH_AES_128_SHA, TLS1_CK_DHE_RSA_WITH_AES_128_SHA,
- SSL_kDHE, SSL_aRSA, SSL_AES128, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
+ TLS1_TXT_DHE_RSA_WITH_AES_128_SHA,
+ TLS1_CK_DHE_RSA_WITH_AES_128_SHA,
+ SSL_kDHE,
+ SSL_aRSA,
+ SSL_AES128,
+ SSL_SHA1,
+ SSL_HANDSHAKE_MAC_DEFAULT,
},
/* Cipher 35 */
{
- TLS1_TXT_RSA_WITH_AES_256_SHA, TLS1_CK_RSA_WITH_AES_256_SHA, SSL_kRSA,
- SSL_aRSA, SSL_AES256, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_DEFAULT, 256, 256,
+ TLS1_TXT_RSA_WITH_AES_256_SHA,
+ TLS1_CK_RSA_WITH_AES_256_SHA,
+ SSL_kRSA,
+ SSL_aRSA,
+ SSL_AES256,
+ SSL_SHA1,
+ SSL_HANDSHAKE_MAC_DEFAULT,
},
/* Cipher 39 */
{
- TLS1_TXT_DHE_RSA_WITH_AES_256_SHA, TLS1_CK_DHE_RSA_WITH_AES_256_SHA,
- SSL_kDHE, SSL_aRSA, SSL_AES256, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_DEFAULT, 256, 256,
+ TLS1_TXT_DHE_RSA_WITH_AES_256_SHA,
+ TLS1_CK_DHE_RSA_WITH_AES_256_SHA,
+ SSL_kDHE,
+ SSL_aRSA,
+ SSL_AES256,
+ SSL_SHA1,
+ SSL_HANDSHAKE_MAC_DEFAULT,
},
@@ -220,55 +253,81 @@ const SSL_CIPHER kCiphers[] = {
/* Cipher 3C */
{
- TLS1_TXT_RSA_WITH_AES_128_SHA256, TLS1_CK_RSA_WITH_AES_128_SHA256,
- SSL_kRSA, SSL_aRSA, SSL_AES128, SSL_SHA256, SSL_TLSV1_2,
- SSL_HIGH | SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256, 128, 128,
+ TLS1_TXT_RSA_WITH_AES_128_SHA256,
+ TLS1_CK_RSA_WITH_AES_128_SHA256,
+ SSL_kRSA,
+ SSL_aRSA,
+ SSL_AES128,
+ SSL_SHA256,
+ SSL_HANDSHAKE_MAC_SHA256,
},
/* Cipher 3D */
{
- TLS1_TXT_RSA_WITH_AES_256_SHA256, TLS1_CK_RSA_WITH_AES_256_SHA256,
- SSL_kRSA, SSL_aRSA, SSL_AES256, SSL_SHA256, SSL_TLSV1_2,
- SSL_HIGH | SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256, 256, 256,
+ TLS1_TXT_RSA_WITH_AES_256_SHA256,
+ TLS1_CK_RSA_WITH_AES_256_SHA256,
+ SSL_kRSA,
+ SSL_aRSA,
+ SSL_AES256,
+ SSL_SHA256,
+ SSL_HANDSHAKE_MAC_SHA256,
},
/* Cipher 67 */
{
TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256,
- TLS1_CK_DHE_RSA_WITH_AES_128_SHA256, SSL_kDHE, SSL_aRSA, SSL_AES128,
- SSL_SHA256, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_SHA256, 128, 128,
+ TLS1_CK_DHE_RSA_WITH_AES_128_SHA256,
+ SSL_kDHE,
+ SSL_aRSA,
+ SSL_AES128,
+ SSL_SHA256,
+ SSL_HANDSHAKE_MAC_SHA256,
},
/* Cipher 6B */
{
TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256,
- TLS1_CK_DHE_RSA_WITH_AES_256_SHA256, SSL_kDHE, SSL_aRSA, SSL_AES256,
- SSL_SHA256, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_SHA256, 256, 256,
+ TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
+ SSL_kDHE,
+ SSL_aRSA,
+ SSL_AES256,
+ SSL_SHA256,
+ SSL_HANDSHAKE_MAC_SHA256,
},
/* PSK cipher suites. */
/* Cipher 8A */
{
- TLS1_TXT_PSK_WITH_RC4_128_SHA, TLS1_CK_PSK_WITH_RC4_128_SHA, SSL_kPSK,
- SSL_aPSK, SSL_RC4, SSL_SHA1, SSL_TLSV1, SSL_MEDIUM,
- SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
+ TLS1_TXT_PSK_WITH_RC4_128_SHA,
+ TLS1_CK_PSK_WITH_RC4_128_SHA,
+ SSL_kPSK,
+ SSL_aPSK,
+ SSL_RC4,
+ SSL_SHA1,
+ SSL_HANDSHAKE_MAC_DEFAULT,
},
/* Cipher 8C */
{
- TLS1_TXT_PSK_WITH_AES_128_CBC_SHA, TLS1_CK_PSK_WITH_AES_128_CBC_SHA,
- SSL_kPSK, SSL_aPSK, SSL_AES128, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
+ TLS1_TXT_PSK_WITH_AES_128_CBC_SHA,
+ TLS1_CK_PSK_WITH_AES_128_CBC_SHA,
+ SSL_kPSK,
+ SSL_aPSK,
+ SSL_AES128,
+ SSL_SHA1,
+ SSL_HANDSHAKE_MAC_DEFAULT,
},
/* Cipher 8D */
{
- TLS1_TXT_PSK_WITH_AES_256_CBC_SHA, TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
- SSL_kPSK, SSL_aPSK, SSL_AES256, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_DEFAULT, 256, 256,
+ TLS1_TXT_PSK_WITH_AES_256_CBC_SHA,
+ TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
+ SSL_kPSK,
+ SSL_aPSK,
+ SSL_AES256,
+ SSL_SHA1,
+ SSL_HANDSHAKE_MAC_DEFAULT,
},
/* GCM ciphersuites from RFC5288 */
@@ -276,84 +335,111 @@ const SSL_CIPHER kCiphers[] = {
/* Cipher 9C */
{
TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256,
- TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, SSL_kRSA, SSL_aRSA, SSL_AES128GCM,
- SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
+ TLS1_CK_RSA_WITH_AES_128_GCM_SHA256,
+ SSL_kRSA,
+ SSL_aRSA,
+ SSL_AES128GCM,
+ SSL_AEAD,
SSL_HANDSHAKE_MAC_SHA256,
- 128, 128,
},
/* Cipher 9D */
{
TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384,
- TLS1_CK_RSA_WITH_AES_256_GCM_SHA384, SSL_kRSA, SSL_aRSA, SSL_AES256GCM,
- SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
+ TLS1_CK_RSA_WITH_AES_256_GCM_SHA384,
+ SSL_kRSA,
+ SSL_aRSA,
+ SSL_AES256GCM,
+ SSL_AEAD,
SSL_HANDSHAKE_MAC_SHA384,
- 256, 256,
},
/* Cipher 9E */
{
TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256,
- TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, SSL_kDHE, SSL_aRSA, SSL_AES128GCM,
- SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
+ TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256,
+ SSL_kDHE,
+ SSL_aRSA,
+ SSL_AES128GCM,
+ SSL_AEAD,
SSL_HANDSHAKE_MAC_SHA256,
- 128, 128,
},
/* Cipher 9F */
{
TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384,
- TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384, SSL_kDHE, SSL_aRSA, SSL_AES256GCM,
- SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
+ TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384,
+ SSL_kDHE,
+ SSL_aRSA,
+ SSL_AES256GCM,
+ SSL_AEAD,
SSL_HANDSHAKE_MAC_SHA384,
- 256, 256,
},
/* Cipher C007 */
{
TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA,
- TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA, SSL_kECDHE, SSL_aECDSA, SSL_RC4,
- SSL_SHA1, SSL_TLSV1, SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT, 128,
- 128,
+ TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA,
+ SSL_kECDHE,
+ SSL_aECDSA,
+ SSL_RC4,
+ SSL_SHA1,
+ SSL_HANDSHAKE_MAC_DEFAULT,
},
/* Cipher C009 */
{
TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
- TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, SSL_kECDHE, SSL_aECDSA,
- SSL_AES128, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
+ TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+ SSL_kECDHE,
+ SSL_aECDSA,
+ SSL_AES128,
+ SSL_SHA1,
+ SSL_HANDSHAKE_MAC_DEFAULT,
},
/* Cipher C00A */
{
TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
- TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, SSL_kECDHE, SSL_aECDSA,
- SSL_AES256, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_DEFAULT, 256, 256,
+ TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+ SSL_kECDHE,
+ SSL_aECDSA,
+ SSL_AES256,
+ SSL_SHA1,
+ SSL_HANDSHAKE_MAC_DEFAULT,
},
/* Cipher C011 */
{
- TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA, TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA,
- SSL_kECDHE, SSL_aRSA, SSL_RC4, SSL_SHA1, SSL_TLSV1, SSL_MEDIUM,
- SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
+ TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA,
+ TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA,
+ SSL_kECDHE,
+ SSL_aRSA,
+ SSL_RC4,
+ SSL_SHA1,
+ SSL_HANDSHAKE_MAC_DEFAULT,
},
/* Cipher C013 */
{
TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA,
- TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, SSL_kECDHE, SSL_aRSA, SSL_AES128,
- SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
+ TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+ SSL_kECDHE,
+ SSL_aRSA,
+ SSL_AES128,
+ SSL_SHA1,
+ SSL_HANDSHAKE_MAC_DEFAULT,
},
/* Cipher C014 */
{
TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA,
- TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, SSL_kECDHE, SSL_aRSA, SSL_AES256,
- SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_DEFAULT, 256, 256,
+ TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+ SSL_kECDHE,
+ SSL_aRSA,
+ SSL_AES256,
+ SSL_SHA1,
+ SSL_HANDSHAKE_MAC_DEFAULT,
},
@@ -362,33 +448,45 @@ const SSL_CIPHER kCiphers[] = {
/* Cipher C023 */
{
TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256,
- TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256, SSL_kECDHE, SSL_aECDSA,
- SSL_AES128, SSL_SHA256, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_SHA256, 128, 128,
+ TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256,
+ SSL_kECDHE,
+ SSL_aECDSA,
+ SSL_AES128,
+ SSL_SHA256,
+ SSL_HANDSHAKE_MAC_SHA256,
},
/* Cipher C024 */
{
TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384,
- TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384, SSL_kECDHE, SSL_aECDSA,
- SSL_AES256, SSL_SHA384, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_SHA384, 256, 256,
+ TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384,
+ SSL_kECDHE,
+ SSL_aECDSA,
+ SSL_AES256,
+ SSL_SHA384,
+ SSL_HANDSHAKE_MAC_SHA384,
},
/* Cipher C027 */
{
TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256,
- TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256, SSL_kECDHE, SSL_aRSA, SSL_AES128,
- SSL_SHA256, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_SHA256, 128, 128,
+ TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
+ SSL_kECDHE,
+ SSL_aRSA,
+ SSL_AES128,
+ SSL_SHA256,
+ SSL_HANDSHAKE_MAC_SHA256,
},
/* Cipher C028 */
{
TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384,
- TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384, SSL_kECDHE, SSL_aRSA, SSL_AES256,
- SSL_SHA384, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_SHA384, 256, 256,
+ TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
+ SSL_kECDHE,
+ SSL_aRSA,
+ SSL_AES256,
+ SSL_SHA384,
+ SSL_HANDSHAKE_MAC_SHA384,
},
@@ -397,37 +495,45 @@ const SSL_CIPHER kCiphers[] = {
/* Cipher C02B */
{
TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
- TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, SSL_kECDHE, SSL_aECDSA,
- SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
+ TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+ SSL_kECDHE,
+ SSL_aECDSA,
+ SSL_AES128GCM,
+ SSL_AEAD,
SSL_HANDSHAKE_MAC_SHA256,
- 128, 128,
},
/* Cipher C02C */
{
TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
- TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, SSL_kECDHE, SSL_aECDSA,
- SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
+ TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+ SSL_kECDHE,
+ SSL_aECDSA,
+ SSL_AES256GCM,
+ SSL_AEAD,
SSL_HANDSHAKE_MAC_SHA384,
- 256, 256,
},
/* Cipher C02F */
{
TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
- TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, SSL_kECDHE, SSL_aRSA,
- SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
+ TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ SSL_kECDHE,
+ SSL_aRSA,
+ SSL_AES128GCM,
+ SSL_AEAD,
SSL_HANDSHAKE_MAC_SHA256,
- 128, 128,
},
/* Cipher C030 */
{
TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
- TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, SSL_kECDHE, SSL_aRSA,
- SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
+ TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+ SSL_kECDHE,
+ SSL_aRSA,
+ SSL_AES256GCM,
+ SSL_AEAD,
SSL_HANDSHAKE_MAC_SHA384,
- 256, 256,
},
/* ECDHE-PSK cipher suites. */
@@ -436,37 +542,80 @@ const SSL_CIPHER kCiphers[] = {
{
TLS1_TXT_ECDHE_PSK_WITH_AES_128_CBC_SHA,
TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
- SSL_kECDHE, SSL_aPSK, SSL_AES128, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
+ SSL_kECDHE,
+ SSL_aPSK,
+ SSL_AES128,
+ SSL_SHA1,
+ SSL_HANDSHAKE_MAC_DEFAULT,
},
/* Cipher C036 */
{
TLS1_TXT_ECDHE_PSK_WITH_AES_256_CBC_SHA,
TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA,
- SSL_kECDHE, SSL_aPSK, SSL_AES256, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_DEFAULT, 256, 256,
+ SSL_kECDHE,
+ SSL_aPSK,
+ SSL_AES256,
+ SSL_SHA1,
+ SSL_HANDSHAKE_MAC_DEFAULT,
},
-#if !defined(BORINGSSL_ANDROID_SYSTEM)
/* ChaCha20-Poly1305 cipher suites. */
+#if !defined(BORINGSSL_ANDROID_SYSTEM)
{
TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_OLD,
- TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, SSL_kECDHE, SSL_aRSA,
- SSL_CHACHA20POLY1305_OLD, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH,
+ TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD,
+ SSL_kECDHE,
+ SSL_aRSA,
+ SSL_CHACHA20POLY1305_OLD,
+ SSL_AEAD,
SSL_HANDSHAKE_MAC_SHA256,
- 256, 256,
},
{
TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_OLD,
- TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, SSL_kECDHE, SSL_aECDSA,
- SSL_CHACHA20POLY1305_OLD, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH,
+ TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD,
+ SSL_kECDHE,
+ SSL_aECDSA,
+ SSL_CHACHA20POLY1305_OLD,
+ SSL_AEAD,
SSL_HANDSHAKE_MAC_SHA256,
- 256, 256,
},
#endif
+
+ /* Cipher CCA8 */
+ {
+ TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
+ TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
+ SSL_kECDHE,
+ SSL_aRSA,
+ SSL_CHACHA20POLY1305,
+ SSL_AEAD,
+ SSL_HANDSHAKE_MAC_SHA256,
+ },
+
+ /* Cipher CCA9 */
+ {
+ TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
+ TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
+ SSL_kECDHE,
+ SSL_aECDSA,
+ SSL_CHACHA20POLY1305,
+ SSL_AEAD,
+ SSL_HANDSHAKE_MAC_SHA256,
+ },
+
+ /* Cipher CCAB */
+ {
+ TLS1_TXT_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
+ TLS1_CK_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
+ SSL_kECDHE,
+ SSL_aPSK,
+ SSL_CHACHA20POLY1305,
+ SSL_AEAD,
+ SSL_HANDSHAKE_MAC_SHA256,
+ },
};
static const size_t kCiphersLen = sizeof(kCiphers) / sizeof(kCiphers[0]);
@@ -496,13 +645,15 @@ typedef struct cipher_alias_st {
uint32_t algorithm_auth;
uint32_t algorithm_enc;
uint32_t algorithm_mac;
- uint32_t algorithm_ssl;
- uint32_t algo_strength;
+
+ /* min_version, if non-zero, matches all ciphers which were added in that
+ * particular protocol version. */
+ uint16_t min_version;
} CIPHER_ALIAS;
static const CIPHER_ALIAS kCipherAliases[] = {
/* "ALL" doesn't include eNULL (must be specifically enabled) */
- {"ALL", ~0u, ~0u, ~SSL_eNULL, ~0u, ~0u, ~0u},
+ {"ALL", ~0u, ~0u, ~SSL_eNULL, ~0u, 0},
/* The "COMPLEMENTOFDEFAULT" rule is omitted. It matches nothing. */
@@ -510,58 +661,59 @@ static const CIPHER_ALIAS kCipherAliases[] = {
* (some of those using only a single bit here combine
* multiple key exchange algs according to the RFCs,
* e.g. kEDH combines DHE_DSS and DHE_RSA) */
- {"kRSA", SSL_kRSA, ~0u, ~0u, ~0u, ~0u, ~0u},
+ {"kRSA", SSL_kRSA, ~0u, ~0u, ~0u, 0},
- {"kDHE", SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {"kEDH", SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {"DH", SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
+ {"kDHE", SSL_kDHE, ~0u, ~0u, ~0u, 0},
+ {"kEDH", SSL_kDHE, ~0u, ~0u, ~0u, 0},
+ {"DH", SSL_kDHE, ~0u, ~0u, ~0u, 0},
- {"kECDHE", SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {"kEECDH", SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {"ECDH", SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
+ {"kECDHE", SSL_kECDHE, ~0u, ~0u, ~0u, 0},
+ {"kEECDH", SSL_kECDHE, ~0u, ~0u, ~0u, 0},
+ {"ECDH", SSL_kECDHE, ~0u, ~0u, ~0u, 0},
- {"kPSK", SSL_kPSK, ~0u, ~0u, ~0u, ~0u, ~0u},
+ {"kPSK", SSL_kPSK, ~0u, ~0u, ~0u, 0},
/* server authentication aliases */
- {"aRSA", ~0u, SSL_aRSA, ~SSL_eNULL, ~0u, ~0u, ~0u},
- {"aECDSA", ~0u, SSL_aECDSA, ~0u, ~0u, ~0u, ~0u},
- {"ECDSA", ~0u, SSL_aECDSA, ~0u, ~0u, ~0u, ~0u},
- {"aPSK", ~0u, SSL_aPSK, ~0u, ~0u, ~0u, ~0u},
+ {"aRSA", ~0u, SSL_aRSA, ~SSL_eNULL, ~0u, 0},
+ {"aECDSA", ~0u, SSL_aECDSA, ~0u, ~0u, 0},
+ {"ECDSA", ~0u, SSL_aECDSA, ~0u, ~0u, 0},
+ {"aPSK", ~0u, SSL_aPSK, ~0u, ~0u, 0},
/* aliases combining key exchange and server authentication */
- {"DHE", SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {"EDH", SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {"ECDHE", SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {"EECDH", SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {"RSA", SSL_kRSA, SSL_aRSA, ~SSL_eNULL, ~0u, ~0u, ~0u},
- {"PSK", SSL_kPSK, SSL_aPSK, ~0u, ~0u, ~0u, ~0u},
+ {"DHE", SSL_kDHE, ~0u, ~0u, ~0u, 0},
+ {"EDH", SSL_kDHE, ~0u, ~0u, ~0u, 0},
+ {"ECDHE", SSL_kECDHE, ~0u, ~0u, ~0u, 0},
+ {"EECDH", SSL_kECDHE, ~0u, ~0u, ~0u, 0},
+ {"RSA", SSL_kRSA, SSL_aRSA, ~SSL_eNULL, ~0u, 0},
+ {"PSK", SSL_kPSK, SSL_aPSK, ~0u, ~0u, 0},
/* symmetric encryption aliases */
- {"3DES", ~0u, ~0u, SSL_3DES, ~0u, ~0u, ~0u},
- {"RC4", ~0u, ~0u, SSL_RC4, ~0u, ~0u, ~0u},
- {"AES128", ~0u, ~0u, SSL_AES128 | SSL_AES128GCM, ~0u, ~0u, ~0u},
- {"AES256", ~0u, ~0u, SSL_AES256 | SSL_AES256GCM, ~0u, ~0u, ~0u},
- {"AES", ~0u, ~0u, SSL_AES, ~0u, ~0u, ~0u},
- {"AESGCM", ~0u, ~0u, SSL_AES128GCM | SSL_AES256GCM, ~0u, ~0u, ~0u},
- {"CHACHA20", ~0u, ~0u, SSL_CHACHA20POLY1305_OLD, ~0u, ~0u, ~0u},
+ {"3DES", ~0u, ~0u, SSL_3DES, ~0u, 0},
+ {"RC4", ~0u, ~0u, SSL_RC4, ~0u, 0},
+ {"AES128", ~0u, ~0u, SSL_AES128 | SSL_AES128GCM, ~0u, 0},
+ {"AES256", ~0u, ~0u, SSL_AES256 | SSL_AES256GCM, ~0u, 0},
+ {"AES", ~0u, ~0u, SSL_AES, ~0u, 0},
+ {"AESGCM", ~0u, ~0u, SSL_AES128GCM | SSL_AES256GCM, ~0u, 0},
+ {"CHACHA20", ~0u, ~0u, SSL_CHACHA20POLY1305 | SSL_CHACHA20POLY1305_OLD, ~0u,
+ 0},
/* MAC aliases */
- {"MD5", ~0u, ~0u, ~0u, SSL_MD5, ~0u, ~0u},
- {"SHA1", ~0u, ~0u, ~SSL_eNULL, SSL_SHA1, ~0u, ~0u},
- {"SHA", ~0u, ~0u, ~SSL_eNULL, SSL_SHA1, ~0u, ~0u},
- {"SHA256", ~0u, ~0u, ~0u, SSL_SHA256, ~0u, ~0u},
- {"SHA384", ~0u, ~0u, ~0u, SSL_SHA384, ~0u, ~0u},
-
- /* protocol version aliases */
- {"SSLv3", ~0u, ~0u, ~SSL_eNULL, ~0u, SSL_SSLV3, ~0u},
- {"TLSv1", ~0u, ~0u, ~SSL_eNULL, ~0u, SSL_TLSV1, ~0u},
- {"TLSv1.2", ~0u, ~0u, ~SSL_eNULL, ~0u, SSL_TLSV1_2, ~0u},
-
- /* strength classes */
- {"MEDIUM", ~0u, ~0u, ~0u, ~0u, ~0u, SSL_MEDIUM},
- {"HIGH", ~0u, ~0u, ~0u, ~0u, ~0u, SSL_HIGH},
- /* FIPS 140-2 approved ciphersuite */
- {"FIPS", ~0u, ~0u, ~SSL_eNULL, ~0u, ~0u, SSL_FIPS},
+ {"MD5", ~0u, ~0u, ~0u, SSL_MD5, 0},
+ {"SHA1", ~0u, ~0u, ~SSL_eNULL, SSL_SHA1, 0},
+ {"SHA", ~0u, ~0u, ~SSL_eNULL, SSL_SHA1, 0},
+ {"SHA256", ~0u, ~0u, ~0u, SSL_SHA256, 0},
+ {"SHA384", ~0u, ~0u, ~0u, SSL_SHA384, 0},
+
+ /* Legacy protocol minimum version aliases. "TLSv1" is intentionally the
+ * same as "SSLv3". */
+ {"SSLv3", ~0u, ~0u, ~SSL_eNULL, ~0u, SSL3_VERSION},
+ {"TLSv1", ~0u, ~0u, ~SSL_eNULL, ~0u, SSL3_VERSION},
+ {"TLSv1.2", ~0u, ~0u, ~SSL_eNULL, ~0u, TLS1_2_VERSION},
+
+ /* Legacy strength classes. */
+ {"MEDIUM", ~0u, ~0u, SSL_RC4, ~0u, 0},
+ {"HIGH", ~0u, ~0u, ~(SSL_eNULL|SSL_RC4), ~0u, 0},
+ {"FIPS", ~0u, ~0u, ~(SSL_eNULL|SSL_RC4), ~0u, 0},
};
static const size_t kCipherAliasesLen =
@@ -618,6 +770,11 @@ int ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead,
return 1;
#endif
+ case SSL_CHACHA20POLY1305:
+ *out_aead = EVP_aead_chacha20_poly1305();
+ *out_fixed_iv_len = 12;
+ return 1;
+
case SSL_RC4:
switch (cipher->algorithm_mac) {
case SSL_MD5:
@@ -838,19 +995,18 @@ static void ssl_cipher_collect_ciphers(const SSL_PROTOCOL_METHOD *ssl_method,
* - Otherwise, if |strength_bits| is non-negative, it selects ciphers
* of that strength.
* - Otherwise, it selects ciphers that match each bitmasks in |alg_*| and
- * |algo_strength|. */
+ * |min_version|. */
static void ssl_cipher_apply_rule(
uint32_t cipher_id, uint32_t alg_mkey, uint32_t alg_auth,
- uint32_t alg_enc, uint32_t alg_mac, uint32_t alg_ssl,
- uint32_t algo_strength, int rule, int strength_bits, int in_group,
- CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) {
+ uint32_t alg_enc, uint32_t alg_mac, uint16_t min_version, int rule,
+ int strength_bits, int in_group, CIPHER_ORDER **head_p,
+ CIPHER_ORDER **tail_p) {
CIPHER_ORDER *head, *tail, *curr, *next, *last;
const SSL_CIPHER *cp;
int reverse = 0;
- if (cipher_id == 0 && strength_bits == -1 &&
- (alg_mkey == 0 || alg_auth == 0 || alg_enc == 0 || alg_mac == 0 ||
- alg_ssl == 0 || algo_strength == 0)) {
+ if (cipher_id == 0 && strength_bits == -1 && min_version == 0 &&
+ (alg_mkey == 0 || alg_auth == 0 || alg_enc == 0 || alg_mac == 0)) {
/* The rule matches nothing, so bail early. */
return;
}
@@ -892,15 +1048,15 @@ static void ssl_cipher_apply_rule(
continue;
}
} else if (strength_bits >= 0) {
- if (strength_bits != cp->strength_bits) {
+ if (strength_bits != SSL_CIPHER_get_bits(cp, NULL)) {
continue;
}
} else if (!(alg_mkey & cp->algorithm_mkey) ||
!(alg_auth & cp->algorithm_auth) ||
!(alg_enc & cp->algorithm_enc) ||
!(alg_mac & cp->algorithm_mac) ||
- !(alg_ssl & cp->algorithm_ssl) ||
- !(algo_strength & cp->algo_strength)) {
+ (min_version != 0 &&
+ SSL_CIPHER_get_min_version(cp) != min_version)) {
continue;
}
@@ -969,8 +1125,9 @@ static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p,
max_strength_bits = 0;
curr = *head_p;
while (curr != NULL) {
- if (curr->active && curr->cipher->strength_bits > max_strength_bits) {
- max_strength_bits = curr->cipher->strength_bits;
+ if (curr->active &&
+ SSL_CIPHER_get_bits(curr->cipher, NULL) > max_strength_bits) {
+ max_strength_bits = SSL_CIPHER_get_bits(curr->cipher, NULL);
}
curr = curr->next;
}
@@ -986,7 +1143,7 @@ static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p,
curr = *head_p;
while (curr != NULL) {
if (curr->active) {
- number_uses[curr->cipher->strength_bits]++;
+ number_uses[SSL_CIPHER_get_bits(curr->cipher, NULL)]++;
}
curr = curr->next;
}
@@ -994,8 +1151,7 @@ static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p,
/* Go through the list of used strength_bits values in descending order. */
for (i = max_strength_bits; i >= 0; i--) {
if (number_uses[i] > 0) {
- ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ORD, i, 0, head_p,
- tail_p);
+ ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, CIPHER_ORD, i, 0, head_p, tail_p);
}
}
@@ -1007,9 +1163,10 @@ static int ssl_cipher_process_rulestr(const SSL_PROTOCOL_METHOD *ssl_method,
const char *rule_str,
CIPHER_ORDER **head_p,
CIPHER_ORDER **tail_p) {
- uint32_t alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength;
+ uint32_t alg_mkey, alg_auth, alg_enc, alg_mac;
+ uint16_t min_version;
const char *l, *buf;
- int multi, rule, retval, ok, in_group = 0, has_group = 0;
+ int multi, skip_rule, rule, retval, ok, in_group = 0, has_group = 0;
size_t j, buf_len;
uint32_t cipher_id;
char ch;
@@ -1090,8 +1247,8 @@ static int ssl_cipher_process_rulestr(const SSL_PROTOCOL_METHOD *ssl_method,
alg_auth = ~0u;
alg_enc = ~0u;
alg_mac = ~0u;
- alg_ssl = ~0u;
- algo_strength = ~0u;
+ min_version = 0;
+ skip_rule = 0;
for (;;) {
ch = *l;
@@ -1135,13 +1292,18 @@ static int ssl_cipher_process_rulestr(const SSL_PROTOCOL_METHOD *ssl_method,
alg_auth &= kCipherAliases[j].algorithm_auth;
alg_enc &= kCipherAliases[j].algorithm_enc;
alg_mac &= kCipherAliases[j].algorithm_mac;
- alg_ssl &= kCipherAliases[j].algorithm_ssl;
- algo_strength &= kCipherAliases[j].algo_strength;
+
+ if (min_version != 0 &&
+ min_version != kCipherAliases[j].min_version) {
+ skip_rule = 1;
+ } else {
+ min_version = kCipherAliases[j].min_version;
+ }
break;
}
}
if (j == kCipherAliasesLen) {
- alg_mkey = alg_auth = alg_enc = alg_mac = alg_ssl = algo_strength = 0;
+ skip_rule = 1;
}
}
@@ -1153,6 +1315,29 @@ static int ssl_cipher_process_rulestr(const SSL_PROTOCOL_METHOD *ssl_method,
multi = 1;
}
+ /* If one of the CHACHA20_POLY1305 variants is selected, include the other
+ * as well. They have the same name to avoid requiring changes in
+ * configuration. Apply this transformation late so that the cipher name
+ * still behaves as an exact name and not an alias in multipart rules.
+ *
+ * This is temporary and will be removed when the pre-standard construction
+ * is removed. */
+ if (cipher_id == TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD ||
+ cipher_id == TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256) {
+ cipher_id = 0;
+ alg_mkey = SSL_kECDHE;
+ alg_auth = SSL_aRSA;
+ alg_enc = SSL_CHACHA20POLY1305|SSL_CHACHA20POLY1305_OLD;
+ alg_mac = SSL_AEAD;
+ } else if (cipher_id == TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD ||
+ cipher_id == TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256) {
+ cipher_id = 0;
+ alg_mkey = SSL_kECDHE;
+ alg_auth = SSL_aECDSA;
+ alg_enc = SSL_CHACHA20POLY1305|SSL_CHACHA20POLY1305_OLD;
+ alg_mac = SSL_AEAD;
+ }
+
/* Ok, we have the rule, now apply it. */
if (rule == CIPHER_SPECIAL) {
/* special command */
@@ -1172,10 +1357,9 @@ static int ssl_cipher_process_rulestr(const SSL_PROTOCOL_METHOD *ssl_method,
while (*l != '\0' && !ITEM_SEP(*l)) {
l++;
}
- } else {
+ } else if (!skip_rule) {
ssl_cipher_apply_rule(cipher_id, alg_mkey, alg_auth, alg_enc, alg_mac,
- alg_ssl, algo_strength, rule, -1, in_group, head_p,
- tail_p);
+ min_version, rule, -1, in_group, head_p, tail_p);
}
}
@@ -1221,56 +1405,61 @@ ssl_create_cipher_list(const SSL_PROTOCOL_METHOD *ssl_method,
/* Everything else being equal, prefer ECDHE_ECDSA then ECDHE_RSA over other
* key exchange mechanisms */
- ssl_cipher_apply_rule(0, SSL_kECDHE, SSL_aECDSA, ~0u, ~0u, ~0u, ~0u,
- CIPHER_ADD, -1, 0, &head, &tail);
- ssl_cipher_apply_rule(0, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u, CIPHER_ADD, -1,
- 0, &head, &tail);
- ssl_cipher_apply_rule(0, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u, CIPHER_DEL, -1,
+ ssl_cipher_apply_rule(0, SSL_kECDHE, SSL_aECDSA, ~0u, ~0u, 0, CIPHER_ADD, -1,
0, &head, &tail);
+ ssl_cipher_apply_rule(0, SSL_kECDHE, ~0u, ~0u, ~0u, 0, CIPHER_ADD, -1, 0,
+ &head, &tail);
+ ssl_cipher_apply_rule(0, SSL_kECDHE, ~0u, ~0u, ~0u, 0, CIPHER_DEL, -1, 0,
+ &head, &tail);
/* Order the bulk ciphers. First the preferred AEAD ciphers. We prefer
* CHACHA20 unless there is hardware support for fast and constant-time
- * AES_GCM. */
+ * AES_GCM. Of the two CHACHA20 variants, the new one is preferred over the
+ * old one. */
if (EVP_has_aes_hardware()) {
- ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, ~0u, ~0u, CIPHER_ADD,
- -1, 0, &head, &tail);
- ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, ~0u, ~0u, CIPHER_ADD,
+ ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, 0, CIPHER_ADD, -1, 0,
+ &head, &tail);
+ ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, 0, CIPHER_ADD, -1, 0,
+ &head, &tail);
+ ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, 0, CIPHER_ADD,
-1, 0, &head, &tail);
- ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305_OLD, ~0u, ~0u, ~0u,
+ ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305_OLD, ~0u, 0,
CIPHER_ADD, -1, 0, &head, &tail);
} else {
- ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305_OLD, ~0u, ~0u, ~0u,
- CIPHER_ADD, -1, 0, &head, &tail);
- ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, ~0u, ~0u, CIPHER_ADD,
- -1, 0, &head, &tail);
- ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, ~0u, ~0u, CIPHER_ADD,
+ ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, 0, CIPHER_ADD,
-1, 0, &head, &tail);
+ ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305_OLD, ~0u, 0,
+ CIPHER_ADD, -1, 0, &head, &tail);
+ ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, 0, CIPHER_ADD, -1, 0,
+ &head, &tail);
+ ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, 0, CIPHER_ADD, -1, 0,
+ &head, &tail);
}
/* Then the legacy non-AEAD ciphers: AES_256_CBC, AES-128_CBC, RC4_128_SHA,
* RC4_128_MD5, 3DES_EDE_CBC_SHA. */
- ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256, ~0u, ~0u, ~0u, CIPHER_ADD, -1,
- 0, &head, &tail);
- ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128, ~0u, ~0u, ~0u, CIPHER_ADD, -1,
- 0, &head, &tail);
- ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_RC4, ~SSL_MD5, ~0u, ~0u, CIPHER_ADD,
- -1, 0, &head, &tail);
- ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_RC4, SSL_MD5, ~0u, ~0u, CIPHER_ADD, -1,
- 0, &head, &tail);
- ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_3DES, ~0u, ~0u, ~0u, CIPHER_ADD, -1, 0,
+ ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256, ~0u, 0, CIPHER_ADD, -1, 0,
&head, &tail);
+ ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128, ~0u, 0, CIPHER_ADD, -1, 0,
+ &head, &tail);
+ ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_RC4, ~SSL_MD5, 0, CIPHER_ADD, -1, 0,
+ &head, &tail);
+ ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_RC4, SSL_MD5, 0, CIPHER_ADD, -1, 0,
+ &head, &tail);
+ ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_3DES, ~0u, 0, CIPHER_ADD, -1, 0, &head,
+ &tail);
/* Temporarily enable everything else for sorting */
- ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, ~0u, ~0u, CIPHER_ADD, -1, 0,
- &head, &tail);
+ ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_ADD, -1, 0, &head,
+ &tail);
/* Move ciphers without forward secrecy to the end. */
- ssl_cipher_apply_rule(0, ~(SSL_kDHE | SSL_kECDHE), ~0u, ~0u, ~0u, ~0u, ~0u,
+ ssl_cipher_apply_rule(0, ~(SSL_kDHE | SSL_kECDHE), ~0u, ~0u, ~0u, 0,
CIPHER_ORD, -1, 0, &head, &tail);
/* Now disable everything (maintaining the ordering!) */
- ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, ~0u, ~0u, CIPHER_DEL, -1, 0,
- &head, &tail);
+ ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_DEL, -1, 0, &head,
+ &tail);
/* If the rule_string begins with DEFAULT, apply the default rule before
* using the (possibly available) additional rules. */
@@ -1396,8 +1585,17 @@ int SSL_CIPHER_is_AES128GCM(const SSL_CIPHER *cipher) {
return (cipher->algorithm_enc & SSL_AES128GCM) != 0;
}
+int SSL_CIPHER_is_AES128CBC(const SSL_CIPHER *cipher) {
+ return (cipher->algorithm_enc & SSL_AES128) != 0;
+}
+
+int SSL_CIPHER_is_AES256CBC(const SSL_CIPHER *cipher) {
+ return (cipher->algorithm_enc & SSL_AES256) != 0;
+}
+
int SSL_CIPHER_is_CHACHA20POLY1305(const SSL_CIPHER *cipher) {
- return (cipher->algorithm_enc & SSL_CHACHA20POLY1305_OLD) != 0;
+ return (cipher->algorithm_enc &
+ (SSL_CHACHA20POLY1305 | SSL_CHACHA20POLY1305_OLD)) != 0;
}
int SSL_CIPHER_is_NULL(const SSL_CIPHER *cipher) {
@@ -1418,8 +1616,14 @@ int SSL_CIPHER_is_ECDSA(const SSL_CIPHER *cipher) {
return (cipher->algorithm_auth & SSL_aECDSA) != 0;
}
+int SSL_CIPHER_is_ECDHE(const SSL_CIPHER *cipher) {
+ return (cipher->algorithm_mkey & SSL_kECDHE) != 0;
+}
+
uint16_t SSL_CIPHER_get_min_version(const SSL_CIPHER *cipher) {
- if (cipher->algorithm_ssl & SSL_TLSV1_2) {
+ if (cipher->algorithm_prf != SSL_HANDSHAKE_MAC_DEFAULT) {
+ /* Cipher suites before TLS 1.2 use the default PRF, while all those added
+ * afterwards specify a particular hash. */
return TLS1_2_VERSION;
}
return SSL3_VERSION;
@@ -1489,6 +1693,7 @@ static const char *ssl_cipher_get_enc_name(const SSL_CIPHER *cipher) {
return "AES_128_GCM";
case SSL_AES256GCM:
return "AES_256_GCM";
+ case SSL_CHACHA20POLY1305:
case SSL_CHACHA20POLY1305_OLD:
return "CHACHA20_POLY1305";
break;
@@ -1554,32 +1759,57 @@ int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher, int *out_alg_bits) {
return 0;
}
+ int alg_bits, strength_bits;
+ switch (cipher->algorithm_enc) {
+ case SSL_AES128:
+ case SSL_AES128GCM:
+ case SSL_RC4:
+ alg_bits = 128;
+ strength_bits = 128;
+ break;
+
+ case SSL_AES256:
+ case SSL_AES256GCM:
+#if !defined(BORINGSSL_ANDROID_SYSTEM)
+ case SSL_CHACHA20POLY1305_OLD:
+#endif
+ case SSL_CHACHA20POLY1305:
+ alg_bits = 256;
+ strength_bits = 256;
+ break;
+
+ case SSL_3DES:
+ alg_bits = 168;
+ strength_bits = 112;
+ break;
+
+ case SSL_eNULL:
+ alg_bits = 0;
+ strength_bits = 0;
+ break;
+
+ default:
+ assert(0);
+ alg_bits = 0;
+ strength_bits = 0;
+ }
+
if (out_alg_bits != NULL) {
- *out_alg_bits = cipher->alg_bits;
+ *out_alg_bits = alg_bits;
}
- return cipher->strength_bits;
+ return strength_bits;
}
const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf,
int len) {
- const char *ver;
const char *kx, *au, *enc, *mac;
- uint32_t alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl;
- static const char *format = "%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s\n";
+ uint32_t alg_mkey, alg_auth, alg_enc, alg_mac;
+ static const char *format = "%-23s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s\n";
alg_mkey = cipher->algorithm_mkey;
alg_auth = cipher->algorithm_auth;
alg_enc = cipher->algorithm_enc;
alg_mac = cipher->algorithm_mac;
- alg_ssl = cipher->algorithm_ssl;
-
- if (alg_ssl & SSL_SSLV3) {
- ver = "SSLv3";
- } else if (alg_ssl & SSL_TLSV1_2) {
- ver = "TLSv1.2";
- } else {
- ver = "unknown";
- }
switch (alg_mkey) {
case SSL_kRSA:
@@ -1646,6 +1876,10 @@ const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf,
break;
case SSL_CHACHA20POLY1305_OLD:
+ enc = "ChaCha20-Poly1305-Old";
+ break;
+
+ case SSL_CHACHA20POLY1305:
enc = "ChaCha20-Poly1305";
break;
@@ -1694,7 +1928,7 @@ const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf,
return "Buffer too small";
}
- BIO_snprintf(buf, len, format, cipher->name, ver, kx, au, enc, mac);
+ BIO_snprintf(buf, len, format, cipher->name, kx, au, enc, mac);
return buf;
}
diff --git a/src/ssl/ssl_ecdh.c b/src/ssl/ssl_ecdh.c
new file mode 100644
index 0000000..45c5b26
--- /dev/null
+++ b/src/ssl/ssl_ecdh.c
@@ -0,0 +1,383 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <openssl/ssl.h>
+
+#include <assert.h>
+#include <string.h>
+
+#include <openssl/bn.h>
+#include <openssl/bytestring.h>
+#include <openssl/curve25519.h>
+#include <openssl/ec.h>
+#include <openssl/err.h>
+#include <openssl/mem.h>
+#include <openssl/obj.h>
+
+#include "internal.h"
+
+
+/* |EC_POINT| implementation. */
+
+static void ssl_ec_point_cleanup(SSL_ECDH_CTX *ctx) {
+ BIGNUM *private_key = (BIGNUM *)ctx->data;
+ BN_clear_free(private_key);
+}
+
+static int ssl_ec_point_generate_keypair(SSL_ECDH_CTX *ctx, CBB *out) {
+ assert(ctx->data == NULL);
+ BIGNUM *private_key = BN_new();
+ if (private_key == NULL) {
+ return 0;
+ }
+ ctx->data = private_key;
+
+ /* Set up a shared |BN_CTX| for all operations. */
+ BN_CTX *bn_ctx = BN_CTX_new();
+ if (bn_ctx == NULL) {
+ return 0;
+ }
+ BN_CTX_start(bn_ctx);
+
+ int ret = 0;
+ EC_POINT *public_key = NULL;
+ EC_GROUP *group = EC_GROUP_new_by_curve_name(ctx->method->nid);
+ if (group == NULL) {
+ goto err;
+ }
+
+ /* Generate a private key. */
+ const BIGNUM *order = EC_GROUP_get0_order(group);
+ do {
+ if (!BN_rand_range(private_key, order)) {
+ goto err;
+ }
+ } while (BN_is_zero(private_key));
+
+ /* Compute the corresponding public key. */
+ public_key = EC_POINT_new(group);
+ if (public_key == NULL ||
+ !EC_POINT_mul(group, public_key, private_key, NULL, NULL, bn_ctx)) {
+ goto err;
+ }
+
+ /* Serialize the public key. */
+ size_t len = EC_POINT_point2oct(
+ group, public_key, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, bn_ctx);
+ uint8_t *ptr;
+ if (len == 0 ||
+ !CBB_add_space(out, &ptr, len) ||
+ EC_POINT_point2oct(group, public_key, POINT_CONVERSION_UNCOMPRESSED, ptr,
+ len, bn_ctx) != len) {
+ goto err;
+ }
+
+ ret = 1;
+
+err:
+ EC_GROUP_free(group);
+ EC_POINT_free(public_key);
+ BN_CTX_end(bn_ctx);
+ BN_CTX_free(bn_ctx);
+ return ret;
+}
+
+int ssl_ec_point_compute_secret(SSL_ECDH_CTX *ctx, uint8_t **out_secret,
+ size_t *out_secret_len, uint8_t *out_alert,
+ const uint8_t *peer_key, size_t peer_key_len) {
+ BIGNUM *private_key = (BIGNUM *)ctx->data;
+ assert(private_key != NULL);
+ *out_alert = SSL_AD_INTERNAL_ERROR;
+
+ /* Set up a shared |BN_CTX| for all operations. */
+ BN_CTX *bn_ctx = BN_CTX_new();
+ if (bn_ctx == NULL) {
+ return 0;
+ }
+ BN_CTX_start(bn_ctx);
+
+ int ret = 0;
+ EC_GROUP *group = EC_GROUP_new_by_curve_name(ctx->method->nid);
+ EC_POINT *peer_point = NULL, *result = NULL;
+ uint8_t *secret = NULL;
+ if (group == NULL) {
+ goto err;
+ }
+
+ /* Compute the x-coordinate of |peer_key| * |private_key|. */
+ peer_point = EC_POINT_new(group);
+ result = EC_POINT_new(group);
+ if (peer_point == NULL || result == NULL) {
+ goto err;
+ }
+ BIGNUM *x = BN_CTX_get(bn_ctx);
+ if (x == NULL) {
+ goto err;
+ }
+ if (!EC_POINT_oct2point(group, peer_point, peer_key, peer_key_len, bn_ctx)) {
+ *out_alert = SSL_AD_DECODE_ERROR;
+ goto err;
+ }
+ if (!EC_POINT_mul(group, result, NULL, peer_point, private_key, bn_ctx) ||
+ !EC_POINT_get_affine_coordinates_GFp(group, result, x, NULL, bn_ctx)) {
+ goto err;
+ }
+
+ /* Encode the x-coordinate left-padded with zeros. */
+ size_t secret_len = (EC_GROUP_get_degree(group) + 7) / 8;
+ secret = OPENSSL_malloc(secret_len);
+ if (secret == NULL || !BN_bn2bin_padded(secret, secret_len, x)) {
+ goto err;
+ }
+
+ *out_secret = secret;
+ *out_secret_len = secret_len;
+ secret = NULL;
+ ret = 1;
+
+err:
+ EC_GROUP_free(group);
+ EC_POINT_free(peer_point);
+ EC_POINT_free(result);
+ BN_CTX_end(bn_ctx);
+ BN_CTX_free(bn_ctx);
+ OPENSSL_free(secret);
+ return ret;
+}
+
+
+/* X25119 implementation. */
+
+static void ssl_x25519_cleanup(SSL_ECDH_CTX *ctx) {
+ if (ctx->data == NULL) {
+ return;
+ }
+ OPENSSL_cleanse(ctx->data, 32);
+ OPENSSL_free(ctx->data);
+}
+
+static int ssl_x25519_generate_keypair(SSL_ECDH_CTX *ctx, CBB *out) {
+ assert(ctx->data == NULL);
+
+ ctx->data = OPENSSL_malloc(32);
+ if (ctx->data == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ uint8_t public_key[32];
+ X25519_keypair(public_key, (uint8_t *)ctx->data);
+ return CBB_add_bytes(out, public_key, sizeof(public_key));
+}
+
+static int ssl_x25519_compute_secret(SSL_ECDH_CTX *ctx, uint8_t **out_secret,
+ size_t *out_secret_len, uint8_t *out_alert,
+ const uint8_t *peer_key,
+ size_t peer_key_len) {
+ assert(ctx->data != NULL);
+ *out_alert = SSL_AD_INTERNAL_ERROR;
+
+ uint8_t *secret = OPENSSL_malloc(32);
+ if (secret == NULL) {
+ return 0;
+ }
+
+ if (peer_key_len != 32 ||
+ !X25519(secret, (uint8_t *)ctx->data, peer_key)) {
+ OPENSSL_free(secret);
+ *out_alert = SSL_AD_DECODE_ERROR;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT);
+ return 0;
+ }
+
+ *out_secret = secret;
+ *out_secret_len = 32;
+ return 1;
+}
+
+
+/* Legacy DHE-based implementation. */
+
+static void ssl_dhe_cleanup(SSL_ECDH_CTX *ctx) {
+ DH_free((DH *)ctx->data);
+}
+
+static int ssl_dhe_generate_keypair(SSL_ECDH_CTX *ctx, CBB *out) {
+ DH *dh = (DH *)ctx->data;
+ /* The group must have been initialized already, but not the key. */
+ assert(dh != NULL);
+ assert(dh->priv_key == NULL);
+
+ /* Due to a bug in yaSSL, the public key must be zero padded to the size of
+ * the prime. */
+ return DH_generate_key(dh) &&
+ BN_bn2cbb_padded(out, BN_num_bytes(dh->p), dh->pub_key);
+}
+
+static int ssl_dhe_compute_secret(SSL_ECDH_CTX *ctx, uint8_t **out_secret,
+ size_t *out_secret_len, uint8_t *out_alert,
+ const uint8_t *peer_key,
+ size_t peer_key_len) {
+ DH *dh = (DH *)ctx->data;
+ assert(dh != NULL);
+ assert(dh->priv_key != NULL);
+ *out_alert = SSL_AD_INTERNAL_ERROR;
+
+ int secret_len = 0;
+ uint8_t *secret = NULL;
+ BIGNUM *peer_point = BN_bin2bn(peer_key, peer_key_len, NULL);
+ if (peer_point == NULL) {
+ goto err;
+ }
+
+ secret = OPENSSL_malloc(DH_size(dh));
+ if (secret == NULL) {
+ goto err;
+ }
+ secret_len = DH_compute_key(secret, peer_point, dh);
+ if (secret_len <= 0) {
+ goto err;
+ }
+
+ *out_secret = secret;
+ *out_secret_len = (size_t)secret_len;
+ BN_free(peer_point);
+ return 1;
+
+err:
+ if (secret_len > 0) {
+ OPENSSL_cleanse(secret, (size_t)secret_len);
+ }
+ OPENSSL_free(secret);
+ BN_free(peer_point);
+ return 0;
+}
+
+static const SSL_ECDH_METHOD kDHEMethod = {
+ NID_undef, 0, "",
+ ssl_dhe_cleanup,
+ ssl_dhe_generate_keypair,
+ ssl_dhe_compute_secret,
+};
+
+
+static const SSL_ECDH_METHOD kMethods[] = {
+ {
+ NID_X9_62_prime256v1,
+ SSL_CURVE_SECP256R1,
+ "P-256",
+ ssl_ec_point_cleanup,
+ ssl_ec_point_generate_keypair,
+ ssl_ec_point_compute_secret,
+ },
+ {
+ NID_secp384r1,
+ SSL_CURVE_SECP384R1,
+ "P-384",
+ ssl_ec_point_cleanup,
+ ssl_ec_point_generate_keypair,
+ ssl_ec_point_compute_secret,
+ },
+ {
+ NID_secp521r1,
+ SSL_CURVE_SECP521R1,
+ "P-521",
+ ssl_ec_point_cleanup,
+ ssl_ec_point_generate_keypair,
+ ssl_ec_point_compute_secret,
+ },
+ {
+ NID_x25519,
+ SSL_CURVE_ECDH_X25519,
+ "X25519",
+ ssl_x25519_cleanup,
+ ssl_x25519_generate_keypair,
+ ssl_x25519_compute_secret,
+ },
+};
+
+static const SSL_ECDH_METHOD *method_from_curve_id(uint16_t curve_id) {
+ size_t i;
+ for (i = 0; i < sizeof(kMethods) / sizeof(kMethods[0]); i++) {
+ if (kMethods[i].curve_id == curve_id) {
+ return &kMethods[i];
+ }
+ }
+ return NULL;
+}
+
+static const SSL_ECDH_METHOD *method_from_nid(int nid) {
+ size_t i;
+ for (i = 0; i < sizeof(kMethods) / sizeof(kMethods[0]); i++) {
+ if (kMethods[i].nid == nid) {
+ return &kMethods[i];
+ }
+ }
+ return NULL;
+}
+
+const char* SSL_get_curve_name(uint16_t curve_id) {
+ const SSL_ECDH_METHOD *method = method_from_curve_id(curve_id);
+ if (method == NULL) {
+ return NULL;
+ }
+ return method->name;
+}
+
+int ssl_nid_to_curve_id(uint16_t *out_curve_id, int nid) {
+ const SSL_ECDH_METHOD *method = method_from_nid(nid);
+ if (method == NULL) {
+ return 0;
+ }
+ *out_curve_id = method->curve_id;
+ return 1;
+}
+
+int SSL_ECDH_CTX_init(SSL_ECDH_CTX *ctx, uint16_t curve_id) {
+ SSL_ECDH_CTX_cleanup(ctx);
+
+ const SSL_ECDH_METHOD *method = method_from_curve_id(curve_id);
+ if (method == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_ELLIPTIC_CURVE);
+ return 0;
+ }
+ ctx->method = method;
+ return 1;
+}
+
+void SSL_ECDH_CTX_init_for_dhe(SSL_ECDH_CTX *ctx, DH *params) {
+ SSL_ECDH_CTX_cleanup(ctx);
+
+ ctx->method = &kDHEMethod;
+ ctx->data = params;
+}
+
+void SSL_ECDH_CTX_cleanup(SSL_ECDH_CTX *ctx) {
+ if (ctx->method == NULL) {
+ return;
+ }
+ ctx->method->cleanup(ctx);
+ ctx->method = NULL;
+ ctx->data = NULL;
+}
+
+int SSL_ECDH_CTX_generate_keypair(SSL_ECDH_CTX *ctx, CBB *out_public_key) {
+ return ctx->method->generate_keypair(ctx, out_public_key);
+}
+
+int SSL_ECDH_CTX_compute_secret(SSL_ECDH_CTX *ctx, uint8_t **out_secret,
+ size_t *out_secret_len, uint8_t *out_alert,
+ const uint8_t *peer_key, size_t peer_key_len) {
+ return ctx->method->compute_secret(ctx, out_secret, out_secret_len, out_alert,
+ peer_key, peer_key_len);
+}
diff --git a/src/ssl/ssl_lib.c b/src/ssl/ssl_lib.c
index c78a91a..08578a6 100644
--- a/src/ssl/ssl_lib.c
+++ b/src/ssl/ssl_lib.c
@@ -274,7 +274,7 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *method) {
goto err;
}
- CRYPTO_new_ex_data(&g_ex_data_class_ssl_ctx, ret, &ret->ex_data);
+ CRYPTO_new_ex_data(&ret->ex_data);
ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
@@ -285,10 +285,6 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *method) {
ret->options |= SSL_OP_NO_TICKET;
}
- /* Default is to connect to non-RI servers. When RI is more widely deployed
- * might change this. */
- ret->options |= SSL_OP_LEGACY_SERVER_CONNECT;
-
/* Lock the SSL_CTX to the specified version, for compatibility with legacy
* uses of SSL_METHOD. */
if (method->version != 0) {
@@ -343,14 +339,11 @@ void SSL_CTX_free(SSL_CTX *ctx) {
OPENSSL_free(ctx->ocsp_response);
OPENSSL_free(ctx->signed_cert_timestamp_list);
EVP_PKEY_free(ctx->tlsext_channel_id_private);
- BIO_free(ctx->keylog_bio);
OPENSSL_free(ctx);
}
SSL *SSL_new(SSL_CTX *ctx) {
- SSL *s;
-
if (ctx == NULL) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NULL_SSL_CTX);
return NULL;
@@ -360,100 +353,101 @@ SSL *SSL_new(SSL_CTX *ctx) {
return NULL;
}
- s = (SSL *)OPENSSL_malloc(sizeof(SSL));
- if (s == NULL) {
+ SSL *ssl = (SSL *)OPENSSL_malloc(sizeof(SSL));
+ if (ssl == NULL) {
goto err;
}
- memset(s, 0, sizeof(SSL));
+ memset(ssl, 0, sizeof(SSL));
- s->min_version = ctx->min_version;
- s->max_version = ctx->max_version;
+ ssl->min_version = ctx->min_version;
+ ssl->max_version = ctx->max_version;
- s->options = ctx->options;
- s->mode = ctx->mode;
- s->max_cert_list = ctx->max_cert_list;
+ ssl->options = ctx->options;
+ ssl->mode = ctx->mode;
+ ssl->max_cert_list = ctx->max_cert_list;
- s->cert = ssl_cert_dup(ctx->cert);
- if (s->cert == NULL) {
+ ssl->cert = ssl_cert_dup(ctx->cert);
+ if (ssl->cert == NULL) {
goto err;
}
- s->msg_callback = ctx->msg_callback;
- s->msg_callback_arg = ctx->msg_callback_arg;
- s->verify_mode = ctx->verify_mode;
- s->sid_ctx_length = ctx->sid_ctx_length;
- assert(s->sid_ctx_length <= sizeof s->sid_ctx);
- memcpy(&s->sid_ctx, &ctx->sid_ctx, sizeof(s->sid_ctx));
- s->verify_callback = ctx->default_verify_callback;
+ ssl->msg_callback = ctx->msg_callback;
+ ssl->msg_callback_arg = ctx->msg_callback_arg;
+ ssl->verify_mode = ctx->verify_mode;
+ ssl->sid_ctx_length = ctx->sid_ctx_length;
+ assert(ssl->sid_ctx_length <= sizeof ssl->sid_ctx);
+ memcpy(&ssl->sid_ctx, &ctx->sid_ctx, sizeof(ssl->sid_ctx));
+ ssl->verify_callback = ctx->default_verify_callback;
- s->param = X509_VERIFY_PARAM_new();
- if (!s->param) {
+ ssl->param = X509_VERIFY_PARAM_new();
+ if (!ssl->param) {
goto err;
}
- X509_VERIFY_PARAM_inherit(s->param, ctx->param);
- s->quiet_shutdown = ctx->quiet_shutdown;
- s->max_send_fragment = ctx->max_send_fragment;
+ X509_VERIFY_PARAM_inherit(ssl->param, ctx->param);
+ ssl->quiet_shutdown = ctx->quiet_shutdown;
+ ssl->max_send_fragment = ctx->max_send_fragment;
CRYPTO_refcount_inc(&ctx->references);
- s->ctx = ctx;
+ ssl->ctx = ctx;
CRYPTO_refcount_inc(&ctx->references);
- s->initial_ctx = ctx;
+ ssl->initial_ctx = ctx;
if (ctx->tlsext_ellipticcurvelist) {
- s->tlsext_ellipticcurvelist =
+ ssl->tlsext_ellipticcurvelist =
BUF_memdup(ctx->tlsext_ellipticcurvelist,
ctx->tlsext_ellipticcurvelist_length * 2);
- if (!s->tlsext_ellipticcurvelist) {
+ if (!ssl->tlsext_ellipticcurvelist) {
goto err;
}
- s->tlsext_ellipticcurvelist_length = ctx->tlsext_ellipticcurvelist_length;
+ ssl->tlsext_ellipticcurvelist_length = ctx->tlsext_ellipticcurvelist_length;
}
- if (s->ctx->alpn_client_proto_list) {
- s->alpn_client_proto_list = BUF_memdup(s->ctx->alpn_client_proto_list,
- s->ctx->alpn_client_proto_list_len);
- if (s->alpn_client_proto_list == NULL) {
+ if (ssl->ctx->alpn_client_proto_list) {
+ ssl->alpn_client_proto_list = BUF_memdup(
+ ssl->ctx->alpn_client_proto_list, ssl->ctx->alpn_client_proto_list_len);
+ if (ssl->alpn_client_proto_list == NULL) {
goto err;
}
- s->alpn_client_proto_list_len = s->ctx->alpn_client_proto_list_len;
+ ssl->alpn_client_proto_list_len = ssl->ctx->alpn_client_proto_list_len;
}
- s->verify_result = X509_V_OK;
- s->method = ctx->method;
+ ssl->verify_result = X509_V_OK;
+ ssl->method = ctx->method;
- if (!s->method->ssl_new(s)) {
+ if (!ssl->method->ssl_new(ssl)) {
goto err;
}
- s->enc_method = ssl3_get_enc_method(s->version);
- assert(s->enc_method != NULL);
+ ssl->enc_method = ssl3_get_enc_method(ssl->version);
+ assert(ssl->enc_method != NULL);
- s->rwstate = SSL_NOTHING;
+ ssl->rwstate = SSL_NOTHING;
- CRYPTO_new_ex_data(&g_ex_data_class_ssl, s, &s->ex_data);
+ CRYPTO_new_ex_data(&ssl->ex_data);
- s->psk_identity_hint = NULL;
+ ssl->psk_identity_hint = NULL;
if (ctx->psk_identity_hint) {
- s->psk_identity_hint = BUF_strdup(ctx->psk_identity_hint);
- if (s->psk_identity_hint == NULL) {
+ ssl->psk_identity_hint = BUF_strdup(ctx->psk_identity_hint);
+ if (ssl->psk_identity_hint == NULL) {
goto err;
}
}
- s->psk_client_callback = ctx->psk_client_callback;
- s->psk_server_callback = ctx->psk_server_callback;
+ ssl->psk_client_callback = ctx->psk_client_callback;
+ ssl->psk_server_callback = ctx->psk_server_callback;
- s->tlsext_channel_id_enabled = ctx->tlsext_channel_id_enabled;
+ ssl->tlsext_channel_id_enabled = ctx->tlsext_channel_id_enabled;
if (ctx->tlsext_channel_id_private) {
- s->tlsext_channel_id_private =
+ ssl->tlsext_channel_id_private =
EVP_PKEY_up_ref(ctx->tlsext_channel_id_private);
}
- s->signed_cert_timestamps_enabled = s->ctx->signed_cert_timestamps_enabled;
- s->ocsp_stapling_enabled = s->ctx->ocsp_stapling_enabled;
+ ssl->signed_cert_timestamps_enabled =
+ ssl->ctx->signed_cert_timestamps_enabled;
+ ssl->ocsp_stapling_enabled = ssl->ctx->ocsp_stapling_enabled;
- return s;
+ return ssl;
err:
- SSL_free(s);
+ SSL_free(ssl);
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return NULL;
@@ -745,8 +739,8 @@ int SSL_get_error(const SSL *ssl, int ret_code) {
/* This one doesn't make too much sense ... We never try to write to the
* rbio, and an application program where rbio and wbio are separate
* couldn't even know what it should wait for. However if we ever set
- * s->rwstate incorrectly (so that we have SSL_want_read(s) instead of
- * SSL_want_write(s)) and rbio and wbio *are* the same, this test works
+ * ssl->rwstate incorrectly (so that we have SSL_want_read(ssl) instead of
+ * SSL_want_write(ssl)) and rbio and wbio *are* the same, this test works
* around that bug; so it might be safer to keep it. */
return SSL_ERROR_WANT_WRITE;
}
@@ -976,61 +970,6 @@ void ssl_cipher_preference_list_free(
OPENSSL_free(cipher_list);
}
-struct ssl_cipher_preference_list_st *ssl_cipher_preference_list_dup(
- struct ssl_cipher_preference_list_st *cipher_list) {
- struct ssl_cipher_preference_list_st *ret = NULL;
- size_t n = sk_SSL_CIPHER_num(cipher_list->ciphers);
-
- ret = OPENSSL_malloc(sizeof(struct ssl_cipher_preference_list_st));
- if (!ret) {
- goto err;
- }
-
- ret->ciphers = NULL;
- ret->in_group_flags = NULL;
- ret->ciphers = sk_SSL_CIPHER_dup(cipher_list->ciphers);
- if (!ret->ciphers) {
- goto err;
- }
- ret->in_group_flags = BUF_memdup(cipher_list->in_group_flags, n);
- if (!ret->in_group_flags) {
- goto err;
- }
-
- return ret;
-
-err:
- ssl_cipher_preference_list_free(ret);
- return NULL;
-}
-
-struct ssl_cipher_preference_list_st *ssl_cipher_preference_list_from_ciphers(
- STACK_OF(SSL_CIPHER) *ciphers) {
- struct ssl_cipher_preference_list_st *ret = NULL;
- size_t n = sk_SSL_CIPHER_num(ciphers);
-
- ret = OPENSSL_malloc(sizeof(struct ssl_cipher_preference_list_st));
- if (!ret) {
- goto err;
- }
- ret->ciphers = NULL;
- ret->in_group_flags = NULL;
- ret->ciphers = sk_SSL_CIPHER_dup(ciphers);
- if (!ret->ciphers) {
- goto err;
- }
- ret->in_group_flags = OPENSSL_malloc(n);
- if (!ret->in_group_flags) {
- goto err;
- }
- memset(ret->in_group_flags, 0, n);
- return ret;
-
-err:
- ssl_cipher_preference_list_free(ret);
- return NULL;
-}
-
X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) { return ctx->param; }
X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) { return ssl->param; }
@@ -1169,11 +1108,11 @@ void SSL_set_verify_depth(SSL *ssl, int depth) {
int SSL_CTX_get_read_ahead(const SSL_CTX *ctx) { return 0; }
-int SSL_get_read_ahead(const SSL *s) { return 0; }
+int SSL_get_read_ahead(const SSL *ssl) { return 0; }
void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes) { }
-void SSL_set_read_ahead(SSL *s, int yes) { }
+void SSL_set_read_ahead(SSL *ssl, int yes) { }
int SSL_pending(const SSL *ssl) {
if (ssl->s3->rrec.type != SSL3_RT_APPLICATION_DATA) {
@@ -1334,17 +1273,17 @@ STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *ssl) {
/* return a STACK of the ciphers available for the SSL and in order of
* algorithm id */
-STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s) {
- if (s == NULL) {
+STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *ssl) {
+ if (ssl == NULL) {
return NULL;
}
- if (s->cipher_list_by_id != NULL) {
- return s->cipher_list_by_id;
+ if (ssl->cipher_list_by_id != NULL) {
+ return ssl->cipher_list_by_id;
}
- if (s->ctx != NULL && s->ctx->cipher_list_by_id != NULL) {
- return s->ctx->cipher_list_by_id;
+ if (ssl->ctx != NULL && ssl->ctx->cipher_list_by_id != NULL) {
+ return ssl->ctx->cipher_list_by_id;
}
return NULL;
@@ -1435,13 +1374,13 @@ int SSL_set_cipher_list(SSL *ssl, const char *str) {
return 1;
}
-STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs) {
+STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *ssl, const CBS *cbs) {
CBS cipher_suites = *cbs;
const SSL_CIPHER *c;
STACK_OF(SSL_CIPHER) *sk;
- if (s->s3) {
- s->s3->send_connection_binding = 0;
+ if (ssl->s3) {
+ ssl->s3->send_connection_binding = 0;
}
if (CBS_len(&cipher_suites) % 2 != 0) {
@@ -1464,24 +1403,24 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs) {
}
/* Check for SCSV. */
- if (s->s3 && cipher_suite == (SSL3_CK_SCSV & 0xffff)) {
+ if (ssl->s3 && cipher_suite == (SSL3_CK_SCSV & 0xffff)) {
/* SCSV is fatal if renegotiating. */
- if (s->s3->initial_handshake_complete) {
+ if (ssl->s3->initial_handshake_complete) {
OPENSSL_PUT_ERROR(SSL, SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
goto err;
}
- s->s3->send_connection_binding = 1;
+ ssl->s3->send_connection_binding = 1;
continue;
}
/* Check for FALLBACK_SCSV. */
- if (s->s3 && cipher_suite == (SSL3_CK_FALLBACK_SCSV & 0xffff)) {
- uint16_t max_version = ssl3_get_max_server_version(s);
- if (SSL_IS_DTLS(s) ? (uint16_t)s->version > max_version
- : (uint16_t)s->version < max_version) {
+ if (ssl->s3 && cipher_suite == (SSL3_CK_FALLBACK_SCSV & 0xffff)) {
+ uint16_t max_version = ssl3_get_max_server_version(ssl);
+ if (SSL_IS_DTLS(ssl) ? (uint16_t)ssl->version > max_version
+ : (uint16_t)ssl->version < max_version) {
OPENSSL_PUT_ERROR(SSL, SSL_R_INAPPROPRIATE_FALLBACK);
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL3_AD_INAPPROPRIATE_FALLBACK);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL3_AD_INAPPROPRIATE_FALLBACK);
goto err;
}
continue;
@@ -1743,9 +1682,9 @@ void SSL_set_cert_cb(SSL *ssl, int (*cb)(SSL *ssl, void *arg), void *arg) {
ssl_cert_set_cert_cb(ssl->cert, cb, arg);
}
-void ssl_get_compatible_server_ciphers(SSL *s, uint32_t *out_mask_k,
+void ssl_get_compatible_server_ciphers(SSL *ssl, uint32_t *out_mask_k,
uint32_t *out_mask_a) {
- CERT *c = s->cert;
+ CERT *c = ssl->cert;
int have_rsa_cert = 0, dh_tmp;
uint32_t mask_k, mask_a;
int have_ecc_cert = 0, ecdsa_ok;
@@ -1753,10 +1692,10 @@ void ssl_get_compatible_server_ciphers(SSL *s, uint32_t *out_mask_k,
dh_tmp = (c->dh_tmp != NULL || c->dh_tmp_cb != NULL);
- if (s->cert->x509 != NULL && ssl_has_private_key(s)) {
- if (ssl_private_key_type(s) == EVP_PKEY_RSA) {
+ if (ssl->cert->x509 != NULL && ssl_has_private_key(ssl)) {
+ if (ssl_private_key_type(ssl) == EVP_PKEY_RSA) {
have_rsa_cert = 1;
- } else if (ssl_private_key_type(s) == EVP_PKEY_EC) {
+ } else if (ssl_private_key_type(ssl) == EVP_PKEY_EC) {
have_ecc_cert = 1;
}
}
@@ -1781,7 +1720,7 @@ void ssl_get_compatible_server_ciphers(SSL *s, uint32_t *out_mask_k,
ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE)
? (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE)
: 1;
- if (!tls1_check_ec_cert(s, x)) {
+ if (!tls1_check_ec_cert(ssl, x)) {
ecdsa_ok = 0;
}
if (ecdsa_ok) {
@@ -1790,13 +1729,14 @@ void ssl_get_compatible_server_ciphers(SSL *s, uint32_t *out_mask_k,
}
/* If we are considering an ECC cipher suite that uses an ephemeral EC
- * key, check it. */
- if (tls1_check_ec_tmp_key(s)) {
+ * key, check for a shared curve. */
+ uint16_t unused;
+ if (tls1_get_shared_curve(ssl, &unused)) {
mask_k |= SSL_kECDHE;
}
/* PSK requires a server callback. */
- if (s->psk_server_callback != NULL) {
+ if (ssl->psk_server_callback != NULL) {
mask_k |= SSL_kPSK;
mask_a |= SSL_aPSK;
}
@@ -1882,28 +1822,24 @@ const char *SSL_SESSION_get_version(const SSL_SESSION *session) {
return ssl_get_version(session->ssl_version);
}
-const char* SSL_get_curve_name(uint16_t curve_id) {
- return tls1_ec_curve_id2name(curve_id);
+void ssl_clear_cipher_ctx(SSL *ssl) {
+ SSL_AEAD_CTX_free(ssl->aead_read_ctx);
+ ssl->aead_read_ctx = NULL;
+ SSL_AEAD_CTX_free(ssl->aead_write_ctx);
+ ssl->aead_write_ctx = NULL;
}
-void ssl_clear_cipher_ctx(SSL *s) {
- SSL_AEAD_CTX_free(s->aead_read_ctx);
- s->aead_read_ctx = NULL;
- SSL_AEAD_CTX_free(s->aead_write_ctx);
- s->aead_write_ctx = NULL;
-}
-
-X509 *SSL_get_certificate(const SSL *s) {
- if (s->cert != NULL) {
- return s->cert->x509;
+X509 *SSL_get_certificate(const SSL *ssl) {
+ if (ssl->cert != NULL) {
+ return ssl->cert->x509;
}
return NULL;
}
-EVP_PKEY *SSL_get_privatekey(const SSL *s) {
- if (s->cert != NULL) {
- return s->cert->privatekey;
+EVP_PKEY *SSL_get_privatekey(const SSL *ssl) {
+ if (ssl->cert != NULL) {
+ return ssl->cert->privatekey;
}
return NULL;
@@ -1932,23 +1868,23 @@ const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl) {
return ssl->aead_write_ctx->cipher;
}
-const COMP_METHOD *SSL_get_current_compression(SSL *s) { return NULL; }
+const COMP_METHOD *SSL_get_current_compression(SSL *ssl) { return NULL; }
-const COMP_METHOD *SSL_get_current_expansion(SSL *s) { return NULL; }
+const COMP_METHOD *SSL_get_current_expansion(SSL *ssl) { return NULL; }
-int ssl_init_wbio_buffer(SSL *s, int push) {
+int ssl_init_wbio_buffer(SSL *ssl, int push) {
BIO *bbio;
- if (s->bbio == NULL) {
+ if (ssl->bbio == NULL) {
bbio = BIO_new(BIO_f_buffer());
if (bbio == NULL) {
return 0;
}
- s->bbio = bbio;
+ ssl->bbio = bbio;
} else {
- bbio = s->bbio;
- if (s->bbio == s->wbio) {
- s->wbio = BIO_pop(s->wbio);
+ bbio = ssl->bbio;
+ if (ssl->bbio == ssl->wbio) {
+ ssl->wbio = BIO_pop(ssl->wbio);
}
}
@@ -1959,30 +1895,30 @@ int ssl_init_wbio_buffer(SSL *s, int push) {
}
if (push) {
- if (s->wbio != bbio) {
- s->wbio = BIO_push(bbio, s->wbio);
+ if (ssl->wbio != bbio) {
+ ssl->wbio = BIO_push(bbio, ssl->wbio);
}
} else {
- if (s->wbio == bbio) {
- s->wbio = BIO_pop(bbio);
+ if (ssl->wbio == bbio) {
+ ssl->wbio = BIO_pop(bbio);
}
}
return 1;
}
-void ssl_free_wbio_buffer(SSL *s) {
- if (s->bbio == NULL) {
+void ssl_free_wbio_buffer(SSL *ssl) {
+ if (ssl->bbio == NULL) {
return;
}
- if (s->bbio == s->wbio) {
+ if (ssl->bbio == ssl->wbio) {
/* remove buffering */
- s->wbio = BIO_pop(s->wbio);
+ ssl->wbio = BIO_pop(ssl->wbio);
}
- BIO_free(s->bbio);
- s->bbio = NULL;
+ BIO_free(ssl->bbio);
+ ssl->bbio = NULL;
}
void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode) {
@@ -2065,11 +2001,11 @@ void SSL_set_verify_result(SSL *ssl, long result) {
long SSL_get_verify_result(const SSL *ssl) { return ssl->verify_result; }
-int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
int index;
if (!CRYPTO_get_ex_new_index(&g_ex_data_class_ssl, &index, argl, argp,
- new_func, dup_func, free_func)) {
+ dup_func, free_func)) {
return -1;
}
return index;
@@ -2083,12 +2019,12 @@ void *SSL_get_ex_data(const SSL *ssl, int idx) {
return CRYPTO_get_ex_data(&ssl->ex_data, idx);
}
-int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
CRYPTO_EX_dup *dup_func,
CRYPTO_EX_free *free_func) {
int index;
if (!CRYPTO_get_ex_new_index(&g_ex_data_class_ssl_ctx, &index, argl, argp,
- new_func, dup_func, free_func)) {
+ dup_func, free_func)) {
return -1;
}
return index;
@@ -2133,18 +2069,6 @@ void SSL_set_tmp_dh_callback(SSL *ssl, DH *(*callback)(SSL *ssl, int is_export,
ssl->cert->dh_tmp_cb = callback;
}
-void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx,
- EC_KEY *(*callback)(SSL *ssl, int is_export,
- int keylength)) {
- ctx->cert->ecdh_tmp_cb = callback;
-}
-
-void SSL_set_tmp_ecdh_callback(SSL *ssl,
- EC_KEY *(*callback)(SSL *ssl, int is_export,
- int keylength)) {
- ssl->cert->ecdh_tmp_cb = callback;
-}
-
int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint) {
if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
@@ -2252,9 +2176,9 @@ void SSL_set_msg_callback_arg(SSL *ssl, void *arg) {
ssl->msg_callback_arg = arg;
}
-void SSL_CTX_set_keylog_bio(SSL_CTX *ctx, BIO *keylog_bio) {
- BIO_free(ctx->keylog_bio);
- ctx->keylog_bio = keylog_bio;
+void SSL_CTX_set_keylog_callback(SSL_CTX *ctx,
+ void (*cb)(const SSL *ssl, const char *line)) {
+ ctx->keylog_callback = cb;
}
static int cbb_add_hex(CBB *cbb, const uint8_t *in, size_t in_len) {
@@ -2274,18 +2198,12 @@ static int cbb_add_hex(CBB *cbb, const uint8_t *in, size_t in_len) {
return 1;
}
-int ssl_ctx_log_rsa_client_key_exchange(SSL_CTX *ctx,
- const uint8_t *encrypted_premaster,
- size_t encrypted_premaster_len,
- const uint8_t *premaster,
- size_t premaster_len) {
- BIO *bio = ctx->keylog_bio;
- CBB cbb;
- uint8_t *out;
- size_t out_len;
- int ret;
-
- if (bio == NULL) {
+int ssl_log_rsa_client_key_exchange(const SSL *ssl,
+ const uint8_t *encrypted_premaster,
+ size_t encrypted_premaster_len,
+ const uint8_t *premaster,
+ size_t premaster_len) {
+ if (ssl->ctx->keylog_callback == NULL) {
return 1;
}
@@ -2294,7 +2212,9 @@ int ssl_ctx_log_rsa_client_key_exchange(SSL_CTX *ctx,
return 0;
}
- CBB_zero(&cbb);
+ CBB cbb;
+ uint8_t *out;
+ size_t out_len;
if (!CBB_init(&cbb, 4 + 16 + 1 + premaster_len * 2 + 1) ||
!CBB_add_bytes(&cbb, (const uint8_t *)"RSA ", 4) ||
/* Only the first 8 bytes of the encrypted premaster secret are
@@ -2302,30 +2222,21 @@ int ssl_ctx_log_rsa_client_key_exchange(SSL_CTX *ctx,
!cbb_add_hex(&cbb, encrypted_premaster, 8) ||
!CBB_add_bytes(&cbb, (const uint8_t *)" ", 1) ||
!cbb_add_hex(&cbb, premaster, premaster_len) ||
- !CBB_add_bytes(&cbb, (const uint8_t *)"\n", 1) ||
+ !CBB_add_u8(&cbb, 0 /* NUL */) ||
!CBB_finish(&cbb, &out, &out_len)) {
CBB_cleanup(&cbb);
return 0;
}
- CRYPTO_MUTEX_lock_write(&ctx->lock);
- ret = BIO_write(bio, out, out_len) >= 0 && BIO_flush(bio);
- CRYPTO_MUTEX_unlock(&ctx->lock);
-
+ ssl->ctx->keylog_callback(ssl, (const char *)out);
OPENSSL_free(out);
- return ret;
+ return 1;
}
-int ssl_ctx_log_master_secret(SSL_CTX *ctx, const uint8_t *client_random,
- size_t client_random_len, const uint8_t *master,
- size_t master_len) {
- BIO *bio = ctx->keylog_bio;
- CBB cbb;
- uint8_t *out;
- size_t out_len;
- int ret;
-
- if (bio == NULL) {
+int ssl_log_master_secret(const SSL *ssl, const uint8_t *client_random,
+ size_t client_random_len, const uint8_t *master,
+ size_t master_len) {
+ if (ssl->ctx->keylog_callback == NULL) {
return 1;
}
@@ -2334,24 +2245,23 @@ int ssl_ctx_log_master_secret(SSL_CTX *ctx, const uint8_t *client_random,
return 0;
}
- CBB_zero(&cbb);
+ CBB cbb;
+ uint8_t *out;
+ size_t out_len;
if (!CBB_init(&cbb, 14 + 64 + 1 + master_len * 2 + 1) ||
!CBB_add_bytes(&cbb, (const uint8_t *)"CLIENT_RANDOM ", 14) ||
!cbb_add_hex(&cbb, client_random, 32) ||
!CBB_add_bytes(&cbb, (const uint8_t *)" ", 1) ||
!cbb_add_hex(&cbb, master, master_len) ||
- !CBB_add_bytes(&cbb, (const uint8_t *)"\n", 1) ||
+ !CBB_add_u8(&cbb, 0 /* NUL */) ||
!CBB_finish(&cbb, &out, &out_len)) {
CBB_cleanup(&cbb);
return 0;
}
- CRYPTO_MUTEX_lock_write(&ctx->lock);
- ret = BIO_write(bio, out, out_len) >= 0 && BIO_flush(bio);
- CRYPTO_MUTEX_unlock(&ctx->lock);
-
+ ssl->ctx->keylog_callback(ssl, (const char *)out);
OPENSSL_free(out);
- return ret;
+ return 1;
}
int SSL_is_init_finished(const SSL *ssl) {
@@ -2366,8 +2276,8 @@ int SSL_in_false_start(const SSL *ssl) {
return ssl->s3->tmp.in_false_start;
}
-int SSL_cutthrough_complete(const SSL *s) {
- return SSL_in_false_start(s);
+int SSL_cutthrough_complete(const SSL *ssl) {
+ return SSL_in_false_start(ssl);
}
void SSL_get_structure_sizes(size_t *ssl_size, size_t *ssl_ctx_size,
@@ -2377,18 +2287,16 @@ void SSL_get_structure_sizes(size_t *ssl_size, size_t *ssl_ctx_size,
*ssl_session_size = sizeof(SSL_SESSION);
}
-int ssl3_can_false_start(const SSL *s) {
- const SSL_CIPHER *const cipher = SSL_get_current_cipher(s);
+int ssl3_can_false_start(const SSL *ssl) {
+ const SSL_CIPHER *const cipher = SSL_get_current_cipher(ssl);
/* False Start only for TLS 1.2 with an ECDHE+AEAD cipher and ALPN or NPN. */
- return !SSL_IS_DTLS(s) &&
- SSL_version(s) >= TLS1_2_VERSION &&
- (s->s3->alpn_selected || s->s3->next_proto_neg_seen) &&
+ return !SSL_IS_DTLS(ssl) &&
+ SSL_version(ssl) >= TLS1_2_VERSION &&
+ (ssl->s3->alpn_selected || ssl->s3->next_proto_neg_seen) &&
cipher != NULL &&
cipher->algorithm_mkey == SSL_kECDHE &&
- (cipher->algorithm_enc == SSL_AES128GCM ||
- cipher->algorithm_enc == SSL_AES256GCM ||
- cipher->algorithm_enc == SSL_CHACHA20POLY1305_OLD);
+ cipher->algorithm_mac == SSL_AEAD;
}
const SSL3_ENC_METHOD *ssl3_get_enc_method(uint16_t version) {
@@ -2412,84 +2320,89 @@ const SSL3_ENC_METHOD *ssl3_get_enc_method(uint16_t version) {
}
}
-uint16_t ssl3_get_max_server_version(const SSL *s) {
+uint16_t ssl3_get_max_server_version(const SSL *ssl) {
uint16_t max_version;
- if (SSL_IS_DTLS(s)) {
- max_version = (s->max_version != 0) ? s->max_version : DTLS1_2_VERSION;
- if (!(s->options & SSL_OP_NO_DTLSv1_2) && DTLS1_2_VERSION >= max_version) {
+ if (SSL_IS_DTLS(ssl)) {
+ max_version = (ssl->max_version != 0) ? ssl->max_version : DTLS1_2_VERSION;
+ if (!(ssl->options & SSL_OP_NO_DTLSv1_2) &&
+ DTLS1_2_VERSION >= max_version) {
return DTLS1_2_VERSION;
}
- if (!(s->options & SSL_OP_NO_DTLSv1) && DTLS1_VERSION >= max_version) {
+ if (!(ssl->options & SSL_OP_NO_DTLSv1) && DTLS1_VERSION >= max_version) {
return DTLS1_VERSION;
}
return 0;
}
- max_version = (s->max_version != 0) ? s->max_version : TLS1_2_VERSION;
- if (!(s->options & SSL_OP_NO_TLSv1_2) && TLS1_2_VERSION <= max_version) {
+ max_version = (ssl->max_version != 0) ? ssl->max_version : TLS1_2_VERSION;
+ if (!(ssl->options & SSL_OP_NO_TLSv1_2) && TLS1_2_VERSION <= max_version) {
return TLS1_2_VERSION;
}
- if (!(s->options & SSL_OP_NO_TLSv1_1) && TLS1_1_VERSION <= max_version) {
+ if (!(ssl->options & SSL_OP_NO_TLSv1_1) && TLS1_1_VERSION <= max_version) {
return TLS1_1_VERSION;
}
- if (!(s->options & SSL_OP_NO_TLSv1) && TLS1_VERSION <= max_version) {
+ if (!(ssl->options & SSL_OP_NO_TLSv1) && TLS1_VERSION <= max_version) {
return TLS1_VERSION;
}
- if (!(s->options & SSL_OP_NO_SSLv3) && SSL3_VERSION <= max_version) {
+ if (!(ssl->options & SSL_OP_NO_SSLv3) && SSL3_VERSION <= max_version) {
return SSL3_VERSION;
}
return 0;
}
-uint16_t ssl3_get_mutual_version(SSL *s, uint16_t client_version) {
+uint16_t ssl3_get_mutual_version(SSL *ssl, uint16_t client_version) {
uint16_t version = 0;
- if (SSL_IS_DTLS(s)) {
+ if (SSL_IS_DTLS(ssl)) {
/* Clamp client_version to max_version. */
- if (s->max_version != 0 && client_version < s->max_version) {
- client_version = s->max_version;
+ if (ssl->max_version != 0 && client_version < ssl->max_version) {
+ client_version = ssl->max_version;
}
- if (client_version <= DTLS1_2_VERSION && !(s->options & SSL_OP_NO_DTLSv1_2)) {
+ if (client_version <= DTLS1_2_VERSION &&
+ !(ssl->options & SSL_OP_NO_DTLSv1_2)) {
version = DTLS1_2_VERSION;
} else if (client_version <= DTLS1_VERSION &&
- !(s->options & SSL_OP_NO_DTLSv1)) {
+ !(ssl->options & SSL_OP_NO_DTLSv1)) {
version = DTLS1_VERSION;
}
/* Check against min_version. */
- if (version != 0 && s->min_version != 0 && version > s->min_version) {
+ if (version != 0 && ssl->min_version != 0 && version > ssl->min_version) {
return 0;
}
return version;
} else {
/* Clamp client_version to max_version. */
- if (s->max_version != 0 && client_version > s->max_version) {
- client_version = s->max_version;
+ if (ssl->max_version != 0 && client_version > ssl->max_version) {
+ client_version = ssl->max_version;
}
- if (client_version >= TLS1_2_VERSION && !(s->options & SSL_OP_NO_TLSv1_2)) {
+ if (client_version >= TLS1_2_VERSION &&
+ !(ssl->options & SSL_OP_NO_TLSv1_2)) {
version = TLS1_2_VERSION;
} else if (client_version >= TLS1_1_VERSION &&
- !(s->options & SSL_OP_NO_TLSv1_1)) {
+ !(ssl->options & SSL_OP_NO_TLSv1_1)) {
version = TLS1_1_VERSION;
- } else if (client_version >= TLS1_VERSION && !(s->options & SSL_OP_NO_TLSv1)) {
+ } else if (client_version >= TLS1_VERSION &&
+ !(ssl->options & SSL_OP_NO_TLSv1)) {
version = TLS1_VERSION;
- } else if (client_version >= SSL3_VERSION && !(s->options & SSL_OP_NO_SSLv3)) {
+ } else if (client_version >= SSL3_VERSION &&
+ !(ssl->options & SSL_OP_NO_SSLv3)) {
version = SSL3_VERSION;
}
/* Check against min_version. */
- if (version != 0 && s->min_version != 0 && version < s->min_version) {
+ if (version != 0 && ssl->min_version != 0 && version < ssl->min_version) {
return 0;
}
return version;
}
}
-uint16_t ssl3_get_max_client_version(SSL *s) {
- uint32_t options = s->options;
+uint16_t ssl3_get_max_client_version(SSL *ssl) {
+ uint32_t options = ssl->options;
uint16_t version = 0;
/* OpenSSL's API for controlling versions entails blacklisting individual
@@ -2505,15 +2418,15 @@ uint16_t ssl3_get_max_client_version(SSL *s) {
*
* By this scheme, the maximum version is the lowest version V such that V is
* enabled and V+1 is disabled or unimplemented. */
- if (SSL_IS_DTLS(s)) {
+ if (SSL_IS_DTLS(ssl)) {
if (!(options & SSL_OP_NO_DTLSv1_2)) {
version = DTLS1_2_VERSION;
}
if (!(options & SSL_OP_NO_DTLSv1) && (options & SSL_OP_NO_DTLSv1_2)) {
version = DTLS1_VERSION;
}
- if (s->max_version != 0 && version < s->max_version) {
- version = s->max_version;
+ if (ssl->max_version != 0 && version < ssl->max_version) {
+ version = ssl->max_version;
}
} else {
if (!(options & SSL_OP_NO_TLSv1_2)) {
@@ -2528,53 +2441,53 @@ uint16_t ssl3_get_max_client_version(SSL *s) {
if (!(options & SSL_OP_NO_SSLv3) && (options & SSL_OP_NO_TLSv1)) {
version = SSL3_VERSION;
}
- if (s->max_version != 0 && version > s->max_version) {
- version = s->max_version;
+ if (ssl->max_version != 0 && version > ssl->max_version) {
+ version = ssl->max_version;
}
}
return version;
}
-int ssl3_is_version_enabled(SSL *s, uint16_t version) {
- if (SSL_IS_DTLS(s)) {
- if (s->max_version != 0 && version < s->max_version) {
+int ssl3_is_version_enabled(SSL *ssl, uint16_t version) {
+ if (SSL_IS_DTLS(ssl)) {
+ if (ssl->max_version != 0 && version < ssl->max_version) {
return 0;
}
- if (s->min_version != 0 && version > s->min_version) {
+ if (ssl->min_version != 0 && version > ssl->min_version) {
return 0;
}
switch (version) {
case DTLS1_VERSION:
- return !(s->options & SSL_OP_NO_DTLSv1);
+ return !(ssl->options & SSL_OP_NO_DTLSv1);
case DTLS1_2_VERSION:
- return !(s->options & SSL_OP_NO_DTLSv1_2);
+ return !(ssl->options & SSL_OP_NO_DTLSv1_2);
default:
return 0;
}
} else {
- if (s->max_version != 0 && version > s->max_version) {
+ if (ssl->max_version != 0 && version > ssl->max_version) {
return 0;
}
- if (s->min_version != 0 && version < s->min_version) {
+ if (ssl->min_version != 0 && version < ssl->min_version) {
return 0;
}
switch (version) {
case SSL3_VERSION:
- return !(s->options & SSL_OP_NO_SSLv3);
+ return !(ssl->options & SSL_OP_NO_SSLv3);
case TLS1_VERSION:
- return !(s->options & SSL_OP_NO_TLSv1);
+ return !(ssl->options & SSL_OP_NO_TLSv1);
case TLS1_1_VERSION:
- return !(s->options & SSL_OP_NO_TLSv1_1);
+ return !(ssl->options & SSL_OP_NO_TLSv1_1);
case TLS1_2_VERSION:
- return !(s->options & SSL_OP_NO_TLSv1_2);
+ return !(ssl->options & SSL_OP_NO_TLSv1_2);
default:
return 0;
@@ -2582,8 +2495,8 @@ int ssl3_is_version_enabled(SSL *s, uint16_t version) {
}
}
-uint16_t ssl3_version_from_wire(SSL *s, uint16_t wire_version) {
- if (!SSL_IS_DTLS(s)) {
+uint16_t ssl3_version_from_wire(SSL *ssl, uint16_t wire_version) {
+ if (!SSL_IS_DTLS(ssl)) {
return wire_version;
}
diff --git a/src/ssl/ssl_rsa.c b/src/ssl/ssl_rsa.c
index 512a41f..990979b 100644
--- a/src/ssl/ssl_rsa.c
+++ b/src/ssl/ssl_rsa.c
@@ -56,6 +56,8 @@
#include <openssl/ssl.h>
+#include <limits.h>
+
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
@@ -79,18 +81,22 @@ int SSL_use_certificate(SSL *ssl, X509 *x) {
return ssl_set_cert(ssl->cert, x);
}
-int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *d, int len) {
- X509 *x;
- int ret;
+int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) {
+ if (der_len > LONG_MAX) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ return 0;
+ }
- x = d2i_X509(NULL, &d, (long)len);
- if (x == NULL) {
+ const uint8_t *p = der;
+ X509 *x509 = d2i_X509(NULL, &p, (long)der_len);
+ if (x509 == NULL || p != der + der_len) {
OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
+ X509_free(x509);
return 0;
}
- ret = SSL_use_certificate(ssl, x);
- X509_free(x);
+ int ret = SSL_use_certificate(ssl, x509);
+ X509_free(x509);
return ret;
}
@@ -165,19 +171,22 @@ int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) {
return ret;
}
-int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const uint8_t *d, long len) {
- int ret;
- const uint8_t *p;
- EVP_PKEY *pkey;
+int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const uint8_t *der,
+ size_t der_len) {
+ if (der_len > LONG_MAX) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ return 0;
+ }
- p = d;
- pkey = d2i_PrivateKey(type, NULL, &p, (long)len);
- if (pkey == NULL) {
+ const uint8_t *p = der;
+ EVP_PKEY *pkey = d2i_PrivateKey(type, NULL, &p, (long)der_len);
+ if (pkey == NULL || p != der + der_len) {
OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
+ EVP_PKEY_free(pkey);
return 0;
}
- ret = SSL_use_PrivateKey(ssl, pkey);
+ int ret = SSL_use_PrivateKey(ssl, pkey);
EVP_PKEY_free(pkey);
return ret;
}
@@ -227,18 +236,23 @@ static int ssl_set_cert(CERT *c, X509 *x) {
return 1;
}
-int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const uint8_t *d) {
- X509 *x;
- int ret;
+int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, size_t der_len,
+ const uint8_t *der) {
+ if (der_len > LONG_MAX) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ return 0;
+ }
- x = d2i_X509(NULL, &d, (long)len);
- if (x == NULL) {
+ const uint8_t *p = der;
+ X509 *x509 = d2i_X509(NULL, &p, (long)der_len);
+ if (x509 == NULL || p != der + der_len) {
OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
+ X509_free(x509);
return 0;
}
- ret = SSL_CTX_use_certificate(ctx, x);
- X509_free(x);
+ int ret = SSL_CTX_use_certificate(ctx, x509);
+ X509_free(x509);
return ret;
}
@@ -287,20 +301,22 @@ int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) {
return ssl_set_pkey(ctx->cert, pkey);
}
-int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const uint8_t *d,
- long len) {
- int ret;
- const uint8_t *p;
- EVP_PKEY *pkey;
+int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const uint8_t *der,
+ size_t der_len) {
+ if (der_len > LONG_MAX) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ return 0;
+ }
- p = d;
- pkey = d2i_PrivateKey(type, NULL, &p, (long)len);
- if (pkey == NULL) {
+ const uint8_t *p = der;
+ EVP_PKEY *pkey = d2i_PrivateKey(type, NULL, &p, (long)der_len);
+ if (pkey == NULL || p != der + der_len) {
OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
+ EVP_PKEY_free(pkey);
return 0;
}
- ret = SSL_CTX_use_PrivateKey(ctx, pkey);
+ int ret = SSL_CTX_use_PrivateKey(ctx, pkey);
EVP_PKEY_free(pkey);
return ret;
}
@@ -385,20 +401,19 @@ enum ssl_private_key_result_t ssl_private_key_decrypt(
in_len);
}
- if (ssl_private_key_type(ssl) != EVP_PKEY_RSA) {
+ RSA *rsa = EVP_PKEY_get0_RSA(ssl->cert->privatekey);
+ if (rsa == NULL) {
/* Decrypt operations are only supported for RSA keys. */
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return ssl_private_key_failure;
}
- enum ssl_private_key_result_t ret = ssl_private_key_failure;
- RSA *rsa = ssl->cert->privatekey->pkey.rsa;
/* Decrypt with no padding. PKCS#1 padding will be removed as part
* of the timing-sensitive code by the caller. */
- if (RSA_decrypt(rsa, out_len, out, max_out, in, in_len, RSA_NO_PADDING)) {
- ret = ssl_private_key_success;
+ if (!RSA_decrypt(rsa, out_len, out, max_out, in, in_len, RSA_NO_PADDING)) {
+ return ssl_private_key_failure;
}
- return ret;
+ return ssl_private_key_success;
}
enum ssl_private_key_result_t ssl_private_key_decrypt_complete(
diff --git a/src/ssl/ssl_session.c b/src/ssl/ssl_session.c
index ead0b75..3d59bc3 100644
--- a/src/ssl/ssl_session.c
+++ b/src/ssl/ssl_session.c
@@ -172,7 +172,7 @@ SSL_SESSION *SSL_SESSION_new(void) {
session->references = 1;
session->timeout = SSL_DEFAULT_SESSION_TIMEOUT;
session->time = (unsigned long)time(NULL);
- CRYPTO_new_ex_data(&g_ex_data_class, session, &session->ex_data);
+ CRYPTO_new_ex_data(&session->ex_data);
return session;
}
@@ -278,12 +278,13 @@ SSL_SESSION *SSL_get1_session(SSL *ssl) {
return SSL_SESSION_up_ref(ssl->session);
}
-int SSL_SESSION_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+int SSL_SESSION_get_ex_new_index(long argl, void *argp,
+ CRYPTO_EX_unused *unused,
CRYPTO_EX_dup *dup_func,
CRYPTO_EX_free *free_func) {
int index;
- if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, new_func,
- dup_func, free_func)) {
+ if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func,
+ free_func)) {
return -1;
}
return index;
@@ -644,10 +645,10 @@ void SSL_CTX_flush_sessions(SSL_CTX *ctx, long time) {
CRYPTO_MUTEX_unlock(&ctx->lock);
}
-int ssl_clear_bad_session(SSL *s) {
- if (s->session != NULL && !(s->shutdown & SSL_SENT_SHUTDOWN) &&
- !SSL_in_init(s)) {
- SSL_CTX_remove_session(s->ctx, s->session);
+int ssl_clear_bad_session(SSL *ssl) {
+ if (ssl->session != NULL && !(ssl->shutdown & SSL_SENT_SHUTDOWN) &&
+ !SSL_in_init(ssl)) {
+ SSL_CTX_remove_session(ssl->ctx, ssl->session);
return 1;
}
diff --git a/src/ssl/ssl_test.cc b/src/ssl/ssl_test.cc
index 0cd42a2..9558f1c 100644
--- a/src/ssl/ssl_test.cc
+++ b/src/ssl/ssl_test.cc
@@ -50,7 +50,9 @@ static const char kRule1[] =
"ECDHE-RSA-AES128-GCM-SHA256";
static const ExpectedCipher kExpected1[] = {
+ { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
{ TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 },
+ { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
{ TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 },
{ TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
{ TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
@@ -67,8 +69,10 @@ static const char kRule2[] =
"+aRSA";
static const ExpectedCipher kExpected2[] = {
+ { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
{ TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 },
{ TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
+ { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
{ TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 },
{ TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
{ 0, 0 },
@@ -83,6 +87,7 @@ static const char kRule3[] =
"ECDHE-RSA-AES128-GCM-SHA256";
static const ExpectedCipher kExpected3[] = {
+ { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
{ TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 },
{ TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
{ 0, 0 },
@@ -119,7 +124,9 @@ static const char kRule6[] =
"BOGUS1:-BOGUS2:+BOGUS3:!BOGUS4";
static const ExpectedCipher kExpected6[] = {
+ { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
{ TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 },
+ { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
{ TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 },
{ TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
{ TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
@@ -133,8 +140,10 @@ static const char kRule7[] =
"ECDHE-RSA-AES128-GCM-SHA256";
static const ExpectedCipher kExpected7[] = {
+ { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1 },
{ TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 1 },
{ TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
+ { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 1 },
{ TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 },
{ TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
{ 0, 0 },
@@ -157,6 +166,7 @@ static const char kRule8[] =
static const ExpectedCipher kExpected8[] = {
{ TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0 },
+ { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
{ TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 },
{ TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, 0 },
{ TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0 },
@@ -169,13 +179,55 @@ static const ExpectedCipher kExpected8[] = {
// Exact ciphers may not be used in multi-part rules; they are treated
// as unknown aliases.
static const char kRule9[] =
+ "ECDHE-ECDSA-AES128-GCM-SHA256:"
+ "ECDHE-RSA-AES128-GCM-SHA256:"
+ "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
+ "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256";
+
+static const ExpectedCipher kExpected9[] = {
+ { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
+ { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
+ { 0, 0 },
+};
+
+// SSLv3 matches everything that existed before TLS 1.2.
+static const char kRule10[] = "AES128-SHA:AES128-SHA256:!SSLv3";
+
+static const ExpectedCipher kExpected10[] = {
+ { TLS1_CK_RSA_WITH_AES_128_SHA256, 0 },
+ { 0, 0 },
+};
+
+// TLSv1.2 matches everything added in TLS 1.2.
+static const char kRule11[] = "AES128-SHA:AES128-SHA256:!TLSv1.2";
+
+static const ExpectedCipher kExpected11[] = {
+ { TLS1_CK_RSA_WITH_AES_128_SHA, 0 },
+ { 0, 0 },
+};
+
+// The two directives have no intersection.
+static const char kRule12[] = "AES128-SHA:AES128-SHA256:!TLSv1.2+SSLv3";
+
+static const ExpectedCipher kExpected12[] = {
+ { TLS1_CK_RSA_WITH_AES_128_SHA, 0 },
+ { TLS1_CK_RSA_WITH_AES_128_SHA256, 0 },
+ { 0, 0 },
+};
+
+// The shared name of the CHACHA20_POLY1305 variants behaves like a cipher name
+// and not an alias. It may not be used in a multipart rule. (That the shared
+// name works is covered by the standard tests.)
+static const char kRule13[] =
"ECDHE-ECDSA-CHACHA20-POLY1305:"
"ECDHE-RSA-CHACHA20-POLY1305:"
"!ECDHE-RSA-CHACHA20-POLY1305+RSA:"
"!ECDSA+ECDHE-ECDSA-CHACHA20-POLY1305";
-static const ExpectedCipher kExpected9[] = {
+static const ExpectedCipher kExpected13[] = {
+ { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
{ TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 },
+ { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0 },
{ TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 },
{ 0, 0 },
};
@@ -190,6 +242,10 @@ static CipherTest kCipherTests[] = {
{ kRule7, kExpected7 },
{ kRule8, kExpected8 },
{ kRule9, kExpected9 },
+ { kRule10, kExpected10 },
+ { kRule11, kExpected11 },
+ { kRule12, kExpected12 },
+ { kRule13, kExpected13 },
{ NULL, NULL },
};
@@ -222,6 +278,8 @@ static const char *kMustNotIncludeNull[] = {
"DEFAULT",
"ALL:!eNULL",
"ALL:!NULL",
+ "MEDIUM",
+ "HIGH",
"FIPS",
"SHA",
"SHA1",
@@ -521,7 +579,7 @@ static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
}
out->resize(len);
- if (!EVP_DecodeBase64(bssl::vector_data(out), &len, len, (const uint8_t *)in,
+ if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
strlen(in))) {
fprintf(stderr, "EVP_DecodeBase64 failed\n");
return false;
@@ -541,8 +599,7 @@ static bool TestSSL_SESSIONEncoding(const char *input_b64) {
}
// Verify the SSL_SESSION decodes.
- ScopedSSL_SESSION session(SSL_SESSION_from_bytes(bssl::vector_data(&input),
- input.size()));
+ ScopedSSL_SESSION session(SSL_SESSION_from_bytes(input.data(), input.size()));
if (!session) {
fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
return false;
@@ -558,7 +615,7 @@ static bool TestSSL_SESSIONEncoding(const char *input_b64) {
}
encoded.reset(encoded_raw);
if (encoded_len != input.size() ||
- memcmp(bssl::vector_data(&input), encoded.get(), input.size()) != 0) {
+ memcmp(input.data(), encoded.get(), input.size()) != 0) {
fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
hexdump(stderr, "Before: ", input.data(), input.size());
hexdump(stderr, "After: ", encoded_raw, encoded_len);
@@ -566,9 +623,9 @@ static bool TestSSL_SESSIONEncoding(const char *input_b64) {
}
// Verify the SSL_SESSION also decodes with the legacy API.
- cptr = bssl::vector_data(&input);
+ cptr = input.data();
session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
- if (!session || cptr != bssl::vector_data(&input) + input.size()) {
+ if (!session || cptr != input.data() + input.size()) {
fprintf(stderr, "d2i_SSL_SESSION failed\n");
return false;
}
@@ -596,7 +653,7 @@ static bool TestSSL_SESSIONEncoding(const char *input_b64) {
fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
return false;
}
- if (memcmp(bssl::vector_data(&input), encoded.get(), input.size()) != 0) {
+ if (memcmp(input.data(), encoded.get(), input.size()) != 0) {
fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
return false;
}
@@ -611,8 +668,7 @@ static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
}
// Verify that the SSL_SESSION fails to decode.
- ScopedSSL_SESSION session(SSL_SESSION_from_bytes(bssl::vector_data(&input),
- input.size()));
+ ScopedSSL_SESSION session(SSL_SESSION_from_bytes(input.data(), input.size()));
if (session) {
fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
return false;
@@ -668,6 +724,8 @@ static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
{ TLS1_CK_PSK_WITH_RC4_128_SHA, "TLS_PSK_WITH_RC4_SHA" },
{ TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
"TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA" },
+ { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
+ "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
// These names are non-standard:
{ TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD,
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
@@ -700,8 +758,7 @@ static ScopedSSL_SESSION CreateSessionWithTicket(size_t ticket_len) {
if (!DecodeBase64(&der, kOpenSSLSession)) {
return nullptr;
}
- ScopedSSL_SESSION session(SSL_SESSION_from_bytes(bssl::vector_data(&der),
- der.size()));
+ ScopedSSL_SESSION session(SSL_SESSION_from_bytes(der.data(), der.size()));
if (!session) {
return nullptr;
}
diff --git a/src/ssl/t1_enc.c b/src/ssl/t1_enc.c
index 076f8bd..0f1d683 100644
--- a/src/ssl/t1_enc.c
+++ b/src/ssl/t1_enc.c
@@ -159,40 +159,36 @@ static int tls1_P_hash(uint8_t *out, size_t out_len, const EVP_MD *md,
const uint8_t *seed1, size_t seed1_len,
const uint8_t *seed2, size_t seed2_len,
const uint8_t *seed3, size_t seed3_len) {
- size_t chunk;
HMAC_CTX ctx, ctx_tmp, ctx_init;
uint8_t A1[EVP_MAX_MD_SIZE];
unsigned A1_len;
int ret = 0;
- chunk = EVP_MD_size(md);
+ size_t chunk = EVP_MD_size(md);
HMAC_CTX_init(&ctx);
HMAC_CTX_init(&ctx_tmp);
HMAC_CTX_init(&ctx_init);
if (!HMAC_Init_ex(&ctx_init, secret, secret_len, md, NULL) ||
!HMAC_CTX_copy_ex(&ctx, &ctx_init) ||
- (seed1_len && !HMAC_Update(&ctx, seed1, seed1_len)) ||
- (seed2_len && !HMAC_Update(&ctx, seed2, seed2_len)) ||
- (seed3_len && !HMAC_Update(&ctx, seed3, seed3_len)) ||
+ !HMAC_Update(&ctx, seed1, seed1_len) ||
+ !HMAC_Update(&ctx, seed2, seed2_len) ||
+ !HMAC_Update(&ctx, seed3, seed3_len) ||
!HMAC_Final(&ctx, A1, &A1_len)) {
goto err;
}
for (;;) {
- /* Reinit mac contexts. */
+ unsigned len;
+ uint8_t hmac[EVP_MAX_MD_SIZE];
if (!HMAC_CTX_copy_ex(&ctx, &ctx_init) ||
!HMAC_Update(&ctx, A1, A1_len) ||
+ /* Save a copy of |ctx| to compute the next A1 value below. */
(out_len > chunk && !HMAC_CTX_copy_ex(&ctx_tmp, &ctx)) ||
- (seed1_len && !HMAC_Update(&ctx, seed1, seed1_len)) ||
- (seed2_len && !HMAC_Update(&ctx, seed2, seed2_len)) ||
- (seed3_len && !HMAC_Update(&ctx, seed3, seed3_len))) {
- goto err;
- }
-
- unsigned len;
- uint8_t hmac[EVP_MAX_MD_SIZE];
- if (!HMAC_Final(&ctx, hmac, &len)) {
+ !HMAC_Update(&ctx, seed1, seed1_len) ||
+ !HMAC_Update(&ctx, seed2, seed2_len) ||
+ !HMAC_Update(&ctx, seed3, seed3_len) ||
+ !HMAC_Final(&ctx, hmac, &len)) {
goto err;
}
assert(len == chunk);
@@ -228,7 +224,7 @@ err:
return ret;
}
-int tls1_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret,
+int tls1_prf(SSL *ssl, uint8_t *out, size_t out_len, const uint8_t *secret,
size_t secret_len, const char *label, size_t label_len,
const uint8_t *seed1, size_t seed1_len,
const uint8_t *seed2, size_t seed2_len) {
@@ -239,7 +235,7 @@ int tls1_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret,
memset(out, 0, out_len);
- uint32_t algorithm_prf = ssl_get_algorithm_prf(s);
+ uint32_t algorithm_prf = ssl_get_algorithm_prf(ssl);
if (algorithm_prf == SSL_HANDSHAKE_MAC_DEFAULT) {
/* If using the MD5/SHA1 PRF, |secret| is partitioned between SHA-1 and
* MD5, MD5 first. */
@@ -264,17 +260,15 @@ int tls1_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret,
return 1;
}
-static int tls1_generate_key_block(SSL *s, uint8_t *out, size_t out_len) {
- return s->enc_method->prf(s, out, out_len, s->session->master_key,
- s->session->master_key_length,
- TLS_MD_KEY_EXPANSION_CONST,
- TLS_MD_KEY_EXPANSION_CONST_SIZE,
- s->s3->server_random, SSL3_RANDOM_SIZE,
- s->s3->client_random,
- SSL3_RANDOM_SIZE);
+static int tls1_generate_key_block(SSL *ssl, uint8_t *out, size_t out_len) {
+ return ssl->enc_method->prf(
+ ssl, out, out_len, ssl->session->master_key,
+ ssl->session->master_key_length, TLS_MD_KEY_EXPANSION_CONST,
+ TLS_MD_KEY_EXPANSION_CONST_SIZE, ssl->s3->server_random, SSL3_RANDOM_SIZE,
+ ssl->s3->client_random, SSL3_RANDOM_SIZE);
}
-int tls1_change_cipher_state(SSL *s, int which) {
+int tls1_change_cipher_state(SSL *ssl, int which) {
/* is_read is true if we have just read a ChangeCipherSpec message - i.e. we
* need to update the read cipherspec. Otherwise we have just written one. */
const char is_read = (which & SSL3_CC_READ) != 0;
@@ -286,17 +280,28 @@ int tls1_change_cipher_state(SSL *s, int which) {
const uint8_t *client_write_mac_secret, *server_write_mac_secret, *mac_secret;
const uint8_t *client_write_key, *server_write_key, *key;
const uint8_t *client_write_iv, *server_write_iv, *iv;
- const EVP_AEAD *aead = s->s3->tmp.new_aead;
+ const EVP_AEAD *aead = ssl->s3->tmp.new_aead;
size_t key_len, iv_len, mac_secret_len;
const uint8_t *key_data;
/* Reset sequence number to zero. */
- if (!SSL_IS_DTLS(s)) {
- memset(is_read ? s->s3->read_sequence : s->s3->write_sequence, 0, 8);
+ if (is_read) {
+ if (SSL_IS_DTLS(ssl)) {
+ ssl->d1->r_epoch++;
+ memset(&ssl->d1->bitmap, 0, sizeof(ssl->d1->bitmap));
+ }
+ memset(ssl->s3->read_sequence, 0, sizeof(ssl->s3->read_sequence));
+ } else {
+ if (SSL_IS_DTLS(ssl)) {
+ ssl->d1->w_epoch++;
+ memcpy(ssl->d1->last_write_sequence, ssl->s3->write_sequence,
+ sizeof(ssl->s3->write_sequence));
+ }
+ memset(ssl->s3->write_sequence, 0, sizeof(ssl->s3->write_sequence));
}
- mac_secret_len = s->s3->tmp.new_mac_secret_len;
- iv_len = s->s3->tmp.new_fixed_iv_len;
+ mac_secret_len = ssl->s3->tmp.new_mac_secret_len;
+ iv_len = ssl->s3->tmp.new_fixed_iv_len;
if (aead == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
@@ -315,7 +320,7 @@ int tls1_change_cipher_state(SSL *s, int which) {
key_len -= mac_secret_len + iv_len;
}
- key_data = s->s3->tmp.key_block;
+ key_data = ssl->s3->tmp.key_block;
client_write_mac_secret = key_data;
key_data += mac_secret_len;
server_write_mac_secret = key_data;
@@ -339,58 +344,46 @@ int tls1_change_cipher_state(SSL *s, int which) {
iv = server_write_iv;
}
- if (key_data - s->s3->tmp.key_block != s->s3->tmp.key_block_length) {
+ if (key_data - ssl->s3->tmp.key_block != ssl->s3->tmp.key_block_length) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return 0;
}
if (is_read) {
- SSL_AEAD_CTX_free(s->aead_read_ctx);
- s->aead_read_ctx = SSL_AEAD_CTX_new(
- evp_aead_open, ssl3_version_from_wire(s, s->version),
- s->s3->tmp.new_cipher, key, key_len, mac_secret, mac_secret_len, iv,
+ SSL_AEAD_CTX_free(ssl->aead_read_ctx);
+ ssl->aead_read_ctx = SSL_AEAD_CTX_new(
+ evp_aead_open, ssl3_version_from_wire(ssl, ssl->version),
+ ssl->s3->tmp.new_cipher, key, key_len, mac_secret, mac_secret_len, iv,
iv_len);
- return s->aead_read_ctx != NULL;
+ return ssl->aead_read_ctx != NULL;
}
- SSL_AEAD_CTX_free(s->aead_write_ctx);
- s->aead_write_ctx = SSL_AEAD_CTX_new(
- evp_aead_seal, ssl3_version_from_wire(s, s->version),
- s->s3->tmp.new_cipher, key, key_len, mac_secret, mac_secret_len, iv,
+ SSL_AEAD_CTX_free(ssl->aead_write_ctx);
+ ssl->aead_write_ctx = SSL_AEAD_CTX_new(
+ evp_aead_seal, ssl3_version_from_wire(ssl, ssl->version),
+ ssl->s3->tmp.new_cipher, key, key_len, mac_secret, mac_secret_len, iv,
iv_len);
- if (s->aead_write_ctx == NULL) {
- return 0;
- }
-
- s->s3->need_record_splitting = 0;
- if (!SSL_USE_EXPLICIT_IV(s) &&
- (s->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0 &&
- SSL_CIPHER_is_block_cipher(s->s3->tmp.new_cipher)) {
- /* Enable 1/n-1 record-splitting to randomize the IV. See
- * https://www.openssl.org/~bodo/tls-cbc.txt and the BEAST attack. */
- s->s3->need_record_splitting = 1;
- }
- return 1;
+ return ssl->aead_write_ctx != NULL;
}
-int tls1_setup_key_block(SSL *s) {
+int tls1_setup_key_block(SSL *ssl) {
uint8_t *p;
const EVP_AEAD *aead = NULL;
int ret = 0;
size_t mac_secret_len, fixed_iv_len, variable_iv_len, key_len;
size_t key_block_len;
- if (s->s3->tmp.key_block_length != 0) {
+ if (ssl->s3->tmp.key_block_length != 0) {
return 1;
}
- if (s->session->cipher == NULL) {
+ if (ssl->session->cipher == NULL) {
goto cipher_unavailable_err;
}
if (!ssl_cipher_get_evp_aead(&aead, &mac_secret_len, &fixed_iv_len,
- s->session->cipher,
- ssl3_version_from_wire(s, s->version))) {
+ ssl->session->cipher,
+ ssl3_version_from_wire(ssl, ssl->version))) {
goto cipher_unavailable_err;
}
key_len = EVP_AEAD_key_length(aead);
@@ -417,15 +410,15 @@ int tls1_setup_key_block(SSL *s) {
assert(fixed_iv_len < 256);
assert(variable_iv_len < 256);
- s->s3->tmp.new_aead = aead;
- s->s3->tmp.new_mac_secret_len = (uint8_t)mac_secret_len;
- s->s3->tmp.new_fixed_iv_len = (uint8_t)fixed_iv_len;
- s->s3->tmp.new_variable_iv_len = (uint8_t)variable_iv_len;
+ ssl->s3->tmp.new_aead = aead;
+ ssl->s3->tmp.new_mac_secret_len = (uint8_t)mac_secret_len;
+ ssl->s3->tmp.new_fixed_iv_len = (uint8_t)fixed_iv_len;
+ ssl->s3->tmp.new_variable_iv_len = (uint8_t)variable_iv_len;
key_block_len = key_len + mac_secret_len + fixed_iv_len;
key_block_len *= 2;
- ssl3_cleanup_key_block(s);
+ ssl3_cleanup_key_block(ssl);
p = (uint8_t *)OPENSSL_malloc(key_block_len);
if (p == NULL) {
@@ -433,10 +426,10 @@ int tls1_setup_key_block(SSL *s) {
goto err;
}
- s->s3->tmp.key_block_length = key_block_len;
- s->s3->tmp.key_block = p;
+ ssl->s3->tmp.key_block_length = key_block_len;
+ ssl->s3->tmp.key_block = p;
- if (!tls1_generate_key_block(s, p, key_block_len)) {
+ if (!tls1_generate_key_block(ssl, p, key_block_len)) {
goto err;
}
@@ -450,12 +443,12 @@ cipher_unavailable_err:
return 0;
}
-int tls1_cert_verify_mac(SSL *s, int md_nid, uint8_t *out) {
+int tls1_cert_verify_mac(SSL *ssl, int md_nid, uint8_t *out) {
const EVP_MD_CTX *ctx_template;
if (md_nid == NID_md5) {
- ctx_template = &s->s3->handshake_md5;
- } else if (md_nid == EVP_MD_CTX_type(&s->s3->handshake_hash)) {
- ctx_template = &s->s3->handshake_hash;
+ ctx_template = &ssl->s3->handshake_md5;
+ } else if (md_nid == EVP_MD_CTX_type(&ssl->s3->handshake_hash)) {
+ ctx_template = &ssl->s3->handshake_hash;
} else {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_REQUIRED_DIGEST);
return 0;
@@ -503,15 +496,15 @@ err:
* written or -1 in the event of an error. This function works on a copy of the
* underlying digests so can be called multiple times and prior to the final
* update etc. */
-int tls1_handshake_digest(SSL *s, uint8_t *out, size_t out_len) {
+int tls1_handshake_digest(SSL *ssl, uint8_t *out, size_t out_len) {
size_t md5_len = 0;
- if (EVP_MD_CTX_md(&s->s3->handshake_md5) != NULL &&
- !append_digest(&s->s3->handshake_md5, out, &md5_len, out_len)) {
+ if (EVP_MD_CTX_md(&ssl->s3->handshake_md5) != NULL &&
+ !append_digest(&ssl->s3->handshake_md5, out, &md5_len, out_len)) {
return -1;
}
size_t len;
- if (!append_digest(&s->s3->handshake_hash, out + md5_len, &len,
+ if (!append_digest(&ssl->s3->handshake_hash, out + md5_len, &len,
out_len - md5_len)) {
return -1;
}
@@ -519,24 +512,24 @@ int tls1_handshake_digest(SSL *s, uint8_t *out, size_t out_len) {
return (int)(md5_len + len);
}
-int tls1_final_finish_mac(SSL *s, const char *str, int slen, uint8_t *out) {
+int tls1_final_finish_mac(SSL *ssl, const char *str, int slen, uint8_t *out) {
uint8_t buf[2 * EVP_MAX_MD_SIZE];
int err = 0;
int digests_len;
/* At this point, the handshake should have released the handshake buffer on
* its own. */
- assert(s->s3->handshake_buffer == NULL);
+ assert(ssl->s3->handshake_buffer == NULL);
- digests_len = tls1_handshake_digest(s, buf, sizeof(buf));
+ digests_len = tls1_handshake_digest(ssl, buf, sizeof(buf));
if (digests_len < 0) {
err = 1;
digests_len = 0;
}
- if (!s->enc_method->prf(s, out, 12, s->session->master_key,
- s->session->master_key_length, str, slen, buf,
- digests_len, NULL, 0)) {
+ if (!ssl->enc_method->prf(ssl, out, 12, ssl->session->master_key,
+ ssl->session->master_key_length, str, slen, buf,
+ digests_len, NULL, 0)) {
err = 1;
}
@@ -547,27 +540,29 @@ int tls1_final_finish_mac(SSL *s, const char *str, int slen, uint8_t *out) {
}
}
-int tls1_generate_master_secret(SSL *s, uint8_t *out, const uint8_t *premaster,
+int tls1_generate_master_secret(SSL *ssl, uint8_t *out,
+ const uint8_t *premaster,
size_t premaster_len) {
- if (s->s3->tmp.extended_master_secret) {
+ if (ssl->s3->tmp.extended_master_secret) {
uint8_t digests[2 * EVP_MAX_MD_SIZE];
- int digests_len = tls1_handshake_digest(s, digests, sizeof(digests));
+ int digests_len = tls1_handshake_digest(ssl, digests, sizeof(digests));
if (digests_len == -1) {
return 0;
}
- if (!s->enc_method->prf(s, out, SSL3_MASTER_SECRET_SIZE, premaster,
- premaster_len, TLS_MD_EXTENDED_MASTER_SECRET_CONST,
- TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE, digests,
- digests_len, NULL, 0)) {
+ if (!ssl->enc_method->prf(ssl, out, SSL3_MASTER_SECRET_SIZE, premaster,
+ premaster_len,
+ TLS_MD_EXTENDED_MASTER_SECRET_CONST,
+ TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE, digests,
+ digests_len, NULL, 0)) {
return 0;
}
} else {
- if (!s->enc_method->prf(s, out, SSL3_MASTER_SECRET_SIZE, premaster,
- premaster_len, TLS_MD_MASTER_SECRET_CONST,
- TLS_MD_MASTER_SECRET_CONST_SIZE,
- s->s3->client_random, SSL3_RANDOM_SIZE,
- s->s3->server_random, SSL3_RANDOM_SIZE)) {
+ if (!ssl->enc_method->prf(ssl, out, SSL3_MASTER_SECRET_SIZE, premaster,
+ premaster_len, TLS_MD_MASTER_SECRET_CONST,
+ TLS_MD_MASTER_SECRET_CONST_SIZE,
+ ssl->s3->client_random, SSL3_RANDOM_SIZE,
+ ssl->s3->server_random, SSL3_RANDOM_SIZE)) {
return 0;
}
}
@@ -575,11 +570,11 @@ int tls1_generate_master_secret(SSL *s, uint8_t *out, const uint8_t *premaster,
return SSL3_MASTER_SECRET_SIZE;
}
-int tls1_export_keying_material(SSL *s, uint8_t *out, size_t out_len,
+int tls1_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len,
const char *label, size_t label_len,
const uint8_t *context, size_t context_len,
int use_context) {
- if (!s->s3->have_version || s->version == SSL3_VERSION) {
+ if (!ssl->s3->have_version || ssl->version == SSL3_VERSION) {
OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
@@ -598,17 +593,17 @@ int tls1_export_keying_material(SSL *s, uint8_t *out, size_t out_len,
return 0;
}
- memcpy(seed, s->s3->client_random, SSL3_RANDOM_SIZE);
- memcpy(seed + SSL3_RANDOM_SIZE, s->s3->server_random, SSL3_RANDOM_SIZE);
+ memcpy(seed, ssl->s3->client_random, SSL3_RANDOM_SIZE);
+ memcpy(seed + SSL3_RANDOM_SIZE, ssl->s3->server_random, SSL3_RANDOM_SIZE);
if (use_context) {
seed[2 * SSL3_RANDOM_SIZE] = (uint8_t)(context_len >> 8);
seed[2 * SSL3_RANDOM_SIZE + 1] = (uint8_t)context_len;
memcpy(seed + 2 * SSL3_RANDOM_SIZE + 2, context, context_len);
}
- int ret = s->enc_method->prf(s, out, out_len, s->session->master_key,
- s->session->master_key_length, label, label_len,
- seed, seed_len, NULL, 0);
+ int ret = ssl->enc_method->prf(ssl, out, out_len, ssl->session->master_key,
+ ssl->session->master_key_length, label,
+ label_len, seed, seed_len, NULL, 0);
OPENSSL_free(seed);
return ret;
}
diff --git a/src/ssl/t1_lib.c b/src/ssl/t1_lib.c
index 9a29028..5aea08b 100644
--- a/src/ssl/t1_lib.c
+++ b/src/ssl/t1_lib.c
@@ -127,8 +127,8 @@
#include "internal.h"
-static int ssl_check_clienthello_tlsext(SSL *s);
-static int ssl_check_serverhello_tlsext(SSL *s);
+static int ssl_check_clienthello_tlsext(SSL *ssl);
+static int ssl_check_serverhello_tlsext(SSL *ssl);
const SSL3_ENC_METHOD TLSv1_enc_data = {
tls1_prf,
@@ -335,126 +335,61 @@ int SSL_early_callback_ctx_extension_get(
return 0;
}
-struct tls_curve {
- uint16_t curve_id;
- int nid;
- const char curve_name[8];
-};
-
-/* ECC curves from RFC4492. */
-static const struct tls_curve tls_curves[] = {
- {21, NID_secp224r1, "P-224"},
- {23, NID_X9_62_prime256v1, "P-256"},
- {24, NID_secp384r1, "P-384"},
- {25, NID_secp521r1, "P-521"},
-};
-
static const uint16_t eccurves_default[] = {
- 23, /* X9_62_prime256v1 */
- 24, /* secp384r1 */
+ SSL_CURVE_SECP256R1,
+ SSL_CURVE_SECP384R1,
#if defined(BORINGSSL_ANDROID_SYSTEM)
- 25, /* secp521r1 */
+ SSL_CURVE_SECP521R1,
#endif
};
-int tls1_ec_curve_id2nid(uint16_t curve_id) {
- size_t i;
- for (i = 0; i < sizeof(tls_curves) / sizeof(tls_curves[0]); i++) {
- if (curve_id == tls_curves[i].curve_id) {
- return tls_curves[i].nid;
- }
- }
- return NID_undef;
-}
-
-int tls1_ec_nid2curve_id(uint16_t *out_curve_id, int nid) {
- size_t i;
- for (i = 0; i < sizeof(tls_curves) / sizeof(tls_curves[0]); i++) {
- if (nid == tls_curves[i].nid) {
- *out_curve_id = tls_curves[i].curve_id;
- return 1;
- }
- }
- return 0;
-}
-
-const char* tls1_ec_curve_id2name(uint16_t curve_id) {
- size_t i;
- for (i = 0; i < sizeof(tls_curves) / sizeof(tls_curves[0]); i++) {
- if (curve_id == tls_curves[i].curve_id) {
- return tls_curves[i].curve_name;
- }
- }
- return NULL;
-}
-
/* tls1_get_curvelist sets |*out_curve_ids| and |*out_curve_ids_len| to the
* list of allowed curve IDs. If |get_peer_curves| is non-zero, return the
* peer's curve list. Otherwise, return the preferred list. */
-static void tls1_get_curvelist(SSL *s, int get_peer_curves,
+static void tls1_get_curvelist(SSL *ssl, int get_peer_curves,
const uint16_t **out_curve_ids,
size_t *out_curve_ids_len) {
if (get_peer_curves) {
/* Only clients send a curve list, so this function is only called
* on the server. */
- assert(s->server);
- *out_curve_ids = s->s3->tmp.peer_ellipticcurvelist;
- *out_curve_ids_len = s->s3->tmp.peer_ellipticcurvelist_length;
+ assert(ssl->server);
+ *out_curve_ids = ssl->s3->tmp.peer_ellipticcurvelist;
+ *out_curve_ids_len = ssl->s3->tmp.peer_ellipticcurvelist_length;
return;
}
- *out_curve_ids = s->tlsext_ellipticcurvelist;
- *out_curve_ids_len = s->tlsext_ellipticcurvelist_length;
+ *out_curve_ids = ssl->tlsext_ellipticcurvelist;
+ *out_curve_ids_len = ssl->tlsext_ellipticcurvelist_length;
if (!*out_curve_ids) {
*out_curve_ids = eccurves_default;
*out_curve_ids_len = sizeof(eccurves_default) / sizeof(eccurves_default[0]);
}
}
-int tls1_check_curve(SSL *s, CBS *cbs, uint16_t *out_curve_id) {
- uint8_t curve_type;
- uint16_t curve_id;
- const uint16_t *curves;
- size_t curves_len, i;
-
- /* Only support named curves. */
- if (!CBS_get_u8(cbs, &curve_type) ||
- curve_type != NAMED_CURVE_TYPE ||
- !CBS_get_u16(cbs, &curve_id)) {
- return 0;
- }
-
- tls1_get_curvelist(s, 0, &curves, &curves_len);
- for (i = 0; i < curves_len; i++) {
- if (curve_id == curves[i]) {
- *out_curve_id = curve_id;
- return 1;
- }
- }
-
- return 0;
-}
-
-int tls1_get_shared_curve(SSL *s) {
+int tls1_get_shared_curve(SSL *ssl, uint16_t *out_curve_id) {
const uint16_t *curves, *peer_curves, *pref, *supp;
size_t curves_len, peer_curves_len, pref_len, supp_len, i, j;
/* Can't do anything on client side */
- if (s->server == 0) {
- return NID_undef;
+ if (ssl->server == 0) {
+ return 0;
}
- tls1_get_curvelist(s, 0 /* local curves */, &curves, &curves_len);
- tls1_get_curvelist(s, 1 /* peer curves */, &peer_curves, &peer_curves_len);
+ tls1_get_curvelist(ssl, 0 /* local curves */, &curves, &curves_len);
+ tls1_get_curvelist(ssl, 1 /* peer curves */, &peer_curves, &peer_curves_len);
if (peer_curves_len == 0) {
/* Clients are not required to send a supported_curves extension. In this
* case, the server is free to pick any curve it likes. See RFC 4492,
- * section 4, paragraph 3. */
- return (curves_len == 0) ? NID_undef : tls1_ec_curve_id2nid(curves[0]);
+ * section 4, paragraph 3.
+ *
+ * However, in the interests of compatibility, we will skip ECDH if the
+ * client didn't send an extension because we can't be sure that they'll
+ * support our favoured curve. */
+ return 0;
}
- if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) {
+ if (ssl->options & SSL_OP_CIPHER_SERVER_PREFERENCE) {
pref = curves;
pref_len = curves_len;
supp = peer_curves;
@@ -469,12 +404,13 @@ int tls1_get_shared_curve(SSL *s) {
for (i = 0; i < pref_len; i++) {
for (j = 0; j < supp_len; j++) {
if (pref[i] == supp[j]) {
- return tls1_ec_curve_id2nid(pref[i]);
+ *out_curve_id = pref[i];
+ return 1;
}
}
}
- return NID_undef;
+ return 0;
}
int tls1_set_curves(uint16_t **out_curve_ids, size_t *out_curve_ids_len,
@@ -488,7 +424,7 @@ int tls1_set_curves(uint16_t **out_curve_ids, size_t *out_curve_ids_len,
}
for (i = 0; i < ncurves; i++) {
- if (!tls1_ec_nid2curve_id(&curve_ids[i], curves[i])) {
+ if (!ssl_nid_to_curve_id(&curve_ids[i], curves[i])) {
OPENSSL_free(curve_ids);
return 0;
}
@@ -521,7 +457,7 @@ static int tls1_curve_params_from_ec_key(uint16_t *out_curve_id,
/* Determine curve ID */
nid = EC_GROUP_get_curve_name(grp);
- if (!tls1_ec_nid2curve_id(&id, nid)) {
+ if (!ssl_nid_to_curve_id(&id, nid)) {
return 0;
}
@@ -545,19 +481,19 @@ static int tls1_curve_params_from_ec_key(uint16_t *out_curve_id,
/* tls1_check_curve_id returns one if |curve_id| is consistent with both our
* and the peer's curve preferences. Note: if called as the client, only our
* preferences are checked; the peer (the server) does not send preferences. */
-static int tls1_check_curve_id(SSL *s, uint16_t curve_id) {
+int tls1_check_curve_id(SSL *ssl, uint16_t curve_id) {
const uint16_t *curves;
size_t curves_len, i, get_peer_curves;
/* Check against our list, then the peer's list. */
for (get_peer_curves = 0; get_peer_curves <= 1; get_peer_curves++) {
- if (get_peer_curves && !s->server) {
+ if (get_peer_curves && !ssl->server) {
/* Servers do not present a preference list so, if we are a client, only
* check our list. */
continue;
}
- tls1_get_curvelist(s, get_peer_curves, &curves, &curves_len);
+ tls1_get_curvelist(ssl, get_peer_curves, &curves, &curves_len);
if (get_peer_curves && curves_len == 0) {
/* Clients are not required to send a supported_curves extension. In this
* case, the server is free to pick any curve it likes. See RFC 4492,
@@ -578,16 +514,19 @@ static int tls1_check_curve_id(SSL *s, uint16_t curve_id) {
return 1;
}
-int tls1_check_ec_cert(SSL *s, X509 *x) {
+int tls1_check_ec_cert(SSL *ssl, X509 *x) {
int ret = 0;
EVP_PKEY *pkey = X509_get_pubkey(x);
uint16_t curve_id;
uint8_t comp_id;
- if (!pkey ||
- pkey->type != EVP_PKEY_EC ||
- !tls1_curve_params_from_ec_key(&curve_id, &comp_id, pkey->pkey.ec) ||
- !tls1_check_curve_id(s, curve_id) ||
+ if (!pkey) {
+ goto done;
+ }
+ EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey);
+ if (ec_key == NULL ||
+ !tls1_curve_params_from_ec_key(&curve_id, &comp_id, ec_key) ||
+ !tls1_check_curve_id(ssl, curve_id) ||
comp_id != TLSEXT_ECPOINTFORMAT_uncompressed) {
goto done;
}
@@ -599,25 +538,6 @@ done:
return ret;
}
-int tls1_check_ec_tmp_key(SSL *s) {
- if (s->cert->ecdh_nid != NID_undef) {
- /* If the curve is preconfigured, ECDH is acceptable iff the peer supports
- * the curve. */
- uint16_t curve_id;
- return tls1_ec_nid2curve_id(&curve_id, s->cert->ecdh_nid) &&
- tls1_check_curve_id(s, curve_id);
- }
-
- if (s->cert->ecdh_tmp_cb != NULL) {
- /* Assume the callback will provide an acceptable curve. */
- return 1;
- }
-
- /* Otherwise, the curve gets selected automatically. ECDH is acceptable iff
- * there is a shared curve. */
- return tls1_get_shared_curve(s) != NID_undef;
-}
-
/* List of supported signature algorithms and hashes. Should make this
* customisable at some point, for now include everything we support. */
@@ -635,7 +555,7 @@ static const uint8_t tls12_sigalgs[] = {
tlsext_sigalg(TLSEXT_hash_sha1)
};
-size_t tls12_get_psigalgs(SSL *s, const uint8_t **psigs) {
+size_t tls12_get_psigalgs(SSL *ssl, const uint8_t **psigs) {
*psigs = tls12_sigalgs;
return sizeof(tls12_sigalgs);
}
@@ -660,23 +580,6 @@ int tls12_check_peer_sigalg(SSL *ssl, const EVP_MD **out_md, int *out_alert,
return 0;
}
- if (pkey->type == EVP_PKEY_EC) {
- uint16_t curve_id;
- uint8_t comp_id;
- /* Check compression and curve matches extensions */
- if (!tls1_curve_params_from_ec_key(&curve_id, &comp_id, pkey->pkey.ec)) {
- *out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
-
- if (ssl->server && (!tls1_check_curve_id(ssl, curve_id) ||
- comp_id != TLSEXT_ECPOINTFORMAT_uncompressed)) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
- *out_alert = SSL_AD_ILLEGAL_PARAMETER;
- return 0;
- }
- }
-
/* Check signature matches a type we sent */
sent_sigslen = tls12_get_psigalgs(ssl, &sent_sigs);
for (i = 0; i < sent_sigslen; i += 2, sent_sigs += 2) {
@@ -705,8 +608,8 @@ int tls12_check_peer_sigalg(SSL *ssl, const EVP_MD **out_md, int *out_alert,
* supported or doesn't appear in supported signature algorithms. Unlike
* ssl_cipher_get_disabled this applies to a specific session and not global
* settings. */
-void ssl_set_client_disabled(SSL *s) {
- CERT *c = s->cert;
+void ssl_set_client_disabled(SSL *ssl) {
+ CERT *c = ssl->cert;
const uint8_t *sigalgs;
size_t i, sigalgslen;
int have_rsa = 0, have_ecdsa = 0;
@@ -715,7 +618,7 @@ void ssl_set_client_disabled(SSL *s) {
/* Now go through all signature algorithms seeing if we support any for RSA,
* DSA, ECDSA. Do this for all versions not just TLS 1.2. */
- sigalgslen = tls12_get_psigalgs(s, &sigalgs);
+ sigalgslen = tls12_get_psigalgs(ssl, &sigalgs);
for (i = 0; i < sigalgslen; i += 2, sigalgs += 2) {
switch (sigalgs[1]) {
case TLSEXT_signature_rsa:
@@ -737,7 +640,7 @@ void ssl_set_client_disabled(SSL *s) {
}
/* with PSK there must be client callback set */
- if (!s->psk_client_callback) {
+ if (!ssl->psk_client_callback) {
c->mask_a |= SSL_aPSK;
c->mask_k |= SSL_kPSK;
}
@@ -798,7 +701,8 @@ static int ext_sni_add_clienthello(SSL *ssl, CBB *out) {
return 1;
}
-static int ext_sni_parse_serverhello(SSL *ssl, uint8_t *out_alert, CBS *contents) {
+static int ext_sni_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
if (contents == NULL) {
return 1;
}
@@ -821,7 +725,8 @@ static int ext_sni_parse_serverhello(SSL *ssl, uint8_t *out_alert, CBS *contents
return 1;
}
-static int ext_sni_parse_clienthello(SSL *ssl, uint8_t *out_alert, CBS *contents) {
+static int ext_sni_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
if (contents == NULL) {
return 1;
}
@@ -943,23 +848,24 @@ static int ext_ri_add_clienthello(SSL *ssl, CBB *out) {
static int ext_ri_parse_serverhello(SSL *ssl, uint8_t *out_alert,
CBS *contents) {
+ /* Servers may not switch between omitting the extension and supporting it.
+ * See RFC 5746, sections 3.5 and 4.2. */
+ if (ssl->s3->initial_handshake_complete &&
+ (contents != NULL) != ssl->s3->send_connection_binding) {
+ *out_alert = SSL_AD_HANDSHAKE_FAILURE;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
+ return 0;
+ }
+
if (contents == NULL) {
- /* No renegotiation extension received.
- *
- * Strictly speaking if we want to avoid an attack we should *always* see
+ /* Strictly speaking, if we want to avoid an attack we should *always* see
* RI even on initial ServerHello because the client doesn't see any
* renegotiation during an attack. However this would mean we could not
* connect to any server which doesn't support RI.
*
- * A lack of the extension is allowed if SSL_OP_LEGACY_SERVER_CONNECT is
- * defined. */
- if (ssl->options & SSL_OP_LEGACY_SERVER_CONNECT) {
- return 1;
- }
-
- *out_alert = SSL_AD_HANDSHAKE_FAILURE;
- OPENSSL_PUT_ERROR(SSL, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
- return 0;
+ * OpenSSL has |SSL_OP_LEGACY_SERVER_CONNECT| to control this, but in
+ * practical terms every client sets it so it's just assumed here. */
+ return 1;
}
const size_t expected_len = ssl->s3->previous_client_finished_len +
@@ -1037,7 +943,8 @@ static int ext_ri_parse_clienthello(SSL *ssl, uint8_t *out_alert,
}
/* Check that the extension matches */
- if (!CBS_mem_equal(&renegotiated_connection, ssl->s3->previous_client_finished,
+ if (!CBS_mem_equal(&renegotiated_connection,
+ ssl->s3->previous_client_finished,
ssl->s3->previous_client_finished_len)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
*out_alert = SSL_AD_HANDSHAKE_FAILURE;
@@ -1101,7 +1008,8 @@ static int ext_ems_parse_serverhello(SSL *ssl, uint8_t *out_alert,
return 1;
}
-static int ext_ems_parse_clienthello(SSL *ssl, uint8_t *out_alert, CBS *contents) {
+static int ext_ems_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
if (ssl->version == SSL3_VERSION || contents == NULL) {
return 1;
}
@@ -1183,7 +1091,8 @@ static int ext_ticket_parse_serverhello(SSL *ssl, uint8_t *out_alert,
return 1;
}
-static int ext_ticket_parse_clienthello(SSL *ssl, uint8_t *out_alert, CBS *contents) {
+static int ext_ticket_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
/* This function isn't used because the ticket extension from the client is
* handled in ssl_session.c. */
return 1;
@@ -1661,7 +1570,8 @@ static int ext_alpn_add_serverhello(SSL *ssl, CBB *out) {
!CBB_add_u16_length_prefixed(out, &contents) ||
!CBB_add_u16_length_prefixed(&contents, &proto_list) ||
!CBB_add_u8_length_prefixed(&proto_list, &proto) ||
- !CBB_add_bytes(&proto, ssl->s3->alpn_selected, ssl->s3->alpn_selected_len) ||
+ !CBB_add_bytes(&proto, ssl->s3->alpn_selected,
+ ssl->s3->alpn_selected_len) ||
!CBB_flush(out)) {
return 0;
}
@@ -2217,7 +2127,6 @@ int ssl_add_clienthello_tlsext(SSL *ssl, CBB *out, size_t header_len) {
return 1;
}
- size_t orig_len = CBB_len(out);
CBB extensions;
if (!CBB_add_u16_length_prefixed(out, &extensions)) {
goto err;
@@ -2251,7 +2160,7 @@ int ssl_add_clienthello_tlsext(SSL *ssl, CBB *out, size_t header_len) {
}
if (!SSL_IS_DTLS(ssl)) {
- header_len += CBB_len(&extensions) - orig_len;
+ header_len += 2 + CBB_len(&extensions);
if (header_len > 0xff && header_len < 0x200) {
/* Add padding to workaround bugs in F5 terminators. See RFC 7685.
*
@@ -2278,10 +2187,8 @@ int ssl_add_clienthello_tlsext(SSL *ssl, CBB *out, size_t header_len) {
}
}
- /* If only two bytes have been written then the extensions are actually empty
- * and those two bytes are the zero length. In that case, we don't bother
- * sending the extensions length. */
- if (CBB_len(&extensions) - orig_len == 2) {
+ /* Discard empty extensions blocks. */
+ if (CBB_len(&extensions) == 0) {
CBB_discard_child(out);
}
@@ -2293,8 +2200,6 @@ err:
}
int ssl_add_serverhello_tlsext(SSL *ssl, CBB *out) {
- const size_t orig_len = CBB_len(out);
-
CBB extensions;
if (!CBB_add_u16_length_prefixed(out, &extensions)) {
goto err;
@@ -2318,10 +2223,8 @@ int ssl_add_serverhello_tlsext(SSL *ssl, CBB *out) {
goto err;
}
- /* If only two bytes have been written then the extensions are actually empty
- * and those two bytes are the zero length. In that case, we don't bother
- * sending the extensions length. */
- if (CBB_len(&extensions) - orig_len == 2) {
+ /* Discard empty extensions blocks. */
+ if (CBB_len(&extensions) == 0) {
CBB_discard_child(out);
}
@@ -2332,16 +2235,16 @@ err:
return 0;
}
-static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert) {
+static int ssl_scan_clienthello_tlsext(SSL *ssl, CBS *cbs, int *out_alert) {
size_t i;
for (i = 0; i < kNumExtensions; i++) {
if (kExtensions[i].init != NULL) {
- kExtensions[i].init(s);
+ kExtensions[i].init(ssl);
}
}
- s->s3->tmp.extensions.received = 0;
- s->s3->tmp.custom_extensions.received = 0;
+ ssl->s3->tmp.extensions.received = 0;
+ ssl->s3->tmp.custom_extensions.received = 0;
/* The renegotiation extension must always be at index zero because the
* |received| and |sent| bitsets need to be tweaked when the "extension" is
* sent as an SCSV. */
@@ -2370,7 +2273,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert) {
/* RFC 5746 made the existence of extensions in SSL 3.0 somewhat
* ambiguous. Ignore all but the renegotiation_info extension. */
- if (s->version == SSL3_VERSION && type != TLSEXT_TYPE_renegotiate) {
+ if (ssl->version == SSL3_VERSION && type != TLSEXT_TYPE_renegotiate) {
continue;
}
@@ -2379,16 +2282,16 @@ static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert) {
tls_extension_find(&ext_index, type);
if (ext == NULL) {
- if (!custom_ext_parse_clienthello(s, out_alert, type, &extension)) {
+ if (!custom_ext_parse_clienthello(ssl, out_alert, type, &extension)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
return 0;
}
continue;
}
- s->s3->tmp.extensions.received |= (1u << ext_index);
+ ssl->s3->tmp.extensions.received |= (1u << ext_index);
uint8_t alert = SSL_AD_DECODE_ERROR;
- if (!ext->parse_clienthello(s, &alert, &extension)) {
+ if (!ext->parse_clienthello(ssl, &alert, &extension)) {
*out_alert = alert;
OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
ERR_add_error_dataf("extension: %u", (unsigned)type);
@@ -2398,11 +2301,11 @@ static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert) {
}
for (i = 0; i < kNumExtensions; i++) {
- if (!(s->s3->tmp.extensions.received & (1u << i))) {
+ if (!(ssl->s3->tmp.extensions.received & (1u << i))) {
/* Extension wasn't observed so call the callback with a NULL
* parameter. */
uint8_t alert = SSL_AD_DECODE_ERROR;
- if (!kExtensions[i].parse_clienthello(s, &alert, NULL)) {
+ if (!kExtensions[i].parse_clienthello(ssl, &alert, NULL)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION);
ERR_add_error_dataf("extension: %u", (unsigned)kExtensions[i].value);
*out_alert = alert;
@@ -2414,14 +2317,14 @@ static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert) {
return 1;
}
-int ssl_parse_clienthello_tlsext(SSL *s, CBS *cbs) {
+int ssl_parse_clienthello_tlsext(SSL *ssl, CBS *cbs) {
int alert = -1;
- if (ssl_scan_clienthello_tlsext(s, cbs, &alert) <= 0) {
- ssl3_send_alert(s, SSL3_AL_FATAL, alert);
+ if (ssl_scan_clienthello_tlsext(ssl, cbs, &alert) <= 0) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
return 0;
}
- if (ssl_check_clienthello_tlsext(s) <= 0) {
+ if (ssl_check_clienthello_tlsext(ssl) <= 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_TLSEXT);
return 0;
}
@@ -2431,7 +2334,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, CBS *cbs) {
OPENSSL_COMPILE_ASSERT(kNumExtensions <= sizeof(uint32_t) * 8, too_many_bits);
-static int ssl_scan_serverhello_tlsext(SSL *s, CBS *cbs, int *out_alert) {
+static int ssl_scan_serverhello_tlsext(SSL *ssl, CBS *cbs, int *out_alert) {
uint32_t received = 0;
if (CBS_len(cbs) != 0) {
@@ -2460,13 +2363,13 @@ static int ssl_scan_serverhello_tlsext(SSL *s, CBS *cbs, int *out_alert) {
tls_extension_find(&ext_index, type);
if (ext == NULL) {
- if (!custom_ext_parse_serverhello(s, out_alert, type, &extension)) {
+ if (!custom_ext_parse_serverhello(ssl, out_alert, type, &extension)) {
return 0;
}
continue;
}
- if (!(s->s3->tmp.extensions.sent & (1u << ext_index))) {
+ if (!(ssl->s3->tmp.extensions.sent & (1u << ext_index))) {
/* If the extension was never sent then it is illegal. */
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
ERR_add_error_dataf("extension :%u", (unsigned)type);
@@ -2477,7 +2380,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, CBS *cbs, int *out_alert) {
received |= (1u << ext_index);
uint8_t alert = SSL_AD_DECODE_ERROR;
- if (!ext->parse_serverhello(s, &alert, &extension)) {
+ if (!ext->parse_serverhello(ssl, &alert, &extension)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
ERR_add_error_dataf("extension: %u", (unsigned)type);
*out_alert = alert;
@@ -2492,7 +2395,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, CBS *cbs, int *out_alert) {
/* Extension wasn't observed so call the callback with a NULL
* parameter. */
uint8_t alert = SSL_AD_DECODE_ERROR;
- if (!kExtensions[i].parse_serverhello(s, &alert, NULL)) {
+ if (!kExtensions[i].parse_serverhello(ssl, &alert, NULL)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION);
ERR_add_error_dataf("extension: %u", (unsigned)kExtensions[i].value);
*out_alert = alert;
@@ -2504,33 +2407,33 @@ static int ssl_scan_serverhello_tlsext(SSL *s, CBS *cbs, int *out_alert) {
return 1;
}
-static int ssl_check_clienthello_tlsext(SSL *s) {
+static int ssl_check_clienthello_tlsext(SSL *ssl) {
int ret = SSL_TLSEXT_ERR_NOACK;
int al = SSL_AD_UNRECOGNIZED_NAME;
/* The handling of the ECPointFormats extension is done elsewhere, namely in
* ssl3_choose_cipher in s3_lib.c. */
- if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) {
- ret = s->ctx->tlsext_servername_callback(s, &al,
- s->ctx->tlsext_servername_arg);
- } else if (s->initial_ctx != NULL &&
- s->initial_ctx->tlsext_servername_callback != 0) {
- ret = s->initial_ctx->tlsext_servername_callback(
- s, &al, s->initial_ctx->tlsext_servername_arg);
+ if (ssl->ctx != NULL && ssl->ctx->tlsext_servername_callback != 0) {
+ ret = ssl->ctx->tlsext_servername_callback(ssl, &al,
+ ssl->ctx->tlsext_servername_arg);
+ } else if (ssl->initial_ctx != NULL &&
+ ssl->initial_ctx->tlsext_servername_callback != 0) {
+ ret = ssl->initial_ctx->tlsext_servername_callback(
+ ssl, &al, ssl->initial_ctx->tlsext_servername_arg);
}
switch (ret) {
case SSL_TLSEXT_ERR_ALERT_FATAL:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
return -1;
case SSL_TLSEXT_ERR_ALERT_WARNING:
- ssl3_send_alert(s, SSL3_AL_WARNING, al);
+ ssl3_send_alert(ssl, SSL3_AL_WARNING, al);
return 1;
case SSL_TLSEXT_ERR_NOACK:
- s->s3->tmp.should_ack_sni = 0;
+ ssl->s3->tmp.should_ack_sni = 0;
return 1;
default:
@@ -2538,26 +2441,26 @@ static int ssl_check_clienthello_tlsext(SSL *s) {
}
}
-static int ssl_check_serverhello_tlsext(SSL *s) {
+static int ssl_check_serverhello_tlsext(SSL *ssl) {
int ret = SSL_TLSEXT_ERR_OK;
int al = SSL_AD_UNRECOGNIZED_NAME;
- if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) {
- ret = s->ctx->tlsext_servername_callback(s, &al,
- s->ctx->tlsext_servername_arg);
- } else if (s->initial_ctx != NULL &&
- s->initial_ctx->tlsext_servername_callback != 0) {
- ret = s->initial_ctx->tlsext_servername_callback(
- s, &al, s->initial_ctx->tlsext_servername_arg);
+ if (ssl->ctx != NULL && ssl->ctx->tlsext_servername_callback != 0) {
+ ret = ssl->ctx->tlsext_servername_callback(ssl, &al,
+ ssl->ctx->tlsext_servername_arg);
+ } else if (ssl->initial_ctx != NULL &&
+ ssl->initial_ctx->tlsext_servername_callback != 0) {
+ ret = ssl->initial_ctx->tlsext_servername_callback(
+ ssl, &al, ssl->initial_ctx->tlsext_servername_arg);
}
switch (ret) {
case SSL_TLSEXT_ERR_ALERT_FATAL:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
return -1;
case SSL_TLSEXT_ERR_ALERT_WARNING:
- ssl3_send_alert(s, SSL3_AL_WARNING, al);
+ ssl3_send_alert(ssl, SSL3_AL_WARNING, al);
return 1;
default:
@@ -2565,14 +2468,14 @@ static int ssl_check_serverhello_tlsext(SSL *s) {
}
}
-int ssl_parse_serverhello_tlsext(SSL *s, CBS *cbs) {
+int ssl_parse_serverhello_tlsext(SSL *ssl, CBS *cbs) {
int alert = -1;
- if (ssl_scan_serverhello_tlsext(s, cbs, &alert) <= 0) {
- ssl3_send_alert(s, SSL3_AL_FATAL, alert);
+ if (ssl_scan_serverhello_tlsext(ssl, cbs, &alert) <= 0) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
return 0;
}
- if (ssl_check_serverhello_tlsext(s) <= 0) {
+ if (ssl_check_serverhello_tlsext(ssl) <= 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_SERVERHELLO_TLSEXT);
return 0;
}
@@ -2616,9 +2519,9 @@ int tls_process_ticket(SSL *ssl, SSL_SESSION **out_session,
const uint8_t *iv = ticket + SSL_TICKET_KEY_NAME_LEN;
if (ssl_ctx->tlsext_ticket_key_cb != NULL) {
- int cb_ret = ssl_ctx->tlsext_ticket_key_cb(ssl, (uint8_t*)ticket /* name */,
- (uint8_t*)iv, &cipher_ctx, &hmac_ctx,
- 0 /* decrypt */);
+ int cb_ret = ssl_ctx->tlsext_ticket_key_cb(
+ ssl, (uint8_t *)ticket /* name */, (uint8_t *)iv, &cipher_ctx,
+ &hmac_ctx, 0 /* decrypt */);
if (cb_ret < 0) {
ret = 0;
goto done;
@@ -2732,27 +2635,15 @@ int tls12_get_sigid(int pkey_type) {
sizeof(tls12_sig) / sizeof(tls12_lookup));
}
-int tls12_get_sigandhash(SSL *ssl, uint8_t *p, const EVP_MD *md) {
- int sig_id, md_id;
+int tls12_add_sigandhash(SSL *ssl, CBB *out, const EVP_MD *md) {
+ int md_id = tls12_find_id(EVP_MD_type(md), tls12_md,
+ sizeof(tls12_md) / sizeof(tls12_lookup));
+ int sig_id = tls12_get_sigid(ssl_private_key_type(ssl));
- if (!md) {
- return 0;
- }
-
- md_id = tls12_find_id(EVP_MD_type(md), tls12_md,
- sizeof(tls12_md) / sizeof(tls12_lookup));
- if (md_id == -1) {
- return 0;
- }
-
- sig_id = tls12_get_sigid(ssl_private_key_type(ssl));
- if (sig_id == -1) {
- return 0;
- }
-
- p[0] = (uint8_t)md_id;
- p[1] = (uint8_t)sig_id;
- return 1;
+ return md_id != -1 &&
+ sig_id != -1 &&
+ CBB_add_u8(out, (uint8_t)md_id) &&
+ CBB_add_u8(out, (uint8_t)sig_id);
}
const EVP_MD *tls12_get_hash(uint8_t hash_alg) {
@@ -2921,24 +2812,25 @@ err:
}
/* tls1_record_handshake_hashes_for_channel_id records the current handshake
- * hashes in |s->session| so that Channel ID resumptions can sign that data. */
-int tls1_record_handshake_hashes_for_channel_id(SSL *s) {
+ * hashes in |ssl->session| so that Channel ID resumptions can sign that
+ * data. */
+int tls1_record_handshake_hashes_for_channel_id(SSL *ssl) {
int digest_len;
/* This function should never be called for a resumed session because the
* handshake hashes that we wish to record are for the original, full
* handshake. */
- if (s->hit) {
+ if (ssl->hit) {
return -1;
}
digest_len =
- tls1_handshake_digest(s, s->session->original_handshake_hash,
- sizeof(s->session->original_handshake_hash));
+ tls1_handshake_digest(ssl, ssl->session->original_handshake_hash,
+ sizeof(ssl->session->original_handshake_hash));
if (digest_len < 0) {
return -1;
}
- s->session->original_handshake_hash_len = digest_len;
+ ssl->session->original_handshake_hash_len = digest_len;
return 1;
}
diff --git a/src/ssl/test/bssl_shim.cc b/src/ssl/test/bssl_shim.cc
index 07ba9f5..74674a4 100644
--- a/src/ssl/test/bssl_shim.cc
+++ b/src/ssl/test/bssl_shim.cc
@@ -12,6 +12,10 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+#if !defined(__STDC_FORMAT_MACROS)
+#define __STDC_FORMAT_MACROS
+#endif
+
#include <openssl/base.h>
#if !defined(OPENSSL_WINDOWS)
@@ -20,7 +24,7 @@
#include <netinet/tcp.h>
#include <signal.h>
#include <sys/socket.h>
-#include <sys/types.h>
+#include <sys/time.h>
#include <unistd.h>
#else
#include <io.h>
@@ -32,8 +36,8 @@
#pragma comment(lib, "Ws2_32.lib")
#endif
+#include <inttypes.h>
#include <string.h>
-#include <sys/types.h>
#include <openssl/bio.h>
#include <openssl/buf.h>
@@ -42,6 +46,7 @@
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/hmac.h>
+#include <openssl/obj.h>
#include <openssl/rand.h>
#include <openssl/ssl.h>
@@ -120,9 +125,10 @@ static const TestConfig *GetConfigPtr(const SSL *ssl) {
return (const TestConfig *)SSL_get_ex_data(ssl, g_config_index);
}
-static bool SetTestState(SSL *ssl, std::unique_ptr<TestState> async) {
- if (SSL_set_ex_data(ssl, g_state_index, (void *)async.get()) == 1) {
- async.release();
+static bool SetTestState(SSL *ssl, std::unique_ptr<TestState> state) {
+ // |SSL_set_ex_data| takes ownership of |state| only on success.
+ if (SSL_set_ex_data(ssl, g_state_index, state.get()) == 1) {
+ state.release();
return true;
}
return false;
@@ -172,8 +178,8 @@ static ssl_private_key_result_t AsyncPrivateKeySign(
return ssl_private_key_failure;
}
test_state->private_key_result.resize(len);
- if (!EVP_PKEY_sign(ctx.get(), bssl::vector_data(
- &test_state->private_key_result), &len, in, in_len)) {
+ if (!EVP_PKEY_sign(ctx.get(), test_state->private_key_result.data(), &len, in,
+ in_len)) {
return ssl_private_key_failure;
}
test_state->private_key_result.resize(len);
@@ -202,7 +208,7 @@ static ssl_private_key_result_t AsyncPrivateKeySignComplete(
fprintf(stderr, "Output buffer too small.\n");
return ssl_private_key_failure;
}
- memcpy(out, bssl::vector_data(&test_state->private_key_result),
+ memcpy(out, test_state->private_key_result.data(),
test_state->private_key_result.size());
*out_len = test_state->private_key_result.size();
@@ -221,16 +227,14 @@ static ssl_private_key_result_t AsyncPrivateKeyDecrypt(
abort();
}
- EVP_PKEY *pkey = test_state->private_key.get();
- if (pkey->type != EVP_PKEY_RSA || pkey->pkey.rsa == NULL) {
+ RSA *rsa = EVP_PKEY_get0_RSA(test_state->private_key.get());
+ if (rsa == NULL) {
fprintf(stderr,
"AsyncPrivateKeyDecrypt called with incorrect key type.\n");
abort();
}
- RSA *rsa = pkey->pkey.rsa;
test_state->private_key_result.resize(RSA_size(rsa));
- if (!RSA_decrypt(rsa, out_len,
- bssl::vector_data(&test_state->private_key_result),
+ if (!RSA_decrypt(rsa, out_len, test_state->private_key_result.data(),
RSA_size(rsa), in, in_len, RSA_NO_PADDING)) {
return ssl_private_key_failure;
}
@@ -262,7 +266,7 @@ static ssl_private_key_result_t AsyncPrivateKeyDecryptComplete(
fprintf(stderr, "Output buffer too small.\n");
return ssl_private_key_failure;
}
- memcpy(out, bssl::vector_data(&test_state->private_key_result),
+ memcpy(out, test_state->private_key_result.data(),
test_state->private_key_result.size());
*out_len = test_state->private_key_result.size();
@@ -728,6 +732,24 @@ static ScopedSSL_CTX SetupCtx(const TestConfig *config) {
}
ScopedDH dh(DH_get_2048_256(NULL));
+
+ if (config->use_sparse_dh_prime) {
+ // This prime number is 2^1024 + 643 – a value just above a power of two.
+ // Because of its form, values modulo it are essentially certain to be one
+ // byte shorter. This is used to test padding of these values.
+ if (BN_hex2bn(
+ &dh->p,
+ "1000000000000000000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000000000028"
+ "3") == 0 ||
+ !BN_set_word(dh->g, 2)) {
+ return nullptr;
+ }
+ dh->priv_length = 0;
+ }
+
if (!dh || !SSL_CTX_set_tmp_dh(ssl_ctx.get(), dh.get())) {
return nullptr;
}
@@ -1070,6 +1092,15 @@ static bool CheckHandshakeProperties(SSL *ssl, bool is_resume) {
return false;
}
+ if (config->expect_key_exchange_info != 0) {
+ uint32_t info = SSL_SESSION_get_key_exchange_info(SSL_get_session(ssl));
+ if (static_cast<uint32_t>(config->expect_key_exchange_info) != info) {
+ fprintf(stderr, "key_exchange_info was %" PRIu32 ", wanted %" PRIu32 "\n",
+ info, static_cast<uint32_t>(config->expect_key_exchange_info));
+ return false;
+ }
+ }
+
if (!config->is_server) {
/* Clients should expect a peer certificate chain iff this was not a PSK
* cipher suite. */
@@ -1143,15 +1174,6 @@ static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx,
if (config->no_ssl3) {
SSL_set_options(ssl.get(), SSL_OP_NO_SSLv3);
}
- if (config->tls_d5_bug) {
- SSL_set_options(ssl.get(), SSL_OP_TLS_D5_BUG);
- }
- if (config->microsoft_big_sslv3_buffer) {
- SSL_set_options(ssl.get(), SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER);
- }
- if (config->no_legacy_server_connect) {
- SSL_clear_options(ssl.get(), SSL_OP_LEGACY_SERVER_CONNECT);
- }
if (!config->expected_channel_id.empty()) {
SSL_enable_tls_channel_id(ssl.get());
}
@@ -1223,6 +1245,21 @@ static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx,
if (config->disable_npn) {
SSL_set_options(ssl.get(), SSL_OP_DISABLE_NPN);
}
+ if (config->p384_only) {
+ int nid = NID_secp384r1;
+ if (!SSL_set1_curves(ssl.get(), &nid, 1)) {
+ return false;
+ }
+ }
+ if (config->enable_all_curves) {
+ static const int kAllCurves[] = {
+ NID_X9_62_prime256v1, NID_secp384r1, NID_secp521r1, NID_x25519,
+ };
+ if (!SSL_set1_curves(ssl.get(), kAllCurves,
+ sizeof(kAllCurves) / sizeof(kAllCurves[0]))) {
+ return false;
+ }
+ }
int sock = Connect(config->port);
if (sock == -1) {
diff --git a/src/ssl/test/packeted_bio.h b/src/ssl/test/packeted_bio.h
index 30697a5..75cfa13 100644
--- a/src/ssl/test/packeted_bio.h
+++ b/src/ssl/test/packeted_bio.h
@@ -25,7 +25,7 @@
#include <winsock2.h>
#pragma warning(pop)
#else
-#include <sys/types.h>
+#include <sys/time.h>
#endif
diff --git a/src/ssl/test/runner/chacha20_poly1305.go b/src/ssl/test/runner/chacha20_poly1305.go
index f2a1bbf..3c6ad82 100644
--- a/src/ssl/test/runner/chacha20_poly1305.go
+++ b/src/ssl/test/runner/chacha20_poly1305.go
@@ -5,11 +5,11 @@ import (
"crypto/subtle"
"encoding/binary"
"errors"
+
+ "./poly1305"
)
-// See draft-agl-tls-chacha20poly1305-04 and
-// draft-irtf-cfrg-chacha20-poly1305-10. Where the two differ, the
-// draft-agl-tls-chacha20poly1305-04 variant is implemented.
+// See RFC 7539.
func leftRotate(a uint32, n uint) uint32 {
return (a << n) | (a >> (32 - n))
@@ -62,37 +62,30 @@ func sliceForAppend(in []byte, n int) (head, tail []byte) {
return
}
-type chaCha20Poly1305 struct {
- key [32]byte
-}
-
-func newChaCha20Poly1305(key []byte) (cipher.AEAD, error) {
- if len(key) != 32 {
- return nil, errors.New("bad key length")
- }
- aead := new(chaCha20Poly1305)
- copy(aead.key[:], key)
- return aead, nil
-}
-
-func (c *chaCha20Poly1305) NonceSize() int { return 8 }
-func (c *chaCha20Poly1305) Overhead() int { return 16 }
-
-func (c *chaCha20Poly1305) chaCha20(out, in, nonce []byte, counter uint64) {
+func chaCha20(out, in, key, nonce []byte, counter uint64) {
var state [16]uint32
state[0] = 0x61707865
state[1] = 0x3320646e
state[2] = 0x79622d32
state[3] = 0x6b206574
for i := 0; i < 8; i++ {
- state[4+i] = binary.LittleEndian.Uint32(c.key[i*4 : i*4+4])
+ state[4+i] = binary.LittleEndian.Uint32(key[i*4 : i*4+4])
+ }
+
+ switch len(nonce) {
+ case 8:
+ state[14] = binary.LittleEndian.Uint32(nonce[0:4])
+ state[15] = binary.LittleEndian.Uint32(nonce[4:8])
+ case 12:
+ state[13] = binary.LittleEndian.Uint32(nonce[0:4])
+ state[14] = binary.LittleEndian.Uint32(nonce[4:8])
+ state[15] = binary.LittleEndian.Uint32(nonce[8:12])
+ default:
+ panic("bad nonce length")
}
- state[14] = binary.LittleEndian.Uint32(nonce[0:4])
- state[15] = binary.LittleEndian.Uint32(nonce[4:8])
for i := 0; i < len(in); i += 64 {
- state[12] = uint32(counter & 0xffffffff)
- state[13] = uint32(counter >> 32)
+ state[12] = uint32(counter)
var tmp [64]byte
chaCha20Block(&state, tmp[:])
@@ -108,7 +101,68 @@ func (c *chaCha20Poly1305) chaCha20(out, in, nonce []byte, counter uint64) {
}
}
+// chaCha20Poly1305 implements the AEAD from
+// RFC 7539 and draft-agl-tls-chacha20poly1305-04.
+type chaCha20Poly1305 struct {
+ key [32]byte
+ // oldMode, if true, indicates that the draft spec should be
+ // implemented rather than the final, RFC version.
+ oldMode bool
+}
+
+func newChaCha20Poly1305(key []byte) (cipher.AEAD, error) {
+ if len(key) != 32 {
+ return nil, errors.New("bad key length")
+ }
+ aead := new(chaCha20Poly1305)
+ copy(aead.key[:], key)
+ return aead, nil
+}
+
+func newChaCha20Poly1305Old(key []byte) (cipher.AEAD, error) {
+ if len(key) != 32 {
+ return nil, errors.New("bad key length")
+ }
+ aead := &chaCha20Poly1305{
+ oldMode: true,
+ }
+ copy(aead.key[:], key)
+ return aead, nil
+}
+
+func (c *chaCha20Poly1305) NonceSize() int {
+ if c.oldMode {
+ return 8
+ } else {
+ return 12
+ }
+}
+
+func (c *chaCha20Poly1305) Overhead() int { return 16 }
+
func (c *chaCha20Poly1305) poly1305(tag *[16]byte, nonce, ciphertext, additionalData []byte) {
+ input := make([]byte, 0, len(additionalData)+15+len(ciphertext)+15+8+8)
+ input = append(input, additionalData...)
+ var zeros [15]byte
+ if pad := len(input) % 16; pad != 0 {
+ input = append(input, zeros[:16-pad]...)
+ }
+ input = append(input, ciphertext...)
+ if pad := len(input) % 16; pad != 0 {
+ input = append(input, zeros[:16-pad]...)
+ }
+ input, out := sliceForAppend(input, 8)
+ binary.LittleEndian.PutUint64(out, uint64(len(additionalData)))
+ input, out = sliceForAppend(input, 8)
+ binary.LittleEndian.PutUint64(out, uint64(len(ciphertext)))
+
+ var poly1305Key [32]byte
+ chaCha20(poly1305Key[:], poly1305Key[:], c.key[:], nonce, 0)
+
+ poly1305.Sum(tag, input, &poly1305Key)
+}
+
+func (c *chaCha20Poly1305) poly1305Old(tag *[16]byte, nonce, ciphertext, additionalData []byte) {
input := make([]byte, 0, len(additionalData)+8+len(ciphertext)+8)
input = append(input, additionalData...)
input, out := sliceForAppend(input, 8)
@@ -118,28 +172,32 @@ func (c *chaCha20Poly1305) poly1305(tag *[16]byte, nonce, ciphertext, additional
binary.LittleEndian.PutUint64(out, uint64(len(ciphertext)))
var poly1305Key [32]byte
- c.chaCha20(poly1305Key[:], poly1305Key[:], nonce, 0)
+ chaCha20(poly1305Key[:], poly1305Key[:], c.key[:], nonce, 0)
- poly1305Sum(tag, input, &poly1305Key)
+ poly1305.Sum(tag, input, &poly1305Key)
}
func (c *chaCha20Poly1305) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
- if len(nonce) != 8 {
+ if len(nonce) != c.NonceSize() {
panic("Bad nonce length")
}
ret, out := sliceForAppend(dst, len(plaintext)+16)
- c.chaCha20(out[:len(plaintext)], plaintext, nonce, 1)
+ chaCha20(out[:len(plaintext)], plaintext, c.key[:], nonce, 1)
var tag [16]byte
- c.poly1305(&tag, nonce, out[:len(plaintext)], additionalData)
+ if c.oldMode {
+ c.poly1305Old(&tag, nonce, out[:len(plaintext)], additionalData)
+ } else {
+ c.poly1305(&tag, nonce, out[:len(plaintext)], additionalData)
+ }
copy(out[len(plaintext):], tag[:])
return ret
}
func (c *chaCha20Poly1305) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
- if len(nonce) != 8 {
+ if len(nonce) != c.NonceSize() {
panic("Bad nonce length")
}
if len(ciphertext) < 16 {
@@ -148,12 +206,16 @@ func (c *chaCha20Poly1305) Open(dst, nonce, ciphertext, additionalData []byte) (
plaintextLen := len(ciphertext) - 16
var tag [16]byte
- c.poly1305(&tag, nonce, ciphertext[:plaintextLen], additionalData)
+ if c.oldMode {
+ c.poly1305Old(&tag, nonce, ciphertext[:plaintextLen], additionalData)
+ } else {
+ c.poly1305(&tag, nonce, ciphertext[:plaintextLen], additionalData)
+ }
if subtle.ConstantTimeCompare(tag[:], ciphertext[plaintextLen:]) != 1 {
return nil, errors.New("chacha20: message authentication failed")
}
ret, out := sliceForAppend(dst, plaintextLen)
- c.chaCha20(out, ciphertext[:plaintextLen], nonce, 1)
+ chaCha20(out, ciphertext[:plaintextLen], c.key[:], nonce, 1)
return ret, nil
}
diff --git a/src/ssl/test/runner/chacha20_poly1305_test.go b/src/ssl/test/runner/chacha20_poly1305_test.go
index be49b11..4d19b8c 100644
--- a/src/ssl/test/runner/chacha20_poly1305_test.go
+++ b/src/ssl/test/runner/chacha20_poly1305_test.go
@@ -6,7 +6,7 @@ import (
"testing"
)
-// See draft-irtf-cfrg-chacha20-poly1305-10, section 2.1.1.
+// See RFC 7539, section 2.1.1.
func TestChaChaQuarterRound(t *testing.T) {
state := [16]uint32{0x11111111, 0x01020304, 0x9b8d6f43, 0x01234567}
chaChaQuarterRound(&state, 0, 1, 2, 3)
@@ -17,7 +17,7 @@ func TestChaChaQuarterRound(t *testing.T) {
}
}
-// See draft-irtf-cfrg-chacha20-poly1305-10, section 2.2.1.
+// See RFC 7539, section 2.2.1.
func TestChaChaQuarterRoundState(t *testing.T) {
state := [16]uint32{
0x879531e0, 0xc5ecf37d, 0x516461b1, 0xc9a62f8a,
@@ -40,7 +40,7 @@ func TestChaChaQuarterRoundState(t *testing.T) {
}
}
-// See draft-irtf-cfrg-chacha20-poly1305-10, section 2.3.2.
+// See RFC 7539, section 2.3.2.
func TestChaCha20Block(t *testing.T) {
state := [16]uint32{
0x61707865, 0x3320646e, 0x79622d32, 0x6b206574,
@@ -66,15 +66,23 @@ func TestChaCha20Block(t *testing.T) {
}
}
+func decodeHexOrPanic(in string) []byte {
+ out, err := hex.DecodeString(in)
+ if err != nil {
+ panic(err)
+ }
+ return out
+}
+
// See draft-agl-tls-chacha20poly1305-04, section 7.
-func TestChaCha20Poly1305(t *testing.T) {
- key, _ := hex.DecodeString("4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd1100a1007")
- input, _ := hex.DecodeString("86d09974840bded2a5ca")
- nonce, _ := hex.DecodeString("cd7cf67be39c794a")
- ad, _ := hex.DecodeString("87e229d4500845a079c0")
- output, _ := hex.DecodeString("e3e446f7ede9a19b62a4677dabf4e3d24b876bb284753896e1d6")
+func TestChaCha20Poly1305Old(t *testing.T) {
+ key := decodeHexOrPanic("4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd1100a1007")
+ input := decodeHexOrPanic("86d09974840bded2a5ca")
+ nonce := decodeHexOrPanic("cd7cf67be39c794a")
+ ad := decodeHexOrPanic("87e229d4500845a079c0")
+ output := decodeHexOrPanic("e3e446f7ede9a19b62a4677dabf4e3d24b876bb284753896e1d6")
- aead, err := newChaCha20Poly1305(key)
+ aead, err := newChaCha20Poly1305Old(key)
if err != nil {
t.Fatal(err)
}
@@ -97,3 +105,58 @@ func TestChaCha20Poly1305(t *testing.T) {
t.Errorf("Open on malformed data unexpectedly succeeded")
}
}
+
+var chaCha20Poly1305TestVectors = []struct {
+ key, input, nonce, ad, output string
+}{
+ {
+ // See RFC 7539, section 2.8.2.
+ key: "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ input: "4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e",
+ nonce: "070000004041424344454647",
+ ad: "50515253c0c1c2c3c4c5c6c7",
+ output: "d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b61161ae10b594f09e26a7e902ecbd0600691",
+ },
+ {
+ // See RFC 7539, section A.5.
+ key: "1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0",
+ input: "496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d",
+ nonce: "000000000102030405060708",
+ ad: "f33388860000000000004e91",
+ output: "64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709beead9d67890cbb22392336fea1851f38",
+ },
+}
+
+// See draft-agl-tls-chacha20poly1305-04, section 7.
+func TestChaCha20Poly1305(t *testing.T) {
+ for i, tt := range chaCha20Poly1305TestVectors {
+ key := decodeHexOrPanic(tt.key)
+ input := decodeHexOrPanic(tt.input)
+ nonce := decodeHexOrPanic(tt.nonce)
+ ad := decodeHexOrPanic(tt.ad)
+ output := decodeHexOrPanic(tt.output)
+
+ aead, err := newChaCha20Poly1305(key)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ out, err := aead.Open(nil, nonce, output, ad)
+ if err != nil {
+ t.Errorf("%d. Open failed: %s", i, err)
+ } else if !bytes.Equal(out, input) {
+ t.Errorf("%d. Open gave %x, wanted %x", i, out, input)
+ }
+
+ out = aead.Seal(nil, nonce, input, ad)
+ if !bytes.Equal(out, output) {
+ t.Errorf("%d. Open gave %x, wanted %x", i, out, output)
+ }
+
+ out[0]++
+ _, err = aead.Open(nil, nonce, out, ad)
+ if err == nil {
+ t.Errorf("%d. Open on malformed data unexpectedly succeeded", i)
+ }
+ }
+}
diff --git a/src/ssl/test/runner/cipher_suites.go b/src/ssl/test/runner/cipher_suites.go
index c406000..bfd31a5 100644
--- a/src/ssl/test/runner/cipher_suites.go
+++ b/src/ssl/test/runner/cipher_suites.go
@@ -86,8 +86,10 @@ type cipherSuite struct {
var cipherSuites = []*cipherSuite{
// Ciphersuite order is chosen so that ECDHE comes before plain RSA
// and RC4 comes before AES (because of the Lucky13 attack).
- {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 32, 0, 0, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadCHACHA20POLY1305},
- {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 32, 0, 0, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadCHACHA20POLY1305},
+ {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 32, 0, 12, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadCHACHA20POLY1305},
+ {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 32, 0, 12, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadCHACHA20POLY1305},
+ {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256_OLD, 32, 0, 0, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadCHACHA20POLY1305Old},
+ {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD, 32, 0, 0, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadCHACHA20POLY1305Old},
{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM},
{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadAESGCM},
{TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
@@ -119,11 +121,12 @@ var cipherSuites = []*cipherSuite{
{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil},
{TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, dheRSAKA, 0, cipher3DES, macSHA1, nil},
{TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, 0, cipher3DES, macSHA1, nil},
+ {TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, 32, 0, 12, ecdhePSKKA, suiteECDHE | suitePSK | suiteTLS12, nil, nil, aeadCHACHA20POLY1305},
+ {TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdhePSKKA, suiteECDHE | suitePSK, cipherAES, macSHA1, nil},
+ {TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdhePSKKA, suiteECDHE | suitePSK, cipherAES, macSHA1, nil},
{TLS_PSK_WITH_RC4_128_SHA, 16, 20, 0, pskKA, suiteNoDTLS | suitePSK, cipherRC4, macSHA1, nil},
{TLS_PSK_WITH_AES_128_CBC_SHA, 16, 20, 16, pskKA, suitePSK, cipherAES, macSHA1, nil},
{TLS_PSK_WITH_AES_256_CBC_SHA, 32, 20, 16, pskKA, suitePSK, cipherAES, macSHA1, nil},
- {TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdhePSKKA, suiteECDHE | suitePSK, cipherAES, macSHA1, nil},
- {TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdhePSKKA, suiteECDHE | suitePSK, cipherAES, macSHA1, nil},
{TLS_RSA_WITH_NULL_SHA, 0, 20, 0, rsaKA, suiteNoDTLS, cipherNull, macSHA1, nil},
}
@@ -248,12 +251,58 @@ func aeadAESGCM(key, fixedNonce []byte) *tlsAead {
return &tlsAead{&fixedNonceAEAD{nonce1, nonce2, aead}, true}
}
+func aeadCHACHA20POLY1305Old(key, fixedNonce []byte) *tlsAead {
+ aead, err := newChaCha20Poly1305Old(key)
+ if err != nil {
+ panic(err)
+ }
+ return &tlsAead{aead, false}
+}
+
+func xorSlice(out, in []byte) {
+ for i := range out {
+ out[i] ^= in[i]
+ }
+}
+
+// xorNonceAEAD wraps an AEAD and XORs a fixed portion of the nonce, left-padded
+// if necessary, each call.
+type xorNonceAEAD struct {
+ // sealNonce and openNonce are buffers where the larger nonce will be
+ // constructed. Since a seal and open operation may be running
+ // concurrently, there is a separate buffer for each.
+ sealNonce, openNonce []byte
+ aead cipher.AEAD
+}
+
+func (x *xorNonceAEAD) NonceSize() int { return 8 }
+func (x *xorNonceAEAD) Overhead() int { return x.aead.Overhead() }
+
+func (x *xorNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte {
+ xorSlice(x.sealNonce[len(x.sealNonce)-len(nonce):], nonce)
+ ret := x.aead.Seal(out, x.sealNonce, plaintext, additionalData)
+ xorSlice(x.sealNonce[len(x.sealNonce)-len(nonce):], nonce)
+ return ret
+}
+
+func (x *xorNonceAEAD) Open(out, nonce, plaintext, additionalData []byte) ([]byte, error) {
+ xorSlice(x.openNonce[len(x.openNonce)-len(nonce):], nonce)
+ ret, err := x.aead.Open(out, x.openNonce, plaintext, additionalData)
+ xorSlice(x.openNonce[len(x.openNonce)-len(nonce):], nonce)
+ return ret, err
+}
+
func aeadCHACHA20POLY1305(key, fixedNonce []byte) *tlsAead {
aead, err := newChaCha20Poly1305(key)
if err != nil {
panic(err)
}
- return &tlsAead{aead, false}
+
+ nonce1, nonce2 := make([]byte, len(fixedNonce)), make([]byte, len(fixedNonce))
+ copy(nonce1, fixedNonce)
+ copy(nonce2, fixedNonce)
+
+ return &tlsAead{&xorNonceAEAD{nonce1, nonce2, aead}, false}
}
// ssl30MAC implements the SSLv3 MAC function, as defined in
@@ -375,49 +424,52 @@ func mutualCipherSuite(have []uint16, want uint16) *cipherSuite {
// A list of the possible cipher suite ids. Taken from
// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
const (
- TLS_RSA_WITH_NULL_SHA uint16 = 0x0002
- TLS_RSA_WITH_RC4_128_MD5 uint16 = 0x0004
- TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005
- TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a
- TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x0016
- TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f
- TLS_DHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0x0033
- TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035
- TLS_DHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0039
- TLS_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003c
- TLS_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x003d
- TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x0067
- TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x006b
- TLS_PSK_WITH_RC4_128_SHA uint16 = 0x008a
- TLS_PSK_WITH_AES_128_CBC_SHA uint16 = 0x008c
- TLS_PSK_WITH_AES_256_CBC_SHA uint16 = 0x008d
- TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009c
- TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009d
- TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009e
- TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009f
- TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xc007
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xc009
- TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xc00a
- TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011
- TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013
- TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xc014
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc023
- TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 uint16 = 0xc024
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc027
- TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 uint16 = 0xc028
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc02c
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02f
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc030
- TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA uint16 = 0xc035
- TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA uint16 = 0xc036
- renegotiationSCSV uint16 = 0x00ff
- fallbackSCSV uint16 = 0x5600
+ TLS_RSA_WITH_NULL_SHA uint16 = 0x0002
+ TLS_RSA_WITH_RC4_128_MD5 uint16 = 0x0004
+ TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005
+ TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a
+ TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x0016
+ TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f
+ TLS_DHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0x0033
+ TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035
+ TLS_DHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0039
+ TLS_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003c
+ TLS_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x003d
+ TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x0067
+ TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x006b
+ TLS_PSK_WITH_RC4_128_SHA uint16 = 0x008a
+ TLS_PSK_WITH_AES_128_CBC_SHA uint16 = 0x008c
+ TLS_PSK_WITH_AES_256_CBC_SHA uint16 = 0x008d
+ TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009c
+ TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009d
+ TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009e
+ TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009f
+ TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xc007
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xc009
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xc00a
+ TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011
+ TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xc014
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc023
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 uint16 = 0xc024
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc027
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 uint16 = 0xc028
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc02c
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02f
+ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc030
+ TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA uint16 = 0xc035
+ TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA uint16 = 0xc036
+ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcca8
+ TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcca9
+ TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xccac
+ renegotiationSCSV uint16 = 0x00ff
+ fallbackSCSV uint16 = 0x5600
)
// Additional cipher suite IDs, not IANA-assigned.
const (
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcc13
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcc14
+ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD uint16 = 0xcc13
+ TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256_OLD uint16 = 0xcc14
)
diff --git a/src/ssl/test/runner/common.go b/src/ssl/test/runner/common.go
index 078c227..db3c675 100644
--- a/src/ssl/test/runner/common.go
+++ b/src/ssl/test/runner/common.go
@@ -98,10 +98,11 @@ const (
type CurveID uint16
const (
- CurveP224 CurveID = 21
- CurveP256 CurveID = 23
- CurveP384 CurveID = 24
- CurveP521 CurveID = 25
+ CurveP224 CurveID = 21
+ CurveP256 CurveID = 23
+ CurveP384 CurveID = 24
+ CurveP521 CurveID = 25
+ CurveX25519 CurveID = 29
)
// TLS Elliptic Curve Point Formats
@@ -399,6 +400,17 @@ const (
NumBadValues
)
+type RSABadValue int
+
+const (
+ RSABadValueNone RSABadValue = iota
+ RSABadValueCorrupt
+ RSABadValueTooLong
+ RSABadValueTooShort
+ RSABadValueWrongVersion
+ NumRSABadValues
+)
+
type ProtocolBugs struct {
// InvalidSKXSignature specifies that the signature in a
// ServerKeyExchange message should be invalid.
@@ -509,10 +521,9 @@ type ProtocolBugs struct {
// alert to be sent.
SendSpuriousAlert alert
- // RsaClientKeyExchangeVersion, if non-zero, causes the client to send a
- // ClientKeyExchange with the specified version rather than the
- // client_version when performing the RSA key exchange.
- RsaClientKeyExchangeVersion uint16
+ // BadRSAClientKeyExchange causes the client to send a corrupted RSA
+ // ClientKeyExchange which would not pass padding checks.
+ BadRSAClientKeyExchange RSABadValue
// RenewTicketOnResume causes the server to renew the session ticket and
// send a NewSessionTicket message during an abbreviated handshake.
@@ -535,11 +546,6 @@ type ProtocolBugs struct {
// closed the connection) before or after sending app data.
AlertBeforeFalseStartTest alert
- // SSL3RSAKeyExchange causes the client to always send an RSA
- // ClientKeyExchange message without the two-byte length
- // prefix, as if it were SSL3.
- SSL3RSAKeyExchange bool
-
// SkipCipherVersionCheck causes the server to negotiate
// TLS 1.2 ciphers in earlier versions of TLS.
SkipCipherVersionCheck bool
@@ -584,10 +590,18 @@ type ProtocolBugs struct {
// renegotiation handshake to be incorrect.
BadRenegotiationInfo bool
- // NoRenegotiationInfo causes the client to behave as if it
- // didn't support the renegotiation info extension.
+ // NoRenegotiationInfo disables renegotiation info support in all
+ // handshakes.
NoRenegotiationInfo bool
+ // NoRenegotiationInfoInInitial disables renegotiation info support in
+ // the initial handshake.
+ NoRenegotiationInfoInInitial bool
+
+ // NoRenegotiationInfoAfterInitial disables renegotiation info support
+ // in renegotiation handshakes.
+ NoRenegotiationInfoAfterInitial bool
+
// RequireRenegotiationInfo, if true, causes the client to return an
// error if the server doesn't reply with the renegotiation extension.
RequireRenegotiationInfo bool
@@ -787,6 +801,19 @@ type ProtocolBugs struct {
// HelloRequest handshake message to be sent before each application
// data record. This only makes sense for a server.
SendHelloRequestBeforeEveryAppDataRecord bool
+
+ // RequireDHPublicValueLen causes a fatal error if the length (in
+ // bytes) of the server's Diffie-Hellman public value is not equal to
+ // this.
+ RequireDHPublicValueLen int
+
+ // BadChangeCipherSpec, if not nil, is the body to be sent in
+ // ChangeCipherSpec records instead of {1}.
+ BadChangeCipherSpec []byte
+
+ // BadHelloRequest, if not nil, is what to send instead of a
+ // HelloRequest.
+ BadHelloRequest []byte
}
func (c *Config) serverInit() {
@@ -844,7 +871,7 @@ func (c *Config) maxVersion() uint16 {
return c.MaxVersion
}
-var defaultCurvePreferences = []CurveID{CurveP256, CurveP384, CurveP521}
+var defaultCurvePreferences = []CurveID{CurveX25519, CurveP256, CurveP384, CurveP521}
func (c *Config) curvePreferences() []CurveID {
if c == nil || len(c.CurvePreferences) == 0 {
diff --git a/src/ssl/test/runner/conn.go b/src/ssl/test/runner/conn.go
index ab9e233..cb60a92 100644
--- a/src/ssl/test/runner/conn.go
+++ b/src/ssl/test/runner/conn.go
@@ -1201,8 +1201,11 @@ func (c *Conn) handleRenegotiation() error {
func (c *Conn) Renegotiate() error {
if !c.isClient {
- helloReq := new(helloRequestMsg)
- c.writeRecord(recordTypeHandshake, helloReq.marshal())
+ helloReq := new(helloRequestMsg).marshal()
+ if c.config.Bugs.BadHelloRequest != nil {
+ helloReq = c.config.Bugs.BadHelloRequest
+ }
+ c.writeRecord(recordTypeHandshake, helloReq)
}
c.handshakeComplete = false
@@ -1414,3 +1417,18 @@ func (c *Conn) ExportKeyingMaterial(length int, label, context []byte, useContex
prfForVersion(c.vers, c.cipherSuite)(result, c.masterSecret[:], label, seed)
return result, nil
}
+
+// noRenegotiationInfo returns true if the renegotiation info extension
+// should be supported in the current handshake.
+func (c *Conn) noRenegotiationInfo() bool {
+ if c.config.Bugs.NoRenegotiationInfo {
+ return true
+ }
+ if c.cipherSuite == nil && c.config.Bugs.NoRenegotiationInfoInInitial {
+ return true
+ }
+ if c.cipherSuite != nil && c.config.Bugs.NoRenegotiationInfoAfterInitial {
+ return true
+ }
+ return false
+}
diff --git a/src/ssl/test/runner/curve25519/const_amd64.s b/src/ssl/test/runner/curve25519/const_amd64.s
new file mode 100644
index 0000000..797f9b0
--- /dev/null
+++ b/src/ssl/test/runner/curve25519/const_amd64.s
@@ -0,0 +1,20 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This code was translated into a form compatible with 6a from the public
+// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
+
+// +build amd64,!gccgo,!appengine
+
+DATA ·REDMASK51(SB)/8, $0x0007FFFFFFFFFFFF
+GLOBL ·REDMASK51(SB), 8, $8
+
+DATA ·_121666_213(SB)/8, $996687872
+GLOBL ·_121666_213(SB), 8, $8
+
+DATA ·_2P0(SB)/8, $0xFFFFFFFFFFFDA
+GLOBL ·_2P0(SB), 8, $8
+
+DATA ·_2P1234(SB)/8, $0xFFFFFFFFFFFFE
+GLOBL ·_2P1234(SB), 8, $8
diff --git a/src/ssl/test/runner/curve25519/cswap_amd64.s b/src/ssl/test/runner/curve25519/cswap_amd64.s
new file mode 100644
index 0000000..45484d1
--- /dev/null
+++ b/src/ssl/test/runner/curve25519/cswap_amd64.s
@@ -0,0 +1,88 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This code was translated into a form compatible with 6a from the public
+// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
+
+// +build amd64,!gccgo,!appengine
+
+// func cswap(inout *[5]uint64, v uint64)
+TEXT ·cswap(SB),7,$0
+ MOVQ inout+0(FP),DI
+ MOVQ v+8(FP),SI
+
+ CMPQ SI,$1
+ MOVQ 0(DI),SI
+ MOVQ 80(DI),DX
+ MOVQ 8(DI),CX
+ MOVQ 88(DI),R8
+ MOVQ SI,R9
+ CMOVQEQ DX,SI
+ CMOVQEQ R9,DX
+ MOVQ CX,R9
+ CMOVQEQ R8,CX
+ CMOVQEQ R9,R8
+ MOVQ SI,0(DI)
+ MOVQ DX,80(DI)
+ MOVQ CX,8(DI)
+ MOVQ R8,88(DI)
+ MOVQ 16(DI),SI
+ MOVQ 96(DI),DX
+ MOVQ 24(DI),CX
+ MOVQ 104(DI),R8
+ MOVQ SI,R9
+ CMOVQEQ DX,SI
+ CMOVQEQ R9,DX
+ MOVQ CX,R9
+ CMOVQEQ R8,CX
+ CMOVQEQ R9,R8
+ MOVQ SI,16(DI)
+ MOVQ DX,96(DI)
+ MOVQ CX,24(DI)
+ MOVQ R8,104(DI)
+ MOVQ 32(DI),SI
+ MOVQ 112(DI),DX
+ MOVQ 40(DI),CX
+ MOVQ 120(DI),R8
+ MOVQ SI,R9
+ CMOVQEQ DX,SI
+ CMOVQEQ R9,DX
+ MOVQ CX,R9
+ CMOVQEQ R8,CX
+ CMOVQEQ R9,R8
+ MOVQ SI,32(DI)
+ MOVQ DX,112(DI)
+ MOVQ CX,40(DI)
+ MOVQ R8,120(DI)
+ MOVQ 48(DI),SI
+ MOVQ 128(DI),DX
+ MOVQ 56(DI),CX
+ MOVQ 136(DI),R8
+ MOVQ SI,R9
+ CMOVQEQ DX,SI
+ CMOVQEQ R9,DX
+ MOVQ CX,R9
+ CMOVQEQ R8,CX
+ CMOVQEQ R9,R8
+ MOVQ SI,48(DI)
+ MOVQ DX,128(DI)
+ MOVQ CX,56(DI)
+ MOVQ R8,136(DI)
+ MOVQ 64(DI),SI
+ MOVQ 144(DI),DX
+ MOVQ 72(DI),CX
+ MOVQ 152(DI),R8
+ MOVQ SI,R9
+ CMOVQEQ DX,SI
+ CMOVQEQ R9,DX
+ MOVQ CX,R9
+ CMOVQEQ R8,CX
+ CMOVQEQ R9,R8
+ MOVQ SI,64(DI)
+ MOVQ DX,144(DI)
+ MOVQ CX,72(DI)
+ MOVQ R8,152(DI)
+ MOVQ DI,AX
+ MOVQ SI,DX
+ RET
diff --git a/src/ssl/test/runner/curve25519/curve25519.go b/src/ssl/test/runner/curve25519/curve25519.go
new file mode 100644
index 0000000..6918c47
--- /dev/null
+++ b/src/ssl/test/runner/curve25519/curve25519.go
@@ -0,0 +1,841 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// We have a implementation in amd64 assembly so this code is only run on
+// non-amd64 platforms. The amd64 assembly does not support gccgo.
+// +build !amd64 gccgo appengine
+
+package curve25519
+
+// This code is a port of the public domain, "ref10" implementation of
+// curve25519 from SUPERCOP 20130419 by D. J. Bernstein.
+
+// fieldElement represents an element of the field GF(2^255 - 19). An element
+// t, entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77
+// t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on
+// context.
+type fieldElement [10]int32
+
+func feZero(fe *fieldElement) {
+ for i := range fe {
+ fe[i] = 0
+ }
+}
+
+func feOne(fe *fieldElement) {
+ feZero(fe)
+ fe[0] = 1
+}
+
+func feAdd(dst, a, b *fieldElement) {
+ for i := range dst {
+ dst[i] = a[i] + b[i]
+ }
+}
+
+func feSub(dst, a, b *fieldElement) {
+ for i := range dst {
+ dst[i] = a[i] - b[i]
+ }
+}
+
+func feCopy(dst, src *fieldElement) {
+ for i := range dst {
+ dst[i] = src[i]
+ }
+}
+
+// feCSwap replaces (f,g) with (g,f) if b == 1; replaces (f,g) with (f,g) if b == 0.
+//
+// Preconditions: b in {0,1}.
+func feCSwap(f, g *fieldElement, b int32) {
+ var x fieldElement
+ b = -b
+ for i := range x {
+ x[i] = b & (f[i] ^ g[i])
+ }
+
+ for i := range f {
+ f[i] ^= x[i]
+ }
+ for i := range g {
+ g[i] ^= x[i]
+ }
+}
+
+// load3 reads a 24-bit, little-endian value from in.
+func load3(in []byte) int64 {
+ var r int64
+ r = int64(in[0])
+ r |= int64(in[1]) << 8
+ r |= int64(in[2]) << 16
+ return r
+}
+
+// load4 reads a 32-bit, little-endian value from in.
+func load4(in []byte) int64 {
+ var r int64
+ r = int64(in[0])
+ r |= int64(in[1]) << 8
+ r |= int64(in[2]) << 16
+ r |= int64(in[3]) << 24
+ return r
+}
+
+func feFromBytes(dst *fieldElement, src *[32]byte) {
+ h0 := load4(src[:])
+ h1 := load3(src[4:]) << 6
+ h2 := load3(src[7:]) << 5
+ h3 := load3(src[10:]) << 3
+ h4 := load3(src[13:]) << 2
+ h5 := load4(src[16:])
+ h6 := load3(src[20:]) << 7
+ h7 := load3(src[23:]) << 5
+ h8 := load3(src[26:]) << 4
+ h9 := load3(src[29:]) << 2
+
+ var carry [10]int64
+ carry[9] = (h9 + 1<<24) >> 25
+ h0 += carry[9] * 19
+ h9 -= carry[9] << 25
+ carry[1] = (h1 + 1<<24) >> 25
+ h2 += carry[1]
+ h1 -= carry[1] << 25
+ carry[3] = (h3 + 1<<24) >> 25
+ h4 += carry[3]
+ h3 -= carry[3] << 25
+ carry[5] = (h5 + 1<<24) >> 25
+ h6 += carry[5]
+ h5 -= carry[5] << 25
+ carry[7] = (h7 + 1<<24) >> 25
+ h8 += carry[7]
+ h7 -= carry[7] << 25
+
+ carry[0] = (h0 + 1<<25) >> 26
+ h1 += carry[0]
+ h0 -= carry[0] << 26
+ carry[2] = (h2 + 1<<25) >> 26
+ h3 += carry[2]
+ h2 -= carry[2] << 26
+ carry[4] = (h4 + 1<<25) >> 26
+ h5 += carry[4]
+ h4 -= carry[4] << 26
+ carry[6] = (h6 + 1<<25) >> 26
+ h7 += carry[6]
+ h6 -= carry[6] << 26
+ carry[8] = (h8 + 1<<25) >> 26
+ h9 += carry[8]
+ h8 -= carry[8] << 26
+
+ dst[0] = int32(h0)
+ dst[1] = int32(h1)
+ dst[2] = int32(h2)
+ dst[3] = int32(h3)
+ dst[4] = int32(h4)
+ dst[5] = int32(h5)
+ dst[6] = int32(h6)
+ dst[7] = int32(h7)
+ dst[8] = int32(h8)
+ dst[9] = int32(h9)
+}
+
+// feToBytes marshals h to s.
+// Preconditions:
+// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+//
+// Write p=2^255-19; q=floor(h/p).
+// Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
+//
+// Proof:
+// Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.
+// Also have |h-2^230 h9|<2^230 so |19 2^(-255)(h-2^230 h9)|<1/4.
+//
+// Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).
+// Then 0<y<1.
+//
+// Write r=h-pq.
+// Have 0<=r<=p-1=2^255-20.
+// Thus 0<=r+19(2^-255)r<r+19(2^-255)2^255<=2^255-1.
+//
+// Write x=r+19(2^-255)r+y.
+// Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q.
+//
+// Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1))
+// so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q.
+func feToBytes(s *[32]byte, h *fieldElement) {
+ var carry [10]int32
+
+ q := (19*h[9] + (1 << 24)) >> 25
+ q = (h[0] + q) >> 26
+ q = (h[1] + q) >> 25
+ q = (h[2] + q) >> 26
+ q = (h[3] + q) >> 25
+ q = (h[4] + q) >> 26
+ q = (h[5] + q) >> 25
+ q = (h[6] + q) >> 26
+ q = (h[7] + q) >> 25
+ q = (h[8] + q) >> 26
+ q = (h[9] + q) >> 25
+
+ // Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20.
+ h[0] += 19 * q
+ // Goal: Output h-2^255 q, which is between 0 and 2^255-20.
+
+ carry[0] = h[0] >> 26
+ h[1] += carry[0]
+ h[0] -= carry[0] << 26
+ carry[1] = h[1] >> 25
+ h[2] += carry[1]
+ h[1] -= carry[1] << 25
+ carry[2] = h[2] >> 26
+ h[3] += carry[2]
+ h[2] -= carry[2] << 26
+ carry[3] = h[3] >> 25
+ h[4] += carry[3]
+ h[3] -= carry[3] << 25
+ carry[4] = h[4] >> 26
+ h[5] += carry[4]
+ h[4] -= carry[4] << 26
+ carry[5] = h[5] >> 25
+ h[6] += carry[5]
+ h[5] -= carry[5] << 25
+ carry[6] = h[6] >> 26
+ h[7] += carry[6]
+ h[6] -= carry[6] << 26
+ carry[7] = h[7] >> 25
+ h[8] += carry[7]
+ h[7] -= carry[7] << 25
+ carry[8] = h[8] >> 26
+ h[9] += carry[8]
+ h[8] -= carry[8] << 26
+ carry[9] = h[9] >> 25
+ h[9] -= carry[9] << 25
+ // h10 = carry9
+
+ // Goal: Output h[0]+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
+ // Have h[0]+...+2^230 h[9] between 0 and 2^255-1;
+ // evidently 2^255 h10-2^255 q = 0.
+ // Goal: Output h[0]+...+2^230 h[9].
+
+ s[0] = byte(h[0] >> 0)
+ s[1] = byte(h[0] >> 8)
+ s[2] = byte(h[0] >> 16)
+ s[3] = byte((h[0] >> 24) | (h[1] << 2))
+ s[4] = byte(h[1] >> 6)
+ s[5] = byte(h[1] >> 14)
+ s[6] = byte((h[1] >> 22) | (h[2] << 3))
+ s[7] = byte(h[2] >> 5)
+ s[8] = byte(h[2] >> 13)
+ s[9] = byte((h[2] >> 21) | (h[3] << 5))
+ s[10] = byte(h[3] >> 3)
+ s[11] = byte(h[3] >> 11)
+ s[12] = byte((h[3] >> 19) | (h[4] << 6))
+ s[13] = byte(h[4] >> 2)
+ s[14] = byte(h[4] >> 10)
+ s[15] = byte(h[4] >> 18)
+ s[16] = byte(h[5] >> 0)
+ s[17] = byte(h[5] >> 8)
+ s[18] = byte(h[5] >> 16)
+ s[19] = byte((h[5] >> 24) | (h[6] << 1))
+ s[20] = byte(h[6] >> 7)
+ s[21] = byte(h[6] >> 15)
+ s[22] = byte((h[6] >> 23) | (h[7] << 3))
+ s[23] = byte(h[7] >> 5)
+ s[24] = byte(h[7] >> 13)
+ s[25] = byte((h[7] >> 21) | (h[8] << 4))
+ s[26] = byte(h[8] >> 4)
+ s[27] = byte(h[8] >> 12)
+ s[28] = byte((h[8] >> 20) | (h[9] << 6))
+ s[29] = byte(h[9] >> 2)
+ s[30] = byte(h[9] >> 10)
+ s[31] = byte(h[9] >> 18)
+}
+
+// feMul calculates h = f * g
+// Can overlap h with f or g.
+//
+// Preconditions:
+// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+// |g| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+//
+// Postconditions:
+// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+//
+// Notes on implementation strategy:
+//
+// Using schoolbook multiplication.
+// Karatsuba would save a little in some cost models.
+//
+// Most multiplications by 2 and 19 are 32-bit precomputations;
+// cheaper than 64-bit postcomputations.
+//
+// There is one remaining multiplication by 19 in the carry chain;
+// one *19 precomputation can be merged into this,
+// but the resulting data flow is considerably less clean.
+//
+// There are 12 carries below.
+// 10 of them are 2-way parallelizable and vectorizable.
+// Can get away with 11 carries, but then data flow is much deeper.
+//
+// With tighter constraints on inputs can squeeze carries into int32.
+func feMul(h, f, g *fieldElement) {
+ f0 := f[0]
+ f1 := f[1]
+ f2 := f[2]
+ f3 := f[3]
+ f4 := f[4]
+ f5 := f[5]
+ f6 := f[6]
+ f7 := f[7]
+ f8 := f[8]
+ f9 := f[9]
+ g0 := g[0]
+ g1 := g[1]
+ g2 := g[2]
+ g3 := g[3]
+ g4 := g[4]
+ g5 := g[5]
+ g6 := g[6]
+ g7 := g[7]
+ g8 := g[8]
+ g9 := g[9]
+ g1_19 := 19 * g1 // 1.4*2^29
+ g2_19 := 19 * g2 // 1.4*2^30; still ok
+ g3_19 := 19 * g3
+ g4_19 := 19 * g4
+ g5_19 := 19 * g5
+ g6_19 := 19 * g6
+ g7_19 := 19 * g7
+ g8_19 := 19 * g8
+ g9_19 := 19 * g9
+ f1_2 := 2 * f1
+ f3_2 := 2 * f3
+ f5_2 := 2 * f5
+ f7_2 := 2 * f7
+ f9_2 := 2 * f9
+ f0g0 := int64(f0) * int64(g0)
+ f0g1 := int64(f0) * int64(g1)
+ f0g2 := int64(f0) * int64(g2)
+ f0g3 := int64(f0) * int64(g3)
+ f0g4 := int64(f0) * int64(g4)
+ f0g5 := int64(f0) * int64(g5)
+ f0g6 := int64(f0) * int64(g6)
+ f0g7 := int64(f0) * int64(g7)
+ f0g8 := int64(f0) * int64(g8)
+ f0g9 := int64(f0) * int64(g9)
+ f1g0 := int64(f1) * int64(g0)
+ f1g1_2 := int64(f1_2) * int64(g1)
+ f1g2 := int64(f1) * int64(g2)
+ f1g3_2 := int64(f1_2) * int64(g3)
+ f1g4 := int64(f1) * int64(g4)
+ f1g5_2 := int64(f1_2) * int64(g5)
+ f1g6 := int64(f1) * int64(g6)
+ f1g7_2 := int64(f1_2) * int64(g7)
+ f1g8 := int64(f1) * int64(g8)
+ f1g9_38 := int64(f1_2) * int64(g9_19)
+ f2g0 := int64(f2) * int64(g0)
+ f2g1 := int64(f2) * int64(g1)
+ f2g2 := int64(f2) * int64(g2)
+ f2g3 := int64(f2) * int64(g3)
+ f2g4 := int64(f2) * int64(g4)
+ f2g5 := int64(f2) * int64(g5)
+ f2g6 := int64(f2) * int64(g6)
+ f2g7 := int64(f2) * int64(g7)
+ f2g8_19 := int64(f2) * int64(g8_19)
+ f2g9_19 := int64(f2) * int64(g9_19)
+ f3g0 := int64(f3) * int64(g0)
+ f3g1_2 := int64(f3_2) * int64(g1)
+ f3g2 := int64(f3) * int64(g2)
+ f3g3_2 := int64(f3_2) * int64(g3)
+ f3g4 := int64(f3) * int64(g4)
+ f3g5_2 := int64(f3_2) * int64(g5)
+ f3g6 := int64(f3) * int64(g6)
+ f3g7_38 := int64(f3_2) * int64(g7_19)
+ f3g8_19 := int64(f3) * int64(g8_19)
+ f3g9_38 := int64(f3_2) * int64(g9_19)
+ f4g0 := int64(f4) * int64(g0)
+ f4g1 := int64(f4) * int64(g1)
+ f4g2 := int64(f4) * int64(g2)
+ f4g3 := int64(f4) * int64(g3)
+ f4g4 := int64(f4) * int64(g4)
+ f4g5 := int64(f4) * int64(g5)
+ f4g6_19 := int64(f4) * int64(g6_19)
+ f4g7_19 := int64(f4) * int64(g7_19)
+ f4g8_19 := int64(f4) * int64(g8_19)
+ f4g9_19 := int64(f4) * int64(g9_19)
+ f5g0 := int64(f5) * int64(g0)
+ f5g1_2 := int64(f5_2) * int64(g1)
+ f5g2 := int64(f5) * int64(g2)
+ f5g3_2 := int64(f5_2) * int64(g3)
+ f5g4 := int64(f5) * int64(g4)
+ f5g5_38 := int64(f5_2) * int64(g5_19)
+ f5g6_19 := int64(f5) * int64(g6_19)
+ f5g7_38 := int64(f5_2) * int64(g7_19)
+ f5g8_19 := int64(f5) * int64(g8_19)
+ f5g9_38 := int64(f5_2) * int64(g9_19)
+ f6g0 := int64(f6) * int64(g0)
+ f6g1 := int64(f6) * int64(g1)
+ f6g2 := int64(f6) * int64(g2)
+ f6g3 := int64(f6) * int64(g3)
+ f6g4_19 := int64(f6) * int64(g4_19)
+ f6g5_19 := int64(f6) * int64(g5_19)
+ f6g6_19 := int64(f6) * int64(g6_19)
+ f6g7_19 := int64(f6) * int64(g7_19)
+ f6g8_19 := int64(f6) * int64(g8_19)
+ f6g9_19 := int64(f6) * int64(g9_19)
+ f7g0 := int64(f7) * int64(g0)
+ f7g1_2 := int64(f7_2) * int64(g1)
+ f7g2 := int64(f7) * int64(g2)
+ f7g3_38 := int64(f7_2) * int64(g3_19)
+ f7g4_19 := int64(f7) * int64(g4_19)
+ f7g5_38 := int64(f7_2) * int64(g5_19)
+ f7g6_19 := int64(f7) * int64(g6_19)
+ f7g7_38 := int64(f7_2) * int64(g7_19)
+ f7g8_19 := int64(f7) * int64(g8_19)
+ f7g9_38 := int64(f7_2) * int64(g9_19)
+ f8g0 := int64(f8) * int64(g0)
+ f8g1 := int64(f8) * int64(g1)
+ f8g2_19 := int64(f8) * int64(g2_19)
+ f8g3_19 := int64(f8) * int64(g3_19)
+ f8g4_19 := int64(f8) * int64(g4_19)
+ f8g5_19 := int64(f8) * int64(g5_19)
+ f8g6_19 := int64(f8) * int64(g6_19)
+ f8g7_19 := int64(f8) * int64(g7_19)
+ f8g8_19 := int64(f8) * int64(g8_19)
+ f8g9_19 := int64(f8) * int64(g9_19)
+ f9g0 := int64(f9) * int64(g0)
+ f9g1_38 := int64(f9_2) * int64(g1_19)
+ f9g2_19 := int64(f9) * int64(g2_19)
+ f9g3_38 := int64(f9_2) * int64(g3_19)
+ f9g4_19 := int64(f9) * int64(g4_19)
+ f9g5_38 := int64(f9_2) * int64(g5_19)
+ f9g6_19 := int64(f9) * int64(g6_19)
+ f9g7_38 := int64(f9_2) * int64(g7_19)
+ f9g8_19 := int64(f9) * int64(g8_19)
+ f9g9_38 := int64(f9_2) * int64(g9_19)
+ h0 := f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38
+ h1 := f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19
+ h2 := f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38
+ h3 := f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19
+ h4 := f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38
+ h5 := f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19
+ h6 := f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38
+ h7 := f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19
+ h8 := f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38
+ h9 := f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0
+ var carry [10]int64
+
+ // |h0| <= (1.1*1.1*2^52*(1+19+19+19+19)+1.1*1.1*2^50*(38+38+38+38+38))
+ // i.e. |h0| <= 1.2*2^59; narrower ranges for h2, h4, h6, h8
+ // |h1| <= (1.1*1.1*2^51*(1+1+19+19+19+19+19+19+19+19))
+ // i.e. |h1| <= 1.5*2^58; narrower ranges for h3, h5, h7, h9
+
+ carry[0] = (h0 + (1 << 25)) >> 26
+ h1 += carry[0]
+ h0 -= carry[0] << 26
+ carry[4] = (h4 + (1 << 25)) >> 26
+ h5 += carry[4]
+ h4 -= carry[4] << 26
+ // |h0| <= 2^25
+ // |h4| <= 2^25
+ // |h1| <= 1.51*2^58
+ // |h5| <= 1.51*2^58
+
+ carry[1] = (h1 + (1 << 24)) >> 25
+ h2 += carry[1]
+ h1 -= carry[1] << 25
+ carry[5] = (h5 + (1 << 24)) >> 25
+ h6 += carry[5]
+ h5 -= carry[5] << 25
+ // |h1| <= 2^24; from now on fits into int32
+ // |h5| <= 2^24; from now on fits into int32
+ // |h2| <= 1.21*2^59
+ // |h6| <= 1.21*2^59
+
+ carry[2] = (h2 + (1 << 25)) >> 26
+ h3 += carry[2]
+ h2 -= carry[2] << 26
+ carry[6] = (h6 + (1 << 25)) >> 26
+ h7 += carry[6]
+ h6 -= carry[6] << 26
+ // |h2| <= 2^25; from now on fits into int32 unchanged
+ // |h6| <= 2^25; from now on fits into int32 unchanged
+ // |h3| <= 1.51*2^58
+ // |h7| <= 1.51*2^58
+
+ carry[3] = (h3 + (1 << 24)) >> 25
+ h4 += carry[3]
+ h3 -= carry[3] << 25
+ carry[7] = (h7 + (1 << 24)) >> 25
+ h8 += carry[7]
+ h7 -= carry[7] << 25
+ // |h3| <= 2^24; from now on fits into int32 unchanged
+ // |h7| <= 2^24; from now on fits into int32 unchanged
+ // |h4| <= 1.52*2^33
+ // |h8| <= 1.52*2^33
+
+ carry[4] = (h4 + (1 << 25)) >> 26
+ h5 += carry[4]
+ h4 -= carry[4] << 26
+ carry[8] = (h8 + (1 << 25)) >> 26
+ h9 += carry[8]
+ h8 -= carry[8] << 26
+ // |h4| <= 2^25; from now on fits into int32 unchanged
+ // |h8| <= 2^25; from now on fits into int32 unchanged
+ // |h5| <= 1.01*2^24
+ // |h9| <= 1.51*2^58
+
+ carry[9] = (h9 + (1 << 24)) >> 25
+ h0 += carry[9] * 19
+ h9 -= carry[9] << 25
+ // |h9| <= 2^24; from now on fits into int32 unchanged
+ // |h0| <= 1.8*2^37
+
+ carry[0] = (h0 + (1 << 25)) >> 26
+ h1 += carry[0]
+ h0 -= carry[0] << 26
+ // |h0| <= 2^25; from now on fits into int32 unchanged
+ // |h1| <= 1.01*2^24
+
+ h[0] = int32(h0)
+ h[1] = int32(h1)
+ h[2] = int32(h2)
+ h[3] = int32(h3)
+ h[4] = int32(h4)
+ h[5] = int32(h5)
+ h[6] = int32(h6)
+ h[7] = int32(h7)
+ h[8] = int32(h8)
+ h[9] = int32(h9)
+}
+
+// feSquare calculates h = f*f. Can overlap h with f.
+//
+// Preconditions:
+// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+//
+// Postconditions:
+// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+func feSquare(h, f *fieldElement) {
+ f0 := f[0]
+ f1 := f[1]
+ f2 := f[2]
+ f3 := f[3]
+ f4 := f[4]
+ f5 := f[5]
+ f6 := f[6]
+ f7 := f[7]
+ f8 := f[8]
+ f9 := f[9]
+ f0_2 := 2 * f0
+ f1_2 := 2 * f1
+ f2_2 := 2 * f2
+ f3_2 := 2 * f3
+ f4_2 := 2 * f4
+ f5_2 := 2 * f5
+ f6_2 := 2 * f6
+ f7_2 := 2 * f7
+ f5_38 := 38 * f5 // 1.31*2^30
+ f6_19 := 19 * f6 // 1.31*2^30
+ f7_38 := 38 * f7 // 1.31*2^30
+ f8_19 := 19 * f8 // 1.31*2^30
+ f9_38 := 38 * f9 // 1.31*2^30
+ f0f0 := int64(f0) * int64(f0)
+ f0f1_2 := int64(f0_2) * int64(f1)
+ f0f2_2 := int64(f0_2) * int64(f2)
+ f0f3_2 := int64(f0_2) * int64(f3)
+ f0f4_2 := int64(f0_2) * int64(f4)
+ f0f5_2 := int64(f0_2) * int64(f5)
+ f0f6_2 := int64(f0_2) * int64(f6)
+ f0f7_2 := int64(f0_2) * int64(f7)
+ f0f8_2 := int64(f0_2) * int64(f8)
+ f0f9_2 := int64(f0_2) * int64(f9)
+ f1f1_2 := int64(f1_2) * int64(f1)
+ f1f2_2 := int64(f1_2) * int64(f2)
+ f1f3_4 := int64(f1_2) * int64(f3_2)
+ f1f4_2 := int64(f1_2) * int64(f4)
+ f1f5_4 := int64(f1_2) * int64(f5_2)
+ f1f6_2 := int64(f1_2) * int64(f6)
+ f1f7_4 := int64(f1_2) * int64(f7_2)
+ f1f8_2 := int64(f1_2) * int64(f8)
+ f1f9_76 := int64(f1_2) * int64(f9_38)
+ f2f2 := int64(f2) * int64(f2)
+ f2f3_2 := int64(f2_2) * int64(f3)
+ f2f4_2 := int64(f2_2) * int64(f4)
+ f2f5_2 := int64(f2_2) * int64(f5)
+ f2f6_2 := int64(f2_2) * int64(f6)
+ f2f7_2 := int64(f2_2) * int64(f7)
+ f2f8_38 := int64(f2_2) * int64(f8_19)
+ f2f9_38 := int64(f2) * int64(f9_38)
+ f3f3_2 := int64(f3_2) * int64(f3)
+ f3f4_2 := int64(f3_2) * int64(f4)
+ f3f5_4 := int64(f3_2) * int64(f5_2)
+ f3f6_2 := int64(f3_2) * int64(f6)
+ f3f7_76 := int64(f3_2) * int64(f7_38)
+ f3f8_38 := int64(f3_2) * int64(f8_19)
+ f3f9_76 := int64(f3_2) * int64(f9_38)
+ f4f4 := int64(f4) * int64(f4)
+ f4f5_2 := int64(f4_2) * int64(f5)
+ f4f6_38 := int64(f4_2) * int64(f6_19)
+ f4f7_38 := int64(f4) * int64(f7_38)
+ f4f8_38 := int64(f4_2) * int64(f8_19)
+ f4f9_38 := int64(f4) * int64(f9_38)
+ f5f5_38 := int64(f5) * int64(f5_38)
+ f5f6_38 := int64(f5_2) * int64(f6_19)
+ f5f7_76 := int64(f5_2) * int64(f7_38)
+ f5f8_38 := int64(f5_2) * int64(f8_19)
+ f5f9_76 := int64(f5_2) * int64(f9_38)
+ f6f6_19 := int64(f6) * int64(f6_19)
+ f6f7_38 := int64(f6) * int64(f7_38)
+ f6f8_38 := int64(f6_2) * int64(f8_19)
+ f6f9_38 := int64(f6) * int64(f9_38)
+ f7f7_38 := int64(f7) * int64(f7_38)
+ f7f8_38 := int64(f7_2) * int64(f8_19)
+ f7f9_76 := int64(f7_2) * int64(f9_38)
+ f8f8_19 := int64(f8) * int64(f8_19)
+ f8f9_38 := int64(f8) * int64(f9_38)
+ f9f9_38 := int64(f9) * int64(f9_38)
+ h0 := f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38
+ h1 := f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38
+ h2 := f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19
+ h3 := f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38
+ h4 := f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38
+ h5 := f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38
+ h6 := f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19
+ h7 := f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38
+ h8 := f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38
+ h9 := f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2
+ var carry [10]int64
+
+ carry[0] = (h0 + (1 << 25)) >> 26
+ h1 += carry[0]
+ h0 -= carry[0] << 26
+ carry[4] = (h4 + (1 << 25)) >> 26
+ h5 += carry[4]
+ h4 -= carry[4] << 26
+
+ carry[1] = (h1 + (1 << 24)) >> 25
+ h2 += carry[1]
+ h1 -= carry[1] << 25
+ carry[5] = (h5 + (1 << 24)) >> 25
+ h6 += carry[5]
+ h5 -= carry[5] << 25
+
+ carry[2] = (h2 + (1 << 25)) >> 26
+ h3 += carry[2]
+ h2 -= carry[2] << 26
+ carry[6] = (h6 + (1 << 25)) >> 26
+ h7 += carry[6]
+ h6 -= carry[6] << 26
+
+ carry[3] = (h3 + (1 << 24)) >> 25
+ h4 += carry[3]
+ h3 -= carry[3] << 25
+ carry[7] = (h7 + (1 << 24)) >> 25
+ h8 += carry[7]
+ h7 -= carry[7] << 25
+
+ carry[4] = (h4 + (1 << 25)) >> 26
+ h5 += carry[4]
+ h4 -= carry[4] << 26
+ carry[8] = (h8 + (1 << 25)) >> 26
+ h9 += carry[8]
+ h8 -= carry[8] << 26
+
+ carry[9] = (h9 + (1 << 24)) >> 25
+ h0 += carry[9] * 19
+ h9 -= carry[9] << 25
+
+ carry[0] = (h0 + (1 << 25)) >> 26
+ h1 += carry[0]
+ h0 -= carry[0] << 26
+
+ h[0] = int32(h0)
+ h[1] = int32(h1)
+ h[2] = int32(h2)
+ h[3] = int32(h3)
+ h[4] = int32(h4)
+ h[5] = int32(h5)
+ h[6] = int32(h6)
+ h[7] = int32(h7)
+ h[8] = int32(h8)
+ h[9] = int32(h9)
+}
+
+// feMul121666 calculates h = f * 121666. Can overlap h with f.
+//
+// Preconditions:
+// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+//
+// Postconditions:
+// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+func feMul121666(h, f *fieldElement) {
+ h0 := int64(f[0]) * 121666
+ h1 := int64(f[1]) * 121666
+ h2 := int64(f[2]) * 121666
+ h3 := int64(f[3]) * 121666
+ h4 := int64(f[4]) * 121666
+ h5 := int64(f[5]) * 121666
+ h6 := int64(f[6]) * 121666
+ h7 := int64(f[7]) * 121666
+ h8 := int64(f[8]) * 121666
+ h9 := int64(f[9]) * 121666
+ var carry [10]int64
+
+ carry[9] = (h9 + (1 << 24)) >> 25
+ h0 += carry[9] * 19
+ h9 -= carry[9] << 25
+ carry[1] = (h1 + (1 << 24)) >> 25
+ h2 += carry[1]
+ h1 -= carry[1] << 25
+ carry[3] = (h3 + (1 << 24)) >> 25
+ h4 += carry[3]
+ h3 -= carry[3] << 25
+ carry[5] = (h5 + (1 << 24)) >> 25
+ h6 += carry[5]
+ h5 -= carry[5] << 25
+ carry[7] = (h7 + (1 << 24)) >> 25
+ h8 += carry[7]
+ h7 -= carry[7] << 25
+
+ carry[0] = (h0 + (1 << 25)) >> 26
+ h1 += carry[0]
+ h0 -= carry[0] << 26
+ carry[2] = (h2 + (1 << 25)) >> 26
+ h3 += carry[2]
+ h2 -= carry[2] << 26
+ carry[4] = (h4 + (1 << 25)) >> 26
+ h5 += carry[4]
+ h4 -= carry[4] << 26
+ carry[6] = (h6 + (1 << 25)) >> 26
+ h7 += carry[6]
+ h6 -= carry[6] << 26
+ carry[8] = (h8 + (1 << 25)) >> 26
+ h9 += carry[8]
+ h8 -= carry[8] << 26
+
+ h[0] = int32(h0)
+ h[1] = int32(h1)
+ h[2] = int32(h2)
+ h[3] = int32(h3)
+ h[4] = int32(h4)
+ h[5] = int32(h5)
+ h[6] = int32(h6)
+ h[7] = int32(h7)
+ h[8] = int32(h8)
+ h[9] = int32(h9)
+}
+
+// feInvert sets out = z^-1.
+func feInvert(out, z *fieldElement) {
+ var t0, t1, t2, t3 fieldElement
+ var i int
+
+ feSquare(&t0, z)
+ for i = 1; i < 1; i++ {
+ feSquare(&t0, &t0)
+ }
+ feSquare(&t1, &t0)
+ for i = 1; i < 2; i++ {
+ feSquare(&t1, &t1)
+ }
+ feMul(&t1, z, &t1)
+ feMul(&t0, &t0, &t1)
+ feSquare(&t2, &t0)
+ for i = 1; i < 1; i++ {
+ feSquare(&t2, &t2)
+ }
+ feMul(&t1, &t1, &t2)
+ feSquare(&t2, &t1)
+ for i = 1; i < 5; i++ {
+ feSquare(&t2, &t2)
+ }
+ feMul(&t1, &t2, &t1)
+ feSquare(&t2, &t1)
+ for i = 1; i < 10; i++ {
+ feSquare(&t2, &t2)
+ }
+ feMul(&t2, &t2, &t1)
+ feSquare(&t3, &t2)
+ for i = 1; i < 20; i++ {
+ feSquare(&t3, &t3)
+ }
+ feMul(&t2, &t3, &t2)
+ feSquare(&t2, &t2)
+ for i = 1; i < 10; i++ {
+ feSquare(&t2, &t2)
+ }
+ feMul(&t1, &t2, &t1)
+ feSquare(&t2, &t1)
+ for i = 1; i < 50; i++ {
+ feSquare(&t2, &t2)
+ }
+ feMul(&t2, &t2, &t1)
+ feSquare(&t3, &t2)
+ for i = 1; i < 100; i++ {
+ feSquare(&t3, &t3)
+ }
+ feMul(&t2, &t3, &t2)
+ feSquare(&t2, &t2)
+ for i = 1; i < 50; i++ {
+ feSquare(&t2, &t2)
+ }
+ feMul(&t1, &t2, &t1)
+ feSquare(&t1, &t1)
+ for i = 1; i < 5; i++ {
+ feSquare(&t1, &t1)
+ }
+ feMul(out, &t1, &t0)
+}
+
+func scalarMult(out, in, base *[32]byte) {
+ var e [32]byte
+
+ copy(e[:], in[:])
+ e[0] &= 248
+ e[31] &= 127
+ e[31] |= 64
+
+ var x1, x2, z2, x3, z3, tmp0, tmp1 fieldElement
+ feFromBytes(&x1, base)
+ feOne(&x2)
+ feCopy(&x3, &x1)
+ feOne(&z3)
+
+ swap := int32(0)
+ for pos := 254; pos >= 0; pos-- {
+ b := e[pos/8] >> uint(pos&7)
+ b &= 1
+ swap ^= int32(b)
+ feCSwap(&x2, &x3, swap)
+ feCSwap(&z2, &z3, swap)
+ swap = int32(b)
+
+ feSub(&tmp0, &x3, &z3)
+ feSub(&tmp1, &x2, &z2)
+ feAdd(&x2, &x2, &z2)
+ feAdd(&z2, &x3, &z3)
+ feMul(&z3, &tmp0, &x2)
+ feMul(&z2, &z2, &tmp1)
+ feSquare(&tmp0, &tmp1)
+ feSquare(&tmp1, &x2)
+ feAdd(&x3, &z3, &z2)
+ feSub(&z2, &z3, &z2)
+ feMul(&x2, &tmp1, &tmp0)
+ feSub(&tmp1, &tmp1, &tmp0)
+ feSquare(&z2, &z2)
+ feMul121666(&z3, &tmp1)
+ feSquare(&x3, &x3)
+ feAdd(&tmp0, &tmp0, &z3)
+ feMul(&z3, &x1, &z2)
+ feMul(&z2, &tmp1, &tmp0)
+ }
+
+ feCSwap(&x2, &x3, swap)
+ feCSwap(&z2, &z3, swap)
+
+ feInvert(&z2, &z2)
+ feMul(&x2, &x2, &z2)
+ feToBytes(out, &x2)
+}
diff --git a/src/ssl/test/runner/curve25519/curve25519_test.go b/src/ssl/test/runner/curve25519/curve25519_test.go
new file mode 100644
index 0000000..14b0ee8
--- /dev/null
+++ b/src/ssl/test/runner/curve25519/curve25519_test.go
@@ -0,0 +1,29 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package curve25519
+
+import (
+ "fmt"
+ "testing"
+)
+
+const expectedHex = "89161fde887b2b53de549af483940106ecc114d6982daa98256de23bdf77661a"
+
+func TestBaseScalarMult(t *testing.T) {
+ var a, b [32]byte
+ in := &a
+ out := &b
+ a[0] = 1
+
+ for i := 0; i < 200; i++ {
+ ScalarBaseMult(out, in)
+ in, out = out, in
+ }
+
+ result := fmt.Sprintf("%x", in[:])
+ if result != expectedHex {
+ t.Errorf("incorrect result: got %s, want %s", result, expectedHex)
+ }
+}
diff --git a/src/ssl/test/runner/curve25519/doc.go b/src/ssl/test/runner/curve25519/doc.go
new file mode 100644
index 0000000..ebeea3c
--- /dev/null
+++ b/src/ssl/test/runner/curve25519/doc.go
@@ -0,0 +1,23 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package curve25519 provides an implementation of scalar multiplication on
+// the elliptic curve known as curve25519. See http://cr.yp.to/ecdh.html
+package curve25519 // import "golang.org/x/crypto/curve25519"
+
+// basePoint is the x coordinate of the generator of the curve.
+var basePoint = [32]byte{9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+
+// ScalarMult sets dst to the product in*base where dst and base are the x
+// coordinates of group points and all values are in little-endian form.
+func ScalarMult(dst, in, base *[32]byte) {
+ scalarMult(dst, in, base)
+}
+
+// ScalarBaseMult sets dst to the product in*base where dst and base are the x
+// coordinates of group points, base is the standard generator and all values
+// are in little-endian form.
+func ScalarBaseMult(dst, in *[32]byte) {
+ ScalarMult(dst, in, &basePoint)
+}
diff --git a/src/ssl/test/runner/curve25519/freeze_amd64.s b/src/ssl/test/runner/curve25519/freeze_amd64.s
new file mode 100644
index 0000000..37599fa
--- /dev/null
+++ b/src/ssl/test/runner/curve25519/freeze_amd64.s
@@ -0,0 +1,94 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This code was translated into a form compatible with 6a from the public
+// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
+
+// +build amd64,!gccgo,!appengine
+
+// func freeze(inout *[5]uint64)
+TEXT ·freeze(SB),7,$96-8
+ MOVQ inout+0(FP), DI
+
+ MOVQ SP,R11
+ MOVQ $31,CX
+ NOTQ CX
+ ANDQ CX,SP
+ ADDQ $32,SP
+
+ MOVQ R11,0(SP)
+ MOVQ R12,8(SP)
+ MOVQ R13,16(SP)
+ MOVQ R14,24(SP)
+ MOVQ R15,32(SP)
+ MOVQ BX,40(SP)
+ MOVQ BP,48(SP)
+ MOVQ 0(DI),SI
+ MOVQ 8(DI),DX
+ MOVQ 16(DI),CX
+ MOVQ 24(DI),R8
+ MOVQ 32(DI),R9
+ MOVQ ·REDMASK51(SB),AX
+ MOVQ AX,R10
+ SUBQ $18,R10
+ MOVQ $3,R11
+REDUCELOOP:
+ MOVQ SI,R12
+ SHRQ $51,R12
+ ANDQ AX,SI
+ ADDQ R12,DX
+ MOVQ DX,R12
+ SHRQ $51,R12
+ ANDQ AX,DX
+ ADDQ R12,CX
+ MOVQ CX,R12
+ SHRQ $51,R12
+ ANDQ AX,CX
+ ADDQ R12,R8
+ MOVQ R8,R12
+ SHRQ $51,R12
+ ANDQ AX,R8
+ ADDQ R12,R9
+ MOVQ R9,R12
+ SHRQ $51,R12
+ ANDQ AX,R9
+ IMUL3Q $19,R12,R12
+ ADDQ R12,SI
+ SUBQ $1,R11
+ JA REDUCELOOP
+ MOVQ $1,R12
+ CMPQ R10,SI
+ CMOVQLT R11,R12
+ CMPQ AX,DX
+ CMOVQNE R11,R12
+ CMPQ AX,CX
+ CMOVQNE R11,R12
+ CMPQ AX,R8
+ CMOVQNE R11,R12
+ CMPQ AX,R9
+ CMOVQNE R11,R12
+ NEGQ R12
+ ANDQ R12,AX
+ ANDQ R12,R10
+ SUBQ R10,SI
+ SUBQ AX,DX
+ SUBQ AX,CX
+ SUBQ AX,R8
+ SUBQ AX,R9
+ MOVQ SI,0(DI)
+ MOVQ DX,8(DI)
+ MOVQ CX,16(DI)
+ MOVQ R8,24(DI)
+ MOVQ R9,32(DI)
+ MOVQ 0(SP),R11
+ MOVQ 8(SP),R12
+ MOVQ 16(SP),R13
+ MOVQ 24(SP),R14
+ MOVQ 32(SP),R15
+ MOVQ 40(SP),BX
+ MOVQ 48(SP),BP
+ MOVQ R11,SP
+ MOVQ DI,AX
+ MOVQ SI,DX
+ RET
diff --git a/src/ssl/test/runner/curve25519/ladderstep_amd64.s b/src/ssl/test/runner/curve25519/ladderstep_amd64.s
new file mode 100644
index 0000000..3949f9c
--- /dev/null
+++ b/src/ssl/test/runner/curve25519/ladderstep_amd64.s
@@ -0,0 +1,1398 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This code was translated into a form compatible with 6a from the public
+// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
+
+// +build amd64,!gccgo,!appengine
+
+// func ladderstep(inout *[5][5]uint64)
+TEXT ·ladderstep(SB),0,$384-8
+ MOVQ inout+0(FP),DI
+
+ MOVQ SP,R11
+ MOVQ $31,CX
+ NOTQ CX
+ ANDQ CX,SP
+ ADDQ $32,SP
+
+ MOVQ R11,0(SP)
+ MOVQ R12,8(SP)
+ MOVQ R13,16(SP)
+ MOVQ R14,24(SP)
+ MOVQ R15,32(SP)
+ MOVQ BX,40(SP)
+ MOVQ BP,48(SP)
+ MOVQ 40(DI),SI
+ MOVQ 48(DI),DX
+ MOVQ 56(DI),CX
+ MOVQ 64(DI),R8
+ MOVQ 72(DI),R9
+ MOVQ SI,AX
+ MOVQ DX,R10
+ MOVQ CX,R11
+ MOVQ R8,R12
+ MOVQ R9,R13
+ ADDQ ·_2P0(SB),AX
+ ADDQ ·_2P1234(SB),R10
+ ADDQ ·_2P1234(SB),R11
+ ADDQ ·_2P1234(SB),R12
+ ADDQ ·_2P1234(SB),R13
+ ADDQ 80(DI),SI
+ ADDQ 88(DI),DX
+ ADDQ 96(DI),CX
+ ADDQ 104(DI),R8
+ ADDQ 112(DI),R9
+ SUBQ 80(DI),AX
+ SUBQ 88(DI),R10
+ SUBQ 96(DI),R11
+ SUBQ 104(DI),R12
+ SUBQ 112(DI),R13
+ MOVQ SI,56(SP)
+ MOVQ DX,64(SP)
+ MOVQ CX,72(SP)
+ MOVQ R8,80(SP)
+ MOVQ R9,88(SP)
+ MOVQ AX,96(SP)
+ MOVQ R10,104(SP)
+ MOVQ R11,112(SP)
+ MOVQ R12,120(SP)
+ MOVQ R13,128(SP)
+ MOVQ 96(SP),AX
+ MULQ 96(SP)
+ MOVQ AX,SI
+ MOVQ DX,CX
+ MOVQ 96(SP),AX
+ SHLQ $1,AX
+ MULQ 104(SP)
+ MOVQ AX,R8
+ MOVQ DX,R9
+ MOVQ 96(SP),AX
+ SHLQ $1,AX
+ MULQ 112(SP)
+ MOVQ AX,R10
+ MOVQ DX,R11
+ MOVQ 96(SP),AX
+ SHLQ $1,AX
+ MULQ 120(SP)
+ MOVQ AX,R12
+ MOVQ DX,R13
+ MOVQ 96(SP),AX
+ SHLQ $1,AX
+ MULQ 128(SP)
+ MOVQ AX,R14
+ MOVQ DX,R15
+ MOVQ 104(SP),AX
+ MULQ 104(SP)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 104(SP),AX
+ SHLQ $1,AX
+ MULQ 112(SP)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ 104(SP),AX
+ SHLQ $1,AX
+ MULQ 120(SP)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 104(SP),DX
+ IMUL3Q $38,DX,AX
+ MULQ 128(SP)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 112(SP),AX
+ MULQ 112(SP)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 112(SP),DX
+ IMUL3Q $38,DX,AX
+ MULQ 120(SP)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 112(SP),DX
+ IMUL3Q $38,DX,AX
+ MULQ 128(SP)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 120(SP),DX
+ IMUL3Q $19,DX,AX
+ MULQ 120(SP)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 120(SP),DX
+ IMUL3Q $38,DX,AX
+ MULQ 128(SP)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 128(SP),DX
+ IMUL3Q $19,DX,AX
+ MULQ 128(SP)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ ·REDMASK51(SB),DX
+ SHLQ $13,CX:SI
+ ANDQ DX,SI
+ SHLQ $13,R9:R8
+ ANDQ DX,R8
+ ADDQ CX,R8
+ SHLQ $13,R11:R10
+ ANDQ DX,R10
+ ADDQ R9,R10
+ SHLQ $13,R13:R12
+ ANDQ DX,R12
+ ADDQ R11,R12
+ SHLQ $13,R15:R14
+ ANDQ DX,R14
+ ADDQ R13,R14
+ IMUL3Q $19,R15,CX
+ ADDQ CX,SI
+ MOVQ SI,CX
+ SHRQ $51,CX
+ ADDQ R8,CX
+ ANDQ DX,SI
+ MOVQ CX,R8
+ SHRQ $51,CX
+ ADDQ R10,CX
+ ANDQ DX,R8
+ MOVQ CX,R9
+ SHRQ $51,CX
+ ADDQ R12,CX
+ ANDQ DX,R9
+ MOVQ CX,AX
+ SHRQ $51,CX
+ ADDQ R14,CX
+ ANDQ DX,AX
+ MOVQ CX,R10
+ SHRQ $51,CX
+ IMUL3Q $19,CX,CX
+ ADDQ CX,SI
+ ANDQ DX,R10
+ MOVQ SI,136(SP)
+ MOVQ R8,144(SP)
+ MOVQ R9,152(SP)
+ MOVQ AX,160(SP)
+ MOVQ R10,168(SP)
+ MOVQ 56(SP),AX
+ MULQ 56(SP)
+ MOVQ AX,SI
+ MOVQ DX,CX
+ MOVQ 56(SP),AX
+ SHLQ $1,AX
+ MULQ 64(SP)
+ MOVQ AX,R8
+ MOVQ DX,R9
+ MOVQ 56(SP),AX
+ SHLQ $1,AX
+ MULQ 72(SP)
+ MOVQ AX,R10
+ MOVQ DX,R11
+ MOVQ 56(SP),AX
+ SHLQ $1,AX
+ MULQ 80(SP)
+ MOVQ AX,R12
+ MOVQ DX,R13
+ MOVQ 56(SP),AX
+ SHLQ $1,AX
+ MULQ 88(SP)
+ MOVQ AX,R14
+ MOVQ DX,R15
+ MOVQ 64(SP),AX
+ MULQ 64(SP)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 64(SP),AX
+ SHLQ $1,AX
+ MULQ 72(SP)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ 64(SP),AX
+ SHLQ $1,AX
+ MULQ 80(SP)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 64(SP),DX
+ IMUL3Q $38,DX,AX
+ MULQ 88(SP)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 72(SP),AX
+ MULQ 72(SP)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 72(SP),DX
+ IMUL3Q $38,DX,AX
+ MULQ 80(SP)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 72(SP),DX
+ IMUL3Q $38,DX,AX
+ MULQ 88(SP)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 80(SP),DX
+ IMUL3Q $19,DX,AX
+ MULQ 80(SP)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 80(SP),DX
+ IMUL3Q $38,DX,AX
+ MULQ 88(SP)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 88(SP),DX
+ IMUL3Q $19,DX,AX
+ MULQ 88(SP)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ ·REDMASK51(SB),DX
+ SHLQ $13,CX:SI
+ ANDQ DX,SI
+ SHLQ $13,R9:R8
+ ANDQ DX,R8
+ ADDQ CX,R8
+ SHLQ $13,R11:R10
+ ANDQ DX,R10
+ ADDQ R9,R10
+ SHLQ $13,R13:R12
+ ANDQ DX,R12
+ ADDQ R11,R12
+ SHLQ $13,R15:R14
+ ANDQ DX,R14
+ ADDQ R13,R14
+ IMUL3Q $19,R15,CX
+ ADDQ CX,SI
+ MOVQ SI,CX
+ SHRQ $51,CX
+ ADDQ R8,CX
+ ANDQ DX,SI
+ MOVQ CX,R8
+ SHRQ $51,CX
+ ADDQ R10,CX
+ ANDQ DX,R8
+ MOVQ CX,R9
+ SHRQ $51,CX
+ ADDQ R12,CX
+ ANDQ DX,R9
+ MOVQ CX,AX
+ SHRQ $51,CX
+ ADDQ R14,CX
+ ANDQ DX,AX
+ MOVQ CX,R10
+ SHRQ $51,CX
+ IMUL3Q $19,CX,CX
+ ADDQ CX,SI
+ ANDQ DX,R10
+ MOVQ SI,176(SP)
+ MOVQ R8,184(SP)
+ MOVQ R9,192(SP)
+ MOVQ AX,200(SP)
+ MOVQ R10,208(SP)
+ MOVQ SI,SI
+ MOVQ R8,DX
+ MOVQ R9,CX
+ MOVQ AX,R8
+ MOVQ R10,R9
+ ADDQ ·_2P0(SB),SI
+ ADDQ ·_2P1234(SB),DX
+ ADDQ ·_2P1234(SB),CX
+ ADDQ ·_2P1234(SB),R8
+ ADDQ ·_2P1234(SB),R9
+ SUBQ 136(SP),SI
+ SUBQ 144(SP),DX
+ SUBQ 152(SP),CX
+ SUBQ 160(SP),R8
+ SUBQ 168(SP),R9
+ MOVQ SI,216(SP)
+ MOVQ DX,224(SP)
+ MOVQ CX,232(SP)
+ MOVQ R8,240(SP)
+ MOVQ R9,248(SP)
+ MOVQ 120(DI),SI
+ MOVQ 128(DI),DX
+ MOVQ 136(DI),CX
+ MOVQ 144(DI),R8
+ MOVQ 152(DI),R9
+ MOVQ SI,AX
+ MOVQ DX,R10
+ MOVQ CX,R11
+ MOVQ R8,R12
+ MOVQ R9,R13
+ ADDQ ·_2P0(SB),AX
+ ADDQ ·_2P1234(SB),R10
+ ADDQ ·_2P1234(SB),R11
+ ADDQ ·_2P1234(SB),R12
+ ADDQ ·_2P1234(SB),R13
+ ADDQ 160(DI),SI
+ ADDQ 168(DI),DX
+ ADDQ 176(DI),CX
+ ADDQ 184(DI),R8
+ ADDQ 192(DI),R9
+ SUBQ 160(DI),AX
+ SUBQ 168(DI),R10
+ SUBQ 176(DI),R11
+ SUBQ 184(DI),R12
+ SUBQ 192(DI),R13
+ MOVQ SI,256(SP)
+ MOVQ DX,264(SP)
+ MOVQ CX,272(SP)
+ MOVQ R8,280(SP)
+ MOVQ R9,288(SP)
+ MOVQ AX,296(SP)
+ MOVQ R10,304(SP)
+ MOVQ R11,312(SP)
+ MOVQ R12,320(SP)
+ MOVQ R13,328(SP)
+ MOVQ 280(SP),SI
+ IMUL3Q $19,SI,AX
+ MOVQ AX,336(SP)
+ MULQ 112(SP)
+ MOVQ AX,SI
+ MOVQ DX,CX
+ MOVQ 288(SP),DX
+ IMUL3Q $19,DX,AX
+ MOVQ AX,344(SP)
+ MULQ 104(SP)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 256(SP),AX
+ MULQ 96(SP)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 256(SP),AX
+ MULQ 104(SP)
+ MOVQ AX,R8
+ MOVQ DX,R9
+ MOVQ 256(SP),AX
+ MULQ 112(SP)
+ MOVQ AX,R10
+ MOVQ DX,R11
+ MOVQ 256(SP),AX
+ MULQ 120(SP)
+ MOVQ AX,R12
+ MOVQ DX,R13
+ MOVQ 256(SP),AX
+ MULQ 128(SP)
+ MOVQ AX,R14
+ MOVQ DX,R15
+ MOVQ 264(SP),AX
+ MULQ 96(SP)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 264(SP),AX
+ MULQ 104(SP)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 264(SP),AX
+ MULQ 112(SP)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ 264(SP),AX
+ MULQ 120(SP)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 264(SP),DX
+ IMUL3Q $19,DX,AX
+ MULQ 128(SP)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 272(SP),AX
+ MULQ 96(SP)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 272(SP),AX
+ MULQ 104(SP)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ 272(SP),AX
+ MULQ 112(SP)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 272(SP),DX
+ IMUL3Q $19,DX,AX
+ MULQ 120(SP)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 272(SP),DX
+ IMUL3Q $19,DX,AX
+ MULQ 128(SP)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 280(SP),AX
+ MULQ 96(SP)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ 280(SP),AX
+ MULQ 104(SP)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 336(SP),AX
+ MULQ 120(SP)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 336(SP),AX
+ MULQ 128(SP)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 288(SP),AX
+ MULQ 96(SP)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 344(SP),AX
+ MULQ 112(SP)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 344(SP),AX
+ MULQ 120(SP)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 344(SP),AX
+ MULQ 128(SP)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ ·REDMASK51(SB),DX
+ SHLQ $13,CX:SI
+ ANDQ DX,SI
+ SHLQ $13,R9:R8
+ ANDQ DX,R8
+ ADDQ CX,R8
+ SHLQ $13,R11:R10
+ ANDQ DX,R10
+ ADDQ R9,R10
+ SHLQ $13,R13:R12
+ ANDQ DX,R12
+ ADDQ R11,R12
+ SHLQ $13,R15:R14
+ ANDQ DX,R14
+ ADDQ R13,R14
+ IMUL3Q $19,R15,CX
+ ADDQ CX,SI
+ MOVQ SI,CX
+ SHRQ $51,CX
+ ADDQ R8,CX
+ MOVQ CX,R8
+ SHRQ $51,CX
+ ANDQ DX,SI
+ ADDQ R10,CX
+ MOVQ CX,R9
+ SHRQ $51,CX
+ ANDQ DX,R8
+ ADDQ R12,CX
+ MOVQ CX,AX
+ SHRQ $51,CX
+ ANDQ DX,R9
+ ADDQ R14,CX
+ MOVQ CX,R10
+ SHRQ $51,CX
+ ANDQ DX,AX
+ IMUL3Q $19,CX,CX
+ ADDQ CX,SI
+ ANDQ DX,R10
+ MOVQ SI,96(SP)
+ MOVQ R8,104(SP)
+ MOVQ R9,112(SP)
+ MOVQ AX,120(SP)
+ MOVQ R10,128(SP)
+ MOVQ 320(SP),SI
+ IMUL3Q $19,SI,AX
+ MOVQ AX,256(SP)
+ MULQ 72(SP)
+ MOVQ AX,SI
+ MOVQ DX,CX
+ MOVQ 328(SP),DX
+ IMUL3Q $19,DX,AX
+ MOVQ AX,264(SP)
+ MULQ 64(SP)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 296(SP),AX
+ MULQ 56(SP)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 296(SP),AX
+ MULQ 64(SP)
+ MOVQ AX,R8
+ MOVQ DX,R9
+ MOVQ 296(SP),AX
+ MULQ 72(SP)
+ MOVQ AX,R10
+ MOVQ DX,R11
+ MOVQ 296(SP),AX
+ MULQ 80(SP)
+ MOVQ AX,R12
+ MOVQ DX,R13
+ MOVQ 296(SP),AX
+ MULQ 88(SP)
+ MOVQ AX,R14
+ MOVQ DX,R15
+ MOVQ 304(SP),AX
+ MULQ 56(SP)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 304(SP),AX
+ MULQ 64(SP)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 304(SP),AX
+ MULQ 72(SP)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ 304(SP),AX
+ MULQ 80(SP)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 304(SP),DX
+ IMUL3Q $19,DX,AX
+ MULQ 88(SP)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 312(SP),AX
+ MULQ 56(SP)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 312(SP),AX
+ MULQ 64(SP)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ 312(SP),AX
+ MULQ 72(SP)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 312(SP),DX
+ IMUL3Q $19,DX,AX
+ MULQ 80(SP)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 312(SP),DX
+ IMUL3Q $19,DX,AX
+ MULQ 88(SP)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 320(SP),AX
+ MULQ 56(SP)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ 320(SP),AX
+ MULQ 64(SP)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 256(SP),AX
+ MULQ 80(SP)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 256(SP),AX
+ MULQ 88(SP)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 328(SP),AX
+ MULQ 56(SP)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 264(SP),AX
+ MULQ 72(SP)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 264(SP),AX
+ MULQ 80(SP)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 264(SP),AX
+ MULQ 88(SP)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ ·REDMASK51(SB),DX
+ SHLQ $13,CX:SI
+ ANDQ DX,SI
+ SHLQ $13,R9:R8
+ ANDQ DX,R8
+ ADDQ CX,R8
+ SHLQ $13,R11:R10
+ ANDQ DX,R10
+ ADDQ R9,R10
+ SHLQ $13,R13:R12
+ ANDQ DX,R12
+ ADDQ R11,R12
+ SHLQ $13,R15:R14
+ ANDQ DX,R14
+ ADDQ R13,R14
+ IMUL3Q $19,R15,CX
+ ADDQ CX,SI
+ MOVQ SI,CX
+ SHRQ $51,CX
+ ADDQ R8,CX
+ MOVQ CX,R8
+ SHRQ $51,CX
+ ANDQ DX,SI
+ ADDQ R10,CX
+ MOVQ CX,R9
+ SHRQ $51,CX
+ ANDQ DX,R8
+ ADDQ R12,CX
+ MOVQ CX,AX
+ SHRQ $51,CX
+ ANDQ DX,R9
+ ADDQ R14,CX
+ MOVQ CX,R10
+ SHRQ $51,CX
+ ANDQ DX,AX
+ IMUL3Q $19,CX,CX
+ ADDQ CX,SI
+ ANDQ DX,R10
+ MOVQ SI,DX
+ MOVQ R8,CX
+ MOVQ R9,R11
+ MOVQ AX,R12
+ MOVQ R10,R13
+ ADDQ ·_2P0(SB),DX
+ ADDQ ·_2P1234(SB),CX
+ ADDQ ·_2P1234(SB),R11
+ ADDQ ·_2P1234(SB),R12
+ ADDQ ·_2P1234(SB),R13
+ ADDQ 96(SP),SI
+ ADDQ 104(SP),R8
+ ADDQ 112(SP),R9
+ ADDQ 120(SP),AX
+ ADDQ 128(SP),R10
+ SUBQ 96(SP),DX
+ SUBQ 104(SP),CX
+ SUBQ 112(SP),R11
+ SUBQ 120(SP),R12
+ SUBQ 128(SP),R13
+ MOVQ SI,120(DI)
+ MOVQ R8,128(DI)
+ MOVQ R9,136(DI)
+ MOVQ AX,144(DI)
+ MOVQ R10,152(DI)
+ MOVQ DX,160(DI)
+ MOVQ CX,168(DI)
+ MOVQ R11,176(DI)
+ MOVQ R12,184(DI)
+ MOVQ R13,192(DI)
+ MOVQ 120(DI),AX
+ MULQ 120(DI)
+ MOVQ AX,SI
+ MOVQ DX,CX
+ MOVQ 120(DI),AX
+ SHLQ $1,AX
+ MULQ 128(DI)
+ MOVQ AX,R8
+ MOVQ DX,R9
+ MOVQ 120(DI),AX
+ SHLQ $1,AX
+ MULQ 136(DI)
+ MOVQ AX,R10
+ MOVQ DX,R11
+ MOVQ 120(DI),AX
+ SHLQ $1,AX
+ MULQ 144(DI)
+ MOVQ AX,R12
+ MOVQ DX,R13
+ MOVQ 120(DI),AX
+ SHLQ $1,AX
+ MULQ 152(DI)
+ MOVQ AX,R14
+ MOVQ DX,R15
+ MOVQ 128(DI),AX
+ MULQ 128(DI)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 128(DI),AX
+ SHLQ $1,AX
+ MULQ 136(DI)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ 128(DI),AX
+ SHLQ $1,AX
+ MULQ 144(DI)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 128(DI),DX
+ IMUL3Q $38,DX,AX
+ MULQ 152(DI)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 136(DI),AX
+ MULQ 136(DI)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 136(DI),DX
+ IMUL3Q $38,DX,AX
+ MULQ 144(DI)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 136(DI),DX
+ IMUL3Q $38,DX,AX
+ MULQ 152(DI)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 144(DI),DX
+ IMUL3Q $19,DX,AX
+ MULQ 144(DI)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 144(DI),DX
+ IMUL3Q $38,DX,AX
+ MULQ 152(DI)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 152(DI),DX
+ IMUL3Q $19,DX,AX
+ MULQ 152(DI)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ ·REDMASK51(SB),DX
+ SHLQ $13,CX:SI
+ ANDQ DX,SI
+ SHLQ $13,R9:R8
+ ANDQ DX,R8
+ ADDQ CX,R8
+ SHLQ $13,R11:R10
+ ANDQ DX,R10
+ ADDQ R9,R10
+ SHLQ $13,R13:R12
+ ANDQ DX,R12
+ ADDQ R11,R12
+ SHLQ $13,R15:R14
+ ANDQ DX,R14
+ ADDQ R13,R14
+ IMUL3Q $19,R15,CX
+ ADDQ CX,SI
+ MOVQ SI,CX
+ SHRQ $51,CX
+ ADDQ R8,CX
+ ANDQ DX,SI
+ MOVQ CX,R8
+ SHRQ $51,CX
+ ADDQ R10,CX
+ ANDQ DX,R8
+ MOVQ CX,R9
+ SHRQ $51,CX
+ ADDQ R12,CX
+ ANDQ DX,R9
+ MOVQ CX,AX
+ SHRQ $51,CX
+ ADDQ R14,CX
+ ANDQ DX,AX
+ MOVQ CX,R10
+ SHRQ $51,CX
+ IMUL3Q $19,CX,CX
+ ADDQ CX,SI
+ ANDQ DX,R10
+ MOVQ SI,120(DI)
+ MOVQ R8,128(DI)
+ MOVQ R9,136(DI)
+ MOVQ AX,144(DI)
+ MOVQ R10,152(DI)
+ MOVQ 160(DI),AX
+ MULQ 160(DI)
+ MOVQ AX,SI
+ MOVQ DX,CX
+ MOVQ 160(DI),AX
+ SHLQ $1,AX
+ MULQ 168(DI)
+ MOVQ AX,R8
+ MOVQ DX,R9
+ MOVQ 160(DI),AX
+ SHLQ $1,AX
+ MULQ 176(DI)
+ MOVQ AX,R10
+ MOVQ DX,R11
+ MOVQ 160(DI),AX
+ SHLQ $1,AX
+ MULQ 184(DI)
+ MOVQ AX,R12
+ MOVQ DX,R13
+ MOVQ 160(DI),AX
+ SHLQ $1,AX
+ MULQ 192(DI)
+ MOVQ AX,R14
+ MOVQ DX,R15
+ MOVQ 168(DI),AX
+ MULQ 168(DI)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 168(DI),AX
+ SHLQ $1,AX
+ MULQ 176(DI)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ 168(DI),AX
+ SHLQ $1,AX
+ MULQ 184(DI)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 168(DI),DX
+ IMUL3Q $38,DX,AX
+ MULQ 192(DI)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 176(DI),AX
+ MULQ 176(DI)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 176(DI),DX
+ IMUL3Q $38,DX,AX
+ MULQ 184(DI)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 176(DI),DX
+ IMUL3Q $38,DX,AX
+ MULQ 192(DI)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 184(DI),DX
+ IMUL3Q $19,DX,AX
+ MULQ 184(DI)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 184(DI),DX
+ IMUL3Q $38,DX,AX
+ MULQ 192(DI)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 192(DI),DX
+ IMUL3Q $19,DX,AX
+ MULQ 192(DI)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ ·REDMASK51(SB),DX
+ SHLQ $13,CX:SI
+ ANDQ DX,SI
+ SHLQ $13,R9:R8
+ ANDQ DX,R8
+ ADDQ CX,R8
+ SHLQ $13,R11:R10
+ ANDQ DX,R10
+ ADDQ R9,R10
+ SHLQ $13,R13:R12
+ ANDQ DX,R12
+ ADDQ R11,R12
+ SHLQ $13,R15:R14
+ ANDQ DX,R14
+ ADDQ R13,R14
+ IMUL3Q $19,R15,CX
+ ADDQ CX,SI
+ MOVQ SI,CX
+ SHRQ $51,CX
+ ADDQ R8,CX
+ ANDQ DX,SI
+ MOVQ CX,R8
+ SHRQ $51,CX
+ ADDQ R10,CX
+ ANDQ DX,R8
+ MOVQ CX,R9
+ SHRQ $51,CX
+ ADDQ R12,CX
+ ANDQ DX,R9
+ MOVQ CX,AX
+ SHRQ $51,CX
+ ADDQ R14,CX
+ ANDQ DX,AX
+ MOVQ CX,R10
+ SHRQ $51,CX
+ IMUL3Q $19,CX,CX
+ ADDQ CX,SI
+ ANDQ DX,R10
+ MOVQ SI,160(DI)
+ MOVQ R8,168(DI)
+ MOVQ R9,176(DI)
+ MOVQ AX,184(DI)
+ MOVQ R10,192(DI)
+ MOVQ 184(DI),SI
+ IMUL3Q $19,SI,AX
+ MOVQ AX,56(SP)
+ MULQ 16(DI)
+ MOVQ AX,SI
+ MOVQ DX,CX
+ MOVQ 192(DI),DX
+ IMUL3Q $19,DX,AX
+ MOVQ AX,64(SP)
+ MULQ 8(DI)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 160(DI),AX
+ MULQ 0(DI)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 160(DI),AX
+ MULQ 8(DI)
+ MOVQ AX,R8
+ MOVQ DX,R9
+ MOVQ 160(DI),AX
+ MULQ 16(DI)
+ MOVQ AX,R10
+ MOVQ DX,R11
+ MOVQ 160(DI),AX
+ MULQ 24(DI)
+ MOVQ AX,R12
+ MOVQ DX,R13
+ MOVQ 160(DI),AX
+ MULQ 32(DI)
+ MOVQ AX,R14
+ MOVQ DX,R15
+ MOVQ 168(DI),AX
+ MULQ 0(DI)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 168(DI),AX
+ MULQ 8(DI)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 168(DI),AX
+ MULQ 16(DI)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ 168(DI),AX
+ MULQ 24(DI)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 168(DI),DX
+ IMUL3Q $19,DX,AX
+ MULQ 32(DI)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 176(DI),AX
+ MULQ 0(DI)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 176(DI),AX
+ MULQ 8(DI)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ 176(DI),AX
+ MULQ 16(DI)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 176(DI),DX
+ IMUL3Q $19,DX,AX
+ MULQ 24(DI)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 176(DI),DX
+ IMUL3Q $19,DX,AX
+ MULQ 32(DI)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 184(DI),AX
+ MULQ 0(DI)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ 184(DI),AX
+ MULQ 8(DI)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 56(SP),AX
+ MULQ 24(DI)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 56(SP),AX
+ MULQ 32(DI)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 192(DI),AX
+ MULQ 0(DI)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 64(SP),AX
+ MULQ 16(DI)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 64(SP),AX
+ MULQ 24(DI)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 64(SP),AX
+ MULQ 32(DI)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ ·REDMASK51(SB),DX
+ SHLQ $13,CX:SI
+ ANDQ DX,SI
+ SHLQ $13,R9:R8
+ ANDQ DX,R8
+ ADDQ CX,R8
+ SHLQ $13,R11:R10
+ ANDQ DX,R10
+ ADDQ R9,R10
+ SHLQ $13,R13:R12
+ ANDQ DX,R12
+ ADDQ R11,R12
+ SHLQ $13,R15:R14
+ ANDQ DX,R14
+ ADDQ R13,R14
+ IMUL3Q $19,R15,CX
+ ADDQ CX,SI
+ MOVQ SI,CX
+ SHRQ $51,CX
+ ADDQ R8,CX
+ MOVQ CX,R8
+ SHRQ $51,CX
+ ANDQ DX,SI
+ ADDQ R10,CX
+ MOVQ CX,R9
+ SHRQ $51,CX
+ ANDQ DX,R8
+ ADDQ R12,CX
+ MOVQ CX,AX
+ SHRQ $51,CX
+ ANDQ DX,R9
+ ADDQ R14,CX
+ MOVQ CX,R10
+ SHRQ $51,CX
+ ANDQ DX,AX
+ IMUL3Q $19,CX,CX
+ ADDQ CX,SI
+ ANDQ DX,R10
+ MOVQ SI,160(DI)
+ MOVQ R8,168(DI)
+ MOVQ R9,176(DI)
+ MOVQ AX,184(DI)
+ MOVQ R10,192(DI)
+ MOVQ 200(SP),SI
+ IMUL3Q $19,SI,AX
+ MOVQ AX,56(SP)
+ MULQ 152(SP)
+ MOVQ AX,SI
+ MOVQ DX,CX
+ MOVQ 208(SP),DX
+ IMUL3Q $19,DX,AX
+ MOVQ AX,64(SP)
+ MULQ 144(SP)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 176(SP),AX
+ MULQ 136(SP)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 176(SP),AX
+ MULQ 144(SP)
+ MOVQ AX,R8
+ MOVQ DX,R9
+ MOVQ 176(SP),AX
+ MULQ 152(SP)
+ MOVQ AX,R10
+ MOVQ DX,R11
+ MOVQ 176(SP),AX
+ MULQ 160(SP)
+ MOVQ AX,R12
+ MOVQ DX,R13
+ MOVQ 176(SP),AX
+ MULQ 168(SP)
+ MOVQ AX,R14
+ MOVQ DX,R15
+ MOVQ 184(SP),AX
+ MULQ 136(SP)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 184(SP),AX
+ MULQ 144(SP)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 184(SP),AX
+ MULQ 152(SP)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ 184(SP),AX
+ MULQ 160(SP)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 184(SP),DX
+ IMUL3Q $19,DX,AX
+ MULQ 168(SP)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 192(SP),AX
+ MULQ 136(SP)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 192(SP),AX
+ MULQ 144(SP)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ 192(SP),AX
+ MULQ 152(SP)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 192(SP),DX
+ IMUL3Q $19,DX,AX
+ MULQ 160(SP)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 192(SP),DX
+ IMUL3Q $19,DX,AX
+ MULQ 168(SP)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 200(SP),AX
+ MULQ 136(SP)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ 200(SP),AX
+ MULQ 144(SP)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 56(SP),AX
+ MULQ 160(SP)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 56(SP),AX
+ MULQ 168(SP)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 208(SP),AX
+ MULQ 136(SP)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 64(SP),AX
+ MULQ 152(SP)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 64(SP),AX
+ MULQ 160(SP)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 64(SP),AX
+ MULQ 168(SP)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ ·REDMASK51(SB),DX
+ SHLQ $13,CX:SI
+ ANDQ DX,SI
+ SHLQ $13,R9:R8
+ ANDQ DX,R8
+ ADDQ CX,R8
+ SHLQ $13,R11:R10
+ ANDQ DX,R10
+ ADDQ R9,R10
+ SHLQ $13,R13:R12
+ ANDQ DX,R12
+ ADDQ R11,R12
+ SHLQ $13,R15:R14
+ ANDQ DX,R14
+ ADDQ R13,R14
+ IMUL3Q $19,R15,CX
+ ADDQ CX,SI
+ MOVQ SI,CX
+ SHRQ $51,CX
+ ADDQ R8,CX
+ MOVQ CX,R8
+ SHRQ $51,CX
+ ANDQ DX,SI
+ ADDQ R10,CX
+ MOVQ CX,R9
+ SHRQ $51,CX
+ ANDQ DX,R8
+ ADDQ R12,CX
+ MOVQ CX,AX
+ SHRQ $51,CX
+ ANDQ DX,R9
+ ADDQ R14,CX
+ MOVQ CX,R10
+ SHRQ $51,CX
+ ANDQ DX,AX
+ IMUL3Q $19,CX,CX
+ ADDQ CX,SI
+ ANDQ DX,R10
+ MOVQ SI,40(DI)
+ MOVQ R8,48(DI)
+ MOVQ R9,56(DI)
+ MOVQ AX,64(DI)
+ MOVQ R10,72(DI)
+ MOVQ 216(SP),AX
+ MULQ ·_121666_213(SB)
+ SHRQ $13,AX
+ MOVQ AX,SI
+ MOVQ DX,CX
+ MOVQ 224(SP),AX
+ MULQ ·_121666_213(SB)
+ SHRQ $13,AX
+ ADDQ AX,CX
+ MOVQ DX,R8
+ MOVQ 232(SP),AX
+ MULQ ·_121666_213(SB)
+ SHRQ $13,AX
+ ADDQ AX,R8
+ MOVQ DX,R9
+ MOVQ 240(SP),AX
+ MULQ ·_121666_213(SB)
+ SHRQ $13,AX
+ ADDQ AX,R9
+ MOVQ DX,R10
+ MOVQ 248(SP),AX
+ MULQ ·_121666_213(SB)
+ SHRQ $13,AX
+ ADDQ AX,R10
+ IMUL3Q $19,DX,DX
+ ADDQ DX,SI
+ ADDQ 136(SP),SI
+ ADDQ 144(SP),CX
+ ADDQ 152(SP),R8
+ ADDQ 160(SP),R9
+ ADDQ 168(SP),R10
+ MOVQ SI,80(DI)
+ MOVQ CX,88(DI)
+ MOVQ R8,96(DI)
+ MOVQ R9,104(DI)
+ MOVQ R10,112(DI)
+ MOVQ 104(DI),SI
+ IMUL3Q $19,SI,AX
+ MOVQ AX,56(SP)
+ MULQ 232(SP)
+ MOVQ AX,SI
+ MOVQ DX,CX
+ MOVQ 112(DI),DX
+ IMUL3Q $19,DX,AX
+ MOVQ AX,64(SP)
+ MULQ 224(SP)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 80(DI),AX
+ MULQ 216(SP)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 80(DI),AX
+ MULQ 224(SP)
+ MOVQ AX,R8
+ MOVQ DX,R9
+ MOVQ 80(DI),AX
+ MULQ 232(SP)
+ MOVQ AX,R10
+ MOVQ DX,R11
+ MOVQ 80(DI),AX
+ MULQ 240(SP)
+ MOVQ AX,R12
+ MOVQ DX,R13
+ MOVQ 80(DI),AX
+ MULQ 248(SP)
+ MOVQ AX,R14
+ MOVQ DX,R15
+ MOVQ 88(DI),AX
+ MULQ 216(SP)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 88(DI),AX
+ MULQ 224(SP)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 88(DI),AX
+ MULQ 232(SP)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ 88(DI),AX
+ MULQ 240(SP)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 88(DI),DX
+ IMUL3Q $19,DX,AX
+ MULQ 248(SP)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 96(DI),AX
+ MULQ 216(SP)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 96(DI),AX
+ MULQ 224(SP)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ 96(DI),AX
+ MULQ 232(SP)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 96(DI),DX
+ IMUL3Q $19,DX,AX
+ MULQ 240(SP)
+ ADDQ AX,SI
+ ADCQ DX,CX
+ MOVQ 96(DI),DX
+ IMUL3Q $19,DX,AX
+ MULQ 248(SP)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 104(DI),AX
+ MULQ 216(SP)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ 104(DI),AX
+ MULQ 224(SP)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 56(SP),AX
+ MULQ 240(SP)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 56(SP),AX
+ MULQ 248(SP)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 112(DI),AX
+ MULQ 216(SP)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 64(SP),AX
+ MULQ 232(SP)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 64(SP),AX
+ MULQ 240(SP)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 64(SP),AX
+ MULQ 248(SP)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ ·REDMASK51(SB),DX
+ SHLQ $13,CX:SI
+ ANDQ DX,SI
+ SHLQ $13,R9:R8
+ ANDQ DX,R8
+ ADDQ CX,R8
+ SHLQ $13,R11:R10
+ ANDQ DX,R10
+ ADDQ R9,R10
+ SHLQ $13,R13:R12
+ ANDQ DX,R12
+ ADDQ R11,R12
+ SHLQ $13,R15:R14
+ ANDQ DX,R14
+ ADDQ R13,R14
+ IMUL3Q $19,R15,CX
+ ADDQ CX,SI
+ MOVQ SI,CX
+ SHRQ $51,CX
+ ADDQ R8,CX
+ MOVQ CX,R8
+ SHRQ $51,CX
+ ANDQ DX,SI
+ ADDQ R10,CX
+ MOVQ CX,R9
+ SHRQ $51,CX
+ ANDQ DX,R8
+ ADDQ R12,CX
+ MOVQ CX,AX
+ SHRQ $51,CX
+ ANDQ DX,R9
+ ADDQ R14,CX
+ MOVQ CX,R10
+ SHRQ $51,CX
+ ANDQ DX,AX
+ IMUL3Q $19,CX,CX
+ ADDQ CX,SI
+ ANDQ DX,R10
+ MOVQ SI,80(DI)
+ MOVQ R8,88(DI)
+ MOVQ R9,96(DI)
+ MOVQ AX,104(DI)
+ MOVQ R10,112(DI)
+ MOVQ 0(SP),R11
+ MOVQ 8(SP),R12
+ MOVQ 16(SP),R13
+ MOVQ 24(SP),R14
+ MOVQ 32(SP),R15
+ MOVQ 40(SP),BX
+ MOVQ 48(SP),BP
+ MOVQ R11,SP
+ MOVQ DI,AX
+ MOVQ SI,DX
+ RET
diff --git a/src/ssl/test/runner/curve25519/mont25519_amd64.go b/src/ssl/test/runner/curve25519/mont25519_amd64.go
new file mode 100644
index 0000000..5822bd5
--- /dev/null
+++ b/src/ssl/test/runner/curve25519/mont25519_amd64.go
@@ -0,0 +1,240 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build amd64,!gccgo,!appengine
+
+package curve25519
+
+// These functions are implemented in the .s files. The names of the functions
+// in the rest of the file are also taken from the SUPERCOP sources to help
+// people following along.
+
+//go:noescape
+
+func cswap(inout *[5]uint64, v uint64)
+
+//go:noescape
+
+func ladderstep(inout *[5][5]uint64)
+
+//go:noescape
+
+func freeze(inout *[5]uint64)
+
+//go:noescape
+
+func mul(dest, a, b *[5]uint64)
+
+//go:noescape
+
+func square(out, in *[5]uint64)
+
+// mladder uses a Montgomery ladder to calculate (xr/zr) *= s.
+func mladder(xr, zr *[5]uint64, s *[32]byte) {
+ var work [5][5]uint64
+
+ work[0] = *xr
+ setint(&work[1], 1)
+ setint(&work[2], 0)
+ work[3] = *xr
+ setint(&work[4], 1)
+
+ j := uint(6)
+ var prevbit byte
+
+ for i := 31; i >= 0; i-- {
+ for j < 8 {
+ bit := ((*s)[i] >> j) & 1
+ swap := bit ^ prevbit
+ prevbit = bit
+ cswap(&work[1], uint64(swap))
+ ladderstep(&work)
+ j--
+ }
+ j = 7
+ }
+
+ *xr = work[1]
+ *zr = work[2]
+}
+
+func scalarMult(out, in, base *[32]byte) {
+ var e [32]byte
+ copy(e[:], (*in)[:])
+ e[0] &= 248
+ e[31] &= 127
+ e[31] |= 64
+
+ var t, z [5]uint64
+ unpack(&t, base)
+ mladder(&t, &z, &e)
+ invert(&z, &z)
+ mul(&t, &t, &z)
+ pack(out, &t)
+}
+
+func setint(r *[5]uint64, v uint64) {
+ r[0] = v
+ r[1] = 0
+ r[2] = 0
+ r[3] = 0
+ r[4] = 0
+}
+
+// unpack sets r = x where r consists of 5, 51-bit limbs in little-endian
+// order.
+func unpack(r *[5]uint64, x *[32]byte) {
+ r[0] = uint64(x[0]) |
+ uint64(x[1])<<8 |
+ uint64(x[2])<<16 |
+ uint64(x[3])<<24 |
+ uint64(x[4])<<32 |
+ uint64(x[5])<<40 |
+ uint64(x[6]&7)<<48
+
+ r[1] = uint64(x[6])>>3 |
+ uint64(x[7])<<5 |
+ uint64(x[8])<<13 |
+ uint64(x[9])<<21 |
+ uint64(x[10])<<29 |
+ uint64(x[11])<<37 |
+ uint64(x[12]&63)<<45
+
+ r[2] = uint64(x[12])>>6 |
+ uint64(x[13])<<2 |
+ uint64(x[14])<<10 |
+ uint64(x[15])<<18 |
+ uint64(x[16])<<26 |
+ uint64(x[17])<<34 |
+ uint64(x[18])<<42 |
+ uint64(x[19]&1)<<50
+
+ r[3] = uint64(x[19])>>1 |
+ uint64(x[20])<<7 |
+ uint64(x[21])<<15 |
+ uint64(x[22])<<23 |
+ uint64(x[23])<<31 |
+ uint64(x[24])<<39 |
+ uint64(x[25]&15)<<47
+
+ r[4] = uint64(x[25])>>4 |
+ uint64(x[26])<<4 |
+ uint64(x[27])<<12 |
+ uint64(x[28])<<20 |
+ uint64(x[29])<<28 |
+ uint64(x[30])<<36 |
+ uint64(x[31]&127)<<44
+}
+
+// pack sets out = x where out is the usual, little-endian form of the 5,
+// 51-bit limbs in x.
+func pack(out *[32]byte, x *[5]uint64) {
+ t := *x
+ freeze(&t)
+
+ out[0] = byte(t[0])
+ out[1] = byte(t[0] >> 8)
+ out[2] = byte(t[0] >> 16)
+ out[3] = byte(t[0] >> 24)
+ out[4] = byte(t[0] >> 32)
+ out[5] = byte(t[0] >> 40)
+ out[6] = byte(t[0] >> 48)
+
+ out[6] ^= byte(t[1]<<3) & 0xf8
+ out[7] = byte(t[1] >> 5)
+ out[8] = byte(t[1] >> 13)
+ out[9] = byte(t[1] >> 21)
+ out[10] = byte(t[1] >> 29)
+ out[11] = byte(t[1] >> 37)
+ out[12] = byte(t[1] >> 45)
+
+ out[12] ^= byte(t[2]<<6) & 0xc0
+ out[13] = byte(t[2] >> 2)
+ out[14] = byte(t[2] >> 10)
+ out[15] = byte(t[2] >> 18)
+ out[16] = byte(t[2] >> 26)
+ out[17] = byte(t[2] >> 34)
+ out[18] = byte(t[2] >> 42)
+ out[19] = byte(t[2] >> 50)
+
+ out[19] ^= byte(t[3]<<1) & 0xfe
+ out[20] = byte(t[3] >> 7)
+ out[21] = byte(t[3] >> 15)
+ out[22] = byte(t[3] >> 23)
+ out[23] = byte(t[3] >> 31)
+ out[24] = byte(t[3] >> 39)
+ out[25] = byte(t[3] >> 47)
+
+ out[25] ^= byte(t[4]<<4) & 0xf0
+ out[26] = byte(t[4] >> 4)
+ out[27] = byte(t[4] >> 12)
+ out[28] = byte(t[4] >> 20)
+ out[29] = byte(t[4] >> 28)
+ out[30] = byte(t[4] >> 36)
+ out[31] = byte(t[4] >> 44)
+}
+
+// invert calculates r = x^-1 mod p using Fermat's little theorem.
+func invert(r *[5]uint64, x *[5]uint64) {
+ var z2, z9, z11, z2_5_0, z2_10_0, z2_20_0, z2_50_0, z2_100_0, t [5]uint64
+
+ square(&z2, x) /* 2 */
+ square(&t, &z2) /* 4 */
+ square(&t, &t) /* 8 */
+ mul(&z9, &t, x) /* 9 */
+ mul(&z11, &z9, &z2) /* 11 */
+ square(&t, &z11) /* 22 */
+ mul(&z2_5_0, &t, &z9) /* 2^5 - 2^0 = 31 */
+
+ square(&t, &z2_5_0) /* 2^6 - 2^1 */
+ for i := 1; i < 5; i++ { /* 2^20 - 2^10 */
+ square(&t, &t)
+ }
+ mul(&z2_10_0, &t, &z2_5_0) /* 2^10 - 2^0 */
+
+ square(&t, &z2_10_0) /* 2^11 - 2^1 */
+ for i := 1; i < 10; i++ { /* 2^20 - 2^10 */
+ square(&t, &t)
+ }
+ mul(&z2_20_0, &t, &z2_10_0) /* 2^20 - 2^0 */
+
+ square(&t, &z2_20_0) /* 2^21 - 2^1 */
+ for i := 1; i < 20; i++ { /* 2^40 - 2^20 */
+ square(&t, &t)
+ }
+ mul(&t, &t, &z2_20_0) /* 2^40 - 2^0 */
+
+ square(&t, &t) /* 2^41 - 2^1 */
+ for i := 1; i < 10; i++ { /* 2^50 - 2^10 */
+ square(&t, &t)
+ }
+ mul(&z2_50_0, &t, &z2_10_0) /* 2^50 - 2^0 */
+
+ square(&t, &z2_50_0) /* 2^51 - 2^1 */
+ for i := 1; i < 50; i++ { /* 2^100 - 2^50 */
+ square(&t, &t)
+ }
+ mul(&z2_100_0, &t, &z2_50_0) /* 2^100 - 2^0 */
+
+ square(&t, &z2_100_0) /* 2^101 - 2^1 */
+ for i := 1; i < 100; i++ { /* 2^200 - 2^100 */
+ square(&t, &t)
+ }
+ mul(&t, &t, &z2_100_0) /* 2^200 - 2^0 */
+
+ square(&t, &t) /* 2^201 - 2^1 */
+ for i := 1; i < 50; i++ { /* 2^250 - 2^50 */
+ square(&t, &t)
+ }
+ mul(&t, &t, &z2_50_0) /* 2^250 - 2^0 */
+
+ square(&t, &t) /* 2^251 - 2^1 */
+ square(&t, &t) /* 2^252 - 2^2 */
+ square(&t, &t) /* 2^253 - 2^3 */
+
+ square(&t, &t) /* 2^254 - 2^4 */
+
+ square(&t, &t) /* 2^255 - 2^5 */
+ mul(r, &t, &z11) /* 2^255 - 21 */
+}
diff --git a/src/ssl/test/runner/curve25519/mul_amd64.s b/src/ssl/test/runner/curve25519/mul_amd64.s
new file mode 100644
index 0000000..e48d183
--- /dev/null
+++ b/src/ssl/test/runner/curve25519/mul_amd64.s
@@ -0,0 +1,191 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This code was translated into a form compatible with 6a from the public
+// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
+
+// +build amd64,!gccgo,!appengine
+
+// func mul(dest, a, b *[5]uint64)
+TEXT ·mul(SB),0,$128-24
+ MOVQ dest+0(FP), DI
+ MOVQ a+8(FP), SI
+ MOVQ b+16(FP), DX
+
+ MOVQ SP,R11
+ MOVQ $31,CX
+ NOTQ CX
+ ANDQ CX,SP
+ ADDQ $32,SP
+
+ MOVQ R11,0(SP)
+ MOVQ R12,8(SP)
+ MOVQ R13,16(SP)
+ MOVQ R14,24(SP)
+ MOVQ R15,32(SP)
+ MOVQ BX,40(SP)
+ MOVQ BP,48(SP)
+ MOVQ DI,56(SP)
+ MOVQ DX,CX
+ MOVQ 24(SI),DX
+ IMUL3Q $19,DX,AX
+ MOVQ AX,64(SP)
+ MULQ 16(CX)
+ MOVQ AX,R8
+ MOVQ DX,R9
+ MOVQ 32(SI),DX
+ IMUL3Q $19,DX,AX
+ MOVQ AX,72(SP)
+ MULQ 8(CX)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 0(SI),AX
+ MULQ 0(CX)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 0(SI),AX
+ MULQ 8(CX)
+ MOVQ AX,R10
+ MOVQ DX,R11
+ MOVQ 0(SI),AX
+ MULQ 16(CX)
+ MOVQ AX,R12
+ MOVQ DX,R13
+ MOVQ 0(SI),AX
+ MULQ 24(CX)
+ MOVQ AX,R14
+ MOVQ DX,R15
+ MOVQ 0(SI),AX
+ MULQ 32(CX)
+ MOVQ AX,BX
+ MOVQ DX,BP
+ MOVQ 8(SI),AX
+ MULQ 0(CX)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 8(SI),AX
+ MULQ 8(CX)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ 8(SI),AX
+ MULQ 16(CX)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 8(SI),AX
+ MULQ 24(CX)
+ ADDQ AX,BX
+ ADCQ DX,BP
+ MOVQ 8(SI),DX
+ IMUL3Q $19,DX,AX
+ MULQ 32(CX)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 16(SI),AX
+ MULQ 0(CX)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ 16(SI),AX
+ MULQ 8(CX)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 16(SI),AX
+ MULQ 16(CX)
+ ADDQ AX,BX
+ ADCQ DX,BP
+ MOVQ 16(SI),DX
+ IMUL3Q $19,DX,AX
+ MULQ 24(CX)
+ ADDQ AX,R8
+ ADCQ DX,R9
+ MOVQ 16(SI),DX
+ IMUL3Q $19,DX,AX
+ MULQ 32(CX)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 24(SI),AX
+ MULQ 0(CX)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ 24(SI),AX
+ MULQ 8(CX)
+ ADDQ AX,BX
+ ADCQ DX,BP
+ MOVQ 64(SP),AX
+ MULQ 24(CX)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 64(SP),AX
+ MULQ 32(CX)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ 32(SI),AX
+ MULQ 0(CX)
+ ADDQ AX,BX
+ ADCQ DX,BP
+ MOVQ 72(SP),AX
+ MULQ 16(CX)
+ ADDQ AX,R10
+ ADCQ DX,R11
+ MOVQ 72(SP),AX
+ MULQ 24(CX)
+ ADDQ AX,R12
+ ADCQ DX,R13
+ MOVQ 72(SP),AX
+ MULQ 32(CX)
+ ADDQ AX,R14
+ ADCQ DX,R15
+ MOVQ ·REDMASK51(SB),SI
+ SHLQ $13,R9:R8
+ ANDQ SI,R8
+ SHLQ $13,R11:R10
+ ANDQ SI,R10
+ ADDQ R9,R10
+ SHLQ $13,R13:R12
+ ANDQ SI,R12
+ ADDQ R11,R12
+ SHLQ $13,R15:R14
+ ANDQ SI,R14
+ ADDQ R13,R14
+ SHLQ $13,BP:BX
+ ANDQ SI,BX
+ ADDQ R15,BX
+ IMUL3Q $19,BP,DX
+ ADDQ DX,R8
+ MOVQ R8,DX
+ SHRQ $51,DX
+ ADDQ R10,DX
+ MOVQ DX,CX
+ SHRQ $51,DX
+ ANDQ SI,R8
+ ADDQ R12,DX
+ MOVQ DX,R9
+ SHRQ $51,DX
+ ANDQ SI,CX
+ ADDQ R14,DX
+ MOVQ DX,AX
+ SHRQ $51,DX
+ ANDQ SI,R9
+ ADDQ BX,DX
+ MOVQ DX,R10
+ SHRQ $51,DX
+ ANDQ SI,AX
+ IMUL3Q $19,DX,DX
+ ADDQ DX,R8
+ ANDQ SI,R10
+ MOVQ R8,0(DI)
+ MOVQ CX,8(DI)
+ MOVQ R9,16(DI)
+ MOVQ AX,24(DI)
+ MOVQ R10,32(DI)
+ MOVQ 0(SP),R11
+ MOVQ 8(SP),R12
+ MOVQ 16(SP),R13
+ MOVQ 24(SP),R14
+ MOVQ 32(SP),R15
+ MOVQ 40(SP),BX
+ MOVQ 48(SP),BP
+ MOVQ R11,SP
+ MOVQ DI,AX
+ MOVQ SI,DX
+ RET
diff --git a/src/ssl/test/runner/curve25519/square_amd64.s b/src/ssl/test/runner/curve25519/square_amd64.s
new file mode 100644
index 0000000..78d1a50
--- /dev/null
+++ b/src/ssl/test/runner/curve25519/square_amd64.s
@@ -0,0 +1,153 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This code was translated into a form compatible with 6a from the public
+// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
+
+// +build amd64,!gccgo,!appengine
+
+// func square(out, in *[5]uint64)
+TEXT ·square(SB),7,$96-16
+ MOVQ out+0(FP), DI
+ MOVQ in+8(FP), SI
+
+ MOVQ SP,R11
+ MOVQ $31,CX
+ NOTQ CX
+ ANDQ CX,SP
+ ADDQ $32, SP
+
+ MOVQ R11,0(SP)
+ MOVQ R12,8(SP)
+ MOVQ R13,16(SP)
+ MOVQ R14,24(SP)
+ MOVQ R15,32(SP)
+ MOVQ BX,40(SP)
+ MOVQ BP,48(SP)
+ MOVQ 0(SI),AX
+ MULQ 0(SI)
+ MOVQ AX,CX
+ MOVQ DX,R8
+ MOVQ 0(SI),AX
+ SHLQ $1,AX
+ MULQ 8(SI)
+ MOVQ AX,R9
+ MOVQ DX,R10
+ MOVQ 0(SI),AX
+ SHLQ $1,AX
+ MULQ 16(SI)
+ MOVQ AX,R11
+ MOVQ DX,R12
+ MOVQ 0(SI),AX
+ SHLQ $1,AX
+ MULQ 24(SI)
+ MOVQ AX,R13
+ MOVQ DX,R14
+ MOVQ 0(SI),AX
+ SHLQ $1,AX
+ MULQ 32(SI)
+ MOVQ AX,R15
+ MOVQ DX,BX
+ MOVQ 8(SI),AX
+ MULQ 8(SI)
+ ADDQ AX,R11
+ ADCQ DX,R12
+ MOVQ 8(SI),AX
+ SHLQ $1,AX
+ MULQ 16(SI)
+ ADDQ AX,R13
+ ADCQ DX,R14
+ MOVQ 8(SI),AX
+ SHLQ $1,AX
+ MULQ 24(SI)
+ ADDQ AX,R15
+ ADCQ DX,BX
+ MOVQ 8(SI),DX
+ IMUL3Q $38,DX,AX
+ MULQ 32(SI)
+ ADDQ AX,CX
+ ADCQ DX,R8
+ MOVQ 16(SI),AX
+ MULQ 16(SI)
+ ADDQ AX,R15
+ ADCQ DX,BX
+ MOVQ 16(SI),DX
+ IMUL3Q $38,DX,AX
+ MULQ 24(SI)
+ ADDQ AX,CX
+ ADCQ DX,R8
+ MOVQ 16(SI),DX
+ IMUL3Q $38,DX,AX
+ MULQ 32(SI)
+ ADDQ AX,R9
+ ADCQ DX,R10
+ MOVQ 24(SI),DX
+ IMUL3Q $19,DX,AX
+ MULQ 24(SI)
+ ADDQ AX,R9
+ ADCQ DX,R10
+ MOVQ 24(SI),DX
+ IMUL3Q $38,DX,AX
+ MULQ 32(SI)
+ ADDQ AX,R11
+ ADCQ DX,R12
+ MOVQ 32(SI),DX
+ IMUL3Q $19,DX,AX
+ MULQ 32(SI)
+ ADDQ AX,R13
+ ADCQ DX,R14
+ MOVQ ·REDMASK51(SB),SI
+ SHLQ $13,R8:CX
+ ANDQ SI,CX
+ SHLQ $13,R10:R9
+ ANDQ SI,R9
+ ADDQ R8,R9
+ SHLQ $13,R12:R11
+ ANDQ SI,R11
+ ADDQ R10,R11
+ SHLQ $13,R14:R13
+ ANDQ SI,R13
+ ADDQ R12,R13
+ SHLQ $13,BX:R15
+ ANDQ SI,R15
+ ADDQ R14,R15
+ IMUL3Q $19,BX,DX
+ ADDQ DX,CX
+ MOVQ CX,DX
+ SHRQ $51,DX
+ ADDQ R9,DX
+ ANDQ SI,CX
+ MOVQ DX,R8
+ SHRQ $51,DX
+ ADDQ R11,DX
+ ANDQ SI,R8
+ MOVQ DX,R9
+ SHRQ $51,DX
+ ADDQ R13,DX
+ ANDQ SI,R9
+ MOVQ DX,AX
+ SHRQ $51,DX
+ ADDQ R15,DX
+ ANDQ SI,AX
+ MOVQ DX,R10
+ SHRQ $51,DX
+ IMUL3Q $19,DX,DX
+ ADDQ DX,CX
+ ANDQ SI,R10
+ MOVQ CX,0(DI)
+ MOVQ R8,8(DI)
+ MOVQ R9,16(DI)
+ MOVQ AX,24(DI)
+ MOVQ R10,32(DI)
+ MOVQ 0(SP),R11
+ MOVQ 8(SP),R12
+ MOVQ 16(SP),R13
+ MOVQ 24(SP),R14
+ MOVQ 32(SP),R15
+ MOVQ 40(SP),BX
+ MOVQ 48(SP),BP
+ MOVQ R11,SP
+ MOVQ DI,AX
+ MOVQ SI,DX
+ RET
diff --git a/src/ssl/test/runner/handshake_client.go b/src/ssl/test/runner/handshake_client.go
index 9d8ffee..64630ba 100644
--- a/src/ssl/test/runner/handshake_client.go
+++ b/src/ssl/test/runner/handshake_client.go
@@ -98,7 +98,7 @@ func (c *Conn) clientHandshake() error {
}
}
- if c.config.Bugs.NoRenegotiationInfo {
+ if c.noRenegotiationInfo() {
hello.secureRenegotiation = nil
}
@@ -282,7 +282,7 @@ NextCipherSuite:
return errors.New("tls: renegotiation extension missing")
}
- if len(c.clientVerify) > 0 && !c.config.Bugs.NoRenegotiationInfo {
+ if len(c.clientVerify) > 0 && !c.noRenegotiationInfo() {
var expectedRenegInfo []byte
expectedRenegInfo = append(expectedRenegInfo, c.clientVerify...)
expectedRenegInfo = append(expectedRenegInfo, c.serverVerify...)
@@ -924,7 +924,11 @@ func (hs *clientHandshakeState) sendFinished(out []byte, isResume bool) error {
if !c.config.Bugs.SkipChangeCipherSpec &&
c.config.Bugs.EarlyChangeCipherSpec == 0 {
- c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
+ ccs := []byte{1}
+ if c.config.Bugs.BadChangeCipherSpec != nil {
+ ccs = c.config.Bugs.BadChangeCipherSpec
+ }
+ c.writeRecord(recordTypeChangeCipherSpec, ccs)
}
if c.config.Bugs.AppDataAfterChangeCipherSpec != nil {
diff --git a/src/ssl/test/runner/handshake_server.go b/src/ssl/test/runner/handshake_server.go
index 568f836..0232772 100644
--- a/src/ssl/test/runner/handshake_server.go
+++ b/src/ssl/test/runner/handshake_server.go
@@ -286,7 +286,7 @@ Curves:
hs.hello.secureRenegotiation = hs.clientHello.secureRenegotiation
}
- if c.config.Bugs.NoRenegotiationInfo {
+ if c.noRenegotiationInfo() {
hs.hello.secureRenegotiation = nil
}
@@ -914,7 +914,11 @@ func (hs *serverHandshakeState) sendFinished(out []byte) error {
c.dtlsFlushHandshake()
if !c.config.Bugs.SkipChangeCipherSpec {
- c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
+ ccs := []byte{1}
+ if c.config.Bugs.BadChangeCipherSpec != nil {
+ ccs = c.config.Bugs.BadChangeCipherSpec
+ }
+ c.writeRecord(recordTypeChangeCipherSpec, ccs)
}
if c.config.Bugs.AppDataAfterChangeCipherSpec != nil {
diff --git a/src/ssl/test/runner/key_agreement.go b/src/ssl/test/runner/key_agreement.go
index 3a9b899..4f399d9 100644
--- a/src/ssl/test/runner/key_agreement.go
+++ b/src/ssl/test/runner/key_agreement.go
@@ -12,11 +12,15 @@ import (
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
+ "crypto/subtle"
"crypto/x509"
"encoding/asn1"
"errors"
+ "fmt"
"io"
"math/big"
+
+ "./curve25519"
)
var errClientKeyExchange = errors.New("tls: invalid ClientKeyExchange message")
@@ -137,10 +141,11 @@ func (ka *rsaKeyAgreement) processServerKeyExchange(config *Config, clientHello
}
func (ka *rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
+ bad := config.Bugs.BadRSAClientKeyExchange
preMasterSecret := make([]byte, 48)
vers := clientHello.vers
- if config.Bugs.RsaClientKeyExchangeVersion != 0 {
- vers = config.Bugs.RsaClientKeyExchangeVersion
+ if bad == RSABadValueWrongVersion {
+ vers ^= 1
}
vers = versionToWire(vers, clientHello.isDTLS)
preMasterSecret[0] = byte(vers >> 8)
@@ -150,12 +155,25 @@ func (ka *rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello
return nil, nil, err
}
- encrypted, err := rsa.EncryptPKCS1v15(config.rand(), cert.PublicKey.(*rsa.PublicKey), preMasterSecret)
+ sentPreMasterSecret := preMasterSecret
+ if bad == RSABadValueTooLong {
+ sentPreMasterSecret = make([]byte, len(sentPreMasterSecret)+1)
+ copy(sentPreMasterSecret, preMasterSecret)
+ } else if bad == RSABadValueTooShort {
+ sentPreMasterSecret = sentPreMasterSecret[:len(sentPreMasterSecret)-1]
+ }
+
+ encrypted, err := rsa.EncryptPKCS1v15(config.rand(), cert.PublicKey.(*rsa.PublicKey), sentPreMasterSecret)
if err != nil {
return nil, nil, err
}
+ if bad == RSABadValueCorrupt {
+ encrypted[len(encrypted)-1] ^= 1
+ // Clear the high byte to ensure |encrypted| is still below the RSA modulus.
+ encrypted[0] = 0
+ }
ckx := new(clientKeyExchangeMsg)
- if clientHello.vers != VersionSSL30 && !config.Bugs.SSL3RSAKeyExchange {
+ if clientHello.vers != VersionSSL30 {
ckx.ciphertext = make([]byte, len(encrypted)+2)
ckx.ciphertext[0] = byte(len(encrypted) >> 8)
ckx.ciphertext[1] = byte(len(encrypted))
@@ -232,16 +250,90 @@ func pickTLS12HashForSignature(sigType uint8, clientList, serverList []signature
return 0, errors.New("tls: client doesn't support any common hash functions")
}
-func curveForCurveID(id CurveID) (elliptic.Curve, bool) {
+// A ecdhCurve is an instance of ECDH-style key agreement for TLS.
+type ecdhCurve interface {
+ // generateKeypair generates a keypair using rand. It returns the
+ // encoded public key.
+ generateKeypair(rand io.Reader) (publicKey []byte, err error)
+
+ // computeSecret performs a key exchange against peerKey and returns
+ // the resulting shared secret.
+ computeSecret(peerKey []byte) (preMasterSecret []byte, err error)
+}
+
+// ellipticECDHCurve implements ecdhCurve with an elliptic.Curve.
+type ellipticECDHCurve struct {
+ curve elliptic.Curve
+ privateKey []byte
+}
+
+func (e *ellipticECDHCurve) generateKeypair(rand io.Reader) (publicKey []byte, err error) {
+ var x, y *big.Int
+ e.privateKey, x, y, err = elliptic.GenerateKey(e.curve, rand)
+ if err != nil {
+ return nil, err
+ }
+ return elliptic.Marshal(e.curve, x, y), nil
+}
+
+func (e *ellipticECDHCurve) computeSecret(peerKey []byte) (preMasterSecret []byte, err error) {
+ x, y := elliptic.Unmarshal(e.curve, peerKey)
+ if x == nil {
+ return nil, errors.New("tls: invalid peer key")
+ }
+ x, _ = e.curve.ScalarMult(x, y, e.privateKey)
+ preMasterSecret = make([]byte, (e.curve.Params().BitSize+7)>>3)
+ xBytes := x.Bytes()
+ copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
+
+ return preMasterSecret, nil
+}
+
+// x25519ECDHCurve implements ecdhCurve with X25519.
+type x25519ECDHCurve struct {
+ privateKey [32]byte
+}
+
+func (e *x25519ECDHCurve) generateKeypair(rand io.Reader) (publicKey []byte, err error) {
+ _, err = io.ReadFull(rand, e.privateKey[:])
+ if err != nil {
+ return
+ }
+ var out [32]byte
+ curve25519.ScalarBaseMult(&out, &e.privateKey)
+ return out[:], nil
+}
+
+func (e *x25519ECDHCurve) computeSecret(peerKey []byte) (preMasterSecret []byte, err error) {
+ if len(peerKey) != 32 {
+ return nil, errors.New("tls: invalid peer key")
+ }
+ var out, peerKeyCopy [32]byte
+ copy(peerKeyCopy[:], peerKey)
+ curve25519.ScalarMult(&out, &e.privateKey, &peerKeyCopy)
+
+ // Per draft-irtf-cfrg-curves-11, reject the all-zero value in constant
+ // time.
+ var zeros [32]byte
+ if subtle.ConstantTimeCompare(zeros[:], out[:]) == 1 {
+ return nil, errors.New("tls: X25519 value with wrong order")
+ }
+
+ return out[:], nil
+}
+
+func curveForCurveID(id CurveID) (ecdhCurve, bool) {
switch id {
case CurveP224:
- return elliptic.P224(), true
+ return &ellipticECDHCurve{curve: elliptic.P224()}, true
case CurveP256:
- return elliptic.P256(), true
+ return &ellipticECDHCurve{curve: elliptic.P256()}, true
case CurveP384:
- return elliptic.P384(), true
+ return &ellipticECDHCurve{curve: elliptic.P384()}, true
case CurveP521:
- return elliptic.P521(), true
+ return &ellipticECDHCurve{curve: elliptic.P521()}, true
+ case CurveX25519:
+ return &x25519ECDHCurve{}, true
default:
return nil, false
}
@@ -269,6 +361,24 @@ func (ka *nilKeyAgreementAuthentication) verifyParameters(config *Config, client
return nil
}
+func maybeCorruptECDSAValue(n *big.Int, typeOfCorruption BadValue, limit *big.Int) *big.Int {
+ switch typeOfCorruption {
+ case BadValueNone:
+ return n
+ case BadValueNegative:
+ return new(big.Int).Neg(n)
+ case BadValueZero:
+ return big.NewInt(0)
+ case BadValueLimit:
+ return limit
+ case BadValueLarge:
+ bad := new(big.Int).Set(limit)
+ return bad.Lsh(bad, 20)
+ default:
+ panic("unknown BadValue type")
+ }
+}
+
// signedKeyAgreement signs the ServerKeyExchange parameters with the
// server's private key.
type signedKeyAgreement struct {
@@ -414,28 +524,9 @@ func (ka *signedKeyAgreement) verifyParameters(config *Config, clientHello *clie
// pre-master secret is then calculated using ECDH. The signature may
// either be ECDSA or RSA.
type ecdheKeyAgreement struct {
- auth keyAgreementAuthentication
- privateKey []byte
- curve elliptic.Curve
- x, y *big.Int
-}
-
-func maybeCorruptECDSAValue(n *big.Int, typeOfCorruption BadValue, limit *big.Int) *big.Int {
- switch typeOfCorruption {
- case BadValueNone:
- return n
- case BadValueNegative:
- return new(big.Int).Neg(n)
- case BadValueZero:
- return big.NewInt(0)
- case BadValueLimit:
- return limit
- case BadValueLarge:
- bad := new(big.Int).Set(limit)
- return bad.Lsh(bad, 20)
- default:
- panic("unknown BadValue type")
- }
+ auth keyAgreementAuthentication
+ curve ecdhCurve
+ peerKey []byte
}
func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
@@ -461,24 +552,21 @@ NextCandidate:
return nil, errors.New("tls: preferredCurves includes unsupported curve")
}
- var x, y *big.Int
- var err error
- ka.privateKey, x, y, err = elliptic.GenerateKey(ka.curve, config.rand())
+ publicKey, err := ka.curve.generateKeypair(config.rand())
if err != nil {
return nil, err
}
- ecdhePublic := elliptic.Marshal(ka.curve, x, y)
// http://tools.ietf.org/html/rfc4492#section-5.4
- serverECDHParams := make([]byte, 1+2+1+len(ecdhePublic))
+ serverECDHParams := make([]byte, 1+2+1+len(publicKey))
serverECDHParams[0] = 3 // named curve
serverECDHParams[1] = byte(curveid >> 8)
serverECDHParams[2] = byte(curveid)
if config.Bugs.InvalidSKXCurve {
serverECDHParams[2] ^= 0xff
}
- serverECDHParams[3] = byte(len(ecdhePublic))
- copy(serverECDHParams[4:], ecdhePublic)
+ serverECDHParams[3] = byte(len(publicKey))
+ copy(serverECDHParams[4:], publicKey)
return ka.auth.signParameters(config, cert, clientHello, hello, serverECDHParams)
}
@@ -487,16 +575,7 @@ func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Cert
if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 {
return nil, errClientKeyExchange
}
- x, y := elliptic.Unmarshal(ka.curve, ckx.ciphertext[1:])
- if x == nil {
- return nil, errClientKeyExchange
- }
- x, _ = ka.curve.ScalarMult(x, y, ka.privateKey)
- preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3)
- xBytes := x.Bytes()
- copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
-
- return preMasterSecret, nil
+ return ka.curve.computeSecret(ckx.ciphertext[1:])
}
func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
@@ -517,13 +596,12 @@ func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHell
if publicLen+4 > len(skx.key) {
return errServerKeyExchange
}
- ka.x, ka.y = elliptic.Unmarshal(ka.curve, skx.key[4:4+publicLen])
- if ka.x == nil {
- return errServerKeyExchange
- }
+ // Save the peer key for later.
+ ka.peerKey = skx.key[4 : 4+publicLen]
+
+ // Check the signature.
serverECDHParams := skx.key[:4+publicLen]
sig := skx.key[4+publicLen:]
-
return ka.auth.verifyParameters(config, clientHello, serverHello, cert, serverECDHParams, sig)
}
@@ -531,21 +609,20 @@ func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHel
if ka.curve == nil {
return nil, nil, errors.New("missing ServerKeyExchange message")
}
- priv, mx, my, err := elliptic.GenerateKey(ka.curve, config.rand())
+
+ publicKey, err := ka.curve.generateKeypair(config.rand())
+ if err != nil {
+ return nil, nil, err
+ }
+ preMasterSecret, err := ka.curve.computeSecret(ka.peerKey)
if err != nil {
return nil, nil, err
}
- x, _ := ka.curve.ScalarMult(ka.x, ka.y, priv)
- preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3)
- xBytes := x.Bytes()
- copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
-
- serialized := elliptic.Marshal(ka.curve, mx, my)
ckx := new(clientKeyExchangeMsg)
- ckx.ciphertext = make([]byte, 1+len(serialized))
- ckx.ciphertext[0] = byte(len(serialized))
- copy(ckx.ciphertext[1:], serialized)
+ ckx.ciphertext = make([]byte, 1+len(publicKey))
+ ckx.ciphertext[0] = byte(len(publicKey))
+ copy(ckx.ciphertext[1:], publicKey)
return preMasterSecret, ckx, nil
}
@@ -652,6 +729,10 @@ func (ka *dheKeyAgreement) processServerKeyExchange(config *Config, clientHello
return errServerKeyExchange
}
+ if l := config.Bugs.RequireDHPublicValueLen; l != 0 && l != yLen {
+ return fmt.Errorf("RequireDHPublicValueLen set to %d, but server's public value was %d bytes on the wire and %d bytes if minimal", l, yLen, (ka.yTheirs.BitLen()+7)/8)
+ }
+
sig := k
serverDHParams := skx.key[:len(skx.key)-len(sig)]
diff --git a/src/ssl/test/runner/packet_adapter.go b/src/ssl/test/runner/packet_adapter.go
index 2351eb0..a8da311 100644
--- a/src/ssl/test/runner/packet_adapter.go
+++ b/src/ssl/test/runner/packet_adapter.go
@@ -96,7 +96,7 @@ func (p *packetAdaptor) Write(b []byte) (int, error) {
// for acknowledgement of the timeout, buffering any packets received since
// then. The packets are then returned.
func (p *packetAdaptor) SendReadTimeout(d time.Duration) ([][]byte, error) {
- p.log("Simulating read timeout: " + d.String(), nil)
+ p.log("Simulating read timeout: "+d.String(), nil)
payload := make([]byte, 1+8)
payload[0] = opcodeTimeout
diff --git a/src/ssl/test/runner/poly1305/const_amd64.s b/src/ssl/test/runner/poly1305/const_amd64.s
new file mode 100644
index 0000000..8e861f3
--- /dev/null
+++ b/src/ssl/test/runner/poly1305/const_amd64.s
@@ -0,0 +1,45 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This code was translated into a form compatible with 6a from the public
+// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
+
+// +build amd64,!gccgo,!appengine
+
+DATA ·SCALE(SB)/8, $0x37F4000000000000
+GLOBL ·SCALE(SB), 8, $8
+DATA ·TWO32(SB)/8, $0x41F0000000000000
+GLOBL ·TWO32(SB), 8, $8
+DATA ·TWO64(SB)/8, $0x43F0000000000000
+GLOBL ·TWO64(SB), 8, $8
+DATA ·TWO96(SB)/8, $0x45F0000000000000
+GLOBL ·TWO96(SB), 8, $8
+DATA ·ALPHA32(SB)/8, $0x45E8000000000000
+GLOBL ·ALPHA32(SB), 8, $8
+DATA ·ALPHA64(SB)/8, $0x47E8000000000000
+GLOBL ·ALPHA64(SB), 8, $8
+DATA ·ALPHA96(SB)/8, $0x49E8000000000000
+GLOBL ·ALPHA96(SB), 8, $8
+DATA ·ALPHA130(SB)/8, $0x4C08000000000000
+GLOBL ·ALPHA130(SB), 8, $8
+DATA ·DOFFSET0(SB)/8, $0x4330000000000000
+GLOBL ·DOFFSET0(SB), 8, $8
+DATA ·DOFFSET1(SB)/8, $0x4530000000000000
+GLOBL ·DOFFSET1(SB), 8, $8
+DATA ·DOFFSET2(SB)/8, $0x4730000000000000
+GLOBL ·DOFFSET2(SB), 8, $8
+DATA ·DOFFSET3(SB)/8, $0x4930000000000000
+GLOBL ·DOFFSET3(SB), 8, $8
+DATA ·DOFFSET3MINUSTWO128(SB)/8, $0x492FFFFE00000000
+GLOBL ·DOFFSET3MINUSTWO128(SB), 8, $8
+DATA ·HOFFSET0(SB)/8, $0x43300001FFFFFFFB
+GLOBL ·HOFFSET0(SB), 8, $8
+DATA ·HOFFSET1(SB)/8, $0x45300001FFFFFFFE
+GLOBL ·HOFFSET1(SB), 8, $8
+DATA ·HOFFSET2(SB)/8, $0x47300001FFFFFFFE
+GLOBL ·HOFFSET2(SB), 8, $8
+DATA ·HOFFSET3(SB)/8, $0x49300003FFFFFFFE
+GLOBL ·HOFFSET3(SB), 8, $8
+DATA ·ROUNDING(SB)/2, $0x137f
+GLOBL ·ROUNDING(SB), 8, $2
diff --git a/src/ssl/test/runner/poly1305/poly1305.go b/src/ssl/test/runner/poly1305/poly1305.go
new file mode 100644
index 0000000..4a5f826
--- /dev/null
+++ b/src/ssl/test/runner/poly1305/poly1305.go
@@ -0,0 +1,32 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Package poly1305 implements Poly1305 one-time message authentication code as specified in http://cr.yp.to/mac/poly1305-20050329.pdf.
+
+Poly1305 is a fast, one-time authentication function. It is infeasible for an
+attacker to generate an authenticator for a message without the key. However, a
+key must only be used for a single message. Authenticating two different
+messages with the same key allows an attacker to forge authenticators for other
+messages with the same key.
+
+Poly1305 was originally coupled with AES in order to make Poly1305-AES. AES was
+used with a fixed key in order to generate one-time keys from an nonce.
+However, in this package AES isn't used and the one-time key is specified
+directly.
+*/
+package poly1305 // import "golang.org/x/crypto/poly1305"
+
+import "crypto/subtle"
+
+// TagSize is the size, in bytes, of a poly1305 authenticator.
+const TagSize = 16
+
+// Verify returns true if mac is a valid authenticator for m with the given
+// key.
+func Verify(mac *[16]byte, m []byte, key *[32]byte) bool {
+ var tmp [16]byte
+ Sum(&tmp, m, key)
+ return subtle.ConstantTimeCompare(tmp[:], mac[:]) == 1
+}
diff --git a/src/ssl/test/runner/poly1305/poly1305_amd64.s b/src/ssl/test/runner/poly1305/poly1305_amd64.s
new file mode 100644
index 0000000..f8d4ee9
--- /dev/null
+++ b/src/ssl/test/runner/poly1305/poly1305_amd64.s
@@ -0,0 +1,497 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This code was translated into a form compatible with 6a from the public
+// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
+
+// +build amd64,!gccgo,!appengine
+
+// func poly1305(out *[16]byte, m *byte, mlen uint64, key *[32]key)
+TEXT ·poly1305(SB),0,$224-32
+ MOVQ out+0(FP),DI
+ MOVQ m+8(FP),SI
+ MOVQ mlen+16(FP),DX
+ MOVQ key+24(FP),CX
+
+ MOVQ SP,R11
+ MOVQ $31,R9
+ NOTQ R9
+ ANDQ R9,SP
+ ADDQ $32,SP
+
+ MOVQ R11,32(SP)
+ MOVQ R12,40(SP)
+ MOVQ R13,48(SP)
+ MOVQ R14,56(SP)
+ MOVQ R15,64(SP)
+ MOVQ BX,72(SP)
+ MOVQ BP,80(SP)
+ FLDCW ·ROUNDING(SB)
+ MOVL 0(CX),R8
+ MOVL 4(CX),R9
+ MOVL 8(CX),AX
+ MOVL 12(CX),R10
+ MOVQ DI,88(SP)
+ MOVQ CX,96(SP)
+ MOVL $0X43300000,108(SP)
+ MOVL $0X45300000,116(SP)
+ MOVL $0X47300000,124(SP)
+ MOVL $0X49300000,132(SP)
+ ANDL $0X0FFFFFFF,R8
+ ANDL $0X0FFFFFFC,R9
+ ANDL $0X0FFFFFFC,AX
+ ANDL $0X0FFFFFFC,R10
+ MOVL R8,104(SP)
+ MOVL R9,112(SP)
+ MOVL AX,120(SP)
+ MOVL R10,128(SP)
+ FMOVD 104(SP), F0
+ FSUBD ·DOFFSET0(SB), F0
+ FMOVD 112(SP), F0
+ FSUBD ·DOFFSET1(SB), F0
+ FMOVD 120(SP), F0
+ FSUBD ·DOFFSET2(SB), F0
+ FMOVD 128(SP), F0
+ FSUBD ·DOFFSET3(SB), F0
+ FXCHD F0, F3
+ FMOVDP F0, 136(SP)
+ FXCHD F0, F1
+ FMOVD F0, 144(SP)
+ FMULD ·SCALE(SB), F0
+ FMOVDP F0, 152(SP)
+ FMOVD F0, 160(SP)
+ FMULD ·SCALE(SB), F0
+ FMOVDP F0, 168(SP)
+ FMOVD F0, 176(SP)
+ FMULD ·SCALE(SB), F0
+ FMOVDP F0, 184(SP)
+ FLDZ
+ FLDZ
+ FLDZ
+ FLDZ
+ CMPQ DX,$16
+ JB ADDATMOST15BYTES
+ INITIALATLEAST16BYTES:
+ MOVL 12(SI),DI
+ MOVL 8(SI),CX
+ MOVL 4(SI),R8
+ MOVL 0(SI),R9
+ MOVL DI,128(SP)
+ MOVL CX,120(SP)
+ MOVL R8,112(SP)
+ MOVL R9,104(SP)
+ ADDQ $16,SI
+ SUBQ $16,DX
+ FXCHD F0, F3
+ FADDD 128(SP), F0
+ FSUBD ·DOFFSET3MINUSTWO128(SB), F0
+ FXCHD F0, F1
+ FADDD 112(SP), F0
+ FSUBD ·DOFFSET1(SB), F0
+ FXCHD F0, F2
+ FADDD 120(SP), F0
+ FSUBD ·DOFFSET2(SB), F0
+ FXCHD F0, F3
+ FADDD 104(SP), F0
+ FSUBD ·DOFFSET0(SB), F0
+ CMPQ DX,$16
+ JB MULTIPLYADDATMOST15BYTES
+ MULTIPLYADDATLEAST16BYTES:
+ MOVL 12(SI),DI
+ MOVL 8(SI),CX
+ MOVL 4(SI),R8
+ MOVL 0(SI),R9
+ MOVL DI,128(SP)
+ MOVL CX,120(SP)
+ MOVL R8,112(SP)
+ MOVL R9,104(SP)
+ ADDQ $16,SI
+ SUBQ $16,DX
+ FMOVD ·ALPHA130(SB), F0
+ FADDD F2,F0
+ FSUBD ·ALPHA130(SB), F0
+ FSUBD F0,F2
+ FMULD ·SCALE(SB), F0
+ FMOVD ·ALPHA32(SB), F0
+ FADDD F2,F0
+ FSUBD ·ALPHA32(SB), F0
+ FSUBD F0,F2
+ FXCHD F0, F2
+ FADDDP F0,F1
+ FMOVD ·ALPHA64(SB), F0
+ FADDD F4,F0
+ FSUBD ·ALPHA64(SB), F0
+ FSUBD F0,F4
+ FMOVD ·ALPHA96(SB), F0
+ FADDD F6,F0
+ FSUBD ·ALPHA96(SB), F0
+ FSUBD F0,F6
+ FXCHD F0, F6
+ FADDDP F0,F1
+ FXCHD F0, F3
+ FADDDP F0,F5
+ FXCHD F0, F3
+ FADDDP F0,F1
+ FMOVD 176(SP), F0
+ FMULD F3,F0
+ FMOVD 160(SP), F0
+ FMULD F4,F0
+ FMOVD 144(SP), F0
+ FMULD F5,F0
+ FMOVD 136(SP), F0
+ FMULDP F0,F6
+ FMOVD 160(SP), F0
+ FMULD F4,F0
+ FADDDP F0,F3
+ FMOVD 144(SP), F0
+ FMULD F4,F0
+ FADDDP F0,F2
+ FMOVD 136(SP), F0
+ FMULD F4,F0
+ FADDDP F0,F1
+ FMOVD 184(SP), F0
+ FMULDP F0,F4
+ FXCHD F0, F3
+ FADDDP F0,F5
+ FMOVD 144(SP), F0
+ FMULD F4,F0
+ FADDDP F0,F2
+ FMOVD 136(SP), F0
+ FMULD F4,F0
+ FADDDP F0,F1
+ FMOVD 184(SP), F0
+ FMULD F4,F0
+ FADDDP F0,F3
+ FMOVD 168(SP), F0
+ FMULDP F0,F4
+ FXCHD F0, F3
+ FADDDP F0,F4
+ FMOVD 136(SP), F0
+ FMULD F5,F0
+ FADDDP F0,F1
+ FXCHD F0, F3
+ FMOVD 184(SP), F0
+ FMULD F5,F0
+ FADDDP F0,F3
+ FXCHD F0, F1
+ FMOVD 168(SP), F0
+ FMULD F5,F0
+ FADDDP F0,F1
+ FMOVD 152(SP), F0
+ FMULDP F0,F5
+ FXCHD F0, F4
+ FADDDP F0,F1
+ CMPQ DX,$16
+ FXCHD F0, F2
+ FMOVD 128(SP), F0
+ FSUBD ·DOFFSET3MINUSTWO128(SB), F0
+ FADDDP F0,F1
+ FXCHD F0, F1
+ FMOVD 120(SP), F0
+ FSUBD ·DOFFSET2(SB), F0
+ FADDDP F0,F1
+ FXCHD F0, F3
+ FMOVD 112(SP), F0
+ FSUBD ·DOFFSET1(SB), F0
+ FADDDP F0,F1
+ FXCHD F0, F2
+ FMOVD 104(SP), F0
+ FSUBD ·DOFFSET0(SB), F0
+ FADDDP F0,F1
+ JAE MULTIPLYADDATLEAST16BYTES
+ MULTIPLYADDATMOST15BYTES:
+ FMOVD ·ALPHA130(SB), F0
+ FADDD F2,F0
+ FSUBD ·ALPHA130(SB), F0
+ FSUBD F0,F2
+ FMULD ·SCALE(SB), F0
+ FMOVD ·ALPHA32(SB), F0
+ FADDD F2,F0
+ FSUBD ·ALPHA32(SB), F0
+ FSUBD F0,F2
+ FMOVD ·ALPHA64(SB), F0
+ FADDD F5,F0
+ FSUBD ·ALPHA64(SB), F0
+ FSUBD F0,F5
+ FMOVD ·ALPHA96(SB), F0
+ FADDD F7,F0
+ FSUBD ·ALPHA96(SB), F0
+ FSUBD F0,F7
+ FXCHD F0, F7
+ FADDDP F0,F1
+ FXCHD F0, F5
+ FADDDP F0,F1
+ FXCHD F0, F3
+ FADDDP F0,F5
+ FADDDP F0,F1
+ FMOVD 176(SP), F0
+ FMULD F1,F0
+ FMOVD 160(SP), F0
+ FMULD F2,F0
+ FMOVD 144(SP), F0
+ FMULD F3,F0
+ FMOVD 136(SP), F0
+ FMULDP F0,F4
+ FMOVD 160(SP), F0
+ FMULD F5,F0
+ FADDDP F0,F3
+ FMOVD 144(SP), F0
+ FMULD F5,F0
+ FADDDP F0,F2
+ FMOVD 136(SP), F0
+ FMULD F5,F0
+ FADDDP F0,F1
+ FMOVD 184(SP), F0
+ FMULDP F0,F5
+ FXCHD F0, F4
+ FADDDP F0,F3
+ FMOVD 144(SP), F0
+ FMULD F5,F0
+ FADDDP F0,F2
+ FMOVD 136(SP), F0
+ FMULD F5,F0
+ FADDDP F0,F1
+ FMOVD 184(SP), F0
+ FMULD F5,F0
+ FADDDP F0,F4
+ FMOVD 168(SP), F0
+ FMULDP F0,F5
+ FXCHD F0, F4
+ FADDDP F0,F2
+ FMOVD 136(SP), F0
+ FMULD F5,F0
+ FADDDP F0,F1
+ FMOVD 184(SP), F0
+ FMULD F5,F0
+ FADDDP F0,F4
+ FMOVD 168(SP), F0
+ FMULD F5,F0
+ FADDDP F0,F3
+ FMOVD 152(SP), F0
+ FMULDP F0,F5
+ FXCHD F0, F4
+ FADDDP F0,F1
+ ADDATMOST15BYTES:
+ CMPQ DX,$0
+ JE NOMOREBYTES
+ MOVL $0,0(SP)
+ MOVL $0, 4 (SP)
+ MOVL $0, 8 (SP)
+ MOVL $0, 12 (SP)
+ LEAQ 0(SP),DI
+ MOVQ DX,CX
+ REP; MOVSB
+ MOVB $1,0(DI)
+ MOVL 12 (SP),DI
+ MOVL 8 (SP),SI
+ MOVL 4 (SP),DX
+ MOVL 0(SP),CX
+ MOVL DI,128(SP)
+ MOVL SI,120(SP)
+ MOVL DX,112(SP)
+ MOVL CX,104(SP)
+ FXCHD F0, F3
+ FADDD 128(SP), F0
+ FSUBD ·DOFFSET3(SB), F0
+ FXCHD F0, F2
+ FADDD 120(SP), F0
+ FSUBD ·DOFFSET2(SB), F0
+ FXCHD F0, F1
+ FADDD 112(SP), F0
+ FSUBD ·DOFFSET1(SB), F0
+ FXCHD F0, F3
+ FADDD 104(SP), F0
+ FSUBD ·DOFFSET0(SB), F0
+ FMOVD ·ALPHA130(SB), F0
+ FADDD F3,F0
+ FSUBD ·ALPHA130(SB), F0
+ FSUBD F0,F3
+ FMULD ·SCALE(SB), F0
+ FMOVD ·ALPHA32(SB), F0
+ FADDD F2,F0
+ FSUBD ·ALPHA32(SB), F0
+ FSUBD F0,F2
+ FMOVD ·ALPHA64(SB), F0
+ FADDD F6,F0
+ FSUBD ·ALPHA64(SB), F0
+ FSUBD F0,F6
+ FMOVD ·ALPHA96(SB), F0
+ FADDD F5,F0
+ FSUBD ·ALPHA96(SB), F0
+ FSUBD F0,F5
+ FXCHD F0, F4
+ FADDDP F0,F3
+ FXCHD F0, F6
+ FADDDP F0,F1
+ FXCHD F0, F3
+ FADDDP F0,F5
+ FXCHD F0, F3
+ FADDDP F0,F1
+ FMOVD 176(SP), F0
+ FMULD F3,F0
+ FMOVD 160(SP), F0
+ FMULD F4,F0
+ FMOVD 144(SP), F0
+ FMULD F5,F0
+ FMOVD 136(SP), F0
+ FMULDP F0,F6
+ FMOVD 160(SP), F0
+ FMULD F5,F0
+ FADDDP F0,F3
+ FMOVD 144(SP), F0
+ FMULD F5,F0
+ FADDDP F0,F2
+ FMOVD 136(SP), F0
+ FMULD F5,F0
+ FADDDP F0,F1
+ FMOVD 184(SP), F0
+ FMULDP F0,F5
+ FXCHD F0, F4
+ FADDDP F0,F5
+ FMOVD 144(SP), F0
+ FMULD F6,F0
+ FADDDP F0,F2
+ FMOVD 136(SP), F0
+ FMULD F6,F0
+ FADDDP F0,F1
+ FMOVD 184(SP), F0
+ FMULD F6,F0
+ FADDDP F0,F4
+ FMOVD 168(SP), F0
+ FMULDP F0,F6
+ FXCHD F0, F5
+ FADDDP F0,F4
+ FMOVD 136(SP), F0
+ FMULD F2,F0
+ FADDDP F0,F1
+ FMOVD 184(SP), F0
+ FMULD F2,F0
+ FADDDP F0,F5
+ FMOVD 168(SP), F0
+ FMULD F2,F0
+ FADDDP F0,F3
+ FMOVD 152(SP), F0
+ FMULDP F0,F2
+ FXCHD F0, F1
+ FADDDP F0,F3
+ FXCHD F0, F3
+ FXCHD F0, F2
+ NOMOREBYTES:
+ MOVL $0,R10
+ FMOVD ·ALPHA130(SB), F0
+ FADDD F4,F0
+ FSUBD ·ALPHA130(SB), F0
+ FSUBD F0,F4
+ FMULD ·SCALE(SB), F0
+ FMOVD ·ALPHA32(SB), F0
+ FADDD F2,F0
+ FSUBD ·ALPHA32(SB), F0
+ FSUBD F0,F2
+ FMOVD ·ALPHA64(SB), F0
+ FADDD F4,F0
+ FSUBD ·ALPHA64(SB), F0
+ FSUBD F0,F4
+ FMOVD ·ALPHA96(SB), F0
+ FADDD F6,F0
+ FSUBD ·ALPHA96(SB), F0
+ FXCHD F0, F6
+ FSUBD F6,F0
+ FXCHD F0, F4
+ FADDDP F0,F3
+ FXCHD F0, F4
+ FADDDP F0,F1
+ FXCHD F0, F2
+ FADDDP F0,F3
+ FXCHD F0, F4
+ FADDDP F0,F3
+ FXCHD F0, F3
+ FADDD ·HOFFSET0(SB), F0
+ FXCHD F0, F3
+ FADDD ·HOFFSET1(SB), F0
+ FXCHD F0, F1
+ FADDD ·HOFFSET2(SB), F0
+ FXCHD F0, F2
+ FADDD ·HOFFSET3(SB), F0
+ FXCHD F0, F3
+ FMOVDP F0, 104(SP)
+ FMOVDP F0, 112(SP)
+ FMOVDP F0, 120(SP)
+ FMOVDP F0, 128(SP)
+ MOVL 108(SP),DI
+ ANDL $63,DI
+ MOVL 116(SP),SI
+ ANDL $63,SI
+ MOVL 124(SP),DX
+ ANDL $63,DX
+ MOVL 132(SP),CX
+ ANDL $63,CX
+ MOVL 112(SP),R8
+ ADDL DI,R8
+ MOVQ R8,112(SP)
+ MOVL 120(SP),DI
+ ADCL SI,DI
+ MOVQ DI,120(SP)
+ MOVL 128(SP),DI
+ ADCL DX,DI
+ MOVQ DI,128(SP)
+ MOVL R10,DI
+ ADCL CX,DI
+ MOVQ DI,136(SP)
+ MOVQ $5,DI
+ MOVL 104(SP),SI
+ ADDL SI,DI
+ MOVQ DI,104(SP)
+ MOVL R10,DI
+ MOVQ 112(SP),DX
+ ADCL DX,DI
+ MOVQ DI,112(SP)
+ MOVL R10,DI
+ MOVQ 120(SP),CX
+ ADCL CX,DI
+ MOVQ DI,120(SP)
+ MOVL R10,DI
+ MOVQ 128(SP),R8
+ ADCL R8,DI
+ MOVQ DI,128(SP)
+ MOVQ $0XFFFFFFFC,DI
+ MOVQ 136(SP),R9
+ ADCL R9,DI
+ SARL $16,DI
+ MOVQ DI,R9
+ XORL $0XFFFFFFFF,R9
+ ANDQ DI,SI
+ MOVQ 104(SP),AX
+ ANDQ R9,AX
+ ORQ AX,SI
+ ANDQ DI,DX
+ MOVQ 112(SP),AX
+ ANDQ R9,AX
+ ORQ AX,DX
+ ANDQ DI,CX
+ MOVQ 120(SP),AX
+ ANDQ R9,AX
+ ORQ AX,CX
+ ANDQ DI,R8
+ MOVQ 128(SP),DI
+ ANDQ R9,DI
+ ORQ DI,R8
+ MOVQ 88(SP),DI
+ MOVQ 96(SP),R9
+ ADDL 16(R9),SI
+ ADCL 20(R9),DX
+ ADCL 24(R9),CX
+ ADCL 28(R9),R8
+ MOVL SI,0(DI)
+ MOVL DX,4(DI)
+ MOVL CX,8(DI)
+ MOVL R8,12(DI)
+ MOVQ 32(SP),R11
+ MOVQ 40(SP),R12
+ MOVQ 48(SP),R13
+ MOVQ 56(SP),R14
+ MOVQ 64(SP),R15
+ MOVQ 72(SP),BX
+ MOVQ 80(SP),BP
+ MOVQ R11,SP
+ RET
diff --git a/src/ssl/test/runner/poly1305/poly1305_arm.s b/src/ssl/test/runner/poly1305/poly1305_arm.s
new file mode 100644
index 0000000..c153867
--- /dev/null
+++ b/src/ssl/test/runner/poly1305/poly1305_arm.s
@@ -0,0 +1,379 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This code was translated into a form compatible with 5a from the public
+// domain source by Andrew Moon: github.com/floodyberry/poly1305-opt/blob/master/app/extensions/poly1305.
+
+// +build arm,!gccgo,!appengine
+
+DATA poly1305_init_constants_armv6<>+0x00(SB)/4, $0x3ffffff
+DATA poly1305_init_constants_armv6<>+0x04(SB)/4, $0x3ffff03
+DATA poly1305_init_constants_armv6<>+0x08(SB)/4, $0x3ffc0ff
+DATA poly1305_init_constants_armv6<>+0x0c(SB)/4, $0x3f03fff
+DATA poly1305_init_constants_armv6<>+0x10(SB)/4, $0x00fffff
+GLOBL poly1305_init_constants_armv6<>(SB), 8, $20
+
+// Warning: the linker may use R11 to synthesize certain instructions. Please
+// take care and verify that no synthetic instructions use it.
+
+TEXT poly1305_init_ext_armv6<>(SB),4,$-4
+ MOVM.DB.W [R4-R11], (R13)
+ MOVM.IA.W (R1), [R2-R5]
+ MOVW $poly1305_init_constants_armv6<>(SB), R7
+ MOVW R2, R8
+ MOVW R2>>26, R9
+ MOVW R3>>20, g
+ MOVW R4>>14, R11
+ MOVW R5>>8, R12
+ ORR R3<<6, R9, R9
+ ORR R4<<12, g, g
+ ORR R5<<18, R11, R11
+ MOVM.IA (R7), [R2-R6]
+ AND R8, R2, R2
+ AND R9, R3, R3
+ AND g, R4, R4
+ AND R11, R5, R5
+ AND R12, R6, R6
+ MOVM.IA.W [R2-R6], (R0)
+ EOR R2, R2, R2
+ EOR R3, R3, R3
+ EOR R4, R4, R4
+ EOR R5, R5, R5
+ EOR R6, R6, R6
+ MOVM.IA.W [R2-R6], (R0)
+ MOVM.IA.W (R1), [R2-R5]
+ MOVM.IA [R2-R6], (R0)
+ MOVM.IA.W (R13), [R4-R11]
+ RET
+
+#define MOVW_UNALIGNED(Rsrc, Rdst, Rtmp, offset) \
+ MOVBU (offset+0)(Rsrc), Rtmp; \
+ MOVBU Rtmp, (offset+0)(Rdst); \
+ MOVBU (offset+1)(Rsrc), Rtmp; \
+ MOVBU Rtmp, (offset+1)(Rdst); \
+ MOVBU (offset+2)(Rsrc), Rtmp; \
+ MOVBU Rtmp, (offset+2)(Rdst); \
+ MOVBU (offset+3)(Rsrc), Rtmp; \
+ MOVBU Rtmp, (offset+3)(Rdst)
+
+TEXT poly1305_blocks_armv6<>(SB),4,$-4
+ MOVM.DB.W [R4, R5, R6, R7, R8, R9, g, R11, R14], (R13)
+ SUB $128, R13
+ MOVW R0, 36(R13)
+ MOVW R1, 40(R13)
+ MOVW R2, 44(R13)
+ MOVW R1, R14
+ MOVW R2, R12
+ MOVW 56(R0), R8
+ WORD $0xe1180008 // TST R8, R8 not working see issue 5921
+ EOR R6, R6, R6
+ MOVW.EQ $(1<<24), R6
+ MOVW R6, 32(R13)
+ ADD $64, R13, g
+ MOVM.IA (R0), [R0-R9]
+ MOVM.IA [R0-R4], (g)
+ CMP $16, R12
+ BLO poly1305_blocks_armv6_done
+poly1305_blocks_armv6_mainloop:
+ WORD $0xe31e0003 // TST R14, #3 not working see issue 5921
+ BEQ poly1305_blocks_armv6_mainloop_aligned
+ ADD $48, R13, g
+ MOVW_UNALIGNED(R14, g, R0, 0)
+ MOVW_UNALIGNED(R14, g, R0, 4)
+ MOVW_UNALIGNED(R14, g, R0, 8)
+ MOVW_UNALIGNED(R14, g, R0, 12)
+ MOVM.IA (g), [R0-R3]
+ ADD $16, R14
+ B poly1305_blocks_armv6_mainloop_loaded
+poly1305_blocks_armv6_mainloop_aligned:
+ MOVM.IA.W (R14), [R0-R3]
+poly1305_blocks_armv6_mainloop_loaded:
+ MOVW R0>>26, g
+ MOVW R1>>20, R11
+ MOVW R2>>14, R12
+ MOVW R14, 40(R13)
+ MOVW R3>>8, R4
+ ORR R1<<6, g, g
+ ORR R2<<12, R11, R11
+ ORR R3<<18, R12, R12
+ BIC $0xfc000000, R0, R0
+ BIC $0xfc000000, g, g
+ MOVW 32(R13), R3
+ BIC $0xfc000000, R11, R11
+ BIC $0xfc000000, R12, R12
+ ADD R0, R5, R5
+ ADD g, R6, R6
+ ORR R3, R4, R4
+ ADD R11, R7, R7
+ ADD $64, R13, R14
+ ADD R12, R8, R8
+ ADD R4, R9, R9
+ MOVM.IA (R14), [R0-R4]
+ MULLU R4, R5, (R11, g)
+ MULLU R3, R5, (R14, R12)
+ MULALU R3, R6, (R11, g)
+ MULALU R2, R6, (R14, R12)
+ MULALU R2, R7, (R11, g)
+ MULALU R1, R7, (R14, R12)
+ ADD R4<<2, R4, R4
+ ADD R3<<2, R3, R3
+ MULALU R1, R8, (R11, g)
+ MULALU R0, R8, (R14, R12)
+ MULALU R0, R9, (R11, g)
+ MULALU R4, R9, (R14, R12)
+ MOVW g, 24(R13)
+ MOVW R11, 28(R13)
+ MOVW R12, 16(R13)
+ MOVW R14, 20(R13)
+ MULLU R2, R5, (R11, g)
+ MULLU R1, R5, (R14, R12)
+ MULALU R1, R6, (R11, g)
+ MULALU R0, R6, (R14, R12)
+ MULALU R0, R7, (R11, g)
+ MULALU R4, R7, (R14, R12)
+ ADD R2<<2, R2, R2
+ ADD R1<<2, R1, R1
+ MULALU R4, R8, (R11, g)
+ MULALU R3, R8, (R14, R12)
+ MULALU R3, R9, (R11, g)
+ MULALU R2, R9, (R14, R12)
+ MOVW g, 8(R13)
+ MOVW R11, 12(R13)
+ MOVW R12, 0(R13)
+ MOVW R14, w+4(SP)
+ MULLU R0, R5, (R11, g)
+ MULALU R4, R6, (R11, g)
+ MULALU R3, R7, (R11, g)
+ MULALU R2, R8, (R11, g)
+ MULALU R1, R9, (R11, g)
+ MOVM.IA (R13), [R0-R7]
+ MOVW g>>26, R12
+ MOVW R4>>26, R14
+ ORR R11<<6, R12, R12
+ ORR R5<<6, R14, R14
+ BIC $0xfc000000, g, g
+ BIC $0xfc000000, R4, R4
+ ADD.S R12, R0, R0
+ ADC $0, R1, R1
+ ADD.S R14, R6, R6
+ ADC $0, R7, R7
+ MOVW R0>>26, R12
+ MOVW R6>>26, R14
+ ORR R1<<6, R12, R12
+ ORR R7<<6, R14, R14
+ BIC $0xfc000000, R0, R0
+ BIC $0xfc000000, R6, R6
+ ADD R14<<2, R14, R14
+ ADD.S R12, R2, R2
+ ADC $0, R3, R3
+ ADD R14, g, g
+ MOVW R2>>26, R12
+ MOVW g>>26, R14
+ ORR R3<<6, R12, R12
+ BIC $0xfc000000, g, R5
+ BIC $0xfc000000, R2, R7
+ ADD R12, R4, R4
+ ADD R14, R0, R0
+ MOVW R4>>26, R12
+ BIC $0xfc000000, R4, R8
+ ADD R12, R6, R9
+ MOVW w+44(SP), R12
+ MOVW w+40(SP), R14
+ MOVW R0, R6
+ CMP $32, R12
+ SUB $16, R12, R12
+ MOVW R12, 44(R13)
+ BHS poly1305_blocks_armv6_mainloop
+poly1305_blocks_armv6_done:
+ MOVW 36(R13), R12
+ MOVW R5, 20(R12)
+ MOVW R6, 24(R12)
+ MOVW R7, 28(R12)
+ MOVW R8, 32(R12)
+ MOVW R9, 36(R12)
+ ADD $128, R13, R13
+ MOVM.IA.W (R13), [R4, R5, R6, R7, R8, R9, g, R11, R14]
+ RET
+
+#define MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp) \
+ MOVBU.P 1(Rsrc), Rtmp; \
+ MOVBU.P Rtmp, 1(Rdst); \
+ MOVBU.P 1(Rsrc), Rtmp; \
+ MOVBU.P Rtmp, 1(Rdst)
+
+#define MOVWP_UNALIGNED(Rsrc, Rdst, Rtmp) \
+ MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp); \
+ MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp)
+
+TEXT poly1305_finish_ext_armv6<>(SB),4,$-4
+ MOVM.DB.W [R4, R5, R6, R7, R8, R9, g, R11, R14], (R13)
+ SUB $16, R13, R13
+ MOVW R0, R5
+ MOVW R1, R6
+ MOVW R2, R7
+ MOVW R3, R8
+ AND.S R2, R2, R2
+ BEQ poly1305_finish_ext_armv6_noremaining
+ EOR R0, R0
+ MOVW R13, R9
+ MOVW R0, 0(R13)
+ MOVW R0, 4(R13)
+ MOVW R0, 8(R13)
+ MOVW R0, 12(R13)
+ WORD $0xe3110003 // TST R1, #3 not working see issue 5921
+ BEQ poly1305_finish_ext_armv6_aligned
+ WORD $0xe3120008 // TST R2, #8 not working see issue 5921
+ BEQ poly1305_finish_ext_armv6_skip8
+ MOVWP_UNALIGNED(R1, R9, g)
+ MOVWP_UNALIGNED(R1, R9, g)
+poly1305_finish_ext_armv6_skip8:
+ WORD $0xe3120004 // TST $4, R2 not working see issue 5921
+ BEQ poly1305_finish_ext_armv6_skip4
+ MOVWP_UNALIGNED(R1, R9, g)
+poly1305_finish_ext_armv6_skip4:
+ WORD $0xe3120002 // TST $2, R2 not working see issue 5921
+ BEQ poly1305_finish_ext_armv6_skip2
+ MOVHUP_UNALIGNED(R1, R9, g)
+ B poly1305_finish_ext_armv6_skip2
+poly1305_finish_ext_armv6_aligned:
+ WORD $0xe3120008 // TST R2, #8 not working see issue 5921
+ BEQ poly1305_finish_ext_armv6_skip8_aligned
+ MOVM.IA.W (R1), [g-R11]
+ MOVM.IA.W [g-R11], (R9)
+poly1305_finish_ext_armv6_skip8_aligned:
+ WORD $0xe3120004 // TST $4, R2 not working see issue 5921
+ BEQ poly1305_finish_ext_armv6_skip4_aligned
+ MOVW.P 4(R1), g
+ MOVW.P g, 4(R9)
+poly1305_finish_ext_armv6_skip4_aligned:
+ WORD $0xe3120002 // TST $2, R2 not working see issue 5921
+ BEQ poly1305_finish_ext_armv6_skip2
+ MOVHU.P 2(R1), g
+ MOVH.P g, 2(R9)
+poly1305_finish_ext_armv6_skip2:
+ WORD $0xe3120001 // TST $1, R2 not working see issue 5921
+ BEQ poly1305_finish_ext_armv6_skip1
+ MOVBU.P 1(R1), g
+ MOVBU.P g, 1(R9)
+poly1305_finish_ext_armv6_skip1:
+ MOVW $1, R11
+ MOVBU R11, 0(R9)
+ MOVW R11, 56(R5)
+ MOVW R5, R0
+ MOVW R13, R1
+ MOVW $16, R2
+ BL poly1305_blocks_armv6<>(SB)
+poly1305_finish_ext_armv6_noremaining:
+ MOVW 20(R5), R0
+ MOVW 24(R5), R1
+ MOVW 28(R5), R2
+ MOVW 32(R5), R3
+ MOVW 36(R5), R4
+ MOVW R4>>26, R12
+ BIC $0xfc000000, R4, R4
+ ADD R12<<2, R12, R12
+ ADD R12, R0, R0
+ MOVW R0>>26, R12
+ BIC $0xfc000000, R0, R0
+ ADD R12, R1, R1
+ MOVW R1>>26, R12
+ BIC $0xfc000000, R1, R1
+ ADD R12, R2, R2
+ MOVW R2>>26, R12
+ BIC $0xfc000000, R2, R2
+ ADD R12, R3, R3
+ MOVW R3>>26, R12
+ BIC $0xfc000000, R3, R3
+ ADD R12, R4, R4
+ ADD $5, R0, R6
+ MOVW R6>>26, R12
+ BIC $0xfc000000, R6, R6
+ ADD R12, R1, R7
+ MOVW R7>>26, R12
+ BIC $0xfc000000, R7, R7
+ ADD R12, R2, g
+ MOVW g>>26, R12
+ BIC $0xfc000000, g, g
+ ADD R12, R3, R11
+ MOVW $-(1<<26), R12
+ ADD R11>>26, R12, R12
+ BIC $0xfc000000, R11, R11
+ ADD R12, R4, R14
+ MOVW R14>>31, R12
+ SUB $1, R12
+ AND R12, R6, R6
+ AND R12, R7, R7
+ AND R12, g, g
+ AND R12, R11, R11
+ AND R12, R14, R14
+ MVN R12, R12
+ AND R12, R0, R0
+ AND R12, R1, R1
+ AND R12, R2, R2
+ AND R12, R3, R3
+ AND R12, R4, R4
+ ORR R6, R0, R0
+ ORR R7, R1, R1
+ ORR g, R2, R2
+ ORR R11, R3, R3
+ ORR R14, R4, R4
+ ORR R1<<26, R0, R0
+ MOVW R1>>6, R1
+ ORR R2<<20, R1, R1
+ MOVW R2>>12, R2
+ ORR R3<<14, R2, R2
+ MOVW R3>>18, R3
+ ORR R4<<8, R3, R3
+ MOVW 40(R5), R6
+ MOVW 44(R5), R7
+ MOVW 48(R5), g
+ MOVW 52(R5), R11
+ ADD.S R6, R0, R0
+ ADC.S R7, R1, R1
+ ADC.S g, R2, R2
+ ADC.S R11, R3, R3
+ MOVM.IA [R0-R3], (R8)
+ MOVW R5, R12
+ EOR R0, R0, R0
+ EOR R1, R1, R1
+ EOR R2, R2, R2
+ EOR R3, R3, R3
+ EOR R4, R4, R4
+ EOR R5, R5, R5
+ EOR R6, R6, R6
+ EOR R7, R7, R7
+ MOVM.IA.W [R0-R7], (R12)
+ MOVM.IA [R0-R7], (R12)
+ ADD $16, R13, R13
+ MOVM.IA.W (R13), [R4, R5, R6, R7, R8, R9, g, R11, R14]
+ RET
+
+// func poly1305_auth_armv6(out *[16]byte, m *byte, mlen uint32, key *[32]key)
+TEXT ·poly1305_auth_armv6(SB),0,$280-16
+ MOVW out+0(FP), R4
+ MOVW m+4(FP), R5
+ MOVW mlen+8(FP), R6
+ MOVW key+12(FP), R7
+
+ MOVW R13, R8
+ BIC $63, R13
+ SUB $64, R13, R13
+ MOVW R13, R0
+ MOVW R7, R1
+ BL poly1305_init_ext_armv6<>(SB)
+ BIC.S $15, R6, R2
+ BEQ poly1305_auth_armv6_noblocks
+ MOVW R13, R0
+ MOVW R5, R1
+ ADD R2, R5, R5
+ SUB R2, R6, R6
+ BL poly1305_blocks_armv6<>(SB)
+poly1305_auth_armv6_noblocks:
+ MOVW R13, R0
+ MOVW R5, R1
+ MOVW R6, R2
+ MOVW R4, R3
+ BL poly1305_finish_ext_armv6<>(SB)
+ MOVW R8, R13
+ RET
diff --git a/src/ssl/test/runner/poly1305/poly1305_test.go b/src/ssl/test/runner/poly1305/poly1305_test.go
new file mode 100644
index 0000000..b3e9231
--- /dev/null
+++ b/src/ssl/test/runner/poly1305/poly1305_test.go
@@ -0,0 +1,86 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package poly1305
+
+import (
+ "bytes"
+ "testing"
+ "unsafe"
+)
+
+var testData = []struct {
+ in, k, correct []byte
+}{
+ {
+ []byte("Hello world!"),
+ []byte("this is 32-byte key for Poly1305"),
+ []byte{0xa6, 0xf7, 0x45, 0x00, 0x8f, 0x81, 0xc9, 0x16, 0xa2, 0x0d, 0xcc, 0x74, 0xee, 0xf2, 0xb2, 0xf0},
+ },
+ {
+ make([]byte, 32),
+ []byte("this is 32-byte key for Poly1305"),
+ []byte{0x49, 0xec, 0x78, 0x09, 0x0e, 0x48, 0x1e, 0xc6, 0xc2, 0x6b, 0x33, 0xb9, 0x1c, 0xcc, 0x03, 0x07},
+ },
+ {
+ make([]byte, 2007),
+ []byte("this is 32-byte key for Poly1305"),
+ []byte{0xda, 0x84, 0xbc, 0xab, 0x02, 0x67, 0x6c, 0x38, 0xcd, 0xb0, 0x15, 0x60, 0x42, 0x74, 0xc2, 0xaa},
+ },
+ {
+ make([]byte, 2007),
+ make([]byte, 32),
+ make([]byte, 16),
+ },
+}
+
+func testSum(t *testing.T, unaligned bool) {
+ var out [16]byte
+ var key [32]byte
+
+ for i, v := range testData {
+ in := v.in
+ if unaligned {
+ in = unalignBytes(in)
+ }
+ copy(key[:], v.k)
+ Sum(&out, in, &key)
+ if !bytes.Equal(out[:], v.correct) {
+ t.Errorf("%d: expected %x, got %x", i, v.correct, out[:])
+ }
+ }
+}
+
+func TestSum(t *testing.T) { testSum(t, false) }
+func TestSumUnaligned(t *testing.T) { testSum(t, true) }
+
+func benchmark(b *testing.B, size int, unaligned bool) {
+ var out [16]byte
+ var key [32]byte
+ in := make([]byte, size)
+ if unaligned {
+ in = unalignBytes(in)
+ }
+ b.SetBytes(int64(len(in)))
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ Sum(&out, in, &key)
+ }
+}
+
+func Benchmark64(b *testing.B) { benchmark(b, 64, false) }
+func Benchmark1K(b *testing.B) { benchmark(b, 1024, false) }
+func Benchmark64Unaligned(b *testing.B) { benchmark(b, 64, true) }
+func Benchmark1KUnaligned(b *testing.B) { benchmark(b, 1024, true) }
+
+func unalignBytes(in []byte) []byte {
+ out := make([]byte, len(in)+1)
+ if uintptr(unsafe.Pointer(&out[0]))&(unsafe.Alignof(uint32(0))-1) == 0 {
+ out = out[1:]
+ } else {
+ out = out[:len(in)]
+ }
+ copy(out, in)
+ return out
+}
diff --git a/src/ssl/test/runner/poly1305/sum_amd64.go b/src/ssl/test/runner/poly1305/sum_amd64.go
new file mode 100644
index 0000000..6775c70
--- /dev/null
+++ b/src/ssl/test/runner/poly1305/sum_amd64.go
@@ -0,0 +1,24 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build amd64,!gccgo,!appengine
+
+package poly1305
+
+// This function is implemented in poly1305_amd64.s
+
+//go:noescape
+
+func poly1305(out *[16]byte, m *byte, mlen uint64, key *[32]byte)
+
+// Sum generates an authenticator for m using a one-time key and puts the
+// 16-byte result into out. Authenticating two different messages with the same
+// key allows an attacker to forge messages at will.
+func Sum(out *[16]byte, m []byte, key *[32]byte) {
+ var mPtr *byte
+ if len(m) > 0 {
+ mPtr = &m[0]
+ }
+ poly1305(out, mPtr, uint64(len(m)), key)
+}
diff --git a/src/ssl/test/runner/poly1305/sum_arm.go b/src/ssl/test/runner/poly1305/sum_arm.go
new file mode 100644
index 0000000..50b979c
--- /dev/null
+++ b/src/ssl/test/runner/poly1305/sum_arm.go
@@ -0,0 +1,24 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build arm,!gccgo,!appengine
+
+package poly1305
+
+// This function is implemented in poly1305_arm.s
+
+//go:noescape
+
+func poly1305_auth_armv6(out *[16]byte, m *byte, mlen uint32, key *[32]byte)
+
+// Sum generates an authenticator for m using a one-time key and puts the
+// 16-byte result into out. Authenticating two different messages with the same
+// key allows an attacker to forge messages at will.
+func Sum(out *[16]byte, m []byte, key *[32]byte) {
+ var mPtr *byte
+ if len(m) > 0 {
+ mPtr = &m[0]
+ }
+ poly1305_auth_armv6(out, mPtr, uint32(len(m)), key)
+}
diff --git a/src/ssl/test/runner/poly1305.go b/src/ssl/test/runner/poly1305/sum_ref.go
index edef338..0b24fc7 100644
--- a/src/ssl/test/runner/poly1305.go
+++ b/src/ssl/test/runner/poly1305/sum_ref.go
@@ -2,15 +2,14 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package runner
+// +build !amd64,!arm gccgo appengine
+
+package poly1305
// Based on original, public domain implementation from NaCl by D. J.
// Bernstein.
-import (
- "crypto/subtle"
- "math"
-)
+import "math"
const (
alpham80 = 0.00000000558793544769287109375
@@ -32,18 +31,10 @@ const (
offset3 = 535219245894202480694386063513315216128475136.0
)
-// poly1305Verify returns true if mac is a valid authenticator for m with the
-// given key.
-func poly1305Verify(mac *[16]byte, m []byte, key *[32]byte) bool {
- var tmp [16]byte
- poly1305Sum(&tmp, m, key)
- return subtle.ConstantTimeCompare(tmp[:], mac[:]) == 1
-}
-
-// poly1305Sum generates an authenticator for m using a one-time key and puts
-// the 16-byte result into out. Authenticating two different messages with the
-// same key allows an attacker to forge messages at will.
-func poly1305Sum(out *[16]byte, m []byte, key *[32]byte) {
+// Sum generates an authenticator for m using a one-time key and puts the
+// 16-byte result into out. Authenticating two different messages with the same
+// key allows an attacker to forge messages at will.
+func Sum(out *[16]byte, m []byte, key *[32]byte) {
r := key
s := key[16:]
var (
diff --git a/src/ssl/test/runner/runner.go b/src/ssl/test/runner/runner.go
index 6ab71cf..45bb0b7 100644
--- a/src/ssl/test/runner/runner.go
+++ b/src/ssl/test/runner/runner.go
@@ -27,6 +27,7 @@ import (
var (
useValgrind = flag.Bool("valgrind", false, "If true, run code under valgrind")
useGDB = flag.Bool("gdb", false, "If true, run BoringSSL code under gdb")
+ useLLDB = flag.Bool("lldb", false, "If true, run BoringSSL code under lldb")
flagDebug = flag.Bool("debug", false, "Hexdump the contents of the connection")
mallocTest = flag.Int64("malloc-test", -1, "If non-negative, run each test with each malloc in turn failing from the given number onwards.")
mallocTestDebug = flag.Bool("malloc-test-debug", false, "If true, ask bssl_shim to abort rather than fail a malloc. This can be used with a specific value for --malloc-test to identity the malloc failing that is causing problems.")
@@ -521,6 +522,14 @@ func gdbOf(path string, args ...string) *exec.Cmd {
return exec.Command("xterm", xtermArgs...)
}
+func lldbOf(path string, args ...string) *exec.Cmd {
+ xtermArgs := []string{"-e", "lldb", "--"}
+ xtermArgs = append(xtermArgs, path)
+ xtermArgs = append(xtermArgs, args...)
+
+ return exec.Command("xterm", xtermArgs...)
+}
+
type moreMallocsError struct{}
func (moreMallocsError) Error() string {
@@ -637,6 +646,8 @@ func runTest(test *testCase, shimPath string, mallocNumToFail int64) error {
shim = valgrindOf(false, shimPath, flags...)
} else if *useGDB {
shim = gdbOf(shimPath, flags...)
+ } else if *useLLDB {
+ shim = lldbOf(shimPath, flags...)
} else {
shim = exec.Command(shimPath, flags...)
}
@@ -801,6 +812,7 @@ var testCipherSuites = []struct {
{"ECDHE-ECDSA-AES256-SHA", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
{"ECDHE-ECDSA-AES256-SHA384", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384},
{"ECDHE-ECDSA-CHACHA20-POLY1305", TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256},
+ {"ECDHE-ECDSA-CHACHA20-POLY1305-OLD", TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256_OLD},
{"ECDHE-ECDSA-RC4-SHA", TLS_ECDHE_ECDSA_WITH_RC4_128_SHA},
{"ECDHE-RSA-AES128-GCM", TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
{"ECDHE-RSA-AES128-SHA", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
@@ -809,11 +821,13 @@ var testCipherSuites = []struct {
{"ECDHE-RSA-AES256-SHA", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA},
{"ECDHE-RSA-AES256-SHA384", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384},
{"ECDHE-RSA-CHACHA20-POLY1305", TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
+ {"ECDHE-RSA-CHACHA20-POLY1305-OLD", TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD},
{"ECDHE-RSA-RC4-SHA", TLS_ECDHE_RSA_WITH_RC4_128_SHA},
{"PSK-AES128-CBC-SHA", TLS_PSK_WITH_AES_128_CBC_SHA},
{"PSK-AES256-CBC-SHA", TLS_PSK_WITH_AES_256_CBC_SHA},
{"ECDHE-PSK-AES128-CBC-SHA", TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA},
{"ECDHE-PSK-AES256-CBC-SHA", TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA},
+ {"ECDHE-PSK-CHACHA20-POLY1305", TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256},
{"PSK-RC4-SHA", TLS_PSK_WITH_RC4_128_SHA},
{"RC4-MD5", TLS_RSA_WITH_RC4_128_MD5},
{"RC4-SHA", TLS_RSA_WITH_RC4_128_SHA},
@@ -824,6 +838,12 @@ func hasComponent(suiteName, component string) bool {
return strings.Contains("-"+suiteName+"-", "-"+component+"-")
}
+func isTLSOnly(suiteName string) bool {
+ // BoringSSL doesn't support ECDHE without a curves extension, and
+ // SSLv3 doesn't contain extensions.
+ return hasComponent(suiteName, "ECDHE") || isTLS12Only(suiteName)
+}
+
func isTLS12Only(suiteName string) bool {
return hasComponent(suiteName, "GCM") ||
hasComponent(suiteName, "SHA256") ||
@@ -907,18 +927,6 @@ func addBasicTests() {
expectedError: ":WRONG_CURVE:",
},
{
- testType: serverTest,
- name: "BadRSAVersion",
- config: Config{
- CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
- Bugs: ProtocolBugs{
- RsaClientKeyExchangeVersion: VersionTLS11,
- },
- },
- shouldFail: true,
- expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
- },
- {
name: "NoFallbackSCSV",
config: Config{
Bugs: ProtocolBugs{
@@ -1006,7 +1014,7 @@ func addBasicTests() {
},
},
shouldFail: true,
- expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
+ expectedError: ":UNEXPECTED_RECORD:",
},
{
testType: serverTest,
@@ -1017,7 +1025,7 @@ func addBasicTests() {
},
},
shouldFail: true,
- expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
+ expectedError: ":UNEXPECTED_RECORD:",
},
{
testType: serverTest,
@@ -1032,7 +1040,7 @@ func addBasicTests() {
"-advertise-npn", "\x03foo\x03bar\x03baz",
},
shouldFail: true,
- expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
+ expectedError: ":UNEXPECTED_RECORD:",
},
{
name: "FragmentAcrossChangeCipherSpec-Client",
@@ -1042,7 +1050,7 @@ func addBasicTests() {
},
},
shouldFail: true,
- expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
+ expectedError: ":UNEXPECTED_RECORD:",
},
{
testType: serverTest,
@@ -1053,7 +1061,7 @@ func addBasicTests() {
},
},
shouldFail: true,
- expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
+ expectedError: ":UNEXPECTED_RECORD:",
},
{
testType: serverTest,
@@ -1068,7 +1076,7 @@ func addBasicTests() {
"-advertise-npn", "\x03foo\x03bar\x03baz",
},
shouldFail: true,
- expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
+ expectedError: ":UNEXPECTED_RECORD:",
},
{
testType: serverTest,
@@ -1127,7 +1135,7 @@ func addBasicTests() {
},
},
shouldFail: true,
- expectedError: ":CCS_RECEIVED_EARLY:",
+ expectedError: ":UNEXPECTED_RECORD:",
},
{
testType: serverTest,
@@ -1138,7 +1146,7 @@ func addBasicTests() {
},
},
shouldFail: true,
- expectedError: ":CCS_RECEIVED_EARLY:",
+ expectedError: ":UNEXPECTED_RECORD:",
},
{
name: "SkipNewSessionTicket",
@@ -1148,7 +1156,7 @@ func addBasicTests() {
},
},
shouldFail: true,
- expectedError: ":CCS_RECEIVED_EARLY:",
+ expectedError: ":UNEXPECTED_RECORD:",
},
{
testType: serverTest,
@@ -1425,7 +1433,7 @@ func addBasicTests() {
},
},
shouldFail: true,
- expectedError: ":DATA_BETWEEN_CCS_AND_FINISHED:",
+ expectedError: ":UNEXPECTED_RECORD:",
},
{
name: "AppDataAfterChangeCipherSpec-Empty",
@@ -1435,7 +1443,7 @@ func addBasicTests() {
},
},
shouldFail: true,
- expectedError: ":DATA_BETWEEN_CCS_AND_FINISHED:",
+ expectedError: ":UNEXPECTED_RECORD:",
},
{
protocol: dtls,
@@ -1689,14 +1697,13 @@ func addBasicTests() {
{
name: "UnsupportedCurve",
config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- // BoringSSL implements P-224 but doesn't enable it by
- // default.
- CurvePreferences: []CurveID{CurveP224},
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ CurvePreferences: []CurveID{CurveP256},
Bugs: ProtocolBugs{
IgnorePeerCurvePreferences: true,
},
},
+ flags: []string{"-p384-only"},
shouldFail: true,
expectedError: ":WRONG_CURVE:",
},
@@ -1812,6 +1819,8 @@ func addBasicTests() {
NoSupportedCurves: true,
},
},
+ shouldFail: true,
+ expectedError: ":NO_SHARED_CIPHER:",
},
{
testType: serverTest,
@@ -1997,6 +2006,88 @@ func addBasicTests() {
resumeSession: true,
expectResumeRejected: true,
},
+ {
+ name: "CheckLeafCurve",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+ Certificates: []Certificate{getECDSACertificate()},
+ },
+ flags: []string{"-p384-only"},
+ shouldFail: true,
+ expectedError: ":BAD_ECC_CERT:",
+ },
+ {
+ name: "BadChangeCipherSpec-1",
+ config: Config{
+ Bugs: ProtocolBugs{
+ BadChangeCipherSpec: []byte{2},
+ },
+ },
+ shouldFail: true,
+ expectedError: ":BAD_CHANGE_CIPHER_SPEC:",
+ },
+ {
+ name: "BadChangeCipherSpec-2",
+ config: Config{
+ Bugs: ProtocolBugs{
+ BadChangeCipherSpec: []byte{1, 1},
+ },
+ },
+ shouldFail: true,
+ expectedError: ":BAD_CHANGE_CIPHER_SPEC:",
+ },
+ {
+ protocol: dtls,
+ name: "BadChangeCipherSpec-DTLS-1",
+ config: Config{
+ Bugs: ProtocolBugs{
+ BadChangeCipherSpec: []byte{2},
+ },
+ },
+ shouldFail: true,
+ expectedError: ":BAD_CHANGE_CIPHER_SPEC:",
+ },
+ {
+ protocol: dtls,
+ name: "BadChangeCipherSpec-DTLS-2",
+ config: Config{
+ Bugs: ProtocolBugs{
+ BadChangeCipherSpec: []byte{1, 1},
+ },
+ },
+ shouldFail: true,
+ expectedError: ":BAD_CHANGE_CIPHER_SPEC:",
+ },
+ {
+ name: "BadHelloRequest-1",
+ renegotiate: 1,
+ config: Config{
+ Bugs: ProtocolBugs{
+ BadHelloRequest: []byte{typeHelloRequest, 0, 0, 1, 1},
+ },
+ },
+ flags: []string{
+ "-renegotiate-freely",
+ "-expect-total-renegotiations", "1",
+ },
+ shouldFail: true,
+ expectedError: ":BAD_HELLO_REQUEST:",
+ },
+ {
+ name: "BadHelloRequest-2",
+ renegotiate: 1,
+ config: Config{
+ Bugs: ProtocolBugs{
+ BadHelloRequest: []byte{typeServerKeyExchange, 0, 0, 0},
+ },
+ },
+ flags: []string{
+ "-renegotiate-freely",
+ "-expect-total-renegotiations", "1",
+ },
+ shouldFail: true,
+ expectedError: ":BAD_HELLO_REQUEST:",
+ },
}
testCases = append(testCases, basicTests...)
}
@@ -2035,9 +2126,16 @@ func addCipherSuiteTests() {
continue
}
+ shouldFail := isTLSOnly(suite.name) && ver.version == VersionSSL30
+
+ expectedError := ""
+ if shouldFail {
+ expectedError = ":NO_SHARED_CIPHER:"
+ }
+
testCases = append(testCases, testCase{
- testType: clientTest,
- name: ver.name + "-" + suite.name + "-client",
+ testType: serverTest,
+ name: ver.name + "-" + suite.name + "-server",
config: Config{
MinVersion: ver.version,
MaxVersion: ver.version,
@@ -2046,13 +2144,21 @@ func addCipherSuiteTests() {
PreSharedKey: []byte(psk),
PreSharedKeyIdentity: pskIdentity,
},
+ certFile: certFile,
+ keyFile: keyFile,
flags: flags,
resumeSession: true,
+ shouldFail: shouldFail,
+ expectedError: expectedError,
})
+ if shouldFail {
+ continue
+ }
+
testCases = append(testCases, testCase{
- testType: serverTest,
- name: ver.name + "-" + suite.name + "-server",
+ testType: clientTest,
+ name: ver.name + "-" + suite.name + "-client",
config: Config{
MinVersion: ver.version,
MaxVersion: ver.version,
@@ -2061,8 +2167,6 @@ func addCipherSuiteTests() {
PreSharedKey: []byte(psk),
PreSharedKeyIdentity: pskIdentity,
},
- certFile: certFile,
- keyFile: keyFile,
flags: flags,
resumeSession: true,
})
@@ -2115,20 +2219,6 @@ func addCipherSuiteTests() {
flags: flags,
messageLen: maxPlaintext,
})
- testCases = append(testCases, testCase{
- name: suite.name + "-LargeRecord-Extra",
- config: Config{
- CipherSuites: []uint16{suite.id},
- Certificates: []Certificate{cert},
- PreSharedKey: []byte(psk),
- PreSharedKeyIdentity: pskIdentity,
- Bugs: ProtocolBugs{
- SendLargeRecords: true,
- },
- },
- flags: append(flags, "-microsoft-big-sslv3-buffer"),
- messageLen: maxPlaintext + 16384,
- })
if isDTLSCipher(suite.name) {
testCases = append(testCases, testCase{
protocol: dtls,
@@ -2157,7 +2247,37 @@ func addCipherSuiteTests() {
},
},
shouldFail: true,
- expectedError: "BAD_DH_P_LENGTH",
+ expectedError: ":BAD_DH_P_LENGTH:",
+ })
+
+ testCases = append(testCases, testCase{
+ name: "SillyDH",
+ config: Config{
+ CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
+ Bugs: ProtocolBugs{
+ // This is a 4097-bit prime number, generated
+ // with:
+ // openssl gendh 4097 | openssl asn1parse -i
+ DHGroupPrime: bigFromHex("01D366FA64A47419B0CD4A45918E8D8C8430F674621956A9F52B0CA592BC104C6E38D60C58F2CA66792A2B7EBDC6F8FFE75AB7D6862C261F34E96A2AEEF53AB7C21365C2E8FB0582F71EB57B1C227C0E55AE859E9904A25EFECD7B435C4D4357BD840B03649D4A1F8037D89EA4E1967DBEEF1CC17A6111C48F12E9615FFF336D3F07064CB17C0B765A012C850B9E3AA7A6984B96D8C867DDC6D0F4AB52042572244796B7ECFF681CD3B3E2E29AAECA391A775BEE94E502FB15881B0F4AC60314EA947C0C82541C3D16FD8C0E09BB7F8F786582032859D9C13187CE6C0CB6F2D3EE6C3C9727C15F14B21D3CD2E02BDB9D119959B0E03DC9E5A91E2578762300B1517D2352FC1D0BB934A4C3E1B20CE9327DB102E89A6C64A8C3148EDFC5A94913933853442FA84451B31FD21E492F92DD5488E0D871AEBFE335A4B92431DEC69591548010E76A5B365D346786E9A2D3E589867D796AA5E25211201D757560D318A87DFB27F3E625BC373DB48BF94A63161C674C3D4265CB737418441B7650EABC209CF675A439BEB3E9D1AA1B79F67198A40CEFD1C89144F7D8BAF61D6AD36F466DA546B4174A0E0CAF5BD788C8243C7C2DDDCC3DB6FC89F12F17D19FBD9B0BC76FE92891CD6BA07BEA3B66EF12D0D85E788FD58675C1B0FBD16029DCC4D34E7A1A41471BDEDF78BF591A8B4E96D88BEC8EDC093E616292BFC096E69A916E8D624B"),
+ },
+ },
+ shouldFail: true,
+ expectedError: ":DH_P_TOO_LONG:",
+ })
+
+ // This test ensures that Diffie-Hellman public values are padded with
+ // zeros so that they're the same length as the prime. This is to avoid
+ // hitting a bug in yaSSL.
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "DHPublicValuePadded",
+ config: Config{
+ CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
+ Bugs: ProtocolBugs{
+ RequireDHPublicValueLen: (1025 + 7) / 8,
+ },
+ },
+ flags: []string{"-use-sparse-dh-prime"},
})
// versionSpecificCiphersTest specifies a test for the TLS 1.0 and TLS
@@ -3168,40 +3288,6 @@ func addMinimumVersionTests() {
}
}
-func addD5BugTests() {
- testCases = append(testCases, testCase{
- testType: serverTest,
- name: "D5Bug-NoQuirk-Reject",
- config: Config{
- CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
- Bugs: ProtocolBugs{
- SSL3RSAKeyExchange: true,
- },
- },
- shouldFail: true,
- expectedError: ":TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG:",
- })
- testCases = append(testCases, testCase{
- testType: serverTest,
- name: "D5Bug-Quirk-Normal",
- config: Config{
- CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
- },
- flags: []string{"-tls-d5-bug"},
- })
- testCases = append(testCases, testCase{
- testType: serverTest,
- name: "D5Bug-Quirk-Bug",
- config: Config{
- CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
- Bugs: ProtocolBugs{
- SSL3RSAKeyExchange: true,
- },
- },
- flags: []string{"-tls-d5-bug"},
- })
-}
-
func addExtensionTests() {
testCases = append(testCases, testCase{
testType: clientTest,
@@ -3801,15 +3887,28 @@ func addRenegotiationTests() {
expectedError: ":RENEGOTIATION_MISMATCH:",
})
testCases = append(testCases, testCase{
- name: "Renegotiate-Client-NoExt",
+ name: "Renegotiate-Client-Downgrade",
+ renegotiate: 1,
+ config: Config{
+ Bugs: ProtocolBugs{
+ NoRenegotiationInfoAfterInitial: true,
+ },
+ },
+ flags: []string{"-renegotiate-freely"},
+ shouldFail: true,
+ expectedError: ":RENEGOTIATION_MISMATCH:",
+ })
+ testCases = append(testCases, testCase{
+ name: "Renegotiate-Client-Upgrade",
+ renegotiate: 1,
config: Config{
Bugs: ProtocolBugs{
- NoRenegotiationInfo: true,
+ NoRenegotiationInfoInInitial: true,
},
},
+ flags: []string{"-renegotiate-freely"},
shouldFail: true,
- expectedError: ":UNSAFE_LEGACY_RENEGOTIATION_DISABLED:",
- flags: []string{"-no-legacy-server-connect"},
+ expectedError: ":RENEGOTIATION_MISMATCH:",
})
testCases = append(testCases, testCase{
name: "Renegotiate-Client-NoExt-Allowed",
@@ -4518,6 +4617,114 @@ func addCustomExtensionTests() {
})
}
+func addRSAClientKeyExchangeTests() {
+ for bad := RSABadValue(1); bad < NumRSABadValues; bad++ {
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: fmt.Sprintf("BadRSAClientKeyExchange-%d", bad),
+ config: Config{
+ // Ensure the ClientHello version and final
+ // version are different, to detect if the
+ // server uses the wrong one.
+ MaxVersion: VersionTLS11,
+ CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ Bugs: ProtocolBugs{
+ BadRSAClientKeyExchange: bad,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
+ })
+ }
+}
+
+var testCurves = []struct {
+ name string
+ id CurveID
+}{
+ {"P-256", CurveP256},
+ {"P-384", CurveP384},
+ {"P-521", CurveP521},
+ {"X25519", CurveX25519},
+}
+
+func addCurveTests() {
+ for _, curve := range testCurves {
+ testCases = append(testCases, testCase{
+ name: "CurveTest-Client-" + curve.name,
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ CurvePreferences: []CurveID{curve.id},
+ },
+ flags: []string{"-enable-all-curves"},
+ })
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "CurveTest-Server-" + curve.name,
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ CurvePreferences: []CurveID{curve.id},
+ },
+ flags: []string{"-enable-all-curves"},
+ })
+ }
+}
+
+func addKeyExchangeInfoTests() {
+ testCases = append(testCases, testCase{
+ name: "KeyExchangeInfo-RSA-Client",
+ config: Config{
+ CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
+ },
+ // key.pem is a 1024-bit RSA key.
+ flags: []string{"-expect-key-exchange-info", "1024"},
+ })
+ // TODO(davidben): key_exchange_info doesn't work for plain RSA on the
+ // server. Either fix this or change the API as it's not very useful in
+ // this case.
+
+ testCases = append(testCases, testCase{
+ name: "KeyExchangeInfo-DHE-Client",
+ config: Config{
+ CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
+ Bugs: ProtocolBugs{
+ // This is a 1234-bit prime number, generated
+ // with:
+ // openssl gendh 1234 | openssl asn1parse -i
+ DHGroupPrime: bigFromHex("0215C589A86BE450D1255A86D7A08877A70E124C11F0C75E476BA6A2186B1C830D4A132555973F2D5881D5F737BB800B7F417C01EC5960AEBF79478F8E0BBB6A021269BD10590C64C57F50AD8169D5488B56EE38DC5E02DA1A16ED3B5F41FEB2AD184B78A31F3A5B2BEC8441928343DA35DE3D4F89F0D4CEDE0034045084A0D1E6182E5EF7FCA325DD33CE81BE7FA87D43613E8FA7A1457099AB53"),
+ },
+ },
+ flags: []string{"-expect-key-exchange-info", "1234"},
+ })
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "KeyExchangeInfo-DHE-Server",
+ config: Config{
+ CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
+ },
+ // bssl_shim as a server configures a 2048-bit DHE group.
+ flags: []string{"-expect-key-exchange-info", "2048"},
+ })
+
+ testCases = append(testCases, testCase{
+ name: "KeyExchangeInfo-ECDHE-Client",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ CurvePreferences: []CurveID{CurveX25519},
+ },
+ flags: []string{"-expect-key-exchange-info", "29", "-enable-all-curves"},
+ })
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "KeyExchangeInfo-ECDHE-Server",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ CurvePreferences: []CurveID{CurveX25519},
+ },
+ flags: []string{"-expect-key-exchange-info", "29", "-enable-all-curves"},
+ })
+}
+
func worker(statusChan chan statusMsg, c chan *testCase, shimPath string, wg *sync.WaitGroup) {
defer wg.Done()
@@ -4604,7 +4811,6 @@ func main() {
addDDoSCallbackTests()
addVersionNegotiationTests()
addMinimumVersionTests()
- addD5BugTests()
addExtensionTests()
addResumptionVersionTests()
addExtendedMasterSecretTests()
@@ -4615,6 +4821,9 @@ func main() {
addExportKeyingMaterialTests()
addTLSUniqueTests()
addCustomExtensionTests()
+ addRSAClientKeyExchangeTests()
+ addCurveTests()
+ addKeyExchangeInfoTests()
for _, async := range []bool{false, true} {
for _, splitHandshake := range []bool{false, true} {
for _, protocol := range []protocol{tls, dtls} {
diff --git a/src/ssl/test/test_config.cc b/src/ssl/test/test_config.cc
index 50e6b23..1cf316d 100644
--- a/src/ssl/test/test_config.cc
+++ b/src/ssl/test/test_config.cc
@@ -61,7 +61,6 @@ const Flag<bool> kBoolFlags[] = {
{ "-no-tls1", &TestConfig::no_tls1 },
{ "-no-ssl3", &TestConfig::no_ssl3 },
{ "-shim-writes-first", &TestConfig::shim_writes_first },
- { "-tls-d5-bug", &TestConfig::tls_d5_bug },
{ "-expect-session-miss", &TestConfig::expect_session_miss },
{ "-expect-extended-master-secret",
&TestConfig::expect_extended_master_secret },
@@ -76,7 +75,6 @@ const Flag<bool> kBoolFlags[] = {
{ "-fail-second-ddos-callback", &TestConfig::fail_second_ddos_callback },
{ "-handshake-never-done", &TestConfig::handshake_never_done },
{ "-use-export-context", &TestConfig::use_export_context },
- { "-no-legacy-server-connect", &TestConfig::no_legacy_server_connect },
{ "-tls-unique", &TestConfig::tls_unique },
{ "-expect-ticket-renewal", &TestConfig::expect_ticket_renewal },
{ "-expect-no-session", &TestConfig::expect_no_session },
@@ -90,7 +88,6 @@ const Flag<bool> kBoolFlags[] = {
{ "-custom-extension-fail-add", &TestConfig::custom_extension_fail_add },
{ "-check-close-notify", &TestConfig::check_close_notify },
{ "-shim-shuts-down", &TestConfig::shim_shuts_down },
- { "-microsoft-big-sslv3-buffer", &TestConfig::microsoft_big_sslv3_buffer },
{ "-verify-fail", &TestConfig::verify_fail },
{ "-verify-peer", &TestConfig::verify_peer },
{ "-expect-verify-result", &TestConfig::expect_verify_result },
@@ -98,6 +95,9 @@ const Flag<bool> kBoolFlags[] = {
{ "-renegotiate-freely", &TestConfig::renegotiate_freely },
{ "-renegotiate-ignore", &TestConfig::renegotiate_ignore },
{ "-disable-npn", &TestConfig::disable_npn },
+ { "-p384-only", &TestConfig::p384_only },
+ { "-enable-all-curves", &TestConfig::enable_all_curves },
+ { "-use-sparse-dh-prime", &TestConfig::use_sparse_dh_prime },
};
const Flag<std::string> kStringFlags[] = {
@@ -143,6 +143,8 @@ const Flag<int> kIntFlags[] = {
{ "-expect-total-renegotiations", &TestConfig::expect_total_renegotiations },
{ "-expect-server-key-exchange-hash",
&TestConfig::expect_server_key_exchange_hash },
+ { "-expect-key-exchange-info",
+ &TestConfig::expect_key_exchange_info },
};
} // namespace
diff --git a/src/ssl/test/test_config.h b/src/ssl/test/test_config.h
index 9f295ae..4e0a46a 100644
--- a/src/ssl/test/test_config.h
+++ b/src/ssl/test/test_config.h
@@ -45,7 +45,6 @@ struct TestConfig {
std::string expected_channel_id;
std::string send_channel_id;
bool shim_writes_first = false;
- bool tls_d5_bug = false;
std::string host_name;
std::string advertise_alpn;
std::string expected_alpn;
@@ -77,7 +76,6 @@ struct TestConfig {
std::string export_label;
std::string export_context;
bool use_export_context = false;
- bool no_legacy_server_connect = false;
bool tls_unique = false;
bool expect_ticket_renewal = false;
bool expect_no_session = false;
@@ -90,7 +88,6 @@ struct TestConfig {
std::string ocsp_response;
bool check_close_notify = false;
bool shim_shuts_down = false;
- bool microsoft_big_sslv3_buffer = false;
bool verify_fail = false;
bool verify_peer = false;
bool expect_verify_result = false;
@@ -101,6 +98,10 @@ struct TestConfig {
bool renegotiate_ignore = false;
bool disable_npn = false;
int expect_server_key_exchange_hash = 0;
+ bool p384_only = false;
+ bool enable_all_curves = false;
+ bool use_sparse_dh_prime = false;
+ int expect_key_exchange_info = 0;
};
bool ParseConfig(int argc, char **argv, TestConfig *out_config);
diff --git a/src/ssl/tls_record.c b/src/ssl/tls_record.c
index bdc5c01..3381eae 100644
--- a/src/ssl/tls_record.c
+++ b/src/ssl/tls_record.c
@@ -114,7 +114,6 @@
#include <openssl/err.h>
#include "internal.h"
-#include "../crypto/internal.h"
/* kMaxEmptyRecords is the number of consecutive, empty records that will be
@@ -123,14 +122,12 @@
* forever. */
static const uint8_t kMaxEmptyRecords = 32;
-static struct CRYPTO_STATIC_MUTEX g_big_buffer_lock = CRYPTO_STATIC_MUTEX_INIT;
-static uint64_t g_big_buffer_use_count = 0;
-
-uint64_t OPENSSL_get_big_buffer_use_count(void) {
- CRYPTO_STATIC_MUTEX_lock_read(&g_big_buffer_lock);
- uint64_t ret = g_big_buffer_use_count;
- CRYPTO_STATIC_MUTEX_unlock(&g_big_buffer_lock);
- return ret;
+/* ssl_needs_record_splitting returns one if |ssl|'s current outgoing cipher
+ * state needs record-splitting and zero otherwise. */
+static int ssl_needs_record_splitting(const SSL *ssl) {
+ return !SSL_USE_EXPLICIT_IV(ssl) && ssl->aead_write_ctx != NULL &&
+ (ssl->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0 &&
+ SSL_CIPHER_is_block_cipher(ssl->aead_write_ctx->cipher);
}
size_t ssl_record_prefix_len(const SSL *ssl) {
@@ -150,7 +147,7 @@ size_t ssl_seal_prefix_len(const SSL *ssl) {
} else {
size_t ret = SSL3_RT_HEADER_LENGTH +
SSL_AEAD_CTX_explicit_nonce_len(ssl->aead_write_ctx);
- if (ssl->s3->need_record_splitting) {
+ if (ssl_needs_record_splitting(ssl)) {
ret += SSL3_RT_HEADER_LENGTH;
ret += ssl_cipher_get_record_split_len(ssl->aead_write_ctx->cipher);
}
@@ -165,7 +162,7 @@ size_t ssl_max_seal_overhead(const SSL *ssl) {
} else {
size_t ret = SSL3_RT_HEADER_LENGTH +
SSL_AEAD_CTX_max_overhead(ssl->aead_write_ctx);
- if (ssl->s3->need_record_splitting) {
+ if (ssl_needs_record_splitting(ssl)) {
ret *= 2;
}
return ret;
@@ -198,11 +195,7 @@ enum ssl_open_record_t tls_open_record(
}
/* Check the ciphertext length. */
- size_t extra = 0;
- if (ssl->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) {
- extra = SSL3_RT_MAX_EXTRA;
- }
- if (ciphertext_len > SSL3_RT_MAX_ENCRYPTED_LENGTH + extra) {
+ if (ciphertext_len > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
OPENSSL_PUT_ERROR(SSL, SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
*out_alert = SSL_AD_RECORD_OVERFLOW;
return ssl_open_record_error;
@@ -235,20 +228,12 @@ enum ssl_open_record_t tls_open_record(
}
/* Check the plaintext length. */
- if (plaintext_len > SSL3_RT_MAX_PLAIN_LENGTH + extra) {
+ if (plaintext_len > SSL3_RT_MAX_PLAIN_LENGTH) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
*out_alert = SSL_AD_RECORD_OVERFLOW;
return ssl_open_record_error;
}
- if (extra > 0 &&
- (ciphertext_len > SSL3_RT_MAX_ENCRYPTED_LENGTH ||
- plaintext_len > SSL3_RT_MAX_PLAIN_LENGTH)) {
- CRYPTO_STATIC_MUTEX_lock_write(&g_big_buffer_lock);
- g_big_buffer_use_count++;
- CRYPTO_STATIC_MUTEX_unlock(&g_big_buffer_lock);
- }
-
/* Limit the number of consecutive empty records. */
if (plaintext_len == 0) {
ssl->s3->empty_record_count++;
@@ -323,8 +308,8 @@ static int do_seal_record(SSL *ssl, uint8_t *out, size_t *out_len,
int tls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
uint8_t type, const uint8_t *in, size_t in_len) {
size_t frag_len = 0;
- if (ssl->s3->need_record_splitting && type == SSL3_RT_APPLICATION_DATA &&
- in_len > 1) {
+ if (type == SSL3_RT_APPLICATION_DATA && in_len > 1 &&
+ ssl_needs_record_splitting(ssl)) {
/* |do_seal_record| will notice if it clobbers |in[0]|, but not if it
* aliases the rest of |in|. */
if (in + 1 <= out && out < in + in_len) {
diff --git a/src/tool/CMakeLists.txt b/src/tool/CMakeLists.txt
index a6cc15f..f0af283 100644
--- a/src/tool/CMakeLists.txt
+++ b/src/tool/CMakeLists.txt
@@ -8,6 +8,7 @@ add_executable(
client.cc
const.cc
digest.cc
+ generate_ed25519.cc
genrsa.cc
pkcs12.cc
rand.cc
diff --git a/src/tool/client.cc b/src/tool/client.cc
index cd8353b..dbec184 100644
--- a/src/tool/client.cc
+++ b/src/tool/client.cc
@@ -14,6 +14,8 @@
#include <openssl/base.h>
+#include <stdio.h>
+
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
@@ -80,6 +82,10 @@ static const struct argument kArguments[] = {
"A file to write the negotiated session to.",
},
{
+ "-key", kOptionalArgument,
+ "Private-key file to use (default is no client certificate)",
+ },
+ {
"", kOptionalArgument, "",
},
};
@@ -119,6 +125,13 @@ static int NextProtoSelectCallback(SSL* ssl, uint8_t** out, uint8_t* outlen,
return SSL_TLSEXT_ERR_OK;
}
+static FILE *g_keylog_file = nullptr;
+
+static void KeyLogCallback(const SSL *ssl, const char *line) {
+ fprintf(g_keylog_file, "%s\n", line);
+ fflush(g_keylog_file);
+}
+
bool Client(const std::vector<std::string> &args) {
if (!InitSocketLibrary()) {
return false;
@@ -135,12 +148,12 @@ bool Client(const std::vector<std::string> &args) {
const char *keylog_file = getenv("SSLKEYLOGFILE");
if (keylog_file) {
- BIO *keylog_bio = BIO_new_file(keylog_file, "a");
- if (!keylog_bio) {
- ERR_print_errors_cb(PrintErrorCallback, stderr);
+ g_keylog_file = fopen(keylog_file, "a");
+ if (g_keylog_file == nullptr) {
+ perror("fopen");
return false;
}
- SSL_CTX_set_keylog_bio(ctx.get(), keylog_bio);
+ SSL_CTX_set_keylog_callback(ctx.get(), KeyLogCallback);
}
if (args_map.count("-cipher") != 0 &&
@@ -227,6 +240,18 @@ bool Client(const std::vector<std::string> &args) {
SSL_CTX_set_mode(ctx.get(), SSL_MODE_ENABLE_FALSE_START);
}
+ if (args_map.count("-key") != 0) {
+ const std::string &key = args_map["-key"];
+ if (!SSL_CTX_use_PrivateKey_file(ctx.get(), key.c_str(), SSL_FILETYPE_PEM)) {
+ fprintf(stderr, "Failed to load private key: %s\n", key.c_str());
+ return false;
+ }
+ if (!SSL_CTX_use_certificate_chain_file(ctx.get(), key.c_str())) {
+ fprintf(stderr, "Failed to load cert chain: %s\n", key.c_str());
+ return false;
+ }
+ }
+
int sock = -1;
if (!Connect(&sock, args_map["-connect"])) {
return false;
diff --git a/src/tool/generate_ed25519.cc b/src/tool/generate_ed25519.cc
new file mode 100644
index 0000000..15d3692
--- /dev/null
+++ b/src/tool/generate_ed25519.cc
@@ -0,0 +1,67 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <openssl/curve25519.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "../crypto/test/scoped_types.h"
+#include "internal.h"
+
+
+static const struct argument kArguments[] = {
+ {
+ "-out-public", kRequiredArgument, "The file to write the public key to",
+ },
+ {
+ "-out-private", kRequiredArgument,
+ "The file to write the private key to",
+ },
+ {
+ "", kOptionalArgument, "",
+ },
+};
+
+static bool WriteToFile(const std::string &path, const uint8_t *in,
+ size_t in_len) {
+ ScopedFILE file(fopen(path.c_str(), "wb"));
+ if (!file) {
+ fprintf(stderr, "Failed to open '%s': %s\n", path.c_str(), strerror(errno));
+ return false;
+ }
+ if (fwrite(in, in_len, 1, file.get()) != 1) {
+ fprintf(stderr, "Failed to write to '%s': %s\n", path.c_str(),
+ strerror(errno));
+ return false;
+ }
+ return true;
+}
+
+bool GenerateEd25519Key(const std::vector<std::string> &args) {
+ std::map<std::string, std::string> args_map;
+
+ if (!ParseKeyValueArguments(&args_map, args, kArguments)) {
+ PrintUsage(kArguments);
+ return false;
+ }
+
+ uint8_t public_key[32], private_key[64];
+ ED25519_keypair(public_key, private_key);
+
+ return WriteToFile(args_map["-out-public"], public_key, sizeof(public_key)) &&
+ WriteToFile(args_map["-out-private"], private_key,
+ sizeof(private_key));
+}
diff --git a/src/tool/server.cc b/src/tool/server.cc
index abc71cf..14f37a4 100644
--- a/src/tool/server.cc
+++ b/src/tool/server.cc
@@ -103,11 +103,11 @@ bool Server(const std::vector<std::string> &args) {
if (args_map.count("-key") != 0) {
key_file = args_map["-key"];
}
- if (SSL_CTX_use_PrivateKey_file(ctx, key_file.c_str(), SSL_FILETYPE_PEM) <= 0) {
+ if (!SSL_CTX_use_PrivateKey_file(ctx, key_file.c_str(), SSL_FILETYPE_PEM)) {
fprintf(stderr, "Failed to load private key: %s\n", key_file.c_str());
return false;
}
- if (SSL_CTX_use_certificate_chain_file(ctx, key_file.c_str()) != 1) {
+ if (!SSL_CTX_use_certificate_chain_file(ctx, key_file.c_str())) {
fprintf(stderr, "Failed to load cert chain: %s\n", key_file.c_str());
return false;
}
diff --git a/src/tool/speed.cc b/src/tool/speed.cc
index 39bbadb..db7c5fa 100644
--- a/src/tool/speed.cc
+++ b/src/tool/speed.cc
@@ -21,6 +21,7 @@
#include <string.h>
#include <openssl/aead.h>
+#include <openssl/curve25519.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/obj.h>
@@ -397,6 +398,75 @@ static bool SpeedECDSA(const std::string &selected) {
SpeedECDSACurve("ECDSA P-521", NID_secp521r1, selected);
}
+static bool Speed25519(const std::string &selected) {
+ if (!selected.empty() && selected.find("25519") == std::string::npos) {
+ return true;
+ }
+
+ TimeResults results;
+
+ uint8_t public_key[32], private_key[64];
+
+ if (!TimeFunction(&results, [&public_key, &private_key]() -> bool {
+ ED25519_keypair(public_key, private_key);
+ return true;
+ })) {
+ return false;
+ }
+
+ results.Print("Ed25519 key generation");
+
+ static const uint8_t kMessage[] = {0, 1, 2, 3, 4, 5};
+ uint8_t signature[64];
+
+ if (!TimeFunction(&results, [&private_key, &signature]() -> bool {
+ return ED25519_sign(signature, kMessage, sizeof(kMessage),
+ private_key) == 1;
+ })) {
+ return false;
+ }
+
+ results.Print("Ed25519 signing");
+
+ if (!TimeFunction(&results, [&public_key, &signature]() -> bool {
+ return ED25519_verify(kMessage, sizeof(kMessage), signature,
+ public_key) == 1;
+ })) {
+ fprintf(stderr, "Ed25519 verify failed.\n");
+ return false;
+ }
+
+ results.Print("Ed25519 verify");
+
+ if (!TimeFunction(&results, []() -> bool {
+ uint8_t out[32], in[32];
+ memset(in, 0, sizeof(in));
+ X25519_public_from_private(out, in);
+ return true;
+ })) {
+ fprintf(stderr, "Curve25519 base-point multiplication failed.\n");
+ return false;
+ }
+
+ results.Print("Curve25519 base-point multiplication");
+
+ if (!TimeFunction(&results, []() -> bool {
+ uint8_t out[32], in1[32], in2[32];
+ memset(in1, 0, sizeof(in1));
+ memset(in2, 0, sizeof(in2));
+ in1[0] = 1;
+ in2[0] = 9;
+ return X25519(out, in1, in2) == 1;
+ })) {
+ fprintf(stderr, "Curve25519 arbitrary point multiplication failed.\n");
+ return false;
+ }
+
+ results.Print("Curve25519 arbitrary point multiplication");
+
+ return true;
+}
+
bool Speed(const std::vector<std::string> &args) {
std::string selected;
if (args.size() > 1) {
@@ -458,11 +528,14 @@ bool Speed(const std::vector<std::string> &args) {
if (!SpeedAEAD(EVP_aead_aes_128_gcm(), "AES-128-GCM", kTLSADLen, selected) ||
!SpeedAEAD(EVP_aead_aes_256_gcm(), "AES-256-GCM", kTLSADLen, selected) ||
- !SpeedAEAD(EVP_aead_chacha20_poly1305_rfc7539(), "ChaCha20-Poly1305",
- kTLSADLen, selected) ||
+ !SpeedAEAD(EVP_aead_chacha20_poly1305(), "ChaCha20-Poly1305", kTLSADLen,
+ selected) ||
!SpeedAEAD(EVP_aead_chacha20_poly1305_old(), "ChaCha20-Poly1305-Old",
kTLSADLen, selected) ||
!SpeedAEAD(EVP_aead_rc4_md5_tls(), "RC4-MD5", kLegacyADLen, selected) ||
+ !SpeedAEAD(EVP_aead_rc4_sha1_tls(), "RC4-SHA1", kLegacyADLen, selected) ||
+ !SpeedAEAD(EVP_aead_des_ede3_cbc_sha1_tls(), "DES-EDE3-CBC-SHA1",
+ kLegacyADLen, selected) ||
!SpeedAEAD(EVP_aead_aes_128_cbc_sha1_tls(), "AES-128-CBC-SHA1",
kLegacyADLen, selected) ||
!SpeedAEAD(EVP_aead_aes_256_cbc_sha1_tls(), "AES-256-CBC-SHA1",
@@ -472,7 +545,8 @@ bool Speed(const std::vector<std::string> &args) {
!SpeedHash(EVP_sha512(), "SHA-512", selected) ||
!SpeedRandom(selected) ||
!SpeedECDH(selected) ||
- !SpeedECDSA(selected)) {
+ !SpeedECDSA(selected) ||
+ !Speed25519(selected)) {
return false;
}
diff --git a/src/tool/tool.cc b/src/tool/tool.cc
index afe6840..b825008 100644
--- a/src/tool/tool.cc
+++ b/src/tool/tool.cc
@@ -30,6 +30,7 @@
bool Ciphers(const std::vector<std::string> &args);
bool Client(const std::vector<std::string> &args);
bool DoPKCS12(const std::vector<std::string> &args);
+bool GenerateEd25519Key(const std::vector<std::string> &args);
bool GenerateRSAKey(const std::vector<std::string> &args);
bool MD5Sum(const std::vector<std::string> &args);
bool Rand(const std::vector<std::string> &args);
@@ -44,13 +45,14 @@ bool Speed(const std::vector<std::string> &args);
typedef bool (*tool_func_t)(const std::vector<std::string> &args);
struct Tool {
- char name[16];
+ const char *name;
tool_func_t func;
};
static const Tool kTools[] = {
{ "ciphers", Ciphers },
{ "client", Client },
+ { "generate-ed25519", GenerateEd25519Key },
{ "genrsa", GenerateRSAKey },
{ "md5sum", MD5Sum },
{ "pkcs12", DoPKCS12 },
@@ -68,19 +70,17 @@ static const Tool kTools[] = {
};
static void usage(const char *name) {
- printf("Usage: %s [", name);
+ printf("Usage: %s COMMAND\n", name);
+ printf("\n");
+ printf("Available commands:\n");
for (size_t i = 0;; i++) {
const Tool &tool = kTools[i];
if (tool.func == nullptr) {
break;
}
- if (i > 0) {
- printf("|");
- }
- printf("%s", tool.name);
+ printf(" %s\n", tool.name);
}
- printf("]\n");
}
tool_func_t FindTool(const std::string &name) {
diff --git a/src/tool/transport_common.cc b/src/tool/transport_common.cc
index cfda6c3..2c15c00 100644
--- a/src/tool/transport_common.cc
+++ b/src/tool/transport_common.cc
@@ -172,6 +172,11 @@ void PrintConnectionInfo(const SSL *ssl) {
fprintf(stderr, " Resumed session: %s\n",
SSL_session_reused(ssl) ? "yes" : "no");
fprintf(stderr, " Cipher: %s\n", SSL_CIPHER_get_name(cipher));
+ if (SSL_CIPHER_is_ECDHE(cipher)) {
+ fprintf(stderr, " ECDHE curve: %s\n",
+ SSL_get_curve_name(
+ SSL_SESSION_get_key_exchange_info(SSL_get_session(ssl))));
+ }
fprintf(stderr, " Secure renegotiation: %s\n",
SSL_get_secure_renegotiation_support(ssl) ? "yes" : "no");
diff --git a/src/util/all_tests.json b/src/util/all_tests.json
index ba57cc7..c621799 100644
--- a/src/util/all_tests.json
+++ b/src/util/all_tests.json
@@ -31,6 +31,8 @@
["crypto/cipher/cipher_test", "crypto/cipher/test/cipher_test.txt"],
["crypto/cmac/cmac_test"],
["crypto/constant_time_test"],
+ ["crypto/curve25519/ed25519_test", "crypto/curve25519/ed25519_tests.txt"],
+ ["crypto/curve25519/x25519_test"],
["crypto/dh/dh_test"],
["crypto/digest/digest_test"],
["crypto/dsa/dsa_test"],
diff --git a/src/util/bot/update_clang.py b/src/util/bot/update_clang.py
index 0836d11..1824393 100644
--- a/src/util/bot/update_clang.py
+++ b/src/util/bot/update_clang.py
@@ -20,7 +20,7 @@ import tempfile
import urllib
# CLANG_REVISION and CLANG_SUB_REVISION determine the build of clang
-# to use. These should be synced with tools/clang/scripts/update.sh in
+# to use. These should be synced with tools/clang/scripts/update.py in
# Chromium.
CLANG_REVISION = "233105"
CLANG_SUB_REVISION = "1"
diff --git a/src/util/doc.config b/src/util/doc.config
index 77498ee..cbee543 100644
--- a/src/util/doc.config
+++ b/src/util/doc.config
@@ -24,6 +24,7 @@
"include/openssl/aes.h",
"include/openssl/bn.h",
"include/openssl/cmac.h",
+ "include/openssl/curve25519.h",
"include/openssl/des.h",
"include/openssl/dh.h",
"include/openssl/dsa.h",
diff --git a/src/util/generate_build_files.py b/src/util/generate_build_files.py
index 856960e..6321c5c 100644
--- a/src/util/generate_build_files.py
+++ b/src/util/generate_build_files.py
@@ -39,9 +39,10 @@ OS_ARCH_COMBOS = [
# perlasm system.
NON_PERL_FILES = {
('linux', 'arm'): [
- 'src/crypto/poly1305/poly1305_arm_asm.S',
'src/crypto/chacha/chacha_vec_arm.S',
'src/crypto/cpu-arm-asm.S',
+ 'src/crypto/curve25519/asm/x25519-asm-arm.S',
+ 'src/crypto/poly1305/poly1305_arm_asm.S',
],
}
@@ -149,8 +150,8 @@ class Android(object):
with open('sources.mk', 'w+') as makefile:
makefile.write(self.header)
- files['crypto'].extend(self.ExtraFiles())
- self.PrintVariableSection(makefile, 'crypto_sources', files['crypto'])
+ crypto_files = files['crypto'] + self.ExtraFiles()
+ self.PrintVariableSection(makefile, 'crypto_sources', crypto_files)
self.PrintVariableSection(makefile, 'ssl_sources', files['ssl'])
self.PrintVariableSection(makefile, 'tool_sources', files['tool'])
diff --git a/win-x86/crypto/sha/sha1-586.asm b/win-x86/crypto/sha/sha1-586.asm
index 43bf964..cee8c62 100644
--- a/win-x86/crypto/sha/sha1-586.asm
+++ b/win-x86/crypto/sha/sha1-586.asm
@@ -35,6 +35,11 @@ L$000pic_point:
mov ecx,DWORD [8+esi]
test eax,16777216
jz NEAR L$001x86
+ and edx,268435456
+ and eax,1073741824
+ or eax,edx
+ cmp eax,1342177280
+ je NEAR L$avx_shortcut
jmp NEAR L$ssse3_shortcut
align 16
L$001x86:
@@ -2619,6 +2624,1174 @@ L$005done:
pop ebx
pop ebp
ret
+align 16
+__sha1_block_data_order_avx:
+ push ebp
+ push ebx
+ push esi
+ push edi
+ call L$006pic_point
+L$006pic_point:
+ pop ebp
+ lea ebp,[(L$K_XX_XX-L$006pic_point)+ebp]
+L$avx_shortcut:
+ vzeroall
+ vmovdqa xmm7,[ebp]
+ vmovdqa xmm0,[16+ebp]
+ vmovdqa xmm1,[32+ebp]
+ vmovdqa xmm2,[48+ebp]
+ vmovdqa xmm6,[64+ebp]
+ mov edi,DWORD [20+esp]
+ mov ebp,DWORD [24+esp]
+ mov edx,DWORD [28+esp]
+ mov esi,esp
+ sub esp,208
+ and esp,-64
+ vmovdqa [112+esp],xmm0
+ vmovdqa [128+esp],xmm1
+ vmovdqa [144+esp],xmm2
+ shl edx,6
+ vmovdqa [160+esp],xmm7
+ add edx,ebp
+ vmovdqa [176+esp],xmm6
+ add ebp,64
+ mov DWORD [192+esp],edi
+ mov DWORD [196+esp],ebp
+ mov DWORD [200+esp],edx
+ mov DWORD [204+esp],esi
+ mov eax,DWORD [edi]
+ mov ebx,DWORD [4+edi]
+ mov ecx,DWORD [8+edi]
+ mov edx,DWORD [12+edi]
+ mov edi,DWORD [16+edi]
+ mov esi,ebx
+ vmovdqu xmm0,[ebp-64]
+ vmovdqu xmm1,[ebp-48]
+ vmovdqu xmm2,[ebp-32]
+ vmovdqu xmm3,[ebp-16]
+ vpshufb xmm0,xmm0,xmm6
+ vpshufb xmm1,xmm1,xmm6
+ vpshufb xmm2,xmm2,xmm6
+ vmovdqa [96+esp],xmm7
+ vpshufb xmm3,xmm3,xmm6
+ vpaddd xmm4,xmm0,xmm7
+ vpaddd xmm5,xmm1,xmm7
+ vpaddd xmm6,xmm2,xmm7
+ vmovdqa [esp],xmm4
+ mov ebp,ecx
+ vmovdqa [16+esp],xmm5
+ xor ebp,edx
+ vmovdqa [32+esp],xmm6
+ and esi,ebp
+ jmp NEAR L$007loop
+align 16
+L$007loop:
+ shrd ebx,ebx,2
+ xor esi,edx
+ vpalignr xmm4,xmm1,xmm0,8
+ mov ebp,eax
+ add edi,DWORD [esp]
+ vpaddd xmm7,xmm7,xmm3
+ vmovdqa [64+esp],xmm0
+ xor ebx,ecx
+ shld eax,eax,5
+ vpsrldq xmm6,xmm3,4
+ add edi,esi
+ and ebp,ebx
+ vpxor xmm4,xmm4,xmm0
+ xor ebx,ecx
+ add edi,eax
+ vpxor xmm6,xmm6,xmm2
+ shrd eax,eax,7
+ xor ebp,ecx
+ vmovdqa [48+esp],xmm7
+ mov esi,edi
+ add edx,DWORD [4+esp]
+ vpxor xmm4,xmm4,xmm6
+ xor eax,ebx
+ shld edi,edi,5
+ add edx,ebp
+ and esi,eax
+ vpsrld xmm6,xmm4,31
+ xor eax,ebx
+ add edx,edi
+ shrd edi,edi,7
+ xor esi,ebx
+ vpslldq xmm0,xmm4,12
+ vpaddd xmm4,xmm4,xmm4
+ mov ebp,edx
+ add ecx,DWORD [8+esp]
+ xor edi,eax
+ shld edx,edx,5
+ vpsrld xmm7,xmm0,30
+ vpor xmm4,xmm4,xmm6
+ add ecx,esi
+ and ebp,edi
+ xor edi,eax
+ add ecx,edx
+ vpslld xmm0,xmm0,2
+ shrd edx,edx,7
+ xor ebp,eax
+ vpxor xmm4,xmm4,xmm7
+ mov esi,ecx
+ add ebx,DWORD [12+esp]
+ xor edx,edi
+ shld ecx,ecx,5
+ vpxor xmm4,xmm4,xmm0
+ add ebx,ebp
+ and esi,edx
+ vmovdqa xmm0,[96+esp]
+ xor edx,edi
+ add ebx,ecx
+ shrd ecx,ecx,7
+ xor esi,edi
+ vpalignr xmm5,xmm2,xmm1,8
+ mov ebp,ebx
+ add eax,DWORD [16+esp]
+ vpaddd xmm0,xmm0,xmm4
+ vmovdqa [80+esp],xmm1
+ xor ecx,edx
+ shld ebx,ebx,5
+ vpsrldq xmm7,xmm4,4
+ add eax,esi
+ and ebp,ecx
+ vpxor xmm5,xmm5,xmm1
+ xor ecx,edx
+ add eax,ebx
+ vpxor xmm7,xmm7,xmm3
+ shrd ebx,ebx,7
+ xor ebp,edx
+ vmovdqa [esp],xmm0
+ mov esi,eax
+ add edi,DWORD [20+esp]
+ vpxor xmm5,xmm5,xmm7
+ xor ebx,ecx
+ shld eax,eax,5
+ add edi,ebp
+ and esi,ebx
+ vpsrld xmm7,xmm5,31
+ xor ebx,ecx
+ add edi,eax
+ shrd eax,eax,7
+ xor esi,ecx
+ vpslldq xmm1,xmm5,12
+ vpaddd xmm5,xmm5,xmm5
+ mov ebp,edi
+ add edx,DWORD [24+esp]
+ xor eax,ebx
+ shld edi,edi,5
+ vpsrld xmm0,xmm1,30
+ vpor xmm5,xmm5,xmm7
+ add edx,esi
+ and ebp,eax
+ xor eax,ebx
+ add edx,edi
+ vpslld xmm1,xmm1,2
+ shrd edi,edi,7
+ xor ebp,ebx
+ vpxor xmm5,xmm5,xmm0
+ mov esi,edx
+ add ecx,DWORD [28+esp]
+ xor edi,eax
+ shld edx,edx,5
+ vpxor xmm5,xmm5,xmm1
+ add ecx,ebp
+ and esi,edi
+ vmovdqa xmm1,[112+esp]
+ xor edi,eax
+ add ecx,edx
+ shrd edx,edx,7
+ xor esi,eax
+ vpalignr xmm6,xmm3,xmm2,8
+ mov ebp,ecx
+ add ebx,DWORD [32+esp]
+ vpaddd xmm1,xmm1,xmm5
+ vmovdqa [96+esp],xmm2
+ xor edx,edi
+ shld ecx,ecx,5
+ vpsrldq xmm0,xmm5,4
+ add ebx,esi
+ and ebp,edx
+ vpxor xmm6,xmm6,xmm2
+ xor edx,edi
+ add ebx,ecx
+ vpxor xmm0,xmm0,xmm4
+ shrd ecx,ecx,7
+ xor ebp,edi
+ vmovdqa [16+esp],xmm1
+ mov esi,ebx
+ add eax,DWORD [36+esp]
+ vpxor xmm6,xmm6,xmm0
+ xor ecx,edx
+ shld ebx,ebx,5
+ add eax,ebp
+ and esi,ecx
+ vpsrld xmm0,xmm6,31
+ xor ecx,edx
+ add eax,ebx
+ shrd ebx,ebx,7
+ xor esi,edx
+ vpslldq xmm2,xmm6,12
+ vpaddd xmm6,xmm6,xmm6
+ mov ebp,eax
+ add edi,DWORD [40+esp]
+ xor ebx,ecx
+ shld eax,eax,5
+ vpsrld xmm1,xmm2,30
+ vpor xmm6,xmm6,xmm0
+ add edi,esi
+ and ebp,ebx
+ xor ebx,ecx
+ add edi,eax
+ vpslld xmm2,xmm2,2
+ vmovdqa xmm0,[64+esp]
+ shrd eax,eax,7
+ xor ebp,ecx
+ vpxor xmm6,xmm6,xmm1
+ mov esi,edi
+ add edx,DWORD [44+esp]
+ xor eax,ebx
+ shld edi,edi,5
+ vpxor xmm6,xmm6,xmm2
+ add edx,ebp
+ and esi,eax
+ vmovdqa xmm2,[112+esp]
+ xor eax,ebx
+ add edx,edi
+ shrd edi,edi,7
+ xor esi,ebx
+ vpalignr xmm7,xmm4,xmm3,8
+ mov ebp,edx
+ add ecx,DWORD [48+esp]
+ vpaddd xmm2,xmm2,xmm6
+ vmovdqa [64+esp],xmm3
+ xor edi,eax
+ shld edx,edx,5
+ vpsrldq xmm1,xmm6,4
+ add ecx,esi
+ and ebp,edi
+ vpxor xmm7,xmm7,xmm3
+ xor edi,eax
+ add ecx,edx
+ vpxor xmm1,xmm1,xmm5
+ shrd edx,edx,7
+ xor ebp,eax
+ vmovdqa [32+esp],xmm2
+ mov esi,ecx
+ add ebx,DWORD [52+esp]
+ vpxor xmm7,xmm7,xmm1
+ xor edx,edi
+ shld ecx,ecx,5
+ add ebx,ebp
+ and esi,edx
+ vpsrld xmm1,xmm7,31
+ xor edx,edi
+ add ebx,ecx
+ shrd ecx,ecx,7
+ xor esi,edi
+ vpslldq xmm3,xmm7,12
+ vpaddd xmm7,xmm7,xmm7
+ mov ebp,ebx
+ add eax,DWORD [56+esp]
+ xor ecx,edx
+ shld ebx,ebx,5
+ vpsrld xmm2,xmm3,30
+ vpor xmm7,xmm7,xmm1
+ add eax,esi
+ and ebp,ecx
+ xor ecx,edx
+ add eax,ebx
+ vpslld xmm3,xmm3,2
+ vmovdqa xmm1,[80+esp]
+ shrd ebx,ebx,7
+ xor ebp,edx
+ vpxor xmm7,xmm7,xmm2
+ mov esi,eax
+ add edi,DWORD [60+esp]
+ xor ebx,ecx
+ shld eax,eax,5
+ vpxor xmm7,xmm7,xmm3
+ add edi,ebp
+ and esi,ebx
+ vmovdqa xmm3,[112+esp]
+ xor ebx,ecx
+ add edi,eax
+ vpalignr xmm2,xmm7,xmm6,8
+ vpxor xmm0,xmm0,xmm4
+ shrd eax,eax,7
+ xor esi,ecx
+ mov ebp,edi
+ add edx,DWORD [esp]
+ vpxor xmm0,xmm0,xmm1
+ vmovdqa [80+esp],xmm4
+ xor eax,ebx
+ shld edi,edi,5
+ vmovdqa xmm4,xmm3
+ vpaddd xmm3,xmm3,xmm7
+ add edx,esi
+ and ebp,eax
+ vpxor xmm0,xmm0,xmm2
+ xor eax,ebx
+ add edx,edi
+ shrd edi,edi,7
+ xor ebp,ebx
+ vpsrld xmm2,xmm0,30
+ vmovdqa [48+esp],xmm3
+ mov esi,edx
+ add ecx,DWORD [4+esp]
+ xor edi,eax
+ shld edx,edx,5
+ vpslld xmm0,xmm0,2
+ add ecx,ebp
+ and esi,edi
+ xor edi,eax
+ add ecx,edx
+ shrd edx,edx,7
+ xor esi,eax
+ mov ebp,ecx
+ add ebx,DWORD [8+esp]
+ vpor xmm0,xmm0,xmm2
+ xor edx,edi
+ shld ecx,ecx,5
+ vmovdqa xmm2,[96+esp]
+ add ebx,esi
+ and ebp,edx
+ xor edx,edi
+ add ebx,ecx
+ add eax,DWORD [12+esp]
+ xor ebp,edi
+ mov esi,ebx
+ shld ebx,ebx,5
+ add eax,ebp
+ xor esi,edx
+ shrd ecx,ecx,7
+ add eax,ebx
+ vpalignr xmm3,xmm0,xmm7,8
+ vpxor xmm1,xmm1,xmm5
+ add edi,DWORD [16+esp]
+ xor esi,ecx
+ mov ebp,eax
+ shld eax,eax,5
+ vpxor xmm1,xmm1,xmm2
+ vmovdqa [96+esp],xmm5
+ add edi,esi
+ xor ebp,ecx
+ vmovdqa xmm5,xmm4
+ vpaddd xmm4,xmm4,xmm0
+ shrd ebx,ebx,7
+ add edi,eax
+ vpxor xmm1,xmm1,xmm3
+ add edx,DWORD [20+esp]
+ xor ebp,ebx
+ mov esi,edi
+ shld edi,edi,5
+ vpsrld xmm3,xmm1,30
+ vmovdqa [esp],xmm4
+ add edx,ebp
+ xor esi,ebx
+ shrd eax,eax,7
+ add edx,edi
+ vpslld xmm1,xmm1,2
+ add ecx,DWORD [24+esp]
+ xor esi,eax
+ mov ebp,edx
+ shld edx,edx,5
+ add ecx,esi
+ xor ebp,eax
+ shrd edi,edi,7
+ add ecx,edx
+ vpor xmm1,xmm1,xmm3
+ add ebx,DWORD [28+esp]
+ xor ebp,edi
+ vmovdqa xmm3,[64+esp]
+ mov esi,ecx
+ shld ecx,ecx,5
+ add ebx,ebp
+ xor esi,edi
+ shrd edx,edx,7
+ add ebx,ecx
+ vpalignr xmm4,xmm1,xmm0,8
+ vpxor xmm2,xmm2,xmm6
+ add eax,DWORD [32+esp]
+ xor esi,edx
+ mov ebp,ebx
+ shld ebx,ebx,5
+ vpxor xmm2,xmm2,xmm3
+ vmovdqa [64+esp],xmm6
+ add eax,esi
+ xor ebp,edx
+ vmovdqa xmm6,[128+esp]
+ vpaddd xmm5,xmm5,xmm1
+ shrd ecx,ecx,7
+ add eax,ebx
+ vpxor xmm2,xmm2,xmm4
+ add edi,DWORD [36+esp]
+ xor ebp,ecx
+ mov esi,eax
+ shld eax,eax,5
+ vpsrld xmm4,xmm2,30
+ vmovdqa [16+esp],xmm5
+ add edi,ebp
+ xor esi,ecx
+ shrd ebx,ebx,7
+ add edi,eax
+ vpslld xmm2,xmm2,2
+ add edx,DWORD [40+esp]
+ xor esi,ebx
+ mov ebp,edi
+ shld edi,edi,5
+ add edx,esi
+ xor ebp,ebx
+ shrd eax,eax,7
+ add edx,edi
+ vpor xmm2,xmm2,xmm4
+ add ecx,DWORD [44+esp]
+ xor ebp,eax
+ vmovdqa xmm4,[80+esp]
+ mov esi,edx
+ shld edx,edx,5
+ add ecx,ebp
+ xor esi,eax
+ shrd edi,edi,7
+ add ecx,edx
+ vpalignr xmm5,xmm2,xmm1,8
+ vpxor xmm3,xmm3,xmm7
+ add ebx,DWORD [48+esp]
+ xor esi,edi
+ mov ebp,ecx
+ shld ecx,ecx,5
+ vpxor xmm3,xmm3,xmm4
+ vmovdqa [80+esp],xmm7
+ add ebx,esi
+ xor ebp,edi
+ vmovdqa xmm7,xmm6
+ vpaddd xmm6,xmm6,xmm2
+ shrd edx,edx,7
+ add ebx,ecx
+ vpxor xmm3,xmm3,xmm5
+ add eax,DWORD [52+esp]
+ xor ebp,edx
+ mov esi,ebx
+ shld ebx,ebx,5
+ vpsrld xmm5,xmm3,30
+ vmovdqa [32+esp],xmm6
+ add eax,ebp
+ xor esi,edx
+ shrd ecx,ecx,7
+ add eax,ebx
+ vpslld xmm3,xmm3,2
+ add edi,DWORD [56+esp]
+ xor esi,ecx
+ mov ebp,eax
+ shld eax,eax,5
+ add edi,esi
+ xor ebp,ecx
+ shrd ebx,ebx,7
+ add edi,eax
+ vpor xmm3,xmm3,xmm5
+ add edx,DWORD [60+esp]
+ xor ebp,ebx
+ vmovdqa xmm5,[96+esp]
+ mov esi,edi
+ shld edi,edi,5
+ add edx,ebp
+ xor esi,ebx
+ shrd eax,eax,7
+ add edx,edi
+ vpalignr xmm6,xmm3,xmm2,8
+ vpxor xmm4,xmm4,xmm0
+ add ecx,DWORD [esp]
+ xor esi,eax
+ mov ebp,edx
+ shld edx,edx,5
+ vpxor xmm4,xmm4,xmm5
+ vmovdqa [96+esp],xmm0
+ add ecx,esi
+ xor ebp,eax
+ vmovdqa xmm0,xmm7
+ vpaddd xmm7,xmm7,xmm3
+ shrd edi,edi,7
+ add ecx,edx
+ vpxor xmm4,xmm4,xmm6
+ add ebx,DWORD [4+esp]
+ xor ebp,edi
+ mov esi,ecx
+ shld ecx,ecx,5
+ vpsrld xmm6,xmm4,30
+ vmovdqa [48+esp],xmm7
+ add ebx,ebp
+ xor esi,edi
+ shrd edx,edx,7
+ add ebx,ecx
+ vpslld xmm4,xmm4,2
+ add eax,DWORD [8+esp]
+ xor esi,edx
+ mov ebp,ebx
+ shld ebx,ebx,5
+ add eax,esi
+ xor ebp,edx
+ shrd ecx,ecx,7
+ add eax,ebx
+ vpor xmm4,xmm4,xmm6
+ add edi,DWORD [12+esp]
+ xor ebp,ecx
+ vmovdqa xmm6,[64+esp]
+ mov esi,eax
+ shld eax,eax,5
+ add edi,ebp
+ xor esi,ecx
+ shrd ebx,ebx,7
+ add edi,eax
+ vpalignr xmm7,xmm4,xmm3,8
+ vpxor xmm5,xmm5,xmm1
+ add edx,DWORD [16+esp]
+ xor esi,ebx
+ mov ebp,edi
+ shld edi,edi,5
+ vpxor xmm5,xmm5,xmm6
+ vmovdqa [64+esp],xmm1
+ add edx,esi
+ xor ebp,ebx
+ vmovdqa xmm1,xmm0
+ vpaddd xmm0,xmm0,xmm4
+ shrd eax,eax,7
+ add edx,edi
+ vpxor xmm5,xmm5,xmm7
+ add ecx,DWORD [20+esp]
+ xor ebp,eax
+ mov esi,edx
+ shld edx,edx,5
+ vpsrld xmm7,xmm5,30
+ vmovdqa [esp],xmm0
+ add ecx,ebp
+ xor esi,eax
+ shrd edi,edi,7
+ add ecx,edx
+ vpslld xmm5,xmm5,2
+ add ebx,DWORD [24+esp]
+ xor esi,edi
+ mov ebp,ecx
+ shld ecx,ecx,5
+ add ebx,esi
+ xor ebp,edi
+ shrd edx,edx,7
+ add ebx,ecx
+ vpor xmm5,xmm5,xmm7
+ add eax,DWORD [28+esp]
+ vmovdqa xmm7,[80+esp]
+ shrd ecx,ecx,7
+ mov esi,ebx
+ xor ebp,edx
+ shld ebx,ebx,5
+ add eax,ebp
+ xor esi,ecx
+ xor ecx,edx
+ add eax,ebx
+ vpalignr xmm0,xmm5,xmm4,8
+ vpxor xmm6,xmm6,xmm2
+ add edi,DWORD [32+esp]
+ and esi,ecx
+ xor ecx,edx
+ shrd ebx,ebx,7
+ vpxor xmm6,xmm6,xmm7
+ vmovdqa [80+esp],xmm2
+ mov ebp,eax
+ xor esi,ecx
+ vmovdqa xmm2,xmm1
+ vpaddd xmm1,xmm1,xmm5
+ shld eax,eax,5
+ add edi,esi
+ vpxor xmm6,xmm6,xmm0
+ xor ebp,ebx
+ xor ebx,ecx
+ add edi,eax
+ add edx,DWORD [36+esp]
+ vpsrld xmm0,xmm6,30
+ vmovdqa [16+esp],xmm1
+ and ebp,ebx
+ xor ebx,ecx
+ shrd eax,eax,7
+ mov esi,edi
+ vpslld xmm6,xmm6,2
+ xor ebp,ebx
+ shld edi,edi,5
+ add edx,ebp
+ xor esi,eax
+ xor eax,ebx
+ add edx,edi
+ add ecx,DWORD [40+esp]
+ and esi,eax
+ vpor xmm6,xmm6,xmm0
+ xor eax,ebx
+ shrd edi,edi,7
+ vmovdqa xmm0,[96+esp]
+ mov ebp,edx
+ xor esi,eax
+ shld edx,edx,5
+ add ecx,esi
+ xor ebp,edi
+ xor edi,eax
+ add ecx,edx
+ add ebx,DWORD [44+esp]
+ and ebp,edi
+ xor edi,eax
+ shrd edx,edx,7
+ mov esi,ecx
+ xor ebp,edi
+ shld ecx,ecx,5
+ add ebx,ebp
+ xor esi,edx
+ xor edx,edi
+ add ebx,ecx
+ vpalignr xmm1,xmm6,xmm5,8
+ vpxor xmm7,xmm7,xmm3
+ add eax,DWORD [48+esp]
+ and esi,edx
+ xor edx,edi
+ shrd ecx,ecx,7
+ vpxor xmm7,xmm7,xmm0
+ vmovdqa [96+esp],xmm3
+ mov ebp,ebx
+ xor esi,edx
+ vmovdqa xmm3,[144+esp]
+ vpaddd xmm2,xmm2,xmm6
+ shld ebx,ebx,5
+ add eax,esi
+ vpxor xmm7,xmm7,xmm1
+ xor ebp,ecx
+ xor ecx,edx
+ add eax,ebx
+ add edi,DWORD [52+esp]
+ vpsrld xmm1,xmm7,30
+ vmovdqa [32+esp],xmm2
+ and ebp,ecx
+ xor ecx,edx
+ shrd ebx,ebx,7
+ mov esi,eax
+ vpslld xmm7,xmm7,2
+ xor ebp,ecx
+ shld eax,eax,5
+ add edi,ebp
+ xor esi,ebx
+ xor ebx,ecx
+ add edi,eax
+ add edx,DWORD [56+esp]
+ and esi,ebx
+ vpor xmm7,xmm7,xmm1
+ xor ebx,ecx
+ shrd eax,eax,7
+ vmovdqa xmm1,[64+esp]
+ mov ebp,edi
+ xor esi,ebx
+ shld edi,edi,5
+ add edx,esi
+ xor ebp,eax
+ xor eax,ebx
+ add edx,edi
+ add ecx,DWORD [60+esp]
+ and ebp,eax
+ xor eax,ebx
+ shrd edi,edi,7
+ mov esi,edx
+ xor ebp,eax
+ shld edx,edx,5
+ add ecx,ebp
+ xor esi,edi
+ xor edi,eax
+ add ecx,edx
+ vpalignr xmm2,xmm7,xmm6,8
+ vpxor xmm0,xmm0,xmm4
+ add ebx,DWORD [esp]
+ and esi,edi
+ xor edi,eax
+ shrd edx,edx,7
+ vpxor xmm0,xmm0,xmm1
+ vmovdqa [64+esp],xmm4
+ mov ebp,ecx
+ xor esi,edi
+ vmovdqa xmm4,xmm3
+ vpaddd xmm3,xmm3,xmm7
+ shld ecx,ecx,5
+ add ebx,esi
+ vpxor xmm0,xmm0,xmm2
+ xor ebp,edx
+ xor edx,edi
+ add ebx,ecx
+ add eax,DWORD [4+esp]
+ vpsrld xmm2,xmm0,30
+ vmovdqa [48+esp],xmm3
+ and ebp,edx
+ xor edx,edi
+ shrd ecx,ecx,7
+ mov esi,ebx
+ vpslld xmm0,xmm0,2
+ xor ebp,edx
+ shld ebx,ebx,5
+ add eax,ebp
+ xor esi,ecx
+ xor ecx,edx
+ add eax,ebx
+ add edi,DWORD [8+esp]
+ and esi,ecx
+ vpor xmm0,xmm0,xmm2
+ xor ecx,edx
+ shrd ebx,ebx,7
+ vmovdqa xmm2,[80+esp]
+ mov ebp,eax
+ xor esi,ecx
+ shld eax,eax,5
+ add edi,esi
+ xor ebp,ebx
+ xor ebx,ecx
+ add edi,eax
+ add edx,DWORD [12+esp]
+ and ebp,ebx
+ xor ebx,ecx
+ shrd eax,eax,7
+ mov esi,edi
+ xor ebp,ebx
+ shld edi,edi,5
+ add edx,ebp
+ xor esi,eax
+ xor eax,ebx
+ add edx,edi
+ vpalignr xmm3,xmm0,xmm7,8
+ vpxor xmm1,xmm1,xmm5
+ add ecx,DWORD [16+esp]
+ and esi,eax
+ xor eax,ebx
+ shrd edi,edi,7
+ vpxor xmm1,xmm1,xmm2
+ vmovdqa [80+esp],xmm5
+ mov ebp,edx
+ xor esi,eax
+ vmovdqa xmm5,xmm4
+ vpaddd xmm4,xmm4,xmm0
+ shld edx,edx,5
+ add ecx,esi
+ vpxor xmm1,xmm1,xmm3
+ xor ebp,edi
+ xor edi,eax
+ add ecx,edx
+ add ebx,DWORD [20+esp]
+ vpsrld xmm3,xmm1,30
+ vmovdqa [esp],xmm4
+ and ebp,edi
+ xor edi,eax
+ shrd edx,edx,7
+ mov esi,ecx
+ vpslld xmm1,xmm1,2
+ xor ebp,edi
+ shld ecx,ecx,5
+ add ebx,ebp
+ xor esi,edx
+ xor edx,edi
+ add ebx,ecx
+ add eax,DWORD [24+esp]
+ and esi,edx
+ vpor xmm1,xmm1,xmm3
+ xor edx,edi
+ shrd ecx,ecx,7
+ vmovdqa xmm3,[96+esp]
+ mov ebp,ebx
+ xor esi,edx
+ shld ebx,ebx,5
+ add eax,esi
+ xor ebp,ecx
+ xor ecx,edx
+ add eax,ebx
+ add edi,DWORD [28+esp]
+ and ebp,ecx
+ xor ecx,edx
+ shrd ebx,ebx,7
+ mov esi,eax
+ xor ebp,ecx
+ shld eax,eax,5
+ add edi,ebp
+ xor esi,ebx
+ xor ebx,ecx
+ add edi,eax
+ vpalignr xmm4,xmm1,xmm0,8
+ vpxor xmm2,xmm2,xmm6
+ add edx,DWORD [32+esp]
+ and esi,ebx
+ xor ebx,ecx
+ shrd eax,eax,7
+ vpxor xmm2,xmm2,xmm3
+ vmovdqa [96+esp],xmm6
+ mov ebp,edi
+ xor esi,ebx
+ vmovdqa xmm6,xmm5
+ vpaddd xmm5,xmm5,xmm1
+ shld edi,edi,5
+ add edx,esi
+ vpxor xmm2,xmm2,xmm4
+ xor ebp,eax
+ xor eax,ebx
+ add edx,edi
+ add ecx,DWORD [36+esp]
+ vpsrld xmm4,xmm2,30
+ vmovdqa [16+esp],xmm5
+ and ebp,eax
+ xor eax,ebx
+ shrd edi,edi,7
+ mov esi,edx
+ vpslld xmm2,xmm2,2
+ xor ebp,eax
+ shld edx,edx,5
+ add ecx,ebp
+ xor esi,edi
+ xor edi,eax
+ add ecx,edx
+ add ebx,DWORD [40+esp]
+ and esi,edi
+ vpor xmm2,xmm2,xmm4
+ xor edi,eax
+ shrd edx,edx,7
+ vmovdqa xmm4,[64+esp]
+ mov ebp,ecx
+ xor esi,edi
+ shld ecx,ecx,5
+ add ebx,esi
+ xor ebp,edx
+ xor edx,edi
+ add ebx,ecx
+ add eax,DWORD [44+esp]
+ and ebp,edx
+ xor edx,edi
+ shrd ecx,ecx,7
+ mov esi,ebx
+ xor ebp,edx
+ shld ebx,ebx,5
+ add eax,ebp
+ xor esi,edx
+ add eax,ebx
+ vpalignr xmm5,xmm2,xmm1,8
+ vpxor xmm3,xmm3,xmm7
+ add edi,DWORD [48+esp]
+ xor esi,ecx
+ mov ebp,eax
+ shld eax,eax,5
+ vpxor xmm3,xmm3,xmm4
+ vmovdqa [64+esp],xmm7
+ add edi,esi
+ xor ebp,ecx
+ vmovdqa xmm7,xmm6
+ vpaddd xmm6,xmm6,xmm2
+ shrd ebx,ebx,7
+ add edi,eax
+ vpxor xmm3,xmm3,xmm5
+ add edx,DWORD [52+esp]
+ xor ebp,ebx
+ mov esi,edi
+ shld edi,edi,5
+ vpsrld xmm5,xmm3,30
+ vmovdqa [32+esp],xmm6
+ add edx,ebp
+ xor esi,ebx
+ shrd eax,eax,7
+ add edx,edi
+ vpslld xmm3,xmm3,2
+ add ecx,DWORD [56+esp]
+ xor esi,eax
+ mov ebp,edx
+ shld edx,edx,5
+ add ecx,esi
+ xor ebp,eax
+ shrd edi,edi,7
+ add ecx,edx
+ vpor xmm3,xmm3,xmm5
+ add ebx,DWORD [60+esp]
+ xor ebp,edi
+ mov esi,ecx
+ shld ecx,ecx,5
+ add ebx,ebp
+ xor esi,edi
+ shrd edx,edx,7
+ add ebx,ecx
+ add eax,DWORD [esp]
+ vpaddd xmm7,xmm7,xmm3
+ xor esi,edx
+ mov ebp,ebx
+ shld ebx,ebx,5
+ add eax,esi
+ vmovdqa [48+esp],xmm7
+ xor ebp,edx
+ shrd ecx,ecx,7
+ add eax,ebx
+ add edi,DWORD [4+esp]
+ xor ebp,ecx
+ mov esi,eax
+ shld eax,eax,5
+ add edi,ebp
+ xor esi,ecx
+ shrd ebx,ebx,7
+ add edi,eax
+ add edx,DWORD [8+esp]
+ xor esi,ebx
+ mov ebp,edi
+ shld edi,edi,5
+ add edx,esi
+ xor ebp,ebx
+ shrd eax,eax,7
+ add edx,edi
+ add ecx,DWORD [12+esp]
+ xor ebp,eax
+ mov esi,edx
+ shld edx,edx,5
+ add ecx,ebp
+ xor esi,eax
+ shrd edi,edi,7
+ add ecx,edx
+ mov ebp,DWORD [196+esp]
+ cmp ebp,DWORD [200+esp]
+ je NEAR L$008done
+ vmovdqa xmm7,[160+esp]
+ vmovdqa xmm6,[176+esp]
+ vmovdqu xmm0,[ebp]
+ vmovdqu xmm1,[16+ebp]
+ vmovdqu xmm2,[32+ebp]
+ vmovdqu xmm3,[48+ebp]
+ add ebp,64
+ vpshufb xmm0,xmm0,xmm6
+ mov DWORD [196+esp],ebp
+ vmovdqa [96+esp],xmm7
+ add ebx,DWORD [16+esp]
+ xor esi,edi
+ vpshufb xmm1,xmm1,xmm6
+ mov ebp,ecx
+ shld ecx,ecx,5
+ vpaddd xmm4,xmm0,xmm7
+ add ebx,esi
+ xor ebp,edi
+ shrd edx,edx,7
+ add ebx,ecx
+ vmovdqa [esp],xmm4
+ add eax,DWORD [20+esp]
+ xor ebp,edx
+ mov esi,ebx
+ shld ebx,ebx,5
+ add eax,ebp
+ xor esi,edx
+ shrd ecx,ecx,7
+ add eax,ebx
+ add edi,DWORD [24+esp]
+ xor esi,ecx
+ mov ebp,eax
+ shld eax,eax,5
+ add edi,esi
+ xor ebp,ecx
+ shrd ebx,ebx,7
+ add edi,eax
+ add edx,DWORD [28+esp]
+ xor ebp,ebx
+ mov esi,edi
+ shld edi,edi,5
+ add edx,ebp
+ xor esi,ebx
+ shrd eax,eax,7
+ add edx,edi
+ add ecx,DWORD [32+esp]
+ xor esi,eax
+ vpshufb xmm2,xmm2,xmm6
+ mov ebp,edx
+ shld edx,edx,5
+ vpaddd xmm5,xmm1,xmm7
+ add ecx,esi
+ xor ebp,eax
+ shrd edi,edi,7
+ add ecx,edx
+ vmovdqa [16+esp],xmm5
+ add ebx,DWORD [36+esp]
+ xor ebp,edi
+ mov esi,ecx
+ shld ecx,ecx,5
+ add ebx,ebp
+ xor esi,edi
+ shrd edx,edx,7
+ add ebx,ecx
+ add eax,DWORD [40+esp]
+ xor esi,edx
+ mov ebp,ebx
+ shld ebx,ebx,5
+ add eax,esi
+ xor ebp,edx
+ shrd ecx,ecx,7
+ add eax,ebx
+ add edi,DWORD [44+esp]
+ xor ebp,ecx
+ mov esi,eax
+ shld eax,eax,5
+ add edi,ebp
+ xor esi,ecx
+ shrd ebx,ebx,7
+ add edi,eax
+ add edx,DWORD [48+esp]
+ xor esi,ebx
+ vpshufb xmm3,xmm3,xmm6
+ mov ebp,edi
+ shld edi,edi,5
+ vpaddd xmm6,xmm2,xmm7
+ add edx,esi
+ xor ebp,ebx
+ shrd eax,eax,7
+ add edx,edi
+ vmovdqa [32+esp],xmm6
+ add ecx,DWORD [52+esp]
+ xor ebp,eax
+ mov esi,edx
+ shld edx,edx,5
+ add ecx,ebp
+ xor esi,eax
+ shrd edi,edi,7
+ add ecx,edx
+ add ebx,DWORD [56+esp]
+ xor esi,edi
+ mov ebp,ecx
+ shld ecx,ecx,5
+ add ebx,esi
+ xor ebp,edi
+ shrd edx,edx,7
+ add ebx,ecx
+ add eax,DWORD [60+esp]
+ xor ebp,edx
+ mov esi,ebx
+ shld ebx,ebx,5
+ add eax,ebp
+ shrd ecx,ecx,7
+ add eax,ebx
+ mov ebp,DWORD [192+esp]
+ add eax,DWORD [ebp]
+ add esi,DWORD [4+ebp]
+ add ecx,DWORD [8+ebp]
+ mov DWORD [ebp],eax
+ add edx,DWORD [12+ebp]
+ mov DWORD [4+ebp],esi
+ add edi,DWORD [16+ebp]
+ mov ebx,ecx
+ mov DWORD [8+ebp],ecx
+ xor ebx,edx
+ mov DWORD [12+ebp],edx
+ mov DWORD [16+ebp],edi
+ mov ebp,esi
+ and esi,ebx
+ mov ebx,ebp
+ jmp NEAR L$007loop
+align 16
+L$008done:
+ add ebx,DWORD [16+esp]
+ xor esi,edi
+ mov ebp,ecx
+ shld ecx,ecx,5
+ add ebx,esi
+ xor ebp,edi
+ shrd edx,edx,7
+ add ebx,ecx
+ add eax,DWORD [20+esp]
+ xor ebp,edx
+ mov esi,ebx
+ shld ebx,ebx,5
+ add eax,ebp
+ xor esi,edx
+ shrd ecx,ecx,7
+ add eax,ebx
+ add edi,DWORD [24+esp]
+ xor esi,ecx
+ mov ebp,eax
+ shld eax,eax,5
+ add edi,esi
+ xor ebp,ecx
+ shrd ebx,ebx,7
+ add edi,eax
+ add edx,DWORD [28+esp]
+ xor ebp,ebx
+ mov esi,edi
+ shld edi,edi,5
+ add edx,ebp
+ xor esi,ebx
+ shrd eax,eax,7
+ add edx,edi
+ add ecx,DWORD [32+esp]
+ xor esi,eax
+ mov ebp,edx
+ shld edx,edx,5
+ add ecx,esi
+ xor ebp,eax
+ shrd edi,edi,7
+ add ecx,edx
+ add ebx,DWORD [36+esp]
+ xor ebp,edi
+ mov esi,ecx
+ shld ecx,ecx,5
+ add ebx,ebp
+ xor esi,edi
+ shrd edx,edx,7
+ add ebx,ecx
+ add eax,DWORD [40+esp]
+ xor esi,edx
+ mov ebp,ebx
+ shld ebx,ebx,5
+ add eax,esi
+ xor ebp,edx
+ shrd ecx,ecx,7
+ add eax,ebx
+ add edi,DWORD [44+esp]
+ xor ebp,ecx
+ mov esi,eax
+ shld eax,eax,5
+ add edi,ebp
+ xor esi,ecx
+ shrd ebx,ebx,7
+ add edi,eax
+ add edx,DWORD [48+esp]
+ xor esi,ebx
+ mov ebp,edi
+ shld edi,edi,5
+ add edx,esi
+ xor ebp,ebx
+ shrd eax,eax,7
+ add edx,edi
+ add ecx,DWORD [52+esp]
+ xor ebp,eax
+ mov esi,edx
+ shld edx,edx,5
+ add ecx,ebp
+ xor esi,eax
+ shrd edi,edi,7
+ add ecx,edx
+ add ebx,DWORD [56+esp]
+ xor esi,edi
+ mov ebp,ecx
+ shld ecx,ecx,5
+ add ebx,esi
+ xor ebp,edi
+ shrd edx,edx,7
+ add ebx,ecx
+ add eax,DWORD [60+esp]
+ xor ebp,edx
+ mov esi,ebx
+ shld ebx,ebx,5
+ add eax,ebp
+ shrd ecx,ecx,7
+ add eax,ebx
+ vzeroall
+ mov ebp,DWORD [192+esp]
+ add eax,DWORD [ebp]
+ mov esp,DWORD [204+esp]
+ add esi,DWORD [4+ebp]
+ add ecx,DWORD [8+ebp]
+ mov DWORD [ebp],eax
+ add edx,DWORD [12+ebp]
+ mov DWORD [4+ebp],esi
+ add edi,DWORD [16+ebp]
+ mov DWORD [8+ebp],ecx
+ mov DWORD [12+ebp],edx
+ mov DWORD [16+ebp],edi
+ pop edi
+ pop esi
+ pop ebx
+ pop ebp
+ ret
align 64
L$K_XX_XX:
dd 1518500249,1518500249,1518500249,1518500249
diff --git a/win-x86/crypto/sha/sha256-586.asm b/win-x86/crypto/sha/sha256-586.asm
index d03558c..3e7cfcc 100644
--- a/win-x86/crypto/sha/sha256-586.asm
+++ b/win-x86/crypto/sha/sha256-586.asm
@@ -52,12 +52,13 @@ L$000pic_point:
or ecx,ebx
and ecx,1342177280
cmp ecx,1342177280
+ je NEAR L$004AVX
test ebx,512
- jnz NEAR L$004SSSE3
+ jnz NEAR L$005SSSE3
L$003no_xmm:
sub eax,edi
cmp eax,256
- jae NEAR L$005unrolled
+ jae NEAR L$006unrolled
jmp NEAR L$002loop
align 16
L$002loop:
@@ -129,7 +130,7 @@ L$002loop:
mov DWORD [28+esp],ecx
mov DWORD [32+esp],edi
align 16
-L$00600_15:
+L$00700_15:
mov ecx,edx
mov esi,DWORD [24+esp]
ror ecx,14
@@ -167,11 +168,11 @@ L$00600_15:
add ebp,4
add eax,ebx
cmp esi,3248222580
- jne NEAR L$00600_15
+ jne NEAR L$00700_15
mov ecx,DWORD [156+esp]
- jmp NEAR L$00716_63
+ jmp NEAR L$00816_63
align 16
-L$00716_63:
+L$00816_63:
mov ebx,ecx
mov esi,DWORD [104+esp]
ror ecx,11
@@ -226,7 +227,7 @@ L$00716_63:
add ebp,4
add eax,ebx
cmp esi,3329325298
- jne NEAR L$00716_63
+ jne NEAR L$00816_63
mov esi,DWORD [356+esp]
mov ebx,DWORD [8+esp]
mov ecx,DWORD [16+esp]
@@ -270,7 +271,7 @@ db 67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97
db 112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103
db 62,0
align 16
-L$005unrolled:
+L$006unrolled:
lea esp,[esp-96]
mov eax,DWORD [esi]
mov ebp,DWORD [4+esi]
@@ -287,9 +288,9 @@ L$005unrolled:
mov DWORD [20+esp],ebx
mov DWORD [24+esp],ecx
mov DWORD [28+esp],esi
- jmp NEAR L$008grand_loop
+ jmp NEAR L$009grand_loop
align 16
-L$008grand_loop:
+L$009grand_loop:
mov ebx,DWORD [edi]
mov ecx,DWORD [4+edi]
bswap ebx
@@ -3169,7 +3170,7 @@ L$008grand_loop:
mov DWORD [24+esp],ebx
mov DWORD [28+esp],ecx
cmp edi,DWORD [104+esp]
- jb NEAR L$008grand_loop
+ jb NEAR L$009grand_loop
mov esp,DWORD [108+esp]
pop edi
pop esi
@@ -3177,7 +3178,7 @@ L$008grand_loop:
pop ebp
ret
align 32
-L$004SSSE3:
+L$005SSSE3:
lea esp,[esp-96]
mov eax,DWORD [esi]
mov ebx,DWORD [4+esi]
@@ -3196,9 +3197,9 @@ L$004SSSE3:
mov DWORD [24+esp],ecx
mov DWORD [28+esp],esi
movdqa xmm7,[256+ebp]
- jmp NEAR L$009grand_ssse3
+ jmp NEAR L$010grand_ssse3
align 16
-L$009grand_ssse3:
+L$010grand_ssse3:
movdqu xmm0,[edi]
movdqu xmm1,[16+edi]
movdqu xmm2,[32+edi]
@@ -3221,9 +3222,9 @@ db 102,15,56,0,223
paddd xmm7,xmm3
movdqa [64+esp],xmm6
movdqa [80+esp],xmm7
- jmp NEAR L$010ssse3_00_47
+ jmp NEAR L$011ssse3_00_47
align 16
-L$010ssse3_00_47:
+L$011ssse3_00_47:
add ebp,64
mov ecx,edx
movdqa xmm4,xmm1
@@ -3866,7 +3867,7 @@ db 102,15,58,15,249,4
add eax,ecx
movdqa [80+esp],xmm6
cmp DWORD [64+ebp],66051
- jne NEAR L$010ssse3_00_47
+ jne NEAR L$011ssse3_00_47
mov ecx,edx
ror edx,14
mov esi,DWORD [20+esp]
@@ -4380,12 +4381,1193 @@ db 102,15,58,15,249,4
movdqa xmm7,[64+ebp]
sub ebp,192
cmp edi,DWORD [104+esp]
- jb NEAR L$009grand_ssse3
+ jb NEAR L$010grand_ssse3
mov esp,DWORD [108+esp]
pop edi
pop esi
pop ebx
pop ebp
ret
+align 32
+L$004AVX:
+ lea esp,[esp-96]
+ vzeroall
+ mov eax,DWORD [esi]
+ mov ebx,DWORD [4+esi]
+ mov ecx,DWORD [8+esi]
+ mov edi,DWORD [12+esi]
+ mov DWORD [4+esp],ebx
+ xor ebx,ecx
+ mov DWORD [8+esp],ecx
+ mov DWORD [12+esp],edi
+ mov edx,DWORD [16+esi]
+ mov edi,DWORD [20+esi]
+ mov ecx,DWORD [24+esi]
+ mov esi,DWORD [28+esi]
+ mov DWORD [20+esp],edi
+ mov edi,DWORD [100+esp]
+ mov DWORD [24+esp],ecx
+ mov DWORD [28+esp],esi
+ vmovdqa xmm7,[256+ebp]
+ jmp NEAR L$012grand_avx
+align 32
+L$012grand_avx:
+ vmovdqu xmm0,[edi]
+ vmovdqu xmm1,[16+edi]
+ vmovdqu xmm2,[32+edi]
+ vmovdqu xmm3,[48+edi]
+ add edi,64
+ vpshufb xmm0,xmm0,xmm7
+ mov DWORD [100+esp],edi
+ vpshufb xmm1,xmm1,xmm7
+ vpshufb xmm2,xmm2,xmm7
+ vpaddd xmm4,xmm0,[ebp]
+ vpshufb xmm3,xmm3,xmm7
+ vpaddd xmm5,xmm1,[16+ebp]
+ vpaddd xmm6,xmm2,[32+ebp]
+ vpaddd xmm7,xmm3,[48+ebp]
+ vmovdqa [32+esp],xmm4
+ vmovdqa [48+esp],xmm5
+ vmovdqa [64+esp],xmm6
+ vmovdqa [80+esp],xmm7
+ jmp NEAR L$013avx_00_47
+align 16
+L$013avx_00_47:
+ add ebp,64
+ vpalignr xmm4,xmm1,xmm0,4
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [20+esp]
+ vpalignr xmm7,xmm3,xmm2,4
+ xor edx,ecx
+ mov edi,DWORD [24+esp]
+ xor esi,edi
+ vpsrld xmm6,xmm4,7
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [16+esp],ecx
+ vpaddd xmm0,xmm0,xmm7
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ vpsrld xmm7,xmm4,3
+ mov ecx,eax
+ add edx,edi
+ mov edi,DWORD [4+esp]
+ vpslld xmm5,xmm4,14
+ mov esi,eax
+ shrd ecx,ecx,9
+ mov DWORD [esp],eax
+ vpxor xmm4,xmm7,xmm6
+ xor ecx,eax
+ xor eax,edi
+ add edx,DWORD [28+esp]
+ vpshufd xmm7,xmm3,250
+ shrd ecx,ecx,11
+ and ebx,eax
+ xor ecx,esi
+ vpsrld xmm6,xmm6,11
+ add edx,DWORD [32+esp]
+ xor ebx,edi
+ shrd ecx,ecx,2
+ vpxor xmm4,xmm4,xmm5
+ add ebx,edx
+ add edx,DWORD [12+esp]
+ add ebx,ecx
+ vpslld xmm5,xmm5,11
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [16+esp]
+ vpxor xmm4,xmm4,xmm6
+ xor edx,ecx
+ mov edi,DWORD [20+esp]
+ xor esi,edi
+ vpsrld xmm6,xmm7,10
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [12+esp],ecx
+ vpxor xmm4,xmm4,xmm5
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ vpsrlq xmm5,xmm7,17
+ mov ecx,ebx
+ add edx,edi
+ mov edi,DWORD [esp]
+ vpaddd xmm0,xmm0,xmm4
+ mov esi,ebx
+ shrd ecx,ecx,9
+ mov DWORD [28+esp],ebx
+ vpxor xmm6,xmm6,xmm5
+ xor ecx,ebx
+ xor ebx,edi
+ add edx,DWORD [24+esp]
+ vpsrlq xmm7,xmm7,19
+ shrd ecx,ecx,11
+ and eax,ebx
+ xor ecx,esi
+ vpxor xmm6,xmm6,xmm7
+ add edx,DWORD [36+esp]
+ xor eax,edi
+ shrd ecx,ecx,2
+ vpshufd xmm7,xmm6,132
+ add eax,edx
+ add edx,DWORD [8+esp]
+ add eax,ecx
+ vpsrldq xmm7,xmm7,8
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [12+esp]
+ vpaddd xmm0,xmm0,xmm7
+ xor edx,ecx
+ mov edi,DWORD [16+esp]
+ xor esi,edi
+ vpshufd xmm7,xmm0,80
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [8+esp],ecx
+ vpsrld xmm6,xmm7,10
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ vpsrlq xmm5,xmm7,17
+ mov ecx,eax
+ add edx,edi
+ mov edi,DWORD [28+esp]
+ vpxor xmm6,xmm6,xmm5
+ mov esi,eax
+ shrd ecx,ecx,9
+ mov DWORD [24+esp],eax
+ vpsrlq xmm7,xmm7,19
+ xor ecx,eax
+ xor eax,edi
+ add edx,DWORD [20+esp]
+ vpxor xmm6,xmm6,xmm7
+ shrd ecx,ecx,11
+ and ebx,eax
+ xor ecx,esi
+ vpshufd xmm7,xmm6,232
+ add edx,DWORD [40+esp]
+ xor ebx,edi
+ shrd ecx,ecx,2
+ vpslldq xmm7,xmm7,8
+ add ebx,edx
+ add edx,DWORD [4+esp]
+ add ebx,ecx
+ vpaddd xmm0,xmm0,xmm7
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [8+esp]
+ vpaddd xmm6,xmm0,[ebp]
+ xor edx,ecx
+ mov edi,DWORD [12+esp]
+ xor esi,edi
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [4+esp],ecx
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ mov ecx,ebx
+ add edx,edi
+ mov edi,DWORD [24+esp]
+ mov esi,ebx
+ shrd ecx,ecx,9
+ mov DWORD [20+esp],ebx
+ xor ecx,ebx
+ xor ebx,edi
+ add edx,DWORD [16+esp]
+ shrd ecx,ecx,11
+ and eax,ebx
+ xor ecx,esi
+ add edx,DWORD [44+esp]
+ xor eax,edi
+ shrd ecx,ecx,2
+ add eax,edx
+ add edx,DWORD [esp]
+ add eax,ecx
+ vmovdqa [32+esp],xmm6
+ vpalignr xmm4,xmm2,xmm1,4
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [4+esp]
+ vpalignr xmm7,xmm0,xmm3,4
+ xor edx,ecx
+ mov edi,DWORD [8+esp]
+ xor esi,edi
+ vpsrld xmm6,xmm4,7
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [esp],ecx
+ vpaddd xmm1,xmm1,xmm7
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ vpsrld xmm7,xmm4,3
+ mov ecx,eax
+ add edx,edi
+ mov edi,DWORD [20+esp]
+ vpslld xmm5,xmm4,14
+ mov esi,eax
+ shrd ecx,ecx,9
+ mov DWORD [16+esp],eax
+ vpxor xmm4,xmm7,xmm6
+ xor ecx,eax
+ xor eax,edi
+ add edx,DWORD [12+esp]
+ vpshufd xmm7,xmm0,250
+ shrd ecx,ecx,11
+ and ebx,eax
+ xor ecx,esi
+ vpsrld xmm6,xmm6,11
+ add edx,DWORD [48+esp]
+ xor ebx,edi
+ shrd ecx,ecx,2
+ vpxor xmm4,xmm4,xmm5
+ add ebx,edx
+ add edx,DWORD [28+esp]
+ add ebx,ecx
+ vpslld xmm5,xmm5,11
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [esp]
+ vpxor xmm4,xmm4,xmm6
+ xor edx,ecx
+ mov edi,DWORD [4+esp]
+ xor esi,edi
+ vpsrld xmm6,xmm7,10
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [28+esp],ecx
+ vpxor xmm4,xmm4,xmm5
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ vpsrlq xmm5,xmm7,17
+ mov ecx,ebx
+ add edx,edi
+ mov edi,DWORD [16+esp]
+ vpaddd xmm1,xmm1,xmm4
+ mov esi,ebx
+ shrd ecx,ecx,9
+ mov DWORD [12+esp],ebx
+ vpxor xmm6,xmm6,xmm5
+ xor ecx,ebx
+ xor ebx,edi
+ add edx,DWORD [8+esp]
+ vpsrlq xmm7,xmm7,19
+ shrd ecx,ecx,11
+ and eax,ebx
+ xor ecx,esi
+ vpxor xmm6,xmm6,xmm7
+ add edx,DWORD [52+esp]
+ xor eax,edi
+ shrd ecx,ecx,2
+ vpshufd xmm7,xmm6,132
+ add eax,edx
+ add edx,DWORD [24+esp]
+ add eax,ecx
+ vpsrldq xmm7,xmm7,8
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [28+esp]
+ vpaddd xmm1,xmm1,xmm7
+ xor edx,ecx
+ mov edi,DWORD [esp]
+ xor esi,edi
+ vpshufd xmm7,xmm1,80
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [24+esp],ecx
+ vpsrld xmm6,xmm7,10
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ vpsrlq xmm5,xmm7,17
+ mov ecx,eax
+ add edx,edi
+ mov edi,DWORD [12+esp]
+ vpxor xmm6,xmm6,xmm5
+ mov esi,eax
+ shrd ecx,ecx,9
+ mov DWORD [8+esp],eax
+ vpsrlq xmm7,xmm7,19
+ xor ecx,eax
+ xor eax,edi
+ add edx,DWORD [4+esp]
+ vpxor xmm6,xmm6,xmm7
+ shrd ecx,ecx,11
+ and ebx,eax
+ xor ecx,esi
+ vpshufd xmm7,xmm6,232
+ add edx,DWORD [56+esp]
+ xor ebx,edi
+ shrd ecx,ecx,2
+ vpslldq xmm7,xmm7,8
+ add ebx,edx
+ add edx,DWORD [20+esp]
+ add ebx,ecx
+ vpaddd xmm1,xmm1,xmm7
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [24+esp]
+ vpaddd xmm6,xmm1,[16+ebp]
+ xor edx,ecx
+ mov edi,DWORD [28+esp]
+ xor esi,edi
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [20+esp],ecx
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ mov ecx,ebx
+ add edx,edi
+ mov edi,DWORD [8+esp]
+ mov esi,ebx
+ shrd ecx,ecx,9
+ mov DWORD [4+esp],ebx
+ xor ecx,ebx
+ xor ebx,edi
+ add edx,DWORD [esp]
+ shrd ecx,ecx,11
+ and eax,ebx
+ xor ecx,esi
+ add edx,DWORD [60+esp]
+ xor eax,edi
+ shrd ecx,ecx,2
+ add eax,edx
+ add edx,DWORD [16+esp]
+ add eax,ecx
+ vmovdqa [48+esp],xmm6
+ vpalignr xmm4,xmm3,xmm2,4
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [20+esp]
+ vpalignr xmm7,xmm1,xmm0,4
+ xor edx,ecx
+ mov edi,DWORD [24+esp]
+ xor esi,edi
+ vpsrld xmm6,xmm4,7
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [16+esp],ecx
+ vpaddd xmm2,xmm2,xmm7
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ vpsrld xmm7,xmm4,3
+ mov ecx,eax
+ add edx,edi
+ mov edi,DWORD [4+esp]
+ vpslld xmm5,xmm4,14
+ mov esi,eax
+ shrd ecx,ecx,9
+ mov DWORD [esp],eax
+ vpxor xmm4,xmm7,xmm6
+ xor ecx,eax
+ xor eax,edi
+ add edx,DWORD [28+esp]
+ vpshufd xmm7,xmm1,250
+ shrd ecx,ecx,11
+ and ebx,eax
+ xor ecx,esi
+ vpsrld xmm6,xmm6,11
+ add edx,DWORD [64+esp]
+ xor ebx,edi
+ shrd ecx,ecx,2
+ vpxor xmm4,xmm4,xmm5
+ add ebx,edx
+ add edx,DWORD [12+esp]
+ add ebx,ecx
+ vpslld xmm5,xmm5,11
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [16+esp]
+ vpxor xmm4,xmm4,xmm6
+ xor edx,ecx
+ mov edi,DWORD [20+esp]
+ xor esi,edi
+ vpsrld xmm6,xmm7,10
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [12+esp],ecx
+ vpxor xmm4,xmm4,xmm5
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ vpsrlq xmm5,xmm7,17
+ mov ecx,ebx
+ add edx,edi
+ mov edi,DWORD [esp]
+ vpaddd xmm2,xmm2,xmm4
+ mov esi,ebx
+ shrd ecx,ecx,9
+ mov DWORD [28+esp],ebx
+ vpxor xmm6,xmm6,xmm5
+ xor ecx,ebx
+ xor ebx,edi
+ add edx,DWORD [24+esp]
+ vpsrlq xmm7,xmm7,19
+ shrd ecx,ecx,11
+ and eax,ebx
+ xor ecx,esi
+ vpxor xmm6,xmm6,xmm7
+ add edx,DWORD [68+esp]
+ xor eax,edi
+ shrd ecx,ecx,2
+ vpshufd xmm7,xmm6,132
+ add eax,edx
+ add edx,DWORD [8+esp]
+ add eax,ecx
+ vpsrldq xmm7,xmm7,8
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [12+esp]
+ vpaddd xmm2,xmm2,xmm7
+ xor edx,ecx
+ mov edi,DWORD [16+esp]
+ xor esi,edi
+ vpshufd xmm7,xmm2,80
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [8+esp],ecx
+ vpsrld xmm6,xmm7,10
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ vpsrlq xmm5,xmm7,17
+ mov ecx,eax
+ add edx,edi
+ mov edi,DWORD [28+esp]
+ vpxor xmm6,xmm6,xmm5
+ mov esi,eax
+ shrd ecx,ecx,9
+ mov DWORD [24+esp],eax
+ vpsrlq xmm7,xmm7,19
+ xor ecx,eax
+ xor eax,edi
+ add edx,DWORD [20+esp]
+ vpxor xmm6,xmm6,xmm7
+ shrd ecx,ecx,11
+ and ebx,eax
+ xor ecx,esi
+ vpshufd xmm7,xmm6,232
+ add edx,DWORD [72+esp]
+ xor ebx,edi
+ shrd ecx,ecx,2
+ vpslldq xmm7,xmm7,8
+ add ebx,edx
+ add edx,DWORD [4+esp]
+ add ebx,ecx
+ vpaddd xmm2,xmm2,xmm7
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [8+esp]
+ vpaddd xmm6,xmm2,[32+ebp]
+ xor edx,ecx
+ mov edi,DWORD [12+esp]
+ xor esi,edi
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [4+esp],ecx
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ mov ecx,ebx
+ add edx,edi
+ mov edi,DWORD [24+esp]
+ mov esi,ebx
+ shrd ecx,ecx,9
+ mov DWORD [20+esp],ebx
+ xor ecx,ebx
+ xor ebx,edi
+ add edx,DWORD [16+esp]
+ shrd ecx,ecx,11
+ and eax,ebx
+ xor ecx,esi
+ add edx,DWORD [76+esp]
+ xor eax,edi
+ shrd ecx,ecx,2
+ add eax,edx
+ add edx,DWORD [esp]
+ add eax,ecx
+ vmovdqa [64+esp],xmm6
+ vpalignr xmm4,xmm0,xmm3,4
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [4+esp]
+ vpalignr xmm7,xmm2,xmm1,4
+ xor edx,ecx
+ mov edi,DWORD [8+esp]
+ xor esi,edi
+ vpsrld xmm6,xmm4,7
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [esp],ecx
+ vpaddd xmm3,xmm3,xmm7
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ vpsrld xmm7,xmm4,3
+ mov ecx,eax
+ add edx,edi
+ mov edi,DWORD [20+esp]
+ vpslld xmm5,xmm4,14
+ mov esi,eax
+ shrd ecx,ecx,9
+ mov DWORD [16+esp],eax
+ vpxor xmm4,xmm7,xmm6
+ xor ecx,eax
+ xor eax,edi
+ add edx,DWORD [12+esp]
+ vpshufd xmm7,xmm2,250
+ shrd ecx,ecx,11
+ and ebx,eax
+ xor ecx,esi
+ vpsrld xmm6,xmm6,11
+ add edx,DWORD [80+esp]
+ xor ebx,edi
+ shrd ecx,ecx,2
+ vpxor xmm4,xmm4,xmm5
+ add ebx,edx
+ add edx,DWORD [28+esp]
+ add ebx,ecx
+ vpslld xmm5,xmm5,11
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [esp]
+ vpxor xmm4,xmm4,xmm6
+ xor edx,ecx
+ mov edi,DWORD [4+esp]
+ xor esi,edi
+ vpsrld xmm6,xmm7,10
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [28+esp],ecx
+ vpxor xmm4,xmm4,xmm5
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ vpsrlq xmm5,xmm7,17
+ mov ecx,ebx
+ add edx,edi
+ mov edi,DWORD [16+esp]
+ vpaddd xmm3,xmm3,xmm4
+ mov esi,ebx
+ shrd ecx,ecx,9
+ mov DWORD [12+esp],ebx
+ vpxor xmm6,xmm6,xmm5
+ xor ecx,ebx
+ xor ebx,edi
+ add edx,DWORD [8+esp]
+ vpsrlq xmm7,xmm7,19
+ shrd ecx,ecx,11
+ and eax,ebx
+ xor ecx,esi
+ vpxor xmm6,xmm6,xmm7
+ add edx,DWORD [84+esp]
+ xor eax,edi
+ shrd ecx,ecx,2
+ vpshufd xmm7,xmm6,132
+ add eax,edx
+ add edx,DWORD [24+esp]
+ add eax,ecx
+ vpsrldq xmm7,xmm7,8
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [28+esp]
+ vpaddd xmm3,xmm3,xmm7
+ xor edx,ecx
+ mov edi,DWORD [esp]
+ xor esi,edi
+ vpshufd xmm7,xmm3,80
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [24+esp],ecx
+ vpsrld xmm6,xmm7,10
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ vpsrlq xmm5,xmm7,17
+ mov ecx,eax
+ add edx,edi
+ mov edi,DWORD [12+esp]
+ vpxor xmm6,xmm6,xmm5
+ mov esi,eax
+ shrd ecx,ecx,9
+ mov DWORD [8+esp],eax
+ vpsrlq xmm7,xmm7,19
+ xor ecx,eax
+ xor eax,edi
+ add edx,DWORD [4+esp]
+ vpxor xmm6,xmm6,xmm7
+ shrd ecx,ecx,11
+ and ebx,eax
+ xor ecx,esi
+ vpshufd xmm7,xmm6,232
+ add edx,DWORD [88+esp]
+ xor ebx,edi
+ shrd ecx,ecx,2
+ vpslldq xmm7,xmm7,8
+ add ebx,edx
+ add edx,DWORD [20+esp]
+ add ebx,ecx
+ vpaddd xmm3,xmm3,xmm7
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [24+esp]
+ vpaddd xmm6,xmm3,[48+ebp]
+ xor edx,ecx
+ mov edi,DWORD [28+esp]
+ xor esi,edi
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [20+esp],ecx
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ mov ecx,ebx
+ add edx,edi
+ mov edi,DWORD [8+esp]
+ mov esi,ebx
+ shrd ecx,ecx,9
+ mov DWORD [4+esp],ebx
+ xor ecx,ebx
+ xor ebx,edi
+ add edx,DWORD [esp]
+ shrd ecx,ecx,11
+ and eax,ebx
+ xor ecx,esi
+ add edx,DWORD [92+esp]
+ xor eax,edi
+ shrd ecx,ecx,2
+ add eax,edx
+ add edx,DWORD [16+esp]
+ add eax,ecx
+ vmovdqa [80+esp],xmm6
+ cmp DWORD [64+ebp],66051
+ jne NEAR L$013avx_00_47
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [20+esp]
+ xor edx,ecx
+ mov edi,DWORD [24+esp]
+ xor esi,edi
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [16+esp],ecx
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ mov ecx,eax
+ add edx,edi
+ mov edi,DWORD [4+esp]
+ mov esi,eax
+ shrd ecx,ecx,9
+ mov DWORD [esp],eax
+ xor ecx,eax
+ xor eax,edi
+ add edx,DWORD [28+esp]
+ shrd ecx,ecx,11
+ and ebx,eax
+ xor ecx,esi
+ add edx,DWORD [32+esp]
+ xor ebx,edi
+ shrd ecx,ecx,2
+ add ebx,edx
+ add edx,DWORD [12+esp]
+ add ebx,ecx
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [16+esp]
+ xor edx,ecx
+ mov edi,DWORD [20+esp]
+ xor esi,edi
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [12+esp],ecx
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ mov ecx,ebx
+ add edx,edi
+ mov edi,DWORD [esp]
+ mov esi,ebx
+ shrd ecx,ecx,9
+ mov DWORD [28+esp],ebx
+ xor ecx,ebx
+ xor ebx,edi
+ add edx,DWORD [24+esp]
+ shrd ecx,ecx,11
+ and eax,ebx
+ xor ecx,esi
+ add edx,DWORD [36+esp]
+ xor eax,edi
+ shrd ecx,ecx,2
+ add eax,edx
+ add edx,DWORD [8+esp]
+ add eax,ecx
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [12+esp]
+ xor edx,ecx
+ mov edi,DWORD [16+esp]
+ xor esi,edi
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [8+esp],ecx
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ mov ecx,eax
+ add edx,edi
+ mov edi,DWORD [28+esp]
+ mov esi,eax
+ shrd ecx,ecx,9
+ mov DWORD [24+esp],eax
+ xor ecx,eax
+ xor eax,edi
+ add edx,DWORD [20+esp]
+ shrd ecx,ecx,11
+ and ebx,eax
+ xor ecx,esi
+ add edx,DWORD [40+esp]
+ xor ebx,edi
+ shrd ecx,ecx,2
+ add ebx,edx
+ add edx,DWORD [4+esp]
+ add ebx,ecx
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [8+esp]
+ xor edx,ecx
+ mov edi,DWORD [12+esp]
+ xor esi,edi
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [4+esp],ecx
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ mov ecx,ebx
+ add edx,edi
+ mov edi,DWORD [24+esp]
+ mov esi,ebx
+ shrd ecx,ecx,9
+ mov DWORD [20+esp],ebx
+ xor ecx,ebx
+ xor ebx,edi
+ add edx,DWORD [16+esp]
+ shrd ecx,ecx,11
+ and eax,ebx
+ xor ecx,esi
+ add edx,DWORD [44+esp]
+ xor eax,edi
+ shrd ecx,ecx,2
+ add eax,edx
+ add edx,DWORD [esp]
+ add eax,ecx
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [4+esp]
+ xor edx,ecx
+ mov edi,DWORD [8+esp]
+ xor esi,edi
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [esp],ecx
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ mov ecx,eax
+ add edx,edi
+ mov edi,DWORD [20+esp]
+ mov esi,eax
+ shrd ecx,ecx,9
+ mov DWORD [16+esp],eax
+ xor ecx,eax
+ xor eax,edi
+ add edx,DWORD [12+esp]
+ shrd ecx,ecx,11
+ and ebx,eax
+ xor ecx,esi
+ add edx,DWORD [48+esp]
+ xor ebx,edi
+ shrd ecx,ecx,2
+ add ebx,edx
+ add edx,DWORD [28+esp]
+ add ebx,ecx
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [esp]
+ xor edx,ecx
+ mov edi,DWORD [4+esp]
+ xor esi,edi
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [28+esp],ecx
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ mov ecx,ebx
+ add edx,edi
+ mov edi,DWORD [16+esp]
+ mov esi,ebx
+ shrd ecx,ecx,9
+ mov DWORD [12+esp],ebx
+ xor ecx,ebx
+ xor ebx,edi
+ add edx,DWORD [8+esp]
+ shrd ecx,ecx,11
+ and eax,ebx
+ xor ecx,esi
+ add edx,DWORD [52+esp]
+ xor eax,edi
+ shrd ecx,ecx,2
+ add eax,edx
+ add edx,DWORD [24+esp]
+ add eax,ecx
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [28+esp]
+ xor edx,ecx
+ mov edi,DWORD [esp]
+ xor esi,edi
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [24+esp],ecx
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ mov ecx,eax
+ add edx,edi
+ mov edi,DWORD [12+esp]
+ mov esi,eax
+ shrd ecx,ecx,9
+ mov DWORD [8+esp],eax
+ xor ecx,eax
+ xor eax,edi
+ add edx,DWORD [4+esp]
+ shrd ecx,ecx,11
+ and ebx,eax
+ xor ecx,esi
+ add edx,DWORD [56+esp]
+ xor ebx,edi
+ shrd ecx,ecx,2
+ add ebx,edx
+ add edx,DWORD [20+esp]
+ add ebx,ecx
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [24+esp]
+ xor edx,ecx
+ mov edi,DWORD [28+esp]
+ xor esi,edi
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [20+esp],ecx
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ mov ecx,ebx
+ add edx,edi
+ mov edi,DWORD [8+esp]
+ mov esi,ebx
+ shrd ecx,ecx,9
+ mov DWORD [4+esp],ebx
+ xor ecx,ebx
+ xor ebx,edi
+ add edx,DWORD [esp]
+ shrd ecx,ecx,11
+ and eax,ebx
+ xor ecx,esi
+ add edx,DWORD [60+esp]
+ xor eax,edi
+ shrd ecx,ecx,2
+ add eax,edx
+ add edx,DWORD [16+esp]
+ add eax,ecx
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [20+esp]
+ xor edx,ecx
+ mov edi,DWORD [24+esp]
+ xor esi,edi
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [16+esp],ecx
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ mov ecx,eax
+ add edx,edi
+ mov edi,DWORD [4+esp]
+ mov esi,eax
+ shrd ecx,ecx,9
+ mov DWORD [esp],eax
+ xor ecx,eax
+ xor eax,edi
+ add edx,DWORD [28+esp]
+ shrd ecx,ecx,11
+ and ebx,eax
+ xor ecx,esi
+ add edx,DWORD [64+esp]
+ xor ebx,edi
+ shrd ecx,ecx,2
+ add ebx,edx
+ add edx,DWORD [12+esp]
+ add ebx,ecx
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [16+esp]
+ xor edx,ecx
+ mov edi,DWORD [20+esp]
+ xor esi,edi
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [12+esp],ecx
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ mov ecx,ebx
+ add edx,edi
+ mov edi,DWORD [esp]
+ mov esi,ebx
+ shrd ecx,ecx,9
+ mov DWORD [28+esp],ebx
+ xor ecx,ebx
+ xor ebx,edi
+ add edx,DWORD [24+esp]
+ shrd ecx,ecx,11
+ and eax,ebx
+ xor ecx,esi
+ add edx,DWORD [68+esp]
+ xor eax,edi
+ shrd ecx,ecx,2
+ add eax,edx
+ add edx,DWORD [8+esp]
+ add eax,ecx
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [12+esp]
+ xor edx,ecx
+ mov edi,DWORD [16+esp]
+ xor esi,edi
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [8+esp],ecx
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ mov ecx,eax
+ add edx,edi
+ mov edi,DWORD [28+esp]
+ mov esi,eax
+ shrd ecx,ecx,9
+ mov DWORD [24+esp],eax
+ xor ecx,eax
+ xor eax,edi
+ add edx,DWORD [20+esp]
+ shrd ecx,ecx,11
+ and ebx,eax
+ xor ecx,esi
+ add edx,DWORD [72+esp]
+ xor ebx,edi
+ shrd ecx,ecx,2
+ add ebx,edx
+ add edx,DWORD [4+esp]
+ add ebx,ecx
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [8+esp]
+ xor edx,ecx
+ mov edi,DWORD [12+esp]
+ xor esi,edi
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [4+esp],ecx
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ mov ecx,ebx
+ add edx,edi
+ mov edi,DWORD [24+esp]
+ mov esi,ebx
+ shrd ecx,ecx,9
+ mov DWORD [20+esp],ebx
+ xor ecx,ebx
+ xor ebx,edi
+ add edx,DWORD [16+esp]
+ shrd ecx,ecx,11
+ and eax,ebx
+ xor ecx,esi
+ add edx,DWORD [76+esp]
+ xor eax,edi
+ shrd ecx,ecx,2
+ add eax,edx
+ add edx,DWORD [esp]
+ add eax,ecx
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [4+esp]
+ xor edx,ecx
+ mov edi,DWORD [8+esp]
+ xor esi,edi
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [esp],ecx
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ mov ecx,eax
+ add edx,edi
+ mov edi,DWORD [20+esp]
+ mov esi,eax
+ shrd ecx,ecx,9
+ mov DWORD [16+esp],eax
+ xor ecx,eax
+ xor eax,edi
+ add edx,DWORD [12+esp]
+ shrd ecx,ecx,11
+ and ebx,eax
+ xor ecx,esi
+ add edx,DWORD [80+esp]
+ xor ebx,edi
+ shrd ecx,ecx,2
+ add ebx,edx
+ add edx,DWORD [28+esp]
+ add ebx,ecx
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [esp]
+ xor edx,ecx
+ mov edi,DWORD [4+esp]
+ xor esi,edi
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [28+esp],ecx
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ mov ecx,ebx
+ add edx,edi
+ mov edi,DWORD [16+esp]
+ mov esi,ebx
+ shrd ecx,ecx,9
+ mov DWORD [12+esp],ebx
+ xor ecx,ebx
+ xor ebx,edi
+ add edx,DWORD [8+esp]
+ shrd ecx,ecx,11
+ and eax,ebx
+ xor ecx,esi
+ add edx,DWORD [84+esp]
+ xor eax,edi
+ shrd ecx,ecx,2
+ add eax,edx
+ add edx,DWORD [24+esp]
+ add eax,ecx
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [28+esp]
+ xor edx,ecx
+ mov edi,DWORD [esp]
+ xor esi,edi
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [24+esp],ecx
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ mov ecx,eax
+ add edx,edi
+ mov edi,DWORD [12+esp]
+ mov esi,eax
+ shrd ecx,ecx,9
+ mov DWORD [8+esp],eax
+ xor ecx,eax
+ xor eax,edi
+ add edx,DWORD [4+esp]
+ shrd ecx,ecx,11
+ and ebx,eax
+ xor ecx,esi
+ add edx,DWORD [88+esp]
+ xor ebx,edi
+ shrd ecx,ecx,2
+ add ebx,edx
+ add edx,DWORD [20+esp]
+ add ebx,ecx
+ mov ecx,edx
+ shrd edx,edx,14
+ mov esi,DWORD [24+esp]
+ xor edx,ecx
+ mov edi,DWORD [28+esp]
+ xor esi,edi
+ shrd edx,edx,5
+ and esi,ecx
+ mov DWORD [20+esp],ecx
+ xor edx,ecx
+ xor edi,esi
+ shrd edx,edx,6
+ mov ecx,ebx
+ add edx,edi
+ mov edi,DWORD [8+esp]
+ mov esi,ebx
+ shrd ecx,ecx,9
+ mov DWORD [4+esp],ebx
+ xor ecx,ebx
+ xor ebx,edi
+ add edx,DWORD [esp]
+ shrd ecx,ecx,11
+ and eax,ebx
+ xor ecx,esi
+ add edx,DWORD [92+esp]
+ xor eax,edi
+ shrd ecx,ecx,2
+ add eax,edx
+ add edx,DWORD [16+esp]
+ add eax,ecx
+ mov esi,DWORD [96+esp]
+ xor ebx,edi
+ mov ecx,DWORD [12+esp]
+ add eax,DWORD [esi]
+ add ebx,DWORD [4+esi]
+ add edi,DWORD [8+esi]
+ add ecx,DWORD [12+esi]
+ mov DWORD [esi],eax
+ mov DWORD [4+esi],ebx
+ mov DWORD [8+esi],edi
+ mov DWORD [12+esi],ecx
+ mov DWORD [4+esp],ebx
+ xor ebx,edi
+ mov DWORD [8+esp],edi
+ mov DWORD [12+esp],ecx
+ mov edi,DWORD [20+esp]
+ mov ecx,DWORD [24+esp]
+ add edx,DWORD [16+esi]
+ add edi,DWORD [20+esi]
+ add ecx,DWORD [24+esi]
+ mov DWORD [16+esi],edx
+ mov DWORD [20+esi],edi
+ mov DWORD [20+esp],edi
+ mov edi,DWORD [28+esp]
+ mov DWORD [24+esi],ecx
+ add edi,DWORD [28+esi]
+ mov DWORD [24+esp],ecx
+ mov DWORD [28+esi],edi
+ mov DWORD [28+esp],edi
+ mov edi,DWORD [100+esp]
+ vmovdqa xmm7,[64+ebp]
+ sub ebp,192
+ cmp edi,DWORD [104+esp]
+ jb NEAR L$012grand_avx
+ mov esp,DWORD [108+esp]
+ vzeroall
+ pop edi
+ pop esi
+ pop ebx
+ pop ebp
+ ret
segment .bss
common _OPENSSL_ia32cap_P 16
diff --git a/win-x86_64/crypto/bn/x86_64-mont5.asm b/win-x86_64/crypto/bn/x86_64-mont5.asm
index 284318a..560b384 100644
--- a/win-x86_64/crypto/bn/x86_64-mont5.asm
+++ b/win-x86_64/crypto/bn/x86_64-mont5.asm
@@ -1616,6 +1616,15 @@ $L$8x_tail:
ALIGN 32
$L$8x_tail_done:
add r8,QWORD[rdx]
+ adc r9,0
+ adc r10,0
+ adc r11,0
+ adc r12,0
+ adc r13,0
+ adc r14,0
+ adc r15,0
+
+
xor rax,rax
neg rsi
diff --git a/win-x86_64/crypto/ec/p256-x86_64-asm.asm b/win-x86_64/crypto/ec/p256-x86_64-asm.asm
index c9789f5..45ba686 100644
--- a/win-x86_64/crypto/ec/p256-x86_64-asm.asm
+++ b/win-x86_64/crypto/ec/p256-x86_64-asm.asm
@@ -11,10 +11,6 @@ ALIGN 64
$L$poly:
DQ 0xffffffffffffffff,0x00000000ffffffff,0x0000000000000000,0xffffffff00000001
-
-$L$RR:
- DQ 0x0000000000000003,0xfffffffbffffffff,0xfffffffffffffffe,0x00000004fffffffd
-
$L$One:
DD 1,1,1,1,1,1,1,1
$L$Two:
@@ -24,7 +20,6 @@ $L$Three:
$L$ONE_mont:
DQ 0x0000000000000001,0xffffffff00000000,0xffffffffffffffff,0x00000000fffffffe
-global ecp_nistz256_mul_by_2
ALIGN 64
ecp_nistz256_mul_by_2:
@@ -78,266 +73,6 @@ $L$SEH_end_ecp_nistz256_mul_by_2:
-global ecp_nistz256_div_by_2
-
-ALIGN 32
-ecp_nistz256_div_by_2:
- mov QWORD[8+rsp],rdi ;WIN64 prologue
- mov QWORD[16+rsp],rsi
- mov rax,rsp
-$L$SEH_begin_ecp_nistz256_div_by_2:
- mov rdi,rcx
- mov rsi,rdx
-
-
- push r12
- push r13
-
- mov r8,QWORD[rsi]
- mov r9,QWORD[8+rsi]
- mov r10,QWORD[16+rsi]
- mov rax,r8
- mov r11,QWORD[24+rsi]
- lea rsi,[$L$poly]
-
- mov rdx,r9
- xor r13,r13
- add r8,QWORD[rsi]
- mov rcx,r10
- adc r9,QWORD[8+rsi]
- adc r10,QWORD[16+rsi]
- mov r12,r11
- adc r11,QWORD[24+rsi]
- adc r13,0
- xor rsi,rsi
- test rax,1
-
- cmovz r8,rax
- cmovz r9,rdx
- cmovz r10,rcx
- cmovz r11,r12
- cmovz r13,rsi
-
- mov rax,r9
- shr r8,1
- shl rax,63
- mov rdx,r10
- shr r9,1
- or r8,rax
- shl rdx,63
- mov rcx,r11
- shr r10,1
- or r9,rdx
- shl rcx,63
- shr r11,1
- shl r13,63
- or r10,rcx
- or r11,r13
-
- mov QWORD[rdi],r8
- mov QWORD[8+rdi],r9
- mov QWORD[16+rdi],r10
- mov QWORD[24+rdi],r11
-
- pop r13
- pop r12
- mov rdi,QWORD[8+rsp] ;WIN64 epilogue
- mov rsi,QWORD[16+rsp]
- DB 0F3h,0C3h ;repret
-$L$SEH_end_ecp_nistz256_div_by_2:
-
-
-
-global ecp_nistz256_mul_by_3
-
-ALIGN 32
-ecp_nistz256_mul_by_3:
- mov QWORD[8+rsp],rdi ;WIN64 prologue
- mov QWORD[16+rsp],rsi
- mov rax,rsp
-$L$SEH_begin_ecp_nistz256_mul_by_3:
- mov rdi,rcx
- mov rsi,rdx
-
-
- push r12
- push r13
-
- mov r8,QWORD[rsi]
- xor r13,r13
- mov r9,QWORD[8+rsi]
- add r8,r8
- mov r10,QWORD[16+rsi]
- adc r9,r9
- mov r11,QWORD[24+rsi]
- mov rax,r8
- adc r10,r10
- adc r11,r11
- mov rdx,r9
- adc r13,0
-
- sub r8,-1
- mov rcx,r10
- sbb r9,QWORD[(($L$poly+8))]
- sbb r10,0
- mov r12,r11
- sbb r11,QWORD[(($L$poly+24))]
- test r13,r13
-
- cmovz r8,rax
- cmovz r9,rdx
- cmovz r10,rcx
- cmovz r11,r12
-
- xor r13,r13
- add r8,QWORD[rsi]
- adc r9,QWORD[8+rsi]
- mov rax,r8
- adc r10,QWORD[16+rsi]
- adc r11,QWORD[24+rsi]
- mov rdx,r9
- adc r13,0
-
- sub r8,-1
- mov rcx,r10
- sbb r9,QWORD[(($L$poly+8))]
- sbb r10,0
- mov r12,r11
- sbb r11,QWORD[(($L$poly+24))]
- test r13,r13
-
- cmovz r8,rax
- cmovz r9,rdx
- mov QWORD[rdi],r8
- cmovz r10,rcx
- mov QWORD[8+rdi],r9
- cmovz r11,r12
- mov QWORD[16+rdi],r10
- mov QWORD[24+rdi],r11
-
- pop r13
- pop r12
- mov rdi,QWORD[8+rsp] ;WIN64 epilogue
- mov rsi,QWORD[16+rsp]
- DB 0F3h,0C3h ;repret
-$L$SEH_end_ecp_nistz256_mul_by_3:
-
-
-
-global ecp_nistz256_add
-
-ALIGN 32
-ecp_nistz256_add:
- mov QWORD[8+rsp],rdi ;WIN64 prologue
- mov QWORD[16+rsp],rsi
- mov rax,rsp
-$L$SEH_begin_ecp_nistz256_add:
- mov rdi,rcx
- mov rsi,rdx
- mov rdx,r8
-
-
- push r12
- push r13
-
- mov r8,QWORD[rsi]
- xor r13,r13
- mov r9,QWORD[8+rsi]
- mov r10,QWORD[16+rsi]
- mov r11,QWORD[24+rsi]
- lea rsi,[$L$poly]
-
- add r8,QWORD[rdx]
- adc r9,QWORD[8+rdx]
- mov rax,r8
- adc r10,QWORD[16+rdx]
- adc r11,QWORD[24+rdx]
- mov rdx,r9
- adc r13,0
-
- sub r8,QWORD[rsi]
- mov rcx,r10
- sbb r9,QWORD[8+rsi]
- sbb r10,QWORD[16+rsi]
- mov r12,r11
- sbb r11,QWORD[24+rsi]
- test r13,r13
-
- cmovz r8,rax
- cmovz r9,rdx
- mov QWORD[rdi],r8
- cmovz r10,rcx
- mov QWORD[8+rdi],r9
- cmovz r11,r12
- mov QWORD[16+rdi],r10
- mov QWORD[24+rdi],r11
-
- pop r13
- pop r12
- mov rdi,QWORD[8+rsp] ;WIN64 epilogue
- mov rsi,QWORD[16+rsp]
- DB 0F3h,0C3h ;repret
-$L$SEH_end_ecp_nistz256_add:
-
-
-
-global ecp_nistz256_sub
-
-ALIGN 32
-ecp_nistz256_sub:
- mov QWORD[8+rsp],rdi ;WIN64 prologue
- mov QWORD[16+rsp],rsi
- mov rax,rsp
-$L$SEH_begin_ecp_nistz256_sub:
- mov rdi,rcx
- mov rsi,rdx
- mov rdx,r8
-
-
- push r12
- push r13
-
- mov r8,QWORD[rsi]
- xor r13,r13
- mov r9,QWORD[8+rsi]
- mov r10,QWORD[16+rsi]
- mov r11,QWORD[24+rsi]
- lea rsi,[$L$poly]
-
- sub r8,QWORD[rdx]
- sbb r9,QWORD[8+rdx]
- mov rax,r8
- sbb r10,QWORD[16+rdx]
- sbb r11,QWORD[24+rdx]
- mov rdx,r9
- sbb r13,0
-
- add r8,QWORD[rsi]
- mov rcx,r10
- adc r9,QWORD[8+rsi]
- adc r10,QWORD[16+rsi]
- mov r12,r11
- adc r11,QWORD[24+rsi]
- test r13,r13
-
- cmovz r8,rax
- cmovz r9,rdx
- mov QWORD[rdi],r8
- cmovz r10,rcx
- mov QWORD[8+rdi],r9
- cmovz r11,r12
- mov QWORD[16+rdi],r10
- mov QWORD[24+rdi],r11
-
- pop r13
- pop r12
- mov rdi,QWORD[8+rsp] ;WIN64 epilogue
- mov rsi,QWORD[16+rsp]
- DB 0F3h,0C3h ;repret
-$L$SEH_end_ecp_nistz256_sub:
-
-
-
global ecp_nistz256_neg
ALIGN 32
@@ -395,26 +130,6 @@ $L$SEH_end_ecp_nistz256_neg:
-global ecp_nistz256_to_mont
-
-ALIGN 32
-ecp_nistz256_to_mont:
- mov QWORD[8+rsp],rdi ;WIN64 prologue
- mov QWORD[16+rsp],rsi
- mov rax,rsp
-$L$SEH_begin_ecp_nistz256_to_mont:
- mov rdi,rcx
- mov rsi,rdx
-
-
- lea rdx,[$L$RR]
- jmp NEAR $L$mul_mont
-$L$SEH_end_ecp_nistz256_to_mont:
-
-
-
-
-
global ecp_nistz256_mul_mont
diff --git a/win-x86_64/crypto/rc4/rc4-md5-x86_64.asm b/win-x86_64/crypto/rc4/rc4-md5-x86_64.asm
deleted file mode 100644
index f1ea965..0000000
--- a/win-x86_64/crypto/rc4/rc4-md5-x86_64.asm
+++ /dev/null
@@ -1,1372 +0,0 @@
-default rel
-%define XMMWORD
-%define YMMWORD
-%define ZMMWORD
-section .text code align=64
-
-ALIGN 16
-
-global rc4_md5_enc
-
-rc4_md5_enc:
- mov QWORD[8+rsp],rdi ;WIN64 prologue
- mov QWORD[16+rsp],rsi
- mov rax,rsp
-$L$SEH_begin_rc4_md5_enc:
- mov rdi,rcx
- mov rsi,rdx
- mov rdx,r8
- mov rcx,r9
- mov r8,QWORD[40+rsp]
- mov r9,QWORD[48+rsp]
-
-
- cmp r9,0
- je NEAR $L$abort
- push rbx
- push rbp
- push r12
- push r13
- push r14
- push r15
- sub rsp,40
-$L$body:
- mov r11,rcx
- mov r12,r9
- mov r13,rsi
- mov r14,rdx
- mov r15,r8
- xor rbp,rbp
- xor rcx,rcx
-
- lea rdi,[8+rdi]
- mov bpl,BYTE[((-8))+rdi]
- mov cl,BYTE[((-4))+rdi]
-
- inc bpl
- sub r14,r13
- mov eax,DWORD[rbp*4+rdi]
- add cl,al
- lea rsi,[rbp*4+rdi]
- shl r12,6
- add r12,r15
- mov QWORD[16+rsp],r12
-
- mov QWORD[24+rsp],r11
- mov r8d,DWORD[r11]
- mov r9d,DWORD[4+r11]
- mov r10d,DWORD[8+r11]
- mov r11d,DWORD[12+r11]
- jmp NEAR $L$oop
-
-ALIGN 16
-$L$oop:
- mov DWORD[rsp],r8d
- mov DWORD[4+rsp],r9d
- mov DWORD[8+rsp],r10d
- mov r12d,r11d
- mov DWORD[12+rsp],r11d
- pxor xmm0,xmm0
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r10d
- mov DWORD[rcx*4+rdi],eax
- and r12d,r9d
- add r8d,DWORD[r15]
- add al,dl
- mov ebx,DWORD[4+rsi]
- add r8d,3614090360
- xor r12d,r11d
- movzx eax,al
- mov DWORD[rsi],edx
- add r8d,r12d
- add cl,bl
- rol r8d,7
- mov r12d,r10d
- movd xmm0,DWORD[rax*4+rdi]
-
- add r8d,r9d
- pxor xmm1,xmm1
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r9d
- mov DWORD[rcx*4+rdi],ebx
- and r12d,r8d
- add r11d,DWORD[4+r15]
- add bl,dl
- mov eax,DWORD[8+rsi]
- add r11d,3905402710
- xor r12d,r10d
- movzx ebx,bl
- mov DWORD[4+rsi],edx
- add r11d,r12d
- add cl,al
- rol r11d,12
- mov r12d,r9d
- movd xmm1,DWORD[rbx*4+rdi]
-
- add r11d,r8d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r8d
- mov DWORD[rcx*4+rdi],eax
- and r12d,r11d
- add r10d,DWORD[8+r15]
- add al,dl
- mov ebx,DWORD[12+rsi]
- add r10d,606105819
- xor r12d,r9d
- movzx eax,al
- mov DWORD[8+rsi],edx
- add r10d,r12d
- add cl,bl
- rol r10d,17
- mov r12d,r8d
- pinsrw xmm0,WORD[rax*4+rdi],1
-
- add r10d,r11d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r11d
- mov DWORD[rcx*4+rdi],ebx
- and r12d,r10d
- add r9d,DWORD[12+r15]
- add bl,dl
- mov eax,DWORD[16+rsi]
- add r9d,3250441966
- xor r12d,r8d
- movzx ebx,bl
- mov DWORD[12+rsi],edx
- add r9d,r12d
- add cl,al
- rol r9d,22
- mov r12d,r11d
- pinsrw xmm1,WORD[rbx*4+rdi],1
-
- add r9d,r10d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r10d
- mov DWORD[rcx*4+rdi],eax
- and r12d,r9d
- add r8d,DWORD[16+r15]
- add al,dl
- mov ebx,DWORD[20+rsi]
- add r8d,4118548399
- xor r12d,r11d
- movzx eax,al
- mov DWORD[16+rsi],edx
- add r8d,r12d
- add cl,bl
- rol r8d,7
- mov r12d,r10d
- pinsrw xmm0,WORD[rax*4+rdi],2
-
- add r8d,r9d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r9d
- mov DWORD[rcx*4+rdi],ebx
- and r12d,r8d
- add r11d,DWORD[20+r15]
- add bl,dl
- mov eax,DWORD[24+rsi]
- add r11d,1200080426
- xor r12d,r10d
- movzx ebx,bl
- mov DWORD[20+rsi],edx
- add r11d,r12d
- add cl,al
- rol r11d,12
- mov r12d,r9d
- pinsrw xmm1,WORD[rbx*4+rdi],2
-
- add r11d,r8d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r8d
- mov DWORD[rcx*4+rdi],eax
- and r12d,r11d
- add r10d,DWORD[24+r15]
- add al,dl
- mov ebx,DWORD[28+rsi]
- add r10d,2821735955
- xor r12d,r9d
- movzx eax,al
- mov DWORD[24+rsi],edx
- add r10d,r12d
- add cl,bl
- rol r10d,17
- mov r12d,r8d
- pinsrw xmm0,WORD[rax*4+rdi],3
-
- add r10d,r11d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r11d
- mov DWORD[rcx*4+rdi],ebx
- and r12d,r10d
- add r9d,DWORD[28+r15]
- add bl,dl
- mov eax,DWORD[32+rsi]
- add r9d,4249261313
- xor r12d,r8d
- movzx ebx,bl
- mov DWORD[28+rsi],edx
- add r9d,r12d
- add cl,al
- rol r9d,22
- mov r12d,r11d
- pinsrw xmm1,WORD[rbx*4+rdi],3
-
- add r9d,r10d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r10d
- mov DWORD[rcx*4+rdi],eax
- and r12d,r9d
- add r8d,DWORD[32+r15]
- add al,dl
- mov ebx,DWORD[36+rsi]
- add r8d,1770035416
- xor r12d,r11d
- movzx eax,al
- mov DWORD[32+rsi],edx
- add r8d,r12d
- add cl,bl
- rol r8d,7
- mov r12d,r10d
- pinsrw xmm0,WORD[rax*4+rdi],4
-
- add r8d,r9d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r9d
- mov DWORD[rcx*4+rdi],ebx
- and r12d,r8d
- add r11d,DWORD[36+r15]
- add bl,dl
- mov eax,DWORD[40+rsi]
- add r11d,2336552879
- xor r12d,r10d
- movzx ebx,bl
- mov DWORD[36+rsi],edx
- add r11d,r12d
- add cl,al
- rol r11d,12
- mov r12d,r9d
- pinsrw xmm1,WORD[rbx*4+rdi],4
-
- add r11d,r8d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r8d
- mov DWORD[rcx*4+rdi],eax
- and r12d,r11d
- add r10d,DWORD[40+r15]
- add al,dl
- mov ebx,DWORD[44+rsi]
- add r10d,4294925233
- xor r12d,r9d
- movzx eax,al
- mov DWORD[40+rsi],edx
- add r10d,r12d
- add cl,bl
- rol r10d,17
- mov r12d,r8d
- pinsrw xmm0,WORD[rax*4+rdi],5
-
- add r10d,r11d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r11d
- mov DWORD[rcx*4+rdi],ebx
- and r12d,r10d
- add r9d,DWORD[44+r15]
- add bl,dl
- mov eax,DWORD[48+rsi]
- add r9d,2304563134
- xor r12d,r8d
- movzx ebx,bl
- mov DWORD[44+rsi],edx
- add r9d,r12d
- add cl,al
- rol r9d,22
- mov r12d,r11d
- pinsrw xmm1,WORD[rbx*4+rdi],5
-
- add r9d,r10d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r10d
- mov DWORD[rcx*4+rdi],eax
- and r12d,r9d
- add r8d,DWORD[48+r15]
- add al,dl
- mov ebx,DWORD[52+rsi]
- add r8d,1804603682
- xor r12d,r11d
- movzx eax,al
- mov DWORD[48+rsi],edx
- add r8d,r12d
- add cl,bl
- rol r8d,7
- mov r12d,r10d
- pinsrw xmm0,WORD[rax*4+rdi],6
-
- add r8d,r9d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r9d
- mov DWORD[rcx*4+rdi],ebx
- and r12d,r8d
- add r11d,DWORD[52+r15]
- add bl,dl
- mov eax,DWORD[56+rsi]
- add r11d,4254626195
- xor r12d,r10d
- movzx ebx,bl
- mov DWORD[52+rsi],edx
- add r11d,r12d
- add cl,al
- rol r11d,12
- mov r12d,r9d
- pinsrw xmm1,WORD[rbx*4+rdi],6
-
- add r11d,r8d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r8d
- mov DWORD[rcx*4+rdi],eax
- and r12d,r11d
- add r10d,DWORD[56+r15]
- add al,dl
- mov ebx,DWORD[60+rsi]
- add r10d,2792965006
- xor r12d,r9d
- movzx eax,al
- mov DWORD[56+rsi],edx
- add r10d,r12d
- add cl,bl
- rol r10d,17
- mov r12d,r8d
- pinsrw xmm0,WORD[rax*4+rdi],7
-
- add r10d,r11d
- movdqu xmm2,XMMWORD[r13]
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r11d
- mov DWORD[rcx*4+rdi],ebx
- and r12d,r10d
- add r9d,DWORD[60+r15]
- add bl,dl
- mov eax,DWORD[64+rsi]
- add r9d,1236535329
- xor r12d,r8d
- movzx ebx,bl
- mov DWORD[60+rsi],edx
- add r9d,r12d
- add cl,al
- rol r9d,22
- mov r12d,r10d
- pinsrw xmm1,WORD[rbx*4+rdi],7
-
- add r9d,r10d
- psllq xmm1,8
- pxor xmm2,xmm0
- pxor xmm2,xmm1
- pxor xmm0,xmm0
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r9d
- mov DWORD[rcx*4+rdi],eax
- and r12d,r11d
- add r8d,DWORD[4+r15]
- add al,dl
- mov ebx,DWORD[68+rsi]
- add r8d,4129170786
- xor r12d,r10d
- movzx eax,al
- mov DWORD[64+rsi],edx
- add r8d,r12d
- add cl,bl
- rol r8d,5
- mov r12d,r9d
- movd xmm0,DWORD[rax*4+rdi]
-
- add r8d,r9d
- pxor xmm1,xmm1
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r8d
- mov DWORD[rcx*4+rdi],ebx
- and r12d,r10d
- add r11d,DWORD[24+r15]
- add bl,dl
- mov eax,DWORD[72+rsi]
- add r11d,3225465664
- xor r12d,r9d
- movzx ebx,bl
- mov DWORD[68+rsi],edx
- add r11d,r12d
- add cl,al
- rol r11d,9
- mov r12d,r8d
- movd xmm1,DWORD[rbx*4+rdi]
-
- add r11d,r8d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r11d
- mov DWORD[rcx*4+rdi],eax
- and r12d,r9d
- add r10d,DWORD[44+r15]
- add al,dl
- mov ebx,DWORD[76+rsi]
- add r10d,643717713
- xor r12d,r8d
- movzx eax,al
- mov DWORD[72+rsi],edx
- add r10d,r12d
- add cl,bl
- rol r10d,14
- mov r12d,r11d
- pinsrw xmm0,WORD[rax*4+rdi],1
-
- add r10d,r11d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r10d
- mov DWORD[rcx*4+rdi],ebx
- and r12d,r8d
- add r9d,DWORD[r15]
- add bl,dl
- mov eax,DWORD[80+rsi]
- add r9d,3921069994
- xor r12d,r11d
- movzx ebx,bl
- mov DWORD[76+rsi],edx
- add r9d,r12d
- add cl,al
- rol r9d,20
- mov r12d,r10d
- pinsrw xmm1,WORD[rbx*4+rdi],1
-
- add r9d,r10d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r9d
- mov DWORD[rcx*4+rdi],eax
- and r12d,r11d
- add r8d,DWORD[20+r15]
- add al,dl
- mov ebx,DWORD[84+rsi]
- add r8d,3593408605
- xor r12d,r10d
- movzx eax,al
- mov DWORD[80+rsi],edx
- add r8d,r12d
- add cl,bl
- rol r8d,5
- mov r12d,r9d
- pinsrw xmm0,WORD[rax*4+rdi],2
-
- add r8d,r9d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r8d
- mov DWORD[rcx*4+rdi],ebx
- and r12d,r10d
- add r11d,DWORD[40+r15]
- add bl,dl
- mov eax,DWORD[88+rsi]
- add r11d,38016083
- xor r12d,r9d
- movzx ebx,bl
- mov DWORD[84+rsi],edx
- add r11d,r12d
- add cl,al
- rol r11d,9
- mov r12d,r8d
- pinsrw xmm1,WORD[rbx*4+rdi],2
-
- add r11d,r8d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r11d
- mov DWORD[rcx*4+rdi],eax
- and r12d,r9d
- add r10d,DWORD[60+r15]
- add al,dl
- mov ebx,DWORD[92+rsi]
- add r10d,3634488961
- xor r12d,r8d
- movzx eax,al
- mov DWORD[88+rsi],edx
- add r10d,r12d
- add cl,bl
- rol r10d,14
- mov r12d,r11d
- pinsrw xmm0,WORD[rax*4+rdi],3
-
- add r10d,r11d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r10d
- mov DWORD[rcx*4+rdi],ebx
- and r12d,r8d
- add r9d,DWORD[16+r15]
- add bl,dl
- mov eax,DWORD[96+rsi]
- add r9d,3889429448
- xor r12d,r11d
- movzx ebx,bl
- mov DWORD[92+rsi],edx
- add r9d,r12d
- add cl,al
- rol r9d,20
- mov r12d,r10d
- pinsrw xmm1,WORD[rbx*4+rdi],3
-
- add r9d,r10d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r9d
- mov DWORD[rcx*4+rdi],eax
- and r12d,r11d
- add r8d,DWORD[36+r15]
- add al,dl
- mov ebx,DWORD[100+rsi]
- add r8d,568446438
- xor r12d,r10d
- movzx eax,al
- mov DWORD[96+rsi],edx
- add r8d,r12d
- add cl,bl
- rol r8d,5
- mov r12d,r9d
- pinsrw xmm0,WORD[rax*4+rdi],4
-
- add r8d,r9d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r8d
- mov DWORD[rcx*4+rdi],ebx
- and r12d,r10d
- add r11d,DWORD[56+r15]
- add bl,dl
- mov eax,DWORD[104+rsi]
- add r11d,3275163606
- xor r12d,r9d
- movzx ebx,bl
- mov DWORD[100+rsi],edx
- add r11d,r12d
- add cl,al
- rol r11d,9
- mov r12d,r8d
- pinsrw xmm1,WORD[rbx*4+rdi],4
-
- add r11d,r8d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r11d
- mov DWORD[rcx*4+rdi],eax
- and r12d,r9d
- add r10d,DWORD[12+r15]
- add al,dl
- mov ebx,DWORD[108+rsi]
- add r10d,4107603335
- xor r12d,r8d
- movzx eax,al
- mov DWORD[104+rsi],edx
- add r10d,r12d
- add cl,bl
- rol r10d,14
- mov r12d,r11d
- pinsrw xmm0,WORD[rax*4+rdi],5
-
- add r10d,r11d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r10d
- mov DWORD[rcx*4+rdi],ebx
- and r12d,r8d
- add r9d,DWORD[32+r15]
- add bl,dl
- mov eax,DWORD[112+rsi]
- add r9d,1163531501
- xor r12d,r11d
- movzx ebx,bl
- mov DWORD[108+rsi],edx
- add r9d,r12d
- add cl,al
- rol r9d,20
- mov r12d,r10d
- pinsrw xmm1,WORD[rbx*4+rdi],5
-
- add r9d,r10d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r9d
- mov DWORD[rcx*4+rdi],eax
- and r12d,r11d
- add r8d,DWORD[52+r15]
- add al,dl
- mov ebx,DWORD[116+rsi]
- add r8d,2850285829
- xor r12d,r10d
- movzx eax,al
- mov DWORD[112+rsi],edx
- add r8d,r12d
- add cl,bl
- rol r8d,5
- mov r12d,r9d
- pinsrw xmm0,WORD[rax*4+rdi],6
-
- add r8d,r9d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r8d
- mov DWORD[rcx*4+rdi],ebx
- and r12d,r10d
- add r11d,DWORD[8+r15]
- add bl,dl
- mov eax,DWORD[120+rsi]
- add r11d,4243563512
- xor r12d,r9d
- movzx ebx,bl
- mov DWORD[116+rsi],edx
- add r11d,r12d
- add cl,al
- rol r11d,9
- mov r12d,r8d
- pinsrw xmm1,WORD[rbx*4+rdi],6
-
- add r11d,r8d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r11d
- mov DWORD[rcx*4+rdi],eax
- and r12d,r9d
- add r10d,DWORD[28+r15]
- add al,dl
- mov ebx,DWORD[124+rsi]
- add r10d,1735328473
- xor r12d,r8d
- movzx eax,al
- mov DWORD[120+rsi],edx
- add r10d,r12d
- add cl,bl
- rol r10d,14
- mov r12d,r11d
- pinsrw xmm0,WORD[rax*4+rdi],7
-
- add r10d,r11d
- movdqu xmm3,XMMWORD[16+r13]
- add bpl,32
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r10d
- mov DWORD[rcx*4+rdi],ebx
- and r12d,r8d
- add r9d,DWORD[48+r15]
- add bl,dl
- mov eax,DWORD[rbp*4+rdi]
- add r9d,2368359562
- xor r12d,r11d
- movzx ebx,bl
- mov DWORD[124+rsi],edx
- add r9d,r12d
- add cl,al
- rol r9d,20
- mov r12d,r11d
- pinsrw xmm1,WORD[rbx*4+rdi],7
-
- add r9d,r10d
- mov rsi,rcx
- xor rcx,rcx
- mov cl,sil
- lea rsi,[rbp*4+rdi]
- psllq xmm1,8
- pxor xmm3,xmm0
- pxor xmm3,xmm1
- pxor xmm0,xmm0
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r10d
- mov DWORD[rcx*4+rdi],eax
- xor r12d,r9d
- add r8d,DWORD[20+r15]
- add al,dl
- mov ebx,DWORD[4+rsi]
- add r8d,4294588738
- movzx eax,al
- add r8d,r12d
- mov DWORD[rsi],edx
- add cl,bl
- rol r8d,4
- mov r12d,r10d
- movd xmm0,DWORD[rax*4+rdi]
-
- add r8d,r9d
- pxor xmm1,xmm1
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r9d
- mov DWORD[rcx*4+rdi],ebx
- xor r12d,r8d
- add r11d,DWORD[32+r15]
- add bl,dl
- mov eax,DWORD[8+rsi]
- add r11d,2272392833
- movzx ebx,bl
- add r11d,r12d
- mov DWORD[4+rsi],edx
- add cl,al
- rol r11d,11
- mov r12d,r9d
- movd xmm1,DWORD[rbx*4+rdi]
-
- add r11d,r8d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r8d
- mov DWORD[rcx*4+rdi],eax
- xor r12d,r11d
- add r10d,DWORD[44+r15]
- add al,dl
- mov ebx,DWORD[12+rsi]
- add r10d,1839030562
- movzx eax,al
- add r10d,r12d
- mov DWORD[8+rsi],edx
- add cl,bl
- rol r10d,16
- mov r12d,r8d
- pinsrw xmm0,WORD[rax*4+rdi],1
-
- add r10d,r11d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r11d
- mov DWORD[rcx*4+rdi],ebx
- xor r12d,r10d
- add r9d,DWORD[56+r15]
- add bl,dl
- mov eax,DWORD[16+rsi]
- add r9d,4259657740
- movzx ebx,bl
- add r9d,r12d
- mov DWORD[12+rsi],edx
- add cl,al
- rol r9d,23
- mov r12d,r11d
- pinsrw xmm1,WORD[rbx*4+rdi],1
-
- add r9d,r10d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r10d
- mov DWORD[rcx*4+rdi],eax
- xor r12d,r9d
- add r8d,DWORD[4+r15]
- add al,dl
- mov ebx,DWORD[20+rsi]
- add r8d,2763975236
- movzx eax,al
- add r8d,r12d
- mov DWORD[16+rsi],edx
- add cl,bl
- rol r8d,4
- mov r12d,r10d
- pinsrw xmm0,WORD[rax*4+rdi],2
-
- add r8d,r9d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r9d
- mov DWORD[rcx*4+rdi],ebx
- xor r12d,r8d
- add r11d,DWORD[16+r15]
- add bl,dl
- mov eax,DWORD[24+rsi]
- add r11d,1272893353
- movzx ebx,bl
- add r11d,r12d
- mov DWORD[20+rsi],edx
- add cl,al
- rol r11d,11
- mov r12d,r9d
- pinsrw xmm1,WORD[rbx*4+rdi],2
-
- add r11d,r8d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r8d
- mov DWORD[rcx*4+rdi],eax
- xor r12d,r11d
- add r10d,DWORD[28+r15]
- add al,dl
- mov ebx,DWORD[28+rsi]
- add r10d,4139469664
- movzx eax,al
- add r10d,r12d
- mov DWORD[24+rsi],edx
- add cl,bl
- rol r10d,16
- mov r12d,r8d
- pinsrw xmm0,WORD[rax*4+rdi],3
-
- add r10d,r11d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r11d
- mov DWORD[rcx*4+rdi],ebx
- xor r12d,r10d
- add r9d,DWORD[40+r15]
- add bl,dl
- mov eax,DWORD[32+rsi]
- add r9d,3200236656
- movzx ebx,bl
- add r9d,r12d
- mov DWORD[28+rsi],edx
- add cl,al
- rol r9d,23
- mov r12d,r11d
- pinsrw xmm1,WORD[rbx*4+rdi],3
-
- add r9d,r10d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r10d
- mov DWORD[rcx*4+rdi],eax
- xor r12d,r9d
- add r8d,DWORD[52+r15]
- add al,dl
- mov ebx,DWORD[36+rsi]
- add r8d,681279174
- movzx eax,al
- add r8d,r12d
- mov DWORD[32+rsi],edx
- add cl,bl
- rol r8d,4
- mov r12d,r10d
- pinsrw xmm0,WORD[rax*4+rdi],4
-
- add r8d,r9d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r9d
- mov DWORD[rcx*4+rdi],ebx
- xor r12d,r8d
- add r11d,DWORD[r15]
- add bl,dl
- mov eax,DWORD[40+rsi]
- add r11d,3936430074
- movzx ebx,bl
- add r11d,r12d
- mov DWORD[36+rsi],edx
- add cl,al
- rol r11d,11
- mov r12d,r9d
- pinsrw xmm1,WORD[rbx*4+rdi],4
-
- add r11d,r8d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r8d
- mov DWORD[rcx*4+rdi],eax
- xor r12d,r11d
- add r10d,DWORD[12+r15]
- add al,dl
- mov ebx,DWORD[44+rsi]
- add r10d,3572445317
- movzx eax,al
- add r10d,r12d
- mov DWORD[40+rsi],edx
- add cl,bl
- rol r10d,16
- mov r12d,r8d
- pinsrw xmm0,WORD[rax*4+rdi],5
-
- add r10d,r11d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r11d
- mov DWORD[rcx*4+rdi],ebx
- xor r12d,r10d
- add r9d,DWORD[24+r15]
- add bl,dl
- mov eax,DWORD[48+rsi]
- add r9d,76029189
- movzx ebx,bl
- add r9d,r12d
- mov DWORD[44+rsi],edx
- add cl,al
- rol r9d,23
- mov r12d,r11d
- pinsrw xmm1,WORD[rbx*4+rdi],5
-
- add r9d,r10d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r10d
- mov DWORD[rcx*4+rdi],eax
- xor r12d,r9d
- add r8d,DWORD[36+r15]
- add al,dl
- mov ebx,DWORD[52+rsi]
- add r8d,3654602809
- movzx eax,al
- add r8d,r12d
- mov DWORD[48+rsi],edx
- add cl,bl
- rol r8d,4
- mov r12d,r10d
- pinsrw xmm0,WORD[rax*4+rdi],6
-
- add r8d,r9d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r9d
- mov DWORD[rcx*4+rdi],ebx
- xor r12d,r8d
- add r11d,DWORD[48+r15]
- add bl,dl
- mov eax,DWORD[56+rsi]
- add r11d,3873151461
- movzx ebx,bl
- add r11d,r12d
- mov DWORD[52+rsi],edx
- add cl,al
- rol r11d,11
- mov r12d,r9d
- pinsrw xmm1,WORD[rbx*4+rdi],6
-
- add r11d,r8d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r8d
- mov DWORD[rcx*4+rdi],eax
- xor r12d,r11d
- add r10d,DWORD[60+r15]
- add al,dl
- mov ebx,DWORD[60+rsi]
- add r10d,530742520
- movzx eax,al
- add r10d,r12d
- mov DWORD[56+rsi],edx
- add cl,bl
- rol r10d,16
- mov r12d,r8d
- pinsrw xmm0,WORD[rax*4+rdi],7
-
- add r10d,r11d
- movdqu xmm4,XMMWORD[32+r13]
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r11d
- mov DWORD[rcx*4+rdi],ebx
- xor r12d,r10d
- add r9d,DWORD[8+r15]
- add bl,dl
- mov eax,DWORD[64+rsi]
- add r9d,3299628645
- movzx ebx,bl
- add r9d,r12d
- mov DWORD[60+rsi],edx
- add cl,al
- rol r9d,23
- mov r12d,-1
- pinsrw xmm1,WORD[rbx*4+rdi],7
-
- add r9d,r10d
- psllq xmm1,8
- pxor xmm4,xmm0
- pxor xmm4,xmm1
- pxor xmm0,xmm0
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r11d
- mov DWORD[rcx*4+rdi],eax
- or r12d,r9d
- add r8d,DWORD[r15]
- add al,dl
- mov ebx,DWORD[68+rsi]
- add r8d,4096336452
- movzx eax,al
- xor r12d,r10d
- mov DWORD[64+rsi],edx
- add r8d,r12d
- add cl,bl
- rol r8d,6
- mov r12d,-1
- movd xmm0,DWORD[rax*4+rdi]
-
- add r8d,r9d
- pxor xmm1,xmm1
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r10d
- mov DWORD[rcx*4+rdi],ebx
- or r12d,r8d
- add r11d,DWORD[28+r15]
- add bl,dl
- mov eax,DWORD[72+rsi]
- add r11d,1126891415
- movzx ebx,bl
- xor r12d,r9d
- mov DWORD[68+rsi],edx
- add r11d,r12d
- add cl,al
- rol r11d,10
- mov r12d,-1
- movd xmm1,DWORD[rbx*4+rdi]
-
- add r11d,r8d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r9d
- mov DWORD[rcx*4+rdi],eax
- or r12d,r11d
- add r10d,DWORD[56+r15]
- add al,dl
- mov ebx,DWORD[76+rsi]
- add r10d,2878612391
- movzx eax,al
- xor r12d,r8d
- mov DWORD[72+rsi],edx
- add r10d,r12d
- add cl,bl
- rol r10d,15
- mov r12d,-1
- pinsrw xmm0,WORD[rax*4+rdi],1
-
- add r10d,r11d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r8d
- mov DWORD[rcx*4+rdi],ebx
- or r12d,r10d
- add r9d,DWORD[20+r15]
- add bl,dl
- mov eax,DWORD[80+rsi]
- add r9d,4237533241
- movzx ebx,bl
- xor r12d,r11d
- mov DWORD[76+rsi],edx
- add r9d,r12d
- add cl,al
- rol r9d,21
- mov r12d,-1
- pinsrw xmm1,WORD[rbx*4+rdi],1
-
- add r9d,r10d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r11d
- mov DWORD[rcx*4+rdi],eax
- or r12d,r9d
- add r8d,DWORD[48+r15]
- add al,dl
- mov ebx,DWORD[84+rsi]
- add r8d,1700485571
- movzx eax,al
- xor r12d,r10d
- mov DWORD[80+rsi],edx
- add r8d,r12d
- add cl,bl
- rol r8d,6
- mov r12d,-1
- pinsrw xmm0,WORD[rax*4+rdi],2
-
- add r8d,r9d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r10d
- mov DWORD[rcx*4+rdi],ebx
- or r12d,r8d
- add r11d,DWORD[12+r15]
- add bl,dl
- mov eax,DWORD[88+rsi]
- add r11d,2399980690
- movzx ebx,bl
- xor r12d,r9d
- mov DWORD[84+rsi],edx
- add r11d,r12d
- add cl,al
- rol r11d,10
- mov r12d,-1
- pinsrw xmm1,WORD[rbx*4+rdi],2
-
- add r11d,r8d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r9d
- mov DWORD[rcx*4+rdi],eax
- or r12d,r11d
- add r10d,DWORD[40+r15]
- add al,dl
- mov ebx,DWORD[92+rsi]
- add r10d,4293915773
- movzx eax,al
- xor r12d,r8d
- mov DWORD[88+rsi],edx
- add r10d,r12d
- add cl,bl
- rol r10d,15
- mov r12d,-1
- pinsrw xmm0,WORD[rax*4+rdi],3
-
- add r10d,r11d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r8d
- mov DWORD[rcx*4+rdi],ebx
- or r12d,r10d
- add r9d,DWORD[4+r15]
- add bl,dl
- mov eax,DWORD[96+rsi]
- add r9d,2240044497
- movzx ebx,bl
- xor r12d,r11d
- mov DWORD[92+rsi],edx
- add r9d,r12d
- add cl,al
- rol r9d,21
- mov r12d,-1
- pinsrw xmm1,WORD[rbx*4+rdi],3
-
- add r9d,r10d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r11d
- mov DWORD[rcx*4+rdi],eax
- or r12d,r9d
- add r8d,DWORD[32+r15]
- add al,dl
- mov ebx,DWORD[100+rsi]
- add r8d,1873313359
- movzx eax,al
- xor r12d,r10d
- mov DWORD[96+rsi],edx
- add r8d,r12d
- add cl,bl
- rol r8d,6
- mov r12d,-1
- pinsrw xmm0,WORD[rax*4+rdi],4
-
- add r8d,r9d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r10d
- mov DWORD[rcx*4+rdi],ebx
- or r12d,r8d
- add r11d,DWORD[60+r15]
- add bl,dl
- mov eax,DWORD[104+rsi]
- add r11d,4264355552
- movzx ebx,bl
- xor r12d,r9d
- mov DWORD[100+rsi],edx
- add r11d,r12d
- add cl,al
- rol r11d,10
- mov r12d,-1
- pinsrw xmm1,WORD[rbx*4+rdi],4
-
- add r11d,r8d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r9d
- mov DWORD[rcx*4+rdi],eax
- or r12d,r11d
- add r10d,DWORD[24+r15]
- add al,dl
- mov ebx,DWORD[108+rsi]
- add r10d,2734768916
- movzx eax,al
- xor r12d,r8d
- mov DWORD[104+rsi],edx
- add r10d,r12d
- add cl,bl
- rol r10d,15
- mov r12d,-1
- pinsrw xmm0,WORD[rax*4+rdi],5
-
- add r10d,r11d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r8d
- mov DWORD[rcx*4+rdi],ebx
- or r12d,r10d
- add r9d,DWORD[52+r15]
- add bl,dl
- mov eax,DWORD[112+rsi]
- add r9d,1309151649
- movzx ebx,bl
- xor r12d,r11d
- mov DWORD[108+rsi],edx
- add r9d,r12d
- add cl,al
- rol r9d,21
- mov r12d,-1
- pinsrw xmm1,WORD[rbx*4+rdi],5
-
- add r9d,r10d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r11d
- mov DWORD[rcx*4+rdi],eax
- or r12d,r9d
- add r8d,DWORD[16+r15]
- add al,dl
- mov ebx,DWORD[116+rsi]
- add r8d,4149444226
- movzx eax,al
- xor r12d,r10d
- mov DWORD[112+rsi],edx
- add r8d,r12d
- add cl,bl
- rol r8d,6
- mov r12d,-1
- pinsrw xmm0,WORD[rax*4+rdi],6
-
- add r8d,r9d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r10d
- mov DWORD[rcx*4+rdi],ebx
- or r12d,r8d
- add r11d,DWORD[44+r15]
- add bl,dl
- mov eax,DWORD[120+rsi]
- add r11d,3174756917
- movzx ebx,bl
- xor r12d,r9d
- mov DWORD[116+rsi],edx
- add r11d,r12d
- add cl,al
- rol r11d,10
- mov r12d,-1
- pinsrw xmm1,WORD[rbx*4+rdi],6
-
- add r11d,r8d
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r9d
- mov DWORD[rcx*4+rdi],eax
- or r12d,r11d
- add r10d,DWORD[8+r15]
- add al,dl
- mov ebx,DWORD[124+rsi]
- add r10d,718787259
- movzx eax,al
- xor r12d,r8d
- mov DWORD[120+rsi],edx
- add r10d,r12d
- add cl,bl
- rol r10d,15
- mov r12d,-1
- pinsrw xmm0,WORD[rax*4+rdi],7
-
- add r10d,r11d
- movdqu xmm5,XMMWORD[48+r13]
- add bpl,32
- mov edx,DWORD[rcx*4+rdi]
- xor r12d,r8d
- mov DWORD[rcx*4+rdi],ebx
- or r12d,r10d
- add r9d,DWORD[36+r15]
- add bl,dl
- mov eax,DWORD[rbp*4+rdi]
- add r9d,3951481745
- movzx ebx,bl
- xor r12d,r11d
- mov DWORD[124+rsi],edx
- add r9d,r12d
- add cl,al
- rol r9d,21
- mov r12d,-1
- pinsrw xmm1,WORD[rbx*4+rdi],7
-
- add r9d,r10d
- mov rsi,rbp
- xor rbp,rbp
- mov bpl,sil
- mov rsi,rcx
- xor rcx,rcx
- mov cl,sil
- lea rsi,[rbp*4+rdi]
- psllq xmm1,8
- pxor xmm5,xmm0
- pxor xmm5,xmm1
- add r8d,DWORD[rsp]
- add r9d,DWORD[4+rsp]
- add r10d,DWORD[8+rsp]
- add r11d,DWORD[12+rsp]
-
- movdqu XMMWORD[r13*1+r14],xmm2
- movdqu XMMWORD[16+r13*1+r14],xmm3
- movdqu XMMWORD[32+r13*1+r14],xmm4
- movdqu XMMWORD[48+r13*1+r14],xmm5
- lea r15,[64+r15]
- lea r13,[64+r13]
- cmp r15,QWORD[16+rsp]
- jb NEAR $L$oop
-
- mov r12,QWORD[24+rsp]
- sub cl,al
- mov DWORD[r12],r8d
- mov DWORD[4+r12],r9d
- mov DWORD[8+r12],r10d
- mov DWORD[12+r12],r11d
- sub bpl,1
- mov DWORD[((-8))+rdi],ebp
- mov DWORD[((-4))+rdi],ecx
-
- mov r15,QWORD[40+rsp]
- mov r14,QWORD[48+rsp]
- mov r13,QWORD[56+rsp]
- mov r12,QWORD[64+rsp]
- mov rbp,QWORD[72+rsp]
- mov rbx,QWORD[80+rsp]
- lea rsp,[88+rsp]
-$L$epilogue:
-$L$abort:
- mov rdi,QWORD[8+rsp] ;WIN64 epilogue
- mov rsi,QWORD[16+rsp]
- DB 0F3h,0C3h ;repret
-$L$SEH_end_rc4_md5_enc:
-EXTERN __imp_RtlVirtualUnwind
-
-ALIGN 16
-se_handler:
- push rsi
- push rdi
- push rbx
- push rbp
- push r12
- push r13
- push r14
- push r15
- pushfq
- sub rsp,64
-
- mov rax,QWORD[120+r8]
- mov rbx,QWORD[248+r8]
-
- lea r10,[$L$body]
- cmp rbx,r10
- jb NEAR $L$in_prologue
-
- mov rax,QWORD[152+r8]
-
- lea r10,[$L$epilogue]
- cmp rbx,r10
- jae NEAR $L$in_prologue
-
- mov r15,QWORD[40+rax]
- mov r14,QWORD[48+rax]
- mov r13,QWORD[56+rax]
- mov r12,QWORD[64+rax]
- mov rbp,QWORD[72+rax]
- mov rbx,QWORD[80+rax]
- lea rax,[88+rax]
-
- mov QWORD[144+r8],rbx
- mov QWORD[160+r8],rbp
- mov QWORD[216+r8],r12
- mov QWORD[224+r8],r13
- mov QWORD[232+r8],r14
- mov QWORD[240+r8],r15
-
-$L$in_prologue:
- mov rdi,QWORD[8+rax]
- mov rsi,QWORD[16+rax]
- mov QWORD[152+r8],rax
- mov QWORD[168+r8],rsi
- mov QWORD[176+r8],rdi
-
- mov rdi,QWORD[40+r9]
- mov rsi,r8
- mov ecx,154
- DD 0xa548f3fc
-
- mov rsi,r9
- xor rcx,rcx
- mov rdx,QWORD[8+rsi]
- mov r8,QWORD[rsi]
- mov r9,QWORD[16+rsi]
- mov r10,QWORD[40+rsi]
- lea r11,[56+rsi]
- lea r12,[24+rsi]
- mov QWORD[32+rsp],r10
- mov QWORD[40+rsp],r11
- mov QWORD[48+rsp],r12
- mov QWORD[56+rsp],rcx
- call QWORD[__imp_RtlVirtualUnwind]
-
- mov eax,1
- add rsp,64
- popfq
- pop r15
- pop r14
- pop r13
- pop r12
- pop rbp
- pop rbx
- pop rdi
- pop rsi
- DB 0F3h,0C3h ;repret
-
-
-section .pdata rdata align=4
-ALIGN 4
- DD $L$SEH_begin_rc4_md5_enc wrt ..imagebase
- DD $L$SEH_end_rc4_md5_enc wrt ..imagebase
- DD $L$SEH_info_rc4_md5_enc wrt ..imagebase
-
-section .xdata rdata align=8
-ALIGN 8
-$L$SEH_info_rc4_md5_enc:
-DB 9,0,0,0
- DD se_handler wrt ..imagebase
diff --git a/win-x86_64/crypto/sha/sha1-x86_64.asm b/win-x86_64/crypto/sha/sha1-x86_64.asm
index 0f5361a..168f78d 100644
--- a/win-x86_64/crypto/sha/sha1-x86_64.asm
+++ b/win-x86_64/crypto/sha/sha1-x86_64.asm
@@ -24,6 +24,11 @@ $L$SEH_begin_sha1_block_data_order:
mov r10d,DWORD[((OPENSSL_ia32cap_P+8))]
test r8d,512
jz NEAR $L$ialu
+ and r8d,268435456
+ and r9d,1073741824
+ or r8d,r9d
+ cmp r8d,1342177280
+ je NEAR _avx_shortcut
jmp NEAR _ssse3_shortcut
ALIGN 16
@@ -2445,6 +2450,1146 @@ $L$epilogue_ssse3:
mov rsi,QWORD[16+rsp]
DB 0F3h,0C3h ;repret
$L$SEH_end_sha1_block_data_order_ssse3:
+
+ALIGN 16
+sha1_block_data_order_avx:
+ mov QWORD[8+rsp],rdi ;WIN64 prologue
+ mov QWORD[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_sha1_block_data_order_avx:
+ mov rdi,rcx
+ mov rsi,rdx
+ mov rdx,r8
+
+
+_avx_shortcut:
+ mov rax,rsp
+ push rbx
+ push rbp
+ push r12
+ push r13
+ push r14
+ lea rsp,[((-160))+rsp]
+ vzeroupper
+ vmovaps XMMWORD[(-40-96)+rax],xmm6
+ vmovaps XMMWORD[(-40-80)+rax],xmm7
+ vmovaps XMMWORD[(-40-64)+rax],xmm8
+ vmovaps XMMWORD[(-40-48)+rax],xmm9
+ vmovaps XMMWORD[(-40-32)+rax],xmm10
+ vmovaps XMMWORD[(-40-16)+rax],xmm11
+$L$prologue_avx:
+ mov r14,rax
+ and rsp,-64
+ mov r8,rdi
+ mov r9,rsi
+ mov r10,rdx
+
+ shl r10,6
+ add r10,r9
+ lea r11,[((K_XX_XX+64))]
+
+ mov eax,DWORD[r8]
+ mov ebx,DWORD[4+r8]
+ mov ecx,DWORD[8+r8]
+ mov edx,DWORD[12+r8]
+ mov esi,ebx
+ mov ebp,DWORD[16+r8]
+ mov edi,ecx
+ xor edi,edx
+ and esi,edi
+
+ vmovdqa xmm6,XMMWORD[64+r11]
+ vmovdqa xmm11,XMMWORD[((-64))+r11]
+ vmovdqu xmm0,XMMWORD[r9]
+ vmovdqu xmm1,XMMWORD[16+r9]
+ vmovdqu xmm2,XMMWORD[32+r9]
+ vmovdqu xmm3,XMMWORD[48+r9]
+ vpshufb xmm0,xmm0,xmm6
+ add r9,64
+ vpshufb xmm1,xmm1,xmm6
+ vpshufb xmm2,xmm2,xmm6
+ vpshufb xmm3,xmm3,xmm6
+ vpaddd xmm4,xmm0,xmm11
+ vpaddd xmm5,xmm1,xmm11
+ vpaddd xmm6,xmm2,xmm11
+ vmovdqa XMMWORD[rsp],xmm4
+ vmovdqa XMMWORD[16+rsp],xmm5
+ vmovdqa XMMWORD[32+rsp],xmm6
+ jmp NEAR $L$oop_avx
+ALIGN 16
+$L$oop_avx:
+ shrd ebx,ebx,2
+ xor esi,edx
+ vpalignr xmm4,xmm1,xmm0,8
+ mov edi,eax
+ add ebp,DWORD[rsp]
+ vpaddd xmm9,xmm11,xmm3
+ xor ebx,ecx
+ shld eax,eax,5
+ vpsrldq xmm8,xmm3,4
+ add ebp,esi
+ and edi,ebx
+ vpxor xmm4,xmm4,xmm0
+ xor ebx,ecx
+ add ebp,eax
+ vpxor xmm8,xmm8,xmm2
+ shrd eax,eax,7
+ xor edi,ecx
+ mov esi,ebp
+ add edx,DWORD[4+rsp]
+ vpxor xmm4,xmm4,xmm8
+ xor eax,ebx
+ shld ebp,ebp,5
+ vmovdqa XMMWORD[48+rsp],xmm9
+ add edx,edi
+ and esi,eax
+ vpsrld xmm8,xmm4,31
+ xor eax,ebx
+ add edx,ebp
+ shrd ebp,ebp,7
+ xor esi,ebx
+ vpslldq xmm10,xmm4,12
+ vpaddd xmm4,xmm4,xmm4
+ mov edi,edx
+ add ecx,DWORD[8+rsp]
+ xor ebp,eax
+ shld edx,edx,5
+ vpsrld xmm9,xmm10,30
+ vpor xmm4,xmm4,xmm8
+ add ecx,esi
+ and edi,ebp
+ xor ebp,eax
+ add ecx,edx
+ vpslld xmm10,xmm10,2
+ vpxor xmm4,xmm4,xmm9
+ shrd edx,edx,7
+ xor edi,eax
+ mov esi,ecx
+ add ebx,DWORD[12+rsp]
+ vpxor xmm4,xmm4,xmm10
+ xor edx,ebp
+ shld ecx,ecx,5
+ add ebx,edi
+ and esi,edx
+ xor edx,ebp
+ add ebx,ecx
+ shrd ecx,ecx,7
+ xor esi,ebp
+ vpalignr xmm5,xmm2,xmm1,8
+ mov edi,ebx
+ add eax,DWORD[16+rsp]
+ vpaddd xmm9,xmm11,xmm4
+ xor ecx,edx
+ shld ebx,ebx,5
+ vpsrldq xmm8,xmm4,4
+ add eax,esi
+ and edi,ecx
+ vpxor xmm5,xmm5,xmm1
+ xor ecx,edx
+ add eax,ebx
+ vpxor xmm8,xmm8,xmm3
+ shrd ebx,ebx,7
+ xor edi,edx
+ mov esi,eax
+ add ebp,DWORD[20+rsp]
+ vpxor xmm5,xmm5,xmm8
+ xor ebx,ecx
+ shld eax,eax,5
+ vmovdqa XMMWORD[rsp],xmm9
+ add ebp,edi
+ and esi,ebx
+ vpsrld xmm8,xmm5,31
+ xor ebx,ecx
+ add ebp,eax
+ shrd eax,eax,7
+ xor esi,ecx
+ vpslldq xmm10,xmm5,12
+ vpaddd xmm5,xmm5,xmm5
+ mov edi,ebp
+ add edx,DWORD[24+rsp]
+ xor eax,ebx
+ shld ebp,ebp,5
+ vpsrld xmm9,xmm10,30
+ vpor xmm5,xmm5,xmm8
+ add edx,esi
+ and edi,eax
+ xor eax,ebx
+ add edx,ebp
+ vpslld xmm10,xmm10,2
+ vpxor xmm5,xmm5,xmm9
+ shrd ebp,ebp,7
+ xor edi,ebx
+ mov esi,edx
+ add ecx,DWORD[28+rsp]
+ vpxor xmm5,xmm5,xmm10
+ xor ebp,eax
+ shld edx,edx,5
+ vmovdqa xmm11,XMMWORD[((-32))+r11]
+ add ecx,edi
+ and esi,ebp
+ xor ebp,eax
+ add ecx,edx
+ shrd edx,edx,7
+ xor esi,eax
+ vpalignr xmm6,xmm3,xmm2,8
+ mov edi,ecx
+ add ebx,DWORD[32+rsp]
+ vpaddd xmm9,xmm11,xmm5
+ xor edx,ebp
+ shld ecx,ecx,5
+ vpsrldq xmm8,xmm5,4
+ add ebx,esi
+ and edi,edx
+ vpxor xmm6,xmm6,xmm2
+ xor edx,ebp
+ add ebx,ecx
+ vpxor xmm8,xmm8,xmm4
+ shrd ecx,ecx,7
+ xor edi,ebp
+ mov esi,ebx
+ add eax,DWORD[36+rsp]
+ vpxor xmm6,xmm6,xmm8
+ xor ecx,edx
+ shld ebx,ebx,5
+ vmovdqa XMMWORD[16+rsp],xmm9
+ add eax,edi
+ and esi,ecx
+ vpsrld xmm8,xmm6,31
+ xor ecx,edx
+ add eax,ebx
+ shrd ebx,ebx,7
+ xor esi,edx
+ vpslldq xmm10,xmm6,12
+ vpaddd xmm6,xmm6,xmm6
+ mov edi,eax
+ add ebp,DWORD[40+rsp]
+ xor ebx,ecx
+ shld eax,eax,5
+ vpsrld xmm9,xmm10,30
+ vpor xmm6,xmm6,xmm8
+ add ebp,esi
+ and edi,ebx
+ xor ebx,ecx
+ add ebp,eax
+ vpslld xmm10,xmm10,2
+ vpxor xmm6,xmm6,xmm9
+ shrd eax,eax,7
+ xor edi,ecx
+ mov esi,ebp
+ add edx,DWORD[44+rsp]
+ vpxor xmm6,xmm6,xmm10
+ xor eax,ebx
+ shld ebp,ebp,5
+ add edx,edi
+ and esi,eax
+ xor eax,ebx
+ add edx,ebp
+ shrd ebp,ebp,7
+ xor esi,ebx
+ vpalignr xmm7,xmm4,xmm3,8
+ mov edi,edx
+ add ecx,DWORD[48+rsp]
+ vpaddd xmm9,xmm11,xmm6
+ xor ebp,eax
+ shld edx,edx,5
+ vpsrldq xmm8,xmm6,4
+ add ecx,esi
+ and edi,ebp
+ vpxor xmm7,xmm7,xmm3
+ xor ebp,eax
+ add ecx,edx
+ vpxor xmm8,xmm8,xmm5
+ shrd edx,edx,7
+ xor edi,eax
+ mov esi,ecx
+ add ebx,DWORD[52+rsp]
+ vpxor xmm7,xmm7,xmm8
+ xor edx,ebp
+ shld ecx,ecx,5
+ vmovdqa XMMWORD[32+rsp],xmm9
+ add ebx,edi
+ and esi,edx
+ vpsrld xmm8,xmm7,31
+ xor edx,ebp
+ add ebx,ecx
+ shrd ecx,ecx,7
+ xor esi,ebp
+ vpslldq xmm10,xmm7,12
+ vpaddd xmm7,xmm7,xmm7
+ mov edi,ebx
+ add eax,DWORD[56+rsp]
+ xor ecx,edx
+ shld ebx,ebx,5
+ vpsrld xmm9,xmm10,30
+ vpor xmm7,xmm7,xmm8
+ add eax,esi
+ and edi,ecx
+ xor ecx,edx
+ add eax,ebx
+ vpslld xmm10,xmm10,2
+ vpxor xmm7,xmm7,xmm9
+ shrd ebx,ebx,7
+ xor edi,edx
+ mov esi,eax
+ add ebp,DWORD[60+rsp]
+ vpxor xmm7,xmm7,xmm10
+ xor ebx,ecx
+ shld eax,eax,5
+ add ebp,edi
+ and esi,ebx
+ xor ebx,ecx
+ add ebp,eax
+ vpalignr xmm8,xmm7,xmm6,8
+ vpxor xmm0,xmm0,xmm4
+ shrd eax,eax,7
+ xor esi,ecx
+ mov edi,ebp
+ add edx,DWORD[rsp]
+ vpxor xmm0,xmm0,xmm1
+ xor eax,ebx
+ shld ebp,ebp,5
+ vpaddd xmm9,xmm11,xmm7
+ add edx,esi
+ and edi,eax
+ vpxor xmm0,xmm0,xmm8
+ xor eax,ebx
+ add edx,ebp
+ shrd ebp,ebp,7
+ xor edi,ebx
+ vpsrld xmm8,xmm0,30
+ vmovdqa XMMWORD[48+rsp],xmm9
+ mov esi,edx
+ add ecx,DWORD[4+rsp]
+ xor ebp,eax
+ shld edx,edx,5
+ vpslld xmm0,xmm0,2
+ add ecx,edi
+ and esi,ebp
+ xor ebp,eax
+ add ecx,edx
+ shrd edx,edx,7
+ xor esi,eax
+ mov edi,ecx
+ add ebx,DWORD[8+rsp]
+ vpor xmm0,xmm0,xmm8
+ xor edx,ebp
+ shld ecx,ecx,5
+ add ebx,esi
+ and edi,edx
+ xor edx,ebp
+ add ebx,ecx
+ add eax,DWORD[12+rsp]
+ xor edi,ebp
+ mov esi,ebx
+ shld ebx,ebx,5
+ add eax,edi
+ xor esi,edx
+ shrd ecx,ecx,7
+ add eax,ebx
+ vpalignr xmm8,xmm0,xmm7,8
+ vpxor xmm1,xmm1,xmm5
+ add ebp,DWORD[16+rsp]
+ xor esi,ecx
+ mov edi,eax
+ shld eax,eax,5
+ vpxor xmm1,xmm1,xmm2
+ add ebp,esi
+ xor edi,ecx
+ vpaddd xmm9,xmm11,xmm0
+ shrd ebx,ebx,7
+ add ebp,eax
+ vpxor xmm1,xmm1,xmm8
+ add edx,DWORD[20+rsp]
+ xor edi,ebx
+ mov esi,ebp
+ shld ebp,ebp,5
+ vpsrld xmm8,xmm1,30
+ vmovdqa XMMWORD[rsp],xmm9
+ add edx,edi
+ xor esi,ebx
+ shrd eax,eax,7
+ add edx,ebp
+ vpslld xmm1,xmm1,2
+ add ecx,DWORD[24+rsp]
+ xor esi,eax
+ mov edi,edx
+ shld edx,edx,5
+ add ecx,esi
+ xor edi,eax
+ shrd ebp,ebp,7
+ add ecx,edx
+ vpor xmm1,xmm1,xmm8
+ add ebx,DWORD[28+rsp]
+ xor edi,ebp
+ mov esi,ecx
+ shld ecx,ecx,5
+ add ebx,edi
+ xor esi,ebp
+ shrd edx,edx,7
+ add ebx,ecx
+ vpalignr xmm8,xmm1,xmm0,8
+ vpxor xmm2,xmm2,xmm6
+ add eax,DWORD[32+rsp]
+ xor esi,edx
+ mov edi,ebx
+ shld ebx,ebx,5
+ vpxor xmm2,xmm2,xmm3
+ add eax,esi
+ xor edi,edx
+ vpaddd xmm9,xmm11,xmm1
+ vmovdqa xmm11,XMMWORD[r11]
+ shrd ecx,ecx,7
+ add eax,ebx
+ vpxor xmm2,xmm2,xmm8
+ add ebp,DWORD[36+rsp]
+ xor edi,ecx
+ mov esi,eax
+ shld eax,eax,5
+ vpsrld xmm8,xmm2,30
+ vmovdqa XMMWORD[16+rsp],xmm9
+ add ebp,edi
+ xor esi,ecx
+ shrd ebx,ebx,7
+ add ebp,eax
+ vpslld xmm2,xmm2,2
+ add edx,DWORD[40+rsp]
+ xor esi,ebx
+ mov edi,ebp
+ shld ebp,ebp,5
+ add edx,esi
+ xor edi,ebx
+ shrd eax,eax,7
+ add edx,ebp
+ vpor xmm2,xmm2,xmm8
+ add ecx,DWORD[44+rsp]
+ xor edi,eax
+ mov esi,edx
+ shld edx,edx,5
+ add ecx,edi
+ xor esi,eax
+ shrd ebp,ebp,7
+ add ecx,edx
+ vpalignr xmm8,xmm2,xmm1,8
+ vpxor xmm3,xmm3,xmm7
+ add ebx,DWORD[48+rsp]
+ xor esi,ebp
+ mov edi,ecx
+ shld ecx,ecx,5
+ vpxor xmm3,xmm3,xmm4
+ add ebx,esi
+ xor edi,ebp
+ vpaddd xmm9,xmm11,xmm2
+ shrd edx,edx,7
+ add ebx,ecx
+ vpxor xmm3,xmm3,xmm8
+ add eax,DWORD[52+rsp]
+ xor edi,edx
+ mov esi,ebx
+ shld ebx,ebx,5
+ vpsrld xmm8,xmm3,30
+ vmovdqa XMMWORD[32+rsp],xmm9
+ add eax,edi
+ xor esi,edx
+ shrd ecx,ecx,7
+ add eax,ebx
+ vpslld xmm3,xmm3,2
+ add ebp,DWORD[56+rsp]
+ xor esi,ecx
+ mov edi,eax
+ shld eax,eax,5
+ add ebp,esi
+ xor edi,ecx
+ shrd ebx,ebx,7
+ add ebp,eax
+ vpor xmm3,xmm3,xmm8
+ add edx,DWORD[60+rsp]
+ xor edi,ebx
+ mov esi,ebp
+ shld ebp,ebp,5
+ add edx,edi
+ xor esi,ebx
+ shrd eax,eax,7
+ add edx,ebp
+ vpalignr xmm8,xmm3,xmm2,8
+ vpxor xmm4,xmm4,xmm0
+ add ecx,DWORD[rsp]
+ xor esi,eax
+ mov edi,edx
+ shld edx,edx,5
+ vpxor xmm4,xmm4,xmm5
+ add ecx,esi
+ xor edi,eax
+ vpaddd xmm9,xmm11,xmm3
+ shrd ebp,ebp,7
+ add ecx,edx
+ vpxor xmm4,xmm4,xmm8
+ add ebx,DWORD[4+rsp]
+ xor edi,ebp
+ mov esi,ecx
+ shld ecx,ecx,5
+ vpsrld xmm8,xmm4,30
+ vmovdqa XMMWORD[48+rsp],xmm9
+ add ebx,edi
+ xor esi,ebp
+ shrd edx,edx,7
+ add ebx,ecx
+ vpslld xmm4,xmm4,2
+ add eax,DWORD[8+rsp]
+ xor esi,edx
+ mov edi,ebx
+ shld ebx,ebx,5
+ add eax,esi
+ xor edi,edx
+ shrd ecx,ecx,7
+ add eax,ebx
+ vpor xmm4,xmm4,xmm8
+ add ebp,DWORD[12+rsp]
+ xor edi,ecx
+ mov esi,eax
+ shld eax,eax,5
+ add ebp,edi
+ xor esi,ecx
+ shrd ebx,ebx,7
+ add ebp,eax
+ vpalignr xmm8,xmm4,xmm3,8
+ vpxor xmm5,xmm5,xmm1
+ add edx,DWORD[16+rsp]
+ xor esi,ebx
+ mov edi,ebp
+ shld ebp,ebp,5
+ vpxor xmm5,xmm5,xmm6
+ add edx,esi
+ xor edi,ebx
+ vpaddd xmm9,xmm11,xmm4
+ shrd eax,eax,7
+ add edx,ebp
+ vpxor xmm5,xmm5,xmm8
+ add ecx,DWORD[20+rsp]
+ xor edi,eax
+ mov esi,edx
+ shld edx,edx,5
+ vpsrld xmm8,xmm5,30
+ vmovdqa XMMWORD[rsp],xmm9
+ add ecx,edi
+ xor esi,eax
+ shrd ebp,ebp,7
+ add ecx,edx
+ vpslld xmm5,xmm5,2
+ add ebx,DWORD[24+rsp]
+ xor esi,ebp
+ mov edi,ecx
+ shld ecx,ecx,5
+ add ebx,esi
+ xor edi,ebp
+ shrd edx,edx,7
+ add ebx,ecx
+ vpor xmm5,xmm5,xmm8
+ add eax,DWORD[28+rsp]
+ shrd ecx,ecx,7
+ mov esi,ebx
+ xor edi,edx
+ shld ebx,ebx,5
+ add eax,edi
+ xor esi,ecx
+ xor ecx,edx
+ add eax,ebx
+ vpalignr xmm8,xmm5,xmm4,8
+ vpxor xmm6,xmm6,xmm2
+ add ebp,DWORD[32+rsp]
+ and esi,ecx
+ xor ecx,edx
+ shrd ebx,ebx,7
+ vpxor xmm6,xmm6,xmm7
+ mov edi,eax
+ xor esi,ecx
+ vpaddd xmm9,xmm11,xmm5
+ shld eax,eax,5
+ add ebp,esi
+ vpxor xmm6,xmm6,xmm8
+ xor edi,ebx
+ xor ebx,ecx
+ add ebp,eax
+ add edx,DWORD[36+rsp]
+ vpsrld xmm8,xmm6,30
+ vmovdqa XMMWORD[16+rsp],xmm9
+ and edi,ebx
+ xor ebx,ecx
+ shrd eax,eax,7
+ mov esi,ebp
+ vpslld xmm6,xmm6,2
+ xor edi,ebx
+ shld ebp,ebp,5
+ add edx,edi
+ xor esi,eax
+ xor eax,ebx
+ add edx,ebp
+ add ecx,DWORD[40+rsp]
+ and esi,eax
+ vpor xmm6,xmm6,xmm8
+ xor eax,ebx
+ shrd ebp,ebp,7
+ mov edi,edx
+ xor esi,eax
+ shld edx,edx,5
+ add ecx,esi
+ xor edi,ebp
+ xor ebp,eax
+ add ecx,edx
+ add ebx,DWORD[44+rsp]
+ and edi,ebp
+ xor ebp,eax
+ shrd edx,edx,7
+ mov esi,ecx
+ xor edi,ebp
+ shld ecx,ecx,5
+ add ebx,edi
+ xor esi,edx
+ xor edx,ebp
+ add ebx,ecx
+ vpalignr xmm8,xmm6,xmm5,8
+ vpxor xmm7,xmm7,xmm3
+ add eax,DWORD[48+rsp]
+ and esi,edx
+ xor edx,ebp
+ shrd ecx,ecx,7
+ vpxor xmm7,xmm7,xmm0
+ mov edi,ebx
+ xor esi,edx
+ vpaddd xmm9,xmm11,xmm6
+ vmovdqa xmm11,XMMWORD[32+r11]
+ shld ebx,ebx,5
+ add eax,esi
+ vpxor xmm7,xmm7,xmm8
+ xor edi,ecx
+ xor ecx,edx
+ add eax,ebx
+ add ebp,DWORD[52+rsp]
+ vpsrld xmm8,xmm7,30
+ vmovdqa XMMWORD[32+rsp],xmm9
+ and edi,ecx
+ xor ecx,edx
+ shrd ebx,ebx,7
+ mov esi,eax
+ vpslld xmm7,xmm7,2
+ xor edi,ecx
+ shld eax,eax,5
+ add ebp,edi
+ xor esi,ebx
+ xor ebx,ecx
+ add ebp,eax
+ add edx,DWORD[56+rsp]
+ and esi,ebx
+ vpor xmm7,xmm7,xmm8
+ xor ebx,ecx
+ shrd eax,eax,7
+ mov edi,ebp
+ xor esi,ebx
+ shld ebp,ebp,5
+ add edx,esi
+ xor edi,eax
+ xor eax,ebx
+ add edx,ebp
+ add ecx,DWORD[60+rsp]
+ and edi,eax
+ xor eax,ebx
+ shrd ebp,ebp,7
+ mov esi,edx
+ xor edi,eax
+ shld edx,edx,5
+ add ecx,edi
+ xor esi,ebp
+ xor ebp,eax
+ add ecx,edx
+ vpalignr xmm8,xmm7,xmm6,8
+ vpxor xmm0,xmm0,xmm4
+ add ebx,DWORD[rsp]
+ and esi,ebp
+ xor ebp,eax
+ shrd edx,edx,7
+ vpxor xmm0,xmm0,xmm1
+ mov edi,ecx
+ xor esi,ebp
+ vpaddd xmm9,xmm11,xmm7
+ shld ecx,ecx,5
+ add ebx,esi
+ vpxor xmm0,xmm0,xmm8
+ xor edi,edx
+ xor edx,ebp
+ add ebx,ecx
+ add eax,DWORD[4+rsp]
+ vpsrld xmm8,xmm0,30
+ vmovdqa XMMWORD[48+rsp],xmm9
+ and edi,edx
+ xor edx,ebp
+ shrd ecx,ecx,7
+ mov esi,ebx
+ vpslld xmm0,xmm0,2
+ xor edi,edx
+ shld ebx,ebx,5
+ add eax,edi
+ xor esi,ecx
+ xor ecx,edx
+ add eax,ebx
+ add ebp,DWORD[8+rsp]
+ and esi,ecx
+ vpor xmm0,xmm0,xmm8
+ xor ecx,edx
+ shrd ebx,ebx,7
+ mov edi,eax
+ xor esi,ecx
+ shld eax,eax,5
+ add ebp,esi
+ xor edi,ebx
+ xor ebx,ecx
+ add ebp,eax
+ add edx,DWORD[12+rsp]
+ and edi,ebx
+ xor ebx,ecx
+ shrd eax,eax,7
+ mov esi,ebp
+ xor edi,ebx
+ shld ebp,ebp,5
+ add edx,edi
+ xor esi,eax
+ xor eax,ebx
+ add edx,ebp
+ vpalignr xmm8,xmm0,xmm7,8
+ vpxor xmm1,xmm1,xmm5
+ add ecx,DWORD[16+rsp]
+ and esi,eax
+ xor eax,ebx
+ shrd ebp,ebp,7
+ vpxor xmm1,xmm1,xmm2
+ mov edi,edx
+ xor esi,eax
+ vpaddd xmm9,xmm11,xmm0
+ shld edx,edx,5
+ add ecx,esi
+ vpxor xmm1,xmm1,xmm8
+ xor edi,ebp
+ xor ebp,eax
+ add ecx,edx
+ add ebx,DWORD[20+rsp]
+ vpsrld xmm8,xmm1,30
+ vmovdqa XMMWORD[rsp],xmm9
+ and edi,ebp
+ xor ebp,eax
+ shrd edx,edx,7
+ mov esi,ecx
+ vpslld xmm1,xmm1,2
+ xor edi,ebp
+ shld ecx,ecx,5
+ add ebx,edi
+ xor esi,edx
+ xor edx,ebp
+ add ebx,ecx
+ add eax,DWORD[24+rsp]
+ and esi,edx
+ vpor xmm1,xmm1,xmm8
+ xor edx,ebp
+ shrd ecx,ecx,7
+ mov edi,ebx
+ xor esi,edx
+ shld ebx,ebx,5
+ add eax,esi
+ xor edi,ecx
+ xor ecx,edx
+ add eax,ebx
+ add ebp,DWORD[28+rsp]
+ and edi,ecx
+ xor ecx,edx
+ shrd ebx,ebx,7
+ mov esi,eax
+ xor edi,ecx
+ shld eax,eax,5
+ add ebp,edi
+ xor esi,ebx
+ xor ebx,ecx
+ add ebp,eax
+ vpalignr xmm8,xmm1,xmm0,8
+ vpxor xmm2,xmm2,xmm6
+ add edx,DWORD[32+rsp]
+ and esi,ebx
+ xor ebx,ecx
+ shrd eax,eax,7
+ vpxor xmm2,xmm2,xmm3
+ mov edi,ebp
+ xor esi,ebx
+ vpaddd xmm9,xmm11,xmm1
+ shld ebp,ebp,5
+ add edx,esi
+ vpxor xmm2,xmm2,xmm8
+ xor edi,eax
+ xor eax,ebx
+ add edx,ebp
+ add ecx,DWORD[36+rsp]
+ vpsrld xmm8,xmm2,30
+ vmovdqa XMMWORD[16+rsp],xmm9
+ and edi,eax
+ xor eax,ebx
+ shrd ebp,ebp,7
+ mov esi,edx
+ vpslld xmm2,xmm2,2
+ xor edi,eax
+ shld edx,edx,5
+ add ecx,edi
+ xor esi,ebp
+ xor ebp,eax
+ add ecx,edx
+ add ebx,DWORD[40+rsp]
+ and esi,ebp
+ vpor xmm2,xmm2,xmm8
+ xor ebp,eax
+ shrd edx,edx,7
+ mov edi,ecx
+ xor esi,ebp
+ shld ecx,ecx,5
+ add ebx,esi
+ xor edi,edx
+ xor edx,ebp
+ add ebx,ecx
+ add eax,DWORD[44+rsp]
+ and edi,edx
+ xor edx,ebp
+ shrd ecx,ecx,7
+ mov esi,ebx
+ xor edi,edx
+ shld ebx,ebx,5
+ add eax,edi
+ xor esi,edx
+ add eax,ebx
+ vpalignr xmm8,xmm2,xmm1,8
+ vpxor xmm3,xmm3,xmm7
+ add ebp,DWORD[48+rsp]
+ xor esi,ecx
+ mov edi,eax
+ shld eax,eax,5
+ vpxor xmm3,xmm3,xmm4
+ add ebp,esi
+ xor edi,ecx
+ vpaddd xmm9,xmm11,xmm2
+ shrd ebx,ebx,7
+ add ebp,eax
+ vpxor xmm3,xmm3,xmm8
+ add edx,DWORD[52+rsp]
+ xor edi,ebx
+ mov esi,ebp
+ shld ebp,ebp,5
+ vpsrld xmm8,xmm3,30
+ vmovdqa XMMWORD[32+rsp],xmm9
+ add edx,edi
+ xor esi,ebx
+ shrd eax,eax,7
+ add edx,ebp
+ vpslld xmm3,xmm3,2
+ add ecx,DWORD[56+rsp]
+ xor esi,eax
+ mov edi,edx
+ shld edx,edx,5
+ add ecx,esi
+ xor edi,eax
+ shrd ebp,ebp,7
+ add ecx,edx
+ vpor xmm3,xmm3,xmm8
+ add ebx,DWORD[60+rsp]
+ xor edi,ebp
+ mov esi,ecx
+ shld ecx,ecx,5
+ add ebx,edi
+ xor esi,ebp
+ shrd edx,edx,7
+ add ebx,ecx
+ add eax,DWORD[rsp]
+ vpaddd xmm9,xmm11,xmm3
+ xor esi,edx
+ mov edi,ebx
+ shld ebx,ebx,5
+ add eax,esi
+ vmovdqa XMMWORD[48+rsp],xmm9
+ xor edi,edx
+ shrd ecx,ecx,7
+ add eax,ebx
+ add ebp,DWORD[4+rsp]
+ xor edi,ecx
+ mov esi,eax
+ shld eax,eax,5
+ add ebp,edi
+ xor esi,ecx
+ shrd ebx,ebx,7
+ add ebp,eax
+ add edx,DWORD[8+rsp]
+ xor esi,ebx
+ mov edi,ebp
+ shld ebp,ebp,5
+ add edx,esi
+ xor edi,ebx
+ shrd eax,eax,7
+ add edx,ebp
+ add ecx,DWORD[12+rsp]
+ xor edi,eax
+ mov esi,edx
+ shld edx,edx,5
+ add ecx,edi
+ xor esi,eax
+ shrd ebp,ebp,7
+ add ecx,edx
+ cmp r9,r10
+ je NEAR $L$done_avx
+ vmovdqa xmm6,XMMWORD[64+r11]
+ vmovdqa xmm11,XMMWORD[((-64))+r11]
+ vmovdqu xmm0,XMMWORD[r9]
+ vmovdqu xmm1,XMMWORD[16+r9]
+ vmovdqu xmm2,XMMWORD[32+r9]
+ vmovdqu xmm3,XMMWORD[48+r9]
+ vpshufb xmm0,xmm0,xmm6
+ add r9,64
+ add ebx,DWORD[16+rsp]
+ xor esi,ebp
+ vpshufb xmm1,xmm1,xmm6
+ mov edi,ecx
+ shld ecx,ecx,5
+ vpaddd xmm4,xmm0,xmm11
+ add ebx,esi
+ xor edi,ebp
+ shrd edx,edx,7
+ add ebx,ecx
+ vmovdqa XMMWORD[rsp],xmm4
+ add eax,DWORD[20+rsp]
+ xor edi,edx
+ mov esi,ebx
+ shld ebx,ebx,5
+ add eax,edi
+ xor esi,edx
+ shrd ecx,ecx,7
+ add eax,ebx
+ add ebp,DWORD[24+rsp]
+ xor esi,ecx
+ mov edi,eax
+ shld eax,eax,5
+ add ebp,esi
+ xor edi,ecx
+ shrd ebx,ebx,7
+ add ebp,eax
+ add edx,DWORD[28+rsp]
+ xor edi,ebx
+ mov esi,ebp
+ shld ebp,ebp,5
+ add edx,edi
+ xor esi,ebx
+ shrd eax,eax,7
+ add edx,ebp
+ add ecx,DWORD[32+rsp]
+ xor esi,eax
+ vpshufb xmm2,xmm2,xmm6
+ mov edi,edx
+ shld edx,edx,5
+ vpaddd xmm5,xmm1,xmm11
+ add ecx,esi
+ xor edi,eax
+ shrd ebp,ebp,7
+ add ecx,edx
+ vmovdqa XMMWORD[16+rsp],xmm5
+ add ebx,DWORD[36+rsp]
+ xor edi,ebp
+ mov esi,ecx
+ shld ecx,ecx,5
+ add ebx,edi
+ xor esi,ebp
+ shrd edx,edx,7
+ add ebx,ecx
+ add eax,DWORD[40+rsp]
+ xor esi,edx
+ mov edi,ebx
+ shld ebx,ebx,5
+ add eax,esi
+ xor edi,edx
+ shrd ecx,ecx,7
+ add eax,ebx
+ add ebp,DWORD[44+rsp]
+ xor edi,ecx
+ mov esi,eax
+ shld eax,eax,5
+ add ebp,edi
+ xor esi,ecx
+ shrd ebx,ebx,7
+ add ebp,eax
+ add edx,DWORD[48+rsp]
+ xor esi,ebx
+ vpshufb xmm3,xmm3,xmm6
+ mov edi,ebp
+ shld ebp,ebp,5
+ vpaddd xmm6,xmm2,xmm11
+ add edx,esi
+ xor edi,ebx
+ shrd eax,eax,7
+ add edx,ebp
+ vmovdqa XMMWORD[32+rsp],xmm6
+ add ecx,DWORD[52+rsp]
+ xor edi,eax
+ mov esi,edx
+ shld edx,edx,5
+ add ecx,edi
+ xor esi,eax
+ shrd ebp,ebp,7
+ add ecx,edx
+ add ebx,DWORD[56+rsp]
+ xor esi,ebp
+ mov edi,ecx
+ shld ecx,ecx,5
+ add ebx,esi
+ xor edi,ebp
+ shrd edx,edx,7
+ add ebx,ecx
+ add eax,DWORD[60+rsp]
+ xor edi,edx
+ mov esi,ebx
+ shld ebx,ebx,5
+ add eax,edi
+ shrd ecx,ecx,7
+ add eax,ebx
+ add eax,DWORD[r8]
+ add esi,DWORD[4+r8]
+ add ecx,DWORD[8+r8]
+ add edx,DWORD[12+r8]
+ mov DWORD[r8],eax
+ add ebp,DWORD[16+r8]
+ mov DWORD[4+r8],esi
+ mov ebx,esi
+ mov DWORD[8+r8],ecx
+ mov edi,ecx
+ mov DWORD[12+r8],edx
+ xor edi,edx
+ mov DWORD[16+r8],ebp
+ and esi,edi
+ jmp NEAR $L$oop_avx
+
+ALIGN 16
+$L$done_avx:
+ add ebx,DWORD[16+rsp]
+ xor esi,ebp
+ mov edi,ecx
+ shld ecx,ecx,5
+ add ebx,esi
+ xor edi,ebp
+ shrd edx,edx,7
+ add ebx,ecx
+ add eax,DWORD[20+rsp]
+ xor edi,edx
+ mov esi,ebx
+ shld ebx,ebx,5
+ add eax,edi
+ xor esi,edx
+ shrd ecx,ecx,7
+ add eax,ebx
+ add ebp,DWORD[24+rsp]
+ xor esi,ecx
+ mov edi,eax
+ shld eax,eax,5
+ add ebp,esi
+ xor edi,ecx
+ shrd ebx,ebx,7
+ add ebp,eax
+ add edx,DWORD[28+rsp]
+ xor edi,ebx
+ mov esi,ebp
+ shld ebp,ebp,5
+ add edx,edi
+ xor esi,ebx
+ shrd eax,eax,7
+ add edx,ebp
+ add ecx,DWORD[32+rsp]
+ xor esi,eax
+ mov edi,edx
+ shld edx,edx,5
+ add ecx,esi
+ xor edi,eax
+ shrd ebp,ebp,7
+ add ecx,edx
+ add ebx,DWORD[36+rsp]
+ xor edi,ebp
+ mov esi,ecx
+ shld ecx,ecx,5
+ add ebx,edi
+ xor esi,ebp
+ shrd edx,edx,7
+ add ebx,ecx
+ add eax,DWORD[40+rsp]
+ xor esi,edx
+ mov edi,ebx
+ shld ebx,ebx,5
+ add eax,esi
+ xor edi,edx
+ shrd ecx,ecx,7
+ add eax,ebx
+ add ebp,DWORD[44+rsp]
+ xor edi,ecx
+ mov esi,eax
+ shld eax,eax,5
+ add ebp,edi
+ xor esi,ecx
+ shrd ebx,ebx,7
+ add ebp,eax
+ add edx,DWORD[48+rsp]
+ xor esi,ebx
+ mov edi,ebp
+ shld ebp,ebp,5
+ add edx,esi
+ xor edi,ebx
+ shrd eax,eax,7
+ add edx,ebp
+ add ecx,DWORD[52+rsp]
+ xor edi,eax
+ mov esi,edx
+ shld edx,edx,5
+ add ecx,edi
+ xor esi,eax
+ shrd ebp,ebp,7
+ add ecx,edx
+ add ebx,DWORD[56+rsp]
+ xor esi,ebp
+ mov edi,ecx
+ shld ecx,ecx,5
+ add ebx,esi
+ xor edi,ebp
+ shrd edx,edx,7
+ add ebx,ecx
+ add eax,DWORD[60+rsp]
+ xor edi,edx
+ mov esi,ebx
+ shld ebx,ebx,5
+ add eax,edi
+ shrd ecx,ecx,7
+ add eax,ebx
+ vzeroupper
+
+ add eax,DWORD[r8]
+ add esi,DWORD[4+r8]
+ add ecx,DWORD[8+r8]
+ mov DWORD[r8],eax
+ add edx,DWORD[12+r8]
+ mov DWORD[4+r8],esi
+ add ebp,DWORD[16+r8]
+ mov DWORD[8+r8],ecx
+ mov DWORD[12+r8],edx
+ mov DWORD[16+r8],ebp
+ movaps xmm6,XMMWORD[((-40-96))+r14]
+ movaps xmm7,XMMWORD[((-40-80))+r14]
+ movaps xmm8,XMMWORD[((-40-64))+r14]
+ movaps xmm9,XMMWORD[((-40-48))+r14]
+ movaps xmm10,XMMWORD[((-40-32))+r14]
+ movaps xmm11,XMMWORD[((-40-16))+r14]
+ lea rsi,[r14]
+ mov r14,QWORD[((-40))+rsi]
+ mov r13,QWORD[((-32))+rsi]
+ mov r12,QWORD[((-24))+rsi]
+ mov rbp,QWORD[((-16))+rsi]
+ mov rbx,QWORD[((-8))+rsi]
+ lea rsp,[rsi]
+$L$epilogue_avx:
+ mov rdi,QWORD[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_sha1_block_data_order_avx:
ALIGN 64
K_XX_XX:
DD 0x5a827999,0x5a827999,0x5a827999,0x5a827999
@@ -2605,6 +3750,9 @@ ALIGN 4
DD $L$SEH_begin_sha1_block_data_order_ssse3 wrt ..imagebase
DD $L$SEH_end_sha1_block_data_order_ssse3 wrt ..imagebase
DD $L$SEH_info_sha1_block_data_order_ssse3 wrt ..imagebase
+ DD $L$SEH_begin_sha1_block_data_order_avx wrt ..imagebase
+ DD $L$SEH_end_sha1_block_data_order_avx wrt ..imagebase
+ DD $L$SEH_info_sha1_block_data_order_avx wrt ..imagebase
section .xdata rdata align=8
ALIGN 8
$L$SEH_info_sha1_block_data_order:
@@ -2614,3 +3762,7 @@ $L$SEH_info_sha1_block_data_order_ssse3:
DB 9,0,0,0
DD ssse3_handler wrt ..imagebase
DD $L$prologue_ssse3 wrt ..imagebase,$L$epilogue_ssse3 wrt ..imagebase
+$L$SEH_info_sha1_block_data_order_avx:
+DB 9,0,0,0
+ DD ssse3_handler wrt ..imagebase
+ DD $L$prologue_avx wrt ..imagebase,$L$epilogue_avx wrt ..imagebase
diff --git a/win-x86_64/crypto/sha/sha256-x86_64.asm b/win-x86_64/crypto/sha/sha256-x86_64.asm
index e6193c5..efaf9b5 100644
--- a/win-x86_64/crypto/sha/sha256-x86_64.asm
+++ b/win-x86_64/crypto/sha/sha256-x86_64.asm
@@ -23,6 +23,11 @@ $L$SEH_begin_sha256_block_data_order:
mov r9d,DWORD[r11]
mov r10d,DWORD[4+r11]
mov r11d,DWORD[8+r11]
+ and r9d,1073741824
+ and r10d,268435968
+ or r10d,r9d
+ cmp r10d,1342177792
+ je NEAR $L$avx_shortcut
test r10d,512
jnz NEAR $L$ssse3_shortcut
push rbx
@@ -2877,6 +2882,1082 @@ $L$epilogue_ssse3:
mov rsi,QWORD[16+rsp]
DB 0F3h,0C3h ;repret
$L$SEH_end_sha256_block_data_order_ssse3:
+
+ALIGN 64
+sha256_block_data_order_avx:
+ mov QWORD[8+rsp],rdi ;WIN64 prologue
+ mov QWORD[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_sha256_block_data_order_avx:
+ mov rdi,rcx
+ mov rsi,rdx
+ mov rdx,r8
+
+
+$L$avx_shortcut:
+ push rbx
+ push rbp
+ push r12
+ push r13
+ push r14
+ push r15
+ mov r11,rsp
+ shl rdx,4
+ sub rsp,160
+ lea rdx,[rdx*4+rsi]
+ and rsp,-64
+ mov QWORD[((64+0))+rsp],rdi
+ mov QWORD[((64+8))+rsp],rsi
+ mov QWORD[((64+16))+rsp],rdx
+ mov QWORD[((64+24))+rsp],r11
+ movaps XMMWORD[(64+32)+rsp],xmm6
+ movaps XMMWORD[(64+48)+rsp],xmm7
+ movaps XMMWORD[(64+64)+rsp],xmm8
+ movaps XMMWORD[(64+80)+rsp],xmm9
+$L$prologue_avx:
+
+ vzeroupper
+ mov eax,DWORD[rdi]
+ mov ebx,DWORD[4+rdi]
+ mov ecx,DWORD[8+rdi]
+ mov edx,DWORD[12+rdi]
+ mov r8d,DWORD[16+rdi]
+ mov r9d,DWORD[20+rdi]
+ mov r10d,DWORD[24+rdi]
+ mov r11d,DWORD[28+rdi]
+ vmovdqa xmm8,XMMWORD[((K256+512+32))]
+ vmovdqa xmm9,XMMWORD[((K256+512+64))]
+ jmp NEAR $L$loop_avx
+ALIGN 16
+$L$loop_avx:
+ vmovdqa xmm7,XMMWORD[((K256+512))]
+ vmovdqu xmm0,XMMWORD[rsi]
+ vmovdqu xmm1,XMMWORD[16+rsi]
+ vmovdqu xmm2,XMMWORD[32+rsi]
+ vmovdqu xmm3,XMMWORD[48+rsi]
+ vpshufb xmm0,xmm0,xmm7
+ lea rbp,[K256]
+ vpshufb xmm1,xmm1,xmm7
+ vpshufb xmm2,xmm2,xmm7
+ vpaddd xmm4,xmm0,XMMWORD[rbp]
+ vpshufb xmm3,xmm3,xmm7
+ vpaddd xmm5,xmm1,XMMWORD[32+rbp]
+ vpaddd xmm6,xmm2,XMMWORD[64+rbp]
+ vpaddd xmm7,xmm3,XMMWORD[96+rbp]
+ vmovdqa XMMWORD[rsp],xmm4
+ mov r14d,eax
+ vmovdqa XMMWORD[16+rsp],xmm5
+ mov edi,ebx
+ vmovdqa XMMWORD[32+rsp],xmm6
+ xor edi,ecx
+ vmovdqa XMMWORD[48+rsp],xmm7
+ mov r13d,r8d
+ jmp NEAR $L$avx_00_47
+
+ALIGN 16
+$L$avx_00_47:
+ sub rbp,-128
+ vpalignr xmm4,xmm1,xmm0,4
+ shrd r13d,r13d,14
+ mov eax,r14d
+ mov r12d,r9d
+ vpalignr xmm7,xmm3,xmm2,4
+ shrd r14d,r14d,9
+ xor r13d,r8d
+ xor r12d,r10d
+ vpsrld xmm6,xmm4,7
+ shrd r13d,r13d,5
+ xor r14d,eax
+ and r12d,r8d
+ vpaddd xmm0,xmm0,xmm7
+ xor r13d,r8d
+ add r11d,DWORD[rsp]
+ mov r15d,eax
+ vpsrld xmm7,xmm4,3
+ xor r12d,r10d
+ shrd r14d,r14d,11
+ xor r15d,ebx
+ vpslld xmm5,xmm4,14
+ add r11d,r12d
+ shrd r13d,r13d,6
+ and edi,r15d
+ vpxor xmm4,xmm7,xmm6
+ xor r14d,eax
+ add r11d,r13d
+ xor edi,ebx
+ vpshufd xmm7,xmm3,250
+ shrd r14d,r14d,2
+ add edx,r11d
+ add r11d,edi
+ vpsrld xmm6,xmm6,11
+ mov r13d,edx
+ add r14d,r11d
+ shrd r13d,r13d,14
+ vpxor xmm4,xmm4,xmm5
+ mov r11d,r14d
+ mov r12d,r8d
+ shrd r14d,r14d,9
+ vpslld xmm5,xmm5,11
+ xor r13d,edx
+ xor r12d,r9d
+ shrd r13d,r13d,5
+ vpxor xmm4,xmm4,xmm6
+ xor r14d,r11d
+ and r12d,edx
+ xor r13d,edx
+ vpsrld xmm6,xmm7,10
+ add r10d,DWORD[4+rsp]
+ mov edi,r11d
+ xor r12d,r9d
+ vpxor xmm4,xmm4,xmm5
+ shrd r14d,r14d,11
+ xor edi,eax
+ add r10d,r12d
+ vpsrlq xmm7,xmm7,17
+ shrd r13d,r13d,6
+ and r15d,edi
+ xor r14d,r11d
+ vpaddd xmm0,xmm0,xmm4
+ add r10d,r13d
+ xor r15d,eax
+ shrd r14d,r14d,2
+ vpxor xmm6,xmm6,xmm7
+ add ecx,r10d
+ add r10d,r15d
+ mov r13d,ecx
+ vpsrlq xmm7,xmm7,2
+ add r14d,r10d
+ shrd r13d,r13d,14
+ mov r10d,r14d
+ vpxor xmm6,xmm6,xmm7
+ mov r12d,edx
+ shrd r14d,r14d,9
+ xor r13d,ecx
+ vpshufb xmm6,xmm6,xmm8
+ xor r12d,r8d
+ shrd r13d,r13d,5
+ xor r14d,r10d
+ vpaddd xmm0,xmm0,xmm6
+ and r12d,ecx
+ xor r13d,ecx
+ add r9d,DWORD[8+rsp]
+ vpshufd xmm7,xmm0,80
+ mov r15d,r10d
+ xor r12d,r8d
+ shrd r14d,r14d,11
+ vpsrld xmm6,xmm7,10
+ xor r15d,r11d
+ add r9d,r12d
+ shrd r13d,r13d,6
+ vpsrlq xmm7,xmm7,17
+ and edi,r15d
+ xor r14d,r10d
+ add r9d,r13d
+ vpxor xmm6,xmm6,xmm7
+ xor edi,r11d
+ shrd r14d,r14d,2
+ add ebx,r9d
+ vpsrlq xmm7,xmm7,2
+ add r9d,edi
+ mov r13d,ebx
+ add r14d,r9d
+ vpxor xmm6,xmm6,xmm7
+ shrd r13d,r13d,14
+ mov r9d,r14d
+ mov r12d,ecx
+ vpshufb xmm6,xmm6,xmm9
+ shrd r14d,r14d,9
+ xor r13d,ebx
+ xor r12d,edx
+ vpaddd xmm0,xmm0,xmm6
+ shrd r13d,r13d,5
+ xor r14d,r9d
+ and r12d,ebx
+ vpaddd xmm6,xmm0,XMMWORD[rbp]
+ xor r13d,ebx
+ add r8d,DWORD[12+rsp]
+ mov edi,r9d
+ xor r12d,edx
+ shrd r14d,r14d,11
+ xor edi,r10d
+ add r8d,r12d
+ shrd r13d,r13d,6
+ and r15d,edi
+ xor r14d,r9d
+ add r8d,r13d
+ xor r15d,r10d
+ shrd r14d,r14d,2
+ add eax,r8d
+ add r8d,r15d
+ mov r13d,eax
+ add r14d,r8d
+ vmovdqa XMMWORD[rsp],xmm6
+ vpalignr xmm4,xmm2,xmm1,4
+ shrd r13d,r13d,14
+ mov r8d,r14d
+ mov r12d,ebx
+ vpalignr xmm7,xmm0,xmm3,4
+ shrd r14d,r14d,9
+ xor r13d,eax
+ xor r12d,ecx
+ vpsrld xmm6,xmm4,7
+ shrd r13d,r13d,5
+ xor r14d,r8d
+ and r12d,eax
+ vpaddd xmm1,xmm1,xmm7
+ xor r13d,eax
+ add edx,DWORD[16+rsp]
+ mov r15d,r8d
+ vpsrld xmm7,xmm4,3
+ xor r12d,ecx
+ shrd r14d,r14d,11
+ xor r15d,r9d
+ vpslld xmm5,xmm4,14
+ add edx,r12d
+ shrd r13d,r13d,6
+ and edi,r15d
+ vpxor xmm4,xmm7,xmm6
+ xor r14d,r8d
+ add edx,r13d
+ xor edi,r9d
+ vpshufd xmm7,xmm0,250
+ shrd r14d,r14d,2
+ add r11d,edx
+ add edx,edi
+ vpsrld xmm6,xmm6,11
+ mov r13d,r11d
+ add r14d,edx
+ shrd r13d,r13d,14
+ vpxor xmm4,xmm4,xmm5
+ mov edx,r14d
+ mov r12d,eax
+ shrd r14d,r14d,9
+ vpslld xmm5,xmm5,11
+ xor r13d,r11d
+ xor r12d,ebx
+ shrd r13d,r13d,5
+ vpxor xmm4,xmm4,xmm6
+ xor r14d,edx
+ and r12d,r11d
+ xor r13d,r11d
+ vpsrld xmm6,xmm7,10
+ add ecx,DWORD[20+rsp]
+ mov edi,edx
+ xor r12d,ebx
+ vpxor xmm4,xmm4,xmm5
+ shrd r14d,r14d,11
+ xor edi,r8d
+ add ecx,r12d
+ vpsrlq xmm7,xmm7,17
+ shrd r13d,r13d,6
+ and r15d,edi
+ xor r14d,edx
+ vpaddd xmm1,xmm1,xmm4
+ add ecx,r13d
+ xor r15d,r8d
+ shrd r14d,r14d,2
+ vpxor xmm6,xmm6,xmm7
+ add r10d,ecx
+ add ecx,r15d
+ mov r13d,r10d
+ vpsrlq xmm7,xmm7,2
+ add r14d,ecx
+ shrd r13d,r13d,14
+ mov ecx,r14d
+ vpxor xmm6,xmm6,xmm7
+ mov r12d,r11d
+ shrd r14d,r14d,9
+ xor r13d,r10d
+ vpshufb xmm6,xmm6,xmm8
+ xor r12d,eax
+ shrd r13d,r13d,5
+ xor r14d,ecx
+ vpaddd xmm1,xmm1,xmm6
+ and r12d,r10d
+ xor r13d,r10d
+ add ebx,DWORD[24+rsp]
+ vpshufd xmm7,xmm1,80
+ mov r15d,ecx
+ xor r12d,eax
+ shrd r14d,r14d,11
+ vpsrld xmm6,xmm7,10
+ xor r15d,edx
+ add ebx,r12d
+ shrd r13d,r13d,6
+ vpsrlq xmm7,xmm7,17
+ and edi,r15d
+ xor r14d,ecx
+ add ebx,r13d
+ vpxor xmm6,xmm6,xmm7
+ xor edi,edx
+ shrd r14d,r14d,2
+ add r9d,ebx
+ vpsrlq xmm7,xmm7,2
+ add ebx,edi
+ mov r13d,r9d
+ add r14d,ebx
+ vpxor xmm6,xmm6,xmm7
+ shrd r13d,r13d,14
+ mov ebx,r14d
+ mov r12d,r10d
+ vpshufb xmm6,xmm6,xmm9
+ shrd r14d,r14d,9
+ xor r13d,r9d
+ xor r12d,r11d
+ vpaddd xmm1,xmm1,xmm6
+ shrd r13d,r13d,5
+ xor r14d,ebx
+ and r12d,r9d
+ vpaddd xmm6,xmm1,XMMWORD[32+rbp]
+ xor r13d,r9d
+ add eax,DWORD[28+rsp]
+ mov edi,ebx
+ xor r12d,r11d
+ shrd r14d,r14d,11
+ xor edi,ecx
+ add eax,r12d
+ shrd r13d,r13d,6
+ and r15d,edi
+ xor r14d,ebx
+ add eax,r13d
+ xor r15d,ecx
+ shrd r14d,r14d,2
+ add r8d,eax
+ add eax,r15d
+ mov r13d,r8d
+ add r14d,eax
+ vmovdqa XMMWORD[16+rsp],xmm6
+ vpalignr xmm4,xmm3,xmm2,4
+ shrd r13d,r13d,14
+ mov eax,r14d
+ mov r12d,r9d
+ vpalignr xmm7,xmm1,xmm0,4
+ shrd r14d,r14d,9
+ xor r13d,r8d
+ xor r12d,r10d
+ vpsrld xmm6,xmm4,7
+ shrd r13d,r13d,5
+ xor r14d,eax
+ and r12d,r8d
+ vpaddd xmm2,xmm2,xmm7
+ xor r13d,r8d
+ add r11d,DWORD[32+rsp]
+ mov r15d,eax
+ vpsrld xmm7,xmm4,3
+ xor r12d,r10d
+ shrd r14d,r14d,11
+ xor r15d,ebx
+ vpslld xmm5,xmm4,14
+ add r11d,r12d
+ shrd r13d,r13d,6
+ and edi,r15d
+ vpxor xmm4,xmm7,xmm6
+ xor r14d,eax
+ add r11d,r13d
+ xor edi,ebx
+ vpshufd xmm7,xmm1,250
+ shrd r14d,r14d,2
+ add edx,r11d
+ add r11d,edi
+ vpsrld xmm6,xmm6,11
+ mov r13d,edx
+ add r14d,r11d
+ shrd r13d,r13d,14
+ vpxor xmm4,xmm4,xmm5
+ mov r11d,r14d
+ mov r12d,r8d
+ shrd r14d,r14d,9
+ vpslld xmm5,xmm5,11
+ xor r13d,edx
+ xor r12d,r9d
+ shrd r13d,r13d,5
+ vpxor xmm4,xmm4,xmm6
+ xor r14d,r11d
+ and r12d,edx
+ xor r13d,edx
+ vpsrld xmm6,xmm7,10
+ add r10d,DWORD[36+rsp]
+ mov edi,r11d
+ xor r12d,r9d
+ vpxor xmm4,xmm4,xmm5
+ shrd r14d,r14d,11
+ xor edi,eax
+ add r10d,r12d
+ vpsrlq xmm7,xmm7,17
+ shrd r13d,r13d,6
+ and r15d,edi
+ xor r14d,r11d
+ vpaddd xmm2,xmm2,xmm4
+ add r10d,r13d
+ xor r15d,eax
+ shrd r14d,r14d,2
+ vpxor xmm6,xmm6,xmm7
+ add ecx,r10d
+ add r10d,r15d
+ mov r13d,ecx
+ vpsrlq xmm7,xmm7,2
+ add r14d,r10d
+ shrd r13d,r13d,14
+ mov r10d,r14d
+ vpxor xmm6,xmm6,xmm7
+ mov r12d,edx
+ shrd r14d,r14d,9
+ xor r13d,ecx
+ vpshufb xmm6,xmm6,xmm8
+ xor r12d,r8d
+ shrd r13d,r13d,5
+ xor r14d,r10d
+ vpaddd xmm2,xmm2,xmm6
+ and r12d,ecx
+ xor r13d,ecx
+ add r9d,DWORD[40+rsp]
+ vpshufd xmm7,xmm2,80
+ mov r15d,r10d
+ xor r12d,r8d
+ shrd r14d,r14d,11
+ vpsrld xmm6,xmm7,10
+ xor r15d,r11d
+ add r9d,r12d
+ shrd r13d,r13d,6
+ vpsrlq xmm7,xmm7,17
+ and edi,r15d
+ xor r14d,r10d
+ add r9d,r13d
+ vpxor xmm6,xmm6,xmm7
+ xor edi,r11d
+ shrd r14d,r14d,2
+ add ebx,r9d
+ vpsrlq xmm7,xmm7,2
+ add r9d,edi
+ mov r13d,ebx
+ add r14d,r9d
+ vpxor xmm6,xmm6,xmm7
+ shrd r13d,r13d,14
+ mov r9d,r14d
+ mov r12d,ecx
+ vpshufb xmm6,xmm6,xmm9
+ shrd r14d,r14d,9
+ xor r13d,ebx
+ xor r12d,edx
+ vpaddd xmm2,xmm2,xmm6
+ shrd r13d,r13d,5
+ xor r14d,r9d
+ and r12d,ebx
+ vpaddd xmm6,xmm2,XMMWORD[64+rbp]
+ xor r13d,ebx
+ add r8d,DWORD[44+rsp]
+ mov edi,r9d
+ xor r12d,edx
+ shrd r14d,r14d,11
+ xor edi,r10d
+ add r8d,r12d
+ shrd r13d,r13d,6
+ and r15d,edi
+ xor r14d,r9d
+ add r8d,r13d
+ xor r15d,r10d
+ shrd r14d,r14d,2
+ add eax,r8d
+ add r8d,r15d
+ mov r13d,eax
+ add r14d,r8d
+ vmovdqa XMMWORD[32+rsp],xmm6
+ vpalignr xmm4,xmm0,xmm3,4
+ shrd r13d,r13d,14
+ mov r8d,r14d
+ mov r12d,ebx
+ vpalignr xmm7,xmm2,xmm1,4
+ shrd r14d,r14d,9
+ xor r13d,eax
+ xor r12d,ecx
+ vpsrld xmm6,xmm4,7
+ shrd r13d,r13d,5
+ xor r14d,r8d
+ and r12d,eax
+ vpaddd xmm3,xmm3,xmm7
+ xor r13d,eax
+ add edx,DWORD[48+rsp]
+ mov r15d,r8d
+ vpsrld xmm7,xmm4,3
+ xor r12d,ecx
+ shrd r14d,r14d,11
+ xor r15d,r9d
+ vpslld xmm5,xmm4,14
+ add edx,r12d
+ shrd r13d,r13d,6
+ and edi,r15d
+ vpxor xmm4,xmm7,xmm6
+ xor r14d,r8d
+ add edx,r13d
+ xor edi,r9d
+ vpshufd xmm7,xmm2,250
+ shrd r14d,r14d,2
+ add r11d,edx
+ add edx,edi
+ vpsrld xmm6,xmm6,11
+ mov r13d,r11d
+ add r14d,edx
+ shrd r13d,r13d,14
+ vpxor xmm4,xmm4,xmm5
+ mov edx,r14d
+ mov r12d,eax
+ shrd r14d,r14d,9
+ vpslld xmm5,xmm5,11
+ xor r13d,r11d
+ xor r12d,ebx
+ shrd r13d,r13d,5
+ vpxor xmm4,xmm4,xmm6
+ xor r14d,edx
+ and r12d,r11d
+ xor r13d,r11d
+ vpsrld xmm6,xmm7,10
+ add ecx,DWORD[52+rsp]
+ mov edi,edx
+ xor r12d,ebx
+ vpxor xmm4,xmm4,xmm5
+ shrd r14d,r14d,11
+ xor edi,r8d
+ add ecx,r12d
+ vpsrlq xmm7,xmm7,17
+ shrd r13d,r13d,6
+ and r15d,edi
+ xor r14d,edx
+ vpaddd xmm3,xmm3,xmm4
+ add ecx,r13d
+ xor r15d,r8d
+ shrd r14d,r14d,2
+ vpxor xmm6,xmm6,xmm7
+ add r10d,ecx
+ add ecx,r15d
+ mov r13d,r10d
+ vpsrlq xmm7,xmm7,2
+ add r14d,ecx
+ shrd r13d,r13d,14
+ mov ecx,r14d
+ vpxor xmm6,xmm6,xmm7
+ mov r12d,r11d
+ shrd r14d,r14d,9
+ xor r13d,r10d
+ vpshufb xmm6,xmm6,xmm8
+ xor r12d,eax
+ shrd r13d,r13d,5
+ xor r14d,ecx
+ vpaddd xmm3,xmm3,xmm6
+ and r12d,r10d
+ xor r13d,r10d
+ add ebx,DWORD[56+rsp]
+ vpshufd xmm7,xmm3,80
+ mov r15d,ecx
+ xor r12d,eax
+ shrd r14d,r14d,11
+ vpsrld xmm6,xmm7,10
+ xor r15d,edx
+ add ebx,r12d
+ shrd r13d,r13d,6
+ vpsrlq xmm7,xmm7,17
+ and edi,r15d
+ xor r14d,ecx
+ add ebx,r13d
+ vpxor xmm6,xmm6,xmm7
+ xor edi,edx
+ shrd r14d,r14d,2
+ add r9d,ebx
+ vpsrlq xmm7,xmm7,2
+ add ebx,edi
+ mov r13d,r9d
+ add r14d,ebx
+ vpxor xmm6,xmm6,xmm7
+ shrd r13d,r13d,14
+ mov ebx,r14d
+ mov r12d,r10d
+ vpshufb xmm6,xmm6,xmm9
+ shrd r14d,r14d,9
+ xor r13d,r9d
+ xor r12d,r11d
+ vpaddd xmm3,xmm3,xmm6
+ shrd r13d,r13d,5
+ xor r14d,ebx
+ and r12d,r9d
+ vpaddd xmm6,xmm3,XMMWORD[96+rbp]
+ xor r13d,r9d
+ add eax,DWORD[60+rsp]
+ mov edi,ebx
+ xor r12d,r11d
+ shrd r14d,r14d,11
+ xor edi,ecx
+ add eax,r12d
+ shrd r13d,r13d,6
+ and r15d,edi
+ xor r14d,ebx
+ add eax,r13d
+ xor r15d,ecx
+ shrd r14d,r14d,2
+ add r8d,eax
+ add eax,r15d
+ mov r13d,r8d
+ add r14d,eax
+ vmovdqa XMMWORD[48+rsp],xmm6
+ cmp BYTE[131+rbp],0
+ jne NEAR $L$avx_00_47
+ shrd r13d,r13d,14
+ mov eax,r14d
+ mov r12d,r9d
+ shrd r14d,r14d,9
+ xor r13d,r8d
+ xor r12d,r10d
+ shrd r13d,r13d,5
+ xor r14d,eax
+ and r12d,r8d
+ xor r13d,r8d
+ add r11d,DWORD[rsp]
+ mov r15d,eax
+ xor r12d,r10d
+ shrd r14d,r14d,11
+ xor r15d,ebx
+ add r11d,r12d
+ shrd r13d,r13d,6
+ and edi,r15d
+ xor r14d,eax
+ add r11d,r13d
+ xor edi,ebx
+ shrd r14d,r14d,2
+ add edx,r11d
+ add r11d,edi
+ mov r13d,edx
+ add r14d,r11d
+ shrd r13d,r13d,14
+ mov r11d,r14d
+ mov r12d,r8d
+ shrd r14d,r14d,9
+ xor r13d,edx
+ xor r12d,r9d
+ shrd r13d,r13d,5
+ xor r14d,r11d
+ and r12d,edx
+ xor r13d,edx
+ add r10d,DWORD[4+rsp]
+ mov edi,r11d
+ xor r12d,r9d
+ shrd r14d,r14d,11
+ xor edi,eax
+ add r10d,r12d
+ shrd r13d,r13d,6
+ and r15d,edi
+ xor r14d,r11d
+ add r10d,r13d
+ xor r15d,eax
+ shrd r14d,r14d,2
+ add ecx,r10d
+ add r10d,r15d
+ mov r13d,ecx
+ add r14d,r10d
+ shrd r13d,r13d,14
+ mov r10d,r14d
+ mov r12d,edx
+ shrd r14d,r14d,9
+ xor r13d,ecx
+ xor r12d,r8d
+ shrd r13d,r13d,5
+ xor r14d,r10d
+ and r12d,ecx
+ xor r13d,ecx
+ add r9d,DWORD[8+rsp]
+ mov r15d,r10d
+ xor r12d,r8d
+ shrd r14d,r14d,11
+ xor r15d,r11d
+ add r9d,r12d
+ shrd r13d,r13d,6
+ and edi,r15d
+ xor r14d,r10d
+ add r9d,r13d
+ xor edi,r11d
+ shrd r14d,r14d,2
+ add ebx,r9d
+ add r9d,edi
+ mov r13d,ebx
+ add r14d,r9d
+ shrd r13d,r13d,14
+ mov r9d,r14d
+ mov r12d,ecx
+ shrd r14d,r14d,9
+ xor r13d,ebx
+ xor r12d,edx
+ shrd r13d,r13d,5
+ xor r14d,r9d
+ and r12d,ebx
+ xor r13d,ebx
+ add r8d,DWORD[12+rsp]
+ mov edi,r9d
+ xor r12d,edx
+ shrd r14d,r14d,11
+ xor edi,r10d
+ add r8d,r12d
+ shrd r13d,r13d,6
+ and r15d,edi
+ xor r14d,r9d
+ add r8d,r13d
+ xor r15d,r10d
+ shrd r14d,r14d,2
+ add eax,r8d
+ add r8d,r15d
+ mov r13d,eax
+ add r14d,r8d
+ shrd r13d,r13d,14
+ mov r8d,r14d
+ mov r12d,ebx
+ shrd r14d,r14d,9
+ xor r13d,eax
+ xor r12d,ecx
+ shrd r13d,r13d,5
+ xor r14d,r8d
+ and r12d,eax
+ xor r13d,eax
+ add edx,DWORD[16+rsp]
+ mov r15d,r8d
+ xor r12d,ecx
+ shrd r14d,r14d,11
+ xor r15d,r9d
+ add edx,r12d
+ shrd r13d,r13d,6
+ and edi,r15d
+ xor r14d,r8d
+ add edx,r13d
+ xor edi,r9d
+ shrd r14d,r14d,2
+ add r11d,edx
+ add edx,edi
+ mov r13d,r11d
+ add r14d,edx
+ shrd r13d,r13d,14
+ mov edx,r14d
+ mov r12d,eax
+ shrd r14d,r14d,9
+ xor r13d,r11d
+ xor r12d,ebx
+ shrd r13d,r13d,5
+ xor r14d,edx
+ and r12d,r11d
+ xor r13d,r11d
+ add ecx,DWORD[20+rsp]
+ mov edi,edx
+ xor r12d,ebx
+ shrd r14d,r14d,11
+ xor edi,r8d
+ add ecx,r12d
+ shrd r13d,r13d,6
+ and r15d,edi
+ xor r14d,edx
+ add ecx,r13d
+ xor r15d,r8d
+ shrd r14d,r14d,2
+ add r10d,ecx
+ add ecx,r15d
+ mov r13d,r10d
+ add r14d,ecx
+ shrd r13d,r13d,14
+ mov ecx,r14d
+ mov r12d,r11d
+ shrd r14d,r14d,9
+ xor r13d,r10d
+ xor r12d,eax
+ shrd r13d,r13d,5
+ xor r14d,ecx
+ and r12d,r10d
+ xor r13d,r10d
+ add ebx,DWORD[24+rsp]
+ mov r15d,ecx
+ xor r12d,eax
+ shrd r14d,r14d,11
+ xor r15d,edx
+ add ebx,r12d
+ shrd r13d,r13d,6
+ and edi,r15d
+ xor r14d,ecx
+ add ebx,r13d
+ xor edi,edx
+ shrd r14d,r14d,2
+ add r9d,ebx
+ add ebx,edi
+ mov r13d,r9d
+ add r14d,ebx
+ shrd r13d,r13d,14
+ mov ebx,r14d
+ mov r12d,r10d
+ shrd r14d,r14d,9
+ xor r13d,r9d
+ xor r12d,r11d
+ shrd r13d,r13d,5
+ xor r14d,ebx
+ and r12d,r9d
+ xor r13d,r9d
+ add eax,DWORD[28+rsp]
+ mov edi,ebx
+ xor r12d,r11d
+ shrd r14d,r14d,11
+ xor edi,ecx
+ add eax,r12d
+ shrd r13d,r13d,6
+ and r15d,edi
+ xor r14d,ebx
+ add eax,r13d
+ xor r15d,ecx
+ shrd r14d,r14d,2
+ add r8d,eax
+ add eax,r15d
+ mov r13d,r8d
+ add r14d,eax
+ shrd r13d,r13d,14
+ mov eax,r14d
+ mov r12d,r9d
+ shrd r14d,r14d,9
+ xor r13d,r8d
+ xor r12d,r10d
+ shrd r13d,r13d,5
+ xor r14d,eax
+ and r12d,r8d
+ xor r13d,r8d
+ add r11d,DWORD[32+rsp]
+ mov r15d,eax
+ xor r12d,r10d
+ shrd r14d,r14d,11
+ xor r15d,ebx
+ add r11d,r12d
+ shrd r13d,r13d,6
+ and edi,r15d
+ xor r14d,eax
+ add r11d,r13d
+ xor edi,ebx
+ shrd r14d,r14d,2
+ add edx,r11d
+ add r11d,edi
+ mov r13d,edx
+ add r14d,r11d
+ shrd r13d,r13d,14
+ mov r11d,r14d
+ mov r12d,r8d
+ shrd r14d,r14d,9
+ xor r13d,edx
+ xor r12d,r9d
+ shrd r13d,r13d,5
+ xor r14d,r11d
+ and r12d,edx
+ xor r13d,edx
+ add r10d,DWORD[36+rsp]
+ mov edi,r11d
+ xor r12d,r9d
+ shrd r14d,r14d,11
+ xor edi,eax
+ add r10d,r12d
+ shrd r13d,r13d,6
+ and r15d,edi
+ xor r14d,r11d
+ add r10d,r13d
+ xor r15d,eax
+ shrd r14d,r14d,2
+ add ecx,r10d
+ add r10d,r15d
+ mov r13d,ecx
+ add r14d,r10d
+ shrd r13d,r13d,14
+ mov r10d,r14d
+ mov r12d,edx
+ shrd r14d,r14d,9
+ xor r13d,ecx
+ xor r12d,r8d
+ shrd r13d,r13d,5
+ xor r14d,r10d
+ and r12d,ecx
+ xor r13d,ecx
+ add r9d,DWORD[40+rsp]
+ mov r15d,r10d
+ xor r12d,r8d
+ shrd r14d,r14d,11
+ xor r15d,r11d
+ add r9d,r12d
+ shrd r13d,r13d,6
+ and edi,r15d
+ xor r14d,r10d
+ add r9d,r13d
+ xor edi,r11d
+ shrd r14d,r14d,2
+ add ebx,r9d
+ add r9d,edi
+ mov r13d,ebx
+ add r14d,r9d
+ shrd r13d,r13d,14
+ mov r9d,r14d
+ mov r12d,ecx
+ shrd r14d,r14d,9
+ xor r13d,ebx
+ xor r12d,edx
+ shrd r13d,r13d,5
+ xor r14d,r9d
+ and r12d,ebx
+ xor r13d,ebx
+ add r8d,DWORD[44+rsp]
+ mov edi,r9d
+ xor r12d,edx
+ shrd r14d,r14d,11
+ xor edi,r10d
+ add r8d,r12d
+ shrd r13d,r13d,6
+ and r15d,edi
+ xor r14d,r9d
+ add r8d,r13d
+ xor r15d,r10d
+ shrd r14d,r14d,2
+ add eax,r8d
+ add r8d,r15d
+ mov r13d,eax
+ add r14d,r8d
+ shrd r13d,r13d,14
+ mov r8d,r14d
+ mov r12d,ebx
+ shrd r14d,r14d,9
+ xor r13d,eax
+ xor r12d,ecx
+ shrd r13d,r13d,5
+ xor r14d,r8d
+ and r12d,eax
+ xor r13d,eax
+ add edx,DWORD[48+rsp]
+ mov r15d,r8d
+ xor r12d,ecx
+ shrd r14d,r14d,11
+ xor r15d,r9d
+ add edx,r12d
+ shrd r13d,r13d,6
+ and edi,r15d
+ xor r14d,r8d
+ add edx,r13d
+ xor edi,r9d
+ shrd r14d,r14d,2
+ add r11d,edx
+ add edx,edi
+ mov r13d,r11d
+ add r14d,edx
+ shrd r13d,r13d,14
+ mov edx,r14d
+ mov r12d,eax
+ shrd r14d,r14d,9
+ xor r13d,r11d
+ xor r12d,ebx
+ shrd r13d,r13d,5
+ xor r14d,edx
+ and r12d,r11d
+ xor r13d,r11d
+ add ecx,DWORD[52+rsp]
+ mov edi,edx
+ xor r12d,ebx
+ shrd r14d,r14d,11
+ xor edi,r8d
+ add ecx,r12d
+ shrd r13d,r13d,6
+ and r15d,edi
+ xor r14d,edx
+ add ecx,r13d
+ xor r15d,r8d
+ shrd r14d,r14d,2
+ add r10d,ecx
+ add ecx,r15d
+ mov r13d,r10d
+ add r14d,ecx
+ shrd r13d,r13d,14
+ mov ecx,r14d
+ mov r12d,r11d
+ shrd r14d,r14d,9
+ xor r13d,r10d
+ xor r12d,eax
+ shrd r13d,r13d,5
+ xor r14d,ecx
+ and r12d,r10d
+ xor r13d,r10d
+ add ebx,DWORD[56+rsp]
+ mov r15d,ecx
+ xor r12d,eax
+ shrd r14d,r14d,11
+ xor r15d,edx
+ add ebx,r12d
+ shrd r13d,r13d,6
+ and edi,r15d
+ xor r14d,ecx
+ add ebx,r13d
+ xor edi,edx
+ shrd r14d,r14d,2
+ add r9d,ebx
+ add ebx,edi
+ mov r13d,r9d
+ add r14d,ebx
+ shrd r13d,r13d,14
+ mov ebx,r14d
+ mov r12d,r10d
+ shrd r14d,r14d,9
+ xor r13d,r9d
+ xor r12d,r11d
+ shrd r13d,r13d,5
+ xor r14d,ebx
+ and r12d,r9d
+ xor r13d,r9d
+ add eax,DWORD[60+rsp]
+ mov edi,ebx
+ xor r12d,r11d
+ shrd r14d,r14d,11
+ xor edi,ecx
+ add eax,r12d
+ shrd r13d,r13d,6
+ and r15d,edi
+ xor r14d,ebx
+ add eax,r13d
+ xor r15d,ecx
+ shrd r14d,r14d,2
+ add r8d,eax
+ add eax,r15d
+ mov r13d,r8d
+ add r14d,eax
+ mov rdi,QWORD[((64+0))+rsp]
+ mov eax,r14d
+
+ add eax,DWORD[rdi]
+ lea rsi,[64+rsi]
+ add ebx,DWORD[4+rdi]
+ add ecx,DWORD[8+rdi]
+ add edx,DWORD[12+rdi]
+ add r8d,DWORD[16+rdi]
+ add r9d,DWORD[20+rdi]
+ add r10d,DWORD[24+rdi]
+ add r11d,DWORD[28+rdi]
+
+ cmp rsi,QWORD[((64+16))+rsp]
+
+ mov DWORD[rdi],eax
+ mov DWORD[4+rdi],ebx
+ mov DWORD[8+rdi],ecx
+ mov DWORD[12+rdi],edx
+ mov DWORD[16+rdi],r8d
+ mov DWORD[20+rdi],r9d
+ mov DWORD[24+rdi],r10d
+ mov DWORD[28+rdi],r11d
+ jb NEAR $L$loop_avx
+
+ mov rsi,QWORD[((64+24))+rsp]
+ vzeroupper
+ movaps xmm6,XMMWORD[((64+32))+rsp]
+ movaps xmm7,XMMWORD[((64+48))+rsp]
+ movaps xmm8,XMMWORD[((64+64))+rsp]
+ movaps xmm9,XMMWORD[((64+80))+rsp]
+ mov r15,QWORD[rsi]
+ mov r14,QWORD[8+rsi]
+ mov r13,QWORD[16+rsi]
+ mov r12,QWORD[24+rsi]
+ mov rbp,QWORD[32+rsi]
+ mov rbx,QWORD[40+rsi]
+ lea rsp,[48+rsi]
+$L$epilogue_avx:
+ mov rdi,QWORD[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_sha256_block_data_order_avx:
EXTERN __imp_RtlVirtualUnwind
ALIGN 16
@@ -2982,6 +4063,9 @@ ALIGN 4
DD $L$SEH_begin_sha256_block_data_order_ssse3 wrt ..imagebase
DD $L$SEH_end_sha256_block_data_order_ssse3 wrt ..imagebase
DD $L$SEH_info_sha256_block_data_order_ssse3 wrt ..imagebase
+ DD $L$SEH_begin_sha256_block_data_order_avx wrt ..imagebase
+ DD $L$SEH_end_sha256_block_data_order_avx wrt ..imagebase
+ DD $L$SEH_info_sha256_block_data_order_avx wrt ..imagebase
section .xdata rdata align=8
ALIGN 8
$L$SEH_info_sha256_block_data_order:
@@ -2992,3 +4076,7 @@ $L$SEH_info_sha256_block_data_order_ssse3:
DB 9,0,0,0
DD se_handler wrt ..imagebase
DD $L$prologue_ssse3 wrt ..imagebase,$L$epilogue_ssse3 wrt ..imagebase
+$L$SEH_info_sha256_block_data_order_avx:
+DB 9,0,0,0
+ DD se_handler wrt ..imagebase
+ DD $L$prologue_avx wrt ..imagebase,$L$epilogue_avx wrt ..imagebase
diff --git a/win-x86_64/crypto/sha/sha512-x86_64.asm b/win-x86_64/crypto/sha/sha512-x86_64.asm
index b76cc0e..71449cd 100644
--- a/win-x86_64/crypto/sha/sha512-x86_64.asm
+++ b/win-x86_64/crypto/sha/sha512-x86_64.asm
@@ -19,6 +19,17 @@ $L$SEH_begin_sha512_block_data_order:
mov rdx,r8
+ lea r11,[OPENSSL_ia32cap_P]
+ mov r9d,DWORD[r11]
+ mov r10d,DWORD[4+r11]
+ mov r11d,DWORD[8+r11]
+ test r10d,2048
+ jnz NEAR $L$xop_shortcut
+ and r9d,1073741824
+ and r10d,268435968
+ or r10d,r9d
+ cmp r10d,1342177792
+ je NEAR $L$avx_shortcut
push rbx
push rbp
push r12
@@ -1801,6 +1812,2282 @@ DB 110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54
DB 52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121
DB 32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46
DB 111,114,103,62,0
+
+ALIGN 64
+sha512_block_data_order_xop:
+ mov QWORD[8+rsp],rdi ;WIN64 prologue
+ mov QWORD[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_sha512_block_data_order_xop:
+ mov rdi,rcx
+ mov rsi,rdx
+ mov rdx,r8
+
+
+$L$xop_shortcut:
+ push rbx
+ push rbp
+ push r12
+ push r13
+ push r14
+ push r15
+ mov r11,rsp
+ shl rdx,4
+ sub rsp,256
+ lea rdx,[rdx*8+rsi]
+ and rsp,-64
+ mov QWORD[((128+0))+rsp],rdi
+ mov QWORD[((128+8))+rsp],rsi
+ mov QWORD[((128+16))+rsp],rdx
+ mov QWORD[((128+24))+rsp],r11
+ movaps XMMWORD[(128+32)+rsp],xmm6
+ movaps XMMWORD[(128+48)+rsp],xmm7
+ movaps XMMWORD[(128+64)+rsp],xmm8
+ movaps XMMWORD[(128+80)+rsp],xmm9
+ movaps XMMWORD[(128+96)+rsp],xmm10
+ movaps XMMWORD[(128+112)+rsp],xmm11
+$L$prologue_xop:
+
+ vzeroupper
+ mov rax,QWORD[rdi]
+ mov rbx,QWORD[8+rdi]
+ mov rcx,QWORD[16+rdi]
+ mov rdx,QWORD[24+rdi]
+ mov r8,QWORD[32+rdi]
+ mov r9,QWORD[40+rdi]
+ mov r10,QWORD[48+rdi]
+ mov r11,QWORD[56+rdi]
+ jmp NEAR $L$loop_xop
+ALIGN 16
+$L$loop_xop:
+ vmovdqa xmm11,XMMWORD[((K512+1280))]
+ vmovdqu xmm0,XMMWORD[rsi]
+ lea rbp,[((K512+128))]
+ vmovdqu xmm1,XMMWORD[16+rsi]
+ vmovdqu xmm2,XMMWORD[32+rsi]
+ vpshufb xmm0,xmm0,xmm11
+ vmovdqu xmm3,XMMWORD[48+rsi]
+ vpshufb xmm1,xmm1,xmm11
+ vmovdqu xmm4,XMMWORD[64+rsi]
+ vpshufb xmm2,xmm2,xmm11
+ vmovdqu xmm5,XMMWORD[80+rsi]
+ vpshufb xmm3,xmm3,xmm11
+ vmovdqu xmm6,XMMWORD[96+rsi]
+ vpshufb xmm4,xmm4,xmm11
+ vmovdqu xmm7,XMMWORD[112+rsi]
+ vpshufb xmm5,xmm5,xmm11
+ vpaddq xmm8,xmm0,XMMWORD[((-128))+rbp]
+ vpshufb xmm6,xmm6,xmm11
+ vpaddq xmm9,xmm1,XMMWORD[((-96))+rbp]
+ vpshufb xmm7,xmm7,xmm11
+ vpaddq xmm10,xmm2,XMMWORD[((-64))+rbp]
+ vpaddq xmm11,xmm3,XMMWORD[((-32))+rbp]
+ vmovdqa XMMWORD[rsp],xmm8
+ vpaddq xmm8,xmm4,XMMWORD[rbp]
+ vmovdqa XMMWORD[16+rsp],xmm9
+ vpaddq xmm9,xmm5,XMMWORD[32+rbp]
+ vmovdqa XMMWORD[32+rsp],xmm10
+ vpaddq xmm10,xmm6,XMMWORD[64+rbp]
+ vmovdqa XMMWORD[48+rsp],xmm11
+ vpaddq xmm11,xmm7,XMMWORD[96+rbp]
+ vmovdqa XMMWORD[64+rsp],xmm8
+ mov r14,rax
+ vmovdqa XMMWORD[80+rsp],xmm9
+ mov rdi,rbx
+ vmovdqa XMMWORD[96+rsp],xmm10
+ xor rdi,rcx
+ vmovdqa XMMWORD[112+rsp],xmm11
+ mov r13,r8
+ jmp NEAR $L$xop_00_47
+
+ALIGN 16
+$L$xop_00_47:
+ add rbp,256
+ vpalignr xmm8,xmm1,xmm0,8
+ ror r13,23
+ mov rax,r14
+ vpalignr xmm11,xmm5,xmm4,8
+ mov r12,r9
+ ror r14,5
+DB 143,72,120,195,200,56
+ xor r13,r8
+ xor r12,r10
+ vpsrlq xmm8,xmm8,7
+ ror r13,4
+ xor r14,rax
+ vpaddq xmm0,xmm0,xmm11
+ and r12,r8
+ xor r13,r8
+ add r11,QWORD[rsp]
+ mov r15,rax
+DB 143,72,120,195,209,7
+ xor r12,r10
+ ror r14,6
+ vpxor xmm8,xmm8,xmm9
+ xor r15,rbx
+ add r11,r12
+ ror r13,14
+ and rdi,r15
+DB 143,104,120,195,223,3
+ xor r14,rax
+ add r11,r13
+ vpxor xmm8,xmm8,xmm10
+ xor rdi,rbx
+ ror r14,28
+ vpsrlq xmm10,xmm7,6
+ add rdx,r11
+ add r11,rdi
+ vpaddq xmm0,xmm0,xmm8
+ mov r13,rdx
+ add r14,r11
+DB 143,72,120,195,203,42
+ ror r13,23
+ mov r11,r14
+ vpxor xmm11,xmm11,xmm10
+ mov r12,r8
+ ror r14,5
+ xor r13,rdx
+ xor r12,r9
+ vpxor xmm11,xmm11,xmm9
+ ror r13,4
+ xor r14,r11
+ and r12,rdx
+ xor r13,rdx
+ vpaddq xmm0,xmm0,xmm11
+ add r10,QWORD[8+rsp]
+ mov rdi,r11
+ xor r12,r9
+ ror r14,6
+ vpaddq xmm10,xmm0,XMMWORD[((-128))+rbp]
+ xor rdi,rax
+ add r10,r12
+ ror r13,14
+ and r15,rdi
+ xor r14,r11
+ add r10,r13
+ xor r15,rax
+ ror r14,28
+ add rcx,r10
+ add r10,r15
+ mov r13,rcx
+ add r14,r10
+ vmovdqa XMMWORD[rsp],xmm10
+ vpalignr xmm8,xmm2,xmm1,8
+ ror r13,23
+ mov r10,r14
+ vpalignr xmm11,xmm6,xmm5,8
+ mov r12,rdx
+ ror r14,5
+DB 143,72,120,195,200,56
+ xor r13,rcx
+ xor r12,r8
+ vpsrlq xmm8,xmm8,7
+ ror r13,4
+ xor r14,r10
+ vpaddq xmm1,xmm1,xmm11
+ and r12,rcx
+ xor r13,rcx
+ add r9,QWORD[16+rsp]
+ mov r15,r10
+DB 143,72,120,195,209,7
+ xor r12,r8
+ ror r14,6
+ vpxor xmm8,xmm8,xmm9
+ xor r15,r11
+ add r9,r12
+ ror r13,14
+ and rdi,r15
+DB 143,104,120,195,216,3
+ xor r14,r10
+ add r9,r13
+ vpxor xmm8,xmm8,xmm10
+ xor rdi,r11
+ ror r14,28
+ vpsrlq xmm10,xmm0,6
+ add rbx,r9
+ add r9,rdi
+ vpaddq xmm1,xmm1,xmm8
+ mov r13,rbx
+ add r14,r9
+DB 143,72,120,195,203,42
+ ror r13,23
+ mov r9,r14
+ vpxor xmm11,xmm11,xmm10
+ mov r12,rcx
+ ror r14,5
+ xor r13,rbx
+ xor r12,rdx
+ vpxor xmm11,xmm11,xmm9
+ ror r13,4
+ xor r14,r9
+ and r12,rbx
+ xor r13,rbx
+ vpaddq xmm1,xmm1,xmm11
+ add r8,QWORD[24+rsp]
+ mov rdi,r9
+ xor r12,rdx
+ ror r14,6
+ vpaddq xmm10,xmm1,XMMWORD[((-96))+rbp]
+ xor rdi,r10
+ add r8,r12
+ ror r13,14
+ and r15,rdi
+ xor r14,r9
+ add r8,r13
+ xor r15,r10
+ ror r14,28
+ add rax,r8
+ add r8,r15
+ mov r13,rax
+ add r14,r8
+ vmovdqa XMMWORD[16+rsp],xmm10
+ vpalignr xmm8,xmm3,xmm2,8
+ ror r13,23
+ mov r8,r14
+ vpalignr xmm11,xmm7,xmm6,8
+ mov r12,rbx
+ ror r14,5
+DB 143,72,120,195,200,56
+ xor r13,rax
+ xor r12,rcx
+ vpsrlq xmm8,xmm8,7
+ ror r13,4
+ xor r14,r8
+ vpaddq xmm2,xmm2,xmm11
+ and r12,rax
+ xor r13,rax
+ add rdx,QWORD[32+rsp]
+ mov r15,r8
+DB 143,72,120,195,209,7
+ xor r12,rcx
+ ror r14,6
+ vpxor xmm8,xmm8,xmm9
+ xor r15,r9
+ add rdx,r12
+ ror r13,14
+ and rdi,r15
+DB 143,104,120,195,217,3
+ xor r14,r8
+ add rdx,r13
+ vpxor xmm8,xmm8,xmm10
+ xor rdi,r9
+ ror r14,28
+ vpsrlq xmm10,xmm1,6
+ add r11,rdx
+ add rdx,rdi
+ vpaddq xmm2,xmm2,xmm8
+ mov r13,r11
+ add r14,rdx
+DB 143,72,120,195,203,42
+ ror r13,23
+ mov rdx,r14
+ vpxor xmm11,xmm11,xmm10
+ mov r12,rax
+ ror r14,5
+ xor r13,r11
+ xor r12,rbx
+ vpxor xmm11,xmm11,xmm9
+ ror r13,4
+ xor r14,rdx
+ and r12,r11
+ xor r13,r11
+ vpaddq xmm2,xmm2,xmm11
+ add rcx,QWORD[40+rsp]
+ mov rdi,rdx
+ xor r12,rbx
+ ror r14,6
+ vpaddq xmm10,xmm2,XMMWORD[((-64))+rbp]
+ xor rdi,r8
+ add rcx,r12
+ ror r13,14
+ and r15,rdi
+ xor r14,rdx
+ add rcx,r13
+ xor r15,r8
+ ror r14,28
+ add r10,rcx
+ add rcx,r15
+ mov r13,r10
+ add r14,rcx
+ vmovdqa XMMWORD[32+rsp],xmm10
+ vpalignr xmm8,xmm4,xmm3,8
+ ror r13,23
+ mov rcx,r14
+ vpalignr xmm11,xmm0,xmm7,8
+ mov r12,r11
+ ror r14,5
+DB 143,72,120,195,200,56
+ xor r13,r10
+ xor r12,rax
+ vpsrlq xmm8,xmm8,7
+ ror r13,4
+ xor r14,rcx
+ vpaddq xmm3,xmm3,xmm11
+ and r12,r10
+ xor r13,r10
+ add rbx,QWORD[48+rsp]
+ mov r15,rcx
+DB 143,72,120,195,209,7
+ xor r12,rax
+ ror r14,6
+ vpxor xmm8,xmm8,xmm9
+ xor r15,rdx
+ add rbx,r12
+ ror r13,14
+ and rdi,r15
+DB 143,104,120,195,218,3
+ xor r14,rcx
+ add rbx,r13
+ vpxor xmm8,xmm8,xmm10
+ xor rdi,rdx
+ ror r14,28
+ vpsrlq xmm10,xmm2,6
+ add r9,rbx
+ add rbx,rdi
+ vpaddq xmm3,xmm3,xmm8
+ mov r13,r9
+ add r14,rbx
+DB 143,72,120,195,203,42
+ ror r13,23
+ mov rbx,r14
+ vpxor xmm11,xmm11,xmm10
+ mov r12,r10
+ ror r14,5
+ xor r13,r9
+ xor r12,r11
+ vpxor xmm11,xmm11,xmm9
+ ror r13,4
+ xor r14,rbx
+ and r12,r9
+ xor r13,r9
+ vpaddq xmm3,xmm3,xmm11
+ add rax,QWORD[56+rsp]
+ mov rdi,rbx
+ xor r12,r11
+ ror r14,6
+ vpaddq xmm10,xmm3,XMMWORD[((-32))+rbp]
+ xor rdi,rcx
+ add rax,r12
+ ror r13,14
+ and r15,rdi
+ xor r14,rbx
+ add rax,r13
+ xor r15,rcx
+ ror r14,28
+ add r8,rax
+ add rax,r15
+ mov r13,r8
+ add r14,rax
+ vmovdqa XMMWORD[48+rsp],xmm10
+ vpalignr xmm8,xmm5,xmm4,8
+ ror r13,23
+ mov rax,r14
+ vpalignr xmm11,xmm1,xmm0,8
+ mov r12,r9
+ ror r14,5
+DB 143,72,120,195,200,56
+ xor r13,r8
+ xor r12,r10
+ vpsrlq xmm8,xmm8,7
+ ror r13,4
+ xor r14,rax
+ vpaddq xmm4,xmm4,xmm11
+ and r12,r8
+ xor r13,r8
+ add r11,QWORD[64+rsp]
+ mov r15,rax
+DB 143,72,120,195,209,7
+ xor r12,r10
+ ror r14,6
+ vpxor xmm8,xmm8,xmm9
+ xor r15,rbx
+ add r11,r12
+ ror r13,14
+ and rdi,r15
+DB 143,104,120,195,219,3
+ xor r14,rax
+ add r11,r13
+ vpxor xmm8,xmm8,xmm10
+ xor rdi,rbx
+ ror r14,28
+ vpsrlq xmm10,xmm3,6
+ add rdx,r11
+ add r11,rdi
+ vpaddq xmm4,xmm4,xmm8
+ mov r13,rdx
+ add r14,r11
+DB 143,72,120,195,203,42
+ ror r13,23
+ mov r11,r14
+ vpxor xmm11,xmm11,xmm10
+ mov r12,r8
+ ror r14,5
+ xor r13,rdx
+ xor r12,r9
+ vpxor xmm11,xmm11,xmm9
+ ror r13,4
+ xor r14,r11
+ and r12,rdx
+ xor r13,rdx
+ vpaddq xmm4,xmm4,xmm11
+ add r10,QWORD[72+rsp]
+ mov rdi,r11
+ xor r12,r9
+ ror r14,6
+ vpaddq xmm10,xmm4,XMMWORD[rbp]
+ xor rdi,rax
+ add r10,r12
+ ror r13,14
+ and r15,rdi
+ xor r14,r11
+ add r10,r13
+ xor r15,rax
+ ror r14,28
+ add rcx,r10
+ add r10,r15
+ mov r13,rcx
+ add r14,r10
+ vmovdqa XMMWORD[64+rsp],xmm10
+ vpalignr xmm8,xmm6,xmm5,8
+ ror r13,23
+ mov r10,r14
+ vpalignr xmm11,xmm2,xmm1,8
+ mov r12,rdx
+ ror r14,5
+DB 143,72,120,195,200,56
+ xor r13,rcx
+ xor r12,r8
+ vpsrlq xmm8,xmm8,7
+ ror r13,4
+ xor r14,r10
+ vpaddq xmm5,xmm5,xmm11
+ and r12,rcx
+ xor r13,rcx
+ add r9,QWORD[80+rsp]
+ mov r15,r10
+DB 143,72,120,195,209,7
+ xor r12,r8
+ ror r14,6
+ vpxor xmm8,xmm8,xmm9
+ xor r15,r11
+ add r9,r12
+ ror r13,14
+ and rdi,r15
+DB 143,104,120,195,220,3
+ xor r14,r10
+ add r9,r13
+ vpxor xmm8,xmm8,xmm10
+ xor rdi,r11
+ ror r14,28
+ vpsrlq xmm10,xmm4,6
+ add rbx,r9
+ add r9,rdi
+ vpaddq xmm5,xmm5,xmm8
+ mov r13,rbx
+ add r14,r9
+DB 143,72,120,195,203,42
+ ror r13,23
+ mov r9,r14
+ vpxor xmm11,xmm11,xmm10
+ mov r12,rcx
+ ror r14,5
+ xor r13,rbx
+ xor r12,rdx
+ vpxor xmm11,xmm11,xmm9
+ ror r13,4
+ xor r14,r9
+ and r12,rbx
+ xor r13,rbx
+ vpaddq xmm5,xmm5,xmm11
+ add r8,QWORD[88+rsp]
+ mov rdi,r9
+ xor r12,rdx
+ ror r14,6
+ vpaddq xmm10,xmm5,XMMWORD[32+rbp]
+ xor rdi,r10
+ add r8,r12
+ ror r13,14
+ and r15,rdi
+ xor r14,r9
+ add r8,r13
+ xor r15,r10
+ ror r14,28
+ add rax,r8
+ add r8,r15
+ mov r13,rax
+ add r14,r8
+ vmovdqa XMMWORD[80+rsp],xmm10
+ vpalignr xmm8,xmm7,xmm6,8
+ ror r13,23
+ mov r8,r14
+ vpalignr xmm11,xmm3,xmm2,8
+ mov r12,rbx
+ ror r14,5
+DB 143,72,120,195,200,56
+ xor r13,rax
+ xor r12,rcx
+ vpsrlq xmm8,xmm8,7
+ ror r13,4
+ xor r14,r8
+ vpaddq xmm6,xmm6,xmm11
+ and r12,rax
+ xor r13,rax
+ add rdx,QWORD[96+rsp]
+ mov r15,r8
+DB 143,72,120,195,209,7
+ xor r12,rcx
+ ror r14,6
+ vpxor xmm8,xmm8,xmm9
+ xor r15,r9
+ add rdx,r12
+ ror r13,14
+ and rdi,r15
+DB 143,104,120,195,221,3
+ xor r14,r8
+ add rdx,r13
+ vpxor xmm8,xmm8,xmm10
+ xor rdi,r9
+ ror r14,28
+ vpsrlq xmm10,xmm5,6
+ add r11,rdx
+ add rdx,rdi
+ vpaddq xmm6,xmm6,xmm8
+ mov r13,r11
+ add r14,rdx
+DB 143,72,120,195,203,42
+ ror r13,23
+ mov rdx,r14
+ vpxor xmm11,xmm11,xmm10
+ mov r12,rax
+ ror r14,5
+ xor r13,r11
+ xor r12,rbx
+ vpxor xmm11,xmm11,xmm9
+ ror r13,4
+ xor r14,rdx
+ and r12,r11
+ xor r13,r11
+ vpaddq xmm6,xmm6,xmm11
+ add rcx,QWORD[104+rsp]
+ mov rdi,rdx
+ xor r12,rbx
+ ror r14,6
+ vpaddq xmm10,xmm6,XMMWORD[64+rbp]
+ xor rdi,r8
+ add rcx,r12
+ ror r13,14
+ and r15,rdi
+ xor r14,rdx
+ add rcx,r13
+ xor r15,r8
+ ror r14,28
+ add r10,rcx
+ add rcx,r15
+ mov r13,r10
+ add r14,rcx
+ vmovdqa XMMWORD[96+rsp],xmm10
+ vpalignr xmm8,xmm0,xmm7,8
+ ror r13,23
+ mov rcx,r14
+ vpalignr xmm11,xmm4,xmm3,8
+ mov r12,r11
+ ror r14,5
+DB 143,72,120,195,200,56
+ xor r13,r10
+ xor r12,rax
+ vpsrlq xmm8,xmm8,7
+ ror r13,4
+ xor r14,rcx
+ vpaddq xmm7,xmm7,xmm11
+ and r12,r10
+ xor r13,r10
+ add rbx,QWORD[112+rsp]
+ mov r15,rcx
+DB 143,72,120,195,209,7
+ xor r12,rax
+ ror r14,6
+ vpxor xmm8,xmm8,xmm9
+ xor r15,rdx
+ add rbx,r12
+ ror r13,14
+ and rdi,r15
+DB 143,104,120,195,222,3
+ xor r14,rcx
+ add rbx,r13
+ vpxor xmm8,xmm8,xmm10
+ xor rdi,rdx
+ ror r14,28
+ vpsrlq xmm10,xmm6,6
+ add r9,rbx
+ add rbx,rdi
+ vpaddq xmm7,xmm7,xmm8
+ mov r13,r9
+ add r14,rbx
+DB 143,72,120,195,203,42
+ ror r13,23
+ mov rbx,r14
+ vpxor xmm11,xmm11,xmm10
+ mov r12,r10
+ ror r14,5
+ xor r13,r9
+ xor r12,r11
+ vpxor xmm11,xmm11,xmm9
+ ror r13,4
+ xor r14,rbx
+ and r12,r9
+ xor r13,r9
+ vpaddq xmm7,xmm7,xmm11
+ add rax,QWORD[120+rsp]
+ mov rdi,rbx
+ xor r12,r11
+ ror r14,6
+ vpaddq xmm10,xmm7,XMMWORD[96+rbp]
+ xor rdi,rcx
+ add rax,r12
+ ror r13,14
+ and r15,rdi
+ xor r14,rbx
+ add rax,r13
+ xor r15,rcx
+ ror r14,28
+ add r8,rax
+ add rax,r15
+ mov r13,r8
+ add r14,rax
+ vmovdqa XMMWORD[112+rsp],xmm10
+ cmp BYTE[135+rbp],0
+ jne NEAR $L$xop_00_47
+ ror r13,23
+ mov rax,r14
+ mov r12,r9
+ ror r14,5
+ xor r13,r8
+ xor r12,r10
+ ror r13,4
+ xor r14,rax
+ and r12,r8
+ xor r13,r8
+ add r11,QWORD[rsp]
+ mov r15,rax
+ xor r12,r10
+ ror r14,6
+ xor r15,rbx
+ add r11,r12
+ ror r13,14
+ and rdi,r15
+ xor r14,rax
+ add r11,r13
+ xor rdi,rbx
+ ror r14,28
+ add rdx,r11
+ add r11,rdi
+ mov r13,rdx
+ add r14,r11
+ ror r13,23
+ mov r11,r14
+ mov r12,r8
+ ror r14,5
+ xor r13,rdx
+ xor r12,r9
+ ror r13,4
+ xor r14,r11
+ and r12,rdx
+ xor r13,rdx
+ add r10,QWORD[8+rsp]
+ mov rdi,r11
+ xor r12,r9
+ ror r14,6
+ xor rdi,rax
+ add r10,r12
+ ror r13,14
+ and r15,rdi
+ xor r14,r11
+ add r10,r13
+ xor r15,rax
+ ror r14,28
+ add rcx,r10
+ add r10,r15
+ mov r13,rcx
+ add r14,r10
+ ror r13,23
+ mov r10,r14
+ mov r12,rdx
+ ror r14,5
+ xor r13,rcx
+ xor r12,r8
+ ror r13,4
+ xor r14,r10
+ and r12,rcx
+ xor r13,rcx
+ add r9,QWORD[16+rsp]
+ mov r15,r10
+ xor r12,r8
+ ror r14,6
+ xor r15,r11
+ add r9,r12
+ ror r13,14
+ and rdi,r15
+ xor r14,r10
+ add r9,r13
+ xor rdi,r11
+ ror r14,28
+ add rbx,r9
+ add r9,rdi
+ mov r13,rbx
+ add r14,r9
+ ror r13,23
+ mov r9,r14
+ mov r12,rcx
+ ror r14,5
+ xor r13,rbx
+ xor r12,rdx
+ ror r13,4
+ xor r14,r9
+ and r12,rbx
+ xor r13,rbx
+ add r8,QWORD[24+rsp]
+ mov rdi,r9
+ xor r12,rdx
+ ror r14,6
+ xor rdi,r10
+ add r8,r12
+ ror r13,14
+ and r15,rdi
+ xor r14,r9
+ add r8,r13
+ xor r15,r10
+ ror r14,28
+ add rax,r8
+ add r8,r15
+ mov r13,rax
+ add r14,r8
+ ror r13,23
+ mov r8,r14
+ mov r12,rbx
+ ror r14,5
+ xor r13,rax
+ xor r12,rcx
+ ror r13,4
+ xor r14,r8
+ and r12,rax
+ xor r13,rax
+ add rdx,QWORD[32+rsp]
+ mov r15,r8
+ xor r12,rcx
+ ror r14,6
+ xor r15,r9
+ add rdx,r12
+ ror r13,14
+ and rdi,r15
+ xor r14,r8
+ add rdx,r13
+ xor rdi,r9
+ ror r14,28
+ add r11,rdx
+ add rdx,rdi
+ mov r13,r11
+ add r14,rdx
+ ror r13,23
+ mov rdx,r14
+ mov r12,rax
+ ror r14,5
+ xor r13,r11
+ xor r12,rbx
+ ror r13,4
+ xor r14,rdx
+ and r12,r11
+ xor r13,r11
+ add rcx,QWORD[40+rsp]
+ mov rdi,rdx
+ xor r12,rbx
+ ror r14,6
+ xor rdi,r8
+ add rcx,r12
+ ror r13,14
+ and r15,rdi
+ xor r14,rdx
+ add rcx,r13
+ xor r15,r8
+ ror r14,28
+ add r10,rcx
+ add rcx,r15
+ mov r13,r10
+ add r14,rcx
+ ror r13,23
+ mov rcx,r14
+ mov r12,r11
+ ror r14,5
+ xor r13,r10
+ xor r12,rax
+ ror r13,4
+ xor r14,rcx
+ and r12,r10
+ xor r13,r10
+ add rbx,QWORD[48+rsp]
+ mov r15,rcx
+ xor r12,rax
+ ror r14,6
+ xor r15,rdx
+ add rbx,r12
+ ror r13,14
+ and rdi,r15
+ xor r14,rcx
+ add rbx,r13
+ xor rdi,rdx
+ ror r14,28
+ add r9,rbx
+ add rbx,rdi
+ mov r13,r9
+ add r14,rbx
+ ror r13,23
+ mov rbx,r14
+ mov r12,r10
+ ror r14,5
+ xor r13,r9
+ xor r12,r11
+ ror r13,4
+ xor r14,rbx
+ and r12,r9
+ xor r13,r9
+ add rax,QWORD[56+rsp]
+ mov rdi,rbx
+ xor r12,r11
+ ror r14,6
+ xor rdi,rcx
+ add rax,r12
+ ror r13,14
+ and r15,rdi
+ xor r14,rbx
+ add rax,r13
+ xor r15,rcx
+ ror r14,28
+ add r8,rax
+ add rax,r15
+ mov r13,r8
+ add r14,rax
+ ror r13,23
+ mov rax,r14
+ mov r12,r9
+ ror r14,5
+ xor r13,r8
+ xor r12,r10
+ ror r13,4
+ xor r14,rax
+ and r12,r8
+ xor r13,r8
+ add r11,QWORD[64+rsp]
+ mov r15,rax
+ xor r12,r10
+ ror r14,6
+ xor r15,rbx
+ add r11,r12
+ ror r13,14
+ and rdi,r15
+ xor r14,rax
+ add r11,r13
+ xor rdi,rbx
+ ror r14,28
+ add rdx,r11
+ add r11,rdi
+ mov r13,rdx
+ add r14,r11
+ ror r13,23
+ mov r11,r14
+ mov r12,r8
+ ror r14,5
+ xor r13,rdx
+ xor r12,r9
+ ror r13,4
+ xor r14,r11
+ and r12,rdx
+ xor r13,rdx
+ add r10,QWORD[72+rsp]
+ mov rdi,r11
+ xor r12,r9
+ ror r14,6
+ xor rdi,rax
+ add r10,r12
+ ror r13,14
+ and r15,rdi
+ xor r14,r11
+ add r10,r13
+ xor r15,rax
+ ror r14,28
+ add rcx,r10
+ add r10,r15
+ mov r13,rcx
+ add r14,r10
+ ror r13,23
+ mov r10,r14
+ mov r12,rdx
+ ror r14,5
+ xor r13,rcx
+ xor r12,r8
+ ror r13,4
+ xor r14,r10
+ and r12,rcx
+ xor r13,rcx
+ add r9,QWORD[80+rsp]
+ mov r15,r10
+ xor r12,r8
+ ror r14,6
+ xor r15,r11
+ add r9,r12
+ ror r13,14
+ and rdi,r15
+ xor r14,r10
+ add r9,r13
+ xor rdi,r11
+ ror r14,28
+ add rbx,r9
+ add r9,rdi
+ mov r13,rbx
+ add r14,r9
+ ror r13,23
+ mov r9,r14
+ mov r12,rcx
+ ror r14,5
+ xor r13,rbx
+ xor r12,rdx
+ ror r13,4
+ xor r14,r9
+ and r12,rbx
+ xor r13,rbx
+ add r8,QWORD[88+rsp]
+ mov rdi,r9
+ xor r12,rdx
+ ror r14,6
+ xor rdi,r10
+ add r8,r12
+ ror r13,14
+ and r15,rdi
+ xor r14,r9
+ add r8,r13
+ xor r15,r10
+ ror r14,28
+ add rax,r8
+ add r8,r15
+ mov r13,rax
+ add r14,r8
+ ror r13,23
+ mov r8,r14
+ mov r12,rbx
+ ror r14,5
+ xor r13,rax
+ xor r12,rcx
+ ror r13,4
+ xor r14,r8
+ and r12,rax
+ xor r13,rax
+ add rdx,QWORD[96+rsp]
+ mov r15,r8
+ xor r12,rcx
+ ror r14,6
+ xor r15,r9
+ add rdx,r12
+ ror r13,14
+ and rdi,r15
+ xor r14,r8
+ add rdx,r13
+ xor rdi,r9
+ ror r14,28
+ add r11,rdx
+ add rdx,rdi
+ mov r13,r11
+ add r14,rdx
+ ror r13,23
+ mov rdx,r14
+ mov r12,rax
+ ror r14,5
+ xor r13,r11
+ xor r12,rbx
+ ror r13,4
+ xor r14,rdx
+ and r12,r11
+ xor r13,r11
+ add rcx,QWORD[104+rsp]
+ mov rdi,rdx
+ xor r12,rbx
+ ror r14,6
+ xor rdi,r8
+ add rcx,r12
+ ror r13,14
+ and r15,rdi
+ xor r14,rdx
+ add rcx,r13
+ xor r15,r8
+ ror r14,28
+ add r10,rcx
+ add rcx,r15
+ mov r13,r10
+ add r14,rcx
+ ror r13,23
+ mov rcx,r14
+ mov r12,r11
+ ror r14,5
+ xor r13,r10
+ xor r12,rax
+ ror r13,4
+ xor r14,rcx
+ and r12,r10
+ xor r13,r10
+ add rbx,QWORD[112+rsp]
+ mov r15,rcx
+ xor r12,rax
+ ror r14,6
+ xor r15,rdx
+ add rbx,r12
+ ror r13,14
+ and rdi,r15
+ xor r14,rcx
+ add rbx,r13
+ xor rdi,rdx
+ ror r14,28
+ add r9,rbx
+ add rbx,rdi
+ mov r13,r9
+ add r14,rbx
+ ror r13,23
+ mov rbx,r14
+ mov r12,r10
+ ror r14,5
+ xor r13,r9
+ xor r12,r11
+ ror r13,4
+ xor r14,rbx
+ and r12,r9
+ xor r13,r9
+ add rax,QWORD[120+rsp]
+ mov rdi,rbx
+ xor r12,r11
+ ror r14,6
+ xor rdi,rcx
+ add rax,r12
+ ror r13,14
+ and r15,rdi
+ xor r14,rbx
+ add rax,r13
+ xor r15,rcx
+ ror r14,28
+ add r8,rax
+ add rax,r15
+ mov r13,r8
+ add r14,rax
+ mov rdi,QWORD[((128+0))+rsp]
+ mov rax,r14
+
+ add rax,QWORD[rdi]
+ lea rsi,[128+rsi]
+ add rbx,QWORD[8+rdi]
+ add rcx,QWORD[16+rdi]
+ add rdx,QWORD[24+rdi]
+ add r8,QWORD[32+rdi]
+ add r9,QWORD[40+rdi]
+ add r10,QWORD[48+rdi]
+ add r11,QWORD[56+rdi]
+
+ cmp rsi,QWORD[((128+16))+rsp]
+
+ mov QWORD[rdi],rax
+ mov QWORD[8+rdi],rbx
+ mov QWORD[16+rdi],rcx
+ mov QWORD[24+rdi],rdx
+ mov QWORD[32+rdi],r8
+ mov QWORD[40+rdi],r9
+ mov QWORD[48+rdi],r10
+ mov QWORD[56+rdi],r11
+ jb NEAR $L$loop_xop
+
+ mov rsi,QWORD[((128+24))+rsp]
+ vzeroupper
+ movaps xmm6,XMMWORD[((128+32))+rsp]
+ movaps xmm7,XMMWORD[((128+48))+rsp]
+ movaps xmm8,XMMWORD[((128+64))+rsp]
+ movaps xmm9,XMMWORD[((128+80))+rsp]
+ movaps xmm10,XMMWORD[((128+96))+rsp]
+ movaps xmm11,XMMWORD[((128+112))+rsp]
+ mov r15,QWORD[rsi]
+ mov r14,QWORD[8+rsi]
+ mov r13,QWORD[16+rsi]
+ mov r12,QWORD[24+rsi]
+ mov rbp,QWORD[32+rsi]
+ mov rbx,QWORD[40+rsi]
+ lea rsp,[48+rsi]
+$L$epilogue_xop:
+ mov rdi,QWORD[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_sha512_block_data_order_xop:
+
+ALIGN 64
+sha512_block_data_order_avx:
+ mov QWORD[8+rsp],rdi ;WIN64 prologue
+ mov QWORD[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_sha512_block_data_order_avx:
+ mov rdi,rcx
+ mov rsi,rdx
+ mov rdx,r8
+
+
+$L$avx_shortcut:
+ push rbx
+ push rbp
+ push r12
+ push r13
+ push r14
+ push r15
+ mov r11,rsp
+ shl rdx,4
+ sub rsp,256
+ lea rdx,[rdx*8+rsi]
+ and rsp,-64
+ mov QWORD[((128+0))+rsp],rdi
+ mov QWORD[((128+8))+rsp],rsi
+ mov QWORD[((128+16))+rsp],rdx
+ mov QWORD[((128+24))+rsp],r11
+ movaps XMMWORD[(128+32)+rsp],xmm6
+ movaps XMMWORD[(128+48)+rsp],xmm7
+ movaps XMMWORD[(128+64)+rsp],xmm8
+ movaps XMMWORD[(128+80)+rsp],xmm9
+ movaps XMMWORD[(128+96)+rsp],xmm10
+ movaps XMMWORD[(128+112)+rsp],xmm11
+$L$prologue_avx:
+
+ vzeroupper
+ mov rax,QWORD[rdi]
+ mov rbx,QWORD[8+rdi]
+ mov rcx,QWORD[16+rdi]
+ mov rdx,QWORD[24+rdi]
+ mov r8,QWORD[32+rdi]
+ mov r9,QWORD[40+rdi]
+ mov r10,QWORD[48+rdi]
+ mov r11,QWORD[56+rdi]
+ jmp NEAR $L$loop_avx
+ALIGN 16
+$L$loop_avx:
+ vmovdqa xmm11,XMMWORD[((K512+1280))]
+ vmovdqu xmm0,XMMWORD[rsi]
+ lea rbp,[((K512+128))]
+ vmovdqu xmm1,XMMWORD[16+rsi]
+ vmovdqu xmm2,XMMWORD[32+rsi]
+ vpshufb xmm0,xmm0,xmm11
+ vmovdqu xmm3,XMMWORD[48+rsi]
+ vpshufb xmm1,xmm1,xmm11
+ vmovdqu xmm4,XMMWORD[64+rsi]
+ vpshufb xmm2,xmm2,xmm11
+ vmovdqu xmm5,XMMWORD[80+rsi]
+ vpshufb xmm3,xmm3,xmm11
+ vmovdqu xmm6,XMMWORD[96+rsi]
+ vpshufb xmm4,xmm4,xmm11
+ vmovdqu xmm7,XMMWORD[112+rsi]
+ vpshufb xmm5,xmm5,xmm11
+ vpaddq xmm8,xmm0,XMMWORD[((-128))+rbp]
+ vpshufb xmm6,xmm6,xmm11
+ vpaddq xmm9,xmm1,XMMWORD[((-96))+rbp]
+ vpshufb xmm7,xmm7,xmm11
+ vpaddq xmm10,xmm2,XMMWORD[((-64))+rbp]
+ vpaddq xmm11,xmm3,XMMWORD[((-32))+rbp]
+ vmovdqa XMMWORD[rsp],xmm8
+ vpaddq xmm8,xmm4,XMMWORD[rbp]
+ vmovdqa XMMWORD[16+rsp],xmm9
+ vpaddq xmm9,xmm5,XMMWORD[32+rbp]
+ vmovdqa XMMWORD[32+rsp],xmm10
+ vpaddq xmm10,xmm6,XMMWORD[64+rbp]
+ vmovdqa XMMWORD[48+rsp],xmm11
+ vpaddq xmm11,xmm7,XMMWORD[96+rbp]
+ vmovdqa XMMWORD[64+rsp],xmm8
+ mov r14,rax
+ vmovdqa XMMWORD[80+rsp],xmm9
+ mov rdi,rbx
+ vmovdqa XMMWORD[96+rsp],xmm10
+ xor rdi,rcx
+ vmovdqa XMMWORD[112+rsp],xmm11
+ mov r13,r8
+ jmp NEAR $L$avx_00_47
+
+ALIGN 16
+$L$avx_00_47:
+ add rbp,256
+ vpalignr xmm8,xmm1,xmm0,8
+ shrd r13,r13,23
+ mov rax,r14
+ vpalignr xmm11,xmm5,xmm4,8
+ mov r12,r9
+ shrd r14,r14,5
+ vpsrlq xmm10,xmm8,1
+ xor r13,r8
+ xor r12,r10
+ vpaddq xmm0,xmm0,xmm11
+ shrd r13,r13,4
+ xor r14,rax
+ vpsrlq xmm11,xmm8,7
+ and r12,r8
+ xor r13,r8
+ vpsllq xmm9,xmm8,56
+ add r11,QWORD[rsp]
+ mov r15,rax
+ vpxor xmm8,xmm11,xmm10
+ xor r12,r10
+ shrd r14,r14,6
+ vpsrlq xmm10,xmm10,7
+ xor r15,rbx
+ add r11,r12
+ vpxor xmm8,xmm8,xmm9
+ shrd r13,r13,14
+ and rdi,r15
+ vpsllq xmm9,xmm9,7
+ xor r14,rax
+ add r11,r13
+ vpxor xmm8,xmm8,xmm10
+ xor rdi,rbx
+ shrd r14,r14,28
+ vpsrlq xmm11,xmm7,6
+ add rdx,r11
+ add r11,rdi
+ vpxor xmm8,xmm8,xmm9
+ mov r13,rdx
+ add r14,r11
+ vpsllq xmm10,xmm7,3
+ shrd r13,r13,23
+ mov r11,r14
+ vpaddq xmm0,xmm0,xmm8
+ mov r12,r8
+ shrd r14,r14,5
+ vpsrlq xmm9,xmm7,19
+ xor r13,rdx
+ xor r12,r9
+ vpxor xmm11,xmm11,xmm10
+ shrd r13,r13,4
+ xor r14,r11
+ vpsllq xmm10,xmm10,42
+ and r12,rdx
+ xor r13,rdx
+ vpxor xmm11,xmm11,xmm9
+ add r10,QWORD[8+rsp]
+ mov rdi,r11
+ vpsrlq xmm9,xmm9,42
+ xor r12,r9
+ shrd r14,r14,6
+ vpxor xmm11,xmm11,xmm10
+ xor rdi,rax
+ add r10,r12
+ vpxor xmm11,xmm11,xmm9
+ shrd r13,r13,14
+ and r15,rdi
+ vpaddq xmm0,xmm0,xmm11
+ xor r14,r11
+ add r10,r13
+ vpaddq xmm10,xmm0,XMMWORD[((-128))+rbp]
+ xor r15,rax
+ shrd r14,r14,28
+ add rcx,r10
+ add r10,r15
+ mov r13,rcx
+ add r14,r10
+ vmovdqa XMMWORD[rsp],xmm10
+ vpalignr xmm8,xmm2,xmm1,8
+ shrd r13,r13,23
+ mov r10,r14
+ vpalignr xmm11,xmm6,xmm5,8
+ mov r12,rdx
+ shrd r14,r14,5
+ vpsrlq xmm10,xmm8,1
+ xor r13,rcx
+ xor r12,r8
+ vpaddq xmm1,xmm1,xmm11
+ shrd r13,r13,4
+ xor r14,r10
+ vpsrlq xmm11,xmm8,7
+ and r12,rcx
+ xor r13,rcx
+ vpsllq xmm9,xmm8,56
+ add r9,QWORD[16+rsp]
+ mov r15,r10
+ vpxor xmm8,xmm11,xmm10
+ xor r12,r8
+ shrd r14,r14,6
+ vpsrlq xmm10,xmm10,7
+ xor r15,r11
+ add r9,r12
+ vpxor xmm8,xmm8,xmm9
+ shrd r13,r13,14
+ and rdi,r15
+ vpsllq xmm9,xmm9,7
+ xor r14,r10
+ add r9,r13
+ vpxor xmm8,xmm8,xmm10
+ xor rdi,r11
+ shrd r14,r14,28
+ vpsrlq xmm11,xmm0,6
+ add rbx,r9
+ add r9,rdi
+ vpxor xmm8,xmm8,xmm9
+ mov r13,rbx
+ add r14,r9
+ vpsllq xmm10,xmm0,3
+ shrd r13,r13,23
+ mov r9,r14
+ vpaddq xmm1,xmm1,xmm8
+ mov r12,rcx
+ shrd r14,r14,5
+ vpsrlq xmm9,xmm0,19
+ xor r13,rbx
+ xor r12,rdx
+ vpxor xmm11,xmm11,xmm10
+ shrd r13,r13,4
+ xor r14,r9
+ vpsllq xmm10,xmm10,42
+ and r12,rbx
+ xor r13,rbx
+ vpxor xmm11,xmm11,xmm9
+ add r8,QWORD[24+rsp]
+ mov rdi,r9
+ vpsrlq xmm9,xmm9,42
+ xor r12,rdx
+ shrd r14,r14,6
+ vpxor xmm11,xmm11,xmm10
+ xor rdi,r10
+ add r8,r12
+ vpxor xmm11,xmm11,xmm9
+ shrd r13,r13,14
+ and r15,rdi
+ vpaddq xmm1,xmm1,xmm11
+ xor r14,r9
+ add r8,r13
+ vpaddq xmm10,xmm1,XMMWORD[((-96))+rbp]
+ xor r15,r10
+ shrd r14,r14,28
+ add rax,r8
+ add r8,r15
+ mov r13,rax
+ add r14,r8
+ vmovdqa XMMWORD[16+rsp],xmm10
+ vpalignr xmm8,xmm3,xmm2,8
+ shrd r13,r13,23
+ mov r8,r14
+ vpalignr xmm11,xmm7,xmm6,8
+ mov r12,rbx
+ shrd r14,r14,5
+ vpsrlq xmm10,xmm8,1
+ xor r13,rax
+ xor r12,rcx
+ vpaddq xmm2,xmm2,xmm11
+ shrd r13,r13,4
+ xor r14,r8
+ vpsrlq xmm11,xmm8,7
+ and r12,rax
+ xor r13,rax
+ vpsllq xmm9,xmm8,56
+ add rdx,QWORD[32+rsp]
+ mov r15,r8
+ vpxor xmm8,xmm11,xmm10
+ xor r12,rcx
+ shrd r14,r14,6
+ vpsrlq xmm10,xmm10,7
+ xor r15,r9
+ add rdx,r12
+ vpxor xmm8,xmm8,xmm9
+ shrd r13,r13,14
+ and rdi,r15
+ vpsllq xmm9,xmm9,7
+ xor r14,r8
+ add rdx,r13
+ vpxor xmm8,xmm8,xmm10
+ xor rdi,r9
+ shrd r14,r14,28
+ vpsrlq xmm11,xmm1,6
+ add r11,rdx
+ add rdx,rdi
+ vpxor xmm8,xmm8,xmm9
+ mov r13,r11
+ add r14,rdx
+ vpsllq xmm10,xmm1,3
+ shrd r13,r13,23
+ mov rdx,r14
+ vpaddq xmm2,xmm2,xmm8
+ mov r12,rax
+ shrd r14,r14,5
+ vpsrlq xmm9,xmm1,19
+ xor r13,r11
+ xor r12,rbx
+ vpxor xmm11,xmm11,xmm10
+ shrd r13,r13,4
+ xor r14,rdx
+ vpsllq xmm10,xmm10,42
+ and r12,r11
+ xor r13,r11
+ vpxor xmm11,xmm11,xmm9
+ add rcx,QWORD[40+rsp]
+ mov rdi,rdx
+ vpsrlq xmm9,xmm9,42
+ xor r12,rbx
+ shrd r14,r14,6
+ vpxor xmm11,xmm11,xmm10
+ xor rdi,r8
+ add rcx,r12
+ vpxor xmm11,xmm11,xmm9
+ shrd r13,r13,14
+ and r15,rdi
+ vpaddq xmm2,xmm2,xmm11
+ xor r14,rdx
+ add rcx,r13
+ vpaddq xmm10,xmm2,XMMWORD[((-64))+rbp]
+ xor r15,r8
+ shrd r14,r14,28
+ add r10,rcx
+ add rcx,r15
+ mov r13,r10
+ add r14,rcx
+ vmovdqa XMMWORD[32+rsp],xmm10
+ vpalignr xmm8,xmm4,xmm3,8
+ shrd r13,r13,23
+ mov rcx,r14
+ vpalignr xmm11,xmm0,xmm7,8
+ mov r12,r11
+ shrd r14,r14,5
+ vpsrlq xmm10,xmm8,1
+ xor r13,r10
+ xor r12,rax
+ vpaddq xmm3,xmm3,xmm11
+ shrd r13,r13,4
+ xor r14,rcx
+ vpsrlq xmm11,xmm8,7
+ and r12,r10
+ xor r13,r10
+ vpsllq xmm9,xmm8,56
+ add rbx,QWORD[48+rsp]
+ mov r15,rcx
+ vpxor xmm8,xmm11,xmm10
+ xor r12,rax
+ shrd r14,r14,6
+ vpsrlq xmm10,xmm10,7
+ xor r15,rdx
+ add rbx,r12
+ vpxor xmm8,xmm8,xmm9
+ shrd r13,r13,14
+ and rdi,r15
+ vpsllq xmm9,xmm9,7
+ xor r14,rcx
+ add rbx,r13
+ vpxor xmm8,xmm8,xmm10
+ xor rdi,rdx
+ shrd r14,r14,28
+ vpsrlq xmm11,xmm2,6
+ add r9,rbx
+ add rbx,rdi
+ vpxor xmm8,xmm8,xmm9
+ mov r13,r9
+ add r14,rbx
+ vpsllq xmm10,xmm2,3
+ shrd r13,r13,23
+ mov rbx,r14
+ vpaddq xmm3,xmm3,xmm8
+ mov r12,r10
+ shrd r14,r14,5
+ vpsrlq xmm9,xmm2,19
+ xor r13,r9
+ xor r12,r11
+ vpxor xmm11,xmm11,xmm10
+ shrd r13,r13,4
+ xor r14,rbx
+ vpsllq xmm10,xmm10,42
+ and r12,r9
+ xor r13,r9
+ vpxor xmm11,xmm11,xmm9
+ add rax,QWORD[56+rsp]
+ mov rdi,rbx
+ vpsrlq xmm9,xmm9,42
+ xor r12,r11
+ shrd r14,r14,6
+ vpxor xmm11,xmm11,xmm10
+ xor rdi,rcx
+ add rax,r12
+ vpxor xmm11,xmm11,xmm9
+ shrd r13,r13,14
+ and r15,rdi
+ vpaddq xmm3,xmm3,xmm11
+ xor r14,rbx
+ add rax,r13
+ vpaddq xmm10,xmm3,XMMWORD[((-32))+rbp]
+ xor r15,rcx
+ shrd r14,r14,28
+ add r8,rax
+ add rax,r15
+ mov r13,r8
+ add r14,rax
+ vmovdqa XMMWORD[48+rsp],xmm10
+ vpalignr xmm8,xmm5,xmm4,8
+ shrd r13,r13,23
+ mov rax,r14
+ vpalignr xmm11,xmm1,xmm0,8
+ mov r12,r9
+ shrd r14,r14,5
+ vpsrlq xmm10,xmm8,1
+ xor r13,r8
+ xor r12,r10
+ vpaddq xmm4,xmm4,xmm11
+ shrd r13,r13,4
+ xor r14,rax
+ vpsrlq xmm11,xmm8,7
+ and r12,r8
+ xor r13,r8
+ vpsllq xmm9,xmm8,56
+ add r11,QWORD[64+rsp]
+ mov r15,rax
+ vpxor xmm8,xmm11,xmm10
+ xor r12,r10
+ shrd r14,r14,6
+ vpsrlq xmm10,xmm10,7
+ xor r15,rbx
+ add r11,r12
+ vpxor xmm8,xmm8,xmm9
+ shrd r13,r13,14
+ and rdi,r15
+ vpsllq xmm9,xmm9,7
+ xor r14,rax
+ add r11,r13
+ vpxor xmm8,xmm8,xmm10
+ xor rdi,rbx
+ shrd r14,r14,28
+ vpsrlq xmm11,xmm3,6
+ add rdx,r11
+ add r11,rdi
+ vpxor xmm8,xmm8,xmm9
+ mov r13,rdx
+ add r14,r11
+ vpsllq xmm10,xmm3,3
+ shrd r13,r13,23
+ mov r11,r14
+ vpaddq xmm4,xmm4,xmm8
+ mov r12,r8
+ shrd r14,r14,5
+ vpsrlq xmm9,xmm3,19
+ xor r13,rdx
+ xor r12,r9
+ vpxor xmm11,xmm11,xmm10
+ shrd r13,r13,4
+ xor r14,r11
+ vpsllq xmm10,xmm10,42
+ and r12,rdx
+ xor r13,rdx
+ vpxor xmm11,xmm11,xmm9
+ add r10,QWORD[72+rsp]
+ mov rdi,r11
+ vpsrlq xmm9,xmm9,42
+ xor r12,r9
+ shrd r14,r14,6
+ vpxor xmm11,xmm11,xmm10
+ xor rdi,rax
+ add r10,r12
+ vpxor xmm11,xmm11,xmm9
+ shrd r13,r13,14
+ and r15,rdi
+ vpaddq xmm4,xmm4,xmm11
+ xor r14,r11
+ add r10,r13
+ vpaddq xmm10,xmm4,XMMWORD[rbp]
+ xor r15,rax
+ shrd r14,r14,28
+ add rcx,r10
+ add r10,r15
+ mov r13,rcx
+ add r14,r10
+ vmovdqa XMMWORD[64+rsp],xmm10
+ vpalignr xmm8,xmm6,xmm5,8
+ shrd r13,r13,23
+ mov r10,r14
+ vpalignr xmm11,xmm2,xmm1,8
+ mov r12,rdx
+ shrd r14,r14,5
+ vpsrlq xmm10,xmm8,1
+ xor r13,rcx
+ xor r12,r8
+ vpaddq xmm5,xmm5,xmm11
+ shrd r13,r13,4
+ xor r14,r10
+ vpsrlq xmm11,xmm8,7
+ and r12,rcx
+ xor r13,rcx
+ vpsllq xmm9,xmm8,56
+ add r9,QWORD[80+rsp]
+ mov r15,r10
+ vpxor xmm8,xmm11,xmm10
+ xor r12,r8
+ shrd r14,r14,6
+ vpsrlq xmm10,xmm10,7
+ xor r15,r11
+ add r9,r12
+ vpxor xmm8,xmm8,xmm9
+ shrd r13,r13,14
+ and rdi,r15
+ vpsllq xmm9,xmm9,7
+ xor r14,r10
+ add r9,r13
+ vpxor xmm8,xmm8,xmm10
+ xor rdi,r11
+ shrd r14,r14,28
+ vpsrlq xmm11,xmm4,6
+ add rbx,r9
+ add r9,rdi
+ vpxor xmm8,xmm8,xmm9
+ mov r13,rbx
+ add r14,r9
+ vpsllq xmm10,xmm4,3
+ shrd r13,r13,23
+ mov r9,r14
+ vpaddq xmm5,xmm5,xmm8
+ mov r12,rcx
+ shrd r14,r14,5
+ vpsrlq xmm9,xmm4,19
+ xor r13,rbx
+ xor r12,rdx
+ vpxor xmm11,xmm11,xmm10
+ shrd r13,r13,4
+ xor r14,r9
+ vpsllq xmm10,xmm10,42
+ and r12,rbx
+ xor r13,rbx
+ vpxor xmm11,xmm11,xmm9
+ add r8,QWORD[88+rsp]
+ mov rdi,r9
+ vpsrlq xmm9,xmm9,42
+ xor r12,rdx
+ shrd r14,r14,6
+ vpxor xmm11,xmm11,xmm10
+ xor rdi,r10
+ add r8,r12
+ vpxor xmm11,xmm11,xmm9
+ shrd r13,r13,14
+ and r15,rdi
+ vpaddq xmm5,xmm5,xmm11
+ xor r14,r9
+ add r8,r13
+ vpaddq xmm10,xmm5,XMMWORD[32+rbp]
+ xor r15,r10
+ shrd r14,r14,28
+ add rax,r8
+ add r8,r15
+ mov r13,rax
+ add r14,r8
+ vmovdqa XMMWORD[80+rsp],xmm10
+ vpalignr xmm8,xmm7,xmm6,8
+ shrd r13,r13,23
+ mov r8,r14
+ vpalignr xmm11,xmm3,xmm2,8
+ mov r12,rbx
+ shrd r14,r14,5
+ vpsrlq xmm10,xmm8,1
+ xor r13,rax
+ xor r12,rcx
+ vpaddq xmm6,xmm6,xmm11
+ shrd r13,r13,4
+ xor r14,r8
+ vpsrlq xmm11,xmm8,7
+ and r12,rax
+ xor r13,rax
+ vpsllq xmm9,xmm8,56
+ add rdx,QWORD[96+rsp]
+ mov r15,r8
+ vpxor xmm8,xmm11,xmm10
+ xor r12,rcx
+ shrd r14,r14,6
+ vpsrlq xmm10,xmm10,7
+ xor r15,r9
+ add rdx,r12
+ vpxor xmm8,xmm8,xmm9
+ shrd r13,r13,14
+ and rdi,r15
+ vpsllq xmm9,xmm9,7
+ xor r14,r8
+ add rdx,r13
+ vpxor xmm8,xmm8,xmm10
+ xor rdi,r9
+ shrd r14,r14,28
+ vpsrlq xmm11,xmm5,6
+ add r11,rdx
+ add rdx,rdi
+ vpxor xmm8,xmm8,xmm9
+ mov r13,r11
+ add r14,rdx
+ vpsllq xmm10,xmm5,3
+ shrd r13,r13,23
+ mov rdx,r14
+ vpaddq xmm6,xmm6,xmm8
+ mov r12,rax
+ shrd r14,r14,5
+ vpsrlq xmm9,xmm5,19
+ xor r13,r11
+ xor r12,rbx
+ vpxor xmm11,xmm11,xmm10
+ shrd r13,r13,4
+ xor r14,rdx
+ vpsllq xmm10,xmm10,42
+ and r12,r11
+ xor r13,r11
+ vpxor xmm11,xmm11,xmm9
+ add rcx,QWORD[104+rsp]
+ mov rdi,rdx
+ vpsrlq xmm9,xmm9,42
+ xor r12,rbx
+ shrd r14,r14,6
+ vpxor xmm11,xmm11,xmm10
+ xor rdi,r8
+ add rcx,r12
+ vpxor xmm11,xmm11,xmm9
+ shrd r13,r13,14
+ and r15,rdi
+ vpaddq xmm6,xmm6,xmm11
+ xor r14,rdx
+ add rcx,r13
+ vpaddq xmm10,xmm6,XMMWORD[64+rbp]
+ xor r15,r8
+ shrd r14,r14,28
+ add r10,rcx
+ add rcx,r15
+ mov r13,r10
+ add r14,rcx
+ vmovdqa XMMWORD[96+rsp],xmm10
+ vpalignr xmm8,xmm0,xmm7,8
+ shrd r13,r13,23
+ mov rcx,r14
+ vpalignr xmm11,xmm4,xmm3,8
+ mov r12,r11
+ shrd r14,r14,5
+ vpsrlq xmm10,xmm8,1
+ xor r13,r10
+ xor r12,rax
+ vpaddq xmm7,xmm7,xmm11
+ shrd r13,r13,4
+ xor r14,rcx
+ vpsrlq xmm11,xmm8,7
+ and r12,r10
+ xor r13,r10
+ vpsllq xmm9,xmm8,56
+ add rbx,QWORD[112+rsp]
+ mov r15,rcx
+ vpxor xmm8,xmm11,xmm10
+ xor r12,rax
+ shrd r14,r14,6
+ vpsrlq xmm10,xmm10,7
+ xor r15,rdx
+ add rbx,r12
+ vpxor xmm8,xmm8,xmm9
+ shrd r13,r13,14
+ and rdi,r15
+ vpsllq xmm9,xmm9,7
+ xor r14,rcx
+ add rbx,r13
+ vpxor xmm8,xmm8,xmm10
+ xor rdi,rdx
+ shrd r14,r14,28
+ vpsrlq xmm11,xmm6,6
+ add r9,rbx
+ add rbx,rdi
+ vpxor xmm8,xmm8,xmm9
+ mov r13,r9
+ add r14,rbx
+ vpsllq xmm10,xmm6,3
+ shrd r13,r13,23
+ mov rbx,r14
+ vpaddq xmm7,xmm7,xmm8
+ mov r12,r10
+ shrd r14,r14,5
+ vpsrlq xmm9,xmm6,19
+ xor r13,r9
+ xor r12,r11
+ vpxor xmm11,xmm11,xmm10
+ shrd r13,r13,4
+ xor r14,rbx
+ vpsllq xmm10,xmm10,42
+ and r12,r9
+ xor r13,r9
+ vpxor xmm11,xmm11,xmm9
+ add rax,QWORD[120+rsp]
+ mov rdi,rbx
+ vpsrlq xmm9,xmm9,42
+ xor r12,r11
+ shrd r14,r14,6
+ vpxor xmm11,xmm11,xmm10
+ xor rdi,rcx
+ add rax,r12
+ vpxor xmm11,xmm11,xmm9
+ shrd r13,r13,14
+ and r15,rdi
+ vpaddq xmm7,xmm7,xmm11
+ xor r14,rbx
+ add rax,r13
+ vpaddq xmm10,xmm7,XMMWORD[96+rbp]
+ xor r15,rcx
+ shrd r14,r14,28
+ add r8,rax
+ add rax,r15
+ mov r13,r8
+ add r14,rax
+ vmovdqa XMMWORD[112+rsp],xmm10
+ cmp BYTE[135+rbp],0
+ jne NEAR $L$avx_00_47
+ shrd r13,r13,23
+ mov rax,r14
+ mov r12,r9
+ shrd r14,r14,5
+ xor r13,r8
+ xor r12,r10
+ shrd r13,r13,4
+ xor r14,rax
+ and r12,r8
+ xor r13,r8
+ add r11,QWORD[rsp]
+ mov r15,rax
+ xor r12,r10
+ shrd r14,r14,6
+ xor r15,rbx
+ add r11,r12
+ shrd r13,r13,14
+ and rdi,r15
+ xor r14,rax
+ add r11,r13
+ xor rdi,rbx
+ shrd r14,r14,28
+ add rdx,r11
+ add r11,rdi
+ mov r13,rdx
+ add r14,r11
+ shrd r13,r13,23
+ mov r11,r14
+ mov r12,r8
+ shrd r14,r14,5
+ xor r13,rdx
+ xor r12,r9
+ shrd r13,r13,4
+ xor r14,r11
+ and r12,rdx
+ xor r13,rdx
+ add r10,QWORD[8+rsp]
+ mov rdi,r11
+ xor r12,r9
+ shrd r14,r14,6
+ xor rdi,rax
+ add r10,r12
+ shrd r13,r13,14
+ and r15,rdi
+ xor r14,r11
+ add r10,r13
+ xor r15,rax
+ shrd r14,r14,28
+ add rcx,r10
+ add r10,r15
+ mov r13,rcx
+ add r14,r10
+ shrd r13,r13,23
+ mov r10,r14
+ mov r12,rdx
+ shrd r14,r14,5
+ xor r13,rcx
+ xor r12,r8
+ shrd r13,r13,4
+ xor r14,r10
+ and r12,rcx
+ xor r13,rcx
+ add r9,QWORD[16+rsp]
+ mov r15,r10
+ xor r12,r8
+ shrd r14,r14,6
+ xor r15,r11
+ add r9,r12
+ shrd r13,r13,14
+ and rdi,r15
+ xor r14,r10
+ add r9,r13
+ xor rdi,r11
+ shrd r14,r14,28
+ add rbx,r9
+ add r9,rdi
+ mov r13,rbx
+ add r14,r9
+ shrd r13,r13,23
+ mov r9,r14
+ mov r12,rcx
+ shrd r14,r14,5
+ xor r13,rbx
+ xor r12,rdx
+ shrd r13,r13,4
+ xor r14,r9
+ and r12,rbx
+ xor r13,rbx
+ add r8,QWORD[24+rsp]
+ mov rdi,r9
+ xor r12,rdx
+ shrd r14,r14,6
+ xor rdi,r10
+ add r8,r12
+ shrd r13,r13,14
+ and r15,rdi
+ xor r14,r9
+ add r8,r13
+ xor r15,r10
+ shrd r14,r14,28
+ add rax,r8
+ add r8,r15
+ mov r13,rax
+ add r14,r8
+ shrd r13,r13,23
+ mov r8,r14
+ mov r12,rbx
+ shrd r14,r14,5
+ xor r13,rax
+ xor r12,rcx
+ shrd r13,r13,4
+ xor r14,r8
+ and r12,rax
+ xor r13,rax
+ add rdx,QWORD[32+rsp]
+ mov r15,r8
+ xor r12,rcx
+ shrd r14,r14,6
+ xor r15,r9
+ add rdx,r12
+ shrd r13,r13,14
+ and rdi,r15
+ xor r14,r8
+ add rdx,r13
+ xor rdi,r9
+ shrd r14,r14,28
+ add r11,rdx
+ add rdx,rdi
+ mov r13,r11
+ add r14,rdx
+ shrd r13,r13,23
+ mov rdx,r14
+ mov r12,rax
+ shrd r14,r14,5
+ xor r13,r11
+ xor r12,rbx
+ shrd r13,r13,4
+ xor r14,rdx
+ and r12,r11
+ xor r13,r11
+ add rcx,QWORD[40+rsp]
+ mov rdi,rdx
+ xor r12,rbx
+ shrd r14,r14,6
+ xor rdi,r8
+ add rcx,r12
+ shrd r13,r13,14
+ and r15,rdi
+ xor r14,rdx
+ add rcx,r13
+ xor r15,r8
+ shrd r14,r14,28
+ add r10,rcx
+ add rcx,r15
+ mov r13,r10
+ add r14,rcx
+ shrd r13,r13,23
+ mov rcx,r14
+ mov r12,r11
+ shrd r14,r14,5
+ xor r13,r10
+ xor r12,rax
+ shrd r13,r13,4
+ xor r14,rcx
+ and r12,r10
+ xor r13,r10
+ add rbx,QWORD[48+rsp]
+ mov r15,rcx
+ xor r12,rax
+ shrd r14,r14,6
+ xor r15,rdx
+ add rbx,r12
+ shrd r13,r13,14
+ and rdi,r15
+ xor r14,rcx
+ add rbx,r13
+ xor rdi,rdx
+ shrd r14,r14,28
+ add r9,rbx
+ add rbx,rdi
+ mov r13,r9
+ add r14,rbx
+ shrd r13,r13,23
+ mov rbx,r14
+ mov r12,r10
+ shrd r14,r14,5
+ xor r13,r9
+ xor r12,r11
+ shrd r13,r13,4
+ xor r14,rbx
+ and r12,r9
+ xor r13,r9
+ add rax,QWORD[56+rsp]
+ mov rdi,rbx
+ xor r12,r11
+ shrd r14,r14,6
+ xor rdi,rcx
+ add rax,r12
+ shrd r13,r13,14
+ and r15,rdi
+ xor r14,rbx
+ add rax,r13
+ xor r15,rcx
+ shrd r14,r14,28
+ add r8,rax
+ add rax,r15
+ mov r13,r8
+ add r14,rax
+ shrd r13,r13,23
+ mov rax,r14
+ mov r12,r9
+ shrd r14,r14,5
+ xor r13,r8
+ xor r12,r10
+ shrd r13,r13,4
+ xor r14,rax
+ and r12,r8
+ xor r13,r8
+ add r11,QWORD[64+rsp]
+ mov r15,rax
+ xor r12,r10
+ shrd r14,r14,6
+ xor r15,rbx
+ add r11,r12
+ shrd r13,r13,14
+ and rdi,r15
+ xor r14,rax
+ add r11,r13
+ xor rdi,rbx
+ shrd r14,r14,28
+ add rdx,r11
+ add r11,rdi
+ mov r13,rdx
+ add r14,r11
+ shrd r13,r13,23
+ mov r11,r14
+ mov r12,r8
+ shrd r14,r14,5
+ xor r13,rdx
+ xor r12,r9
+ shrd r13,r13,4
+ xor r14,r11
+ and r12,rdx
+ xor r13,rdx
+ add r10,QWORD[72+rsp]
+ mov rdi,r11
+ xor r12,r9
+ shrd r14,r14,6
+ xor rdi,rax
+ add r10,r12
+ shrd r13,r13,14
+ and r15,rdi
+ xor r14,r11
+ add r10,r13
+ xor r15,rax
+ shrd r14,r14,28
+ add rcx,r10
+ add r10,r15
+ mov r13,rcx
+ add r14,r10
+ shrd r13,r13,23
+ mov r10,r14
+ mov r12,rdx
+ shrd r14,r14,5
+ xor r13,rcx
+ xor r12,r8
+ shrd r13,r13,4
+ xor r14,r10
+ and r12,rcx
+ xor r13,rcx
+ add r9,QWORD[80+rsp]
+ mov r15,r10
+ xor r12,r8
+ shrd r14,r14,6
+ xor r15,r11
+ add r9,r12
+ shrd r13,r13,14
+ and rdi,r15
+ xor r14,r10
+ add r9,r13
+ xor rdi,r11
+ shrd r14,r14,28
+ add rbx,r9
+ add r9,rdi
+ mov r13,rbx
+ add r14,r9
+ shrd r13,r13,23
+ mov r9,r14
+ mov r12,rcx
+ shrd r14,r14,5
+ xor r13,rbx
+ xor r12,rdx
+ shrd r13,r13,4
+ xor r14,r9
+ and r12,rbx
+ xor r13,rbx
+ add r8,QWORD[88+rsp]
+ mov rdi,r9
+ xor r12,rdx
+ shrd r14,r14,6
+ xor rdi,r10
+ add r8,r12
+ shrd r13,r13,14
+ and r15,rdi
+ xor r14,r9
+ add r8,r13
+ xor r15,r10
+ shrd r14,r14,28
+ add rax,r8
+ add r8,r15
+ mov r13,rax
+ add r14,r8
+ shrd r13,r13,23
+ mov r8,r14
+ mov r12,rbx
+ shrd r14,r14,5
+ xor r13,rax
+ xor r12,rcx
+ shrd r13,r13,4
+ xor r14,r8
+ and r12,rax
+ xor r13,rax
+ add rdx,QWORD[96+rsp]
+ mov r15,r8
+ xor r12,rcx
+ shrd r14,r14,6
+ xor r15,r9
+ add rdx,r12
+ shrd r13,r13,14
+ and rdi,r15
+ xor r14,r8
+ add rdx,r13
+ xor rdi,r9
+ shrd r14,r14,28
+ add r11,rdx
+ add rdx,rdi
+ mov r13,r11
+ add r14,rdx
+ shrd r13,r13,23
+ mov rdx,r14
+ mov r12,rax
+ shrd r14,r14,5
+ xor r13,r11
+ xor r12,rbx
+ shrd r13,r13,4
+ xor r14,rdx
+ and r12,r11
+ xor r13,r11
+ add rcx,QWORD[104+rsp]
+ mov rdi,rdx
+ xor r12,rbx
+ shrd r14,r14,6
+ xor rdi,r8
+ add rcx,r12
+ shrd r13,r13,14
+ and r15,rdi
+ xor r14,rdx
+ add rcx,r13
+ xor r15,r8
+ shrd r14,r14,28
+ add r10,rcx
+ add rcx,r15
+ mov r13,r10
+ add r14,rcx
+ shrd r13,r13,23
+ mov rcx,r14
+ mov r12,r11
+ shrd r14,r14,5
+ xor r13,r10
+ xor r12,rax
+ shrd r13,r13,4
+ xor r14,rcx
+ and r12,r10
+ xor r13,r10
+ add rbx,QWORD[112+rsp]
+ mov r15,rcx
+ xor r12,rax
+ shrd r14,r14,6
+ xor r15,rdx
+ add rbx,r12
+ shrd r13,r13,14
+ and rdi,r15
+ xor r14,rcx
+ add rbx,r13
+ xor rdi,rdx
+ shrd r14,r14,28
+ add r9,rbx
+ add rbx,rdi
+ mov r13,r9
+ add r14,rbx
+ shrd r13,r13,23
+ mov rbx,r14
+ mov r12,r10
+ shrd r14,r14,5
+ xor r13,r9
+ xor r12,r11
+ shrd r13,r13,4
+ xor r14,rbx
+ and r12,r9
+ xor r13,r9
+ add rax,QWORD[120+rsp]
+ mov rdi,rbx
+ xor r12,r11
+ shrd r14,r14,6
+ xor rdi,rcx
+ add rax,r12
+ shrd r13,r13,14
+ and r15,rdi
+ xor r14,rbx
+ add rax,r13
+ xor r15,rcx
+ shrd r14,r14,28
+ add r8,rax
+ add rax,r15
+ mov r13,r8
+ add r14,rax
+ mov rdi,QWORD[((128+0))+rsp]
+ mov rax,r14
+
+ add rax,QWORD[rdi]
+ lea rsi,[128+rsi]
+ add rbx,QWORD[8+rdi]
+ add rcx,QWORD[16+rdi]
+ add rdx,QWORD[24+rdi]
+ add r8,QWORD[32+rdi]
+ add r9,QWORD[40+rdi]
+ add r10,QWORD[48+rdi]
+ add r11,QWORD[56+rdi]
+
+ cmp rsi,QWORD[((128+16))+rsp]
+
+ mov QWORD[rdi],rax
+ mov QWORD[8+rdi],rbx
+ mov QWORD[16+rdi],rcx
+ mov QWORD[24+rdi],rdx
+ mov QWORD[32+rdi],r8
+ mov QWORD[40+rdi],r9
+ mov QWORD[48+rdi],r10
+ mov QWORD[56+rdi],r11
+ jb NEAR $L$loop_avx
+
+ mov rsi,QWORD[((128+24))+rsp]
+ vzeroupper
+ movaps xmm6,XMMWORD[((128+32))+rsp]
+ movaps xmm7,XMMWORD[((128+48))+rsp]
+ movaps xmm8,XMMWORD[((128+64))+rsp]
+ movaps xmm9,XMMWORD[((128+80))+rsp]
+ movaps xmm10,XMMWORD[((128+96))+rsp]
+ movaps xmm11,XMMWORD[((128+112))+rsp]
+ mov r15,QWORD[rsi]
+ mov r14,QWORD[8+rsi]
+ mov r13,QWORD[16+rsi]
+ mov r12,QWORD[24+rsi]
+ mov rbp,QWORD[32+rsi]
+ mov rbx,QWORD[40+rsi]
+ lea rsp,[48+rsi]
+$L$epilogue_avx:
+ mov rdi,QWORD[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_sha512_block_data_order_avx:
EXTERN __imp_RtlVirtualUnwind
ALIGN 16
@@ -1903,9 +4190,23 @@ ALIGN 4
DD $L$SEH_begin_sha512_block_data_order wrt ..imagebase
DD $L$SEH_end_sha512_block_data_order wrt ..imagebase
DD $L$SEH_info_sha512_block_data_order wrt ..imagebase
+ DD $L$SEH_begin_sha512_block_data_order_xop wrt ..imagebase
+ DD $L$SEH_end_sha512_block_data_order_xop wrt ..imagebase
+ DD $L$SEH_info_sha512_block_data_order_xop wrt ..imagebase
+ DD $L$SEH_begin_sha512_block_data_order_avx wrt ..imagebase
+ DD $L$SEH_end_sha512_block_data_order_avx wrt ..imagebase
+ DD $L$SEH_info_sha512_block_data_order_avx wrt ..imagebase
section .xdata rdata align=8
ALIGN 8
$L$SEH_info_sha512_block_data_order:
DB 9,0,0,0
DD se_handler wrt ..imagebase
DD $L$prologue wrt ..imagebase,$L$epilogue wrt ..imagebase
+$L$SEH_info_sha512_block_data_order_xop:
+DB 9,0,0,0
+ DD se_handler wrt ..imagebase
+ DD $L$prologue_xop wrt ..imagebase,$L$epilogue_xop wrt ..imagebase
+$L$SEH_info_sha512_block_data_order_avx:
+DB 9,0,0,0
+ DD se_handler wrt ..imagebase
+ DD $L$prologue_avx wrt ..imagebase,$L$epilogue_avx wrt ..imagebase