summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Langley <agl@chromium.org>2016-01-15 01:00:33 +0000
committerandroid-build-merger <android-build-merger@google.com>2016-01-15 01:00:33 +0000
commit6290bff2114c67a0d1a57e75b0a11544ad894406 (patch)
tree80b47f41b8e3971267452f49e48560c9c36434e2
parent7410f4ee26ae91ef240e8e767e9f91e83ba32d38 (diff)
parent4139edb02e59e7ad48e0a8f4c02e45923bc8a344 (diff)
downloadexternal_boringssl-6290bff2114c67a0d1a57e75b0a11544ad894406.zip
external_boringssl-6290bff2114c67a0d1a57e75b0a11544ad894406.tar.gz
external_boringssl-6290bff2114c67a0d1a57e75b0a11544ad894406.tar.bz2
external/boringssl: sync to 7b8b9c17
am: 4139edb02e * commit '4139edb02e59e7ad48e0a8f4c02e45923bc8a344': external/boringssl: sync to 7b8b9c17
-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