summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk80
-rw-r--r--BORINGSSL_REVISION2
-rw-r--r--UPDATING9
-rw-r--r--crypto-sources.mk16
-rw-r--r--err_data.c2542
-rw-r--r--linux-aarch64/crypto/aes/aesv8-armx64.S (renamed from linux-aarch64/crypto/aes/aesv8-armx.S)4
-rw-r--r--linux-aarch64/crypto/bn/armv8-mont.S1406
-rw-r--r--linux-aarch64/crypto/modes/ghashv8-armx64.S (renamed from linux-aarch64/crypto/modes/ghashv8-armx.S)26
-rw-r--r--linux-aarch64/crypto/sha/sha1-armv8.S4
-rw-r--r--linux-aarch64/crypto/sha/sha256-armv8.S4
-rw-r--r--linux-aarch64/crypto/sha/sha512-armv8.S4
-rw-r--r--linux-arm/crypto/aes/aes-armv4.S4
-rw-r--r--linux-arm/crypto/aes/aesv8-armx32.S (renamed from linux-arm/crypto/aes/aesv8-armx.S)4
-rw-r--r--linux-arm/crypto/aes/bsaes-armv7.S6
-rw-r--r--linux-arm/crypto/bn/armv4-mont.S4
-rw-r--r--linux-arm/crypto/modes/ghash-armv4.S7
-rw-r--r--linux-arm/crypto/modes/ghashv8-armx32.S (renamed from linux-arm/crypto/modes/ghashv8-armx.S)26
-rw-r--r--linux-arm/crypto/sha/sha1-armv4-large.S4
-rw-r--r--linux-arm/crypto/sha/sha256-armv4.S4
-rw-r--r--linux-arm/crypto/sha/sha512-armv4.S4
-rw-r--r--linux-x86/crypto/cpu-x86-asm.S322
-rw-r--r--linux-x86/crypto/sha/sha1-586.S1365
-rw-r--r--linux-x86/crypto/sha/sha256-586.S1394
-rw-r--r--linux-x86_64/crypto/bn/modexp512-x86_64.S1776
-rw-r--r--linux-x86_64/crypto/bn/x86_64-mont5.S9
-rw-r--r--linux-x86_64/crypto/cpu-x86_64-asm.S143
-rw-r--r--linux-x86_64/crypto/ec/p256-x86_64-asm.S1780
-rw-r--r--linux-x86_64/crypto/rand/rdrand-x86_64.S39
-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/cpu-x86-asm.S309
-rw-r--r--mac-x86/crypto/sha/sha1-586.S1359
-rw-r--r--mac-x86/crypto/sha/sha256-586.S1394
-rw-r--r--mac-x86_64/crypto/bn/modexp512-x86_64.S1776
-rw-r--r--mac-x86_64/crypto/bn/x86_64-mont5.S9
-rw-r--r--mac-x86_64/crypto/cpu-x86_64-asm.S143
-rw-r--r--mac-x86_64/crypto/ec/p256-x86_64-asm.S1779
-rw-r--r--mac-x86_64/crypto/rand/rdrand-x86_64.S39
-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--rules.mk15
-rw-r--r--sources.mk49
-rw-r--r--src/.gitignore1
-rw-r--r--src/BUILDING96
-rw-r--r--src/BUILDING.md143
-rw-r--r--src/CMakeLists.txt39
-rw-r--r--src/FUZZING.md40
-rw-r--r--src/LICENSE39
-rw-r--r--src/PORTING.md164
-rw-r--r--src/README.md30
-rw-r--r--src/STYLE198
-rw-r--r--src/STYLE.md197
-rw-r--r--src/crypto/CMakeLists.txt12
-rw-r--r--src/crypto/aes/CMakeLists.txt12
-rw-r--r--src/crypto/aes/aes.c65
-rw-r--r--src/crypto/aes/aes_test.cc102
-rwxr-xr-xsrc/crypto/aes/asm/aes-586.pl6
-rw-r--r--src/crypto/aes/asm/aes-armv4.pl2
-rw-r--r--src/crypto/aes/asm/aesni-x86.pl2
-rw-r--r--src/crypto/aes/asm/aesv8-armx.pl2
-rw-r--r--src/crypto/aes/asm/bsaes-armv7.pl4
-rw-r--r--src/crypto/aes/mode_wrappers.c4
-rw-r--r--src/crypto/asn1/CMakeLists.txt2
-rw-r--r--src/crypto/asn1/a_bitstr.c11
-rw-r--r--src/crypto/asn1/a_bool.c2
-rw-r--r--src/crypto/asn1/a_bytes.c6
-rw-r--r--src/crypto/asn1/a_d2i_fp.c24
-rw-r--r--src/crypto/asn1/a_dup.c4
-rw-r--r--src/crypto/asn1/a_enum.c8
-rw-r--r--src/crypto/asn1/a_gentm.c2
-rw-r--r--src/crypto/asn1/a_i2d_fp.c10
-rw-r--r--src/crypto/asn1/a_int.c12
-rw-r--r--src/crypto/asn1/a_mbstr.c20
-rw-r--r--src/crypto/asn1/a_object.c22
-rw-r--r--src/crypto/asn1/a_strnid.c4
-rw-r--r--src/crypto/asn1/a_time.c4
-rw-r--r--src/crypto/asn1/a_utctm.c6
-rw-r--r--src/crypto/asn1/asn1_lib.c19
-rw-r--r--src/crypto/asn1/asn1_par.c9
-rw-r--r--src/crypto/asn1/asn_pack.c8
-rw-r--r--src/crypto/asn1/bio_ndef.c2
-rw-r--r--src/crypto/asn1/f_enum.c8
-rw-r--r--src/crypto/asn1/f_int.c8
-rw-r--r--src/crypto/asn1/f_string.c8
-rw-r--r--src/crypto/asn1/tasn_dec.c121
-rw-r--r--src/crypto/asn1/tasn_new.c6
-rw-r--r--src/crypto/asn1/tasn_prn.c4
-rw-r--r--src/crypto/asn1/tasn_utl.c3
-rw-r--r--src/crypto/asn1/x_bignum.c3
-rw-r--r--src/crypto/asn1/x_long.c4
-rw-r--r--src/crypto/base64/CMakeLists.txt3
-rw-r--r--src/crypto/bio/CMakeLists.txt3
-rw-r--r--src/crypto/bio/bio.c24
-rw-r--r--src/crypto/bio/bio_mem.c6
-rw-r--r--src/crypto/bio/buffer.c2
-rw-r--r--src/crypto/bio/connect.c146
-rw-r--r--src/crypto/bio/fd.c4
-rw-r--r--src/crypto/bio/file.c27
-rw-r--r--src/crypto/bio/pair.c64
-rw-r--r--src/crypto/bio/printf.c8
-rw-r--r--src/crypto/bio/socket_helper.c9
-rw-r--r--src/crypto/bn/CMakeLists.txt13
-rw-r--r--src/crypto/bn/add.c27
-rw-r--r--src/crypto/bn/asm/armv4-mont.pl2
-rw-r--r--src/crypto/bn/asm/armv8-mont.pl1503
-rw-r--r--src/crypto/bn/asm/rsaz-avx2.pl30
-rw-r--r--src/crypto/bn/asm/rsaz-x86_64.pl25
-rw-r--r--src/crypto/bn/asm/x86_64-mont.pl20
-rw-r--r--src/crypto/bn/asm/x86_64-mont5.pl42
-rw-r--r--src/crypto/bn/bn.c27
-rw-r--r--src/crypto/bn/bn_asn1.c93
-rw-r--r--src/crypto/bn/bn_test.cc441
-rw-r--r--src/crypto/bn/convert.c184
-rw-r--r--src/crypto/bn/ctx.c6
-rw-r--r--src/crypto/bn/div.c18
-rw-r--r--src/crypto/bn/exponentiation.c185
-rw-r--r--src/crypto/bn/gcd.c34
-rw-r--r--src/crypto/bn/generic.c138
-rw-r--r--src/crypto/bn/internal.h47
-rw-r--r--src/crypto/bn/montgomery.c42
-rw-r--r--src/crypto/bn/mul.c8
-rw-r--r--src/crypto/bn/prime.c11
-rw-r--r--src/crypto/bn/random.c14
-rw-r--r--src/crypto/bn/rsaz_exp.h68
-rw-r--r--src/crypto/bn/shift.c4
-rw-r--r--src/crypto/bn/sqrt.c24
-rw-r--r--src/crypto/buf/CMakeLists.txt2
-rw-r--r--src/crypto/buf/buf.c16
-rw-r--r--src/crypto/bytestring/CMakeLists.txt3
-rw-r--r--src/crypto/bytestring/ber.c2
-rw-r--r--src/crypto/bytestring/bytestring_test.cc115
-rw-r--r--src/crypto/bytestring/cbb.c109
-rw-r--r--src/crypto/bytestring/cbs.c20
-rw-r--r--src/crypto/bytestring/internal.h8
-rw-r--r--src/crypto/chacha/CMakeLists.txt2
-rw-r--r--src/crypto/chacha/chacha_generic.c17
-rw-r--r--src/crypto/chacha/chacha_vec.c28
-rw-r--r--src/crypto/chacha/chacha_vec_arm.S595
-rw-r--r--src/crypto/chacha/chacha_vec_arm_generate.go9
-rw-r--r--src/crypto/cipher/CMakeLists.txt3
-rw-r--r--src/crypto/cipher/aead.c24
-rw-r--r--src/crypto/cipher/aead_test.cc90
-rw-r--r--src/crypto/cipher/cipher.c41
-rw-r--r--src/crypto/cipher/cipher_test.cc71
-rw-r--r--src/crypto/cipher/e_aes.c248
-rw-r--r--src/crypto/cipher/e_chacha20poly1305.c223
-rw-r--r--src/crypto/cipher/e_des.c76
-rw-r--r--src/crypto/cipher/e_rc2.c27
-rw-r--r--src/crypto/cipher/e_rc4.c310
-rw-r--r--src/crypto/cipher/e_ssl3.c75
-rw-r--r--src/crypto/cipher/e_tls.c146
-rw-r--r--src/crypto/cipher/internal.h3
-rw-r--r--src/crypto/cipher/test/aes_128_gcm_tests.txt111
-rw-r--r--src/crypto/cipher/test/aes_256_gcm_tests.txt46
-rw-r--r--src/crypto/cipher/test/chacha20_poly1305_old_tests.txt524
-rw-r--r--src/crypto/cipher/test/chacha20_poly1305_tests.txt508
-rw-r--r--src/crypto/cipher/test/cipher_test.txt60
-rw-r--r--src/crypto/cipher/tls_cbc.c10
-rw-r--r--src/crypto/cmac/CMakeLists.txt5
-rw-r--r--src/crypto/cmac/cmac_test.cc13
-rw-r--r--src/crypto/conf/CMakeLists.txt2
-rw-r--r--src/crypto/conf/conf.c64
-rw-r--r--src/crypto/conf/internal.h31
-rw-r--r--src/crypto/cpu-arm.c30
-rw-r--r--src/crypto/cpu-intel.c157
-rw-r--r--src/crypto/cpu-x86-asm.pl334
-rw-r--r--src/crypto/cpu-x86_64-asm.pl163
-rw-r--r--src/crypto/crypto.c50
-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/CMakeLists.txt2
-rw-r--r--src/crypto/des/des.c155
-rw-r--r--src/crypto/des/internal.h27
-rw-r--r--src/crypto/dh/CMakeLists.txt4
-rw-r--r--src/crypto/dh/dh.c317
-rw-r--r--src/crypto/dh/dh_impl.c326
-rw-r--r--src/crypto/dh/dh_test.cc13
-rw-r--r--src/crypto/dh/params.c257
-rw-r--r--src/crypto/digest/CMakeLists.txt3
-rw-r--r--src/crypto/digest/digest.c32
-rw-r--r--src/crypto/digest/digests.c3
-rw-r--r--src/crypto/digest/internal.h17
-rw-r--r--src/crypto/digest/md32_common.h438
-rw-r--r--src/crypto/dsa/CMakeLists.txt4
-rw-r--r--src/crypto/dsa/dsa.c666
-rw-r--r--src/crypto/dsa/dsa_asn1.c2
-rw-r--r--src/crypto/dsa/dsa_impl.c750
-rw-r--r--src/crypto/ec/CMakeLists.txt19
-rw-r--r--src/crypto/ec/asm/p256-x86_64-asm.pl2725
-rw-r--r--src/crypto/ec/ec.c408
-rw-r--r--src/crypto/ec/ec_asn1.c94
-rw-r--r--src/crypto/ec/ec_key.c123
-rw-r--r--src/crypto/ec/ec_montgomery.c95
-rw-r--r--src/crypto/ec/ec_test.cc77
-rw-r--r--src/crypto/ec/internal.h124
-rw-r--r--src/crypto/ec/oct.c117
-rw-r--r--src/crypto/ec/p224-64.c1305
-rw-r--r--src/crypto/ec/p256-64.c129
-rw-r--r--src/crypto/ec/p256-x86_64-table.h9548
-rw-r--r--src/crypto/ec/p256-x86_64.c596
-rw-r--r--src/crypto/ec/simple.c66
-rw-r--r--src/crypto/ec/wnaf.c480
-rw-r--r--src/crypto/ecdh/CMakeLists.txt2
-rw-r--r--src/crypto/ecdh/ecdh.c84
-rw-r--r--src/crypto/ecdsa/CMakeLists.txt3
-rw-r--r--src/crypto/ecdsa/ecdsa.c166
-rw-r--r--src/crypto/ecdsa/ecdsa_asn1.c189
-rw-r--r--src/crypto/ecdsa/ecdsa_test.cc102
-rw-r--r--src/crypto/engine/CMakeLists.txt2
-rw-r--r--src/crypto/engine/engine.c24
-rw-r--r--src/crypto/err/CMakeLists.txt5
-rw-r--r--src/crypto/err/asn1.errordata239
-rw-r--r--src/crypto/err/bio.errordata53
-rw-r--r--src/crypto/err/bn.errordata63
-rw-r--r--src/crypto/err/buf.errordata4
-rw-r--r--src/crypto/err/cipher.errordata85
-rw-r--r--src/crypto/err/conf.errordata16
-rw-r--r--src/crypto/err/crypto.errordata4
-rw-r--r--src/crypto/err/dh.errordata12
-rw-r--r--src/crypto/err/digest.errordata4
-rw-r--r--src/crypto/err/dsa.errordata13
-rw-r--r--src/crypto/err/ec.errordata123
-rw-r--r--src/crypto/err/ecdh.errordata7
-rw-r--r--src/crypto/err/ecdsa.errordata16
-rw-r--r--src/crypto/err/engine.errordata2
-rw-r--r--src/crypto/err/err.c83
-rw-r--r--src/crypto/err/err_data_generate.go32
-rw-r--r--src/crypto/err/err_test.cc46
-rw-r--r--src/crypto/err/evp.errordata160
-rw-r--r--src/crypto/err/hkdf.errordata3
-rw-r--r--src/crypto/err/obj.errordata6
-rw-r--r--src/crypto/err/pem.errordata54
-rw-r--r--src/crypto/err/pkcs8.errordata68
-rw-r--r--src/crypto/err/rsa.errordata115
-rw-r--r--src/crypto/err/ssl.errordata564
-rw-r--r--src/crypto/err/x509.errordata133
-rw-r--r--src/crypto/err/x509v3.errordata183
-rw-r--r--src/crypto/evp/CMakeLists.txt7
-rw-r--r--src/crypto/evp/algorithm.c18
-rw-r--r--src/crypto/evp/digestsign.c77
-rw-r--r--src/crypto/evp/evp.c104
-rw-r--r--src/crypto/evp/evp_asn1.c (renamed from src/crypto/evp/asn1.c)30
-rw-r--r--src/crypto/evp/evp_ctx.c80
-rw-r--r--src/crypto/evp/evp_extra_test.cc348
-rw-r--r--src/crypto/evp/evp_test.cc78
-rw-r--r--src/crypto/evp/evp_tests.txt5
-rw-r--r--src/crypto/evp/internal.h76
-rw-r--r--src/crypto/evp/p_dsa_asn1.c65
-rw-r--r--src/crypto/evp/p_ec.c52
-rw-r--r--src/crypto/evp/p_ec_asn1.c71
-rw-r--r--src/crypto/evp/p_hmac.c223
-rw-r--r--src/crypto/evp/p_hmac_asn1.c89
-rw-r--r--src/crypto/evp/p_rsa.c51
-rw-r--r--src/crypto/evp/p_rsa_asn1.c118
-rw-r--r--src/crypto/evp/pbkdf.c16
-rw-r--r--src/crypto/evp/pbkdf_test.cc43
-rw-r--r--src/crypto/ex_data.c71
-rw-r--r--src/crypto/hkdf/CMakeLists.txt3
-rw-r--r--src/crypto/hkdf/hkdf.c4
-rw-r--r--src/crypto/hmac/CMakeLists.txt3
-rw-r--r--src/crypto/hmac/hmac.c4
-rw-r--r--src/crypto/hmac/hmac_test.cc25
-rw-r--r--src/crypto/hmac/hmac_tests.txt3
-rw-r--r--src/crypto/internal.h30
-rw-r--r--src/crypto/lhash/CMakeLists.txt3
-rw-r--r--src/crypto/lhash/lhash.c3
-rw-r--r--src/crypto/md4/CMakeLists.txt2
-rw-r--r--src/crypto/md4/md4.c48
-rw-r--r--src/crypto/md5/CMakeLists.txt2
-rw-r--r--src/crypto/md5/md5.c51
-rw-r--r--src/crypto/mem.c3
-rw-r--r--src/crypto/modes/CMakeLists.txt3
-rw-r--r--src/crypto/modes/asm/aesni-gcm-x86_64.pl24
-rw-r--r--src/crypto/modes/asm/ghash-armv4.pl15
-rw-r--r--src/crypto/modes/asm/ghash-x86.pl2
-rw-r--r--src/crypto/modes/asm/ghash-x86_64.pl32
-rw-r--r--src/crypto/modes/asm/ghashv8-armx.pl24
-rw-r--r--src/crypto/modes/cbc.c1
-rw-r--r--src/crypto/modes/cfb.c5
-rw-r--r--src/crypto/modes/ctr.c6
-rw-r--r--src/crypto/modes/gcm.c70
-rw-r--r--src/crypto/modes/gcm_test.c25
-rw-r--r--src/crypto/modes/internal.h180
-rw-r--r--src/crypto/modes/ofb.c5
-rw-r--r--src/crypto/obj/CMakeLists.txt2
-rw-r--r--src/crypto/obj/obj.c10
-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/CMakeLists.txt2
-rw-r--r--src/crypto/pem/pem_all.c10
-rw-r--r--src/crypto/pem/pem_info.c16
-rw-r--r--src/crypto/pem/pem_lib.c71
-rw-r--r--src/crypto/pem/pem_oth.c2
-rw-r--r--src/crypto/pem/pem_pk8.c10
-rw-r--r--src/crypto/pem/pem_pkey.c20
-rwxr-xr-xsrc/crypto/perlasm/arm-xlate.pl5
-rwxr-xr-xsrc/crypto/perlasm/x86_64-xlate.pl15
-rw-r--r--src/crypto/pkcs8/CMakeLists.txt10
-rw-r--r--src/crypto/pkcs8/internal.h9
-rw-r--r--src/crypto/pkcs8/p5_pbe.c10
-rw-r--r--src/crypto/pkcs8/p5_pbev2.c145
-rw-r--r--src/crypto/pkcs8/p8_pkey.c2
-rw-r--r--src/crypto/pkcs8/pkcs12_test.cc16
-rw-r--r--src/crypto/pkcs8/pkcs8.c298
-rw-r--r--src/crypto/pkcs8/pkcs8_test.cc91
-rw-r--r--src/crypto/poly1305/CMakeLists.txt12
-rw-r--r--src/crypto/poly1305/poly1305_arm.c2
-rw-r--r--src/crypto/poly1305/poly1305_test.cc80
-rw-r--r--src/crypto/poly1305/poly1305_test.txt52
-rw-r--r--src/crypto/rand/CMakeLists.txt3
-rw-r--r--src/crypto/rand/asm/rdrand-x86_64.pl52
-rw-r--r--src/crypto/rand/internal.h8
-rw-r--r--src/crypto/rand/rand.c93
-rw-r--r--src/crypto/rand/urandom.c296
-rw-r--r--src/crypto/rc4/CMakeLists.txt4
-rw-r--r--src/crypto/rc4/asm/rc4-md5-x86_64.pl632
-rw-r--r--src/crypto/rc4/asm/rc4-x86_64.pl2
-rw-r--r--src/crypto/rc4/rc4.c17
-rw-r--r--src/crypto/rsa/CMakeLists.txt5
-rw-r--r--src/crypto/rsa/blinding.c45
-rw-r--r--src/crypto/rsa/internal.h60
-rw-r--r--src/crypto/rsa/padding.c297
-rw-r--r--src/crypto/rsa/rsa.c206
-rw-r--r--src/crypto/rsa/rsa_asn1.c436
-rw-r--r--src/crypto/rsa/rsa_impl.c396
-rw-r--r--src/crypto/rsa/rsa_test.c511
-rw-r--r--src/crypto/rsa/rsa_test.cc918
-rw-r--r--src/crypto/sha/CMakeLists.txt2
-rw-r--r--src/crypto/sha/asm/sha1-586.pl27
-rw-r--r--src/crypto/sha/asm/sha1-armv4-large.pl2
-rw-r--r--src/crypto/sha/asm/sha1-armv8.pl2
-rw-r--r--src/crypto/sha/asm/sha1-x86_64.pl28
-rw-r--r--src/crypto/sha/asm/sha256-586.pl30
-rw-r--r--src/crypto/sha/asm/sha256-armv4.pl2
-rw-r--r--src/crypto/sha/asm/sha512-586.pl2
-rw-r--r--src/crypto/sha/asm/sha512-armv4.pl2
-rw-r--r--src/crypto/sha/asm/sha512-armv8.pl2
-rw-r--r--src/crypto/sha/asm/sha512-x86_64.pl34
-rw-r--r--src/crypto/sha/sha1.c208
-rw-r--r--src/crypto/sha/sha256.c195
-rw-r--r--src/crypto/sha/sha512.c280
-rw-r--r--src/crypto/stack/CMakeLists.txt2
-rw-r--r--src/crypto/test/CMakeLists.txt1
-rw-r--r--src/crypto/test/file_test.cc3
-rw-r--r--src/crypto/test/file_test.h8
-rw-r--r--src/crypto/test/malloc.cc17
-rw-r--r--src/crypto/test/scoped_types.h20
-rw-r--r--src/crypto/test/stl_compat.h144
-rw-r--r--src/crypto/test/test_util.cc (renamed from src/crypto/header_removed.h)21
-rw-r--r--src/crypto/test/test_util.h (renamed from src/crypto/rand/hwrand.c)47
-rw-r--r--src/crypto/thread_pthread.c7
-rw-r--r--src/crypto/time_support.c6
-rw-r--r--src/crypto/x509/CMakeLists.txt4
-rw-r--r--src/crypto/x509/a_digest.c2
-rw-r--r--src/crypto/x509/a_sign.c4
-rw-r--r--src/crypto/x509/a_verify.c10
-rw-r--r--src/crypto/x509/asn1_gen.c62
-rw-r--r--src/crypto/x509/by_dir.c14
-rw-r--r--src/crypto/x509/by_file.c24
-rw-r--r--src/crypto/x509/i2d_pr.c2
-rw-r--r--src/crypto/x509/pkcs7.c23
-rw-r--r--src/crypto/x509/t_crl.c2
-rw-r--r--src/crypto/x509/t_req.c246
-rw-r--r--src/crypto/x509/t_x509.c4
-rw-r--r--src/crypto/x509/x509_att.c16
-rw-r--r--src/crypto/x509/x509_cmp.c6
-rw-r--r--src/crypto/x509/x509_lu.c44
-rw-r--r--src/crypto/x509/x509_obj.c2
-rw-r--r--src/crypto/x509/x509_r2x.c2
-rw-r--r--src/crypto/x509/x509_req.c12
-rw-r--r--src/crypto/x509/x509_trs.c10
-rw-r--r--src/crypto/x509/x509_v3.c8
-rw-r--r--src/crypto/x509/x509_vfy.c148
-rw-r--r--src/crypto/x509/x509cset.c7
-rw-r--r--src/crypto/x509/x509name.c20
-rw-r--r--src/crypto/x509/x509spki.c12
-rw-r--r--src/crypto/x509/x_all.c75
-rw-r--r--src/crypto/x509/x_crl.c2
-rw-r--r--src/crypto/x509/x_info.c2
-rw-r--r--src/crypto/x509/x_name.c8
-rw-r--r--src/crypto/x509/x_pkey.c2
-rw-r--r--src/crypto/x509/x_pubkey.c20
-rw-r--r--src/crypto/x509/x_x509.c21
-rw-r--r--src/crypto/x509/x_x509a.c48
-rw-r--r--src/crypto/x509v3/CMakeLists.txt8
-rw-r--r--src/crypto/x509v3/ext_dat.h22
-rw-r--r--src/crypto/x509v3/pcy_tree.c2
-rw-r--r--src/crypto/x509v3/tab_test.c (renamed from src/crypto/x509v3/tabtest.c)5
-rw-r--r--src/crypto/x509v3/v3_akey.c10
-rw-r--r--src/crypto/x509v3/v3_alt.c64
-rw-r--r--src/crypto/x509v3/v3_bcons.c4
-rw-r--r--src/crypto/x509v3/v3_bitst.c6
-rw-r--r--src/crypto/x509v3/v3_conf.c26
-rw-r--r--src/crypto/x509v3/v3_cpols.c40
-rw-r--r--src/crypto/x509v3/v3_crld.c14
-rw-r--r--src/crypto/x509v3/v3_extku.c4
-rw-r--r--src/crypto/x509v3/v3_ia5.c6
-rw-r--r--src/crypto/x509v3/v3_info.c12
-rw-r--r--src/crypto/x509v3/v3_lib.c16
-rw-r--r--src/crypto/x509v3/v3_ncons.c4
-rw-r--r--src/crypto/x509v3/v3_pci.c35
-rw-r--r--src/crypto/x509v3/v3_pcons.c6
-rw-r--r--src/crypto/x509v3/v3_pmaps.c8
-rw-r--r--src/crypto/x509v3/v3_purp.c29
-rw-r--r--src/crypto/x509v3/v3_skey.c10
-rw-r--r--src/crypto/x509v3/v3_sxnet.c16
-rw-r--r--src/crypto/x509v3/v3_utl.c52
-rw-r--r--src/crypto/x509v3/v3name_test.c (renamed from src/crypto/x509v3/v3nametest.c)2
-rw-r--r--src/decrepit/CMakeLists.txt14
-rw-r--r--src/decrepit/bio/CMakeLists.txt9
-rw-r--r--src/decrepit/bio/base64_bio.c536
-rw-r--r--src/decrepit/blowfish/CMakeLists.txt2
-rw-r--r--src/decrepit/cast/CMakeLists.txt2
-rw-r--r--src/decrepit/cast/cast.c10
-rw-r--r--src/decrepit/cast/cast_tables.c3
-rw-r--r--src/decrepit/cast/internal.h (renamed from src/include/openssl/ssl23.h)40
-rw-r--r--src/decrepit/des/CMakeLists.txt9
-rw-r--r--src/decrepit/des/cfb64ede.c236
-rw-r--r--src/decrepit/rsa/CMakeLists.txt9
-rw-r--r--src/decrepit/rsa/rsa_decrepit.c (renamed from src/ssl/ssl_algs.c)34
-rw-r--r--src/decrepit/xts/CMakeLists.txt9
-rw-r--r--src/decrepit/xts/xts.c258
l---------src/doc/doc.css1
-rw-r--r--src/include/openssl/aead.h47
-rw-r--r--src/include/openssl/aes.h2
-rw-r--r--src/include/openssl/arm_arch.h (renamed from src/crypto/arm_arch.h)11
-rw-r--r--src/include/openssl/asn1.h143
-rw-r--r--src/include/openssl/asn1_mac.h1
-rw-r--r--src/include/openssl/asn1t.h1
-rw-r--r--src/include/openssl/base.h40
-rw-r--r--src/include/openssl/base64.h59
-rw-r--r--src/include/openssl/bio.h54
-rw-r--r--src/include/openssl/bn.h105
-rw-r--r--src/include/openssl/buf.h5
-rw-r--r--src/include/openssl/bytestring.h79
-rw-r--r--src/include/openssl/chacha.h6
-rw-r--r--src/include/openssl/cipher.h66
-rw-r--r--src/include/openssl/cmac.h2
-rw-r--r--src/include/openssl/conf.h4
-rw-r--r--src/include/openssl/cpu.h71
-rw-r--r--src/include/openssl/crypto.h15
-rw-r--r--src/include/openssl/curve25519.h92
-rw-r--r--src/include/openssl/des.h40
-rw-r--r--src/include/openssl/dh.h44
-rw-r--r--src/include/openssl/digest.h23
-rw-r--r--src/include/openssl/dsa.h38
-rw-r--r--src/include/openssl/ec.h110
-rw-r--r--src/include/openssl/ec_key.h14
-rw-r--r--src/include/openssl/ecdh.h7
-rw-r--r--src/include/openssl/ecdsa.h44
-rw-r--r--src/include/openssl/engine.h9
-rw-r--r--src/include/openssl/err.h72
-rw-r--r--src/include/openssl/evp.h150
-rw-r--r--src/include/openssl/ex_data.h49
-rw-r--r--src/include/openssl/hkdf.h1
-rw-r--r--src/include/openssl/lhash.h5
-rw-r--r--src/include/openssl/md4.h11
-rw-r--r--src/include/openssl/md5.h11
-rw-r--r--src/include/openssl/mem.h3
-rw-r--r--src/include/openssl/modes.h223
-rw-r--r--src/include/openssl/obj.h14
-rw-r--r--src/include/openssl/obj_mac.h4
-rw-r--r--src/include/openssl/pem.h30
-rw-r--r--src/include/openssl/pkcs8.h99
-rw-r--r--src/include/openssl/poly1305.h28
-rw-r--r--src/include/openssl/rand.h54
-rw-r--r--src/include/openssl/rsa.h266
-rw-r--r--src/include/openssl/sha.h27
-rw-r--r--src/include/openssl/srtp.h188
-rw-r--r--src/include/openssl/ssl.h5519
-rw-r--r--src/include/openssl/ssl2.h268
-rw-r--r--src/include/openssl/ssl3.h272
-rw-r--r--src/include/openssl/stack.h10
-rw-r--r--src/include/openssl/stack_macros.h474
-rw-r--r--src/include/openssl/time_support.h6
-rw-r--r--src/include/openssl/tls1.h137
-rw-r--r--src/include/openssl/x509.h153
-rw-r--r--src/include/openssl/x509_vfy.h3
-rw-r--r--src/include/openssl/x509v3.h57
-rw-r--r--src/ssl/CMakeLists.txt16
-rw-r--r--src/ssl/custom_extensions.c257
-rw-r--r--src/ssl/d1_both.c676
-rw-r--r--src/ssl/d1_clnt.c337
-rw-r--r--src/ssl/d1_lib.c140
-rw-r--r--src/ssl/d1_meth.c6
-rw-r--r--src/ssl/d1_pkt.c767
-rw-r--r--src/ssl/d1_srtp.c256
-rw-r--r--src/ssl/d1_srvr.c272
-rw-r--r--src/ssl/dtls_record.c308
-rw-r--r--src/ssl/internal.h1008
-rw-r--r--src/ssl/pqueue/CMakeLists.txt1
-rw-r--r--src/ssl/pqueue/pqueue_test.c3
-rw-r--r--src/ssl/s3_both.c391
-rw-r--r--src/ssl/s3_clnt.c2242
-rw-r--r--src/ssl/s3_enc.c219
-rw-r--r--src/ssl/s3_lib.c447
-rw-r--r--src/ssl/s3_meth.c5
-rw-r--r--src/ssl/s3_pkt.c952
-rw-r--r--src/ssl/s3_srvr.c1936
-rw-r--r--src/ssl/ssl_aead_ctx.c95
-rw-r--r--src/ssl/ssl_asn1.c450
-rw-r--r--src/ssl/ssl_buffer.c319
-rw-r--r--src/ssl/ssl_cert.c744
-rw-r--r--src/ssl/ssl_cipher.c912
-rw-r--r--src/ssl/ssl_ecdh.c383
-rw-r--r--src/ssl/ssl_file.c633
-rw-r--r--src/ssl/ssl_lib.c2711
-rw-r--r--src/ssl/ssl_rsa.c555
-rw-r--r--src/ssl/ssl_sess.c878
-rw-r--r--src/ssl/ssl_session.c764
-rw-r--r--src/ssl/ssl_stat.c723
-rw-r--r--src/ssl/ssl_test.cc564
-rw-r--r--src/ssl/ssl_txt.c212
-rw-r--r--src/ssl/t1_enc.c428
-rw-r--r--src/ssl/t1_lib.c3383
-rw-r--r--src/ssl/t1_reneg.c246
-rw-r--r--src/ssl/test/async_bio.cc14
-rw-r--r--src/ssl/test/async_bio.h3
-rw-r--r--src/ssl/test/bssl_shim.cc900
-rw-r--r--src/ssl/test/packeted_bio.h2
-rw-r--r--src/ssl/test/runner/alert.go2
-rw-r--r--src/ssl/test/runner/chacha20_poly1305.go130
-rw-r--r--src/ssl/test/runner/chacha20_poly1305_test.go85
-rw-r--r--src/ssl/test/runner/cipher_suites.go155
-rw-r--r--src/ssl/test/runner/common.go179
-rw-r--r--src/ssl/test/runner/conn.go151
-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/dtls.go35
-rw-r--r--src/ssl/test/runner/handshake_client.go58
-rw-r--r--src/ssl/test/runner/handshake_messages.go238
-rw-r--r--src/ssl/test/runner/handshake_server.go76
-rw-r--r--src/ssl/test/runner/key_agreement.go209
-rw-r--r--src/ssl/test/runner/packet_adapter.go17
-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/prf.go2
-rw-r--r--src/ssl/test/runner/recordingconn.go90
-rw-r--r--src/ssl/test/runner/runner.go3536
-rw-r--r--src/ssl/test/runner/runner_test.go7
-rw-r--r--src/ssl/test/runner/test_output.go2
-rw-r--r--src/ssl/test/runner/ticket.go2
-rw-r--r--src/ssl/test/runner/tls.go2
-rw-r--r--src/ssl/test/test_config.cc38
-rw-r--r--src/ssl/test/test_config.h33
-rw-r--r--src/ssl/tls_record.c342
-rw-r--r--src/tool/CMakeLists.txt10
-rw-r--r--src/tool/args.cc27
-rw-r--r--src/tool/ciphers.cc66
-rw-r--r--src/tool/client.cc75
-rw-r--r--src/tool/const.cc120
-rw-r--r--src/tool/generate_ed25519.cc67
-rw-r--r--src/tool/genrsa.cc69
-rw-r--r--src/tool/internal.h14
-rw-r--r--src/tool/pkcs12.cc6
-rw-r--r--src/tool/server.cc54
-rw-r--r--src/tool/speed.cc111
-rw-r--r--src/tool/tool.cc37
-rw-r--r--src/tool/transport_common.cc17
-rw-r--r--src/util/all_tests.go92
-rw-r--r--src/util/all_tests.json61
-rwxr-xr-xsrc/util/bot/go/bootstrap.py5
-rw-r--r--src/util/bot/update_clang.py2
-rw-r--r--src/util/doc.config3
-rw-r--r--src/util/doc.go149
-rw-r--r--src/util/generate_build_files.py231
-rw-r--r--src/util/make_errors.go98
-rw-r--r--ssl-sources.mk2
-rw-r--r--win-x86/crypto/cpu-x86-asm.asm303
-rw-r--r--win-x86/crypto/sha/sha1-586.asm1355
-rw-r--r--win-x86/crypto/sha/sha256-586.asm1394
-rw-r--r--win-x86_64/crypto/bn/modexp512-x86_64.asm1887
-rw-r--r--win-x86_64/crypto/bn/x86_64-mont5.asm9
-rw-r--r--win-x86_64/crypto/cpu-x86_64-asm.asm154
-rw-r--r--win-x86_64/crypto/ec/p256-x86_64-asm.asm1916
-rw-r--r--win-x86_64/crypto/rand/rdrand-x86_64.asm50
-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
606 files changed, 96139 insertions, 44791 deletions
diff --git a/Android.mk b/Android.mk
index 66f6033..3e3ef2a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -13,14 +13,10 @@ LOCAL_MODULE := libcrypto_static
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/src/include
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/crypto-sources.mk
LOCAL_SDK_VERSION := 9
-LOCAL_CFLAGS = -Wno-unused-parameter
+LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -DOPENSSL_SMALL -Wno-unused-parameter
# sha256-armv4.S does not compile with clang.
LOCAL_CLANG_ASFLAGS_arm += -no-integrated-as
-ifeq ($(TARGET_ARCH),arm64)
-ifeq ($(USE_CLANG_PLATFORM_BUILD),true)
-LOCAL_ASFLAGS += -march=armv8-a+crypto
-endif
-endif
+LOCAL_CLANG_ASFLAGS_arm64 += -march=armv8-a+crypto
include $(LOCAL_PATH)/crypto-sources.mk
include $(BUILD_STATIC_LIBRARY)
@@ -30,15 +26,11 @@ LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := libcrypto
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/src/include
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/crypto-sources.mk
-LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -Wno-unused-parameter
+LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -DOPENSSL_SMALL -Wno-unused-parameter
LOCAL_SDK_VERSION := 9
# sha256-armv4.S does not compile with clang.
LOCAL_CLANG_ASFLAGS_arm += -no-integrated-as
-ifeq ($(TARGET_ARCH),arm64)
-ifeq ($(USE_CLANG_PLATFORM_BUILD),true)
-LOCAL_ASFLAGS += -march=armv8-a+crypto
-endif
-endif
+LOCAL_CLANG_ASFLAGS_arm64 += -march=armv8-a+crypto
include $(LOCAL_PATH)/crypto-sources.mk
include $(BUILD_SHARED_LIBRARY)
@@ -49,7 +41,7 @@ LOCAL_CPP_EXTENSION := cc
LOCAL_MODULE := bssl
LOCAL_MODULE_TAGS := optional
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/sources.mk
-LOCAL_CFLAGS = -Wno-unused-parameter
+LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -DOPENSSL_SMALL -Wno-unused-parameter
LOCAL_SHARED_LIBRARIES=libcrypto libssl
include $(LOCAL_PATH)/sources.mk
LOCAL_SRC_FILES = $(tool_sources)
@@ -57,30 +49,39 @@ include $(BUILD_EXECUTABLE)
# Host static library
include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := optional
+LOCAL_IS_HOST_MODULE := true
LOCAL_MODULE := libcrypto_static
+LOCAL_MODULE_HOST_OS := darwin linux windows
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/src/include
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/crypto-sources.mk
-LOCAL_CFLAGS = -Wno-unused-parameter
+LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -DOPENSSL_SMALL -Wno-unused-parameter
+LOCAL_CXX_STL := none
# Windows and Macs both have problems with assembly files
-ifneq ($(HOST_OS),linux)
-LOCAL_CFLAGS += -DOPENSSL_NO_ASM
-endif
+LOCAL_CFLAGS_darwin += -DOPENSSL_NO_ASM
+LOCAL_CFLAGS_windows += -DOPENSSL_NO_ASM
+# TODO: b/26097626. ASAN breaks use of this library in JVM.
+# Re-enable sanitization when the issue with making clients of this library
+# preload ASAN runtime is resolved. Without that, clients are getting runtime
+# errors due to unresoled ASAN symbols, such as
+# __asan_option_detect_stack_use_after_return.
+LOCAL_SANITIZE := never
include $(LOCAL_PATH)/crypto-sources.mk
include $(BUILD_HOST_STATIC_LIBRARY)
# Host shared library
include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := optional
+LOCAL_IS_HOST_MODULE := true
LOCAL_MODULE := libcrypto-host
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
LOCAL_MULTILIB := both
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/crypto-sources.mk
-LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -Wno-unused-parameter
+LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -DOPENSSL_SMALL -Wno-unused-parameter
# Windows and Macs both have problems with assembly files
-ifneq ($(HOST_OS),linux)
-LOCAL_CFLAGS += -DOPENSSL_NO_ASM
-endif
+LOCAL_CFLAGS_darwin += -DOPENSSL_NO_ASM
+LOCAL_CFLAGS_windows += -DOPENSSL_NO_ASM
+LOCAL_LDLIBS_darwin := -lpthread
+LOCAL_LDLIBS_linux := -lpthread
+LOCAL_CXX_STL := none
include $(LOCAL_PATH)/crypto-sources.mk
include $(BUILD_HOST_SHARED_LIBRARY)
@@ -94,7 +95,7 @@ LOCAL_MODULE := libssl_static
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/src/include
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/ssl-sources.mk
LOCAL_SDK_VERSION := 9
-LOCAL_CFLAGS = -Wno-unused-parameter
+LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -DOPENSSL_SMALL -Wno-unused-parameter
include $(LOCAL_PATH)/ssl-sources.mk
include $(BUILD_STATIC_LIBRARY)
@@ -104,7 +105,7 @@ LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := libssl
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/src/include
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/ssl-sources.mk
-LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -Wno-unused-parameter
+LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -DOPENSSL_SMALL -Wno-unused-parameter
LOCAL_SHARED_LIBRARIES=libcrypto
LOCAL_SDK_VERSION := 9
include $(LOCAL_PATH)/ssl-sources.mk
@@ -116,10 +117,34 @@ LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := libssl_static-host
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/src/include
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/ssl-sources.mk
-LOCAL_CFLAGS = -Wno-unused-parameter
+LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -DOPENSSL_SMALL -Wno-unused-parameter
+LOCAL_CXX_STL := none
+# TODO: b/26097626. ASAN breaks use of this library in JVM.
+# Re-enable sanitization when the issue with making clients of this library
+# preload ASAN runtime is resolved. Without that, clients are getting runtime
+# errors due to unresoled ASAN symbols, such as
+# __asan_option_detect_stack_use_after_return.
+LOCAL_SANITIZE := never
include $(LOCAL_PATH)/ssl-sources.mk
include $(BUILD_HOST_STATIC_LIBRARY)
+# Host static tool (for linux only).
+ifeq ($(HOST_OS), linux)
+include $(CLEAR_VARS)
+LOCAL_CFLAGS += -Wall -Werror -std=c++0x
+LOCAL_CPP_EXTENSION := cc
+LOCAL_MODULE := bssl
+LOCAL_MODULE_TAGS := optional
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/sources.mk
+LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -DOPENSSL_SMALL -Wno-unused-parameter
+LOCAL_SHARED_LIBRARIES=libcrypto-host libssl-host
+# Needed for clock_gettime.
+LOCAL_LDFLAGS := -lrt
+include $(LOCAL_PATH)/sources.mk
+LOCAL_SRC_FILES = $(tool_sources)
+include $(BUILD_HOST_EXECUTABLE)
+endif # HOST_OS == linux
+
# Host shared library
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
@@ -127,7 +152,8 @@ LOCAL_MODULE := libssl-host
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/src/include
LOCAL_MULTILIB := both
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/ssl-sources.mk
-LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -Wno-unused-parameter
+LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -DOPENSSL_SMALL -Wno-unused-parameter
+LOCAL_CXX_STL := none
LOCAL_SHARED_LIBRARIES += libcrypto-host
include $(LOCAL_PATH)/ssl-sources.mk
include $(BUILD_HOST_SHARED_LIBRARY)
diff --git a/BORINGSSL_REVISION b/BORINGSSL_REVISION
index d63fc86..6e9fe82 100644
--- a/BORINGSSL_REVISION
+++ b/BORINGSSL_REVISION
@@ -1 +1 @@
-af0e32cb84f0c9cc65b9233a3414d2562642b342
+7b8b9c17db93ea5287575b437c77fb36eeb81b31
diff --git a/UPDATING b/UPDATING
new file mode 100644
index 0000000..c7019e4
--- /dev/null
+++ b/UPDATING
@@ -0,0 +1,9 @@
+rm -Rf src
+git clone https://boringssl.googlesource.com/boringssl src
+cd src
+git show -s --pretty=%H > ../BORINGSSL_REVISION
+cd ..
+rm -Rf src/.git
+rm -Rf src/fuzz
+rm -Rf linux-aarch64/ linux-arm/ linux-x86/ linux-x86_64/ mac-x86/ mac-x86_64/ win-x86_64/ win-x86/
+python src/util/generate_build_files.py android
diff --git a/crypto-sources.mk b/crypto-sources.mk
index 78194f2..a5b8ba3 100644
--- a/crypto-sources.mk
+++ b/crypto-sources.mk
@@ -1,12 +1,16 @@
LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/sources.mk
include $(LOCAL_PATH)/sources.mk
-LOCAL_CFLAGS += -I$(LOCAL_PATH)/src/include -I$(LOCAL_PATH)/src/crypto -Wno-unused-parameter
+LOCAL_CFLAGS += -I$(LOCAL_PATH)/src/include -I$(LOCAL_PATH)/src/crypto -Wno-unused-parameter -DBORINGSSL_ANDROID_SYSTEM
+LOCAL_ASFLAGS += -I$(LOCAL_PATH)/src/include -I$(LOCAL_PATH)/src/crypto -Wno-unused-parameter
# Do not add in the architecture-specific files if we don't want to build assembly
-ifeq (,$(filter -DOPENSSL_NO_ASM,$(LOCAL_CFLAGS)))
-LOCAL_SRC_FILES_x86 = $(linux_x86_sources)
-LOCAL_SRC_FILES_x86_64 = $(linux_x86_64_sources)
-LOCAL_SRC_FILES_arm = $(linux_arm_sources)
-LOCAL_SRC_FILES_arm64 = $(linux_aarch64_sources)
+ifeq ($(LOCAL_IS_HOST_MODULE),true)
+LOCAL_SRC_FILES_linux_x86 := $(linux_x86_sources)
+LOCAL_SRC_FILES_linux_x86_64 := $(linux_x86_64_sources)
+else
+LOCAL_SRC_FILES_x86 := $(linux_x86_sources)
+LOCAL_SRC_FILES_x86_64 := $(linux_x86_64_sources)
+LOCAL_SRC_FILES_arm := $(linux_arm_sources)
+LOCAL_SRC_FILES_arm64 := $(linux_aarch64_sources)
endif
LOCAL_SRC_FILES += $(crypto_sources)
diff --git a/err_data.c b/err_data.c
index 5a79137..fe7979b 100644
--- a/err_data.c
+++ b/err_data.c
@@ -49,1536 +49,183 @@ OPENSSL_COMPILE_ASSERT(ERR_LIB_ECDH == 27, library_values_changed_27);
OPENSSL_COMPILE_ASSERT(ERR_LIB_HMAC == 28, library_values_changed_28);
OPENSSL_COMPILE_ASSERT(ERR_LIB_DIGEST == 29, library_values_changed_29);
OPENSSL_COMPILE_ASSERT(ERR_LIB_CIPHER == 30, library_values_changed_30);
-OPENSSL_COMPILE_ASSERT(ERR_LIB_USER == 31, library_values_changed_31);
-OPENSSL_COMPILE_ASSERT(ERR_LIB_HKDF == 32, library_values_changed_32);
+OPENSSL_COMPILE_ASSERT(ERR_LIB_HKDF == 31, library_values_changed_31);
+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 kOpenSSLFunctionValues[] = {
- 0xc32054b,
- 0xc328556,
- 0xc330561,
- 0xc33856e,
- 0xc340578,
- 0xc348582,
- 0xc350589,
- 0xc358595,
- 0xc36059c,
- 0xc3685b2,
- 0xc3705d1,
- 0xc3785e2,
- 0xc3805f2,
- 0xc38860c,
- 0xc390621,
- 0xc398630,
- 0xc3a0649,
- 0xc3a865d,
- 0xc3b0669,
- 0xc3b8670,
- 0xc3c0678,
- 0xc3c8690,
- 0xc3d0698,
- 0xc3d86a0,
- 0xc3e06ab,
- 0xc3e85c7,
- 0xc3f0686,
- 0x1032193d,
- 0x10329954,
- 0x1033196d,
- 0x10339983,
- 0x10341993,
- 0x103499a6,
- 0x103519b4,
- 0x103599c3,
- 0x103619e3,
- 0x10369a02,
- 0x10371a1f,
- 0x10379a3c,
- 0x10381a51,
- 0x10389a73,
- 0x10391a92,
- 0x10399ab1,
- 0x103a1ac8,
- 0x103a9adf,
- 0x103b1ae8,
- 0x103b9af3,
- 0x103c1b0d,
- 0x103c9b15,
- 0x103d1b1d,
- 0x103d9b24,
- 0x103e1b37,
- 0x103e9b49,
- 0x103f1b5c,
- 0x103f9b65,
- 0x14320a4e,
- 0x14328a5c,
- 0x14330a68,
- 0x14338a75,
- 0x18361224,
- 0x18371252,
- 0x18379263,
- 0x18381279,
- 0x1839129c,
- 0x183992b1,
- 0x183a12c3,
- 0x183c1307,
- 0x183c9315,
- 0x183d1328,
- 0x183d9338,
- 0x183e935e,
- 0x183f1371,
- 0x183f9380,
- 0x184093aa,
- 0x18411416,
- 0x18419427,
- 0x1842143a,
- 0x1842944c,
- 0x1843145e,
- 0x1843946f,
- 0x18441480,
- 0x18449491,
- 0x184514a2,
- 0x184594af,
- 0x184614d1,
- 0x184694e4,
- 0x184714f8,
- 0x18479505,
- 0x18481514,
- 0x18489523,
- 0x18491534,
- 0x18499550,
- 0x184a155e,
- 0x184a956f,
- 0x184b1580,
- 0x184b958e,
- 0x184c159e,
- 0x184c95c4,
- 0x184d15d3,
- 0x184d95e3,
- 0x184e15f3,
- 0x184e9602,
- 0x184f1541,
- 0x184f91b3,
- 0x18501156,
- 0x1850916e,
- 0x18511190,
- 0x185191a2,
- 0x185211d4,
- 0x185291ed,
- 0x185311fe,
- 0x18539214,
- 0x18541239,
- 0x1854928a,
- 0x185512d3,
- 0x185592e8,
- 0x185612f5,
- 0x1856934d,
- 0x18571390,
- 0x1857939d,
- 0x185813b9,
- 0x185893ca,
- 0x185913da,
- 0x185993ea,
- 0x185a13f9,
- 0x185a9408,
- 0x185b14bd,
- 0x1c3206b8,
- 0x1c3286c4,
- 0x1c3306cf,
- 0x1c3386db,
- 0x20321616,
- 0x20329621,
- 0x20331629,
- 0x20339635,
- 0x24321641,
- 0x2432964f,
- 0x24331661,
- 0x24339670,
- 0x24341683,
- 0x24349696,
- 0x243516ad,
- 0x243596c5,
- 0x243616d3,
- 0x243696eb,
- 0x243716f4,
- 0x24379706,
- 0x2438171a,
- 0x24389727,
- 0x2439173d,
- 0x24399755,
- 0x243a176d,
- 0x243a9777,
- 0x243b178c,
- 0x243b979a,
- 0x243c17b2,
- 0x243c97c9,
- 0x243d17d4,
- 0x243d97e2,
- 0x28320aae,
- 0x28328abd,
- 0x28330ac8,
- 0x28338acd,
- 0x28340ad8,
- 0x2c322b00,
- 0x2c32ab0c,
- 0x2c332b1f,
- 0x2c33ab30,
- 0x2c342b49,
- 0x2c34ab71,
- 0x2c352b88,
- 0x2c35aba5,
- 0x2c362bc2,
- 0x2c36abdf,
- 0x2c372bf8,
- 0x2c37ac11,
- 0x2c382c27,
- 0x2c38ac35,
- 0x2c392c47,
- 0x2c39ac64,
- 0x2c3a2c81,
- 0x2c3aac8f,
- 0x2c3b2cad,
- 0x2c3baccb,
- 0x2c3c2ce6,
- 0x2c3cacfa,
- 0x2c3d2d0c,
- 0x2c3dad1c,
- 0x2c3e2d2a,
- 0x2c3ead3a,
- 0x2c3f2d4a,
- 0x2c3fad65,
- 0x2c402d76,
- 0x2c40ad91,
- 0x2c412da5,
- 0x2c41adb8,
- 0x2c422dd7,
- 0x2c42adeb,
- 0x2c432dfe,
- 0x2c43ae0d,
- 0x2c442e1c,
- 0x2c44ae33,
- 0x2c452e4e,
- 0x2c45ae66,
- 0x2c462e7a,
- 0x2c46ae8d,
- 0x2c472e9e,
- 0x2c47aeaf,
- 0x2c482ec0,
- 0x2c48aed1,
- 0x2c492ee0,
- 0x2c49aeed,
- 0x2c4a2efa,
- 0x2c4aaf07,
- 0x2c4b2f10,
- 0x2c4baf24,
- 0x2c4c2f33,
- 0x2c4caf41,
- 0x2c4d2f63,
- 0x2c4daf74,
- 0x2c4e2f85,
- 0x2c4eaf50,
- 0x2c4f2b62,
- 0x30320000,
- 0x30328018,
- 0x3033002c,
- 0x30338042,
- 0x3034005b,
- 0x3034806c,
- 0x3035007f,
- 0x3035808f,
- 0x3036009d,
- 0x303680b3,
- 0x303700c3,
- 0x303780d8,
- 0x303800e6,
- 0x303880f7,
- 0x30390103,
- 0x3039810c,
- 0x303a011d,
- 0x303a812d,
- 0x303b013a,
- 0x303b8146,
- 0x303c0157,
- 0x303c8165,
- 0x303d0176,
- 0x303d8188,
- 0x303e0199,
- 0x303e81a8,
- 0x303f01b9,
- 0x303f81cd,
- 0x304001df,
- 0x304081ec,
- 0x30410202,
- 0x30418215,
- 0x30420225,
- 0x30428239,
- 0x3043024a,
- 0x3043825a,
- 0x30440265,
- 0x3044826d,
- 0x3045027d,
- 0x30458294,
- 0x304602a1,
- 0x304682b7,
- 0x304702c9,
- 0x304782d5,
- 0x304802e1,
- 0x304882ef,
- 0x30490308,
- 0x30498316,
- 0x304a032b,
- 0x304a8343,
- 0x304b034d,
- 0x304b8361,
- 0x304c0372,
- 0x304c8382,
- 0x304d038f,
- 0x304d83a0,
- 0x304e03b0,
- 0x304e83c2,
- 0x304f03d3,
- 0x304f83e2,
- 0x305003f6,
- 0x30508404,
- 0x30510413,
- 0x3051841c,
- 0x343209d6,
- 0x343289e6,
- 0x343309f1,
- 0x343389fe,
- 0x38320a07,
- 0x38328a1f,
- 0x38330a32,
- 0x38338a3c,
- 0x3c320aeb,
- 0x3c328af9,
- 0x3c330b10,
- 0x3c338b24,
- 0x3c340b56,
- 0x3c348b67,
- 0x3c350b73,
- 0x3c358ba0,
- 0x3c360bb2,
- 0x3c368bdb,
- 0x3c370be8,
- 0x3c378bf5,
- 0x3c380c03,
- 0x3c388c10,
- 0x3c390c1d,
- 0x3c398c41,
- 0x3c3a0c51,
- 0x3c3a8c69,
- 0x3c3b0c7e,
- 0x3c3b8c93,
- 0x3c3c0ca0,
- 0x3c3c8cb3,
- 0x3c3d0cc6,
- 0x3c3d8cea,
- 0x3c3e0d12,
- 0x3c3e8d2b,
- 0x3c3f0d41,
- 0x3c3f8d4e,
- 0x3c400d61,
- 0x3c408d72,
- 0x3c410d83,
- 0x3c418d9c,
- 0x3c420db5,
- 0x3c428dcb,
- 0x3c430de8,
- 0x3c438dfe,
- 0x3c440e82,
- 0x3c448ea9,
- 0x3c450ec7,
- 0x3c458ee1,
- 0x3c460ef9,
- 0x3c468f11,
- 0x3c470f3c,
- 0x3c478f67,
- 0x3c480f88,
- 0x3c488fb1,
- 0x3c490fcc,
- 0x3c498ff5,
- 0x3c4a1002,
- 0x3c4a9019,
- 0x3c4b1030,
- 0x3c4b9059,
- 0x3c4c1069,
- 0x3c4c9075,
- 0x3c4d108d,
- 0x3c4d90a0,
- 0x3c4e10b1,
- 0x3c4e90c2,
- 0x3c4f10e8,
- 0x3c4f8adf,
- 0x3c500e1a,
- 0x3c508e3a,
- 0x3c510e67,
- 0x3c518fe7,
- 0x3c5210d2,
- 0x3c528b87,
- 0x3c530b3f,
- 0x40321ba5,
- 0x40329bbf,
- 0x40331be7,
- 0x40339bff,
- 0x40341c1d,
- 0x40349c64,
- 0x40351c7b,
- 0x40359c97,
- 0x40361cb3,
- 0x40369ccd,
- 0x40371cec,
- 0x40379d0b,
- 0x40381d23,
- 0x40389d40,
- 0x40391d63,
- 0x40399d80,
- 0x403a1d9e,
- 0x403a9dae,
- 0x403b1dc3,
- 0x403b9ddf,
- 0x403c1df9,
- 0x403c9e04,
- 0x403d1e27,
- 0x403d9e4b,
- 0x403e1e61,
- 0x403e9e6b,
- 0x403f1e77,
- 0x403f9e88,
- 0x40401ea0,
- 0x40409ea8,
- 0x40411eb1,
- 0x40419eba,
- 0x40421ee2,
- 0x40429ef6,
- 0x40431f01,
- 0x40439f0d,
- 0x40441f61,
- 0x40449f6d,
- 0x40451f7a,
- 0x40459f8d,
- 0x40461fa5,
- 0x40469fbd,
- 0x40471fd3,
- 0x40479fee,
- 0x40482009,
- 0x4048a01d,
- 0x40492036,
- 0x4049a04f,
- 0x404a2069,
- 0x404aa073,
- 0x404b2083,
- 0x404ba0a4,
- 0x404c20bf,
- 0x404ca0cd,
- 0x404d20da,
- 0x404da0ee,
- 0x404e2106,
- 0x404ea114,
- 0x404f213e,
- 0x404fa155,
- 0x40502167,
- 0x4050a198,
- 0x405121c9,
- 0x4051a1de,
- 0x40522201,
- 0x4052a221,
- 0x40532236,
- 0x4053a246,
- 0x4054a252,
- 0x40552268,
- 0x4055a286,
- 0x40562293,
- 0x4056a29d,
- 0x405722ab,
- 0x4057a2c6,
- 0x405822e1,
- 0x4058a300,
- 0x40592315,
- 0x4059a32a,
- 0x405a2347,
- 0x405aa35b,
- 0x405b2377,
- 0x405ba38d,
- 0x405c23aa,
- 0x405ca3bc,
- 0x405d23d3,
- 0x405da3e4,
- 0x405e2400,
- 0x405ea414,
- 0x405f2424,
- 0x405fa440,
- 0x40602455,
- 0x4060a46b,
- 0x40612488,
- 0x4061a4a1,
- 0x406224cb,
- 0x4062a4d4,
- 0x406324e4,
- 0x4063a51d,
- 0x40642533,
- 0x4064a551,
- 0x40652566,
- 0x4065a583,
- 0x4066259a,
- 0x4066a5b8,
- 0x406725d5,
- 0x4067a5ec,
- 0x4068260a,
- 0x4068a621,
- 0x40692639,
- 0x4069a64a,
- 0x406a265d,
- 0x406aa670,
- 0x406b2684,
- 0x406ba6a8,
- 0x406c26c3,
- 0x406ca6e4,
- 0x406d2708,
- 0x406da723,
- 0x406e2744,
- 0x406ea759,
- 0x406f2772,
- 0x406fa77f,
- 0x4070278d,
- 0x4070a79a,
- 0x407127b7,
- 0x4071a7d7,
- 0x407227f2,
- 0x4072a80b,
- 0x40732822,
- 0x4073a83c,
- 0x40742860,
- 0x4074a876,
- 0x4075288a,
- 0x4075a89f,
- 0x407628b9,
- 0x4076a8cb,
- 0x407728e0,
- 0x4077a906,
- 0x40782923,
- 0x4078a946,
- 0x4079296c,
- 0x4079a989,
- 0x407a29ac,
- 0x407aa9c8,
- 0x407b29e4,
- 0x407ba9f6,
- 0x407c2a03,
- 0x407e2a10,
- 0x407eaa26,
- 0x407f2a3e,
- 0x407faa51,
- 0x40802a66,
- 0x4080aa7f,
- 0x40812a9d,
- 0x4081aabd,
- 0x40822ac6,
- 0x4082aae2,
- 0x40832aeb,
- 0x4083a123,
- 0x408421b2,
- 0x4084a182,
- 0x4085250c,
- 0x4085a4f0,
- 0x40861c3c,
- 0x40869c4f,
- 0x40871f41,
- 0x40879f50,
- 0x40881bcb,
- 0x40889eca,
- 0x40891f28,
- 0x4089a4b4,
- 0x408a1b70,
- 0x408a9b81,
- 0x408b1b93,
- 0x408ba1ef,
- 0x4432042a,
- 0x4432843c,
- 0x44330445,
- 0x4433844d,
- 0x4434045a,
- 0x44348475,
- 0x44350490,
- 0x443584b0,
- 0x443604cc,
- 0x443684ed,
- 0x443704f4,
- 0x44378502,
- 0x4438050c,
- 0x44388518,
- 0x44390522,
- 0x4439852d,
- 0x443a0537,
- 0x443a8541,
- 0x443b046a,
- 0x4c3217ea,
- 0x4c3297f9,
- 0x4c331808,
- 0x4c339821,
- 0x4c34183c,
- 0x4c349858,
- 0x4c35186a,
- 0x4c359878,
- 0x4c36188d,
- 0x4c36989e,
- 0x4c3718ac,
- 0x4c3798ba,
- 0x4c3818cc,
- 0x4c3898dc,
- 0x4c3918e6,
- 0x4c3998fe,
- 0x4c3a1916,
- 0x4c3a9929,
- 0x50322f96,
- 0x5032afab,
- 0x50332fbc,
- 0x5033afcf,
- 0x50342fe0,
- 0x5034aff3,
- 0x50353002,
- 0x5035b017,
- 0x50363027,
- 0x5036b036,
- 0x50373047,
- 0x5037b057,
- 0x50383068,
- 0x5038b07b,
- 0x5039308d,
- 0x5039b0a3,
- 0x503a30b5,
- 0x503ab0c6,
- 0x503b30d7,
- 0x503bb0e8,
- 0x503c30f3,
- 0x503cb0ff,
- 0x503d310a,
- 0x503db115,
- 0x503e3122,
- 0x503eb137,
- 0x503f3145,
- 0x503fb159,
- 0x5040316c,
- 0x5040b17d,
- 0x50413197,
- 0x5041b1a6,
- 0x504231af,
- 0x5042b1be,
- 0x504331d0,
- 0x5043b1dc,
- 0x504431e4,
- 0x5044b1f7,
- 0x50453208,
- 0x5045b21e,
- 0x5046322a,
- 0x5046b23e,
- 0x5047324c,
- 0x5047b260,
- 0x5048327a,
- 0x5048b28e,
- 0x504932a4,
- 0x5049b2bb,
- 0x504a32cd,
- 0x504ab2e1,
- 0x504b32f6,
- 0x504bb30d,
- 0x504c3321,
- 0x504cb32a,
- 0x504d3332,
- 0x504db341,
- 0x504e3351,
- 0x68321109,
- 0x6832911a,
- 0x6833112a,
- 0x68339138,
- 0x68341145,
- 0x6c3210f8,
- 0x74320a89,
- 0x74328a9b,
- 0x783206e8,
- 0x7832871b,
- 0x7833072d,
- 0x7833873f,
- 0x78340753,
- 0x78348767,
- 0x78350785,
- 0x78358797,
- 0x783607ab,
- 0x78368819,
- 0x7837082b,
- 0x7837883d,
- 0x7838084f,
- 0x78388866,
- 0x7839087d,
- 0x78398894,
- 0x783a08b0,
- 0x783a88cc,
- 0x783b08e8,
- 0x783b88fe,
- 0x783c0914,
- 0x783c892a,
- 0x783d0947,
- 0x783d8956,
- 0x783e0965,
- 0x783e8974,
- 0x783f0990,
- 0x783f899e,
- 0x784009ac,
- 0x784089ba,
- 0x784109c7,
- 0x784186fa,
- 0x784207bf,
- 0x784287dd,
- 0x784307fb,
- 0x80321611,
-};
-
-const size_t kOpenSSLFunctionValuesLen = sizeof(kOpenSSLFunctionValues) / sizeof(kOpenSSLFunctionValues[0]);
-
-const char kOpenSSLFunctionStringData[] =
- "ASN1_BIT_STRING_set_bit\0"
- "ASN1_ENUMERATED_set\0"
- "ASN1_ENUMERATED_to_BN\0"
- "ASN1_GENERALIZEDTIME_adj\0"
- "ASN1_INTEGER_set\0"
- "ASN1_INTEGER_to_BN\0"
- "ASN1_OBJECT_new\0"
- "ASN1_PCTX_new\0"
- "ASN1_STRING_TABLE_add\0"
- "ASN1_STRING_set\0"
- "ASN1_STRING_type_new\0"
- "ASN1_TIME_adj\0"
- "ASN1_UTCTIME_adj\0"
- "ASN1_d2i_fp\0"
- "ASN1_dup\0"
- "ASN1_generate_v3\0"
- "ASN1_get_object\0"
- "ASN1_i2d_bio\0"
- "ASN1_i2d_fp\0"
- "ASN1_item_d2i_fp\0"
- "ASN1_item_dup\0"
- "ASN1_item_ex_d2i\0"
- "ASN1_item_i2d_bio\0"
- "ASN1_item_i2d_fp\0"
- "ASN1_item_pack\0"
- "ASN1_item_unpack\0"
- "ASN1_mbstring_ncopy\0"
- "ASN1_template_new\0"
- "BIO_new_NDEF\0"
- "BN_to_ASN1_ENUMERATED\0"
- "BN_to_ASN1_INTEGER\0"
- "a2d_ASN1_OBJECT\0"
- "a2i_ASN1_ENUMERATED\0"
- "a2i_ASN1_INTEGER\0"
- "a2i_ASN1_STRING\0"
- "append_exp\0"
- "asn1_cb\0"
- "asn1_check_tlen\0"
- "asn1_collate_primitive\0"
- "asn1_collect\0"
- "asn1_d2i_ex_primitive\0"
- "asn1_d2i_read_bio\0"
- "asn1_do_adb\0"
- "asn1_ex_c2i\0"
- "asn1_find_end\0"
- "asn1_item_ex_combine_new\0"
- "asn1_str2type\0"
- "asn1_template_ex_d2i\0"
- "asn1_template_noexp_d2i\0"
- "bitstr_cb\0"
- "c2i_ASN1_BIT_STRING\0"
- "c2i_ASN1_INTEGER\0"
- "c2i_ASN1_OBJECT\0"
- "collect_data\0"
- "d2i_ASN1_BOOLEAN\0"
- "d2i_ASN1_OBJECT\0"
- "d2i_ASN1_UINTEGER\0"
- "d2i_ASN1_UTCTIME\0"
- "d2i_ASN1_bytes\0"
- "d2i_ASN1_type_bytes\0"
- "i2d_ASN1_TIME\0"
- "i2d_PrivateKey\0"
- "long_c2i\0"
- "parse_tagging\0"
- "BIO_callback_ctrl\0"
- "BIO_ctrl\0"
- "BIO_new\0"
- "BIO_new_file\0"
- "BIO_new_mem_buf\0"
- "BIO_printf\0"
- "BIO_zero_copy_get_read_buf\0"
- "BIO_zero_copy_get_read_buf_done\0"
- "BIO_zero_copy_get_write_buf\0"
- "BIO_zero_copy_get_write_buf_done\0"
- "bio_io\0"
- "bio_make_pair\0"
- "bio_write\0"
- "buffer_ctrl\0"
- "conn_ctrl\0"
- "conn_state\0"
- "file_ctrl\0"
- "file_read\0"
- "mem_write\0"
- "BN_CTX_get\0"
- "BN_CTX_new\0"
- "BN_CTX_start\0"
- "BN_bn2dec\0"
- "BN_bn2hex\0"
- "BN_div\0"
- "BN_div_recp\0"
- "BN_exp\0"
- "BN_generate_dsa_nonce\0"
- "BN_generate_prime_ex\0"
- "BN_lshift\0"
- "BN_mod_exp2_mont\0"
- "BN_mod_exp_mont\0"
- "BN_mod_exp_mont_consttime\0"
- "BN_mod_exp_mont_word\0"
- "BN_mod_inverse\0"
- "BN_mod_inverse_no_branch\0"
- "BN_mod_lshift_quick\0"
- "BN_mod_sqrt\0"
- "BN_new\0"
- "BN_rand\0"
- "BN_rand_range\0"
- "BN_rshift\0"
- "BN_sqrt\0"
- "BN_usub\0"
- "bn_wexpand\0"
- "mod_exp_recp\0"
- "BUF_MEM_new\0"
- "BUF_memdup\0"
- "BUF_strndup\0"
- "buf_mem_grow\0"
- "EVP_AEAD_CTX_init\0"
- "EVP_AEAD_CTX_init_with_direction\0"
- "EVP_AEAD_CTX_open\0"
- "EVP_AEAD_CTX_seal\0"
- "EVP_CIPHER_CTX_copy\0"
- "EVP_CIPHER_CTX_ctrl\0"
- "EVP_CIPHER_CTX_set_key_length\0"
- "EVP_CipherInit_ex\0"
- "EVP_DecryptFinal_ex\0"
- "EVP_EncryptFinal_ex\0"
- "aead_aes_ctr_hmac_sha256_init\0"
- "aead_aes_ctr_hmac_sha256_open\0"
- "aead_aes_ctr_hmac_sha256_seal\0"
- "aead_aes_gcm_init\0"
- "aead_aes_gcm_open\0"
- "aead_aes_gcm_seal\0"
- "aead_aes_key_wrap_init\0"
- "aead_aes_key_wrap_open\0"
- "aead_aes_key_wrap_seal\0"
- "aead_chacha20_poly1305_init\0"
- "aead_chacha20_poly1305_open\0"
- "aead_chacha20_poly1305_seal\0"
- "aead_rc4_md5_tls_init\0"
- "aead_rc4_md5_tls_open\0"
- "aead_rc4_md5_tls_seal\0"
- "aead_ssl3_ensure_cipher_init\0"
- "aead_ssl3_init\0"
- "aead_ssl3_open\0"
- "aead_ssl3_seal\0"
- "aead_tls_ensure_cipher_init\0"
- "aead_tls_init\0"
- "aead_tls_open\0"
- "aead_tls_seal\0"
- "aes_init_key\0"
- "aesni_init_key\0"
- "CONF_parse_list\0"
- "NCONF_load\0"
- "def_load_bio\0"
- "str_copy\0"
- "CRYPTO_get_ex_new_index\0"
- "CRYPTO_set_ex_data\0"
- "get_class\0"
- "get_func_pointers\0"
- "DH_new_method\0"
- "compute_key\0"
- "generate_key\0"
- "generate_parameters\0"
- "EVP_DigestInit_ex\0"
- "EVP_MD_CTX_copy_ex\0"
- "DSA_new_method\0"
- "dsa_sig_cb\0"
- "sign\0"
- "sign_setup\0"
- "verify\0"
- "BN_to_felem\0"
- "EC_GROUP_copy\0"
- "EC_GROUP_get_curve_GFp\0"
- "EC_GROUP_get_degree\0"
- "EC_GROUP_new_by_curve_name\0"
- "EC_GROUP_new_curve_GFp\0"
- "EC_KEY_check_key\0"
- "EC_KEY_copy\0"
- "EC_KEY_generate_key\0"
- "EC_KEY_new_by_curve_name\0"
- "EC_KEY_new_method\0"
- "EC_KEY_set_public_key_affine_coordinates\0"
- "EC_POINT_add\0"
- "EC_POINT_cmp\0"
- "EC_POINT_copy\0"
- "EC_POINT_dbl\0"
- "EC_POINT_dup\0"
- "EC_POINT_get_affine_coordinates_GFp\0"
- "EC_POINT_invert\0"
- "EC_POINT_is_at_infinity\0"
- "EC_POINT_is_on_curve\0"
- "EC_POINT_make_affine\0"
- "EC_POINT_new\0"
- "EC_POINT_oct2point\0"
- "EC_POINT_point2oct\0"
- "EC_POINT_set_affine_coordinates_GFp\0"
- "EC_POINT_set_compressed_coordinates_GFp\0"
- "EC_POINT_set_to_infinity\0"
- "EC_POINTs_make_affine\0"
- "compute_wNAF\0"
- "d2i_ECPKParameters\0"
- "d2i_ECParameters\0"
- "d2i_ECPrivateKey\0"
- "ec_GFp_mont_field_decode\0"
- "ec_GFp_mont_field_encode\0"
- "ec_GFp_mont_field_mul\0"
- "ec_GFp_mont_field_set_to_one\0"
- "ec_GFp_mont_field_sqr\0"
- "ec_GFp_mont_group_set_curve\0"
- "ec_GFp_nistp256_group_set_curve\0"
- "ec_GFp_nistp256_point_get_affine_coordinates\0"
- "ec_GFp_nistp256_points_mul\0"
- "ec_GFp_simple_group_check_discriminant\0"
- "ec_GFp_simple_group_set_curve\0"
- "ec_GFp_simple_make_affine\0"
- "ec_GFp_simple_oct2point\0"
- "ec_GFp_simple_point2oct\0"
- "ec_GFp_simple_point_get_affine_coordinates\0"
- "ec_GFp_simple_point_set_affine_coordinates\0"
- "ec_GFp_simple_points_make_affine\0"
- "ec_GFp_simple_set_compressed_coordinates\0"
- "ec_asn1_group2pkparameters\0"
- "ec_asn1_pkparameters2group\0"
- "ec_group_copy\0"
- "ec_group_new\0"
- "ec_group_new_curve_GFp\0"
- "ec_group_new_from_data\0"
- "ec_point_set_Jprojective_coordinates_GFp\0"
- "ec_pre_comp_new\0"
- "ec_wNAF_mul\0"
- "ec_wNAF_precompute_mult\0"
- "i2d_ECPKParameters\0"
- "i2d_ECParameters\0"
- "i2d_ECPrivateKey\0"
- "i2o_ECPublicKey\0"
- "nistp256_pre_comp_new\0"
- "o2i_ECPublicKey\0"
- "ECDH_compute_key\0"
- "ECDSA_do_sign_ex\0"
- "ECDSA_do_verify\0"
- "ECDSA_sign_ex\0"
- "digest_to_bn\0"
- "ecdsa_sign_setup\0"
- "EVP_DigestSignAlgorithm\0"
- "EVP_DigestVerifyInitFromAlgorithm\0"
- "EVP_PKEY_CTX_ctrl\0"
- "EVP_PKEY_CTX_dup\0"
- "EVP_PKEY_CTX_get0_rsa_oaep_label\0"
- "EVP_PKEY_copy_parameters\0"
- "EVP_PKEY_decrypt\0"
- "EVP_PKEY_decrypt_init\0"
- "EVP_PKEY_derive\0"
- "EVP_PKEY_derive_init\0"
- "EVP_PKEY_derive_set_peer\0"
- "EVP_PKEY_encrypt\0"
- "EVP_PKEY_encrypt_init\0"
- "EVP_PKEY_get1_DH\0"
- "EVP_PKEY_get1_DSA\0"
- "EVP_PKEY_get1_EC_KEY\0"
- "EVP_PKEY_get1_RSA\0"
- "EVP_PKEY_keygen\0"
- "EVP_PKEY_keygen_init\0"
- "EVP_PKEY_new\0"
- "EVP_PKEY_set_type\0"
- "EVP_PKEY_sign\0"
- "EVP_PKEY_sign_init\0"
- "EVP_PKEY_verify\0"
- "EVP_PKEY_verify_init\0"
- "check_padding_md\0"
- "d2i_AutoPrivateKey\0"
- "d2i_PrivateKey\0"
- "do_EC_KEY_print\0"
- "do_dsa_print\0"
- "do_rsa_print\0"
- "do_sigver_init\0"
- "dsa_param_decode\0"
- "dsa_priv_decode\0"
- "dsa_priv_encode\0"
- "dsa_pub_decode\0"
- "dsa_pub_encode\0"
- "dsa_sig_print\0"
- "eckey_param2type\0"
- "eckey_param_decode\0"
- "eckey_priv_decode\0"
- "eckey_priv_encode\0"
- "eckey_pub_decode\0"
- "eckey_pub_encode\0"
- "eckey_type2param\0"
- "evp_pkey_ctx_new\0"
- "hmac_signctx\0"
- "i2d_PublicKey\0"
- "old_dsa_priv_decode\0"
- "old_ec_priv_decode\0"
- "old_rsa_priv_decode\0"
- "pkey_ec_ctrl\0"
- "pkey_ec_derive\0"
- "pkey_ec_keygen\0"
- "pkey_ec_paramgen\0"
- "pkey_ec_sign\0"
- "pkey_hmac_ctrl\0"
- "pkey_rsa_ctrl\0"
- "pkey_rsa_decrypt\0"
- "pkey_rsa_encrypt\0"
- "pkey_rsa_sign\0"
- "rsa_algor_to_md\0"
- "rsa_digest_verify_init_from_algorithm\0"
- "rsa_mgf1_to_md\0"
- "rsa_priv_decode\0"
- "rsa_priv_encode\0"
- "rsa_pss_to_ctx\0"
- "rsa_pub_decode\0"
- "HKDF\0"
- "OBJ_create\0"
- "OBJ_dup\0"
- "OBJ_nid2obj\0"
- "OBJ_txt2obj\0"
- "PEM_ASN1_read\0"
- "PEM_ASN1_read_bio\0"
- "PEM_ASN1_write\0"
- "PEM_ASN1_write_bio\0"
- "PEM_X509_INFO_read\0"
- "PEM_X509_INFO_read_bio\0"
- "PEM_X509_INFO_write_bio\0"
- "PEM_do_header\0"
- "PEM_get_EVP_CIPHER_INFO\0"
- "PEM_read\0"
- "PEM_read_DHparams\0"
- "PEM_read_PrivateKey\0"
- "PEM_read_bio\0"
- "PEM_read_bio_DHparams\0"
- "PEM_read_bio_Parameters\0"
- "PEM_read_bio_PrivateKey\0"
- "PEM_write\0"
- "PEM_write_PrivateKey\0"
- "PEM_write_bio\0"
- "d2i_PKCS8PrivateKey_bio\0"
- "d2i_PKCS8PrivateKey_fp\0"
- "do_pk8pkey\0"
- "do_pk8pkey_fp\0"
- "load_iv\0"
- "EVP_PKCS82PKEY\0"
- "EVP_PKEY2PKCS8\0"
- "PKCS12_get_key_and_certs\0"
- "PKCS12_handle_content_info\0"
- "PKCS12_handle_content_infos\0"
- "PKCS5_pbe2_set_iv\0"
- "PKCS5_pbe_set\0"
- "PKCS5_pbe_set0_algor\0"
- "PKCS5_pbkdf2_set\0"
- "PKCS8_decrypt\0"
- "PKCS8_encrypt\0"
- "PKCS8_encrypt_pbe\0"
- "pbe_cipher_init\0"
- "pbe_crypt\0"
- "pkcs12_item_decrypt_d2i\0"
- "pkcs12_item_i2d_encrypt\0"
- "pkcs12_key_gen_raw\0"
- "pkcs12_pbe_keyivgen\0"
- "BN_BLINDING_convert_ex\0"
- "BN_BLINDING_create_param\0"
- "BN_BLINDING_invert_ex\0"
- "BN_BLINDING_new\0"
- "BN_BLINDING_update\0"
- "RSA_check_key\0"
- "RSA_new_method\0"
- "RSA_padding_add_PKCS1_OAEP_mgf1\0"
- "RSA_padding_add_PKCS1_PSS_mgf1\0"
- "RSA_padding_add_PKCS1_type_1\0"
- "RSA_padding_add_PKCS1_type_2\0"
- "RSA_padding_add_none\0"
- "RSA_padding_check_PKCS1_OAEP_mgf1\0"
- "RSA_padding_check_PKCS1_type_1\0"
- "RSA_padding_check_PKCS1_type_2\0"
- "RSA_padding_check_none\0"
- "RSA_recover_crt_params\0"
- "RSA_sign\0"
- "RSA_verify\0"
- "RSA_verify_PKCS1_PSS_mgf1\0"
- "decrypt\0"
- "encrypt\0"
- "keygen\0"
- "pkcs1_prefixed_msg\0"
- "private_transform\0"
- "rsa_setup_blinding\0"
- "sign_raw\0"
- "verify_raw\0"
- "SSL_AEAD_CTX_new\0"
- "SSL_AEAD_CTX_open\0"
- "SSL_AEAD_CTX_seal\0"
- "SSL_CTX_check_private_key\0"
- "SSL_CTX_new\0"
- "SSL_CTX_set1_tls_channel_id\0"
- "SSL_CTX_set_cipher_list\0"
- "SSL_CTX_set_cipher_list_tls11\0"
- "SSL_CTX_set_session_id_context\0"
- "SSL_CTX_set_tmp_dh\0"
- "SSL_CTX_set_tmp_ecdh\0"
- "SSL_CTX_use_PrivateKey\0"
- "SSL_CTX_use_PrivateKey_ASN1\0"
- "SSL_CTX_use_PrivateKey_file\0"
- "SSL_CTX_use_RSAPrivateKey\0"
- "SSL_CTX_use_RSAPrivateKey_ASN1\0"
- "SSL_CTX_use_RSAPrivateKey_file\0"
- "SSL_CTX_use_certificate\0"
- "SSL_CTX_use_certificate_ASN1\0"
- "SSL_CTX_use_certificate_chain_file\0"
- "SSL_CTX_use_certificate_file\0"
- "SSL_CTX_use_psk_identity_hint\0"
- "SSL_SESSION_new\0"
- "SSL_SESSION_print_fp\0"
- "SSL_SESSION_set1_id_context\0"
- "SSL_SESSION_to_bytes_full\0"
- "SSL_accept\0"
- "SSL_add_dir_cert_subjects_to_stack\0"
- "SSL_add_file_cert_subjects_to_stack\0"
- "SSL_check_private_key\0"
- "SSL_clear\0"
- "SSL_connect\0"
- "SSL_do_handshake\0"
- "SSL_load_client_CA_file\0"
- "SSL_new\0"
- "SSL_peek\0"
- "SSL_read\0"
- "SSL_renegotiate\0"
- "SSL_set1_tls_channel_id\0"
- "SSL_set_cipher_list\0"
- "SSL_set_fd\0"
- "SSL_set_rfd\0"
- "SSL_set_session_id_context\0"
- "SSL_set_tlsext_host_name\0"
- "SSL_set_tmp_dh\0"
- "SSL_set_tmp_ecdh\0"
- "SSL_set_wfd\0"
- "SSL_shutdown\0"
- "SSL_use_PrivateKey\0"
- "SSL_use_PrivateKey_ASN1\0"
- "SSL_use_PrivateKey_file\0"
- "SSL_use_RSAPrivateKey\0"
- "SSL_use_RSAPrivateKey_ASN1\0"
- "SSL_use_RSAPrivateKey_file\0"
- "SSL_use_certificate\0"
- "SSL_use_certificate_ASN1\0"
- "SSL_use_certificate_file\0"
- "SSL_use_psk_identity_hint\0"
- "SSL_write\0"
- "d2i_SSL_SESSION\0"
- "d2i_SSL_SESSION_get_octet_string\0"
- "d2i_SSL_SESSION_get_string\0"
- "do_ssl3_write\0"
- "dtls1_accept\0"
- "dtls1_buffer_record\0"
- "dtls1_check_timeout_num\0"
- "dtls1_connect\0"
- "dtls1_do_write\0"
- "dtls1_get_buffered_message\0"
- "dtls1_get_hello_verify\0"
- "dtls1_get_message\0"
- "dtls1_get_message_fragment\0"
- "dtls1_hm_fragment_new\0"
- "dtls1_preprocess_fragment\0"
- "dtls1_process_fragment\0"
- "dtls1_process_record\0"
- "dtls1_read_bytes\0"
- "dtls1_seal_record\0"
- "dtls1_send_hello_verify_request\0"
- "dtls1_write_app_data\0"
- "i2d_SSL_SESSION\0"
- "ssl3_accept\0"
- "ssl3_cert_verify_hash\0"
- "ssl3_check_cert_and_algorithm\0"
- "ssl3_connect\0"
- "ssl3_ctrl\0"
- "ssl3_ctx_ctrl\0"
- "ssl3_digest_cached_records\0"
- "ssl3_do_change_cipher_spec\0"
- "ssl3_expect_change_cipher_spec\0"
- "ssl3_get_cert_status\0"
- "ssl3_get_cert_verify\0"
- "ssl3_get_certificate_request\0"
- "ssl3_get_channel_id\0"
- "ssl3_get_client_certificate\0"
- "ssl3_get_client_hello\0"
- "ssl3_get_client_key_exchange\0"
- "ssl3_get_finished\0"
- "ssl3_get_initial_bytes\0"
- "ssl3_get_message\0"
- "ssl3_get_new_session_ticket\0"
- "ssl3_get_next_proto\0"
- "ssl3_get_record\0"
- "ssl3_get_server_certificate\0"
- "ssl3_get_server_done\0"
- "ssl3_get_server_hello\0"
- "ssl3_get_server_key_exchange\0"
- "ssl3_get_v2_client_hello\0"
- "ssl3_handshake_mac\0"
- "ssl3_output_cert_chain\0"
- "ssl3_prf\0"
- "ssl3_read_bytes\0"
- "ssl3_read_n\0"
- "ssl3_record_sequence_update\0"
- "ssl3_seal_record\0"
- "ssl3_send_cert_verify\0"
- "ssl3_send_certificate_request\0"
- "ssl3_send_channel_id\0"
- "ssl3_send_client_certificate\0"
- "ssl3_send_client_hello\0"
- "ssl3_send_client_key_exchange\0"
- "ssl3_send_server_certificate\0"
- "ssl3_send_server_hello\0"
- "ssl3_send_server_key_exchange\0"
- "ssl3_setup_read_buffer\0"
- "ssl3_setup_write_buffer\0"
- "ssl3_write_bytes\0"
- "ssl3_write_pending\0"
- "ssl_add_cert_chain\0"
- "ssl_add_cert_to_buf\0"
- "ssl_add_clienthello_renegotiate_ext\0"
- "ssl_add_clienthello_tlsext\0"
- "ssl_add_clienthello_use_srtp_ext\0"
- "ssl_add_serverhello_renegotiate_ext\0"
- "ssl_add_serverhello_tlsext\0"
- "ssl_add_serverhello_use_srtp_ext\0"
- "ssl_build_cert_chain\0"
- "ssl_bytes_to_cipher_list\0"
- "ssl_cert_dup\0"
- "ssl_cert_inst\0"
- "ssl_cert_new\0"
- "ssl_check_serverhello_tlsext\0"
- "ssl_check_srvr_ecc_cert_and_alg\0"
- "ssl_cipher_process_rulestr\0"
- "ssl_cipher_strength_sort\0"
- "ssl_create_cipher_list\0"
- "ssl_ctx_log_master_secret\0"
- "ssl_ctx_log_rsa_client_key_exchange\0"
- "ssl_ctx_make_profiles\0"
- "ssl_get_new_session\0"
- "ssl_get_prev_session\0"
- "ssl_get_server_cert_index\0"
- "ssl_get_sign_pkey\0"
- "ssl_init_wbio_buffer\0"
- "ssl_parse_clienthello_renegotiate_ext\0"
- "ssl_parse_clienthello_tlsext\0"
- "ssl_parse_clienthello_use_srtp_ext\0"
- "ssl_parse_serverhello_renegotiate_ext\0"
- "ssl_parse_serverhello_tlsext\0"
- "ssl_parse_serverhello_use_srtp_ext\0"
- "ssl_scan_clienthello_tlsext\0"
- "ssl_scan_serverhello_tlsext\0"
- "ssl_sess_cert_new\0"
- "ssl_set_cert\0"
- "ssl_set_pkey\0"
- "ssl_verify_cert_chain\0"
- "tls12_check_peer_sigalg\0"
- "tls1_aead_ctx_init\0"
- "tls1_cert_verify_mac\0"
- "tls1_change_cipher_state\0"
- "tls1_change_cipher_state_aead\0"
- "tls1_check_duplicate_extensions\0"
- "tls1_enc\0"
- "tls1_export_keying_material\0"
- "tls1_prf\0"
- "tls1_setup_key_block\0"
- "ASN1_digest\0"
- "ASN1_item_sign_ctx\0"
- "ASN1_item_verify\0"
- "NETSCAPE_SPKI_b64_decode\0"
- "NETSCAPE_SPKI_b64_encode\0"
- "PKCS7_get_CRLs\0"
- "PKCS7_get_certificates\0"
- "X509_ATTRIBUTE_create_by_NID\0"
- "X509_ATTRIBUTE_create_by_OBJ\0"
- "X509_ATTRIBUTE_create_by_txt\0"
- "X509_ATTRIBUTE_get0_data\0"
- "X509_ATTRIBUTE_set1_data\0"
- "X509_CRL_add0_revoked\0"
- "X509_CRL_diff\0"
- "X509_CRL_print_fp\0"
- "X509_EXTENSION_create_by_NID\0"
- "X509_EXTENSION_create_by_OBJ\0"
- "X509_INFO_new\0"
- "X509_NAME_ENTRY_create_by_NID\0"
- "X509_NAME_ENTRY_create_by_txt\0"
- "X509_NAME_ENTRY_set_object\0"
- "X509_NAME_add_entry\0"
- "X509_NAME_oneline\0"
- "X509_NAME_print\0"
- "X509_PKEY_new\0"
- "X509_PUBKEY_get\0"
- "X509_PUBKEY_set\0"
- "X509_REQ_check_private_key\0"
- "X509_REQ_to_X509\0"
- "X509_STORE_CTX_get1_issuer\0"
- "X509_STORE_CTX_init\0"
- "X509_STORE_CTX_new\0"
- "X509_STORE_CTX_purpose_inherit\0"
- "X509_STORE_add_cert\0"
- "X509_STORE_add_crl\0"
- "X509_TRUST_add\0"
- "X509_TRUST_set\0"
- "X509_check_private_key\0"
- "X509_get_pubkey_parameters\0"
- "X509_load_cert_crl_file\0"
- "X509_load_cert_file\0"
- "X509_load_crl_file\0"
- "X509_print_ex_fp\0"
- "X509_to_X509_REQ\0"
- "X509_verify_cert\0"
- "X509at_add1_attr\0"
- "X509v3_add_ext\0"
- "add_cert_dir\0"
- "by_file_ctrl\0"
- "check_policy\0"
- "dir_ctrl\0"
- "get_cert_by_subject\0"
- "i2d_DSA_PUBKEY\0"
- "i2d_EC_PUBKEY\0"
- "i2d_RSA_PUBKEY\0"
- "pkcs7_parse_header\0"
- "x509_name_encode\0"
- "x509_name_ex_d2i\0"
- "x509_name_ex_new\0"
- "SXNET_add_id_INTEGER\0"
- "SXNET_add_id_asc\0"
- "SXNET_add_id_ulong\0"
- "SXNET_get_id_asc\0"
- "SXNET_get_id_ulong\0"
- "X509V3_EXT_add\0"
- "X509V3_EXT_add_alias\0"
- "X509V3_EXT_free\0"
- "X509V3_EXT_i2d\0"
- "X509V3_EXT_nconf\0"
- "X509V3_add1_i2d\0"
- "X509V3_add_value\0"
- "X509V3_get_section\0"
- "X509V3_get_string\0"
- "X509V3_get_value_bool\0"
- "X509V3_parse_list\0"
- "X509_PURPOSE_add\0"
- "X509_PURPOSE_set\0"
- "a2i_GENERAL_NAME\0"
- "copy_email\0"
- "copy_issuer\0"
- "do_dirname\0"
- "do_ext_i2d\0"
- "do_ext_nconf\0"
- "gnames_from_sectname\0"
- "hex_to_string\0"
- "i2s_ASN1_ENUMERATED\0"
- "i2s_ASN1_IA5STRING\0"
- "i2s_ASN1_INTEGER\0"
- "i2v_AUTHORITY_INFO_ACCESS\0"
- "notice_section\0"
- "nref_nos\0"
- "policy_section\0"
- "process_pci_value\0"
- "r2i_certpol\0"
- "r2i_pci\0"
- "s2i_ASN1_IA5STRING\0"
- "s2i_ASN1_INTEGER\0"
- "s2i_ASN1_OCTET_STRING\0"
- "s2i_skey_id\0"
- "set_dist_point_name\0"
- "string_to_hex\0"
- "v2i_ASN1_BIT_STRING\0"
- "v2i_AUTHORITY_INFO_ACCESS\0"
- "v2i_AUTHORITY_KEYID\0"
- "v2i_BASIC_CONSTRAINTS\0"
- "v2i_EXTENDED_KEY_USAGE\0"
- "v2i_GENERAL_NAMES\0"
- "v2i_GENERAL_NAME_ex\0"
- "v2i_NAME_CONSTRAINTS\0"
- "v2i_POLICY_CONSTRAINTS\0"
- "v2i_POLICY_MAPPINGS\0"
- "v2i_crld\0"
- "v2i_idp\0"
- "v2i_issuer_alt\0"
- "v2i_subject_alt\0"
- "v3_generic_extension\0"
- "";
-
const uint32_t kOpenSSLReasonValues[] = {
- 0xc3207ba,
- 0xc3287c7,
- 0xc3307d6,
- 0xc3387e6,
- 0xc3407f5,
- 0xc34880e,
- 0xc35081a,
- 0xc358837,
- 0xc360849,
- 0xc368857,
- 0xc370867,
- 0xc378874,
- 0xc380884,
- 0xc38888f,
- 0xc3908a5,
- 0xc3988b4,
- 0xc3a08c8,
- 0x1032146b,
- 0x10329477,
- 0x10331490,
- 0x103394a3,
- 0x10340dd4,
- 0x103494b6,
- 0x103514cb,
- 0x103594de,
- 0x103614f7,
- 0x1036950c,
- 0x1037152a,
- 0x10379539,
- 0x10381555,
- 0x10389570,
- 0x1039157f,
- 0x1039959b,
- 0x103a15b6,
- 0x103a95cd,
- 0x103b15de,
- 0x103b95f2,
- 0x103c1611,
- 0x103c9620,
- 0x103d1637,
- 0x103d964a,
- 0x103e0b5f,
- 0x103e965d,
- 0x103f1670,
- 0x103f968a,
- 0x1040169a,
- 0x104096ae,
- 0x104116c4,
- 0x104196dc,
- 0x104216f1,
- 0x10429705,
- 0x10431717,
- 0x104385d0,
- 0x104408b4,
- 0x1044972c,
- 0x10451743,
- 0x10459758,
- 0x10461766,
- 0x14320b42,
- 0x14328b50,
- 0x14330b5f,
- 0x14338b71,
+ 0xc3207ab,
+ 0xc3287c5,
+ 0xc3307d4,
+ 0xc3387e4,
+ 0xc3407f3,
+ 0xc34880c,
+ 0xc350818,
+ 0xc358835,
+ 0xc360847,
+ 0xc368855,
+ 0xc370865,
+ 0xc378872,
+ 0xc380882,
+ 0xc38888d,
+ 0xc3908a3,
+ 0xc3988b2,
+ 0xc3a08c6,
+ 0xc3a87b8,
+ 0xc3b00b0,
+ 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,
+ 0x104894b4,
+ 0x14320b40,
+ 0x14328b4e,
+ 0x14330b5d,
+ 0x14338b6f,
0x18320083,
- 0x18328e3a,
- 0x18340e68,
- 0x18348e7c,
- 0x18358eb3,
- 0x18368ee0,
- 0x18370ef3,
- 0x18378f07,
- 0x18380f2b,
- 0x18388f39,
- 0x18390f4f,
- 0x18398f63,
- 0x183a0f73,
- 0x183b0f83,
- 0x183b8f98,
- 0x183c8fc3,
- 0x183d0fd7,
- 0x183d8fe7,
- 0x183e0b8e,
- 0x183e8ff4,
- 0x183f1006,
- 0x183f9011,
- 0x18401021,
- 0x18409032,
- 0x18411043,
- 0x18419055,
- 0x1842107e,
- 0x184290b0,
- 0x184310bf,
- 0x18451128,
- 0x1845913e,
- 0x18461159,
- 0x18468ecb,
- 0x184709cc,
+ 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,
- 0x18480faf,
- 0x184890f4,
- 0x18490e50,
- 0x18498e91,
- 0x184a118f,
- 0x184a910c,
- 0x184b10d3,
- 0x184b8e2a,
- 0x184c1097,
- 0x184c866b,
- 0x184d1174,
- 0x203211b6,
- 0x243211c2,
- 0x243288fa,
- 0x243311d4,
- 0x243391e1,
- 0x243411ee,
- 0x24349200,
- 0x2435120f,
- 0x2435922c,
- 0x24361239,
- 0x24369247,
- 0x24371255,
- 0x24379263,
- 0x2438126c,
- 0x24389279,
- 0x2439128c,
- 0x28320b82,
- 0x28328b8e,
- 0x28330b5f,
- 0x28338ba1,
- 0x2c322ab3,
- 0x2c32aac1,
- 0x2c332ad3,
- 0x2c33aae5,
- 0x2c342af9,
- 0x2c34ab0b,
- 0x2c352b26,
- 0x2c35ab38,
- 0x2c362b4b,
+ 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,
- 0x2c372b58,
- 0x2c37ab6a,
- 0x2c382b7d,
- 0x2c38ab8b,
- 0x2c392b9b,
- 0x2c39abad,
- 0x2c3a2bc1,
- 0x2c3aabd2,
- 0x2c3b134c,
- 0x2c3babe3,
- 0x2c3c2bf7,
- 0x2c3cac0d,
- 0x2c3d2c26,
- 0x2c3dac54,
- 0x2c3e2c62,
- 0x2c3eac7a,
- 0x2c3f2c92,
- 0x2c3fac9f,
- 0x2c402cc2,
- 0x2c40ace1,
- 0x2c4111b6,
- 0x2c41acf2,
- 0x2c422d05,
- 0x2c429128,
- 0x2c432d16,
- 0x2c4386a2,
- 0x2c442c43,
+ 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,
@@ -1630,426 +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,
- 0x34320abc,
- 0x34328ad0,
- 0x34330aed,
- 0x34338b00,
- 0x34340b0f,
- 0x34348b2c,
+ 0x305b063c,
+ 0x305b865c,
+ 0x305c0678,
+ 0x305c8689,
+ 0x305d0693,
+ 0x34320aba,
+ 0x34328ace,
+ 0x34330aeb,
+ 0x34338afe,
+ 0x34340b0d,
+ 0x34348b2a,
0x3c320083,
- 0x3c328bcb,
- 0x3c330be4,
- 0x3c338bff,
- 0x3c340c1c,
- 0x3c348c37,
- 0x3c350c52,
- 0x3c358c67,
- 0x3c360c80,
- 0x3c368c98,
- 0x3c370ca9,
- 0x3c378cb7,
- 0x3c380cc4,
- 0x3c388cd8,
- 0x3c390b8e,
- 0x3c398cec,
- 0x3c3a0d00,
- 0x3c3a8874,
- 0x3c3b0d10,
- 0x3c3b8d2b,
- 0x3c3c0d3d,
- 0x3c3c8d53,
- 0x3c3d0d5d,
- 0x3c3d8d71,
- 0x3c3e0d7f,
- 0x3c3e8da4,
- 0x3c3f0bb7,
- 0x3c3f8d8d,
- 0x4032177d,
- 0x40329793,
- 0x403317c1,
- 0x403397cb,
- 0x403417e2,
- 0x40349800,
- 0x40351810,
- 0x40359822,
- 0x4036182f,
- 0x4036983b,
- 0x40371850,
- 0x40379865,
- 0x40381877,
- 0x40389882,
- 0x40391894,
- 0x40398dd4,
- 0x403a18a4,
- 0x403a98b7,
- 0x403b18d8,
- 0x403b98e9,
- 0x403c18f9,
- 0x403c8064,
- 0x403d1905,
- 0x403d9921,
- 0x403e1937,
- 0x403e9946,
- 0x403f1959,
- 0x403f9973,
- 0x40401981,
- 0x40409996,
- 0x404119aa,
- 0x404199c7,
- 0x404219e0,
- 0x404299fb,
- 0x40431a14,
- 0x40439a27,
- 0x40441a3b,
- 0x40449a53,
- 0x40451a63,
- 0x40459a71,
- 0x40461a8f,
- 0x40468094,
- 0x40471aa4,
- 0x40479ab6,
- 0x40481ada,
- 0x40489afa,
- 0x40491b0e,
- 0x40499b23,
- 0x404a1b3c,
- 0x404a9b76,
- 0x404b1b90,
- 0x404b9bae,
- 0x404c1bc9,
- 0x404c9be3,
- 0x404d1bfa,
+ 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,
- 0x404e1c39,
- 0x404e9c55,
- 0x404f1c71,
- 0x404f9c92,
- 0x40501cb4,
- 0x40509cd0,
- 0x40511ce4,
- 0x40519cf1,
- 0x40521d08,
- 0x40529d18,
- 0x40531d28,
- 0x40539d3c,
- 0x40541d57,
- 0x40549d67,
- 0x40551d7e,
- 0x40559d8d,
- 0x40561da8,
- 0x40569dc0,
- 0x40571ddc,
- 0x40579df5,
- 0x40581e08,
- 0x40589e1d,
- 0x40591e40,
- 0x40599e4e,
- 0x405a1e5b,
- 0x405a9e74,
- 0x405b1e8c,
- 0x405b9e9f,
- 0x405c1eb4,
- 0x405c9ec6,
- 0x405d1edb,
- 0x405d9eeb,
- 0x405e1f04,
- 0x405e9f18,
- 0x405f1f28,
- 0x405f9f40,
- 0x40601f51,
- 0x40609f64,
- 0x40611f75,
- 0x40619f93,
- 0x40621fa4,
- 0x40629fb1,
- 0x40631fc8,
- 0x4063a009,
- 0x40642020,
- 0x4064a02d,
- 0x4065203b,
- 0x4065a05d,
- 0x40662085,
- 0x4066a09a,
- 0x406720b1,
- 0x4067a0c2,
- 0x406820d3,
- 0x4068a0e4,
- 0x406920f9,
- 0x4069a110,
- 0x406a2121,
- 0x406aa13a,
- 0x406b2155,
- 0x406ba16c,
- 0x406c21d9,
- 0x406ca1fa,
- 0x406d220d,
- 0x406da22e,
- 0x406e2249,
- 0x406ea264,
- 0x406f2285,
- 0x406fa2ab,
- 0x407022cb,
- 0x4070a2e7,
- 0x40712474,
- 0x4071a497,
- 0x407224ad,
- 0x4072a4cc,
- 0x407324e4,
- 0x4073a504,
- 0x4074272e,
- 0x4074a753,
- 0x4075276e,
- 0x4075a78d,
- 0x407627bc,
- 0x4076a7e4,
- 0x407727fd,
- 0x4077a81c,
- 0x40782841,
- 0x4078a858,
- 0x4079286b,
- 0x4079a888,
- 0x407a0782,
- 0x407aa89a,
- 0x407b28ad,
- 0x407ba8c6,
- 0x407c28de,
- 0x407c90b0,
- 0x407d28f2,
- 0x407da90c,
- 0x407e291d,
- 0x407ea931,
- 0x407f293f,
- 0x407fa95a,
- 0x40801279,
- 0x4080a97f,
- 0x408129a1,
- 0x4081a9bc,
- 0x408229d1,
- 0x4082a9e9,
- 0x40832a01,
- 0x4083aa18,
- 0x40842a2e,
- 0x4084aa3a,
- 0x40852a4d,
- 0x4085aa62,
- 0x40862a74,
- 0x4086aa89,
- 0x40872a92,
- 0x40879c10,
- 0x40880083,
- 0x40889fe8,
- 0x40890a0a,
- 0x4089a184,
- 0x408a1b5f,
- 0x408aa1ae,
- 0x41f4239f,
- 0x41f92431,
- 0x41fe2324,
- 0x41fea555,
- 0x41ff2646,
- 0x420323b8,
- 0x420823da,
- 0x4208a416,
- 0x42092308,
- 0x4209a450,
- 0x420a235f,
- 0x420aa33f,
- 0x420b237f,
- 0x420ba3f8,
- 0x420c2662,
- 0x420ca522,
- 0x420d253c,
- 0x420da573,
- 0x4212258d,
- 0x42172629,
- 0x4217a5cf,
- 0x421c25f1,
- 0x421f25ac,
- 0x42212679,
- 0x4226260c,
- 0x422b2712,
- 0x422ba6db,
- 0x422c26fa,
- 0x422ca6b5,
- 0x422d2694,
- 0x443206ad,
- 0x443286bc,
- 0x443306c8,
- 0x443386d6,
- 0x443406e9,
- 0x443486fa,
- 0x44350701,
- 0x4435870b,
- 0x4436071e,
- 0x44368734,
- 0x44370746,
- 0x44378753,
- 0x44380762,
- 0x4438876a,
- 0x44390782,
- 0x44398790,
- 0x443a07a3,
- 0x4c3212a3,
- 0x4c3292b3,
- 0x4c3312c6,
- 0x4c3392e6,
+ 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,
- 0x4c3512f2,
- 0x4c359300,
- 0x4c36131c,
- 0x4c36932f,
- 0x4c37133e,
- 0x4c37934c,
- 0x4c381361,
- 0x4c38936d,
- 0x4c39138d,
- 0x4c3993b7,
- 0x4c3a13d0,
- 0x4c3a93e9,
- 0x4c3b05d0,
- 0x4c3b9402,
- 0x4c3c1414,
- 0x4c3c9423,
- 0x4c3d10b0,
- 0x4c3d943c,
- 0x4c3e1449,
- 0x50322d28,
- 0x5032ad37,
- 0x50332d42,
- 0x5033ad52,
- 0x50342d6b,
- 0x5034ad85,
- 0x50352d93,
- 0x5035ada9,
- 0x50362dbb,
- 0x5036add1,
- 0x50372dea,
- 0x5037adfd,
- 0x50382e15,
- 0x5038ae26,
- 0x50392e3b,
- 0x5039ae4f,
- 0x503a2e6f,
- 0x503aae85,
- 0x503b2e9d,
- 0x503baeaf,
- 0x503c2ecb,
- 0x503caee2,
- 0x503d2efb,
- 0x503daf11,
- 0x503e2f1e,
- 0x503eaf34,
- 0x503f2f46,
+ 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,
- 0x50402f59,
- 0x5040af69,
- 0x50412f83,
- 0x5041af92,
- 0x50422fac,
- 0x5042afc9,
- 0x50432fd9,
- 0x5043afe9,
- 0x50442ff8,
- 0x50448414,
- 0x5045300c,
- 0x5045b02a,
- 0x5046303d,
- 0x5046b053,
- 0x50473065,
- 0x5047b07a,
- 0x504830a0,
- 0x5048b0ae,
- 0x504930c1,
- 0x5049b0d6,
- 0x504a30ec,
- 0x504ab0fc,
- 0x504b311c,
- 0x504bb12f,
- 0x504c3152,
- 0x504cb180,
- 0x504d3192,
- 0x504db1af,
- 0x504e31ca,
- 0x504eb1e6,
- 0x504f31f8,
- 0x504fb20f,
- 0x5050321e,
- 0x50508687,
- 0x50513231,
- 0x58320e12,
- 0x68320dd4,
- 0x68328b8e,
- 0x68330ba1,
- 0x68338de2,
- 0x68340df2,
- 0x6c320db0,
- 0x6c328b71,
- 0x6c330dbb,
- 0x74320980,
- 0x783208e5,
- 0x783288fa,
- 0x78330906,
+ 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,
+ 0x6c320dae,
+ 0x6c328b6f,
+ 0x6c330db9,
+ 0x7432097e,
+ 0x783208e3,
+ 0x783288f8,
+ 0x78330904,
0x78338083,
- 0x78340915,
- 0x7834892a,
- 0x78350949,
- 0x7835896b,
- 0x78360980,
- 0x78368996,
- 0x783709a6,
- 0x783789b9,
- 0x783809cc,
- 0x783889de,
- 0x783909eb,
- 0x78398a0a,
- 0x783a0a1f,
- 0x783a8a2d,
- 0x783b0a37,
- 0x783b8a4b,
- 0x783c0a62,
- 0x783c8a77,
- 0x783d0a8e,
- 0x783d8aa3,
- 0x783e09f9,
- 0x803211a5,
+ 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]);
@@ -2105,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"
@@ -2161,6 +779,7 @@ const char kOpenSSLReasonStringData[] =
"UNSUPPORTED_METHOD\0"
"WRITE_TO_READ_ONLY_BIO\0"
"ARG2_LT_ARG3\0"
+ "BAD_ENCODING\0"
"BAD_RECIPROCAL\0"
"BIGNUM_TOO_LONG\0"
"BITS_TOO_SMALL\0"
@@ -2327,8 +946,10 @@ const char kOpenSSLReasonStringData[] =
"BAD_FIXED_HEADER_DECRYPT\0"
"BAD_PAD_BYTE_COUNT\0"
"BAD_RSA_PARAMETERS\0"
+ "BAD_VERSION\0"
"BLOCK_TYPE_IS_NOT_01\0"
"BN_NOT_INITIALIZED\0"
+ "CANNOT_RECOVER_MULTI_PRIME_KEY\0"
"CRT_PARAMS_ALREADY_GIVEN\0"
"CRT_VALUES_INCORRECT\0"
"DATA_LEN_NOT_EQUAL_TO_MOD_LEN\0"
@@ -2346,6 +967,7 @@ const char kOpenSSLReasonStringData[] =
"INVALID_MESSAGE_LENGTH\0"
"KEY_SIZE_TOO_SMALL\0"
"LAST_OCTET_INVALID\0"
+ "MUST_HAVE_AT_LEAST_TWO_PRIMES\0"
"NO_PUBLIC_EXPONENT\0"
"NULL_BEFORE_BLOCK_MISSING\0"
"N_NOT_EQUAL_P_Q\0"
@@ -2369,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"
@@ -2380,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"
@@ -2389,37 +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"
- "D2I_ECDSA_SIG\0"
- "DATA_BETWEEN_CCS_AND_FINISHED\0"
+ "CUSTOM_EXTENSION_ERROR\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"
- "EVP_DIGESTSIGNFINAL_FAILED\0"
- "EVP_DIGESTSIGNINIT_FAILED\0"
+ "ERROR_PARSING_EXTENSION\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"
@@ -2429,22 +1042,19 @@ 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"
"MTU_TOO_SMALL\0"
+ "NEGOTIATED_BOTH_NPN_AND_ALPN\0"
"NESTED_GROUP\0"
"NO_CERTIFICATES_RETURNED\0"
"NO_CERTIFICATE_ASSIGNED\0"
"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"
@@ -2453,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"
@@ -2468,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"
@@ -2482,12 +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"
@@ -2502,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"
@@ -2524,15 +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_GROUP_CLOSE\0"
+ "UNEXPECTED_EXTENSION\0"
"UNEXPECTED_MESSAGE\0"
"UNEXPECTED_OPERATOR_IN_GROUP\0"
"UNEXPECTED_RECORD\0"
@@ -2544,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-aarch64/crypto/aes/aesv8-armx.S b/linux-aarch64/crypto/aes/aesv8-armx64.S
index 9c63291..fa2abbc 100644
--- a/linux-aarch64/crypto/aes/aesv8-armx.S
+++ b/linux-aarch64/crypto/aes/aesv8-armx64.S
@@ -1,4 +1,5 @@
-#include "arm_arch.h"
+#if defined(__aarch64__)
+#include <openssl/arm_arch.h>
#if __ARM_MAX_ARCH__>=7
.text
@@ -747,3 +748,4 @@ aes_v8_ctr32_encrypt_blocks:
ret
.size aes_v8_ctr32_encrypt_blocks,.-aes_v8_ctr32_encrypt_blocks
#endif
+#endif \ No newline at end of file
diff --git a/linux-aarch64/crypto/bn/armv8-mont.S b/linux-aarch64/crypto/bn/armv8-mont.S
new file mode 100644
index 0000000..9355ce7
--- /dev/null
+++ b/linux-aarch64/crypto/bn/armv8-mont.S
@@ -0,0 +1,1406 @@
+#if defined(__aarch64__)
+.text
+
+.globl bn_mul_mont
+.type bn_mul_mont,%function
+.align 5
+bn_mul_mont:
+ tst x5,#7
+ b.eq __bn_sqr8x_mont
+ tst x5,#3
+ b.eq __bn_mul4x_mont
+.Lmul_mont:
+ stp x29,x30,[sp,#-64]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+
+ ldr x9,[x2],#8 // bp[0]
+ sub x22,sp,x5,lsl#3
+ ldp x7,x8,[x1],#16 // ap[0..1]
+ lsl x5,x5,#3
+ ldr x4,[x4] // *n0
+ and x22,x22,#-16 // ABI says so
+ ldp x13,x14,[x3],#16 // np[0..1]
+
+ mul x6,x7,x9 // ap[0]*bp[0]
+ sub x21,x5,#16 // j=num-2
+ umulh x7,x7,x9
+ mul x10,x8,x9 // ap[1]*bp[0]
+ umulh x11,x8,x9
+
+ mul x15,x6,x4 // "tp[0]"*n0
+ mov sp,x22 // alloca
+
+ // (*) mul x12,x13,x15 // np[0]*m1
+ umulh x13,x13,x15
+ mul x16,x14,x15 // np[1]*m1
+ // (*) adds x12,x12,x6 // discarded
+ // (*) As for removal of first multiplication and addition
+ // instructions. The outcome of first addition is
+ // guaranteed to be zero, which leaves two computationally
+ // significant outcomes: it either carries or not. Then
+ // question is when does it carry? Is there alternative
+ // way to deduce it? If you follow operations, you can
+ // observe that condition for carry is quite simple:
+ // x6 being non-zero. So that carry can be calculated
+ // by adding -1 to x6. That's what next instruction does.
+ subs xzr,x6,#1 // (*)
+ umulh x17,x14,x15
+ adc x13,x13,xzr
+ cbz x21,.L1st_skip
+
+.L1st:
+ ldr x8,[x1],#8
+ adds x6,x10,x7
+ sub x21,x21,#8 // j--
+ adc x7,x11,xzr
+
+ ldr x14,[x3],#8
+ adds x12,x16,x13
+ mul x10,x8,x9 // ap[j]*bp[0]
+ adc x13,x17,xzr
+ umulh x11,x8,x9
+
+ adds x12,x12,x6
+ mul x16,x14,x15 // np[j]*m1
+ adc x13,x13,xzr
+ umulh x17,x14,x15
+ str x12,[x22],#8 // tp[j-1]
+ cbnz x21,.L1st
+
+.L1st_skip:
+ adds x6,x10,x7
+ sub x1,x1,x5 // rewind x1
+ adc x7,x11,xzr
+
+ adds x12,x16,x13
+ sub x3,x3,x5 // rewind x3
+ adc x13,x17,xzr
+
+ adds x12,x12,x6
+ sub x20,x5,#8 // i=num-1
+ adcs x13,x13,x7
+
+ adc x19,xzr,xzr // upmost overflow bit
+ stp x12,x13,[x22]
+
+.Louter:
+ ldr x9,[x2],#8 // bp[i]
+ ldp x7,x8,[x1],#16
+ ldr x23,[sp] // tp[0]
+ add x22,sp,#8
+
+ mul x6,x7,x9 // ap[0]*bp[i]
+ sub x21,x5,#16 // j=num-2
+ umulh x7,x7,x9
+ ldp x13,x14,[x3],#16
+ mul x10,x8,x9 // ap[1]*bp[i]
+ adds x6,x6,x23
+ umulh x11,x8,x9
+ adc x7,x7,xzr
+
+ mul x15,x6,x4
+ sub x20,x20,#8 // i--
+
+ // (*) mul x12,x13,x15 // np[0]*m1
+ umulh x13,x13,x15
+ mul x16,x14,x15 // np[1]*m1
+ // (*) adds x12,x12,x6
+ subs xzr,x6,#1 // (*)
+ umulh x17,x14,x15
+ cbz x21,.Linner_skip
+
+.Linner:
+ ldr x8,[x1],#8
+ adc x13,x13,xzr
+ ldr x23,[x22],#8 // tp[j]
+ adds x6,x10,x7
+ sub x21,x21,#8 // j--
+ adc x7,x11,xzr
+
+ adds x12,x16,x13
+ ldr x14,[x3],#8
+ adc x13,x17,xzr
+
+ mul x10,x8,x9 // ap[j]*bp[i]
+ adds x6,x6,x23
+ umulh x11,x8,x9
+ adc x7,x7,xzr
+
+ mul x16,x14,x15 // np[j]*m1
+ adds x12,x12,x6
+ umulh x17,x14,x15
+ str x12,[x22,#-16] // tp[j-1]
+ cbnz x21,.Linner
+
+.Linner_skip:
+ ldr x23,[x22],#8 // tp[j]
+ adc x13,x13,xzr
+ adds x6,x10,x7
+ sub x1,x1,x5 // rewind x1
+ adc x7,x11,xzr
+
+ adds x12,x16,x13
+ sub x3,x3,x5 // rewind x3
+ adcs x13,x17,x19
+ adc x19,xzr,xzr
+
+ adds x6,x6,x23
+ adc x7,x7,xzr
+
+ adds x12,x12,x6
+ adcs x13,x13,x7
+ adc x19,x19,xzr // upmost overflow bit
+ stp x12,x13,[x22,#-16]
+
+ cbnz x20,.Louter
+
+ // Final step. We see if result is larger than modulus, and
+ // if it is, subtract the modulus. But comparison implies
+ // subtraction. So we subtract modulus, see if it borrowed,
+ // and conditionally copy original value.
+ ldr x23,[sp] // tp[0]
+ add x22,sp,#8
+ ldr x14,[x3],#8 // np[0]
+ subs x21,x5,#8 // j=num-1 and clear borrow
+ mov x1,x0
+.Lsub:
+ sbcs x8,x23,x14 // tp[j]-np[j]
+ ldr x23,[x22],#8
+ sub x21,x21,#8 // j--
+ ldr x14,[x3],#8
+ str x8,[x1],#8 // rp[j]=tp[j]-np[j]
+ cbnz x21,.Lsub
+
+ sbcs x8,x23,x14
+ sbcs x19,x19,xzr // did it borrow?
+ str x8,[x1],#8 // rp[num-1]
+
+ ldr x23,[sp] // tp[0]
+ add x22,sp,#8
+ ldr x8,[x0],#8 // rp[0]
+ sub x5,x5,#8 // num--
+ nop
+.Lcond_copy:
+ sub x5,x5,#8 // num--
+ csel x14,x23,x8,lo // did it borrow?
+ ldr x23,[x22],#8
+ ldr x8,[x0],#8
+ str xzr,[x22,#-16] // wipe tp
+ str x14,[x0,#-16]
+ cbnz x5,.Lcond_copy
+
+ csel x14,x23,x8,lo
+ str xzr,[x22,#-8] // wipe tp
+ str x14,[x0,#-8]
+
+ ldp x19,x20,[x29,#16]
+ mov sp,x29
+ ldp x21,x22,[x29,#32]
+ mov x0,#1
+ ldp x23,x24,[x29,#48]
+ ldr x29,[sp],#64
+ ret
+.size bn_mul_mont,.-bn_mul_mont
+.type __bn_sqr8x_mont,%function
+.align 5
+__bn_sqr8x_mont:
+ cmp x1,x2
+ b.ne __bn_mul4x_mont
+.Lsqr8x_mont:
+ stp x29,x30,[sp,#-128]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+ stp x25,x26,[sp,#64]
+ stp x27,x28,[sp,#80]
+ stp x0,x3,[sp,#96] // offload rp and np
+
+ ldp x6,x7,[x1,#8*0]
+ ldp x8,x9,[x1,#8*2]
+ ldp x10,x11,[x1,#8*4]
+ ldp x12,x13,[x1,#8*6]
+
+ sub x2,sp,x5,lsl#4
+ lsl x5,x5,#3
+ ldr x4,[x4] // *n0
+ mov sp,x2 // alloca
+ sub x27,x5,#8*8
+ b .Lsqr8x_zero_start
+
+.Lsqr8x_zero:
+ sub x27,x27,#8*8
+ stp xzr,xzr,[x2,#8*0]
+ stp xzr,xzr,[x2,#8*2]
+ stp xzr,xzr,[x2,#8*4]
+ stp xzr,xzr,[x2,#8*6]
+.Lsqr8x_zero_start:
+ stp xzr,xzr,[x2,#8*8]
+ stp xzr,xzr,[x2,#8*10]
+ stp xzr,xzr,[x2,#8*12]
+ stp xzr,xzr,[x2,#8*14]
+ add x2,x2,#8*16
+ cbnz x27,.Lsqr8x_zero
+
+ add x3,x1,x5
+ add x1,x1,#8*8
+ mov x19,xzr
+ mov x20,xzr
+ mov x21,xzr
+ mov x22,xzr
+ mov x23,xzr
+ mov x24,xzr
+ mov x25,xzr
+ mov x26,xzr
+ mov x2,sp
+ str x4,[x29,#112] // offload n0
+
+ // Multiply everything but a[i]*a[i]
+.align 4
+.Lsqr8x_outer_loop:
+ // a[1]a[0] (i)
+ // a[2]a[0]
+ // a[3]a[0]
+ // a[4]a[0]
+ // a[5]a[0]
+ // a[6]a[0]
+ // a[7]a[0]
+ // a[2]a[1] (ii)
+ // a[3]a[1]
+ // a[4]a[1]
+ // a[5]a[1]
+ // a[6]a[1]
+ // a[7]a[1]
+ // a[3]a[2] (iii)
+ // a[4]a[2]
+ // a[5]a[2]
+ // a[6]a[2]
+ // a[7]a[2]
+ // a[4]a[3] (iv)
+ // a[5]a[3]
+ // a[6]a[3]
+ // a[7]a[3]
+ // a[5]a[4] (v)
+ // a[6]a[4]
+ // a[7]a[4]
+ // a[6]a[5] (vi)
+ // a[7]a[5]
+ // a[7]a[6] (vii)
+
+ mul x14,x7,x6 // lo(a[1..7]*a[0]) (i)
+ mul x15,x8,x6
+ mul x16,x9,x6
+ mul x17,x10,x6
+ adds x20,x20,x14 // t[1]+lo(a[1]*a[0])
+ mul x14,x11,x6
+ adcs x21,x21,x15
+ mul x15,x12,x6
+ adcs x22,x22,x16
+ mul x16,x13,x6
+ adcs x23,x23,x17
+ umulh x17,x7,x6 // hi(a[1..7]*a[0])
+ adcs x24,x24,x14
+ umulh x14,x8,x6
+ adcs x25,x25,x15
+ umulh x15,x9,x6
+ adcs x26,x26,x16
+ umulh x16,x10,x6
+ stp x19,x20,[x2],#8*2 // t[0..1]
+ adc x19,xzr,xzr // t[8]
+ adds x21,x21,x17 // t[2]+lo(a[1]*a[0])
+ umulh x17,x11,x6
+ adcs x22,x22,x14
+ umulh x14,x12,x6
+ adcs x23,x23,x15
+ umulh x15,x13,x6
+ adcs x24,x24,x16
+ mul x16,x8,x7 // lo(a[2..7]*a[1]) (ii)
+ adcs x25,x25,x17
+ mul x17,x9,x7
+ adcs x26,x26,x14
+ mul x14,x10,x7
+ adc x19,x19,x15
+
+ mul x15,x11,x7
+ adds x22,x22,x16
+ mul x16,x12,x7
+ adcs x23,x23,x17
+ mul x17,x13,x7
+ adcs x24,x24,x14
+ umulh x14,x8,x7 // hi(a[2..7]*a[1])
+ adcs x25,x25,x15
+ umulh x15,x9,x7
+ adcs x26,x26,x16
+ umulh x16,x10,x7
+ adcs x19,x19,x17
+ umulh x17,x11,x7
+ stp x21,x22,[x2],#8*2 // t[2..3]
+ adc x20,xzr,xzr // t[9]
+ adds x23,x23,x14
+ umulh x14,x12,x7
+ adcs x24,x24,x15
+ umulh x15,x13,x7
+ adcs x25,x25,x16
+ mul x16,x9,x8 // lo(a[3..7]*a[2]) (iii)
+ adcs x26,x26,x17
+ mul x17,x10,x8
+ adcs x19,x19,x14
+ mul x14,x11,x8
+ adc x20,x20,x15
+
+ mul x15,x12,x8
+ adds x24,x24,x16
+ mul x16,x13,x8
+ adcs x25,x25,x17
+ umulh x17,x9,x8 // hi(a[3..7]*a[2])
+ adcs x26,x26,x14
+ umulh x14,x10,x8
+ adcs x19,x19,x15
+ umulh x15,x11,x8
+ adcs x20,x20,x16
+ umulh x16,x12,x8
+ stp x23,x24,[x2],#8*2 // t[4..5]
+ adc x21,xzr,xzr // t[10]
+ adds x25,x25,x17
+ umulh x17,x13,x8
+ adcs x26,x26,x14
+ mul x14,x10,x9 // lo(a[4..7]*a[3]) (iv)
+ adcs x19,x19,x15
+ mul x15,x11,x9
+ adcs x20,x20,x16
+ mul x16,x12,x9
+ adc x21,x21,x17
+
+ mul x17,x13,x9
+ adds x26,x26,x14
+ umulh x14,x10,x9 // hi(a[4..7]*a[3])
+ adcs x19,x19,x15
+ umulh x15,x11,x9
+ adcs x20,x20,x16
+ umulh x16,x12,x9
+ adcs x21,x21,x17
+ umulh x17,x13,x9
+ stp x25,x26,[x2],#8*2 // t[6..7]
+ adc x22,xzr,xzr // t[11]
+ adds x19,x19,x14
+ mul x14,x11,x10 // lo(a[5..7]*a[4]) (v)
+ adcs x20,x20,x15
+ mul x15,x12,x10
+ adcs x21,x21,x16
+ mul x16,x13,x10
+ adc x22,x22,x17
+
+ umulh x17,x11,x10 // hi(a[5..7]*a[4])
+ adds x20,x20,x14
+ umulh x14,x12,x10
+ adcs x21,x21,x15
+ umulh x15,x13,x10
+ adcs x22,x22,x16
+ mul x16,x12,x11 // lo(a[6..7]*a[5]) (vi)
+ adc x23,xzr,xzr // t[12]
+ adds x21,x21,x17
+ mul x17,x13,x11
+ adcs x22,x22,x14
+ umulh x14,x12,x11 // hi(a[6..7]*a[5])
+ adc x23,x23,x15
+
+ umulh x15,x13,x11
+ adds x22,x22,x16
+ mul x16,x13,x12 // lo(a[7]*a[6]) (vii)
+ adcs x23,x23,x17
+ umulh x17,x13,x12 // hi(a[7]*a[6])
+ adc x24,xzr,xzr // t[13]
+ adds x23,x23,x14
+ sub x27,x3,x1 // done yet?
+ adc x24,x24,x15
+
+ adds x24,x24,x16
+ sub x14,x3,x5 // rewinded ap
+ adc x25,xzr,xzr // t[14]
+ add x25,x25,x17
+
+ cbz x27,.Lsqr8x_outer_break
+
+ mov x4,x6
+ ldp x6,x7,[x2,#8*0]
+ ldp x8,x9,[x2,#8*2]
+ ldp x10,x11,[x2,#8*4]
+ ldp x12,x13,[x2,#8*6]
+ adds x19,x19,x6
+ adcs x20,x20,x7
+ ldp x6,x7,[x1,#8*0]
+ adcs x21,x21,x8
+ adcs x22,x22,x9
+ ldp x8,x9,[x1,#8*2]
+ adcs x23,x23,x10
+ adcs x24,x24,x11
+ ldp x10,x11,[x1,#8*4]
+ adcs x25,x25,x12
+ mov x0,x1
+ adcs x26,xzr,x13
+ ldp x12,x13,[x1,#8*6]
+ add x1,x1,#8*8
+ //adc x28,xzr,xzr // moved below
+ mov x27,#-8*8
+
+ // a[8]a[0]
+ // a[9]a[0]
+ // a[a]a[0]
+ // a[b]a[0]
+ // a[c]a[0]
+ // a[d]a[0]
+ // a[e]a[0]
+ // a[f]a[0]
+ // a[8]a[1]
+ // a[f]a[1]........................
+ // a[8]a[2]
+ // a[f]a[2]........................
+ // a[8]a[3]
+ // a[f]a[3]........................
+ // a[8]a[4]
+ // a[f]a[4]........................
+ // a[8]a[5]
+ // a[f]a[5]........................
+ // a[8]a[6]
+ // a[f]a[6]........................
+ // a[8]a[7]
+ // a[f]a[7]........................
+.Lsqr8x_mul:
+ mul x14,x6,x4
+ adc x28,xzr,xzr // carry bit, modulo-scheduled
+ mul x15,x7,x4
+ add x27,x27,#8
+ mul x16,x8,x4
+ mul x17,x9,x4
+ adds x19,x19,x14
+ mul x14,x10,x4
+ adcs x20,x20,x15
+ mul x15,x11,x4
+ adcs x21,x21,x16
+ mul x16,x12,x4
+ adcs x22,x22,x17
+ mul x17,x13,x4
+ adcs x23,x23,x14
+ umulh x14,x6,x4
+ adcs x24,x24,x15
+ umulh x15,x7,x4
+ adcs x25,x25,x16
+ umulh x16,x8,x4
+ adcs x26,x26,x17
+ umulh x17,x9,x4
+ adc x28,x28,xzr
+ str x19,[x2],#8
+ adds x19,x20,x14
+ umulh x14,x10,x4
+ adcs x20,x21,x15
+ umulh x15,x11,x4
+ adcs x21,x22,x16
+ umulh x16,x12,x4
+ adcs x22,x23,x17
+ umulh x17,x13,x4
+ ldr x4,[x0,x27]
+ adcs x23,x24,x14
+ adcs x24,x25,x15
+ adcs x25,x26,x16
+ adcs x26,x28,x17
+ //adc x28,xzr,xzr // moved above
+ cbnz x27,.Lsqr8x_mul
+ // note that carry flag is guaranteed
+ // to be zero at this point
+ cmp x1,x3 // done yet?
+ b.eq .Lsqr8x_break
+
+ ldp x6,x7,[x2,#8*0]
+ ldp x8,x9,[x2,#8*2]
+ ldp x10,x11,[x2,#8*4]
+ ldp x12,x13,[x2,#8*6]
+ adds x19,x19,x6
+ ldr x4,[x0,#-8*8]
+ adcs x20,x20,x7
+ ldp x6,x7,[x1,#8*0]
+ adcs x21,x21,x8
+ adcs x22,x22,x9
+ ldp x8,x9,[x1,#8*2]
+ adcs x23,x23,x10
+ adcs x24,x24,x11
+ ldp x10,x11,[x1,#8*4]
+ adcs x25,x25,x12
+ mov x27,#-8*8
+ adcs x26,x26,x13
+ ldp x12,x13,[x1,#8*6]
+ add x1,x1,#8*8
+ //adc x28,xzr,xzr // moved above
+ b .Lsqr8x_mul
+
+.align 4
+.Lsqr8x_break:
+ ldp x6,x7,[x0,#8*0]
+ add x1,x0,#8*8
+ ldp x8,x9,[x0,#8*2]
+ sub x14,x3,x1 // is it last iteration?
+ ldp x10,x11,[x0,#8*4]
+ sub x15,x2,x14
+ ldp x12,x13,[x0,#8*6]
+ cbz x14,.Lsqr8x_outer_loop
+
+ stp x19,x20,[x2,#8*0]
+ ldp x19,x20,[x15,#8*0]
+ stp x21,x22,[x2,#8*2]
+ ldp x21,x22,[x15,#8*2]
+ stp x23,x24,[x2,#8*4]
+ ldp x23,x24,[x15,#8*4]
+ stp x25,x26,[x2,#8*6]
+ mov x2,x15
+ ldp x25,x26,[x15,#8*6]
+ b .Lsqr8x_outer_loop
+
+.align 4
+.Lsqr8x_outer_break:
+ // Now multiply above result by 2 and add a[n-1]*a[n-1]|...|a[0]*a[0]
+ ldp x7,x9,[x14,#8*0] // recall that x14 is &a[0]
+ ldp x15,x16,[sp,#8*1]
+ ldp x11,x13,[x14,#8*2]
+ add x1,x14,#8*4
+ ldp x17,x14,[sp,#8*3]
+
+ stp x19,x20,[x2,#8*0]
+ mul x19,x7,x7
+ stp x21,x22,[x2,#8*2]
+ umulh x7,x7,x7
+ stp x23,x24,[x2,#8*4]
+ mul x8,x9,x9
+ stp x25,x26,[x2,#8*6]
+ mov x2,sp
+ umulh x9,x9,x9
+ adds x20,x7,x15,lsl#1
+ extr x15,x16,x15,#63
+ sub x27,x5,#8*4
+
+.Lsqr4x_shift_n_add:
+ adcs x21,x8,x15
+ extr x16,x17,x16,#63
+ sub x27,x27,#8*4
+ adcs x22,x9,x16
+ ldp x15,x16,[x2,#8*5]
+ mul x10,x11,x11
+ ldp x7,x9,[x1],#8*2
+ umulh x11,x11,x11
+ mul x12,x13,x13
+ umulh x13,x13,x13
+ extr x17,x14,x17,#63
+ stp x19,x20,[x2,#8*0]
+ adcs x23,x10,x17
+ extr x14,x15,x14,#63
+ stp x21,x22,[x2,#8*2]
+ adcs x24,x11,x14
+ ldp x17,x14,[x2,#8*7]
+ extr x15,x16,x15,#63
+ adcs x25,x12,x15
+ extr x16,x17,x16,#63
+ adcs x26,x13,x16
+ ldp x15,x16,[x2,#8*9]
+ mul x6,x7,x7
+ ldp x11,x13,[x1],#8*2
+ umulh x7,x7,x7
+ mul x8,x9,x9
+ umulh x9,x9,x9
+ stp x23,x24,[x2,#8*4]
+ extr x17,x14,x17,#63
+ stp x25,x26,[x2,#8*6]
+ add x2,x2,#8*8
+ adcs x19,x6,x17
+ extr x14,x15,x14,#63
+ adcs x20,x7,x14
+ ldp x17,x14,[x2,#8*3]
+ extr x15,x16,x15,#63
+ cbnz x27,.Lsqr4x_shift_n_add
+ ldp x1,x4,[x29,#104] // pull np and n0
+
+ adcs x21,x8,x15
+ extr x16,x17,x16,#63
+ adcs x22,x9,x16
+ ldp x15,x16,[x2,#8*5]
+ mul x10,x11,x11
+ umulh x11,x11,x11
+ stp x19,x20,[x2,#8*0]
+ mul x12,x13,x13
+ umulh x13,x13,x13
+ stp x21,x22,[x2,#8*2]
+ extr x17,x14,x17,#63
+ adcs x23,x10,x17
+ extr x14,x15,x14,#63
+ ldp x19,x20,[sp,#8*0]
+ adcs x24,x11,x14
+ extr x15,x16,x15,#63
+ ldp x6,x7,[x1,#8*0]
+ adcs x25,x12,x15
+ extr x16,xzr,x16,#63
+ ldp x8,x9,[x1,#8*2]
+ adc x26,x13,x16
+ ldp x10,x11,[x1,#8*4]
+
+ // Reduce by 512 bits per iteration
+ mul x28,x4,x19 // t[0]*n0
+ ldp x12,x13,[x1,#8*6]
+ add x3,x1,x5
+ ldp x21,x22,[sp,#8*2]
+ stp x23,x24,[x2,#8*4]
+ ldp x23,x24,[sp,#8*4]
+ stp x25,x26,[x2,#8*6]
+ ldp x25,x26,[sp,#8*6]
+ add x1,x1,#8*8
+ mov x30,xzr // initial top-most carry
+ mov x2,sp
+ mov x27,#8
+
+.Lsqr8x_reduction:
+ // (*) mul x14,x6,x28 // lo(n[0-7])*lo(t[0]*n0)
+ mul x15,x7,x28
+ sub x27,x27,#1
+ mul x16,x8,x28
+ str x28,[x2],#8 // put aside t[0]*n0 for tail processing
+ mul x17,x9,x28
+ // (*) adds xzr,x19,x14
+ subs xzr,x19,#1 // (*)
+ mul x14,x10,x28
+ adcs x19,x20,x15
+ mul x15,x11,x28
+ adcs x20,x21,x16
+ mul x16,x12,x28
+ adcs x21,x22,x17
+ mul x17,x13,x28
+ adcs x22,x23,x14
+ umulh x14,x6,x28 // hi(n[0-7])*lo(t[0]*n0)
+ adcs x23,x24,x15
+ umulh x15,x7,x28
+ adcs x24,x25,x16
+ umulh x16,x8,x28
+ adcs x25,x26,x17
+ umulh x17,x9,x28
+ adc x26,xzr,xzr
+ adds x19,x19,x14
+ umulh x14,x10,x28
+ adcs x20,x20,x15
+ umulh x15,x11,x28
+ adcs x21,x21,x16
+ umulh x16,x12,x28
+ adcs x22,x22,x17
+ umulh x17,x13,x28
+ mul x28,x4,x19 // next t[0]*n0
+ adcs x23,x23,x14
+ adcs x24,x24,x15
+ adcs x25,x25,x16
+ adc x26,x26,x17
+ cbnz x27,.Lsqr8x_reduction
+
+ ldp x14,x15,[x2,#8*0]
+ ldp x16,x17,[x2,#8*2]
+ mov x0,x2
+ sub x27,x3,x1 // done yet?
+ adds x19,x19,x14
+ adcs x20,x20,x15
+ ldp x14,x15,[x2,#8*4]
+ adcs x21,x21,x16
+ adcs x22,x22,x17
+ ldp x16,x17,[x2,#8*6]
+ adcs x23,x23,x14
+ adcs x24,x24,x15
+ adcs x25,x25,x16
+ adcs x26,x26,x17
+ //adc x28,xzr,xzr // moved below
+ cbz x27,.Lsqr8x8_post_condition
+
+ ldr x4,[x2,#-8*8]
+ ldp x6,x7,[x1,#8*0]
+ ldp x8,x9,[x1,#8*2]
+ ldp x10,x11,[x1,#8*4]
+ mov x27,#-8*8
+ ldp x12,x13,[x1,#8*6]
+ add x1,x1,#8*8
+
+.Lsqr8x_tail:
+ mul x14,x6,x4
+ adc x28,xzr,xzr // carry bit, modulo-scheduled
+ mul x15,x7,x4
+ add x27,x27,#8
+ mul x16,x8,x4
+ mul x17,x9,x4
+ adds x19,x19,x14
+ mul x14,x10,x4
+ adcs x20,x20,x15
+ mul x15,x11,x4
+ adcs x21,x21,x16
+ mul x16,x12,x4
+ adcs x22,x22,x17
+ mul x17,x13,x4
+ adcs x23,x23,x14
+ umulh x14,x6,x4
+ adcs x24,x24,x15
+ umulh x15,x7,x4
+ adcs x25,x25,x16
+ umulh x16,x8,x4
+ adcs x26,x26,x17
+ umulh x17,x9,x4
+ adc x28,x28,xzr
+ str x19,[x2],#8
+ adds x19,x20,x14
+ umulh x14,x10,x4
+ adcs x20,x21,x15
+ umulh x15,x11,x4
+ adcs x21,x22,x16
+ umulh x16,x12,x4
+ adcs x22,x23,x17
+ umulh x17,x13,x4
+ ldr x4,[x0,x27]
+ adcs x23,x24,x14
+ adcs x24,x25,x15
+ adcs x25,x26,x16
+ adcs x26,x28,x17
+ //adc x28,xzr,xzr // moved above
+ cbnz x27,.Lsqr8x_tail
+ // note that carry flag is guaranteed
+ // to be zero at this point
+ ldp x6,x7,[x2,#8*0]
+ sub x27,x3,x1 // done yet?
+ sub x16,x3,x5 // rewinded np
+ ldp x8,x9,[x2,#8*2]
+ ldp x10,x11,[x2,#8*4]
+ ldp x12,x13,[x2,#8*6]
+ cbz x27,.Lsqr8x_tail_break
+
+ ldr x4,[x0,#-8*8]
+ adds x19,x19,x6
+ adcs x20,x20,x7
+ ldp x6,x7,[x1,#8*0]
+ adcs x21,x21,x8
+ adcs x22,x22,x9
+ ldp x8,x9,[x1,#8*2]
+ adcs x23,x23,x10
+ adcs x24,x24,x11
+ ldp x10,x11,[x1,#8*4]
+ adcs x25,x25,x12
+ mov x27,#-8*8
+ adcs x26,x26,x13
+ ldp x12,x13,[x1,#8*6]
+ add x1,x1,#8*8
+ //adc x28,xzr,xzr // moved above
+ b .Lsqr8x_tail
+
+.align 4
+.Lsqr8x_tail_break:
+ ldr x4,[x29,#112] // pull n0
+ add x27,x2,#8*8 // end of current t[num] window
+
+ subs xzr,x30,#1 // "move" top-most carry to carry bit
+ adcs x14,x19,x6
+ adcs x15,x20,x7
+ ldp x19,x20,[x0,#8*0]
+ adcs x21,x21,x8
+ ldp x6,x7,[x16,#8*0] // recall that x16 is &n[0]
+ adcs x22,x22,x9
+ ldp x8,x9,[x16,#8*2]
+ adcs x23,x23,x10
+ adcs x24,x24,x11
+ ldp x10,x11,[x16,#8*4]
+ adcs x25,x25,x12
+ adcs x26,x26,x13
+ ldp x12,x13,[x16,#8*6]
+ add x1,x16,#8*8
+ adc x30,xzr,xzr // top-most carry
+ mul x28,x4,x19
+ stp x14,x15,[x2,#8*0]
+ stp x21,x22,[x2,#8*2]
+ ldp x21,x22,[x0,#8*2]
+ stp x23,x24,[x2,#8*4]
+ ldp x23,x24,[x0,#8*4]
+ cmp x27,x29 // did we hit the bottom?
+ stp x25,x26,[x2,#8*6]
+ mov x2,x0 // slide the window
+ ldp x25,x26,[x0,#8*6]
+ mov x27,#8
+ b.ne .Lsqr8x_reduction
+
+ // Final step. We see if result is larger than modulus, and
+ // if it is, subtract the modulus. But comparison implies
+ // subtraction. So we subtract modulus, see if it borrowed,
+ // and conditionally copy original value.
+ ldr x0,[x29,#96] // pull rp
+ add x2,x2,#8*8
+ subs x14,x19,x6
+ sbcs x15,x20,x7
+ sub x27,x5,#8*8
+ mov x3,x0 // x0 copy
+
+.Lsqr8x_sub:
+ sbcs x16,x21,x8
+ ldp x6,x7,[x1,#8*0]
+ sbcs x17,x22,x9
+ stp x14,x15,[x0,#8*0]
+ sbcs x14,x23,x10
+ ldp x8,x9,[x1,#8*2]
+ sbcs x15,x24,x11
+ stp x16,x17,[x0,#8*2]
+ sbcs x16,x25,x12
+ ldp x10,x11,[x1,#8*4]
+ sbcs x17,x26,x13
+ ldp x12,x13,[x1,#8*6]
+ add x1,x1,#8*8
+ ldp x19,x20,[x2,#8*0]
+ sub x27,x27,#8*8
+ ldp x21,x22,[x2,#8*2]
+ ldp x23,x24,[x2,#8*4]
+ ldp x25,x26,[x2,#8*6]
+ add x2,x2,#8*8
+ stp x14,x15,[x0,#8*4]
+ sbcs x14,x19,x6
+ stp x16,x17,[x0,#8*6]
+ add x0,x0,#8*8
+ sbcs x15,x20,x7
+ cbnz x27,.Lsqr8x_sub
+
+ sbcs x16,x21,x8
+ mov x2,sp
+ add x1,sp,x5
+ ldp x6,x7,[x3,#8*0]
+ sbcs x17,x22,x9
+ stp x14,x15,[x0,#8*0]
+ sbcs x14,x23,x10
+ ldp x8,x9,[x3,#8*2]
+ sbcs x15,x24,x11
+ stp x16,x17,[x0,#8*2]
+ sbcs x16,x25,x12
+ ldp x19,x20,[x1,#8*0]
+ sbcs x17,x26,x13
+ ldp x21,x22,[x1,#8*2]
+ sbcs xzr,x30,xzr // did it borrow?
+ ldr x30,[x29,#8] // pull return address
+ stp x14,x15,[x0,#8*4]
+ stp x16,x17,[x0,#8*6]
+
+ sub x27,x5,#8*4
+.Lsqr4x_cond_copy:
+ sub x27,x27,#8*4
+ csel x14,x19,x6,lo
+ stp xzr,xzr,[x2,#8*0]
+ csel x15,x20,x7,lo
+ ldp x6,x7,[x3,#8*4]
+ ldp x19,x20,[x1,#8*4]
+ csel x16,x21,x8,lo
+ stp xzr,xzr,[x2,#8*2]
+ add x2,x2,#8*4
+ csel x17,x22,x9,lo
+ ldp x8,x9,[x3,#8*6]
+ ldp x21,x22,[x1,#8*6]
+ add x1,x1,#8*4
+ stp x14,x15,[x3,#8*0]
+ stp x16,x17,[x3,#8*2]
+ add x3,x3,#8*4
+ stp xzr,xzr,[x1,#8*0]
+ stp xzr,xzr,[x1,#8*2]
+ cbnz x27,.Lsqr4x_cond_copy
+
+ csel x14,x19,x6,lo
+ stp xzr,xzr,[x2,#8*0]
+ csel x15,x20,x7,lo
+ stp xzr,xzr,[x2,#8*2]
+ csel x16,x21,x8,lo
+ csel x17,x22,x9,lo
+ stp x14,x15,[x3,#8*0]
+ stp x16,x17,[x3,#8*2]
+
+ b .Lsqr8x_done
+
+.align 4
+.Lsqr8x8_post_condition:
+ adc x28,xzr,xzr
+ ldr x30,[x29,#8] // pull return address
+ // x19-7,x28 hold result, x6-7 hold modulus
+ subs x6,x19,x6
+ ldr x1,[x29,#96] // pull rp
+ sbcs x7,x20,x7
+ stp xzr,xzr,[sp,#8*0]
+ sbcs x8,x21,x8
+ stp xzr,xzr,[sp,#8*2]
+ sbcs x9,x22,x9
+ stp xzr,xzr,[sp,#8*4]
+ sbcs x10,x23,x10
+ stp xzr,xzr,[sp,#8*6]
+ sbcs x11,x24,x11
+ stp xzr,xzr,[sp,#8*8]
+ sbcs x12,x25,x12
+ stp xzr,xzr,[sp,#8*10]
+ sbcs x13,x26,x13
+ stp xzr,xzr,[sp,#8*12]
+ sbcs x28,x28,xzr // did it borrow?
+ stp xzr,xzr,[sp,#8*14]
+
+ // x6-7 hold result-modulus
+ csel x6,x19,x6,lo
+ csel x7,x20,x7,lo
+ csel x8,x21,x8,lo
+ csel x9,x22,x9,lo
+ stp x6,x7,[x1,#8*0]
+ csel x10,x23,x10,lo
+ csel x11,x24,x11,lo
+ stp x8,x9,[x1,#8*2]
+ csel x12,x25,x12,lo
+ csel x13,x26,x13,lo
+ stp x10,x11,[x1,#8*4]
+ stp x12,x13,[x1,#8*6]
+
+.Lsqr8x_done:
+ ldp x19,x20,[x29,#16]
+ mov sp,x29
+ ldp x21,x22,[x29,#32]
+ mov x0,#1
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x27,x28,[x29,#80]
+ ldr x29,[sp],#128
+ ret
+.size __bn_sqr8x_mont,.-__bn_sqr8x_mont
+.type __bn_mul4x_mont,%function
+.align 5
+__bn_mul4x_mont:
+ stp x29,x30,[sp,#-128]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+ stp x25,x26,[sp,#64]
+ stp x27,x28,[sp,#80]
+
+ sub x26,sp,x5,lsl#3
+ lsl x5,x5,#3
+ ldr x4,[x4] // *n0
+ sub sp,x26,#8*4 // alloca
+
+ add x10,x2,x5
+ add x27,x1,x5
+ stp x0,x10,[x29,#96] // offload rp and &b[num]
+
+ ldr x24,[x2,#8*0] // b[0]
+ ldp x6,x7,[x1,#8*0] // a[0..3]
+ ldp x8,x9,[x1,#8*2]
+ add x1,x1,#8*4
+ mov x19,xzr
+ mov x20,xzr
+ mov x21,xzr
+ mov x22,xzr
+ ldp x14,x15,[x3,#8*0] // n[0..3]
+ ldp x16,x17,[x3,#8*2]
+ adds x3,x3,#8*4 // clear carry bit
+ mov x0,xzr
+ mov x28,#0
+ mov x26,sp
+
+.Loop_mul4x_1st_reduction:
+ mul x10,x6,x24 // lo(a[0..3]*b[0])
+ adc x0,x0,xzr // modulo-scheduled
+ mul x11,x7,x24
+ add x28,x28,#8
+ mul x12,x8,x24
+ and x28,x28,#31
+ mul x13,x9,x24
+ adds x19,x19,x10
+ umulh x10,x6,x24 // hi(a[0..3]*b[0])
+ adcs x20,x20,x11
+ mul x25,x19,x4 // t[0]*n0
+ adcs x21,x21,x12
+ umulh x11,x7,x24
+ adcs x22,x22,x13
+ umulh x12,x8,x24
+ adc x23,xzr,xzr
+ umulh x13,x9,x24
+ ldr x24,[x2,x28] // next b[i] (or b[0])
+ adds x20,x20,x10
+ // (*) mul x10,x14,x25 // lo(n[0..3]*t[0]*n0)
+ str x25,[x26],#8 // put aside t[0]*n0 for tail processing
+ adcs x21,x21,x11
+ mul x11,x15,x25
+ adcs x22,x22,x12
+ mul x12,x16,x25
+ adc x23,x23,x13 // can't overflow
+ mul x13,x17,x25
+ // (*) adds xzr,x19,x10
+ subs xzr,x19,#1 // (*)
+ umulh x10,x14,x25 // hi(n[0..3]*t[0]*n0)
+ adcs x19,x20,x11
+ umulh x11,x15,x25
+ adcs x20,x21,x12
+ umulh x12,x16,x25
+ adcs x21,x22,x13
+ umulh x13,x17,x25
+ adcs x22,x23,x0
+ adc x0,xzr,xzr
+ adds x19,x19,x10
+ sub x10,x27,x1
+ adcs x20,x20,x11
+ adcs x21,x21,x12
+ adcs x22,x22,x13
+ //adc x0,x0,xzr
+ cbnz x28,.Loop_mul4x_1st_reduction
+
+ cbz x10,.Lmul4x4_post_condition
+
+ ldp x6,x7,[x1,#8*0] // a[4..7]
+ ldp x8,x9,[x1,#8*2]
+ add x1,x1,#8*4
+ ldr x25,[sp] // a[0]*n0
+ ldp x14,x15,[x3,#8*0] // n[4..7]
+ ldp x16,x17,[x3,#8*2]
+ add x3,x3,#8*4
+
+.Loop_mul4x_1st_tail:
+ mul x10,x6,x24 // lo(a[4..7]*b[i])
+ adc x0,x0,xzr // modulo-scheduled
+ mul x11,x7,x24
+ add x28,x28,#8
+ mul x12,x8,x24
+ and x28,x28,#31
+ mul x13,x9,x24
+ adds x19,x19,x10
+ umulh x10,x6,x24 // hi(a[4..7]*b[i])
+ adcs x20,x20,x11
+ umulh x11,x7,x24
+ adcs x21,x21,x12
+ umulh x12,x8,x24
+ adcs x22,x22,x13
+ umulh x13,x9,x24
+ adc x23,xzr,xzr
+ ldr x24,[x2,x28] // next b[i] (or b[0])
+ adds x20,x20,x10
+ mul x10,x14,x25 // lo(n[4..7]*a[0]*n0)
+ adcs x21,x21,x11
+ mul x11,x15,x25
+ adcs x22,x22,x12
+ mul x12,x16,x25
+ adc x23,x23,x13 // can't overflow
+ mul x13,x17,x25
+ adds x19,x19,x10
+ umulh x10,x14,x25 // hi(n[4..7]*a[0]*n0)
+ adcs x20,x20,x11
+ umulh x11,x15,x25
+ adcs x21,x21,x12
+ umulh x12,x16,x25
+ adcs x22,x22,x13
+ adcs x23,x23,x0
+ umulh x13,x17,x25
+ adc x0,xzr,xzr
+ ldr x25,[sp,x28] // next t[0]*n0
+ str x19,[x26],#8 // result!!!
+ adds x19,x20,x10
+ sub x10,x27,x1 // done yet?
+ adcs x20,x21,x11
+ adcs x21,x22,x12
+ adcs x22,x23,x13
+ //adc x0,x0,xzr
+ cbnz x28,.Loop_mul4x_1st_tail
+
+ sub x11,x27,x5 // rewinded x1
+ cbz x10,.Lmul4x_proceed
+
+ ldp x6,x7,[x1,#8*0]
+ ldp x8,x9,[x1,#8*2]
+ add x1,x1,#8*4
+ ldp x14,x15,[x3,#8*0]
+ ldp x16,x17,[x3,#8*2]
+ add x3,x3,#8*4
+ b .Loop_mul4x_1st_tail
+
+.align 5
+.Lmul4x_proceed:
+ ldr x24,[x2,#8*4]! // *++b
+ adc x30,x0,xzr
+ ldp x6,x7,[x11,#8*0] // a[0..3]
+ sub x3,x3,x5 // rewind np
+ ldp x8,x9,[x11,#8*2]
+ add x1,x11,#8*4
+
+ stp x19,x20,[x26,#8*0] // result!!!
+ ldp x19,x20,[sp,#8*4] // t[0..3]
+ stp x21,x22,[x26,#8*2] // result!!!
+ ldp x21,x22,[sp,#8*6]
+
+ ldp x14,x15,[x3,#8*0] // n[0..3]
+ mov x26,sp
+ ldp x16,x17,[x3,#8*2]
+ adds x3,x3,#8*4 // clear carry bit
+ mov x0,xzr
+
+.align 4
+.Loop_mul4x_reduction:
+ mul x10,x6,x24 // lo(a[0..3]*b[4])
+ adc x0,x0,xzr // modulo-scheduled
+ mul x11,x7,x24
+ add x28,x28,#8
+ mul x12,x8,x24
+ and x28,x28,#31
+ mul x13,x9,x24
+ adds x19,x19,x10
+ umulh x10,x6,x24 // hi(a[0..3]*b[4])
+ adcs x20,x20,x11
+ mul x25,x19,x4 // t[0]*n0
+ adcs x21,x21,x12
+ umulh x11,x7,x24
+ adcs x22,x22,x13
+ umulh x12,x8,x24
+ adc x23,xzr,xzr
+ umulh x13,x9,x24
+ ldr x24,[x2,x28] // next b[i]
+ adds x20,x20,x10
+ // (*) mul x10,x14,x25
+ str x25,[x26],#8 // put aside t[0]*n0 for tail processing
+ adcs x21,x21,x11
+ mul x11,x15,x25 // lo(n[0..3]*t[0]*n0
+ adcs x22,x22,x12
+ mul x12,x16,x25
+ adc x23,x23,x13 // can't overflow
+ mul x13,x17,x25
+ // (*) adds xzr,x19,x10
+ subs xzr,x19,#1 // (*)
+ umulh x10,x14,x25 // hi(n[0..3]*t[0]*n0
+ adcs x19,x20,x11
+ umulh x11,x15,x25
+ adcs x20,x21,x12
+ umulh x12,x16,x25
+ adcs x21,x22,x13
+ umulh x13,x17,x25
+ adcs x22,x23,x0
+ adc x0,xzr,xzr
+ adds x19,x19,x10
+ adcs x20,x20,x11
+ adcs x21,x21,x12
+ adcs x22,x22,x13
+ //adc x0,x0,xzr
+ cbnz x28,.Loop_mul4x_reduction
+
+ adc x0,x0,xzr
+ ldp x10,x11,[x26,#8*4] // t[4..7]
+ ldp x12,x13,[x26,#8*6]
+ ldp x6,x7,[x1,#8*0] // a[4..7]
+ ldp x8,x9,[x1,#8*2]
+ add x1,x1,#8*4
+ adds x19,x19,x10
+ adcs x20,x20,x11
+ adcs x21,x21,x12
+ adcs x22,x22,x13
+ //adc x0,x0,xzr
+
+ ldr x25,[sp] // t[0]*n0
+ ldp x14,x15,[x3,#8*0] // n[4..7]
+ ldp x16,x17,[x3,#8*2]
+ add x3,x3,#8*4
+
+.align 4
+.Loop_mul4x_tail:
+ mul x10,x6,x24 // lo(a[4..7]*b[4])
+ adc x0,x0,xzr // modulo-scheduled
+ mul x11,x7,x24
+ add x28,x28,#8
+ mul x12,x8,x24
+ and x28,x28,#31
+ mul x13,x9,x24
+ adds x19,x19,x10
+ umulh x10,x6,x24 // hi(a[4..7]*b[4])
+ adcs x20,x20,x11
+ umulh x11,x7,x24
+ adcs x21,x21,x12
+ umulh x12,x8,x24
+ adcs x22,x22,x13
+ umulh x13,x9,x24
+ adc x23,xzr,xzr
+ ldr x24,[x2,x28] // next b[i]
+ adds x20,x20,x10
+ mul x10,x14,x25 // lo(n[4..7]*t[0]*n0)
+ adcs x21,x21,x11
+ mul x11,x15,x25
+ adcs x22,x22,x12
+ mul x12,x16,x25
+ adc x23,x23,x13 // can't overflow
+ mul x13,x17,x25
+ adds x19,x19,x10
+ umulh x10,x14,x25 // hi(n[4..7]*t[0]*n0)
+ adcs x20,x20,x11
+ umulh x11,x15,x25
+ adcs x21,x21,x12
+ umulh x12,x16,x25
+ adcs x22,x22,x13
+ umulh x13,x17,x25
+ adcs x23,x23,x0
+ ldr x25,[sp,x28] // next a[0]*n0
+ adc x0,xzr,xzr
+ str x19,[x26],#8 // result!!!
+ adds x19,x20,x10
+ sub x10,x27,x1 // done yet?
+ adcs x20,x21,x11
+ adcs x21,x22,x12
+ adcs x22,x23,x13
+ //adc x0,x0,xzr
+ cbnz x28,.Loop_mul4x_tail
+
+ sub x11,x3,x5 // rewinded np?
+ adc x0,x0,xzr
+ cbz x10,.Loop_mul4x_break
+
+ ldp x10,x11,[x26,#8*4]
+ ldp x12,x13,[x26,#8*6]
+ ldp x6,x7,[x1,#8*0]
+ ldp x8,x9,[x1,#8*2]
+ add x1,x1,#8*4
+ adds x19,x19,x10
+ adcs x20,x20,x11
+ adcs x21,x21,x12
+ adcs x22,x22,x13
+ //adc x0,x0,xzr
+ ldp x14,x15,[x3,#8*0]
+ ldp x16,x17,[x3,#8*2]
+ add x3,x3,#8*4
+ b .Loop_mul4x_tail
+
+.align 4
+.Loop_mul4x_break:
+ ldp x12,x13,[x29,#96] // pull rp and &b[num]
+ adds x19,x19,x30
+ add x2,x2,#8*4 // bp++
+ adcs x20,x20,xzr
+ sub x1,x1,x5 // rewind ap
+ adcs x21,x21,xzr
+ stp x19,x20,[x26,#8*0] // result!!!
+ adcs x22,x22,xzr
+ ldp x19,x20,[sp,#8*4] // t[0..3]
+ adc x30,x0,xzr
+ stp x21,x22,[x26,#8*2] // result!!!
+ cmp x2,x13 // done yet?
+ ldp x21,x22,[sp,#8*6]
+ ldp x14,x15,[x11,#8*0] // n[0..3]
+ ldp x16,x17,[x11,#8*2]
+ add x3,x11,#8*4
+ b.eq .Lmul4x_post
+
+ ldr x24,[x2]
+ ldp x6,x7,[x1,#8*0] // a[0..3]
+ ldp x8,x9,[x1,#8*2]
+ adds x1,x1,#8*4 // clear carry bit
+ mov x0,xzr
+ mov x26,sp
+ b .Loop_mul4x_reduction
+
+.align 4
+.Lmul4x_post:
+ // Final step. We see if result is larger than modulus, and
+ // if it is, subtract the modulus. But comparison implies
+ // subtraction. So we subtract modulus, see if it borrowed,
+ // and conditionally copy original value.
+ mov x0,x12
+ mov x27,x12 // x0 copy
+ subs x10,x19,x14
+ add x26,sp,#8*8
+ sbcs x11,x20,x15
+ sub x28,x5,#8*4
+
+.Lmul4x_sub:
+ sbcs x12,x21,x16
+ ldp x14,x15,[x3,#8*0]
+ sub x28,x28,#8*4
+ ldp x19,x20,[x26,#8*0]
+ sbcs x13,x22,x17
+ ldp x16,x17,[x3,#8*2]
+ add x3,x3,#8*4
+ ldp x21,x22,[x26,#8*2]
+ add x26,x26,#8*4
+ stp x10,x11,[x0,#8*0]
+ sbcs x10,x19,x14
+ stp x12,x13,[x0,#8*2]
+ add x0,x0,#8*4
+ sbcs x11,x20,x15
+ cbnz x28,.Lmul4x_sub
+
+ sbcs x12,x21,x16
+ mov x26,sp
+ add x1,sp,#8*4
+ ldp x6,x7,[x27,#8*0]
+ sbcs x13,x22,x17
+ stp x10,x11,[x0,#8*0]
+ ldp x8,x9,[x27,#8*2]
+ stp x12,x13,[x0,#8*2]
+ ldp x19,x20,[x1,#8*0]
+ ldp x21,x22,[x1,#8*2]
+ sbcs xzr,x30,xzr // did it borrow?
+ ldr x30,[x29,#8] // pull return address
+
+ sub x28,x5,#8*4
+.Lmul4x_cond_copy:
+ sub x28,x28,#8*4
+ csel x10,x19,x6,lo
+ stp xzr,xzr,[x26,#8*0]
+ csel x11,x20,x7,lo
+ ldp x6,x7,[x27,#8*4]
+ ldp x19,x20,[x1,#8*4]
+ csel x12,x21,x8,lo
+ stp xzr,xzr,[x26,#8*2]
+ add x26,x26,#8*4
+ csel x13,x22,x9,lo
+ ldp x8,x9,[x27,#8*6]
+ ldp x21,x22,[x1,#8*6]
+ add x1,x1,#8*4
+ stp x10,x11,[x27,#8*0]
+ stp x12,x13,[x27,#8*2]
+ add x27,x27,#8*4
+ cbnz x28,.Lmul4x_cond_copy
+
+ csel x10,x19,x6,lo
+ stp xzr,xzr,[x26,#8*0]
+ csel x11,x20,x7,lo
+ stp xzr,xzr,[x26,#8*2]
+ csel x12,x21,x8,lo
+ stp xzr,xzr,[x26,#8*3]
+ csel x13,x22,x9,lo
+ stp xzr,xzr,[x26,#8*4]
+ stp x10,x11,[x27,#8*0]
+ stp x12,x13,[x27,#8*2]
+
+ b .Lmul4x_done
+
+.align 4
+.Lmul4x4_post_condition:
+ adc x0,x0,xzr
+ ldr x1,[x29,#96] // pull rp
+ // x19-3,x0 hold result, x14-7 hold modulus
+ subs x6,x19,x14
+ ldr x30,[x29,#8] // pull return address
+ sbcs x7,x20,x15
+ stp xzr,xzr,[sp,#8*0]
+ sbcs x8,x21,x16
+ stp xzr,xzr,[sp,#8*2]
+ sbcs x9,x22,x17
+ stp xzr,xzr,[sp,#8*4]
+ sbcs xzr,x0,xzr // did it borrow?
+ stp xzr,xzr,[sp,#8*6]
+
+ // x6-3 hold result-modulus
+ csel x6,x19,x6,lo
+ csel x7,x20,x7,lo
+ csel x8,x21,x8,lo
+ csel x9,x22,x9,lo
+ stp x6,x7,[x1,#8*0]
+ stp x8,x9,[x1,#8*2]
+
+.Lmul4x_done:
+ ldp x19,x20,[x29,#16]
+ mov sp,x29
+ ldp x21,x22,[x29,#32]
+ mov x0,#1
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x27,x28,[x29,#80]
+ ldr x29,[sp],#128
+ ret
+.size __bn_mul4x_mont,.-__bn_mul4x_mont
+.byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.align 2
+.align 4
+#endif \ No newline at end of file
diff --git a/linux-aarch64/crypto/modes/ghashv8-armx.S b/linux-aarch64/crypto/modes/ghashv8-armx64.S
index ad19074..8d44667 100644
--- a/linux-aarch64/crypto/modes/ghashv8-armx.S
+++ b/linux-aarch64/crypto/modes/ghashv8-armx64.S
@@ -1,4 +1,5 @@
-#include "arm_arch.h"
+#if defined(__aarch64__)
+#include <openssl/arm_arch.h>
.text
#if !defined(__clang__)
@@ -67,10 +68,10 @@ gcm_gmult_v8:
#endif
ext v3.16b,v17.16b,v17.16b,#8
- pmull v0.1q,v20.1d,v3.1d //H.lo·Xi.lo
+ pmull v0.1q,v20.1d,v3.1d //H.lo·Xi.lo
eor v17.16b,v17.16b,v3.16b //Karatsuba pre-processing
- pmull2 v2.1q,v20.2d,v3.2d //H.hi·Xi.hi
- pmull v1.1q,v21.1d,v17.1d //(H.lo+H.hi)·(Xi.lo+Xi.hi)
+ pmull2 v2.1q,v20.2d,v3.2d //H.hi·Xi.hi
+ pmull v1.1q,v21.1d,v17.1d //(H.lo+H.hi)·(Xi.lo+Xi.hi)
ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing
eor v18.16b,v0.16b,v2.16b
@@ -134,7 +135,7 @@ gcm_ghash_v8:
#endif
ext v7.16b,v17.16b,v17.16b,#8
eor v3.16b,v3.16b,v0.16b //I[i]^=Xi
- pmull v4.1q,v20.1d,v7.1d //H·Ii+1
+ pmull v4.1q,v20.1d,v7.1d //H·Ii+1
eor v17.16b,v17.16b,v7.16b //Karatsuba pre-processing
pmull2 v6.1q,v20.2d,v7.2d
b .Loop_mod2x_v8
@@ -143,14 +144,14 @@ gcm_ghash_v8:
.Loop_mod2x_v8:
ext v18.16b,v3.16b,v3.16b,#8
subs x3,x3,#32 //is there more data?
- pmull v0.1q,v22.1d,v3.1d //H^2.lo·Xi.lo
+ pmull v0.1q,v22.1d,v3.1d //H^2.lo·Xi.lo
csel x12,xzr,x12,lo //is it time to zero x12?
pmull v5.1q,v21.1d,v17.1d
eor v18.16b,v18.16b,v3.16b //Karatsuba pre-processing
- pmull2 v2.1q,v22.2d,v3.2d //H^2.hi·Xi.hi
+ pmull2 v2.1q,v22.2d,v3.2d //H^2.hi·Xi.hi
eor v0.16b,v0.16b,v4.16b //accumulate
- pmull2 v1.1q,v21.2d,v18.2d //(H^2.lo+H^2.hi)·(Xi.lo+Xi.hi)
+ pmull2 v1.1q,v21.2d,v18.2d //(H^2.lo+H^2.hi)·(Xi.lo+Xi.hi)
ld1 {v16.2d},[x2],x12 //load [rotated] I[i+2]
eor v2.16b,v2.16b,v6.16b
@@ -175,7 +176,7 @@ gcm_ghash_v8:
ext v7.16b,v17.16b,v17.16b,#8
ext v3.16b,v16.16b,v16.16b,#8
eor v0.16b,v1.16b,v18.16b
- pmull v4.1q,v20.1d,v7.1d //H·Ii+1
+ pmull v4.1q,v20.1d,v7.1d //H·Ii+1
eor v3.16b,v3.16b,v2.16b //accumulate v3.16b early
ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction
@@ -196,10 +197,10 @@ gcm_ghash_v8:
eor v3.16b,v3.16b,v0.16b //inp^=Xi
eor v17.16b,v16.16b,v18.16b //v17.16b is rotated inp^Xi
- pmull v0.1q,v20.1d,v3.1d //H.lo·Xi.lo
+ pmull v0.1q,v20.1d,v3.1d //H.lo·Xi.lo
eor v17.16b,v17.16b,v3.16b //Karatsuba pre-processing
- pmull2 v2.1q,v20.2d,v3.2d //H.hi·Xi.hi
- pmull v1.1q,v21.1d,v17.1d //(H.lo+H.hi)·(Xi.lo+Xi.hi)
+ pmull2 v2.1q,v20.2d,v3.2d //H.hi·Xi.hi
+ pmull v1.1q,v21.1d,v17.1d //(H.lo+H.hi)·(Xi.lo+Xi.hi)
ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing
eor v18.16b,v0.16b,v2.16b
@@ -228,3 +229,4 @@ gcm_ghash_v8:
.byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
.align 2
.align 2
+#endif \ No newline at end of file
diff --git a/linux-aarch64/crypto/sha/sha1-armv8.S b/linux-aarch64/crypto/sha/sha1-armv8.S
index ab6aa98..6cf9877 100644
--- a/linux-aarch64/crypto/sha/sha1-armv8.S
+++ b/linux-aarch64/crypto/sha/sha1-armv8.S
@@ -1,4 +1,5 @@
-#include "arm_arch.h"
+#if defined(__aarch64__)
+#include <openssl/arm_arch.h>
.text
@@ -1211,3 +1212,4 @@ sha1_block_armv8:
.align 2
.align 2
.comm OPENSSL_armcap_P,4,4
+#endif \ No newline at end of file
diff --git a/linux-aarch64/crypto/sha/sha256-armv8.S b/linux-aarch64/crypto/sha/sha256-armv8.S
index ec572e9..0fad009 100644
--- a/linux-aarch64/crypto/sha/sha256-armv8.S
+++ b/linux-aarch64/crypto/sha/sha256-armv8.S
@@ -1,4 +1,5 @@
-#include "arm_arch.h"
+#if defined(__aarch64__)
+#include <openssl/arm_arch.h>
.text
@@ -1141,3 +1142,4 @@ sha256_block_armv8:
ret
.size sha256_block_armv8,.-sha256_block_armv8
.comm OPENSSL_armcap_P,4,4
+#endif \ No newline at end of file
diff --git a/linux-aarch64/crypto/sha/sha512-armv8.S b/linux-aarch64/crypto/sha/sha512-armv8.S
index 8fc342a..517c033 100644
--- a/linux-aarch64/crypto/sha/sha512-armv8.S
+++ b/linux-aarch64/crypto/sha/sha512-armv8.S
@@ -1,4 +1,5 @@
-#include "arm_arch.h"
+#if defined(__aarch64__)
+#include <openssl/arm_arch.h>
.text
@@ -1021,3 +1022,4 @@ sha512_block_data_order:
.align 2
.align 2
.comm OPENSSL_armcap_P,4,4
+#endif \ No newline at end of file
diff --git a/linux-arm/crypto/aes/aes-armv4.S b/linux-arm/crypto/aes/aes-armv4.S
index 1135020..c4d7065 100644
--- a/linux-arm/crypto/aes/aes-armv4.S
+++ b/linux-arm/crypto/aes/aes-armv4.S
@@ -1,3 +1,4 @@
+#if defined(__arm__)
@ ====================================================================
@ Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
@@ -33,7 +34,7 @@
#if defined(__arm__)
#ifndef __KERNEL__
-# include "arm_arch.h"
+# include <openssl/arm_arch.h>
#else
# define __ARM_ARCH__ __LINUX_ARM_ARCH__
#endif
@@ -1196,3 +1197,4 @@ _armv4_AES_decrypt:
.align 2
#endif
+#endif \ No newline at end of file
diff --git a/linux-arm/crypto/aes/aesv8-armx.S b/linux-arm/crypto/aes/aesv8-armx32.S
index 006300c..6012b0c 100644
--- a/linux-arm/crypto/aes/aesv8-armx.S
+++ b/linux-arm/crypto/aes/aesv8-armx32.S
@@ -1,4 +1,5 @@
-#include "arm_arch.h"
+#if defined(__arm__)
+#include <openssl/arm_arch.h>
#if __ARM_MAX_ARCH__>=7
.text
@@ -752,3 +753,4 @@ aes_v8_ctr32_encrypt_blocks:
ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,pc}
.size aes_v8_ctr32_encrypt_blocks,.-aes_v8_ctr32_encrypt_blocks
#endif
+#endif \ No newline at end of file
diff --git a/linux-arm/crypto/aes/bsaes-armv7.S b/linux-arm/crypto/aes/bsaes-armv7.S
index 204ee3e..a3ebec8 100644
--- a/linux-arm/crypto/aes/bsaes-armv7.S
+++ b/linux-arm/crypto/aes/bsaes-armv7.S
@@ -1,3 +1,4 @@
+#if defined(__arm__)
@ ====================================================================
@ Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
@@ -46,9 +47,8 @@
@
@ <ard.biesheuvel@linaro.org>
-#if defined(__arm__)
#ifndef __KERNEL__
-# include "arm_arch.h"
+# include <openssl/arm_arch.h>
# define VFP_ABI_PUSH vstmdb sp!,{d8-d15}
# define VFP_ABI_POP vldmia sp!,{d8-d15}
@@ -2574,4 +2574,4 @@ bsaes_xts_decrypt:
.size bsaes_xts_decrypt,.-bsaes_xts_decrypt
#endif
-#endif
+#endif \ No newline at end of file
diff --git a/linux-arm/crypto/bn/armv4-mont.S b/linux-arm/crypto/bn/armv4-mont.S
index 81dcbeb..fc671e8 100644
--- a/linux-arm/crypto/bn/armv4-mont.S
+++ b/linux-arm/crypto/bn/armv4-mont.S
@@ -1,4 +1,5 @@
-#include "arm_arch.h"
+#if defined(__arm__)
+#include <openssl/arm_arch.h>
.text
.code 32
@@ -585,3 +586,4 @@ bn_mul8x_mont_neon:
.comm OPENSSL_armcap_P,4,4
.hidden OPENSSL_armcap_P
#endif
+#endif \ No newline at end of file
diff --git a/linux-arm/crypto/modes/ghash-armv4.S b/linux-arm/crypto/modes/ghash-armv4.S
index b6c7e9b..d955d82 100644
--- a/linux-arm/crypto/modes/ghash-armv4.S
+++ b/linux-arm/crypto/modes/ghash-armv4.S
@@ -1,12 +1,12 @@
#if defined(__arm__)
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
.syntax unified
.text
.code 32
-#ifdef __APPLE__
+#ifdef __clang__
#define ldrplb ldrbpl
#define ldrneb ldrbne
#endif
@@ -535,5 +535,4 @@ gcm_ghash_neon:
.byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
.align 2
.align 2
-
-#endif
+#endif \ No newline at end of file
diff --git a/linux-arm/crypto/modes/ghashv8-armx.S b/linux-arm/crypto/modes/ghashv8-armx32.S
index 71913fb..9a38ded 100644
--- a/linux-arm/crypto/modes/ghashv8-armx.S
+++ b/linux-arm/crypto/modes/ghashv8-armx32.S
@@ -1,4 +1,5 @@
-#include "arm_arch.h"
+#if defined(__arm__)
+#include <openssl/arm_arch.h>
.text
.fpu neon
@@ -66,10 +67,10 @@ gcm_gmult_v8:
#endif
vext.8 q3,q9,q9,#8
-.byte 0x86,0x0e,0xa8,0xf2 @ pmull q0,q12,q3 @ H.lo·Xi.lo
+.byte 0x86,0x0e,0xa8,0xf2 @ pmull q0,q12,q3 @ H.lo·Xi.lo
veor q9,q9,q3 @ Karatsuba pre-processing
-.byte 0x87,0x4e,0xa9,0xf2 @ pmull2 q2,q12,q3 @ H.hi·Xi.hi
-.byte 0xa2,0x2e,0xaa,0xf2 @ pmull q1,q13,q9 @ (H.lo+H.hi)·(Xi.lo+Xi.hi)
+.byte 0x87,0x4e,0xa9,0xf2 @ pmull2 q2,q12,q3 @ H.hi·Xi.hi
+.byte 0xa2,0x2e,0xaa,0xf2 @ pmull q1,q13,q9 @ (H.lo+H.hi)·(Xi.lo+Xi.hi)
vext.8 q9,q0,q2,#8 @ Karatsuba post-processing
veor q10,q0,q2
@@ -134,7 +135,7 @@ gcm_ghash_v8:
#endif
vext.8 q7,q9,q9,#8
veor q3,q3,q0 @ I[i]^=Xi
-.byte 0x8e,0x8e,0xa8,0xf2 @ pmull q4,q12,q7 @ H·Ii+1
+.byte 0x8e,0x8e,0xa8,0xf2 @ pmull q4,q12,q7 @ H·Ii+1
veor q9,q9,q7 @ Karatsuba pre-processing
.byte 0x8f,0xce,0xa9,0xf2 @ pmull2 q6,q12,q7
b .Loop_mod2x_v8
@@ -143,14 +144,14 @@ gcm_ghash_v8:
.Loop_mod2x_v8:
vext.8 q10,q3,q3,#8
subs r3,r3,#32 @ is there more data?
-.byte 0x86,0x0e,0xac,0xf2 @ pmull q0,q14,q3 @ H^2.lo·Xi.lo
+.byte 0x86,0x0e,0xac,0xf2 @ pmull q0,q14,q3 @ H^2.lo·Xi.lo
movlo r12,#0 @ is it time to zero r12?
.byte 0xa2,0xae,0xaa,0xf2 @ pmull q5,q13,q9
veor q10,q10,q3 @ Karatsuba pre-processing
-.byte 0x87,0x4e,0xad,0xf2 @ pmull2 q2,q14,q3 @ H^2.hi·Xi.hi
+.byte 0x87,0x4e,0xad,0xf2 @ pmull2 q2,q14,q3 @ H^2.hi·Xi.hi
veor q0,q0,q4 @ accumulate
-.byte 0xa5,0x2e,0xab,0xf2 @ pmull2 q1,q13,q10 @ (H^2.lo+H^2.hi)·(Xi.lo+Xi.hi)
+.byte 0xa5,0x2e,0xab,0xf2 @ pmull2 q1,q13,q10 @ (H^2.lo+H^2.hi)·(Xi.lo+Xi.hi)
vld1.64 {q8},[r2],r12 @ load [rotated] I[i+2]
veor q2,q2,q6
@@ -175,7 +176,7 @@ gcm_ghash_v8:
vext.8 q7,q9,q9,#8
vext.8 q3,q8,q8,#8
veor q0,q1,q10
-.byte 0x8e,0x8e,0xa8,0xf2 @ pmull q4,q12,q7 @ H·Ii+1
+.byte 0x8e,0x8e,0xa8,0xf2 @ pmull q4,q12,q7 @ H·Ii+1
veor q3,q3,q2 @ accumulate q3 early
vext.8 q10,q0,q0,#8 @ 2nd phase of reduction
@@ -196,10 +197,10 @@ gcm_ghash_v8:
veor q3,q3,q0 @ inp^=Xi
veor q9,q8,q10 @ q9 is rotated inp^Xi
-.byte 0x86,0x0e,0xa8,0xf2 @ pmull q0,q12,q3 @ H.lo·Xi.lo
+.byte 0x86,0x0e,0xa8,0xf2 @ pmull q0,q12,q3 @ H.lo·Xi.lo
veor q9,q9,q3 @ Karatsuba pre-processing
-.byte 0x87,0x4e,0xa9,0xf2 @ pmull2 q2,q12,q3 @ H.hi·Xi.hi
-.byte 0xa2,0x2e,0xaa,0xf2 @ pmull q1,q13,q9 @ (H.lo+H.hi)·(Xi.lo+Xi.hi)
+.byte 0x87,0x4e,0xa9,0xf2 @ pmull2 q2,q12,q3 @ H.hi·Xi.hi
+.byte 0xa2,0x2e,0xaa,0xf2 @ pmull q1,q13,q9 @ (H.lo+H.hi)·(Xi.lo+Xi.hi)
vext.8 q9,q0,q2,#8 @ Karatsuba post-processing
veor q10,q0,q2
@@ -229,3 +230,4 @@ gcm_ghash_v8:
.byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
.align 2
.align 2
+#endif \ No newline at end of file
diff --git a/linux-arm/crypto/sha/sha1-armv4-large.S b/linux-arm/crypto/sha/sha1-armv4-large.S
index 52c99bf..66d0ef3 100644
--- a/linux-arm/crypto/sha/sha1-armv4-large.S
+++ b/linux-arm/crypto/sha/sha1-armv4-large.S
@@ -1,4 +1,5 @@
-#include "arm_arch.h"
+#if defined(__arm__)
+#include <openssl/arm_arch.h>
.text
.code 32
@@ -1458,3 +1459,4 @@ sha1_block_data_order_armv8:
.comm OPENSSL_armcap_P,4,4
.hidden OPENSSL_armcap_P
#endif
+#endif \ No newline at end of file
diff --git a/linux-arm/crypto/sha/sha256-armv4.S b/linux-arm/crypto/sha/sha256-armv4.S
index 114aa43..9fc3e0b 100644
--- a/linux-arm/crypto/sha/sha256-armv4.S
+++ b/linux-arm/crypto/sha/sha256-armv4.S
@@ -1,3 +1,4 @@
+#if defined(__arm__)
@ ====================================================================
@ Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
@@ -37,7 +38,7 @@
@ Add ARMv8 code path performing at 2.0 cpb on Apple A7.
#ifndef __KERNEL__
-# include "arm_arch.h"
+# include <openssl/arm_arch.h>
#else
# define __ARM_ARCH__ __LINUX_ARM_ARCH__
# define __ARM_MAX_ARCH__ 7
@@ -2814,3 +2815,4 @@ sha256_block_data_order_armv8:
.comm OPENSSL_armcap_P,4,4
.hidden OPENSSL_armcap_P
#endif
+#endif \ No newline at end of file
diff --git a/linux-arm/crypto/sha/sha512-armv4.S b/linux-arm/crypto/sha/sha512-armv4.S
index 1a3d467..834ede9 100644
--- a/linux-arm/crypto/sha/sha512-armv4.S
+++ b/linux-arm/crypto/sha/sha512-armv4.S
@@ -1,3 +1,4 @@
+#if defined(__arm__)
@ ====================================================================
@ Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
@@ -46,7 +47,7 @@
@ was reflected in below two parameters as 0 and 4. Now caller is
@ expected to maintain native byte order for whole 64-bit values.
#ifndef __KERNEL__
-# include "arm_arch.h"
+# include <openssl/arm_arch.h>
# define VFP_ABI_PUSH vstmdb sp!,{d8-d15}
# define VFP_ABI_POP vldmia sp!,{d8-d15}
#else
@@ -1865,3 +1866,4 @@ sha512_block_data_order_neon:
.comm OPENSSL_armcap_P,4,4
.hidden OPENSSL_armcap_P
#endif
+#endif \ No newline at end of file
diff --git a/linux-x86/crypto/cpu-x86-asm.S b/linux-x86/crypto/cpu-x86-asm.S
deleted file mode 100644
index 24a8dd4..0000000
--- a/linux-x86/crypto/cpu-x86-asm.S
+++ /dev/null
@@ -1,322 +0,0 @@
-#if defined(__i386__)
-.file "crypto/cpu-x86-asm.S"
-.text
-.globl OPENSSL_ia32_cpuid
-.hidden OPENSSL_ia32_cpuid
-.type OPENSSL_ia32_cpuid,@function
-.align 16
-OPENSSL_ia32_cpuid:
-.L_OPENSSL_ia32_cpuid_begin:
- pushl %ebp
- pushl %ebx
- pushl %esi
- pushl %edi
- xorl %edx,%edx
- pushfl
- popl %eax
- movl %eax,%ecx
- xorl $2097152,%eax
- pushl %eax
- popfl
- pushfl
- popl %eax
- xorl %eax,%ecx
- xorl %eax,%eax
- btl $21,%ecx
- jnc .L000nocpuid
- movl 20(%esp),%esi
- movl %eax,8(%esi)
- .byte 0x0f,0xa2
- movl %eax,%edi
- xorl %eax,%eax
- cmpl $1970169159,%ebx
- setne %al
- movl %eax,%ebp
- cmpl $1231384169,%edx
- setne %al
- orl %eax,%ebp
- cmpl $1818588270,%ecx
- setne %al
- orl %eax,%ebp
- jz .L001intel
- cmpl $1752462657,%ebx
- setne %al
- movl %eax,%esi
- cmpl $1769238117,%edx
- setne %al
- orl %eax,%esi
- cmpl $1145913699,%ecx
- setne %al
- orl %eax,%esi
- jnz .L001intel
- movl $2147483648,%eax
- .byte 0x0f,0xa2
- cmpl $2147483649,%eax
- jb .L001intel
- movl %eax,%esi
- movl $2147483649,%eax
- .byte 0x0f,0xa2
- orl %ecx,%ebp
- andl $2049,%ebp
- cmpl $2147483656,%esi
- jb .L001intel
- movl $2147483656,%eax
- .byte 0x0f,0xa2
- movzbl %cl,%esi
- incl %esi
- movl $1,%eax
- xorl %ecx,%ecx
- .byte 0x0f,0xa2
- btl $28,%edx
- jnc .L002generic
- shrl $16,%ebx
- andl $255,%ebx
- cmpl %esi,%ebx
- ja .L002generic
- andl $4026531839,%edx
- jmp .L002generic
-.L001intel:
- cmpl $7,%edi
- jb .L003cacheinfo
- movl 20(%esp),%esi
- movl $7,%eax
- xorl %ecx,%ecx
- .byte 0x0f,0xa2
- movl %ebx,8(%esi)
-.L003cacheinfo:
- cmpl $4,%edi
- movl $-1,%edi
- jb .L004nocacheinfo
- movl $4,%eax
- movl $0,%ecx
- .byte 0x0f,0xa2
- movl %eax,%edi
- shrl $14,%edi
- andl $4095,%edi
-.L004nocacheinfo:
- movl $1,%eax
- xorl %ecx,%ecx
- .byte 0x0f,0xa2
- andl $3220176895,%edx
- cmpl $0,%ebp
- jne .L005notintel
- orl $1073741824,%edx
-.L005notintel:
- btl $28,%edx
- jnc .L002generic
- andl $4026531839,%edx
- cmpl $0,%edi
- je .L002generic
- orl $268435456,%edx
- shrl $16,%ebx
- cmpb $1,%bl
- ja .L002generic
- andl $4026531839,%edx
-.L002generic:
- andl $2048,%ebp
- andl $4294965247,%ecx
- movl %edx,%esi
- orl %ecx,%ebp
- btl $27,%ecx
- jnc .L006clear_avx
- xorl %ecx,%ecx
-.byte 15,1,208
- andl $6,%eax
- cmpl $6,%eax
- je .L007done
- cmpl $2,%eax
- je .L006clear_avx
-.L008clear_xmm:
- andl $4261412861,%ebp
- andl $4278190079,%esi
-.L006clear_avx:
- andl $4026525695,%ebp
- movl 20(%esp),%edi
- andl $4294967263,8(%edi)
-.L007done:
- movl %esi,%eax
- movl %ebp,%edx
-.L000nocpuid:
- popl %edi
- popl %esi
- popl %ebx
- popl %ebp
- ret
-.size OPENSSL_ia32_cpuid,.-.L_OPENSSL_ia32_cpuid_begin
-.globl OPENSSL_rdtsc
-.hidden OPENSSL_rdtsc
-.type OPENSSL_rdtsc,@function
-.align 16
-OPENSSL_rdtsc:
-.L_OPENSSL_rdtsc_begin:
- xorl %eax,%eax
- xorl %edx,%edx
- call .L009PIC_me_up
-.L009PIC_me_up:
- popl %ecx
- leal OPENSSL_ia32cap_P-.L009PIC_me_up(%ecx),%ecx
- btl $4,(%ecx)
- jnc .L010notsc
- .byte 0x0f,0x31
-.L010notsc:
- ret
-.size OPENSSL_rdtsc,.-.L_OPENSSL_rdtsc_begin
-.globl OPENSSL_instrument_halt
-.hidden OPENSSL_instrument_halt
-.type OPENSSL_instrument_halt,@function
-.align 16
-OPENSSL_instrument_halt:
-.L_OPENSSL_instrument_halt_begin:
- call .L011PIC_me_up
-.L011PIC_me_up:
- popl %ecx
- leal OPENSSL_ia32cap_P-.L011PIC_me_up(%ecx),%ecx
- btl $4,(%ecx)
- jnc .L012nohalt
-.long 2421723150
- andl $3,%eax
- jnz .L012nohalt
- pushfl
- popl %eax
- btl $9,%eax
- jnc .L012nohalt
- .byte 0x0f,0x31
- pushl %edx
- pushl %eax
- hlt
- .byte 0x0f,0x31
- subl (%esp),%eax
- sbbl 4(%esp),%edx
- addl $8,%esp
- ret
-.L012nohalt:
- xorl %eax,%eax
- xorl %edx,%edx
- ret
-.size OPENSSL_instrument_halt,.-.L_OPENSSL_instrument_halt_begin
-.globl OPENSSL_far_spin
-.hidden OPENSSL_far_spin
-.type OPENSSL_far_spin,@function
-.align 16
-OPENSSL_far_spin:
-.L_OPENSSL_far_spin_begin:
- pushfl
- popl %eax
- btl $9,%eax
- jnc .L013nospin
- movl 4(%esp),%eax
- movl 8(%esp),%ecx
-.long 2430111262
- xorl %eax,%eax
- movl (%ecx),%edx
- jmp .L014spin
-.align 16
-.L014spin:
- incl %eax
- cmpl (%ecx),%edx
- je .L014spin
-.long 529567888
- ret
-.L013nospin:
- xorl %eax,%eax
- xorl %edx,%edx
- ret
-.size OPENSSL_far_spin,.-.L_OPENSSL_far_spin_begin
-.globl OPENSSL_wipe_cpu
-.hidden OPENSSL_wipe_cpu
-.type OPENSSL_wipe_cpu,@function
-.align 16
-OPENSSL_wipe_cpu:
-.L_OPENSSL_wipe_cpu_begin:
- xorl %eax,%eax
- xorl %edx,%edx
- call .L015PIC_me_up
-.L015PIC_me_up:
- popl %ecx
- leal OPENSSL_ia32cap_P-.L015PIC_me_up(%ecx),%ecx
- movl (%ecx),%ecx
- btl $1,(%ecx)
- jnc .L016no_x87
- andl $83886080,%ecx
- cmpl $83886080,%ecx
- jne .L017no_sse2
- pxor %xmm0,%xmm0
- pxor %xmm1,%xmm1
- pxor %xmm2,%xmm2
- pxor %xmm3,%xmm3
- pxor %xmm4,%xmm4
- pxor %xmm5,%xmm5
- pxor %xmm6,%xmm6
- pxor %xmm7,%xmm7
-.L017no_sse2:
-.long 4007259865,4007259865,4007259865,4007259865,2430851995
-.L016no_x87:
- leal 4(%esp),%eax
- ret
-.size OPENSSL_wipe_cpu,.-.L_OPENSSL_wipe_cpu_begin
-.globl OPENSSL_atomic_add
-.hidden OPENSSL_atomic_add
-.type OPENSSL_atomic_add,@function
-.align 16
-OPENSSL_atomic_add:
-.L_OPENSSL_atomic_add_begin:
- movl 4(%esp),%edx
- movl 8(%esp),%ecx
- pushl %ebx
- nop
- movl (%edx),%eax
-.L018spin:
- leal (%eax,%ecx,1),%ebx
- nop
-.long 447811568
- jne .L018spin
- movl %ebx,%eax
- popl %ebx
- ret
-.size OPENSSL_atomic_add,.-.L_OPENSSL_atomic_add_begin
-.globl OPENSSL_indirect_call
-.hidden OPENSSL_indirect_call
-.type OPENSSL_indirect_call,@function
-.align 16
-OPENSSL_indirect_call:
-.L_OPENSSL_indirect_call_begin:
- pushl %ebp
- movl %esp,%ebp
- subl $28,%esp
- movl 12(%ebp),%ecx
- movl %ecx,(%esp)
- movl 16(%ebp),%edx
- movl %edx,4(%esp)
- movl 20(%ebp),%eax
- movl %eax,8(%esp)
- movl 24(%ebp),%eax
- movl %eax,12(%esp)
- movl 28(%ebp),%eax
- movl %eax,16(%esp)
- movl 32(%ebp),%eax
- movl %eax,20(%esp)
- movl 36(%ebp),%eax
- movl %eax,24(%esp)
- call *8(%ebp)
- movl %ebp,%esp
- popl %ebp
- ret
-.size OPENSSL_indirect_call,.-.L_OPENSSL_indirect_call_begin
-.globl OPENSSL_ia32_rdrand
-.hidden OPENSSL_ia32_rdrand
-.type OPENSSL_ia32_rdrand,@function
-.align 16
-OPENSSL_ia32_rdrand:
-.L_OPENSSL_ia32_rdrand_begin:
- movl $8,%ecx
-.L019loop:
-.byte 15,199,240
- jc .L020break
- loop .L019loop
-.L020break:
- cmpl $0,%eax
- cmovel %ecx,%eax
- ret
-.size OPENSSL_ia32_rdrand,.-.L_OPENSSL_ia32_rdrand_begin
-.hidden OPENSSL_ia32cap_P
-#endif
diff --git a/linux-x86/crypto/sha/sha1-586.S b/linux-x86/crypto/sha/sha1-586.S
index 808ccac..58d0bc1 100644
--- a/linux-x86/crypto/sha/sha1-586.S
+++ b/linux-x86/crypto/sha/sha1-586.S
@@ -23,8 +23,11 @@ sha1_block_data_order:
movl 8(%esi),%ecx
testl $16777216,%eax
jz .L001x86
- testl $536870912,%ecx
- jnz .Lshaext_shortcut
+ andl $268435456,%edx
+ andl $1073741824,%eax
+ orl %edx,%eax
+ cmpl $1342177280,%eax
+ je .Lavx_shortcut
jmp .Lssse3_shortcut
.align 16
.L001x86:
@@ -1393,177 +1396,6 @@ sha1_block_data_order:
popl %ebp
ret
.size sha1_block_data_order,.-.L_sha1_block_data_order_begin
-.hidden _sha1_block_data_order_shaext
-.type _sha1_block_data_order_shaext,@function
-.align 16
-_sha1_block_data_order_shaext:
- pushl %ebp
- pushl %ebx
- pushl %esi
- pushl %edi
- call .L003pic_point
-.L003pic_point:
- popl %ebp
- leal .LK_XX_XX-.L003pic_point(%ebp),%ebp
-.Lshaext_shortcut:
- movl 20(%esp),%edi
- movl %esp,%ebx
- movl 24(%esp),%esi
- movl 28(%esp),%ecx
- subl $32,%esp
- movdqu (%edi),%xmm0
- movd 16(%edi),%xmm1
- andl $-32,%esp
- movdqa 80(%ebp),%xmm3
- movdqu (%esi),%xmm4
- pshufd $27,%xmm0,%xmm0
- movdqu 16(%esi),%xmm5
- pshufd $27,%xmm1,%xmm1
- movdqu 32(%esi),%xmm6
-.byte 102,15,56,0,227
- movdqu 48(%esi),%xmm7
-.byte 102,15,56,0,235
-.byte 102,15,56,0,243
-.byte 102,15,56,0,251
- jmp .L004loop_shaext
-.align 16
-.L004loop_shaext:
- decl %ecx
- leal 64(%esi),%eax
- movdqa %xmm1,(%esp)
- paddd %xmm4,%xmm1
- cmovnel %eax,%esi
- movdqa %xmm0,16(%esp)
-.byte 15,56,201,229
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,0
-.byte 15,56,200,213
- pxor %xmm6,%xmm4
-.byte 15,56,201,238
-.byte 15,56,202,231
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,0
-.byte 15,56,200,206
- pxor %xmm7,%xmm5
-.byte 15,56,202,236
-.byte 15,56,201,247
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,0
-.byte 15,56,200,215
- pxor %xmm4,%xmm6
-.byte 15,56,201,252
-.byte 15,56,202,245
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,0
-.byte 15,56,200,204
- pxor %xmm5,%xmm7
-.byte 15,56,202,254
-.byte 15,56,201,229
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,0
-.byte 15,56,200,213
- pxor %xmm6,%xmm4
-.byte 15,56,201,238
-.byte 15,56,202,231
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,1
-.byte 15,56,200,206
- pxor %xmm7,%xmm5
-.byte 15,56,202,236
-.byte 15,56,201,247
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,1
-.byte 15,56,200,215
- pxor %xmm4,%xmm6
-.byte 15,56,201,252
-.byte 15,56,202,245
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,1
-.byte 15,56,200,204
- pxor %xmm5,%xmm7
-.byte 15,56,202,254
-.byte 15,56,201,229
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,1
-.byte 15,56,200,213
- pxor %xmm6,%xmm4
-.byte 15,56,201,238
-.byte 15,56,202,231
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,1
-.byte 15,56,200,206
- pxor %xmm7,%xmm5
-.byte 15,56,202,236
-.byte 15,56,201,247
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,2
-.byte 15,56,200,215
- pxor %xmm4,%xmm6
-.byte 15,56,201,252
-.byte 15,56,202,245
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,2
-.byte 15,56,200,204
- pxor %xmm5,%xmm7
-.byte 15,56,202,254
-.byte 15,56,201,229
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,2
-.byte 15,56,200,213
- pxor %xmm6,%xmm4
-.byte 15,56,201,238
-.byte 15,56,202,231
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,2
-.byte 15,56,200,206
- pxor %xmm7,%xmm5
-.byte 15,56,202,236
-.byte 15,56,201,247
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,2
-.byte 15,56,200,215
- pxor %xmm4,%xmm6
-.byte 15,56,201,252
-.byte 15,56,202,245
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,3
-.byte 15,56,200,204
- pxor %xmm5,%xmm7
-.byte 15,56,202,254
- movdqu (%esi),%xmm4
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,3
-.byte 15,56,200,213
- movdqu 16(%esi),%xmm5
-.byte 102,15,56,0,227
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,3
-.byte 15,56,200,206
- movdqu 32(%esi),%xmm6
-.byte 102,15,56,0,235
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,3
-.byte 15,56,200,215
- movdqu 48(%esi),%xmm7
-.byte 102,15,56,0,243
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,3
- movdqa (%esp),%xmm2
-.byte 102,15,56,0,251
-.byte 15,56,200,202
- paddd 16(%esp),%xmm0
- jnz .L004loop_shaext
- pshufd $27,%xmm0,%xmm0
- pshufd $27,%xmm1,%xmm1
- movdqu %xmm0,(%edi)
- movd %xmm1,16(%edi)
- movl %ebx,%esp
- popl %edi
- popl %esi
- popl %ebx
- popl %ebp
- ret
-.size _sha1_block_data_order_shaext,.-_sha1_block_data_order_shaext
.hidden _sha1_block_data_order_ssse3
.type _sha1_block_data_order_ssse3,@function
.align 16
@@ -1572,10 +1404,10 @@ _sha1_block_data_order_ssse3:
pushl %ebx
pushl %esi
pushl %edi
- call .L005pic_point
-.L005pic_point:
+ call .L003pic_point
+.L003pic_point:
popl %ebp
- leal .LK_XX_XX-.L005pic_point(%ebp),%ebp
+ leal .LK_XX_XX-.L003pic_point(%ebp),%ebp
.Lssse3_shortcut:
movdqa (%ebp),%xmm7
movdqa 16(%ebp),%xmm0
@@ -1628,9 +1460,9 @@ _sha1_block_data_order_ssse3:
xorl %edx,%ebp
pshufd $238,%xmm0,%xmm4
andl %ebp,%esi
- jmp .L006loop
+ jmp .L004loop
.align 16
-.L006loop:
+.L004loop:
rorl $2,%ebx
xorl %edx,%esi
movl %eax,%ebp
@@ -2533,7 +2365,7 @@ _sha1_block_data_order_ssse3:
addl %edx,%ecx
movl 196(%esp),%ebp
cmpl 200(%esp),%ebp
- je .L007done
+ je .L005done
movdqa 160(%esp),%xmm7
movdqa 176(%esp),%xmm6
movdqu (%ebp),%xmm0
@@ -2668,9 +2500,9 @@ _sha1_block_data_order_ssse3:
pshufd $238,%xmm0,%xmm4
andl %ebx,%esi
movl %ebp,%ebx
- jmp .L006loop
+ jmp .L004loop
.align 16
-.L007done:
+.L005done:
addl 16(%esp),%ebx
xorl %edi,%esi
movl %ecx,%ebp
@@ -2784,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 08d9484..38acbd8 100644
--- a/linux-x86/crypto/sha/sha256-586.S
+++ b/linux-x86/crypto/sha/sha256-586.S
@@ -37,11 +37,10 @@ sha256_block_data_order:
jz .L003no_xmm
andl $1073741824,%ecx
andl $268435968,%ebx
- testl $536870912,%edx
- jnz .L004shaext
orl %ebx,%ecx
andl $1342177280,%ecx
cmpl $1342177280,%ecx
+ je .L004AVX
testl $512,%ebx
jnz .L005SSSE3
.L003no_xmm:
@@ -3167,204 +3166,6 @@ sha256_block_data_order:
popl %ebp
ret
.align 32
-.L004shaext:
- subl $32,%esp
- movdqu (%esi),%xmm1
- leal 128(%ebp),%ebp
- movdqu 16(%esi),%xmm2
- movdqa 128(%ebp),%xmm7
- pshufd $27,%xmm1,%xmm0
- pshufd $177,%xmm1,%xmm1
- pshufd $27,%xmm2,%xmm2
-.byte 102,15,58,15,202,8
- punpcklqdq %xmm0,%xmm2
- jmp .L010loop_shaext
-.align 16
-.L010loop_shaext:
- movdqu (%edi),%xmm3
- movdqu 16(%edi),%xmm4
- movdqu 32(%edi),%xmm5
-.byte 102,15,56,0,223
- movdqu 48(%edi),%xmm6
- movdqa %xmm2,16(%esp)
- movdqa -128(%ebp),%xmm0
- paddd %xmm3,%xmm0
-.byte 102,15,56,0,231
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- nop
- movdqa %xmm1,(%esp)
-.byte 15,56,203,202
- movdqa -112(%ebp),%xmm0
- paddd %xmm4,%xmm0
-.byte 102,15,56,0,239
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- leal 64(%edi),%edi
-.byte 15,56,204,220
-.byte 15,56,203,202
- movdqa -96(%ebp),%xmm0
- paddd %xmm5,%xmm0
-.byte 102,15,56,0,247
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm6,%xmm7
-.byte 102,15,58,15,253,4
- nop
- paddd %xmm7,%xmm3
-.byte 15,56,204,229
-.byte 15,56,203,202
- movdqa -80(%ebp),%xmm0
- paddd %xmm6,%xmm0
-.byte 15,56,205,222
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm3,%xmm7
-.byte 102,15,58,15,254,4
- nop
- paddd %xmm7,%xmm4
-.byte 15,56,204,238
-.byte 15,56,203,202
- movdqa -64(%ebp),%xmm0
- paddd %xmm3,%xmm0
-.byte 15,56,205,227
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm4,%xmm7
-.byte 102,15,58,15,251,4
- nop
- paddd %xmm7,%xmm5
-.byte 15,56,204,243
-.byte 15,56,203,202
- movdqa -48(%ebp),%xmm0
- paddd %xmm4,%xmm0
-.byte 15,56,205,236
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm5,%xmm7
-.byte 102,15,58,15,252,4
- nop
- paddd %xmm7,%xmm6
-.byte 15,56,204,220
-.byte 15,56,203,202
- movdqa -32(%ebp),%xmm0
- paddd %xmm5,%xmm0
-.byte 15,56,205,245
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm6,%xmm7
-.byte 102,15,58,15,253,4
- nop
- paddd %xmm7,%xmm3
-.byte 15,56,204,229
-.byte 15,56,203,202
- movdqa -16(%ebp),%xmm0
- paddd %xmm6,%xmm0
-.byte 15,56,205,222
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm3,%xmm7
-.byte 102,15,58,15,254,4
- nop
- paddd %xmm7,%xmm4
-.byte 15,56,204,238
-.byte 15,56,203,202
- movdqa (%ebp),%xmm0
- paddd %xmm3,%xmm0
-.byte 15,56,205,227
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm4,%xmm7
-.byte 102,15,58,15,251,4
- nop
- paddd %xmm7,%xmm5
-.byte 15,56,204,243
-.byte 15,56,203,202
- movdqa 16(%ebp),%xmm0
- paddd %xmm4,%xmm0
-.byte 15,56,205,236
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm5,%xmm7
-.byte 102,15,58,15,252,4
- nop
- paddd %xmm7,%xmm6
-.byte 15,56,204,220
-.byte 15,56,203,202
- movdqa 32(%ebp),%xmm0
- paddd %xmm5,%xmm0
-.byte 15,56,205,245
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm6,%xmm7
-.byte 102,15,58,15,253,4
- nop
- paddd %xmm7,%xmm3
-.byte 15,56,204,229
-.byte 15,56,203,202
- movdqa 48(%ebp),%xmm0
- paddd %xmm6,%xmm0
-.byte 15,56,205,222
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm3,%xmm7
-.byte 102,15,58,15,254,4
- nop
- paddd %xmm7,%xmm4
-.byte 15,56,204,238
-.byte 15,56,203,202
- movdqa 64(%ebp),%xmm0
- paddd %xmm3,%xmm0
-.byte 15,56,205,227
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm4,%xmm7
-.byte 102,15,58,15,251,4
- nop
- paddd %xmm7,%xmm5
-.byte 15,56,204,243
-.byte 15,56,203,202
- movdqa 80(%ebp),%xmm0
- paddd %xmm4,%xmm0
-.byte 15,56,205,236
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm5,%xmm7
-.byte 102,15,58,15,252,4
-.byte 15,56,203,202
- paddd %xmm7,%xmm6
- movdqa 96(%ebp),%xmm0
- paddd %xmm5,%xmm0
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
-.byte 15,56,205,245
- movdqa 128(%ebp),%xmm7
-.byte 15,56,203,202
- movdqa 112(%ebp),%xmm0
- paddd %xmm6,%xmm0
- nop
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- cmpl %edi,%eax
- nop
-.byte 15,56,203,202
- paddd 16(%esp),%xmm2
- paddd (%esp),%xmm1
- jnz .L010loop_shaext
- pshufd $177,%xmm2,%xmm2
- pshufd $27,%xmm1,%xmm7
- pshufd $177,%xmm1,%xmm1
- punpckhqdq %xmm2,%xmm1
-.byte 102,15,58,15,215,8
- movl 44(%esp),%esp
- movdqu %xmm1,(%esi)
- movdqu %xmm2,16(%esi)
- popl %edi
- popl %esi
- popl %ebx
- popl %ebp
- ret
-.align 32
.L005SSSE3:
leal -96(%esp),%esp
movl (%esi),%eax
@@ -3384,9 +3185,9 @@ sha256_block_data_order:
movl %ecx,24(%esp)
movl %esi,28(%esp)
movdqa 256(%ebp),%xmm7
- jmp .L011grand_ssse3
+ jmp .L010grand_ssse3
.align 16
-.L011grand_ssse3:
+.L010grand_ssse3:
movdqu (%edi),%xmm0
movdqu 16(%edi),%xmm1
movdqu 32(%edi),%xmm2
@@ -3409,9 +3210,9 @@ sha256_block_data_order:
paddd %xmm3,%xmm7
movdqa %xmm6,64(%esp)
movdqa %xmm7,80(%esp)
- jmp .L012ssse3_00_47
+ jmp .L011ssse3_00_47
.align 16
-.L012ssse3_00_47:
+.L011ssse3_00_47:
addl $64,%ebp
movl %edx,%ecx
movdqa %xmm1,%xmm4
@@ -4054,7 +3855,7 @@ sha256_block_data_order:
addl %ecx,%eax
movdqa %xmm6,80(%esp)
cmpl $66051,64(%ebp)
- jne .L012ssse3_00_47
+ jne .L011ssse3_00_47
movl %edx,%ecx
rorl $14,%edx
movl 20(%esp),%esi
@@ -4568,8 +4369,1189 @@ sha256_block_data_order:
movdqa 64(%ebp),%xmm7
subl $192,%ebp
cmpl 104(%esp),%edi
- jb .L011grand_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
diff --git a/linux-x86_64/crypto/bn/modexp512-x86_64.S b/linux-x86_64/crypto/bn/modexp512-x86_64.S
deleted file mode 100644
index e49a2cb..0000000
--- a/linux-x86_64/crypto/bn/modexp512-x86_64.S
+++ /dev/null
@@ -1,1776 +0,0 @@
-#if defined(__x86_64__)
-.text
-
-.type MULADD_128x512,@function
-.align 16
-MULADD_128x512:
- movq 0(%rsi),%rax
- mulq %rbp
- addq %rax,%r8
- adcq $0,%rdx
- movq %r8,0(%rcx)
- movq %rdx,%rbx
-
- movq 8(%rsi),%rax
- mulq %rbp
- addq %rax,%r9
- adcq $0,%rdx
- addq %rbx,%r9
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 16(%rsi),%rax
- mulq %rbp
- addq %rax,%r10
- adcq $0,%rdx
- addq %rbx,%r10
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 24(%rsi),%rax
- mulq %rbp
- addq %rax,%r11
- adcq $0,%rdx
- addq %rbx,%r11
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 32(%rsi),%rax
- mulq %rbp
- addq %rax,%r12
- adcq $0,%rdx
- addq %rbx,%r12
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 40(%rsi),%rax
- mulq %rbp
- addq %rax,%r13
- adcq $0,%rdx
- addq %rbx,%r13
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 48(%rsi),%rax
- mulq %rbp
- addq %rax,%r14
- adcq $0,%rdx
- addq %rbx,%r14
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 56(%rsi),%rax
- mulq %rbp
- addq %rax,%r15
- adcq $0,%rdx
- addq %rbx,%r15
- adcq $0,%rdx
- movq %rdx,%r8
- movq 8(%rdi),%rbp
- movq 0(%rsi),%rax
- mulq %rbp
- addq %rax,%r9
- adcq $0,%rdx
- movq %r9,8(%rcx)
- movq %rdx,%rbx
-
- movq 8(%rsi),%rax
- mulq %rbp
- addq %rax,%r10
- adcq $0,%rdx
- addq %rbx,%r10
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 16(%rsi),%rax
- mulq %rbp
- addq %rax,%r11
- adcq $0,%rdx
- addq %rbx,%r11
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 24(%rsi),%rax
- mulq %rbp
- addq %rax,%r12
- adcq $0,%rdx
- addq %rbx,%r12
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 32(%rsi),%rax
- mulq %rbp
- addq %rax,%r13
- adcq $0,%rdx
- addq %rbx,%r13
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 40(%rsi),%rax
- mulq %rbp
- addq %rax,%r14
- adcq $0,%rdx
- addq %rbx,%r14
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 48(%rsi),%rax
- mulq %rbp
- addq %rax,%r15
- adcq $0,%rdx
- addq %rbx,%r15
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 56(%rsi),%rax
- mulq %rbp
- addq %rax,%r8
- adcq $0,%rdx
- addq %rbx,%r8
- adcq $0,%rdx
- movq %rdx,%r9
- .byte 0xf3,0xc3
-.size MULADD_128x512,.-MULADD_128x512
-.type mont_reduce,@function
-.align 16
-mont_reduce:
- leaq 192(%rsp),%rdi
- movq 32(%rsp),%rsi
- addq $576,%rsi
- leaq 520(%rsp),%rcx
-
- movq 96(%rcx),%rbp
- movq 0(%rsi),%rax
- mulq %rbp
- movq (%rcx),%r8
- addq %rax,%r8
- adcq $0,%rdx
- movq %r8,0(%rdi)
- movq %rdx,%rbx
-
- movq 8(%rsi),%rax
- mulq %rbp
- movq 8(%rcx),%r9
- addq %rax,%r9
- adcq $0,%rdx
- addq %rbx,%r9
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 16(%rsi),%rax
- mulq %rbp
- movq 16(%rcx),%r10
- addq %rax,%r10
- adcq $0,%rdx
- addq %rbx,%r10
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 24(%rsi),%rax
- mulq %rbp
- movq 24(%rcx),%r11
- addq %rax,%r11
- adcq $0,%rdx
- addq %rbx,%r11
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 32(%rsi),%rax
- mulq %rbp
- movq 32(%rcx),%r12
- addq %rax,%r12
- adcq $0,%rdx
- addq %rbx,%r12
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 40(%rsi),%rax
- mulq %rbp
- movq 40(%rcx),%r13
- addq %rax,%r13
- adcq $0,%rdx
- addq %rbx,%r13
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 48(%rsi),%rax
- mulq %rbp
- movq 48(%rcx),%r14
- addq %rax,%r14
- adcq $0,%rdx
- addq %rbx,%r14
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 56(%rsi),%rax
- mulq %rbp
- movq 56(%rcx),%r15
- addq %rax,%r15
- adcq $0,%rdx
- addq %rbx,%r15
- adcq $0,%rdx
- movq %rdx,%r8
- movq 104(%rcx),%rbp
- movq 0(%rsi),%rax
- mulq %rbp
- addq %rax,%r9
- adcq $0,%rdx
- movq %r9,8(%rdi)
- movq %rdx,%rbx
-
- movq 8(%rsi),%rax
- mulq %rbp
- addq %rax,%r10
- adcq $0,%rdx
- addq %rbx,%r10
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 16(%rsi),%rax
- mulq %rbp
- addq %rax,%r11
- adcq $0,%rdx
- addq %rbx,%r11
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 24(%rsi),%rax
- mulq %rbp
- addq %rax,%r12
- adcq $0,%rdx
- addq %rbx,%r12
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 32(%rsi),%rax
- mulq %rbp
- addq %rax,%r13
- adcq $0,%rdx
- addq %rbx,%r13
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 40(%rsi),%rax
- mulq %rbp
- addq %rax,%r14
- adcq $0,%rdx
- addq %rbx,%r14
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 48(%rsi),%rax
- mulq %rbp
- addq %rax,%r15
- adcq $0,%rdx
- addq %rbx,%r15
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 56(%rsi),%rax
- mulq %rbp
- addq %rax,%r8
- adcq $0,%rdx
- addq %rbx,%r8
- adcq $0,%rdx
- movq %rdx,%r9
- movq 112(%rcx),%rbp
- movq 0(%rsi),%rax
- mulq %rbp
- addq %rax,%r10
- adcq $0,%rdx
- movq %r10,16(%rdi)
- movq %rdx,%rbx
-
- movq 8(%rsi),%rax
- mulq %rbp
- addq %rax,%r11
- adcq $0,%rdx
- addq %rbx,%r11
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 16(%rsi),%rax
- mulq %rbp
- addq %rax,%r12
- adcq $0,%rdx
- addq %rbx,%r12
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 24(%rsi),%rax
- mulq %rbp
- addq %rax,%r13
- adcq $0,%rdx
- addq %rbx,%r13
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 32(%rsi),%rax
- mulq %rbp
- addq %rax,%r14
- adcq $0,%rdx
- addq %rbx,%r14
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 40(%rsi),%rax
- mulq %rbp
- addq %rax,%r15
- adcq $0,%rdx
- addq %rbx,%r15
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 48(%rsi),%rax
- mulq %rbp
- addq %rax,%r8
- adcq $0,%rdx
- addq %rbx,%r8
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 56(%rsi),%rax
- mulq %rbp
- addq %rax,%r9
- adcq $0,%rdx
- addq %rbx,%r9
- adcq $0,%rdx
- movq %rdx,%r10
- movq 120(%rcx),%rbp
- movq 0(%rsi),%rax
- mulq %rbp
- addq %rax,%r11
- adcq $0,%rdx
- movq %r11,24(%rdi)
- movq %rdx,%rbx
-
- movq 8(%rsi),%rax
- mulq %rbp
- addq %rax,%r12
- adcq $0,%rdx
- addq %rbx,%r12
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 16(%rsi),%rax
- mulq %rbp
- addq %rax,%r13
- adcq $0,%rdx
- addq %rbx,%r13
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 24(%rsi),%rax
- mulq %rbp
- addq %rax,%r14
- adcq $0,%rdx
- addq %rbx,%r14
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 32(%rsi),%rax
- mulq %rbp
- addq %rax,%r15
- adcq $0,%rdx
- addq %rbx,%r15
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 40(%rsi),%rax
- mulq %rbp
- addq %rax,%r8
- adcq $0,%rdx
- addq %rbx,%r8
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 48(%rsi),%rax
- mulq %rbp
- addq %rax,%r9
- adcq $0,%rdx
- addq %rbx,%r9
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 56(%rsi),%rax
- mulq %rbp
- addq %rax,%r10
- adcq $0,%rdx
- addq %rbx,%r10
- adcq $0,%rdx
- movq %rdx,%r11
- xorq %rax,%rax
-
- addq 64(%rcx),%r8
- adcq 72(%rcx),%r9
- adcq 80(%rcx),%r10
- adcq 88(%rcx),%r11
- adcq $0,%rax
-
-
-
-
- movq %r8,64(%rdi)
- movq %r9,72(%rdi)
- movq %r10,%rbp
- movq %r11,88(%rdi)
-
- movq %rax,384(%rsp)
-
- movq 0(%rdi),%r8
- movq 8(%rdi),%r9
- movq 16(%rdi),%r10
- movq 24(%rdi),%r11
-
-
-
-
-
-
-
-
- addq $80,%rdi
-
- addq $64,%rsi
- leaq 296(%rsp),%rcx
-
- call MULADD_128x512
-
- movq 384(%rsp),%rax
-
-
- addq -16(%rdi),%r8
- adcq -8(%rdi),%r9
- movq %r8,64(%rcx)
- movq %r9,72(%rcx)
-
- adcq %rax,%rax
- movq %rax,384(%rsp)
-
- leaq 192(%rsp),%rdi
- addq $64,%rsi
-
-
-
-
-
- movq (%rsi),%r8
- movq 8(%rsi),%rbx
-
- movq (%rcx),%rax
- mulq %r8
- movq %rax,%rbp
- movq %rdx,%r9
-
- movq 8(%rcx),%rax
- mulq %r8
- addq %rax,%r9
-
- movq (%rcx),%rax
- mulq %rbx
- addq %rax,%r9
-
- movq %r9,8(%rdi)
-
-
- subq $192,%rsi
-
- movq (%rcx),%r8
- movq 8(%rcx),%r9
-
- call MULADD_128x512
-
-
-
-
- movq 0(%rsi),%rax
- movq 8(%rsi),%rbx
- movq 16(%rsi),%rdi
- movq 24(%rsi),%rdx
-
-
- movq 384(%rsp),%rbp
-
- addq 64(%rcx),%r8
- adcq 72(%rcx),%r9
-
-
- adcq %rbp,%rbp
-
-
-
- shlq $3,%rbp
- movq 32(%rsp),%rcx
- addq %rcx,%rbp
-
-
- xorq %rsi,%rsi
-
- addq 0(%rbp),%r10
- adcq 64(%rbp),%r11
- adcq 128(%rbp),%r12
- adcq 192(%rbp),%r13
- adcq 256(%rbp),%r14
- adcq 320(%rbp),%r15
- adcq 384(%rbp),%r8
- adcq 448(%rbp),%r9
-
-
-
- sbbq $0,%rsi
-
-
- andq %rsi,%rax
- andq %rsi,%rbx
- andq %rsi,%rdi
- andq %rsi,%rdx
-
- movq $1,%rbp
- subq %rax,%r10
- sbbq %rbx,%r11
- sbbq %rdi,%r12
- sbbq %rdx,%r13
-
-
-
-
- sbbq $0,%rbp
-
-
-
- addq $512,%rcx
- movq 32(%rcx),%rax
- movq 40(%rcx),%rbx
- movq 48(%rcx),%rdi
- movq 56(%rcx),%rdx
-
-
-
- andq %rsi,%rax
- andq %rsi,%rbx
- andq %rsi,%rdi
- andq %rsi,%rdx
-
-
-
- subq $1,%rbp
-
- sbbq %rax,%r14
- sbbq %rbx,%r15
- sbbq %rdi,%r8
- sbbq %rdx,%r9
-
-
-
- movq 144(%rsp),%rsi
- movq %r10,0(%rsi)
- movq %r11,8(%rsi)
- movq %r12,16(%rsi)
- movq %r13,24(%rsi)
- movq %r14,32(%rsi)
- movq %r15,40(%rsi)
- movq %r8,48(%rsi)
- movq %r9,56(%rsi)
-
- .byte 0xf3,0xc3
-.size mont_reduce,.-mont_reduce
-.type mont_mul_a3b,@function
-.align 16
-mont_mul_a3b:
-
-
-
-
- movq 0(%rdi),%rbp
-
- movq %r10,%rax
- mulq %rbp
- movq %rax,520(%rsp)
- movq %rdx,%r10
- movq %r11,%rax
- mulq %rbp
- addq %rax,%r10
- adcq $0,%rdx
- movq %rdx,%r11
- movq %r12,%rax
- mulq %rbp
- addq %rax,%r11
- adcq $0,%rdx
- movq %rdx,%r12
- movq %r13,%rax
- mulq %rbp
- addq %rax,%r12
- adcq $0,%rdx
- movq %rdx,%r13
- movq %r14,%rax
- mulq %rbp
- addq %rax,%r13
- adcq $0,%rdx
- movq %rdx,%r14
- movq %r15,%rax
- mulq %rbp
- addq %rax,%r14
- adcq $0,%rdx
- movq %rdx,%r15
- movq %r8,%rax
- mulq %rbp
- addq %rax,%r15
- adcq $0,%rdx
- movq %rdx,%r8
- movq %r9,%rax
- mulq %rbp
- addq %rax,%r8
- adcq $0,%rdx
- movq %rdx,%r9
- movq 8(%rdi),%rbp
- movq 0(%rsi),%rax
- mulq %rbp
- addq %rax,%r10
- adcq $0,%rdx
- movq %r10,528(%rsp)
- movq %rdx,%rbx
-
- movq 8(%rsi),%rax
- mulq %rbp
- addq %rax,%r11
- adcq $0,%rdx
- addq %rbx,%r11
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 16(%rsi),%rax
- mulq %rbp
- addq %rax,%r12
- adcq $0,%rdx
- addq %rbx,%r12
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 24(%rsi),%rax
- mulq %rbp
- addq %rax,%r13
- adcq $0,%rdx
- addq %rbx,%r13
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 32(%rsi),%rax
- mulq %rbp
- addq %rax,%r14
- adcq $0,%rdx
- addq %rbx,%r14
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 40(%rsi),%rax
- mulq %rbp
- addq %rax,%r15
- adcq $0,%rdx
- addq %rbx,%r15
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 48(%rsi),%rax
- mulq %rbp
- addq %rax,%r8
- adcq $0,%rdx
- addq %rbx,%r8
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 56(%rsi),%rax
- mulq %rbp
- addq %rax,%r9
- adcq $0,%rdx
- addq %rbx,%r9
- adcq $0,%rdx
- movq %rdx,%r10
- movq 16(%rdi),%rbp
- movq 0(%rsi),%rax
- mulq %rbp
- addq %rax,%r11
- adcq $0,%rdx
- movq %r11,536(%rsp)
- movq %rdx,%rbx
-
- movq 8(%rsi),%rax
- mulq %rbp
- addq %rax,%r12
- adcq $0,%rdx
- addq %rbx,%r12
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 16(%rsi),%rax
- mulq %rbp
- addq %rax,%r13
- adcq $0,%rdx
- addq %rbx,%r13
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 24(%rsi),%rax
- mulq %rbp
- addq %rax,%r14
- adcq $0,%rdx
- addq %rbx,%r14
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 32(%rsi),%rax
- mulq %rbp
- addq %rax,%r15
- adcq $0,%rdx
- addq %rbx,%r15
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 40(%rsi),%rax
- mulq %rbp
- addq %rax,%r8
- adcq $0,%rdx
- addq %rbx,%r8
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 48(%rsi),%rax
- mulq %rbp
- addq %rax,%r9
- adcq $0,%rdx
- addq %rbx,%r9
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 56(%rsi),%rax
- mulq %rbp
- addq %rax,%r10
- adcq $0,%rdx
- addq %rbx,%r10
- adcq $0,%rdx
- movq %rdx,%r11
- movq 24(%rdi),%rbp
- movq 0(%rsi),%rax
- mulq %rbp
- addq %rax,%r12
- adcq $0,%rdx
- movq %r12,544(%rsp)
- movq %rdx,%rbx
-
- movq 8(%rsi),%rax
- mulq %rbp
- addq %rax,%r13
- adcq $0,%rdx
- addq %rbx,%r13
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 16(%rsi),%rax
- mulq %rbp
- addq %rax,%r14
- adcq $0,%rdx
- addq %rbx,%r14
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 24(%rsi),%rax
- mulq %rbp
- addq %rax,%r15
- adcq $0,%rdx
- addq %rbx,%r15
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 32(%rsi),%rax
- mulq %rbp
- addq %rax,%r8
- adcq $0,%rdx
- addq %rbx,%r8
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 40(%rsi),%rax
- mulq %rbp
- addq %rax,%r9
- adcq $0,%rdx
- addq %rbx,%r9
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 48(%rsi),%rax
- mulq %rbp
- addq %rax,%r10
- adcq $0,%rdx
- addq %rbx,%r10
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 56(%rsi),%rax
- mulq %rbp
- addq %rax,%r11
- adcq $0,%rdx
- addq %rbx,%r11
- adcq $0,%rdx
- movq %rdx,%r12
- movq 32(%rdi),%rbp
- movq 0(%rsi),%rax
- mulq %rbp
- addq %rax,%r13
- adcq $0,%rdx
- movq %r13,552(%rsp)
- movq %rdx,%rbx
-
- movq 8(%rsi),%rax
- mulq %rbp
- addq %rax,%r14
- adcq $0,%rdx
- addq %rbx,%r14
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 16(%rsi),%rax
- mulq %rbp
- addq %rax,%r15
- adcq $0,%rdx
- addq %rbx,%r15
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 24(%rsi),%rax
- mulq %rbp
- addq %rax,%r8
- adcq $0,%rdx
- addq %rbx,%r8
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 32(%rsi),%rax
- mulq %rbp
- addq %rax,%r9
- adcq $0,%rdx
- addq %rbx,%r9
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 40(%rsi),%rax
- mulq %rbp
- addq %rax,%r10
- adcq $0,%rdx
- addq %rbx,%r10
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 48(%rsi),%rax
- mulq %rbp
- addq %rax,%r11
- adcq $0,%rdx
- addq %rbx,%r11
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 56(%rsi),%rax
- mulq %rbp
- addq %rax,%r12
- adcq $0,%rdx
- addq %rbx,%r12
- adcq $0,%rdx
- movq %rdx,%r13
- movq 40(%rdi),%rbp
- movq 0(%rsi),%rax
- mulq %rbp
- addq %rax,%r14
- adcq $0,%rdx
- movq %r14,560(%rsp)
- movq %rdx,%rbx
-
- movq 8(%rsi),%rax
- mulq %rbp
- addq %rax,%r15
- adcq $0,%rdx
- addq %rbx,%r15
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 16(%rsi),%rax
- mulq %rbp
- addq %rax,%r8
- adcq $0,%rdx
- addq %rbx,%r8
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 24(%rsi),%rax
- mulq %rbp
- addq %rax,%r9
- adcq $0,%rdx
- addq %rbx,%r9
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 32(%rsi),%rax
- mulq %rbp
- addq %rax,%r10
- adcq $0,%rdx
- addq %rbx,%r10
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 40(%rsi),%rax
- mulq %rbp
- addq %rax,%r11
- adcq $0,%rdx
- addq %rbx,%r11
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 48(%rsi),%rax
- mulq %rbp
- addq %rax,%r12
- adcq $0,%rdx
- addq %rbx,%r12
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 56(%rsi),%rax
- mulq %rbp
- addq %rax,%r13
- adcq $0,%rdx
- addq %rbx,%r13
- adcq $0,%rdx
- movq %rdx,%r14
- movq 48(%rdi),%rbp
- movq 0(%rsi),%rax
- mulq %rbp
- addq %rax,%r15
- adcq $0,%rdx
- movq %r15,568(%rsp)
- movq %rdx,%rbx
-
- movq 8(%rsi),%rax
- mulq %rbp
- addq %rax,%r8
- adcq $0,%rdx
- addq %rbx,%r8
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 16(%rsi),%rax
- mulq %rbp
- addq %rax,%r9
- adcq $0,%rdx
- addq %rbx,%r9
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 24(%rsi),%rax
- mulq %rbp
- addq %rax,%r10
- adcq $0,%rdx
- addq %rbx,%r10
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 32(%rsi),%rax
- mulq %rbp
- addq %rax,%r11
- adcq $0,%rdx
- addq %rbx,%r11
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 40(%rsi),%rax
- mulq %rbp
- addq %rax,%r12
- adcq $0,%rdx
- addq %rbx,%r12
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 48(%rsi),%rax
- mulq %rbp
- addq %rax,%r13
- adcq $0,%rdx
- addq %rbx,%r13
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 56(%rsi),%rax
- mulq %rbp
- addq %rax,%r14
- adcq $0,%rdx
- addq %rbx,%r14
- adcq $0,%rdx
- movq %rdx,%r15
- movq 56(%rdi),%rbp
- movq 0(%rsi),%rax
- mulq %rbp
- addq %rax,%r8
- adcq $0,%rdx
- movq %r8,576(%rsp)
- movq %rdx,%rbx
-
- movq 8(%rsi),%rax
- mulq %rbp
- addq %rax,%r9
- adcq $0,%rdx
- addq %rbx,%r9
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 16(%rsi),%rax
- mulq %rbp
- addq %rax,%r10
- adcq $0,%rdx
- addq %rbx,%r10
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 24(%rsi),%rax
- mulq %rbp
- addq %rax,%r11
- adcq $0,%rdx
- addq %rbx,%r11
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 32(%rsi),%rax
- mulq %rbp
- addq %rax,%r12
- adcq $0,%rdx
- addq %rbx,%r12
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 40(%rsi),%rax
- mulq %rbp
- addq %rax,%r13
- adcq $0,%rdx
- addq %rbx,%r13
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 48(%rsi),%rax
- mulq %rbp
- addq %rax,%r14
- adcq $0,%rdx
- addq %rbx,%r14
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 56(%rsi),%rax
- mulq %rbp
- addq %rax,%r15
- adcq $0,%rdx
- addq %rbx,%r15
- adcq $0,%rdx
- movq %rdx,%r8
- movq %r9,584(%rsp)
- movq %r10,592(%rsp)
- movq %r11,600(%rsp)
- movq %r12,608(%rsp)
- movq %r13,616(%rsp)
- movq %r14,624(%rsp)
- movq %r15,632(%rsp)
- movq %r8,640(%rsp)
-
-
-
-
-
- jmp mont_reduce
-
-
-.size mont_mul_a3b,.-mont_mul_a3b
-.type sqr_reduce,@function
-.align 16
-sqr_reduce:
- movq 16(%rsp),%rcx
-
-
-
- movq %r10,%rbx
-
- movq %r11,%rax
- mulq %rbx
- movq %rax,528(%rsp)
- movq %rdx,%r10
- movq %r12,%rax
- mulq %rbx
- addq %rax,%r10
- adcq $0,%rdx
- movq %rdx,%r11
- movq %r13,%rax
- mulq %rbx
- addq %rax,%r11
- adcq $0,%rdx
- movq %rdx,%r12
- movq %r14,%rax
- mulq %rbx
- addq %rax,%r12
- adcq $0,%rdx
- movq %rdx,%r13
- movq %r15,%rax
- mulq %rbx
- addq %rax,%r13
- adcq $0,%rdx
- movq %rdx,%r14
- movq %r8,%rax
- mulq %rbx
- addq %rax,%r14
- adcq $0,%rdx
- movq %rdx,%r15
- movq %r9,%rax
- mulq %rbx
- addq %rax,%r15
- adcq $0,%rdx
- movq %rdx,%rsi
-
- movq %r10,536(%rsp)
-
-
-
-
-
- movq 8(%rcx),%rbx
-
- movq 16(%rcx),%rax
- mulq %rbx
- addq %rax,%r11
- adcq $0,%rdx
- movq %r11,544(%rsp)
-
- movq %rdx,%r10
- movq 24(%rcx),%rax
- mulq %rbx
- addq %rax,%r12
- adcq $0,%rdx
- addq %r10,%r12
- adcq $0,%rdx
- movq %r12,552(%rsp)
-
- movq %rdx,%r10
- movq 32(%rcx),%rax
- mulq %rbx
- addq %rax,%r13
- adcq $0,%rdx
- addq %r10,%r13
- adcq $0,%rdx
-
- movq %rdx,%r10
- movq 40(%rcx),%rax
- mulq %rbx
- addq %rax,%r14
- adcq $0,%rdx
- addq %r10,%r14
- adcq $0,%rdx
-
- movq %rdx,%r10
- movq %r8,%rax
- mulq %rbx
- addq %rax,%r15
- adcq $0,%rdx
- addq %r10,%r15
- adcq $0,%rdx
-
- movq %rdx,%r10
- movq %r9,%rax
- mulq %rbx
- addq %rax,%rsi
- adcq $0,%rdx
- addq %r10,%rsi
- adcq $0,%rdx
-
- movq %rdx,%r11
-
-
-
-
- movq 16(%rcx),%rbx
-
- movq 24(%rcx),%rax
- mulq %rbx
- addq %rax,%r13
- adcq $0,%rdx
- movq %r13,560(%rsp)
-
- movq %rdx,%r10
- movq 32(%rcx),%rax
- mulq %rbx
- addq %rax,%r14
- adcq $0,%rdx
- addq %r10,%r14
- adcq $0,%rdx
- movq %r14,568(%rsp)
-
- movq %rdx,%r10
- movq 40(%rcx),%rax
- mulq %rbx
- addq %rax,%r15
- adcq $0,%rdx
- addq %r10,%r15
- adcq $0,%rdx
-
- movq %rdx,%r10
- movq %r8,%rax
- mulq %rbx
- addq %rax,%rsi
- adcq $0,%rdx
- addq %r10,%rsi
- adcq $0,%rdx
-
- movq %rdx,%r10
- movq %r9,%rax
- mulq %rbx
- addq %rax,%r11
- adcq $0,%rdx
- addq %r10,%r11
- adcq $0,%rdx
-
- movq %rdx,%r12
-
-
-
-
-
- movq 24(%rcx),%rbx
-
- movq 32(%rcx),%rax
- mulq %rbx
- addq %rax,%r15
- adcq $0,%rdx
- movq %r15,576(%rsp)
-
- movq %rdx,%r10
- movq 40(%rcx),%rax
- mulq %rbx
- addq %rax,%rsi
- adcq $0,%rdx
- addq %r10,%rsi
- adcq $0,%rdx
- movq %rsi,584(%rsp)
-
- movq %rdx,%r10
- movq %r8,%rax
- mulq %rbx
- addq %rax,%r11
- adcq $0,%rdx
- addq %r10,%r11
- adcq $0,%rdx
-
- movq %rdx,%r10
- movq %r9,%rax
- mulq %rbx
- addq %rax,%r12
- adcq $0,%rdx
- addq %r10,%r12
- adcq $0,%rdx
-
- movq %rdx,%r15
-
-
-
-
- movq 32(%rcx),%rbx
-
- movq 40(%rcx),%rax
- mulq %rbx
- addq %rax,%r11
- adcq $0,%rdx
- movq %r11,592(%rsp)
-
- movq %rdx,%r10
- movq %r8,%rax
- mulq %rbx
- addq %rax,%r12
- adcq $0,%rdx
- addq %r10,%r12
- adcq $0,%rdx
- movq %r12,600(%rsp)
-
- movq %rdx,%r10
- movq %r9,%rax
- mulq %rbx
- addq %rax,%r15
- adcq $0,%rdx
- addq %r10,%r15
- adcq $0,%rdx
-
- movq %rdx,%r11
-
-
-
-
- movq 40(%rcx),%rbx
-
- movq %r8,%rax
- mulq %rbx
- addq %rax,%r15
- adcq $0,%rdx
- movq %r15,608(%rsp)
-
- movq %rdx,%r10
- movq %r9,%rax
- mulq %rbx
- addq %rax,%r11
- adcq $0,%rdx
- addq %r10,%r11
- adcq $0,%rdx
- movq %r11,616(%rsp)
-
- movq %rdx,%r12
-
-
-
-
- movq %r8,%rbx
-
- movq %r9,%rax
- mulq %rbx
- addq %rax,%r12
- adcq $0,%rdx
- movq %r12,624(%rsp)
-
- movq %rdx,632(%rsp)
-
-
- movq 528(%rsp),%r10
- movq 536(%rsp),%r11
- movq 544(%rsp),%r12
- movq 552(%rsp),%r13
- movq 560(%rsp),%r14
- movq 568(%rsp),%r15
-
- movq 24(%rcx),%rax
- mulq %rax
- movq %rax,%rdi
- movq %rdx,%r8
-
- addq %r10,%r10
- adcq %r11,%r11
- adcq %r12,%r12
- adcq %r13,%r13
- adcq %r14,%r14
- adcq %r15,%r15
- adcq $0,%r8
-
- movq 0(%rcx),%rax
- mulq %rax
- movq %rax,520(%rsp)
- movq %rdx,%rbx
-
- movq 8(%rcx),%rax
- mulq %rax
-
- addq %rbx,%r10
- adcq %rax,%r11
- adcq $0,%rdx
-
- movq %rdx,%rbx
- movq %r10,528(%rsp)
- movq %r11,536(%rsp)
-
- movq 16(%rcx),%rax
- mulq %rax
-
- addq %rbx,%r12
- adcq %rax,%r13
- adcq $0,%rdx
-
- movq %rdx,%rbx
-
- movq %r12,544(%rsp)
- movq %r13,552(%rsp)
-
- xorq %rbp,%rbp
- addq %rbx,%r14
- adcq %rdi,%r15
- adcq $0,%rbp
-
- movq %r14,560(%rsp)
- movq %r15,568(%rsp)
-
-
-
-
- movq 576(%rsp),%r10
- movq 584(%rsp),%r11
- movq 592(%rsp),%r12
- movq 600(%rsp),%r13
- movq 608(%rsp),%r14
- movq 616(%rsp),%r15
- movq 624(%rsp),%rdi
- movq 632(%rsp),%rsi
-
- movq %r9,%rax
- mulq %rax
- movq %rax,%r9
- movq %rdx,%rbx
-
- addq %r10,%r10
- adcq %r11,%r11
- adcq %r12,%r12
- adcq %r13,%r13
- adcq %r14,%r14
- adcq %r15,%r15
- adcq %rdi,%rdi
- adcq %rsi,%rsi
- adcq $0,%rbx
-
- addq %rbp,%r10
-
- movq 32(%rcx),%rax
- mulq %rax
-
- addq %r8,%r10
- adcq %rax,%r11
- adcq $0,%rdx
-
- movq %rdx,%rbp
-
- movq %r10,576(%rsp)
- movq %r11,584(%rsp)
-
- movq 40(%rcx),%rax
- mulq %rax
-
- addq %rbp,%r12
- adcq %rax,%r13
- adcq $0,%rdx
-
- movq %rdx,%rbp
-
- movq %r12,592(%rsp)
- movq %r13,600(%rsp)
-
- movq 48(%rcx),%rax
- mulq %rax
-
- addq %rbp,%r14
- adcq %rax,%r15
- adcq $0,%rdx
-
- movq %r14,608(%rsp)
- movq %r15,616(%rsp)
-
- addq %rdx,%rdi
- adcq %r9,%rsi
- adcq $0,%rbx
-
- movq %rdi,624(%rsp)
- movq %rsi,632(%rsp)
- movq %rbx,640(%rsp)
-
- jmp mont_reduce
-
-
-.size sqr_reduce,.-sqr_reduce
-.globl mod_exp_512
-.hidden mod_exp_512
-.type mod_exp_512,@function
-mod_exp_512:
- pushq %rbp
- pushq %rbx
- pushq %r12
- pushq %r13
- pushq %r14
- pushq %r15
-
-
- movq %rsp,%r8
- subq $2688,%rsp
- andq $-64,%rsp
-
-
- movq %r8,0(%rsp)
- movq %rdi,8(%rsp)
- movq %rsi,16(%rsp)
- movq %rcx,24(%rsp)
-.Lbody:
-
-
-
- pxor %xmm4,%xmm4
- movdqu 0(%rsi),%xmm0
- movdqu 16(%rsi),%xmm1
- movdqu 32(%rsi),%xmm2
- movdqu 48(%rsi),%xmm3
- movdqa %xmm4,512(%rsp)
- movdqa %xmm4,528(%rsp)
- movdqa %xmm4,608(%rsp)
- movdqa %xmm4,624(%rsp)
- movdqa %xmm0,544(%rsp)
- movdqa %xmm1,560(%rsp)
- movdqa %xmm2,576(%rsp)
- movdqa %xmm3,592(%rsp)
-
-
- movdqu 0(%rdx),%xmm0
- movdqu 16(%rdx),%xmm1
- movdqu 32(%rdx),%xmm2
- movdqu 48(%rdx),%xmm3
-
- leaq 384(%rsp),%rbx
- movq %rbx,136(%rsp)
- call mont_reduce
-
-
- leaq 448(%rsp),%rcx
- xorq %rax,%rax
- movq %rax,0(%rcx)
- movq %rax,8(%rcx)
- movq %rax,24(%rcx)
- movq %rax,32(%rcx)
- movq %rax,40(%rcx)
- movq %rax,48(%rcx)
- movq %rax,56(%rcx)
- movq %rax,128(%rsp)
- movq $1,16(%rcx)
-
- leaq 640(%rsp),%rbp
- movq %rcx,%rsi
- movq %rbp,%rdi
- movq $8,%rax
-loop_0:
- movq (%rcx),%rbx
- movw %bx,(%rdi)
- shrq $16,%rbx
- movw %bx,64(%rdi)
- shrq $16,%rbx
- movw %bx,128(%rdi)
- shrq $16,%rbx
- movw %bx,192(%rdi)
- leaq 8(%rcx),%rcx
- leaq 256(%rdi),%rdi
- decq %rax
- jnz loop_0
- movq $31,%rax
- movq %rax,32(%rsp)
- movq %rbp,40(%rsp)
-
- movq %rsi,136(%rsp)
- movq 0(%rsi),%r10
- movq 8(%rsi),%r11
- movq 16(%rsi),%r12
- movq 24(%rsi),%r13
- movq 32(%rsi),%r14
- movq 40(%rsi),%r15
- movq 48(%rsi),%r8
- movq 56(%rsi),%r9
-init_loop:
- leaq 384(%rsp),%rdi
- call mont_mul_a3b
- leaq 448(%rsp),%rsi
- movq 40(%rsp),%rbp
- addq $2,%rbp
- movq %rbp,40(%rsp)
- movq %rsi,%rcx
- movq $8,%rax
-loop_1:
- movq (%rcx),%rbx
- movw %bx,(%rbp)
- shrq $16,%rbx
- movw %bx,64(%rbp)
- shrq $16,%rbx
- movw %bx,128(%rbp)
- shrq $16,%rbx
- movw %bx,192(%rbp)
- leaq 8(%rcx),%rcx
- leaq 256(%rbp),%rbp
- decq %rax
- jnz loop_1
- movq 32(%rsp),%rax
- subq $1,%rax
- movq %rax,32(%rsp)
- jne init_loop
-
-
-
- movdqa %xmm0,64(%rsp)
- movdqa %xmm1,80(%rsp)
- movdqa %xmm2,96(%rsp)
- movdqa %xmm3,112(%rsp)
-
-
-
-
-
- movl 126(%rsp),%eax
- movq %rax,%rdx
- shrq $11,%rax
- andl $2047,%edx
- movl %edx,126(%rsp)
- leaq 640(%rsp,%rax,2),%rsi
- movq 8(%rsp),%rdx
- movq $4,%rbp
-loop_2:
- movzwq 192(%rsi),%rbx
- movzwq 448(%rsi),%rax
- shlq $16,%rbx
- shlq $16,%rax
- movw 128(%rsi),%bx
- movw 384(%rsi),%ax
- shlq $16,%rbx
- shlq $16,%rax
- movw 64(%rsi),%bx
- movw 320(%rsi),%ax
- shlq $16,%rbx
- shlq $16,%rax
- movw 0(%rsi),%bx
- movw 256(%rsi),%ax
- movq %rbx,0(%rdx)
- movq %rax,8(%rdx)
- leaq 512(%rsi),%rsi
- leaq 16(%rdx),%rdx
- subq $1,%rbp
- jnz loop_2
- movq $505,48(%rsp)
-
- movq 8(%rsp),%rcx
- movq %rcx,136(%rsp)
- movq 0(%rcx),%r10
- movq 8(%rcx),%r11
- movq 16(%rcx),%r12
- movq 24(%rcx),%r13
- movq 32(%rcx),%r14
- movq 40(%rcx),%r15
- movq 48(%rcx),%r8
- movq 56(%rcx),%r9
- jmp sqr_2
-
-main_loop_a3b:
- call sqr_reduce
- call sqr_reduce
- call sqr_reduce
-sqr_2:
- call sqr_reduce
- call sqr_reduce
-
-
-
- movq 48(%rsp),%rcx
- movq %rcx,%rax
- shrq $4,%rax
- movl 64(%rsp,%rax,2),%edx
- andq $15,%rcx
- shrq %cl,%rdx
- andq $31,%rdx
-
- leaq 640(%rsp,%rdx,2),%rsi
- leaq 448(%rsp),%rdx
- movq %rdx,%rdi
- movq $4,%rbp
-loop_3:
- movzwq 192(%rsi),%rbx
- movzwq 448(%rsi),%rax
- shlq $16,%rbx
- shlq $16,%rax
- movw 128(%rsi),%bx
- movw 384(%rsi),%ax
- shlq $16,%rbx
- shlq $16,%rax
- movw 64(%rsi),%bx
- movw 320(%rsi),%ax
- shlq $16,%rbx
- shlq $16,%rax
- movw 0(%rsi),%bx
- movw 256(%rsi),%ax
- movq %rbx,0(%rdx)
- movq %rax,8(%rdx)
- leaq 512(%rsi),%rsi
- leaq 16(%rdx),%rdx
- subq $1,%rbp
- jnz loop_3
- movq 8(%rsp),%rsi
- call mont_mul_a3b
-
-
-
- movq 48(%rsp),%rcx
- subq $5,%rcx
- movq %rcx,48(%rsp)
- jge main_loop_a3b
-
-
-
-end_main_loop_a3b:
-
-
- movq 8(%rsp),%rdx
- pxor %xmm4,%xmm4
- movdqu 0(%rdx),%xmm0
- movdqu 16(%rdx),%xmm1
- movdqu 32(%rdx),%xmm2
- movdqu 48(%rdx),%xmm3
- movdqa %xmm4,576(%rsp)
- movdqa %xmm4,592(%rsp)
- movdqa %xmm4,608(%rsp)
- movdqa %xmm4,624(%rsp)
- movdqa %xmm0,512(%rsp)
- movdqa %xmm1,528(%rsp)
- movdqa %xmm2,544(%rsp)
- movdqa %xmm3,560(%rsp)
- call mont_reduce
-
-
-
- movq 8(%rsp),%rax
- movq 0(%rax),%r8
- movq 8(%rax),%r9
- movq 16(%rax),%r10
- movq 24(%rax),%r11
- movq 32(%rax),%r12
- movq 40(%rax),%r13
- movq 48(%rax),%r14
- movq 56(%rax),%r15
-
-
- movq 24(%rsp),%rbx
- addq $512,%rbx
-
- subq 0(%rbx),%r8
- sbbq 8(%rbx),%r9
- sbbq 16(%rbx),%r10
- sbbq 24(%rbx),%r11
- sbbq 32(%rbx),%r12
- sbbq 40(%rbx),%r13
- sbbq 48(%rbx),%r14
- sbbq 56(%rbx),%r15
-
-
- movq 0(%rax),%rsi
- movq 8(%rax),%rdi
- movq 16(%rax),%rcx
- movq 24(%rax),%rdx
- cmovncq %r8,%rsi
- cmovncq %r9,%rdi
- cmovncq %r10,%rcx
- cmovncq %r11,%rdx
- movq %rsi,0(%rax)
- movq %rdi,8(%rax)
- movq %rcx,16(%rax)
- movq %rdx,24(%rax)
-
- movq 32(%rax),%rsi
- movq 40(%rax),%rdi
- movq 48(%rax),%rcx
- movq 56(%rax),%rdx
- cmovncq %r12,%rsi
- cmovncq %r13,%rdi
- cmovncq %r14,%rcx
- cmovncq %r15,%rdx
- movq %rsi,32(%rax)
- movq %rdi,40(%rax)
- movq %rcx,48(%rax)
- movq %rdx,56(%rax)
-
- movq 0(%rsp),%rsi
- movq 0(%rsi),%r15
- movq 8(%rsi),%r14
- movq 16(%rsi),%r13
- movq 24(%rsi),%r12
- movq 32(%rsi),%rbx
- movq 40(%rsi),%rbp
- leaq 48(%rsi),%rsp
-.Lepilogue:
- .byte 0xf3,0xc3
-.size mod_exp_512, . - mod_exp_512
-#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/cpu-x86_64-asm.S b/linux-x86_64/crypto/cpu-x86_64-asm.S
deleted file mode 100644
index 9eef154..0000000
--- a/linux-x86_64/crypto/cpu-x86_64-asm.S
+++ /dev/null
@@ -1,143 +0,0 @@
-#if defined(__x86_64__)
-.text
-
-.globl OPENSSL_ia32_cpuid
-.hidden OPENSSL_ia32_cpuid
-.type OPENSSL_ia32_cpuid,@function
-.align 16
-OPENSSL_ia32_cpuid:
-
-
- movq %rdi,%rdi
- movq %rbx,%r8
-
- xorl %eax,%eax
- movl %eax,8(%rdi)
- cpuid
- movl %eax,%r11d
-
- xorl %eax,%eax
- cmpl $1970169159,%ebx
- setne %al
- movl %eax,%r9d
- cmpl $1231384169,%edx
- setne %al
- orl %eax,%r9d
- cmpl $1818588270,%ecx
- setne %al
- orl %eax,%r9d
- jz .Lintel
-
- cmpl $1752462657,%ebx
- setne %al
- movl %eax,%r10d
- cmpl $1769238117,%edx
- setne %al
- orl %eax,%r10d
- cmpl $1145913699,%ecx
- setne %al
- orl %eax,%r10d
- jnz .Lintel
-
-
-
-
- movl $2147483648,%eax
- cpuid
-
-
- cmpl $2147483649,%eax
- jb .Lintel
- movl %eax,%r10d
- movl $2147483649,%eax
- cpuid
-
-
- orl %ecx,%r9d
- andl $2049,%r9d
-
- cmpl $2147483656,%r10d
- jb .Lintel
-
- movl $2147483656,%eax
- cpuid
-
- movzbq %cl,%r10
- incq %r10
-
- movl $1,%eax
- cpuid
-
- btl $28,%edx
- jnc .Lgeneric
- shrl $16,%ebx
- cmpb %r10b,%bl
- ja .Lgeneric
- andl $4026531839,%edx
- jmp .Lgeneric
-
-.Lintel:
- cmpl $4,%r11d
- movl $-1,%r10d
- jb .Lnocacheinfo
-
- movl $4,%eax
- movl $0,%ecx
- cpuid
- movl %eax,%r10d
- shrl $14,%r10d
- andl $4095,%r10d
-
- cmpl $7,%r11d
- jb .Lnocacheinfo
-
- movl $7,%eax
- xorl %ecx,%ecx
- cpuid
- movl %ebx,8(%rdi)
-
-.Lnocacheinfo:
- movl $1,%eax
- cpuid
-
- andl $3220176895,%edx
- cmpl $0,%r9d
- jne .Lnotintel
- orl $1073741824,%edx
-.Lnotintel:
- btl $28,%edx
- jnc .Lgeneric
- andl $4026531839,%edx
- cmpl $0,%r10d
- je .Lgeneric
-
- orl $268435456,%edx
- shrl $16,%ebx
- cmpb $1,%bl
- ja .Lgeneric
- andl $4026531839,%edx
-.Lgeneric:
- andl $2048,%r9d
- andl $4294965247,%ecx
- orl %ecx,%r9d
-
- movl %edx,%r10d
- btl $27,%r9d
- jnc .Lclear_avx
- xorl %ecx,%ecx
-.byte 0x0f,0x01,0xd0
- andl $6,%eax
- cmpl $6,%eax
- je .Ldone
-.Lclear_avx:
- movl $4026525695,%eax
- andl %eax,%r9d
- andl $4294967263,8(%rdi)
-.Ldone:
- movl %r9d,4(%rdi)
- movl %r10d,0(%rdi)
- movq %r8,%rbx
- .byte 0xf3,0xc3
-.size OPENSSL_ia32_cpuid,.-OPENSSL_ia32_cpuid
-
-#endif
diff --git a/linux-x86_64/crypto/ec/p256-x86_64-asm.S b/linux-x86_64/crypto/ec/p256-x86_64-asm.S
new file mode 100644
index 0000000..2884c69
--- /dev/null
+++ b/linux-x86_64/crypto/ec/p256-x86_64-asm.S
@@ -0,0 +1,1780 @@
+#if defined(__x86_64__)
+.text
+.extern OPENSSL_ia32cap_P
+.hidden OPENSSL_ia32cap_P
+
+
+.align 64
+.Lpoly:
+.quad 0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001
+
+.LOne:
+.long 1,1,1,1,1,1,1,1
+.LTwo:
+.long 2,2,2,2,2,2,2,2
+.LThree:
+.long 3,3,3,3,3,3,3,3
+.LONE_mont:
+.quad 0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe
+
+.type ecp_nistz256_mul_by_2,@function
+.align 64
+ecp_nistz256_mul_by_2:
+ pushq %r12
+ pushq %r13
+
+ movq 0(%rsi),%r8
+ movq 8(%rsi),%r9
+ addq %r8,%r8
+ movq 16(%rsi),%r10
+ adcq %r9,%r9
+ movq 24(%rsi),%r11
+ leaq .Lpoly(%rip),%rsi
+ movq %r8,%rax
+ adcq %r10,%r10
+ adcq %r11,%r11
+ movq %r9,%rdx
+ sbbq %r13,%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_mul_by_2,.-ecp_nistz256_mul_by_2
+
+
+
+.globl ecp_nistz256_neg
+.hidden ecp_nistz256_neg
+.type ecp_nistz256_neg,@function
+.align 32
+ecp_nistz256_neg:
+ pushq %r12
+ pushq %r13
+
+ xorq %r8,%r8
+ xorq %r9,%r9
+ xorq %r10,%r10
+ xorq %r11,%r11
+ xorq %r13,%r13
+
+ subq 0(%rsi),%r8
+ sbbq 8(%rsi),%r9
+ sbbq 16(%rsi),%r10
+ movq %r8,%rax
+ sbbq 24(%rsi),%r11
+ leaq .Lpoly(%rip),%rsi
+ movq %r9,%rdx
+ sbbq $0,%r13
+
+ addq 0(%rsi),%r8
+ movq %r10,%rcx
+ adcq 8(%rsi),%r9
+ adcq 16(%rsi),%r10
+ movq %r11,%r12
+ adcq 24(%rsi),%r11
+ testq %r13,%r13
+
+ cmovzq %rax,%r8
+ cmovzq %rdx,%r9
+ movq %r8,0(%rdi)
+ cmovzq %rcx,%r10
+ movq %r9,8(%rdi)
+ cmovzq %r12,%r11
+ movq %r10,16(%rdi)
+ movq %r11,24(%rdi)
+
+ popq %r13
+ popq %r12
+ .byte 0xf3,0xc3
+.size ecp_nistz256_neg,.-ecp_nistz256_neg
+
+
+
+
+
+
+.globl ecp_nistz256_mul_mont
+.hidden ecp_nistz256_mul_mont
+.type ecp_nistz256_mul_mont,@function
+.align 32
+ecp_nistz256_mul_mont:
+.Lmul_mont:
+ pushq %rbp
+ pushq %rbx
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ movq %rdx,%rbx
+ movq 0(%rdx),%rax
+ movq 0(%rsi),%r9
+ movq 8(%rsi),%r10
+ movq 16(%rsi),%r11
+ movq 24(%rsi),%r12
+
+ call __ecp_nistz256_mul_montq
+.Lmul_mont_done:
+ popq %r15
+ popq %r14
+ popq %r13
+ popq %r12
+ popq %rbx
+ popq %rbp
+ .byte 0xf3,0xc3
+.size ecp_nistz256_mul_mont,.-ecp_nistz256_mul_mont
+
+.type __ecp_nistz256_mul_montq,@function
+.align 32
+__ecp_nistz256_mul_montq:
+
+
+ movq %rax,%rbp
+ mulq %r9
+ movq .Lpoly+8(%rip),%r14
+ movq %rax,%r8
+ movq %rbp,%rax
+ movq %rdx,%r9
+
+ mulq %r10
+ movq .Lpoly+24(%rip),%r15
+ addq %rax,%r9
+ movq %rbp,%rax
+ adcq $0,%rdx
+ movq %rdx,%r10
+
+ mulq %r11
+ addq %rax,%r10
+ movq %rbp,%rax
+ adcq $0,%rdx
+ movq %rdx,%r11
+
+ mulq %r12
+ addq %rax,%r11
+ movq %r8,%rax
+ adcq $0,%rdx
+ xorq %r13,%r13
+ movq %rdx,%r12
+
+
+
+
+
+
+
+
+
+
+ movq %r8,%rbp
+ shlq $32,%r8
+ mulq %r15
+ shrq $32,%rbp
+ addq %r8,%r9
+ adcq %rbp,%r10
+ adcq %rax,%r11
+ movq 8(%rbx),%rax
+ adcq %rdx,%r12
+ adcq $0,%r13
+ xorq %r8,%r8
+
+
+
+ movq %rax,%rbp
+ mulq 0(%rsi)
+ addq %rax,%r9
+ movq %rbp,%rax
+ adcq $0,%rdx
+ movq %rdx,%rcx
+
+ mulq 8(%rsi)
+ addq %rcx,%r10
+ adcq $0,%rdx
+ addq %rax,%r10
+ movq %rbp,%rax
+ adcq $0,%rdx
+ movq %rdx,%rcx
+
+ mulq 16(%rsi)
+ addq %rcx,%r11
+ adcq $0,%rdx
+ addq %rax,%r11
+ movq %rbp,%rax
+ adcq $0,%rdx
+ movq %rdx,%rcx
+
+ mulq 24(%rsi)
+ addq %rcx,%r12
+ adcq $0,%rdx
+ addq %rax,%r12
+ movq %r9,%rax
+ adcq %rdx,%r13
+ adcq $0,%r8
+
+
+
+ movq %r9,%rbp
+ shlq $32,%r9
+ mulq %r15
+ shrq $32,%rbp
+ addq %r9,%r10
+ adcq %rbp,%r11
+ adcq %rax,%r12
+ movq 16(%rbx),%rax
+ adcq %rdx,%r13
+ adcq $0,%r8
+ xorq %r9,%r9
+
+
+
+ movq %rax,%rbp
+ mulq 0(%rsi)
+ addq %rax,%r10
+ movq %rbp,%rax
+ adcq $0,%rdx
+ movq %rdx,%rcx
+
+ mulq 8(%rsi)
+ addq %rcx,%r11
+ adcq $0,%rdx
+ addq %rax,%r11
+ movq %rbp,%rax
+ adcq $0,%rdx
+ movq %rdx,%rcx
+
+ mulq 16(%rsi)
+ addq %rcx,%r12
+ adcq $0,%rdx
+ addq %rax,%r12
+ movq %rbp,%rax
+ adcq $0,%rdx
+ movq %rdx,%rcx
+
+ mulq 24(%rsi)
+ addq %rcx,%r13
+ adcq $0,%rdx
+ addq %rax,%r13
+ movq %r10,%rax
+ adcq %rdx,%r8
+ adcq $0,%r9
+
+
+
+ movq %r10,%rbp
+ shlq $32,%r10
+ mulq %r15
+ shrq $32,%rbp
+ addq %r10,%r11
+ adcq %rbp,%r12
+ adcq %rax,%r13
+ movq 24(%rbx),%rax
+ adcq %rdx,%r8
+ adcq $0,%r9
+ xorq %r10,%r10
+
+
+
+ movq %rax,%rbp
+ mulq 0(%rsi)
+ addq %rax,%r11
+ movq %rbp,%rax
+ adcq $0,%rdx
+ movq %rdx,%rcx
+
+ mulq 8(%rsi)
+ addq %rcx,%r12
+ adcq $0,%rdx
+ addq %rax,%r12
+ movq %rbp,%rax
+ adcq $0,%rdx
+ movq %rdx,%rcx
+
+ mulq 16(%rsi)
+ addq %rcx,%r13
+ adcq $0,%rdx
+ addq %rax,%r13
+ movq %rbp,%rax
+ adcq $0,%rdx
+ movq %rdx,%rcx
+
+ mulq 24(%rsi)
+ addq %rcx,%r8
+ adcq $0,%rdx
+ addq %rax,%r8
+ movq %r11,%rax
+ adcq %rdx,%r9
+ adcq $0,%r10
+
+
+
+ movq %r11,%rbp
+ shlq $32,%r11
+ mulq %r15
+ shrq $32,%rbp
+ addq %r11,%r12
+ adcq %rbp,%r13
+ movq %r12,%rcx
+ adcq %rax,%r8
+ adcq %rdx,%r9
+ movq %r13,%rbp
+ adcq $0,%r10
+
+
+
+ subq $-1,%r12
+ movq %r8,%rbx
+ sbbq %r14,%r13
+ sbbq $0,%r8
+ movq %r9,%rdx
+ sbbq %r15,%r9
+ sbbq $0,%r10
+
+ cmovcq %rcx,%r12
+ cmovcq %rbp,%r13
+ movq %r12,0(%rdi)
+ cmovcq %rbx,%r8
+ movq %r13,8(%rdi)
+ cmovcq %rdx,%r9
+ movq %r8,16(%rdi)
+ movq %r9,24(%rdi)
+
+ .byte 0xf3,0xc3
+.size __ecp_nistz256_mul_montq,.-__ecp_nistz256_mul_montq
+
+
+
+
+
+
+
+
+.globl ecp_nistz256_sqr_mont
+.hidden ecp_nistz256_sqr_mont
+.type ecp_nistz256_sqr_mont,@function
+.align 32
+ecp_nistz256_sqr_mont:
+ pushq %rbp
+ pushq %rbx
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ movq 0(%rsi),%rax
+ movq 8(%rsi),%r14
+ movq 16(%rsi),%r15
+ movq 24(%rsi),%r8
+
+ call __ecp_nistz256_sqr_montq
+.Lsqr_mont_done:
+ popq %r15
+ popq %r14
+ popq %r13
+ popq %r12
+ popq %rbx
+ popq %rbp
+ .byte 0xf3,0xc3
+.size ecp_nistz256_sqr_mont,.-ecp_nistz256_sqr_mont
+
+.type __ecp_nistz256_sqr_montq,@function
+.align 32
+__ecp_nistz256_sqr_montq:
+ movq %rax,%r13
+ mulq %r14
+ movq %rax,%r9
+ movq %r15,%rax
+ movq %rdx,%r10
+
+ mulq %r13
+ addq %rax,%r10
+ movq %r8,%rax
+ adcq $0,%rdx
+ movq %rdx,%r11
+
+ mulq %r13
+ addq %rax,%r11
+ movq %r15,%rax
+ adcq $0,%rdx
+ movq %rdx,%r12
+
+
+ mulq %r14
+ addq %rax,%r11
+ movq %r8,%rax
+ adcq $0,%rdx
+ movq %rdx,%rbp
+
+ mulq %r14
+ addq %rax,%r12
+ movq %r8,%rax
+ adcq $0,%rdx
+ addq %rbp,%r12
+ movq %rdx,%r13
+ adcq $0,%r13
+
+
+ mulq %r15
+ xorq %r15,%r15
+ addq %rax,%r13
+ movq 0(%rsi),%rax
+ movq %rdx,%r14
+ adcq $0,%r14
+
+ addq %r9,%r9
+ adcq %r10,%r10
+ adcq %r11,%r11
+ adcq %r12,%r12
+ adcq %r13,%r13
+ adcq %r14,%r14
+ adcq $0,%r15
+
+ mulq %rax
+ movq %rax,%r8
+ movq 8(%rsi),%rax
+ movq %rdx,%rcx
+
+ mulq %rax
+ addq %rcx,%r9
+ adcq %rax,%r10
+ movq 16(%rsi),%rax
+ adcq $0,%rdx
+ movq %rdx,%rcx
+
+ mulq %rax
+ addq %rcx,%r11
+ adcq %rax,%r12
+ movq 24(%rsi),%rax
+ adcq $0,%rdx
+ movq %rdx,%rcx
+
+ mulq %rax
+ addq %rcx,%r13
+ adcq %rax,%r14
+ movq %r8,%rax
+ adcq %rdx,%r15
+
+ movq .Lpoly+8(%rip),%rsi
+ movq .Lpoly+24(%rip),%rbp
+
+
+
+
+ movq %r8,%rcx
+ shlq $32,%r8
+ mulq %rbp
+ shrq $32,%rcx
+ addq %r8,%r9
+ adcq %rcx,%r10
+ adcq %rax,%r11
+ movq %r9,%rax
+ adcq $0,%rdx
+
+
+
+ movq %r9,%rcx
+ shlq $32,%r9
+ movq %rdx,%r8
+ mulq %rbp
+ shrq $32,%rcx
+ addq %r9,%r10
+ adcq %rcx,%r11
+ adcq %rax,%r8
+ movq %r10,%rax
+ adcq $0,%rdx
+
+
+
+ movq %r10,%rcx
+ shlq $32,%r10
+ movq %rdx,%r9
+ mulq %rbp
+ shrq $32,%rcx
+ addq %r10,%r11
+ adcq %rcx,%r8
+ adcq %rax,%r9
+ movq %r11,%rax
+ adcq $0,%rdx
+
+
+
+ movq %r11,%rcx
+ shlq $32,%r11
+ movq %rdx,%r10
+ mulq %rbp
+ shrq $32,%rcx
+ addq %r11,%r8
+ adcq %rcx,%r9
+ adcq %rax,%r10
+ adcq $0,%rdx
+ xorq %r11,%r11
+
+
+
+ addq %r8,%r12
+ adcq %r9,%r13
+ movq %r12,%r8
+ adcq %r10,%r14
+ adcq %rdx,%r15
+ movq %r13,%r9
+ adcq $0,%r11
+
+ subq $-1,%r12
+ movq %r14,%r10
+ sbbq %rsi,%r13
+ sbbq $0,%r14
+ movq %r15,%rcx
+ sbbq %rbp,%r15
+ sbbq $0,%r11
+
+ cmovcq %r8,%r12
+ cmovcq %r9,%r13
+ movq %r12,0(%rdi)
+ cmovcq %r10,%r14
+ movq %r13,8(%rdi)
+ cmovcq %rcx,%r15
+ movq %r14,16(%rdi)
+ movq %r15,24(%rdi)
+
+ .byte 0xf3,0xc3
+.size __ecp_nistz256_sqr_montq,.-__ecp_nistz256_sqr_montq
+
+
+
+
+
+
+.globl ecp_nistz256_from_mont
+.hidden ecp_nistz256_from_mont
+.type ecp_nistz256_from_mont,@function
+.align 32
+ecp_nistz256_from_mont:
+ pushq %r12
+ pushq %r13
+
+ movq 0(%rsi),%rax
+ movq .Lpoly+24(%rip),%r13
+ movq 8(%rsi),%r9
+ movq 16(%rsi),%r10
+ movq 24(%rsi),%r11
+ movq %rax,%r8
+ movq .Lpoly+8(%rip),%r12
+
+
+
+ movq %rax,%rcx
+ shlq $32,%r8
+ mulq %r13
+ shrq $32,%rcx
+ addq %r8,%r9
+ adcq %rcx,%r10
+ adcq %rax,%r11
+ movq %r9,%rax
+ adcq $0,%rdx
+
+
+
+ movq %r9,%rcx
+ shlq $32,%r9
+ movq %rdx,%r8
+ mulq %r13
+ shrq $32,%rcx
+ addq %r9,%r10
+ adcq %rcx,%r11
+ adcq %rax,%r8
+ movq %r10,%rax
+ adcq $0,%rdx
+
+
+
+ movq %r10,%rcx
+ shlq $32,%r10
+ movq %rdx,%r9
+ mulq %r13
+ shrq $32,%rcx
+ addq %r10,%r11
+ adcq %rcx,%r8
+ adcq %rax,%r9
+ movq %r11,%rax
+ adcq $0,%rdx
+
+
+
+ movq %r11,%rcx
+ shlq $32,%r11
+ movq %rdx,%r10
+ mulq %r13
+ shrq $32,%rcx
+ addq %r11,%r8
+ adcq %rcx,%r9
+ movq %r8,%rcx
+ adcq %rax,%r10
+ movq %r9,%rsi
+ adcq $0,%rdx
+
+ subq $-1,%r8
+ movq %r10,%rax
+ sbbq %r12,%r9
+ sbbq $0,%r10
+ movq %rdx,%r11
+ sbbq %r13,%rdx
+ sbbq %r13,%r13
+
+ cmovnzq %rcx,%r8
+ cmovnzq %rsi,%r9
+ movq %r8,0(%rdi)
+ cmovnzq %rax,%r10
+ movq %r9,8(%rdi)
+ cmovzq %rdx,%r11
+ movq %r10,16(%rdi)
+ movq %r11,24(%rdi)
+
+ popq %r13
+ popq %r12
+ .byte 0xf3,0xc3
+.size ecp_nistz256_from_mont,.-ecp_nistz256_from_mont
+
+
+.globl ecp_nistz256_select_w5
+.hidden ecp_nistz256_select_w5
+.type ecp_nistz256_select_w5,@function
+.align 32
+ecp_nistz256_select_w5:
+ movdqa .LOne(%rip),%xmm0
+ movd %edx,%xmm1
+
+ pxor %xmm2,%xmm2
+ pxor %xmm3,%xmm3
+ pxor %xmm4,%xmm4
+ pxor %xmm5,%xmm5
+ pxor %xmm6,%xmm6
+ pxor %xmm7,%xmm7
+
+ movdqa %xmm0,%xmm8
+ pshufd $0,%xmm1,%xmm1
+
+ movq $16,%rax
+.Lselect_loop_sse_w5:
+
+ movdqa %xmm8,%xmm15
+ paddd %xmm0,%xmm8
+ pcmpeqd %xmm1,%xmm15
+
+ movdqa 0(%rsi),%xmm9
+ movdqa 16(%rsi),%xmm10
+ movdqa 32(%rsi),%xmm11
+ movdqa 48(%rsi),%xmm12
+ movdqa 64(%rsi),%xmm13
+ movdqa 80(%rsi),%xmm14
+ leaq 96(%rsi),%rsi
+
+ pand %xmm15,%xmm9
+ pand %xmm15,%xmm10
+ por %xmm9,%xmm2
+ pand %xmm15,%xmm11
+ por %xmm10,%xmm3
+ pand %xmm15,%xmm12
+ por %xmm11,%xmm4
+ pand %xmm15,%xmm13
+ por %xmm12,%xmm5
+ pand %xmm15,%xmm14
+ por %xmm13,%xmm6
+ por %xmm14,%xmm7
+
+ decq %rax
+ jnz .Lselect_loop_sse_w5
+
+ movdqu %xmm2,0(%rdi)
+ movdqu %xmm3,16(%rdi)
+ movdqu %xmm4,32(%rdi)
+ movdqu %xmm5,48(%rdi)
+ movdqu %xmm6,64(%rdi)
+ movdqu %xmm7,80(%rdi)
+ .byte 0xf3,0xc3
+.size ecp_nistz256_select_w5,.-ecp_nistz256_select_w5
+
+
+
+.globl ecp_nistz256_select_w7
+.hidden ecp_nistz256_select_w7
+.type ecp_nistz256_select_w7,@function
+.align 32
+ecp_nistz256_select_w7:
+ movdqa .LOne(%rip),%xmm8
+ movd %edx,%xmm1
+
+ pxor %xmm2,%xmm2
+ pxor %xmm3,%xmm3
+ pxor %xmm4,%xmm4
+ pxor %xmm5,%xmm5
+
+ movdqa %xmm8,%xmm0
+ pshufd $0,%xmm1,%xmm1
+ movq $64,%rax
+
+.Lselect_loop_sse_w7:
+ movdqa %xmm8,%xmm15
+ paddd %xmm0,%xmm8
+ movdqa 0(%rsi),%xmm9
+ movdqa 16(%rsi),%xmm10
+ pcmpeqd %xmm1,%xmm15
+ movdqa 32(%rsi),%xmm11
+ movdqa 48(%rsi),%xmm12
+ leaq 64(%rsi),%rsi
+
+ pand %xmm15,%xmm9
+ pand %xmm15,%xmm10
+ por %xmm9,%xmm2
+ pand %xmm15,%xmm11
+ por %xmm10,%xmm3
+ pand %xmm15,%xmm12
+ por %xmm11,%xmm4
+ prefetcht0 255(%rsi)
+ por %xmm12,%xmm5
+
+ decq %rax
+ jnz .Lselect_loop_sse_w7
+
+ movdqu %xmm2,0(%rdi)
+ movdqu %xmm3,16(%rdi)
+ movdqu %xmm4,32(%rdi)
+ movdqu %xmm5,48(%rdi)
+ .byte 0xf3,0xc3
+.size ecp_nistz256_select_w7,.-ecp_nistz256_select_w7
+.globl ecp_nistz256_avx2_select_w7
+.hidden ecp_nistz256_avx2_select_w7
+.type ecp_nistz256_avx2_select_w7,@function
+.align 32
+ecp_nistz256_avx2_select_w7:
+.byte 0x0f,0x0b
+ .byte 0xf3,0xc3
+.size ecp_nistz256_avx2_select_w7,.-ecp_nistz256_avx2_select_w7
+.type __ecp_nistz256_add_toq,@function
+.align 32
+__ecp_nistz256_add_toq:
+ addq 0(%rbx),%r12
+ adcq 8(%rbx),%r13
+ movq %r12,%rax
+ adcq 16(%rbx),%r8
+ adcq 24(%rbx),%r9
+ movq %r13,%rbp
+ sbbq %r11,%r11
+
+ subq $-1,%r12
+ movq %r8,%rcx
+ sbbq %r14,%r13
+ sbbq $0,%r8
+ movq %r9,%r10
+ sbbq %r15,%r9
+ testq %r11,%r11
+
+ cmovzq %rax,%r12
+ cmovzq %rbp,%r13
+ movq %r12,0(%rdi)
+ cmovzq %rcx,%r8
+ movq %r13,8(%rdi)
+ cmovzq %r10,%r9
+ movq %r8,16(%rdi)
+ movq %r9,24(%rdi)
+
+ .byte 0xf3,0xc3
+.size __ecp_nistz256_add_toq,.-__ecp_nistz256_add_toq
+
+.type __ecp_nistz256_sub_fromq,@function
+.align 32
+__ecp_nistz256_sub_fromq:
+ subq 0(%rbx),%r12
+ sbbq 8(%rbx),%r13
+ movq %r12,%rax
+ sbbq 16(%rbx),%r8
+ sbbq 24(%rbx),%r9
+ movq %r13,%rbp
+ sbbq %r11,%r11
+
+ addq $-1,%r12
+ movq %r8,%rcx
+ adcq %r14,%r13
+ adcq $0,%r8
+ movq %r9,%r10
+ adcq %r15,%r9
+ testq %r11,%r11
+
+ cmovzq %rax,%r12
+ cmovzq %rbp,%r13
+ movq %r12,0(%rdi)
+ cmovzq %rcx,%r8
+ movq %r13,8(%rdi)
+ cmovzq %r10,%r9
+ movq %r8,16(%rdi)
+ movq %r9,24(%rdi)
+
+ .byte 0xf3,0xc3
+.size __ecp_nistz256_sub_fromq,.-__ecp_nistz256_sub_fromq
+
+.type __ecp_nistz256_subq,@function
+.align 32
+__ecp_nistz256_subq:
+ subq %r12,%rax
+ sbbq %r13,%rbp
+ movq %rax,%r12
+ sbbq %r8,%rcx
+ sbbq %r9,%r10
+ movq %rbp,%r13
+ sbbq %r11,%r11
+
+ addq $-1,%rax
+ movq %rcx,%r8
+ adcq %r14,%rbp
+ adcq $0,%rcx
+ movq %r10,%r9
+ adcq %r15,%r10
+ testq %r11,%r11
+
+ cmovnzq %rax,%r12
+ cmovnzq %rbp,%r13
+ cmovnzq %rcx,%r8
+ cmovnzq %r10,%r9
+
+ .byte 0xf3,0xc3
+.size __ecp_nistz256_subq,.-__ecp_nistz256_subq
+
+.type __ecp_nistz256_mul_by_2q,@function
+.align 32
+__ecp_nistz256_mul_by_2q:
+ addq %r12,%r12
+ adcq %r13,%r13
+ movq %r12,%rax
+ adcq %r8,%r8
+ adcq %r9,%r9
+ movq %r13,%rbp
+ sbbq %r11,%r11
+
+ subq $-1,%r12
+ movq %r8,%rcx
+ sbbq %r14,%r13
+ sbbq $0,%r8
+ movq %r9,%r10
+ sbbq %r15,%r9
+ testq %r11,%r11
+
+ cmovzq %rax,%r12
+ cmovzq %rbp,%r13
+ movq %r12,0(%rdi)
+ cmovzq %rcx,%r8
+ movq %r13,8(%rdi)
+ cmovzq %r10,%r9
+ movq %r8,16(%rdi)
+ movq %r9,24(%rdi)
+
+ .byte 0xf3,0xc3
+.size __ecp_nistz256_mul_by_2q,.-__ecp_nistz256_mul_by_2q
+.globl ecp_nistz256_point_double
+.hidden ecp_nistz256_point_double
+.type ecp_nistz256_point_double,@function
+.align 32
+ecp_nistz256_point_double:
+ pushq %rbp
+ pushq %rbx
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ subq $160+8,%rsp
+
+ movdqu 0(%rsi),%xmm0
+ movq %rsi,%rbx
+ movdqu 16(%rsi),%xmm1
+ movq 32+0(%rsi),%r12
+ movq 32+8(%rsi),%r13
+ movq 32+16(%rsi),%r8
+ movq 32+24(%rsi),%r9
+ movq .Lpoly+8(%rip),%r14
+ movq .Lpoly+24(%rip),%r15
+ movdqa %xmm0,96(%rsp)
+ movdqa %xmm1,96+16(%rsp)
+ leaq 32(%rdi),%r10
+ leaq 64(%rdi),%r11
+.byte 102,72,15,110,199
+.byte 102,73,15,110,202
+.byte 102,73,15,110,211
+
+ leaq 0(%rsp),%rdi
+ call __ecp_nistz256_mul_by_2q
+
+ movq 64+0(%rsi),%rax
+ movq 64+8(%rsi),%r14
+ movq 64+16(%rsi),%r15
+ movq 64+24(%rsi),%r8
+ leaq 64-0(%rsi),%rsi
+ leaq 64(%rsp),%rdi
+ call __ecp_nistz256_sqr_montq
+
+ movq 0+0(%rsp),%rax
+ movq 8+0(%rsp),%r14
+ leaq 0+0(%rsp),%rsi
+ movq 16+0(%rsp),%r15
+ movq 24+0(%rsp),%r8
+ leaq 0(%rsp),%rdi
+ call __ecp_nistz256_sqr_montq
+
+ movq 32(%rbx),%rax
+ movq 64+0(%rbx),%r9
+ movq 64+8(%rbx),%r10
+ movq 64+16(%rbx),%r11
+ movq 64+24(%rbx),%r12
+ leaq 64-0(%rbx),%rsi
+ leaq 32(%rbx),%rbx
+.byte 102,72,15,126,215
+ call __ecp_nistz256_mul_montq
+ call __ecp_nistz256_mul_by_2q
+
+ movq 96+0(%rsp),%r12
+ movq 96+8(%rsp),%r13
+ leaq 64(%rsp),%rbx
+ movq 96+16(%rsp),%r8
+ movq 96+24(%rsp),%r9
+ leaq 32(%rsp),%rdi
+ call __ecp_nistz256_add_toq
+
+ movq 96+0(%rsp),%r12
+ movq 96+8(%rsp),%r13
+ leaq 64(%rsp),%rbx
+ movq 96+16(%rsp),%r8
+ movq 96+24(%rsp),%r9
+ leaq 64(%rsp),%rdi
+ call __ecp_nistz256_sub_fromq
+
+ movq 0+0(%rsp),%rax
+ movq 8+0(%rsp),%r14
+ leaq 0+0(%rsp),%rsi
+ movq 16+0(%rsp),%r15
+ movq 24+0(%rsp),%r8
+.byte 102,72,15,126,207
+ call __ecp_nistz256_sqr_montq
+ xorq %r9,%r9
+ movq %r12,%rax
+ addq $-1,%r12
+ movq %r13,%r10
+ adcq %rsi,%r13
+ movq %r14,%rcx
+ adcq $0,%r14
+ movq %r15,%r8
+ adcq %rbp,%r15
+ adcq $0,%r9
+ xorq %rsi,%rsi
+ testq $1,%rax
+
+ cmovzq %rax,%r12
+ cmovzq %r10,%r13
+ cmovzq %rcx,%r14
+ cmovzq %r8,%r15
+ cmovzq %rsi,%r9
+
+ movq %r13,%rax
+ shrq $1,%r12
+ shlq $63,%rax
+ movq %r14,%r10
+ shrq $1,%r13
+ orq %rax,%r12
+ shlq $63,%r10
+ movq %r15,%rcx
+ shrq $1,%r14
+ orq %r10,%r13
+ shlq $63,%rcx
+ movq %r12,0(%rdi)
+ shrq $1,%r15
+ movq %r13,8(%rdi)
+ shlq $63,%r9
+ orq %rcx,%r14
+ orq %r9,%r15
+ movq %r14,16(%rdi)
+ movq %r15,24(%rdi)
+ movq 64(%rsp),%rax
+ leaq 64(%rsp),%rbx
+ movq 0+32(%rsp),%r9
+ movq 8+32(%rsp),%r10
+ leaq 0+32(%rsp),%rsi
+ movq 16+32(%rsp),%r11
+ movq 24+32(%rsp),%r12
+ leaq 32(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ leaq 128(%rsp),%rdi
+ call __ecp_nistz256_mul_by_2q
+
+ leaq 32(%rsp),%rbx
+ leaq 32(%rsp),%rdi
+ call __ecp_nistz256_add_toq
+
+ movq 96(%rsp),%rax
+ leaq 96(%rsp),%rbx
+ movq 0+0(%rsp),%r9
+ movq 8+0(%rsp),%r10
+ leaq 0+0(%rsp),%rsi
+ movq 16+0(%rsp),%r11
+ movq 24+0(%rsp),%r12
+ leaq 0(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ leaq 128(%rsp),%rdi
+ call __ecp_nistz256_mul_by_2q
+
+ movq 0+32(%rsp),%rax
+ movq 8+32(%rsp),%r14
+ leaq 0+32(%rsp),%rsi
+ movq 16+32(%rsp),%r15
+ movq 24+32(%rsp),%r8
+.byte 102,72,15,126,199
+ call __ecp_nistz256_sqr_montq
+
+ leaq 128(%rsp),%rbx
+ movq %r14,%r8
+ movq %r15,%r9
+ movq %rsi,%r14
+ movq %rbp,%r15
+ call __ecp_nistz256_sub_fromq
+
+ movq 0+0(%rsp),%rax
+ movq 0+8(%rsp),%rbp
+ movq 0+16(%rsp),%rcx
+ movq 0+24(%rsp),%r10
+ leaq 0(%rsp),%rdi
+ call __ecp_nistz256_subq
+
+ movq 32(%rsp),%rax
+ leaq 32(%rsp),%rbx
+ movq %r12,%r14
+ xorl %ecx,%ecx
+ movq %r12,0+0(%rsp)
+ movq %r13,%r10
+ movq %r13,0+8(%rsp)
+ cmovzq %r8,%r11
+ movq %r8,0+16(%rsp)
+ leaq 0-0(%rsp),%rsi
+ cmovzq %r9,%r12
+ movq %r9,0+24(%rsp)
+ movq %r14,%r9
+ leaq 0(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+.byte 102,72,15,126,203
+.byte 102,72,15,126,207
+ call __ecp_nistz256_sub_fromq
+
+ addq $160+8,%rsp
+ popq %r15
+ popq %r14
+ popq %r13
+ popq %r12
+ popq %rbx
+ popq %rbp
+ .byte 0xf3,0xc3
+.size ecp_nistz256_point_double,.-ecp_nistz256_point_double
+.globl ecp_nistz256_point_add
+.hidden ecp_nistz256_point_add
+.type ecp_nistz256_point_add,@function
+.align 32
+ecp_nistz256_point_add:
+ pushq %rbp
+ pushq %rbx
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ subq $576+8,%rsp
+
+ movdqu 0(%rsi),%xmm0
+ movdqu 16(%rsi),%xmm1
+ movdqu 32(%rsi),%xmm2
+ movdqu 48(%rsi),%xmm3
+ movdqu 64(%rsi),%xmm4
+ movdqu 80(%rsi),%xmm5
+ movq %rsi,%rbx
+ movq %rdx,%rsi
+ movdqa %xmm0,384(%rsp)
+ movdqa %xmm1,384+16(%rsp)
+ por %xmm0,%xmm1
+ movdqa %xmm2,416(%rsp)
+ movdqa %xmm3,416+16(%rsp)
+ por %xmm2,%xmm3
+ movdqa %xmm4,448(%rsp)
+ movdqa %xmm5,448+16(%rsp)
+ por %xmm1,%xmm3
+
+ movdqu 0(%rsi),%xmm0
+ pshufd $177,%xmm3,%xmm5
+ movdqu 16(%rsi),%xmm1
+ movdqu 32(%rsi),%xmm2
+ por %xmm3,%xmm5
+ movdqu 48(%rsi),%xmm3
+ movq 64+0(%rsi),%rax
+ movq 64+8(%rsi),%r14
+ movq 64+16(%rsi),%r15
+ movq 64+24(%rsi),%r8
+ movdqa %xmm0,480(%rsp)
+ pshufd $30,%xmm5,%xmm4
+ movdqa %xmm1,480+16(%rsp)
+ por %xmm0,%xmm1
+.byte 102,72,15,110,199
+ movdqa %xmm2,512(%rsp)
+ movdqa %xmm3,512+16(%rsp)
+ por %xmm2,%xmm3
+ por %xmm4,%xmm5
+ pxor %xmm4,%xmm4
+ por %xmm1,%xmm3
+
+ leaq 64-0(%rsi),%rsi
+ movq %rax,544+0(%rsp)
+ movq %r14,544+8(%rsp)
+ movq %r15,544+16(%rsp)
+ movq %r8,544+24(%rsp)
+ leaq 96(%rsp),%rdi
+ call __ecp_nistz256_sqr_montq
+
+ pcmpeqd %xmm4,%xmm5
+ pshufd $177,%xmm3,%xmm4
+ por %xmm3,%xmm4
+ pshufd $0,%xmm5,%xmm5
+ pshufd $30,%xmm4,%xmm3
+ por %xmm3,%xmm4
+ pxor %xmm3,%xmm3
+ pcmpeqd %xmm3,%xmm4
+ pshufd $0,%xmm4,%xmm4
+ movq 64+0(%rbx),%rax
+ movq 64+8(%rbx),%r14
+ movq 64+16(%rbx),%r15
+ movq 64+24(%rbx),%r8
+
+ leaq 64-0(%rbx),%rsi
+ leaq 32(%rsp),%rdi
+ call __ecp_nistz256_sqr_montq
+
+ movq 544(%rsp),%rax
+ leaq 544(%rsp),%rbx
+ movq 0+96(%rsp),%r9
+ movq 8+96(%rsp),%r10
+ leaq 0+96(%rsp),%rsi
+ movq 16+96(%rsp),%r11
+ movq 24+96(%rsp),%r12
+ leaq 224(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ movq 448(%rsp),%rax
+ leaq 448(%rsp),%rbx
+ movq 0+32(%rsp),%r9
+ movq 8+32(%rsp),%r10
+ leaq 0+32(%rsp),%rsi
+ movq 16+32(%rsp),%r11
+ movq 24+32(%rsp),%r12
+ leaq 256(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ movq 416(%rsp),%rax
+ leaq 416(%rsp),%rbx
+ movq 0+224(%rsp),%r9
+ movq 8+224(%rsp),%r10
+ leaq 0+224(%rsp),%rsi
+ movq 16+224(%rsp),%r11
+ movq 24+224(%rsp),%r12
+ leaq 224(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ movq 512(%rsp),%rax
+ leaq 512(%rsp),%rbx
+ movq 0+256(%rsp),%r9
+ movq 8+256(%rsp),%r10
+ leaq 0+256(%rsp),%rsi
+ movq 16+256(%rsp),%r11
+ movq 24+256(%rsp),%r12
+ leaq 256(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ leaq 224(%rsp),%rbx
+ leaq 64(%rsp),%rdi
+ call __ecp_nistz256_sub_fromq
+
+ orq %r13,%r12
+ movdqa %xmm4,%xmm2
+ orq %r8,%r12
+ orq %r9,%r12
+ por %xmm5,%xmm2
+.byte 102,73,15,110,220
+
+ movq 384(%rsp),%rax
+ leaq 384(%rsp),%rbx
+ movq 0+96(%rsp),%r9
+ movq 8+96(%rsp),%r10
+ leaq 0+96(%rsp),%rsi
+ movq 16+96(%rsp),%r11
+ movq 24+96(%rsp),%r12
+ leaq 160(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ movq 480(%rsp),%rax
+ leaq 480(%rsp),%rbx
+ movq 0+32(%rsp),%r9
+ movq 8+32(%rsp),%r10
+ leaq 0+32(%rsp),%rsi
+ movq 16+32(%rsp),%r11
+ movq 24+32(%rsp),%r12
+ leaq 192(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ leaq 160(%rsp),%rbx
+ leaq 0(%rsp),%rdi
+ call __ecp_nistz256_sub_fromq
+
+ orq %r13,%r12
+ orq %r8,%r12
+ orq %r9,%r12
+
+.byte 0x3e
+ jnz .Ladd_proceedq
+.byte 102,73,15,126,208
+.byte 102,73,15,126,217
+ testq %r8,%r8
+ jnz .Ladd_proceedq
+ testq %r9,%r9
+ jz .Ladd_proceedq
+
+.byte 102,72,15,126,199
+ pxor %xmm0,%xmm0
+ movdqu %xmm0,0(%rdi)
+ movdqu %xmm0,16(%rdi)
+ movdqu %xmm0,32(%rdi)
+ movdqu %xmm0,48(%rdi)
+ movdqu %xmm0,64(%rdi)
+ movdqu %xmm0,80(%rdi)
+ jmp .Ladd_doneq
+
+.align 32
+.Ladd_proceedq:
+ movq 0+64(%rsp),%rax
+ movq 8+64(%rsp),%r14
+ leaq 0+64(%rsp),%rsi
+ movq 16+64(%rsp),%r15
+ movq 24+64(%rsp),%r8
+ leaq 96(%rsp),%rdi
+ call __ecp_nistz256_sqr_montq
+
+ movq 448(%rsp),%rax
+ leaq 448(%rsp),%rbx
+ movq 0+0(%rsp),%r9
+ movq 8+0(%rsp),%r10
+ leaq 0+0(%rsp),%rsi
+ movq 16+0(%rsp),%r11
+ movq 24+0(%rsp),%r12
+ leaq 352(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ movq 0+0(%rsp),%rax
+ movq 8+0(%rsp),%r14
+ leaq 0+0(%rsp),%rsi
+ movq 16+0(%rsp),%r15
+ movq 24+0(%rsp),%r8
+ leaq 32(%rsp),%rdi
+ call __ecp_nistz256_sqr_montq
+
+ movq 544(%rsp),%rax
+ leaq 544(%rsp),%rbx
+ movq 0+352(%rsp),%r9
+ movq 8+352(%rsp),%r10
+ leaq 0+352(%rsp),%rsi
+ movq 16+352(%rsp),%r11
+ movq 24+352(%rsp),%r12
+ leaq 352(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ movq 0(%rsp),%rax
+ leaq 0(%rsp),%rbx
+ movq 0+32(%rsp),%r9
+ movq 8+32(%rsp),%r10
+ leaq 0+32(%rsp),%rsi
+ movq 16+32(%rsp),%r11
+ movq 24+32(%rsp),%r12
+ leaq 128(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ movq 160(%rsp),%rax
+ leaq 160(%rsp),%rbx
+ movq 0+32(%rsp),%r9
+ movq 8+32(%rsp),%r10
+ leaq 0+32(%rsp),%rsi
+ movq 16+32(%rsp),%r11
+ movq 24+32(%rsp),%r12
+ leaq 192(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+
+
+
+ addq %r12,%r12
+ leaq 96(%rsp),%rsi
+ adcq %r13,%r13
+ movq %r12,%rax
+ adcq %r8,%r8
+ adcq %r9,%r9
+ movq %r13,%rbp
+ sbbq %r11,%r11
+
+ subq $-1,%r12
+ movq %r8,%rcx
+ sbbq %r14,%r13
+ sbbq $0,%r8
+ movq %r9,%r10
+ sbbq %r15,%r9
+ testq %r11,%r11
+
+ cmovzq %rax,%r12
+ movq 0(%rsi),%rax
+ cmovzq %rbp,%r13
+ movq 8(%rsi),%rbp
+ cmovzq %rcx,%r8
+ movq 16(%rsi),%rcx
+ cmovzq %r10,%r9
+ movq 24(%rsi),%r10
+
+ call __ecp_nistz256_subq
+
+ leaq 128(%rsp),%rbx
+ leaq 288(%rsp),%rdi
+ call __ecp_nistz256_sub_fromq
+
+ movq 192+0(%rsp),%rax
+ movq 192+8(%rsp),%rbp
+ movq 192+16(%rsp),%rcx
+ movq 192+24(%rsp),%r10
+ leaq 320(%rsp),%rdi
+
+ call __ecp_nistz256_subq
+
+ movq %r12,0(%rdi)
+ movq %r13,8(%rdi)
+ movq %r8,16(%rdi)
+ movq %r9,24(%rdi)
+ movq 128(%rsp),%rax
+ leaq 128(%rsp),%rbx
+ movq 0+224(%rsp),%r9
+ movq 8+224(%rsp),%r10
+ leaq 0+224(%rsp),%rsi
+ movq 16+224(%rsp),%r11
+ movq 24+224(%rsp),%r12
+ leaq 256(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ movq 320(%rsp),%rax
+ leaq 320(%rsp),%rbx
+ movq 0+64(%rsp),%r9
+ movq 8+64(%rsp),%r10
+ leaq 0+64(%rsp),%rsi
+ movq 16+64(%rsp),%r11
+ movq 24+64(%rsp),%r12
+ leaq 320(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ leaq 256(%rsp),%rbx
+ leaq 320(%rsp),%rdi
+ call __ecp_nistz256_sub_fromq
+
+.byte 102,72,15,126,199
+
+ movdqa %xmm5,%xmm0
+ movdqa %xmm5,%xmm1
+ pandn 352(%rsp),%xmm0
+ movdqa %xmm5,%xmm2
+ pandn 352+16(%rsp),%xmm1
+ movdqa %xmm5,%xmm3
+ pand 544(%rsp),%xmm2
+ pand 544+16(%rsp),%xmm3
+ por %xmm0,%xmm2
+ por %xmm1,%xmm3
+
+ movdqa %xmm4,%xmm0
+ movdqa %xmm4,%xmm1
+ pandn %xmm2,%xmm0
+ movdqa %xmm4,%xmm2
+ pandn %xmm3,%xmm1
+ movdqa %xmm4,%xmm3
+ pand 448(%rsp),%xmm2
+ pand 448+16(%rsp),%xmm3
+ por %xmm0,%xmm2
+ por %xmm1,%xmm3
+ movdqu %xmm2,64(%rdi)
+ movdqu %xmm3,80(%rdi)
+
+ movdqa %xmm5,%xmm0
+ movdqa %xmm5,%xmm1
+ pandn 288(%rsp),%xmm0
+ movdqa %xmm5,%xmm2
+ pandn 288+16(%rsp),%xmm1
+ movdqa %xmm5,%xmm3
+ pand 480(%rsp),%xmm2
+ pand 480+16(%rsp),%xmm3
+ por %xmm0,%xmm2
+ por %xmm1,%xmm3
+
+ movdqa %xmm4,%xmm0
+ movdqa %xmm4,%xmm1
+ pandn %xmm2,%xmm0
+ movdqa %xmm4,%xmm2
+ pandn %xmm3,%xmm1
+ movdqa %xmm4,%xmm3
+ pand 384(%rsp),%xmm2
+ pand 384+16(%rsp),%xmm3
+ por %xmm0,%xmm2
+ por %xmm1,%xmm3
+ movdqu %xmm2,0(%rdi)
+ movdqu %xmm3,16(%rdi)
+
+ movdqa %xmm5,%xmm0
+ movdqa %xmm5,%xmm1
+ pandn 320(%rsp),%xmm0
+ movdqa %xmm5,%xmm2
+ pandn 320+16(%rsp),%xmm1
+ movdqa %xmm5,%xmm3
+ pand 512(%rsp),%xmm2
+ pand 512+16(%rsp),%xmm3
+ por %xmm0,%xmm2
+ por %xmm1,%xmm3
+
+ movdqa %xmm4,%xmm0
+ movdqa %xmm4,%xmm1
+ pandn %xmm2,%xmm0
+ movdqa %xmm4,%xmm2
+ pandn %xmm3,%xmm1
+ movdqa %xmm4,%xmm3
+ pand 416(%rsp),%xmm2
+ pand 416+16(%rsp),%xmm3
+ por %xmm0,%xmm2
+ por %xmm1,%xmm3
+ movdqu %xmm2,32(%rdi)
+ movdqu %xmm3,48(%rdi)
+
+.Ladd_doneq:
+ addq $576+8,%rsp
+ popq %r15
+ popq %r14
+ popq %r13
+ popq %r12
+ popq %rbx
+ popq %rbp
+ .byte 0xf3,0xc3
+.size ecp_nistz256_point_add,.-ecp_nistz256_point_add
+.globl ecp_nistz256_point_add_affine
+.hidden ecp_nistz256_point_add_affine
+.type ecp_nistz256_point_add_affine,@function
+.align 32
+ecp_nistz256_point_add_affine:
+ pushq %rbp
+ pushq %rbx
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ subq $480+8,%rsp
+
+ movdqu 0(%rsi),%xmm0
+ movq %rdx,%rbx
+ movdqu 16(%rsi),%xmm1
+ movdqu 32(%rsi),%xmm2
+ movdqu 48(%rsi),%xmm3
+ movdqu 64(%rsi),%xmm4
+ movdqu 80(%rsi),%xmm5
+ movq 64+0(%rsi),%rax
+ movq 64+8(%rsi),%r14
+ movq 64+16(%rsi),%r15
+ movq 64+24(%rsi),%r8
+ movdqa %xmm0,320(%rsp)
+ movdqa %xmm1,320+16(%rsp)
+ por %xmm0,%xmm1
+ movdqa %xmm2,352(%rsp)
+ movdqa %xmm3,352+16(%rsp)
+ por %xmm2,%xmm3
+ movdqa %xmm4,384(%rsp)
+ movdqa %xmm5,384+16(%rsp)
+ por %xmm1,%xmm3
+
+ movdqu 0(%rbx),%xmm0
+ pshufd $177,%xmm3,%xmm5
+ movdqu 16(%rbx),%xmm1
+ movdqu 32(%rbx),%xmm2
+ por %xmm3,%xmm5
+ movdqu 48(%rbx),%xmm3
+ movdqa %xmm0,416(%rsp)
+ pshufd $30,%xmm5,%xmm4
+ movdqa %xmm1,416+16(%rsp)
+ por %xmm0,%xmm1
+.byte 102,72,15,110,199
+ movdqa %xmm2,448(%rsp)
+ movdqa %xmm3,448+16(%rsp)
+ por %xmm2,%xmm3
+ por %xmm4,%xmm5
+ pxor %xmm4,%xmm4
+ por %xmm1,%xmm3
+
+ leaq 64-0(%rsi),%rsi
+ leaq 32(%rsp),%rdi
+ call __ecp_nistz256_sqr_montq
+
+ pcmpeqd %xmm4,%xmm5
+ pshufd $177,%xmm3,%xmm4
+ movq 0(%rbx),%rax
+
+ movq %r12,%r9
+ por %xmm3,%xmm4
+ pshufd $0,%xmm5,%xmm5
+ pshufd $30,%xmm4,%xmm3
+ movq %r13,%r10
+ por %xmm3,%xmm4
+ pxor %xmm3,%xmm3
+ movq %r14,%r11
+ pcmpeqd %xmm3,%xmm4
+ pshufd $0,%xmm4,%xmm4
+
+ leaq 32-0(%rsp),%rsi
+ movq %r15,%r12
+ leaq 0(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ leaq 320(%rsp),%rbx
+ leaq 64(%rsp),%rdi
+ call __ecp_nistz256_sub_fromq
+
+ movq 384(%rsp),%rax
+ leaq 384(%rsp),%rbx
+ movq 0+32(%rsp),%r9
+ movq 8+32(%rsp),%r10
+ leaq 0+32(%rsp),%rsi
+ movq 16+32(%rsp),%r11
+ movq 24+32(%rsp),%r12
+ leaq 32(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ movq 384(%rsp),%rax
+ leaq 384(%rsp),%rbx
+ movq 0+64(%rsp),%r9
+ movq 8+64(%rsp),%r10
+ leaq 0+64(%rsp),%rsi
+ movq 16+64(%rsp),%r11
+ movq 24+64(%rsp),%r12
+ leaq 288(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ movq 448(%rsp),%rax
+ leaq 448(%rsp),%rbx
+ movq 0+32(%rsp),%r9
+ movq 8+32(%rsp),%r10
+ leaq 0+32(%rsp),%rsi
+ movq 16+32(%rsp),%r11
+ movq 24+32(%rsp),%r12
+ leaq 32(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ leaq 352(%rsp),%rbx
+ leaq 96(%rsp),%rdi
+ call __ecp_nistz256_sub_fromq
+
+ movq 0+64(%rsp),%rax
+ movq 8+64(%rsp),%r14
+ leaq 0+64(%rsp),%rsi
+ movq 16+64(%rsp),%r15
+ movq 24+64(%rsp),%r8
+ leaq 128(%rsp),%rdi
+ call __ecp_nistz256_sqr_montq
+
+ movq 0+96(%rsp),%rax
+ movq 8+96(%rsp),%r14
+ leaq 0+96(%rsp),%rsi
+ movq 16+96(%rsp),%r15
+ movq 24+96(%rsp),%r8
+ leaq 192(%rsp),%rdi
+ call __ecp_nistz256_sqr_montq
+
+ movq 128(%rsp),%rax
+ leaq 128(%rsp),%rbx
+ movq 0+64(%rsp),%r9
+ movq 8+64(%rsp),%r10
+ leaq 0+64(%rsp),%rsi
+ movq 16+64(%rsp),%r11
+ movq 24+64(%rsp),%r12
+ leaq 160(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ movq 320(%rsp),%rax
+ leaq 320(%rsp),%rbx
+ movq 0+128(%rsp),%r9
+ movq 8+128(%rsp),%r10
+ leaq 0+128(%rsp),%rsi
+ movq 16+128(%rsp),%r11
+ movq 24+128(%rsp),%r12
+ leaq 0(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+
+
+
+ addq %r12,%r12
+ leaq 192(%rsp),%rsi
+ adcq %r13,%r13
+ movq %r12,%rax
+ adcq %r8,%r8
+ adcq %r9,%r9
+ movq %r13,%rbp
+ sbbq %r11,%r11
+
+ subq $-1,%r12
+ movq %r8,%rcx
+ sbbq %r14,%r13
+ sbbq $0,%r8
+ movq %r9,%r10
+ sbbq %r15,%r9
+ testq %r11,%r11
+
+ cmovzq %rax,%r12
+ movq 0(%rsi),%rax
+ cmovzq %rbp,%r13
+ movq 8(%rsi),%rbp
+ cmovzq %rcx,%r8
+ movq 16(%rsi),%rcx
+ cmovzq %r10,%r9
+ movq 24(%rsi),%r10
+
+ call __ecp_nistz256_subq
+
+ leaq 160(%rsp),%rbx
+ leaq 224(%rsp),%rdi
+ call __ecp_nistz256_sub_fromq
+
+ movq 0+0(%rsp),%rax
+ movq 0+8(%rsp),%rbp
+ movq 0+16(%rsp),%rcx
+ movq 0+24(%rsp),%r10
+ leaq 64(%rsp),%rdi
+
+ call __ecp_nistz256_subq
+
+ movq %r12,0(%rdi)
+ movq %r13,8(%rdi)
+ movq %r8,16(%rdi)
+ movq %r9,24(%rdi)
+ movq 352(%rsp),%rax
+ leaq 352(%rsp),%rbx
+ movq 0+160(%rsp),%r9
+ movq 8+160(%rsp),%r10
+ leaq 0+160(%rsp),%rsi
+ movq 16+160(%rsp),%r11
+ movq 24+160(%rsp),%r12
+ leaq 32(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ movq 96(%rsp),%rax
+ leaq 96(%rsp),%rbx
+ movq 0+64(%rsp),%r9
+ movq 8+64(%rsp),%r10
+ leaq 0+64(%rsp),%rsi
+ movq 16+64(%rsp),%r11
+ movq 24+64(%rsp),%r12
+ leaq 64(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ leaq 32(%rsp),%rbx
+ leaq 256(%rsp),%rdi
+ call __ecp_nistz256_sub_fromq
+
+.byte 102,72,15,126,199
+
+ movdqa %xmm5,%xmm0
+ movdqa %xmm5,%xmm1
+ pandn 288(%rsp),%xmm0
+ movdqa %xmm5,%xmm2
+ pandn 288+16(%rsp),%xmm1
+ movdqa %xmm5,%xmm3
+ pand .LONE_mont(%rip),%xmm2
+ pand .LONE_mont+16(%rip),%xmm3
+ por %xmm0,%xmm2
+ por %xmm1,%xmm3
+
+ movdqa %xmm4,%xmm0
+ movdqa %xmm4,%xmm1
+ pandn %xmm2,%xmm0
+ movdqa %xmm4,%xmm2
+ pandn %xmm3,%xmm1
+ movdqa %xmm4,%xmm3
+ pand 384(%rsp),%xmm2
+ pand 384+16(%rsp),%xmm3
+ por %xmm0,%xmm2
+ por %xmm1,%xmm3
+ movdqu %xmm2,64(%rdi)
+ movdqu %xmm3,80(%rdi)
+
+ movdqa %xmm5,%xmm0
+ movdqa %xmm5,%xmm1
+ pandn 224(%rsp),%xmm0
+ movdqa %xmm5,%xmm2
+ pandn 224+16(%rsp),%xmm1
+ movdqa %xmm5,%xmm3
+ pand 416(%rsp),%xmm2
+ pand 416+16(%rsp),%xmm3
+ por %xmm0,%xmm2
+ por %xmm1,%xmm3
+
+ movdqa %xmm4,%xmm0
+ movdqa %xmm4,%xmm1
+ pandn %xmm2,%xmm0
+ movdqa %xmm4,%xmm2
+ pandn %xmm3,%xmm1
+ movdqa %xmm4,%xmm3
+ pand 320(%rsp),%xmm2
+ pand 320+16(%rsp),%xmm3
+ por %xmm0,%xmm2
+ por %xmm1,%xmm3
+ movdqu %xmm2,0(%rdi)
+ movdqu %xmm3,16(%rdi)
+
+ movdqa %xmm5,%xmm0
+ movdqa %xmm5,%xmm1
+ pandn 256(%rsp),%xmm0
+ movdqa %xmm5,%xmm2
+ pandn 256+16(%rsp),%xmm1
+ movdqa %xmm5,%xmm3
+ pand 448(%rsp),%xmm2
+ pand 448+16(%rsp),%xmm3
+ por %xmm0,%xmm2
+ por %xmm1,%xmm3
+
+ movdqa %xmm4,%xmm0
+ movdqa %xmm4,%xmm1
+ pandn %xmm2,%xmm0
+ movdqa %xmm4,%xmm2
+ pandn %xmm3,%xmm1
+ movdqa %xmm4,%xmm3
+ pand 352(%rsp),%xmm2
+ pand 352+16(%rsp),%xmm3
+ por %xmm0,%xmm2
+ por %xmm1,%xmm3
+ movdqu %xmm2,32(%rdi)
+ movdqu %xmm3,48(%rdi)
+
+ addq $480+8,%rsp
+ popq %r15
+ popq %r14
+ popq %r13
+ popq %r12
+ popq %rbx
+ popq %rbp
+ .byte 0xf3,0xc3
+.size ecp_nistz256_point_add_affine,.-ecp_nistz256_point_add_affine
+#endif
diff --git a/linux-x86_64/crypto/rand/rdrand-x86_64.S b/linux-x86_64/crypto/rand/rdrand-x86_64.S
index 622ae55..94aab9c 100644
--- a/linux-x86_64/crypto/rand/rdrand-x86_64.S
+++ b/linux-x86_64/crypto/rand/rdrand-x86_64.S
@@ -1,11 +1,48 @@
#if defined(__x86_64__)
.text
+
+
+
.globl CRYPTO_rdrand
.hidden CRYPTO_rdrand
.type CRYPTO_rdrand,@function
.align 16
CRYPTO_rdrand:
-.byte 0x48, 0x0f, 0xc7, 0xf0
+ xorq %rax,%rax
+
+
+.byte 0x48, 0x0f, 0xc7, 0xf1
+
+ adcq %rax,%rax
+ movq %rcx,0(%rdi)
+ .byte 0xf3,0xc3
+
+
+
+
+
+.globl CRYPTO_rdrand_multiple8_buf
+.hidden CRYPTO_rdrand_multiple8_buf
+.type CRYPTO_rdrand_multiple8_buf,@function
+.align 16
+CRYPTO_rdrand_multiple8_buf:
+ testq %rsi,%rsi
+ jz .Lout
+ movq $8,%rdx
+.Lloop:
+
+
+.byte 0x48, 0x0f, 0xc7, 0xf1
+ jnc .Lerr
+ movq %rcx,0(%rdi)
+ addq %rdx,%rdi
+ subq %rdx,%rsi
+ jnz .Lloop
+.Lout:
+ movq $1,%rax
+ .byte 0xf3,0xc3
+.Lerr:
+ xorq %rax,%rax
.byte 0xf3,0xc3
#endif
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/cpu-x86-asm.S b/mac-x86/crypto/cpu-x86-asm.S
deleted file mode 100644
index bfb292c..0000000
--- a/mac-x86/crypto/cpu-x86-asm.S
+++ /dev/null
@@ -1,309 +0,0 @@
-#if defined(__i386__)
-.file "crypto/cpu-x86-asm.S"
-.text
-.globl _OPENSSL_ia32_cpuid
-.private_extern _OPENSSL_ia32_cpuid
-.align 4
-_OPENSSL_ia32_cpuid:
-L_OPENSSL_ia32_cpuid_begin:
- pushl %ebp
- pushl %ebx
- pushl %esi
- pushl %edi
- xorl %edx,%edx
- pushfl
- popl %eax
- movl %eax,%ecx
- xorl $2097152,%eax
- pushl %eax
- popfl
- pushfl
- popl %eax
- xorl %eax,%ecx
- xorl %eax,%eax
- btl $21,%ecx
- jnc L000nocpuid
- movl 20(%esp),%esi
- movl %eax,8(%esi)
- .byte 0x0f,0xa2
- movl %eax,%edi
- xorl %eax,%eax
- cmpl $1970169159,%ebx
- setne %al
- movl %eax,%ebp
- cmpl $1231384169,%edx
- setne %al
- orl %eax,%ebp
- cmpl $1818588270,%ecx
- setne %al
- orl %eax,%ebp
- jz L001intel
- cmpl $1752462657,%ebx
- setne %al
- movl %eax,%esi
- cmpl $1769238117,%edx
- setne %al
- orl %eax,%esi
- cmpl $1145913699,%ecx
- setne %al
- orl %eax,%esi
- jnz L001intel
- movl $2147483648,%eax
- .byte 0x0f,0xa2
- cmpl $2147483649,%eax
- jb L001intel
- movl %eax,%esi
- movl $2147483649,%eax
- .byte 0x0f,0xa2
- orl %ecx,%ebp
- andl $2049,%ebp
- cmpl $2147483656,%esi
- jb L001intel
- movl $2147483656,%eax
- .byte 0x0f,0xa2
- movzbl %cl,%esi
- incl %esi
- movl $1,%eax
- xorl %ecx,%ecx
- .byte 0x0f,0xa2
- btl $28,%edx
- jnc L002generic
- shrl $16,%ebx
- andl $255,%ebx
- cmpl %esi,%ebx
- ja L002generic
- andl $4026531839,%edx
- jmp L002generic
-L001intel:
- cmpl $7,%edi
- jb L003cacheinfo
- movl 20(%esp),%esi
- movl $7,%eax
- xorl %ecx,%ecx
- .byte 0x0f,0xa2
- movl %ebx,8(%esi)
-L003cacheinfo:
- cmpl $4,%edi
- movl $-1,%edi
- jb L004nocacheinfo
- movl $4,%eax
- movl $0,%ecx
- .byte 0x0f,0xa2
- movl %eax,%edi
- shrl $14,%edi
- andl $4095,%edi
-L004nocacheinfo:
- movl $1,%eax
- xorl %ecx,%ecx
- .byte 0x0f,0xa2
- andl $3220176895,%edx
- cmpl $0,%ebp
- jne L005notintel
- orl $1073741824,%edx
-L005notintel:
- btl $28,%edx
- jnc L002generic
- andl $4026531839,%edx
- cmpl $0,%edi
- je L002generic
- orl $268435456,%edx
- shrl $16,%ebx
- cmpb $1,%bl
- ja L002generic
- andl $4026531839,%edx
-L002generic:
- andl $2048,%ebp
- andl $4294965247,%ecx
- movl %edx,%esi
- orl %ecx,%ebp
- btl $27,%ecx
- jnc L006clear_avx
- xorl %ecx,%ecx
-.byte 15,1,208
- andl $6,%eax
- cmpl $6,%eax
- je L007done
- cmpl $2,%eax
- je L006clear_avx
-L008clear_xmm:
- andl $4261412861,%ebp
- andl $4278190079,%esi
-L006clear_avx:
- andl $4026525695,%ebp
- movl 20(%esp),%edi
- andl $4294967263,8(%edi)
-L007done:
- movl %esi,%eax
- movl %ebp,%edx
-L000nocpuid:
- popl %edi
- popl %esi
- popl %ebx
- popl %ebp
- ret
-.globl _OPENSSL_rdtsc
-.private_extern _OPENSSL_rdtsc
-.align 4
-_OPENSSL_rdtsc:
-L_OPENSSL_rdtsc_begin:
- xorl %eax,%eax
- xorl %edx,%edx
- call L009PIC_me_up
-L009PIC_me_up:
- popl %ecx
- movl L_OPENSSL_ia32cap_P$non_lazy_ptr-L009PIC_me_up(%ecx),%ecx
- btl $4,(%ecx)
- jnc L010notsc
- .byte 0x0f,0x31
-L010notsc:
- ret
-.globl _OPENSSL_instrument_halt
-.private_extern _OPENSSL_instrument_halt
-.align 4
-_OPENSSL_instrument_halt:
-L_OPENSSL_instrument_halt_begin:
- call L011PIC_me_up
-L011PIC_me_up:
- popl %ecx
- movl L_OPENSSL_ia32cap_P$non_lazy_ptr-L011PIC_me_up(%ecx),%ecx
- btl $4,(%ecx)
- jnc L012nohalt
-.long 2421723150
- andl $3,%eax
- jnz L012nohalt
- pushfl
- popl %eax
- btl $9,%eax
- jnc L012nohalt
- .byte 0x0f,0x31
- pushl %edx
- pushl %eax
- hlt
- .byte 0x0f,0x31
- subl (%esp),%eax
- sbbl 4(%esp),%edx
- addl $8,%esp
- ret
-L012nohalt:
- xorl %eax,%eax
- xorl %edx,%edx
- ret
-.globl _OPENSSL_far_spin
-.private_extern _OPENSSL_far_spin
-.align 4
-_OPENSSL_far_spin:
-L_OPENSSL_far_spin_begin:
- pushfl
- popl %eax
- btl $9,%eax
- jnc L013nospin
- movl 4(%esp),%eax
- movl 8(%esp),%ecx
-.long 2430111262
- xorl %eax,%eax
- movl (%ecx),%edx
- jmp L014spin
-.align 4,0x90
-L014spin:
- incl %eax
- cmpl (%ecx),%edx
- je L014spin
-.long 529567888
- ret
-L013nospin:
- xorl %eax,%eax
- xorl %edx,%edx
- ret
-.globl _OPENSSL_wipe_cpu
-.private_extern _OPENSSL_wipe_cpu
-.align 4
-_OPENSSL_wipe_cpu:
-L_OPENSSL_wipe_cpu_begin:
- xorl %eax,%eax
- xorl %edx,%edx
- call L015PIC_me_up
-L015PIC_me_up:
- popl %ecx
- movl L_OPENSSL_ia32cap_P$non_lazy_ptr-L015PIC_me_up(%ecx),%ecx
- movl (%ecx),%ecx
- btl $1,(%ecx)
- jnc L016no_x87
- andl $83886080,%ecx
- cmpl $83886080,%ecx
- jne L017no_sse2
- pxor %xmm0,%xmm0
- pxor %xmm1,%xmm1
- pxor %xmm2,%xmm2
- pxor %xmm3,%xmm3
- pxor %xmm4,%xmm4
- pxor %xmm5,%xmm5
- pxor %xmm6,%xmm6
- pxor %xmm7,%xmm7
-L017no_sse2:
-.long 4007259865,4007259865,4007259865,4007259865,2430851995
-L016no_x87:
- leal 4(%esp),%eax
- ret
-.globl _OPENSSL_atomic_add
-.private_extern _OPENSSL_atomic_add
-.align 4
-_OPENSSL_atomic_add:
-L_OPENSSL_atomic_add_begin:
- movl 4(%esp),%edx
- movl 8(%esp),%ecx
- pushl %ebx
- nop
- movl (%edx),%eax
-L018spin:
- leal (%eax,%ecx,1),%ebx
- nop
-.long 447811568
- jne L018spin
- movl %ebx,%eax
- popl %ebx
- ret
-.globl _OPENSSL_indirect_call
-.private_extern _OPENSSL_indirect_call
-.align 4
-_OPENSSL_indirect_call:
-L_OPENSSL_indirect_call_begin:
- pushl %ebp
- movl %esp,%ebp
- subl $28,%esp
- movl 12(%ebp),%ecx
- movl %ecx,(%esp)
- movl 16(%ebp),%edx
- movl %edx,4(%esp)
- movl 20(%ebp),%eax
- movl %eax,8(%esp)
- movl 24(%ebp),%eax
- movl %eax,12(%esp)
- movl 28(%ebp),%eax
- movl %eax,16(%esp)
- movl 32(%ebp),%eax
- movl %eax,20(%esp)
- movl 36(%ebp),%eax
- movl %eax,24(%esp)
- call *8(%ebp)
- movl %ebp,%esp
- popl %ebp
- ret
-.globl _OPENSSL_ia32_rdrand
-.private_extern _OPENSSL_ia32_rdrand
-.align 4
-_OPENSSL_ia32_rdrand:
-L_OPENSSL_ia32_rdrand_begin:
- movl $8,%ecx
-L019loop:
-.byte 15,199,240
- jc L020break
- loop L019loop
-L020break:
- cmpl $0,%eax
- cmovel %ecx,%eax
- ret
-.section __IMPORT,__pointers,non_lazy_symbol_pointers
-L_OPENSSL_ia32cap_P$non_lazy_ptr:
-.indirect_symbol _OPENSSL_ia32cap_P
-.long 0
-#endif
diff --git a/mac-x86/crypto/sha/sha1-586.S b/mac-x86/crypto/sha/sha1-586.S
index 97aafbf..72a7205 100644
--- a/mac-x86/crypto/sha/sha1-586.S
+++ b/mac-x86/crypto/sha/sha1-586.S
@@ -22,8 +22,11 @@ L000pic_point:
movl 8(%esi),%ecx
testl $16777216,%eax
jz L001x86
- testl $536870912,%ecx
- jnz Lshaext_shortcut
+ andl $268435456,%edx
+ andl $1073741824,%eax
+ orl %edx,%eax
+ cmpl $1342177280,%eax
+ je Lavx_shortcut
jmp Lssse3_shortcut
.align 4,0x90
L001x86:
@@ -1391,9 +1394,9 @@ L002loop:
popl %ebx
popl %ebp
ret
-.private_extern __sha1_block_data_order_shaext
+.private_extern __sha1_block_data_order_ssse3
.align 4
-__sha1_block_data_order_shaext:
+__sha1_block_data_order_ssse3:
pushl %ebp
pushl %ebx
pushl %esi
@@ -1402,175 +1405,6 @@ __sha1_block_data_order_shaext:
L003pic_point:
popl %ebp
leal LK_XX_XX-L003pic_point(%ebp),%ebp
-Lshaext_shortcut:
- movl 20(%esp),%edi
- movl %esp,%ebx
- movl 24(%esp),%esi
- movl 28(%esp),%ecx
- subl $32,%esp
- movdqu (%edi),%xmm0
- movd 16(%edi),%xmm1
- andl $-32,%esp
- movdqa 80(%ebp),%xmm3
- movdqu (%esi),%xmm4
- pshufd $27,%xmm0,%xmm0
- movdqu 16(%esi),%xmm5
- pshufd $27,%xmm1,%xmm1
- movdqu 32(%esi),%xmm6
-.byte 102,15,56,0,227
- movdqu 48(%esi),%xmm7
-.byte 102,15,56,0,235
-.byte 102,15,56,0,243
-.byte 102,15,56,0,251
- jmp L004loop_shaext
-.align 4,0x90
-L004loop_shaext:
- decl %ecx
- leal 64(%esi),%eax
- movdqa %xmm1,(%esp)
- paddd %xmm4,%xmm1
- cmovnel %eax,%esi
- movdqa %xmm0,16(%esp)
-.byte 15,56,201,229
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,0
-.byte 15,56,200,213
- pxor %xmm6,%xmm4
-.byte 15,56,201,238
-.byte 15,56,202,231
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,0
-.byte 15,56,200,206
- pxor %xmm7,%xmm5
-.byte 15,56,202,236
-.byte 15,56,201,247
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,0
-.byte 15,56,200,215
- pxor %xmm4,%xmm6
-.byte 15,56,201,252
-.byte 15,56,202,245
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,0
-.byte 15,56,200,204
- pxor %xmm5,%xmm7
-.byte 15,56,202,254
-.byte 15,56,201,229
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,0
-.byte 15,56,200,213
- pxor %xmm6,%xmm4
-.byte 15,56,201,238
-.byte 15,56,202,231
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,1
-.byte 15,56,200,206
- pxor %xmm7,%xmm5
-.byte 15,56,202,236
-.byte 15,56,201,247
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,1
-.byte 15,56,200,215
- pxor %xmm4,%xmm6
-.byte 15,56,201,252
-.byte 15,56,202,245
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,1
-.byte 15,56,200,204
- pxor %xmm5,%xmm7
-.byte 15,56,202,254
-.byte 15,56,201,229
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,1
-.byte 15,56,200,213
- pxor %xmm6,%xmm4
-.byte 15,56,201,238
-.byte 15,56,202,231
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,1
-.byte 15,56,200,206
- pxor %xmm7,%xmm5
-.byte 15,56,202,236
-.byte 15,56,201,247
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,2
-.byte 15,56,200,215
- pxor %xmm4,%xmm6
-.byte 15,56,201,252
-.byte 15,56,202,245
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,2
-.byte 15,56,200,204
- pxor %xmm5,%xmm7
-.byte 15,56,202,254
-.byte 15,56,201,229
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,2
-.byte 15,56,200,213
- pxor %xmm6,%xmm4
-.byte 15,56,201,238
-.byte 15,56,202,231
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,2
-.byte 15,56,200,206
- pxor %xmm7,%xmm5
-.byte 15,56,202,236
-.byte 15,56,201,247
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,2
-.byte 15,56,200,215
- pxor %xmm4,%xmm6
-.byte 15,56,201,252
-.byte 15,56,202,245
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,3
-.byte 15,56,200,204
- pxor %xmm5,%xmm7
-.byte 15,56,202,254
- movdqu (%esi),%xmm4
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,3
-.byte 15,56,200,213
- movdqu 16(%esi),%xmm5
-.byte 102,15,56,0,227
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,3
-.byte 15,56,200,206
- movdqu 32(%esi),%xmm6
-.byte 102,15,56,0,235
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,3
-.byte 15,56,200,215
- movdqu 48(%esi),%xmm7
-.byte 102,15,56,0,243
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,3
- movdqa (%esp),%xmm2
-.byte 102,15,56,0,251
-.byte 15,56,200,202
- paddd 16(%esp),%xmm0
- jnz L004loop_shaext
- pshufd $27,%xmm0,%xmm0
- pshufd $27,%xmm1,%xmm1
- movdqu %xmm0,(%edi)
- movd %xmm1,16(%edi)
- movl %ebx,%esp
- popl %edi
- popl %esi
- popl %ebx
- popl %ebp
- ret
-.private_extern __sha1_block_data_order_ssse3
-.align 4
-__sha1_block_data_order_ssse3:
- pushl %ebp
- pushl %ebx
- pushl %esi
- pushl %edi
- call L005pic_point
-L005pic_point:
- popl %ebp
- leal LK_XX_XX-L005pic_point(%ebp),%ebp
Lssse3_shortcut:
movdqa (%ebp),%xmm7
movdqa 16(%ebp),%xmm0
@@ -1623,9 +1457,9 @@ Lssse3_shortcut:
xorl %edx,%ebp
pshufd $238,%xmm0,%xmm4
andl %ebp,%esi
- jmp L006loop
+ jmp L004loop
.align 4,0x90
-L006loop:
+L004loop:
rorl $2,%ebx
xorl %edx,%esi
movl %eax,%ebp
@@ -2528,7 +2362,7 @@ L006loop:
addl %edx,%ecx
movl 196(%esp),%ebp
cmpl 200(%esp),%ebp
- je L007done
+ je L005done
movdqa 160(%esp),%xmm7
movdqa 176(%esp),%xmm6
movdqu (%ebp),%xmm0
@@ -2663,9 +2497,9 @@ L006loop:
pshufd $238,%xmm0,%xmm4
andl %ebx,%esi
movl %ebp,%ebx
- jmp L006loop
+ jmp L004loop
.align 4,0x90
-L007done:
+L005done:
addl 16(%esp),%ebx
xorl %edi,%esi
movl %ecx,%ebp
@@ -2778,6 +2612,1175 @@ L007done:
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 f0ba612..841854f 100644
--- a/mac-x86/crypto/sha/sha256-586.S
+++ b/mac-x86/crypto/sha/sha256-586.S
@@ -36,11 +36,10 @@ L000pic_point:
jz L003no_xmm
andl $1073741824,%ecx
andl $268435968,%ebx
- testl $536870912,%edx
- jnz L004shaext
orl %ebx,%ecx
andl $1342177280,%ecx
cmpl $1342177280,%ecx
+ je L004AVX
testl $512,%ebx
jnz L005SSSE3
L003no_xmm:
@@ -3166,204 +3165,6 @@ L009grand_loop:
popl %ebp
ret
.align 5,0x90
-L004shaext:
- subl $32,%esp
- movdqu (%esi),%xmm1
- leal 128(%ebp),%ebp
- movdqu 16(%esi),%xmm2
- movdqa 128(%ebp),%xmm7
- pshufd $27,%xmm1,%xmm0
- pshufd $177,%xmm1,%xmm1
- pshufd $27,%xmm2,%xmm2
-.byte 102,15,58,15,202,8
- punpcklqdq %xmm0,%xmm2
- jmp L010loop_shaext
-.align 4,0x90
-L010loop_shaext:
- movdqu (%edi),%xmm3
- movdqu 16(%edi),%xmm4
- movdqu 32(%edi),%xmm5
-.byte 102,15,56,0,223
- movdqu 48(%edi),%xmm6
- movdqa %xmm2,16(%esp)
- movdqa -128(%ebp),%xmm0
- paddd %xmm3,%xmm0
-.byte 102,15,56,0,231
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- nop
- movdqa %xmm1,(%esp)
-.byte 15,56,203,202
- movdqa -112(%ebp),%xmm0
- paddd %xmm4,%xmm0
-.byte 102,15,56,0,239
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- leal 64(%edi),%edi
-.byte 15,56,204,220
-.byte 15,56,203,202
- movdqa -96(%ebp),%xmm0
- paddd %xmm5,%xmm0
-.byte 102,15,56,0,247
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm6,%xmm7
-.byte 102,15,58,15,253,4
- nop
- paddd %xmm7,%xmm3
-.byte 15,56,204,229
-.byte 15,56,203,202
- movdqa -80(%ebp),%xmm0
- paddd %xmm6,%xmm0
-.byte 15,56,205,222
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm3,%xmm7
-.byte 102,15,58,15,254,4
- nop
- paddd %xmm7,%xmm4
-.byte 15,56,204,238
-.byte 15,56,203,202
- movdqa -64(%ebp),%xmm0
- paddd %xmm3,%xmm0
-.byte 15,56,205,227
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm4,%xmm7
-.byte 102,15,58,15,251,4
- nop
- paddd %xmm7,%xmm5
-.byte 15,56,204,243
-.byte 15,56,203,202
- movdqa -48(%ebp),%xmm0
- paddd %xmm4,%xmm0
-.byte 15,56,205,236
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm5,%xmm7
-.byte 102,15,58,15,252,4
- nop
- paddd %xmm7,%xmm6
-.byte 15,56,204,220
-.byte 15,56,203,202
- movdqa -32(%ebp),%xmm0
- paddd %xmm5,%xmm0
-.byte 15,56,205,245
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm6,%xmm7
-.byte 102,15,58,15,253,4
- nop
- paddd %xmm7,%xmm3
-.byte 15,56,204,229
-.byte 15,56,203,202
- movdqa -16(%ebp),%xmm0
- paddd %xmm6,%xmm0
-.byte 15,56,205,222
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm3,%xmm7
-.byte 102,15,58,15,254,4
- nop
- paddd %xmm7,%xmm4
-.byte 15,56,204,238
-.byte 15,56,203,202
- movdqa (%ebp),%xmm0
- paddd %xmm3,%xmm0
-.byte 15,56,205,227
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm4,%xmm7
-.byte 102,15,58,15,251,4
- nop
- paddd %xmm7,%xmm5
-.byte 15,56,204,243
-.byte 15,56,203,202
- movdqa 16(%ebp),%xmm0
- paddd %xmm4,%xmm0
-.byte 15,56,205,236
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm5,%xmm7
-.byte 102,15,58,15,252,4
- nop
- paddd %xmm7,%xmm6
-.byte 15,56,204,220
-.byte 15,56,203,202
- movdqa 32(%ebp),%xmm0
- paddd %xmm5,%xmm0
-.byte 15,56,205,245
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm6,%xmm7
-.byte 102,15,58,15,253,4
- nop
- paddd %xmm7,%xmm3
-.byte 15,56,204,229
-.byte 15,56,203,202
- movdqa 48(%ebp),%xmm0
- paddd %xmm6,%xmm0
-.byte 15,56,205,222
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm3,%xmm7
-.byte 102,15,58,15,254,4
- nop
- paddd %xmm7,%xmm4
-.byte 15,56,204,238
-.byte 15,56,203,202
- movdqa 64(%ebp),%xmm0
- paddd %xmm3,%xmm0
-.byte 15,56,205,227
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm4,%xmm7
-.byte 102,15,58,15,251,4
- nop
- paddd %xmm7,%xmm5
-.byte 15,56,204,243
-.byte 15,56,203,202
- movdqa 80(%ebp),%xmm0
- paddd %xmm4,%xmm0
-.byte 15,56,205,236
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm5,%xmm7
-.byte 102,15,58,15,252,4
-.byte 15,56,203,202
- paddd %xmm7,%xmm6
- movdqa 96(%ebp),%xmm0
- paddd %xmm5,%xmm0
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
-.byte 15,56,205,245
- movdqa 128(%ebp),%xmm7
-.byte 15,56,203,202
- movdqa 112(%ebp),%xmm0
- paddd %xmm6,%xmm0
- nop
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- cmpl %edi,%eax
- nop
-.byte 15,56,203,202
- paddd 16(%esp),%xmm2
- paddd (%esp),%xmm1
- jnz L010loop_shaext
- pshufd $177,%xmm2,%xmm2
- pshufd $27,%xmm1,%xmm7
- pshufd $177,%xmm1,%xmm1
- punpckhqdq %xmm2,%xmm1
-.byte 102,15,58,15,215,8
- movl 44(%esp),%esp
- movdqu %xmm1,(%esi)
- movdqu %xmm2,16(%esi)
- popl %edi
- popl %esi
- popl %ebx
- popl %ebp
- ret
-.align 5,0x90
L005SSSE3:
leal -96(%esp),%esp
movl (%esi),%eax
@@ -3383,9 +3184,9 @@ L005SSSE3:
movl %ecx,24(%esp)
movl %esi,28(%esp)
movdqa 256(%ebp),%xmm7
- jmp L011grand_ssse3
+ jmp L010grand_ssse3
.align 4,0x90
-L011grand_ssse3:
+L010grand_ssse3:
movdqu (%edi),%xmm0
movdqu 16(%edi),%xmm1
movdqu 32(%edi),%xmm2
@@ -3408,9 +3209,9 @@ L011grand_ssse3:
paddd %xmm3,%xmm7
movdqa %xmm6,64(%esp)
movdqa %xmm7,80(%esp)
- jmp L012ssse3_00_47
+ jmp L011ssse3_00_47
.align 4,0x90
-L012ssse3_00_47:
+L011ssse3_00_47:
addl $64,%ebp
movl %edx,%ecx
movdqa %xmm1,%xmm4
@@ -4053,7 +3854,7 @@ L012ssse3_00_47:
addl %ecx,%eax
movdqa %xmm6,80(%esp)
cmpl $66051,64(%ebp)
- jne L012ssse3_00_47
+ jne L011ssse3_00_47
movl %edx,%ecx
rorl $14,%edx
movl 20(%esp),%esi
@@ -4567,8 +4368,1189 @@ L012ssse3_00_47:
movdqa 64(%ebp),%xmm7
subl $192,%ebp
cmpl 104(%esp),%edi
- jb L011grand_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
diff --git a/mac-x86_64/crypto/bn/modexp512-x86_64.S b/mac-x86_64/crypto/bn/modexp512-x86_64.S
deleted file mode 100644
index beb133e..0000000
--- a/mac-x86_64/crypto/bn/modexp512-x86_64.S
+++ /dev/null
@@ -1,1776 +0,0 @@
-#if defined(__x86_64__)
-.text
-
-
-.p2align 4
-MULADD_128x512:
- movq 0(%rsi),%rax
- mulq %rbp
- addq %rax,%r8
- adcq $0,%rdx
- movq %r8,0(%rcx)
- movq %rdx,%rbx
-
- movq 8(%rsi),%rax
- mulq %rbp
- addq %rax,%r9
- adcq $0,%rdx
- addq %rbx,%r9
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 16(%rsi),%rax
- mulq %rbp
- addq %rax,%r10
- adcq $0,%rdx
- addq %rbx,%r10
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 24(%rsi),%rax
- mulq %rbp
- addq %rax,%r11
- adcq $0,%rdx
- addq %rbx,%r11
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 32(%rsi),%rax
- mulq %rbp
- addq %rax,%r12
- adcq $0,%rdx
- addq %rbx,%r12
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 40(%rsi),%rax
- mulq %rbp
- addq %rax,%r13
- adcq $0,%rdx
- addq %rbx,%r13
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 48(%rsi),%rax
- mulq %rbp
- addq %rax,%r14
- adcq $0,%rdx
- addq %rbx,%r14
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 56(%rsi),%rax
- mulq %rbp
- addq %rax,%r15
- adcq $0,%rdx
- addq %rbx,%r15
- adcq $0,%rdx
- movq %rdx,%r8
- movq 8(%rdi),%rbp
- movq 0(%rsi),%rax
- mulq %rbp
- addq %rax,%r9
- adcq $0,%rdx
- movq %r9,8(%rcx)
- movq %rdx,%rbx
-
- movq 8(%rsi),%rax
- mulq %rbp
- addq %rax,%r10
- adcq $0,%rdx
- addq %rbx,%r10
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 16(%rsi),%rax
- mulq %rbp
- addq %rax,%r11
- adcq $0,%rdx
- addq %rbx,%r11
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 24(%rsi),%rax
- mulq %rbp
- addq %rax,%r12
- adcq $0,%rdx
- addq %rbx,%r12
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 32(%rsi),%rax
- mulq %rbp
- addq %rax,%r13
- adcq $0,%rdx
- addq %rbx,%r13
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 40(%rsi),%rax
- mulq %rbp
- addq %rax,%r14
- adcq $0,%rdx
- addq %rbx,%r14
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 48(%rsi),%rax
- mulq %rbp
- addq %rax,%r15
- adcq $0,%rdx
- addq %rbx,%r15
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 56(%rsi),%rax
- mulq %rbp
- addq %rax,%r8
- adcq $0,%rdx
- addq %rbx,%r8
- adcq $0,%rdx
- movq %rdx,%r9
- .byte 0xf3,0xc3
-
-
-.p2align 4
-mont_reduce:
- leaq 192(%rsp),%rdi
- movq 32(%rsp),%rsi
- addq $576,%rsi
- leaq 520(%rsp),%rcx
-
- movq 96(%rcx),%rbp
- movq 0(%rsi),%rax
- mulq %rbp
- movq (%rcx),%r8
- addq %rax,%r8
- adcq $0,%rdx
- movq %r8,0(%rdi)
- movq %rdx,%rbx
-
- movq 8(%rsi),%rax
- mulq %rbp
- movq 8(%rcx),%r9
- addq %rax,%r9
- adcq $0,%rdx
- addq %rbx,%r9
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 16(%rsi),%rax
- mulq %rbp
- movq 16(%rcx),%r10
- addq %rax,%r10
- adcq $0,%rdx
- addq %rbx,%r10
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 24(%rsi),%rax
- mulq %rbp
- movq 24(%rcx),%r11
- addq %rax,%r11
- adcq $0,%rdx
- addq %rbx,%r11
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 32(%rsi),%rax
- mulq %rbp
- movq 32(%rcx),%r12
- addq %rax,%r12
- adcq $0,%rdx
- addq %rbx,%r12
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 40(%rsi),%rax
- mulq %rbp
- movq 40(%rcx),%r13
- addq %rax,%r13
- adcq $0,%rdx
- addq %rbx,%r13
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 48(%rsi),%rax
- mulq %rbp
- movq 48(%rcx),%r14
- addq %rax,%r14
- adcq $0,%rdx
- addq %rbx,%r14
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 56(%rsi),%rax
- mulq %rbp
- movq 56(%rcx),%r15
- addq %rax,%r15
- adcq $0,%rdx
- addq %rbx,%r15
- adcq $0,%rdx
- movq %rdx,%r8
- movq 104(%rcx),%rbp
- movq 0(%rsi),%rax
- mulq %rbp
- addq %rax,%r9
- adcq $0,%rdx
- movq %r9,8(%rdi)
- movq %rdx,%rbx
-
- movq 8(%rsi),%rax
- mulq %rbp
- addq %rax,%r10
- adcq $0,%rdx
- addq %rbx,%r10
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 16(%rsi),%rax
- mulq %rbp
- addq %rax,%r11
- adcq $0,%rdx
- addq %rbx,%r11
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 24(%rsi),%rax
- mulq %rbp
- addq %rax,%r12
- adcq $0,%rdx
- addq %rbx,%r12
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 32(%rsi),%rax
- mulq %rbp
- addq %rax,%r13
- adcq $0,%rdx
- addq %rbx,%r13
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 40(%rsi),%rax
- mulq %rbp
- addq %rax,%r14
- adcq $0,%rdx
- addq %rbx,%r14
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 48(%rsi),%rax
- mulq %rbp
- addq %rax,%r15
- adcq $0,%rdx
- addq %rbx,%r15
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 56(%rsi),%rax
- mulq %rbp
- addq %rax,%r8
- adcq $0,%rdx
- addq %rbx,%r8
- adcq $0,%rdx
- movq %rdx,%r9
- movq 112(%rcx),%rbp
- movq 0(%rsi),%rax
- mulq %rbp
- addq %rax,%r10
- adcq $0,%rdx
- movq %r10,16(%rdi)
- movq %rdx,%rbx
-
- movq 8(%rsi),%rax
- mulq %rbp
- addq %rax,%r11
- adcq $0,%rdx
- addq %rbx,%r11
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 16(%rsi),%rax
- mulq %rbp
- addq %rax,%r12
- adcq $0,%rdx
- addq %rbx,%r12
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 24(%rsi),%rax
- mulq %rbp
- addq %rax,%r13
- adcq $0,%rdx
- addq %rbx,%r13
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 32(%rsi),%rax
- mulq %rbp
- addq %rax,%r14
- adcq $0,%rdx
- addq %rbx,%r14
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 40(%rsi),%rax
- mulq %rbp
- addq %rax,%r15
- adcq $0,%rdx
- addq %rbx,%r15
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 48(%rsi),%rax
- mulq %rbp
- addq %rax,%r8
- adcq $0,%rdx
- addq %rbx,%r8
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 56(%rsi),%rax
- mulq %rbp
- addq %rax,%r9
- adcq $0,%rdx
- addq %rbx,%r9
- adcq $0,%rdx
- movq %rdx,%r10
- movq 120(%rcx),%rbp
- movq 0(%rsi),%rax
- mulq %rbp
- addq %rax,%r11
- adcq $0,%rdx
- movq %r11,24(%rdi)
- movq %rdx,%rbx
-
- movq 8(%rsi),%rax
- mulq %rbp
- addq %rax,%r12
- adcq $0,%rdx
- addq %rbx,%r12
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 16(%rsi),%rax
- mulq %rbp
- addq %rax,%r13
- adcq $0,%rdx
- addq %rbx,%r13
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 24(%rsi),%rax
- mulq %rbp
- addq %rax,%r14
- adcq $0,%rdx
- addq %rbx,%r14
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 32(%rsi),%rax
- mulq %rbp
- addq %rax,%r15
- adcq $0,%rdx
- addq %rbx,%r15
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 40(%rsi),%rax
- mulq %rbp
- addq %rax,%r8
- adcq $0,%rdx
- addq %rbx,%r8
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 48(%rsi),%rax
- mulq %rbp
- addq %rax,%r9
- adcq $0,%rdx
- addq %rbx,%r9
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 56(%rsi),%rax
- mulq %rbp
- addq %rax,%r10
- adcq $0,%rdx
- addq %rbx,%r10
- adcq $0,%rdx
- movq %rdx,%r11
- xorq %rax,%rax
-
- addq 64(%rcx),%r8
- adcq 72(%rcx),%r9
- adcq 80(%rcx),%r10
- adcq 88(%rcx),%r11
- adcq $0,%rax
-
-
-
-
- movq %r8,64(%rdi)
- movq %r9,72(%rdi)
- movq %r10,%rbp
- movq %r11,88(%rdi)
-
- movq %rax,384(%rsp)
-
- movq 0(%rdi),%r8
- movq 8(%rdi),%r9
- movq 16(%rdi),%r10
- movq 24(%rdi),%r11
-
-
-
-
-
-
-
-
- addq $80,%rdi
-
- addq $64,%rsi
- leaq 296(%rsp),%rcx
-
- call MULADD_128x512
-
- movq 384(%rsp),%rax
-
-
- addq -16(%rdi),%r8
- adcq -8(%rdi),%r9
- movq %r8,64(%rcx)
- movq %r9,72(%rcx)
-
- adcq %rax,%rax
- movq %rax,384(%rsp)
-
- leaq 192(%rsp),%rdi
- addq $64,%rsi
-
-
-
-
-
- movq (%rsi),%r8
- movq 8(%rsi),%rbx
-
- movq (%rcx),%rax
- mulq %r8
- movq %rax,%rbp
- movq %rdx,%r9
-
- movq 8(%rcx),%rax
- mulq %r8
- addq %rax,%r9
-
- movq (%rcx),%rax
- mulq %rbx
- addq %rax,%r9
-
- movq %r9,8(%rdi)
-
-
- subq $192,%rsi
-
- movq (%rcx),%r8
- movq 8(%rcx),%r9
-
- call MULADD_128x512
-
-
-
-
- movq 0(%rsi),%rax
- movq 8(%rsi),%rbx
- movq 16(%rsi),%rdi
- movq 24(%rsi),%rdx
-
-
- movq 384(%rsp),%rbp
-
- addq 64(%rcx),%r8
- adcq 72(%rcx),%r9
-
-
- adcq %rbp,%rbp
-
-
-
- shlq $3,%rbp
- movq 32(%rsp),%rcx
- addq %rcx,%rbp
-
-
- xorq %rsi,%rsi
-
- addq 0(%rbp),%r10
- adcq 64(%rbp),%r11
- adcq 128(%rbp),%r12
- adcq 192(%rbp),%r13
- adcq 256(%rbp),%r14
- adcq 320(%rbp),%r15
- adcq 384(%rbp),%r8
- adcq 448(%rbp),%r9
-
-
-
- sbbq $0,%rsi
-
-
- andq %rsi,%rax
- andq %rsi,%rbx
- andq %rsi,%rdi
- andq %rsi,%rdx
-
- movq $1,%rbp
- subq %rax,%r10
- sbbq %rbx,%r11
- sbbq %rdi,%r12
- sbbq %rdx,%r13
-
-
-
-
- sbbq $0,%rbp
-
-
-
- addq $512,%rcx
- movq 32(%rcx),%rax
- movq 40(%rcx),%rbx
- movq 48(%rcx),%rdi
- movq 56(%rcx),%rdx
-
-
-
- andq %rsi,%rax
- andq %rsi,%rbx
- andq %rsi,%rdi
- andq %rsi,%rdx
-
-
-
- subq $1,%rbp
-
- sbbq %rax,%r14
- sbbq %rbx,%r15
- sbbq %rdi,%r8
- sbbq %rdx,%r9
-
-
-
- movq 144(%rsp),%rsi
- movq %r10,0(%rsi)
- movq %r11,8(%rsi)
- movq %r12,16(%rsi)
- movq %r13,24(%rsi)
- movq %r14,32(%rsi)
- movq %r15,40(%rsi)
- movq %r8,48(%rsi)
- movq %r9,56(%rsi)
-
- .byte 0xf3,0xc3
-
-
-.p2align 4
-mont_mul_a3b:
-
-
-
-
- movq 0(%rdi),%rbp
-
- movq %r10,%rax
- mulq %rbp
- movq %rax,520(%rsp)
- movq %rdx,%r10
- movq %r11,%rax
- mulq %rbp
- addq %rax,%r10
- adcq $0,%rdx
- movq %rdx,%r11
- movq %r12,%rax
- mulq %rbp
- addq %rax,%r11
- adcq $0,%rdx
- movq %rdx,%r12
- movq %r13,%rax
- mulq %rbp
- addq %rax,%r12
- adcq $0,%rdx
- movq %rdx,%r13
- movq %r14,%rax
- mulq %rbp
- addq %rax,%r13
- adcq $0,%rdx
- movq %rdx,%r14
- movq %r15,%rax
- mulq %rbp
- addq %rax,%r14
- adcq $0,%rdx
- movq %rdx,%r15
- movq %r8,%rax
- mulq %rbp
- addq %rax,%r15
- adcq $0,%rdx
- movq %rdx,%r8
- movq %r9,%rax
- mulq %rbp
- addq %rax,%r8
- adcq $0,%rdx
- movq %rdx,%r9
- movq 8(%rdi),%rbp
- movq 0(%rsi),%rax
- mulq %rbp
- addq %rax,%r10
- adcq $0,%rdx
- movq %r10,528(%rsp)
- movq %rdx,%rbx
-
- movq 8(%rsi),%rax
- mulq %rbp
- addq %rax,%r11
- adcq $0,%rdx
- addq %rbx,%r11
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 16(%rsi),%rax
- mulq %rbp
- addq %rax,%r12
- adcq $0,%rdx
- addq %rbx,%r12
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 24(%rsi),%rax
- mulq %rbp
- addq %rax,%r13
- adcq $0,%rdx
- addq %rbx,%r13
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 32(%rsi),%rax
- mulq %rbp
- addq %rax,%r14
- adcq $0,%rdx
- addq %rbx,%r14
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 40(%rsi),%rax
- mulq %rbp
- addq %rax,%r15
- adcq $0,%rdx
- addq %rbx,%r15
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 48(%rsi),%rax
- mulq %rbp
- addq %rax,%r8
- adcq $0,%rdx
- addq %rbx,%r8
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 56(%rsi),%rax
- mulq %rbp
- addq %rax,%r9
- adcq $0,%rdx
- addq %rbx,%r9
- adcq $0,%rdx
- movq %rdx,%r10
- movq 16(%rdi),%rbp
- movq 0(%rsi),%rax
- mulq %rbp
- addq %rax,%r11
- adcq $0,%rdx
- movq %r11,536(%rsp)
- movq %rdx,%rbx
-
- movq 8(%rsi),%rax
- mulq %rbp
- addq %rax,%r12
- adcq $0,%rdx
- addq %rbx,%r12
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 16(%rsi),%rax
- mulq %rbp
- addq %rax,%r13
- adcq $0,%rdx
- addq %rbx,%r13
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 24(%rsi),%rax
- mulq %rbp
- addq %rax,%r14
- adcq $0,%rdx
- addq %rbx,%r14
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 32(%rsi),%rax
- mulq %rbp
- addq %rax,%r15
- adcq $0,%rdx
- addq %rbx,%r15
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 40(%rsi),%rax
- mulq %rbp
- addq %rax,%r8
- adcq $0,%rdx
- addq %rbx,%r8
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 48(%rsi),%rax
- mulq %rbp
- addq %rax,%r9
- adcq $0,%rdx
- addq %rbx,%r9
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 56(%rsi),%rax
- mulq %rbp
- addq %rax,%r10
- adcq $0,%rdx
- addq %rbx,%r10
- adcq $0,%rdx
- movq %rdx,%r11
- movq 24(%rdi),%rbp
- movq 0(%rsi),%rax
- mulq %rbp
- addq %rax,%r12
- adcq $0,%rdx
- movq %r12,544(%rsp)
- movq %rdx,%rbx
-
- movq 8(%rsi),%rax
- mulq %rbp
- addq %rax,%r13
- adcq $0,%rdx
- addq %rbx,%r13
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 16(%rsi),%rax
- mulq %rbp
- addq %rax,%r14
- adcq $0,%rdx
- addq %rbx,%r14
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 24(%rsi),%rax
- mulq %rbp
- addq %rax,%r15
- adcq $0,%rdx
- addq %rbx,%r15
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 32(%rsi),%rax
- mulq %rbp
- addq %rax,%r8
- adcq $0,%rdx
- addq %rbx,%r8
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 40(%rsi),%rax
- mulq %rbp
- addq %rax,%r9
- adcq $0,%rdx
- addq %rbx,%r9
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 48(%rsi),%rax
- mulq %rbp
- addq %rax,%r10
- adcq $0,%rdx
- addq %rbx,%r10
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 56(%rsi),%rax
- mulq %rbp
- addq %rax,%r11
- adcq $0,%rdx
- addq %rbx,%r11
- adcq $0,%rdx
- movq %rdx,%r12
- movq 32(%rdi),%rbp
- movq 0(%rsi),%rax
- mulq %rbp
- addq %rax,%r13
- adcq $0,%rdx
- movq %r13,552(%rsp)
- movq %rdx,%rbx
-
- movq 8(%rsi),%rax
- mulq %rbp
- addq %rax,%r14
- adcq $0,%rdx
- addq %rbx,%r14
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 16(%rsi),%rax
- mulq %rbp
- addq %rax,%r15
- adcq $0,%rdx
- addq %rbx,%r15
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 24(%rsi),%rax
- mulq %rbp
- addq %rax,%r8
- adcq $0,%rdx
- addq %rbx,%r8
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 32(%rsi),%rax
- mulq %rbp
- addq %rax,%r9
- adcq $0,%rdx
- addq %rbx,%r9
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 40(%rsi),%rax
- mulq %rbp
- addq %rax,%r10
- adcq $0,%rdx
- addq %rbx,%r10
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 48(%rsi),%rax
- mulq %rbp
- addq %rax,%r11
- adcq $0,%rdx
- addq %rbx,%r11
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 56(%rsi),%rax
- mulq %rbp
- addq %rax,%r12
- adcq $0,%rdx
- addq %rbx,%r12
- adcq $0,%rdx
- movq %rdx,%r13
- movq 40(%rdi),%rbp
- movq 0(%rsi),%rax
- mulq %rbp
- addq %rax,%r14
- adcq $0,%rdx
- movq %r14,560(%rsp)
- movq %rdx,%rbx
-
- movq 8(%rsi),%rax
- mulq %rbp
- addq %rax,%r15
- adcq $0,%rdx
- addq %rbx,%r15
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 16(%rsi),%rax
- mulq %rbp
- addq %rax,%r8
- adcq $0,%rdx
- addq %rbx,%r8
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 24(%rsi),%rax
- mulq %rbp
- addq %rax,%r9
- adcq $0,%rdx
- addq %rbx,%r9
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 32(%rsi),%rax
- mulq %rbp
- addq %rax,%r10
- adcq $0,%rdx
- addq %rbx,%r10
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 40(%rsi),%rax
- mulq %rbp
- addq %rax,%r11
- adcq $0,%rdx
- addq %rbx,%r11
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 48(%rsi),%rax
- mulq %rbp
- addq %rax,%r12
- adcq $0,%rdx
- addq %rbx,%r12
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 56(%rsi),%rax
- mulq %rbp
- addq %rax,%r13
- adcq $0,%rdx
- addq %rbx,%r13
- adcq $0,%rdx
- movq %rdx,%r14
- movq 48(%rdi),%rbp
- movq 0(%rsi),%rax
- mulq %rbp
- addq %rax,%r15
- adcq $0,%rdx
- movq %r15,568(%rsp)
- movq %rdx,%rbx
-
- movq 8(%rsi),%rax
- mulq %rbp
- addq %rax,%r8
- adcq $0,%rdx
- addq %rbx,%r8
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 16(%rsi),%rax
- mulq %rbp
- addq %rax,%r9
- adcq $0,%rdx
- addq %rbx,%r9
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 24(%rsi),%rax
- mulq %rbp
- addq %rax,%r10
- adcq $0,%rdx
- addq %rbx,%r10
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 32(%rsi),%rax
- mulq %rbp
- addq %rax,%r11
- adcq $0,%rdx
- addq %rbx,%r11
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 40(%rsi),%rax
- mulq %rbp
- addq %rax,%r12
- adcq $0,%rdx
- addq %rbx,%r12
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 48(%rsi),%rax
- mulq %rbp
- addq %rax,%r13
- adcq $0,%rdx
- addq %rbx,%r13
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 56(%rsi),%rax
- mulq %rbp
- addq %rax,%r14
- adcq $0,%rdx
- addq %rbx,%r14
- adcq $0,%rdx
- movq %rdx,%r15
- movq 56(%rdi),%rbp
- movq 0(%rsi),%rax
- mulq %rbp
- addq %rax,%r8
- adcq $0,%rdx
- movq %r8,576(%rsp)
- movq %rdx,%rbx
-
- movq 8(%rsi),%rax
- mulq %rbp
- addq %rax,%r9
- adcq $0,%rdx
- addq %rbx,%r9
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 16(%rsi),%rax
- mulq %rbp
- addq %rax,%r10
- adcq $0,%rdx
- addq %rbx,%r10
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 24(%rsi),%rax
- mulq %rbp
- addq %rax,%r11
- adcq $0,%rdx
- addq %rbx,%r11
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 32(%rsi),%rax
- mulq %rbp
- addq %rax,%r12
- adcq $0,%rdx
- addq %rbx,%r12
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 40(%rsi),%rax
- mulq %rbp
- addq %rax,%r13
- adcq $0,%rdx
- addq %rbx,%r13
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 48(%rsi),%rax
- mulq %rbp
- addq %rax,%r14
- adcq $0,%rdx
- addq %rbx,%r14
- adcq $0,%rdx
- movq %rdx,%rbx
-
- movq 56(%rsi),%rax
- mulq %rbp
- addq %rax,%r15
- adcq $0,%rdx
- addq %rbx,%r15
- adcq $0,%rdx
- movq %rdx,%r8
- movq %r9,584(%rsp)
- movq %r10,592(%rsp)
- movq %r11,600(%rsp)
- movq %r12,608(%rsp)
- movq %r13,616(%rsp)
- movq %r14,624(%rsp)
- movq %r15,632(%rsp)
- movq %r8,640(%rsp)
-
-
-
-
-
- jmp mont_reduce
-
-
-
-
-.p2align 4
-sqr_reduce:
- movq 16(%rsp),%rcx
-
-
-
- movq %r10,%rbx
-
- movq %r11,%rax
- mulq %rbx
- movq %rax,528(%rsp)
- movq %rdx,%r10
- movq %r12,%rax
- mulq %rbx
- addq %rax,%r10
- adcq $0,%rdx
- movq %rdx,%r11
- movq %r13,%rax
- mulq %rbx
- addq %rax,%r11
- adcq $0,%rdx
- movq %rdx,%r12
- movq %r14,%rax
- mulq %rbx
- addq %rax,%r12
- adcq $0,%rdx
- movq %rdx,%r13
- movq %r15,%rax
- mulq %rbx
- addq %rax,%r13
- adcq $0,%rdx
- movq %rdx,%r14
- movq %r8,%rax
- mulq %rbx
- addq %rax,%r14
- adcq $0,%rdx
- movq %rdx,%r15
- movq %r9,%rax
- mulq %rbx
- addq %rax,%r15
- adcq $0,%rdx
- movq %rdx,%rsi
-
- movq %r10,536(%rsp)
-
-
-
-
-
- movq 8(%rcx),%rbx
-
- movq 16(%rcx),%rax
- mulq %rbx
- addq %rax,%r11
- adcq $0,%rdx
- movq %r11,544(%rsp)
-
- movq %rdx,%r10
- movq 24(%rcx),%rax
- mulq %rbx
- addq %rax,%r12
- adcq $0,%rdx
- addq %r10,%r12
- adcq $0,%rdx
- movq %r12,552(%rsp)
-
- movq %rdx,%r10
- movq 32(%rcx),%rax
- mulq %rbx
- addq %rax,%r13
- adcq $0,%rdx
- addq %r10,%r13
- adcq $0,%rdx
-
- movq %rdx,%r10
- movq 40(%rcx),%rax
- mulq %rbx
- addq %rax,%r14
- adcq $0,%rdx
- addq %r10,%r14
- adcq $0,%rdx
-
- movq %rdx,%r10
- movq %r8,%rax
- mulq %rbx
- addq %rax,%r15
- adcq $0,%rdx
- addq %r10,%r15
- adcq $0,%rdx
-
- movq %rdx,%r10
- movq %r9,%rax
- mulq %rbx
- addq %rax,%rsi
- adcq $0,%rdx
- addq %r10,%rsi
- adcq $0,%rdx
-
- movq %rdx,%r11
-
-
-
-
- movq 16(%rcx),%rbx
-
- movq 24(%rcx),%rax
- mulq %rbx
- addq %rax,%r13
- adcq $0,%rdx
- movq %r13,560(%rsp)
-
- movq %rdx,%r10
- movq 32(%rcx),%rax
- mulq %rbx
- addq %rax,%r14
- adcq $0,%rdx
- addq %r10,%r14
- adcq $0,%rdx
- movq %r14,568(%rsp)
-
- movq %rdx,%r10
- movq 40(%rcx),%rax
- mulq %rbx
- addq %rax,%r15
- adcq $0,%rdx
- addq %r10,%r15
- adcq $0,%rdx
-
- movq %rdx,%r10
- movq %r8,%rax
- mulq %rbx
- addq %rax,%rsi
- adcq $0,%rdx
- addq %r10,%rsi
- adcq $0,%rdx
-
- movq %rdx,%r10
- movq %r9,%rax
- mulq %rbx
- addq %rax,%r11
- adcq $0,%rdx
- addq %r10,%r11
- adcq $0,%rdx
-
- movq %rdx,%r12
-
-
-
-
-
- movq 24(%rcx),%rbx
-
- movq 32(%rcx),%rax
- mulq %rbx
- addq %rax,%r15
- adcq $0,%rdx
- movq %r15,576(%rsp)
-
- movq %rdx,%r10
- movq 40(%rcx),%rax
- mulq %rbx
- addq %rax,%rsi
- adcq $0,%rdx
- addq %r10,%rsi
- adcq $0,%rdx
- movq %rsi,584(%rsp)
-
- movq %rdx,%r10
- movq %r8,%rax
- mulq %rbx
- addq %rax,%r11
- adcq $0,%rdx
- addq %r10,%r11
- adcq $0,%rdx
-
- movq %rdx,%r10
- movq %r9,%rax
- mulq %rbx
- addq %rax,%r12
- adcq $0,%rdx
- addq %r10,%r12
- adcq $0,%rdx
-
- movq %rdx,%r15
-
-
-
-
- movq 32(%rcx),%rbx
-
- movq 40(%rcx),%rax
- mulq %rbx
- addq %rax,%r11
- adcq $0,%rdx
- movq %r11,592(%rsp)
-
- movq %rdx,%r10
- movq %r8,%rax
- mulq %rbx
- addq %rax,%r12
- adcq $0,%rdx
- addq %r10,%r12
- adcq $0,%rdx
- movq %r12,600(%rsp)
-
- movq %rdx,%r10
- movq %r9,%rax
- mulq %rbx
- addq %rax,%r15
- adcq $0,%rdx
- addq %r10,%r15
- adcq $0,%rdx
-
- movq %rdx,%r11
-
-
-
-
- movq 40(%rcx),%rbx
-
- movq %r8,%rax
- mulq %rbx
- addq %rax,%r15
- adcq $0,%rdx
- movq %r15,608(%rsp)
-
- movq %rdx,%r10
- movq %r9,%rax
- mulq %rbx
- addq %rax,%r11
- adcq $0,%rdx
- addq %r10,%r11
- adcq $0,%rdx
- movq %r11,616(%rsp)
-
- movq %rdx,%r12
-
-
-
-
- movq %r8,%rbx
-
- movq %r9,%rax
- mulq %rbx
- addq %rax,%r12
- adcq $0,%rdx
- movq %r12,624(%rsp)
-
- movq %rdx,632(%rsp)
-
-
- movq 528(%rsp),%r10
- movq 536(%rsp),%r11
- movq 544(%rsp),%r12
- movq 552(%rsp),%r13
- movq 560(%rsp),%r14
- movq 568(%rsp),%r15
-
- movq 24(%rcx),%rax
- mulq %rax
- movq %rax,%rdi
- movq %rdx,%r8
-
- addq %r10,%r10
- adcq %r11,%r11
- adcq %r12,%r12
- adcq %r13,%r13
- adcq %r14,%r14
- adcq %r15,%r15
- adcq $0,%r8
-
- movq 0(%rcx),%rax
- mulq %rax
- movq %rax,520(%rsp)
- movq %rdx,%rbx
-
- movq 8(%rcx),%rax
- mulq %rax
-
- addq %rbx,%r10
- adcq %rax,%r11
- adcq $0,%rdx
-
- movq %rdx,%rbx
- movq %r10,528(%rsp)
- movq %r11,536(%rsp)
-
- movq 16(%rcx),%rax
- mulq %rax
-
- addq %rbx,%r12
- adcq %rax,%r13
- adcq $0,%rdx
-
- movq %rdx,%rbx
-
- movq %r12,544(%rsp)
- movq %r13,552(%rsp)
-
- xorq %rbp,%rbp
- addq %rbx,%r14
- adcq %rdi,%r15
- adcq $0,%rbp
-
- movq %r14,560(%rsp)
- movq %r15,568(%rsp)
-
-
-
-
- movq 576(%rsp),%r10
- movq 584(%rsp),%r11
- movq 592(%rsp),%r12
- movq 600(%rsp),%r13
- movq 608(%rsp),%r14
- movq 616(%rsp),%r15
- movq 624(%rsp),%rdi
- movq 632(%rsp),%rsi
-
- movq %r9,%rax
- mulq %rax
- movq %rax,%r9
- movq %rdx,%rbx
-
- addq %r10,%r10
- adcq %r11,%r11
- adcq %r12,%r12
- adcq %r13,%r13
- adcq %r14,%r14
- adcq %r15,%r15
- adcq %rdi,%rdi
- adcq %rsi,%rsi
- adcq $0,%rbx
-
- addq %rbp,%r10
-
- movq 32(%rcx),%rax
- mulq %rax
-
- addq %r8,%r10
- adcq %rax,%r11
- adcq $0,%rdx
-
- movq %rdx,%rbp
-
- movq %r10,576(%rsp)
- movq %r11,584(%rsp)
-
- movq 40(%rcx),%rax
- mulq %rax
-
- addq %rbp,%r12
- adcq %rax,%r13
- adcq $0,%rdx
-
- movq %rdx,%rbp
-
- movq %r12,592(%rsp)
- movq %r13,600(%rsp)
-
- movq 48(%rcx),%rax
- mulq %rax
-
- addq %rbp,%r14
- adcq %rax,%r15
- adcq $0,%rdx
-
- movq %r14,608(%rsp)
- movq %r15,616(%rsp)
-
- addq %rdx,%rdi
- adcq %r9,%rsi
- adcq $0,%rbx
-
- movq %rdi,624(%rsp)
- movq %rsi,632(%rsp)
- movq %rbx,640(%rsp)
-
- jmp mont_reduce
-
-
-
-.globl _mod_exp_512
-.private_extern _mod_exp_512
-
-_mod_exp_512:
- pushq %rbp
- pushq %rbx
- pushq %r12
- pushq %r13
- pushq %r14
- pushq %r15
-
-
- movq %rsp,%r8
- subq $2688,%rsp
- andq $-64,%rsp
-
-
- movq %r8,0(%rsp)
- movq %rdi,8(%rsp)
- movq %rsi,16(%rsp)
- movq %rcx,24(%rsp)
-L$body:
-
-
-
- pxor %xmm4,%xmm4
- movdqu 0(%rsi),%xmm0
- movdqu 16(%rsi),%xmm1
- movdqu 32(%rsi),%xmm2
- movdqu 48(%rsi),%xmm3
- movdqa %xmm4,512(%rsp)
- movdqa %xmm4,528(%rsp)
- movdqa %xmm4,608(%rsp)
- movdqa %xmm4,624(%rsp)
- movdqa %xmm0,544(%rsp)
- movdqa %xmm1,560(%rsp)
- movdqa %xmm2,576(%rsp)
- movdqa %xmm3,592(%rsp)
-
-
- movdqu 0(%rdx),%xmm0
- movdqu 16(%rdx),%xmm1
- movdqu 32(%rdx),%xmm2
- movdqu 48(%rdx),%xmm3
-
- leaq 384(%rsp),%rbx
- movq %rbx,136(%rsp)
- call mont_reduce
-
-
- leaq 448(%rsp),%rcx
- xorq %rax,%rax
- movq %rax,0(%rcx)
- movq %rax,8(%rcx)
- movq %rax,24(%rcx)
- movq %rax,32(%rcx)
- movq %rax,40(%rcx)
- movq %rax,48(%rcx)
- movq %rax,56(%rcx)
- movq %rax,128(%rsp)
- movq $1,16(%rcx)
-
- leaq 640(%rsp),%rbp
- movq %rcx,%rsi
- movq %rbp,%rdi
- movq $8,%rax
-loop_0:
- movq (%rcx),%rbx
- movw %bx,(%rdi)
- shrq $16,%rbx
- movw %bx,64(%rdi)
- shrq $16,%rbx
- movw %bx,128(%rdi)
- shrq $16,%rbx
- movw %bx,192(%rdi)
- leaq 8(%rcx),%rcx
- leaq 256(%rdi),%rdi
- decq %rax
- jnz loop_0
- movq $31,%rax
- movq %rax,32(%rsp)
- movq %rbp,40(%rsp)
-
- movq %rsi,136(%rsp)
- movq 0(%rsi),%r10
- movq 8(%rsi),%r11
- movq 16(%rsi),%r12
- movq 24(%rsi),%r13
- movq 32(%rsi),%r14
- movq 40(%rsi),%r15
- movq 48(%rsi),%r8
- movq 56(%rsi),%r9
-init_loop:
- leaq 384(%rsp),%rdi
- call mont_mul_a3b
- leaq 448(%rsp),%rsi
- movq 40(%rsp),%rbp
- addq $2,%rbp
- movq %rbp,40(%rsp)
- movq %rsi,%rcx
- movq $8,%rax
-loop_1:
- movq (%rcx),%rbx
- movw %bx,(%rbp)
- shrq $16,%rbx
- movw %bx,64(%rbp)
- shrq $16,%rbx
- movw %bx,128(%rbp)
- shrq $16,%rbx
- movw %bx,192(%rbp)
- leaq 8(%rcx),%rcx
- leaq 256(%rbp),%rbp
- decq %rax
- jnz loop_1
- movq 32(%rsp),%rax
- subq $1,%rax
- movq %rax,32(%rsp)
- jne init_loop
-
-
-
- movdqa %xmm0,64(%rsp)
- movdqa %xmm1,80(%rsp)
- movdqa %xmm2,96(%rsp)
- movdqa %xmm3,112(%rsp)
-
-
-
-
-
- movl 126(%rsp),%eax
- movq %rax,%rdx
- shrq $11,%rax
- andl $2047,%edx
- movl %edx,126(%rsp)
- leaq 640(%rsp,%rax,2),%rsi
- movq 8(%rsp),%rdx
- movq $4,%rbp
-loop_2:
- movzwq 192(%rsi),%rbx
- movzwq 448(%rsi),%rax
- shlq $16,%rbx
- shlq $16,%rax
- movw 128(%rsi),%bx
- movw 384(%rsi),%ax
- shlq $16,%rbx
- shlq $16,%rax
- movw 64(%rsi),%bx
- movw 320(%rsi),%ax
- shlq $16,%rbx
- shlq $16,%rax
- movw 0(%rsi),%bx
- movw 256(%rsi),%ax
- movq %rbx,0(%rdx)
- movq %rax,8(%rdx)
- leaq 512(%rsi),%rsi
- leaq 16(%rdx),%rdx
- subq $1,%rbp
- jnz loop_2
- movq $505,48(%rsp)
-
- movq 8(%rsp),%rcx
- movq %rcx,136(%rsp)
- movq 0(%rcx),%r10
- movq 8(%rcx),%r11
- movq 16(%rcx),%r12
- movq 24(%rcx),%r13
- movq 32(%rcx),%r14
- movq 40(%rcx),%r15
- movq 48(%rcx),%r8
- movq 56(%rcx),%r9
- jmp sqr_2
-
-main_loop_a3b:
- call sqr_reduce
- call sqr_reduce
- call sqr_reduce
-sqr_2:
- call sqr_reduce
- call sqr_reduce
-
-
-
- movq 48(%rsp),%rcx
- movq %rcx,%rax
- shrq $4,%rax
- movl 64(%rsp,%rax,2),%edx
- andq $15,%rcx
- shrq %cl,%rdx
- andq $31,%rdx
-
- leaq 640(%rsp,%rdx,2),%rsi
- leaq 448(%rsp),%rdx
- movq %rdx,%rdi
- movq $4,%rbp
-loop_3:
- movzwq 192(%rsi),%rbx
- movzwq 448(%rsi),%rax
- shlq $16,%rbx
- shlq $16,%rax
- movw 128(%rsi),%bx
- movw 384(%rsi),%ax
- shlq $16,%rbx
- shlq $16,%rax
- movw 64(%rsi),%bx
- movw 320(%rsi),%ax
- shlq $16,%rbx
- shlq $16,%rax
- movw 0(%rsi),%bx
- movw 256(%rsi),%ax
- movq %rbx,0(%rdx)
- movq %rax,8(%rdx)
- leaq 512(%rsi),%rsi
- leaq 16(%rdx),%rdx
- subq $1,%rbp
- jnz loop_3
- movq 8(%rsp),%rsi
- call mont_mul_a3b
-
-
-
- movq 48(%rsp),%rcx
- subq $5,%rcx
- movq %rcx,48(%rsp)
- jge main_loop_a3b
-
-
-
-end_main_loop_a3b:
-
-
- movq 8(%rsp),%rdx
- pxor %xmm4,%xmm4
- movdqu 0(%rdx),%xmm0
- movdqu 16(%rdx),%xmm1
- movdqu 32(%rdx),%xmm2
- movdqu 48(%rdx),%xmm3
- movdqa %xmm4,576(%rsp)
- movdqa %xmm4,592(%rsp)
- movdqa %xmm4,608(%rsp)
- movdqa %xmm4,624(%rsp)
- movdqa %xmm0,512(%rsp)
- movdqa %xmm1,528(%rsp)
- movdqa %xmm2,544(%rsp)
- movdqa %xmm3,560(%rsp)
- call mont_reduce
-
-
-
- movq 8(%rsp),%rax
- movq 0(%rax),%r8
- movq 8(%rax),%r9
- movq 16(%rax),%r10
- movq 24(%rax),%r11
- movq 32(%rax),%r12
- movq 40(%rax),%r13
- movq 48(%rax),%r14
- movq 56(%rax),%r15
-
-
- movq 24(%rsp),%rbx
- addq $512,%rbx
-
- subq 0(%rbx),%r8
- sbbq 8(%rbx),%r9
- sbbq 16(%rbx),%r10
- sbbq 24(%rbx),%r11
- sbbq 32(%rbx),%r12
- sbbq 40(%rbx),%r13
- sbbq 48(%rbx),%r14
- sbbq 56(%rbx),%r15
-
-
- movq 0(%rax),%rsi
- movq 8(%rax),%rdi
- movq 16(%rax),%rcx
- movq 24(%rax),%rdx
- cmovncq %r8,%rsi
- cmovncq %r9,%rdi
- cmovncq %r10,%rcx
- cmovncq %r11,%rdx
- movq %rsi,0(%rax)
- movq %rdi,8(%rax)
- movq %rcx,16(%rax)
- movq %rdx,24(%rax)
-
- movq 32(%rax),%rsi
- movq 40(%rax),%rdi
- movq 48(%rax),%rcx
- movq 56(%rax),%rdx
- cmovncq %r12,%rsi
- cmovncq %r13,%rdi
- cmovncq %r14,%rcx
- cmovncq %r15,%rdx
- movq %rsi,32(%rax)
- movq %rdi,40(%rax)
- movq %rcx,48(%rax)
- movq %rdx,56(%rax)
-
- movq 0(%rsp),%rsi
- movq 0(%rsi),%r15
- movq 8(%rsi),%r14
- movq 16(%rsi),%r13
- movq 24(%rsi),%r12
- movq 32(%rsi),%rbx
- movq 40(%rsi),%rbp
- leaq 48(%rsi),%rsp
-L$epilogue:
- .byte 0xf3,0xc3
-
-#endif
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/cpu-x86_64-asm.S b/mac-x86_64/crypto/cpu-x86_64-asm.S
deleted file mode 100644
index 0dde04d..0000000
--- a/mac-x86_64/crypto/cpu-x86_64-asm.S
+++ /dev/null
@@ -1,143 +0,0 @@
-#if defined(__x86_64__)
-.text
-
-.globl _OPENSSL_ia32_cpuid
-.private_extern _OPENSSL_ia32_cpuid
-
-.p2align 4
-_OPENSSL_ia32_cpuid:
-
-
- movq %rdi,%rdi
- movq %rbx,%r8
-
- xorl %eax,%eax
- movl %eax,8(%rdi)
- cpuid
- movl %eax,%r11d
-
- xorl %eax,%eax
- cmpl $1970169159,%ebx
- setne %al
- movl %eax,%r9d
- cmpl $1231384169,%edx
- setne %al
- orl %eax,%r9d
- cmpl $1818588270,%ecx
- setne %al
- orl %eax,%r9d
- jz L$intel
-
- cmpl $1752462657,%ebx
- setne %al
- movl %eax,%r10d
- cmpl $1769238117,%edx
- setne %al
- orl %eax,%r10d
- cmpl $1145913699,%ecx
- setne %al
- orl %eax,%r10d
- jnz L$intel
-
-
-
-
- movl $2147483648,%eax
- cpuid
-
-
- cmpl $2147483649,%eax
- jb L$intel
- movl %eax,%r10d
- movl $2147483649,%eax
- cpuid
-
-
- orl %ecx,%r9d
- andl $2049,%r9d
-
- cmpl $2147483656,%r10d
- jb L$intel
-
- movl $2147483656,%eax
- cpuid
-
- movzbq %cl,%r10
- incq %r10
-
- movl $1,%eax
- cpuid
-
- btl $28,%edx
- jnc L$generic
- shrl $16,%ebx
- cmpb %r10b,%bl
- ja L$generic
- andl $4026531839,%edx
- jmp L$generic
-
-L$intel:
- cmpl $4,%r11d
- movl $-1,%r10d
- jb L$nocacheinfo
-
- movl $4,%eax
- movl $0,%ecx
- cpuid
- movl %eax,%r10d
- shrl $14,%r10d
- andl $4095,%r10d
-
- cmpl $7,%r11d
- jb L$nocacheinfo
-
- movl $7,%eax
- xorl %ecx,%ecx
- cpuid
- movl %ebx,8(%rdi)
-
-L$nocacheinfo:
- movl $1,%eax
- cpuid
-
- andl $3220176895,%edx
- cmpl $0,%r9d
- jne L$notintel
- orl $1073741824,%edx
-L$notintel:
- btl $28,%edx
- jnc L$generic
- andl $4026531839,%edx
- cmpl $0,%r10d
- je L$generic
-
- orl $268435456,%edx
- shrl $16,%ebx
- cmpb $1,%bl
- ja L$generic
- andl $4026531839,%edx
-L$generic:
- andl $2048,%r9d
- andl $4294965247,%ecx
- orl %ecx,%r9d
-
- movl %edx,%r10d
- btl $27,%r9d
- jnc L$clear_avx
- xorl %ecx,%ecx
-.byte 0x0f,0x01,0xd0
- andl $6,%eax
- cmpl $6,%eax
- je L$done
-L$clear_avx:
- movl $4026525695,%eax
- andl %eax,%r9d
- andl $4294967263,8(%rdi)
-L$done:
- movl %r9d,4(%rdi)
- movl %r10d,0(%rdi)
- movq %r8,%rbx
- .byte 0xf3,0xc3
-
-
-#endif
diff --git a/mac-x86_64/crypto/ec/p256-x86_64-asm.S b/mac-x86_64/crypto/ec/p256-x86_64-asm.S
new file mode 100644
index 0000000..bed1130
--- /dev/null
+++ b/mac-x86_64/crypto/ec/p256-x86_64-asm.S
@@ -0,0 +1,1779 @@
+#if defined(__x86_64__)
+.text
+
+
+
+.p2align 6
+L$poly:
+.quad 0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001
+
+L$One:
+.long 1,1,1,1,1,1,1,1
+L$Two:
+.long 2,2,2,2,2,2,2,2
+L$Three:
+.long 3,3,3,3,3,3,3,3
+L$ONE_mont:
+.quad 0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe
+
+
+.p2align 6
+ecp_nistz256_mul_by_2:
+ pushq %r12
+ pushq %r13
+
+ movq 0(%rsi),%r8
+ movq 8(%rsi),%r9
+ addq %r8,%r8
+ movq 16(%rsi),%r10
+ adcq %r9,%r9
+ movq 24(%rsi),%r11
+ leaq L$poly(%rip),%rsi
+ movq %r8,%rax
+ adcq %r10,%r10
+ adcq %r11,%r11
+ movq %r9,%rdx
+ sbbq %r13,%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_neg
+.private_extern _ecp_nistz256_neg
+
+.p2align 5
+_ecp_nistz256_neg:
+ pushq %r12
+ pushq %r13
+
+ xorq %r8,%r8
+ xorq %r9,%r9
+ xorq %r10,%r10
+ xorq %r11,%r11
+ xorq %r13,%r13
+
+ subq 0(%rsi),%r8
+ sbbq 8(%rsi),%r9
+ sbbq 16(%rsi),%r10
+ movq %r8,%rax
+ sbbq 24(%rsi),%r11
+ leaq L$poly(%rip),%rsi
+ movq %r9,%rdx
+ sbbq $0,%r13
+
+ addq 0(%rsi),%r8
+ movq %r10,%rcx
+ adcq 8(%rsi),%r9
+ adcq 16(%rsi),%r10
+ movq %r11,%r12
+ adcq 24(%rsi),%r11
+ testq %r13,%r13
+
+ cmovzq %rax,%r8
+ cmovzq %rdx,%r9
+ movq %r8,0(%rdi)
+ cmovzq %rcx,%r10
+ movq %r9,8(%rdi)
+ cmovzq %r12,%r11
+ movq %r10,16(%rdi)
+ movq %r11,24(%rdi)
+
+ popq %r13
+ popq %r12
+ .byte 0xf3,0xc3
+
+
+
+
+
+
+
+.globl _ecp_nistz256_mul_mont
+.private_extern _ecp_nistz256_mul_mont
+
+.p2align 5
+_ecp_nistz256_mul_mont:
+L$mul_mont:
+ pushq %rbp
+ pushq %rbx
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ movq %rdx,%rbx
+ movq 0(%rdx),%rax
+ movq 0(%rsi),%r9
+ movq 8(%rsi),%r10
+ movq 16(%rsi),%r11
+ movq 24(%rsi),%r12
+
+ call __ecp_nistz256_mul_montq
+L$mul_mont_done:
+ popq %r15
+ popq %r14
+ popq %r13
+ popq %r12
+ popq %rbx
+ popq %rbp
+ .byte 0xf3,0xc3
+
+
+
+.p2align 5
+__ecp_nistz256_mul_montq:
+
+
+ movq %rax,%rbp
+ mulq %r9
+ movq L$poly+8(%rip),%r14
+ movq %rax,%r8
+ movq %rbp,%rax
+ movq %rdx,%r9
+
+ mulq %r10
+ movq L$poly+24(%rip),%r15
+ addq %rax,%r9
+ movq %rbp,%rax
+ adcq $0,%rdx
+ movq %rdx,%r10
+
+ mulq %r11
+ addq %rax,%r10
+ movq %rbp,%rax
+ adcq $0,%rdx
+ movq %rdx,%r11
+
+ mulq %r12
+ addq %rax,%r11
+ movq %r8,%rax
+ adcq $0,%rdx
+ xorq %r13,%r13
+ movq %rdx,%r12
+
+
+
+
+
+
+
+
+
+
+ movq %r8,%rbp
+ shlq $32,%r8
+ mulq %r15
+ shrq $32,%rbp
+ addq %r8,%r9
+ adcq %rbp,%r10
+ adcq %rax,%r11
+ movq 8(%rbx),%rax
+ adcq %rdx,%r12
+ adcq $0,%r13
+ xorq %r8,%r8
+
+
+
+ movq %rax,%rbp
+ mulq 0(%rsi)
+ addq %rax,%r9
+ movq %rbp,%rax
+ adcq $0,%rdx
+ movq %rdx,%rcx
+
+ mulq 8(%rsi)
+ addq %rcx,%r10
+ adcq $0,%rdx
+ addq %rax,%r10
+ movq %rbp,%rax
+ adcq $0,%rdx
+ movq %rdx,%rcx
+
+ mulq 16(%rsi)
+ addq %rcx,%r11
+ adcq $0,%rdx
+ addq %rax,%r11
+ movq %rbp,%rax
+ adcq $0,%rdx
+ movq %rdx,%rcx
+
+ mulq 24(%rsi)
+ addq %rcx,%r12
+ adcq $0,%rdx
+ addq %rax,%r12
+ movq %r9,%rax
+ adcq %rdx,%r13
+ adcq $0,%r8
+
+
+
+ movq %r9,%rbp
+ shlq $32,%r9
+ mulq %r15
+ shrq $32,%rbp
+ addq %r9,%r10
+ adcq %rbp,%r11
+ adcq %rax,%r12
+ movq 16(%rbx),%rax
+ adcq %rdx,%r13
+ adcq $0,%r8
+ xorq %r9,%r9
+
+
+
+ movq %rax,%rbp
+ mulq 0(%rsi)
+ addq %rax,%r10
+ movq %rbp,%rax
+ adcq $0,%rdx
+ movq %rdx,%rcx
+
+ mulq 8(%rsi)
+ addq %rcx,%r11
+ adcq $0,%rdx
+ addq %rax,%r11
+ movq %rbp,%rax
+ adcq $0,%rdx
+ movq %rdx,%rcx
+
+ mulq 16(%rsi)
+ addq %rcx,%r12
+ adcq $0,%rdx
+ addq %rax,%r12
+ movq %rbp,%rax
+ adcq $0,%rdx
+ movq %rdx,%rcx
+
+ mulq 24(%rsi)
+ addq %rcx,%r13
+ adcq $0,%rdx
+ addq %rax,%r13
+ movq %r10,%rax
+ adcq %rdx,%r8
+ adcq $0,%r9
+
+
+
+ movq %r10,%rbp
+ shlq $32,%r10
+ mulq %r15
+ shrq $32,%rbp
+ addq %r10,%r11
+ adcq %rbp,%r12
+ adcq %rax,%r13
+ movq 24(%rbx),%rax
+ adcq %rdx,%r8
+ adcq $0,%r9
+ xorq %r10,%r10
+
+
+
+ movq %rax,%rbp
+ mulq 0(%rsi)
+ addq %rax,%r11
+ movq %rbp,%rax
+ adcq $0,%rdx
+ movq %rdx,%rcx
+
+ mulq 8(%rsi)
+ addq %rcx,%r12
+ adcq $0,%rdx
+ addq %rax,%r12
+ movq %rbp,%rax
+ adcq $0,%rdx
+ movq %rdx,%rcx
+
+ mulq 16(%rsi)
+ addq %rcx,%r13
+ adcq $0,%rdx
+ addq %rax,%r13
+ movq %rbp,%rax
+ adcq $0,%rdx
+ movq %rdx,%rcx
+
+ mulq 24(%rsi)
+ addq %rcx,%r8
+ adcq $0,%rdx
+ addq %rax,%r8
+ movq %r11,%rax
+ adcq %rdx,%r9
+ adcq $0,%r10
+
+
+
+ movq %r11,%rbp
+ shlq $32,%r11
+ mulq %r15
+ shrq $32,%rbp
+ addq %r11,%r12
+ adcq %rbp,%r13
+ movq %r12,%rcx
+ adcq %rax,%r8
+ adcq %rdx,%r9
+ movq %r13,%rbp
+ adcq $0,%r10
+
+
+
+ subq $-1,%r12
+ movq %r8,%rbx
+ sbbq %r14,%r13
+ sbbq $0,%r8
+ movq %r9,%rdx
+ sbbq %r15,%r9
+ sbbq $0,%r10
+
+ cmovcq %rcx,%r12
+ cmovcq %rbp,%r13
+ movq %r12,0(%rdi)
+ cmovcq %rbx,%r8
+ movq %r13,8(%rdi)
+ cmovcq %rdx,%r9
+ movq %r8,16(%rdi)
+ movq %r9,24(%rdi)
+
+ .byte 0xf3,0xc3
+
+
+
+
+
+
+
+
+
+.globl _ecp_nistz256_sqr_mont
+.private_extern _ecp_nistz256_sqr_mont
+
+.p2align 5
+_ecp_nistz256_sqr_mont:
+ pushq %rbp
+ pushq %rbx
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ movq 0(%rsi),%rax
+ movq 8(%rsi),%r14
+ movq 16(%rsi),%r15
+ movq 24(%rsi),%r8
+
+ call __ecp_nistz256_sqr_montq
+L$sqr_mont_done:
+ popq %r15
+ popq %r14
+ popq %r13
+ popq %r12
+ popq %rbx
+ popq %rbp
+ .byte 0xf3,0xc3
+
+
+
+.p2align 5
+__ecp_nistz256_sqr_montq:
+ movq %rax,%r13
+ mulq %r14
+ movq %rax,%r9
+ movq %r15,%rax
+ movq %rdx,%r10
+
+ mulq %r13
+ addq %rax,%r10
+ movq %r8,%rax
+ adcq $0,%rdx
+ movq %rdx,%r11
+
+ mulq %r13
+ addq %rax,%r11
+ movq %r15,%rax
+ adcq $0,%rdx
+ movq %rdx,%r12
+
+
+ mulq %r14
+ addq %rax,%r11
+ movq %r8,%rax
+ adcq $0,%rdx
+ movq %rdx,%rbp
+
+ mulq %r14
+ addq %rax,%r12
+ movq %r8,%rax
+ adcq $0,%rdx
+ addq %rbp,%r12
+ movq %rdx,%r13
+ adcq $0,%r13
+
+
+ mulq %r15
+ xorq %r15,%r15
+ addq %rax,%r13
+ movq 0(%rsi),%rax
+ movq %rdx,%r14
+ adcq $0,%r14
+
+ addq %r9,%r9
+ adcq %r10,%r10
+ adcq %r11,%r11
+ adcq %r12,%r12
+ adcq %r13,%r13
+ adcq %r14,%r14
+ adcq $0,%r15
+
+ mulq %rax
+ movq %rax,%r8
+ movq 8(%rsi),%rax
+ movq %rdx,%rcx
+
+ mulq %rax
+ addq %rcx,%r9
+ adcq %rax,%r10
+ movq 16(%rsi),%rax
+ adcq $0,%rdx
+ movq %rdx,%rcx
+
+ mulq %rax
+ addq %rcx,%r11
+ adcq %rax,%r12
+ movq 24(%rsi),%rax
+ adcq $0,%rdx
+ movq %rdx,%rcx
+
+ mulq %rax
+ addq %rcx,%r13
+ adcq %rax,%r14
+ movq %r8,%rax
+ adcq %rdx,%r15
+
+ movq L$poly+8(%rip),%rsi
+ movq L$poly+24(%rip),%rbp
+
+
+
+
+ movq %r8,%rcx
+ shlq $32,%r8
+ mulq %rbp
+ shrq $32,%rcx
+ addq %r8,%r9
+ adcq %rcx,%r10
+ adcq %rax,%r11
+ movq %r9,%rax
+ adcq $0,%rdx
+
+
+
+ movq %r9,%rcx
+ shlq $32,%r9
+ movq %rdx,%r8
+ mulq %rbp
+ shrq $32,%rcx
+ addq %r9,%r10
+ adcq %rcx,%r11
+ adcq %rax,%r8
+ movq %r10,%rax
+ adcq $0,%rdx
+
+
+
+ movq %r10,%rcx
+ shlq $32,%r10
+ movq %rdx,%r9
+ mulq %rbp
+ shrq $32,%rcx
+ addq %r10,%r11
+ adcq %rcx,%r8
+ adcq %rax,%r9
+ movq %r11,%rax
+ adcq $0,%rdx
+
+
+
+ movq %r11,%rcx
+ shlq $32,%r11
+ movq %rdx,%r10
+ mulq %rbp
+ shrq $32,%rcx
+ addq %r11,%r8
+ adcq %rcx,%r9
+ adcq %rax,%r10
+ adcq $0,%rdx
+ xorq %r11,%r11
+
+
+
+ addq %r8,%r12
+ adcq %r9,%r13
+ movq %r12,%r8
+ adcq %r10,%r14
+ adcq %rdx,%r15
+ movq %r13,%r9
+ adcq $0,%r11
+
+ subq $-1,%r12
+ movq %r14,%r10
+ sbbq %rsi,%r13
+ sbbq $0,%r14
+ movq %r15,%rcx
+ sbbq %rbp,%r15
+ sbbq $0,%r11
+
+ cmovcq %r8,%r12
+ cmovcq %r9,%r13
+ movq %r12,0(%rdi)
+ cmovcq %r10,%r14
+ movq %r13,8(%rdi)
+ cmovcq %rcx,%r15
+ movq %r14,16(%rdi)
+ movq %r15,24(%rdi)
+
+ .byte 0xf3,0xc3
+
+
+
+
+
+
+
+.globl _ecp_nistz256_from_mont
+.private_extern _ecp_nistz256_from_mont
+
+.p2align 5
+_ecp_nistz256_from_mont:
+ pushq %r12
+ pushq %r13
+
+ movq 0(%rsi),%rax
+ movq L$poly+24(%rip),%r13
+ movq 8(%rsi),%r9
+ movq 16(%rsi),%r10
+ movq 24(%rsi),%r11
+ movq %rax,%r8
+ movq L$poly+8(%rip),%r12
+
+
+
+ movq %rax,%rcx
+ shlq $32,%r8
+ mulq %r13
+ shrq $32,%rcx
+ addq %r8,%r9
+ adcq %rcx,%r10
+ adcq %rax,%r11
+ movq %r9,%rax
+ adcq $0,%rdx
+
+
+
+ movq %r9,%rcx
+ shlq $32,%r9
+ movq %rdx,%r8
+ mulq %r13
+ shrq $32,%rcx
+ addq %r9,%r10
+ adcq %rcx,%r11
+ adcq %rax,%r8
+ movq %r10,%rax
+ adcq $0,%rdx
+
+
+
+ movq %r10,%rcx
+ shlq $32,%r10
+ movq %rdx,%r9
+ mulq %r13
+ shrq $32,%rcx
+ addq %r10,%r11
+ adcq %rcx,%r8
+ adcq %rax,%r9
+ movq %r11,%rax
+ adcq $0,%rdx
+
+
+
+ movq %r11,%rcx
+ shlq $32,%r11
+ movq %rdx,%r10
+ mulq %r13
+ shrq $32,%rcx
+ addq %r11,%r8
+ adcq %rcx,%r9
+ movq %r8,%rcx
+ adcq %rax,%r10
+ movq %r9,%rsi
+ adcq $0,%rdx
+
+ subq $-1,%r8
+ movq %r10,%rax
+ sbbq %r12,%r9
+ sbbq $0,%r10
+ movq %rdx,%r11
+ sbbq %r13,%rdx
+ sbbq %r13,%r13
+
+ cmovnzq %rcx,%r8
+ cmovnzq %rsi,%r9
+ movq %r8,0(%rdi)
+ cmovnzq %rax,%r10
+ movq %r9,8(%rdi)
+ cmovzq %rdx,%r11
+ movq %r10,16(%rdi)
+ movq %r11,24(%rdi)
+
+ popq %r13
+ popq %r12
+ .byte 0xf3,0xc3
+
+
+
+.globl _ecp_nistz256_select_w5
+.private_extern _ecp_nistz256_select_w5
+
+.p2align 5
+_ecp_nistz256_select_w5:
+ movdqa L$One(%rip),%xmm0
+ movd %edx,%xmm1
+
+ pxor %xmm2,%xmm2
+ pxor %xmm3,%xmm3
+ pxor %xmm4,%xmm4
+ pxor %xmm5,%xmm5
+ pxor %xmm6,%xmm6
+ pxor %xmm7,%xmm7
+
+ movdqa %xmm0,%xmm8
+ pshufd $0,%xmm1,%xmm1
+
+ movq $16,%rax
+L$select_loop_sse_w5:
+
+ movdqa %xmm8,%xmm15
+ paddd %xmm0,%xmm8
+ pcmpeqd %xmm1,%xmm15
+
+ movdqa 0(%rsi),%xmm9
+ movdqa 16(%rsi),%xmm10
+ movdqa 32(%rsi),%xmm11
+ movdqa 48(%rsi),%xmm12
+ movdqa 64(%rsi),%xmm13
+ movdqa 80(%rsi),%xmm14
+ leaq 96(%rsi),%rsi
+
+ pand %xmm15,%xmm9
+ pand %xmm15,%xmm10
+ por %xmm9,%xmm2
+ pand %xmm15,%xmm11
+ por %xmm10,%xmm3
+ pand %xmm15,%xmm12
+ por %xmm11,%xmm4
+ pand %xmm15,%xmm13
+ por %xmm12,%xmm5
+ pand %xmm15,%xmm14
+ por %xmm13,%xmm6
+ por %xmm14,%xmm7
+
+ decq %rax
+ jnz L$select_loop_sse_w5
+
+ movdqu %xmm2,0(%rdi)
+ movdqu %xmm3,16(%rdi)
+ movdqu %xmm4,32(%rdi)
+ movdqu %xmm5,48(%rdi)
+ movdqu %xmm6,64(%rdi)
+ movdqu %xmm7,80(%rdi)
+ .byte 0xf3,0xc3
+
+
+
+
+.globl _ecp_nistz256_select_w7
+.private_extern _ecp_nistz256_select_w7
+
+.p2align 5
+_ecp_nistz256_select_w7:
+ movdqa L$One(%rip),%xmm8
+ movd %edx,%xmm1
+
+ pxor %xmm2,%xmm2
+ pxor %xmm3,%xmm3
+ pxor %xmm4,%xmm4
+ pxor %xmm5,%xmm5
+
+ movdqa %xmm8,%xmm0
+ pshufd $0,%xmm1,%xmm1
+ movq $64,%rax
+
+L$select_loop_sse_w7:
+ movdqa %xmm8,%xmm15
+ paddd %xmm0,%xmm8
+ movdqa 0(%rsi),%xmm9
+ movdqa 16(%rsi),%xmm10
+ pcmpeqd %xmm1,%xmm15
+ movdqa 32(%rsi),%xmm11
+ movdqa 48(%rsi),%xmm12
+ leaq 64(%rsi),%rsi
+
+ pand %xmm15,%xmm9
+ pand %xmm15,%xmm10
+ por %xmm9,%xmm2
+ pand %xmm15,%xmm11
+ por %xmm10,%xmm3
+ pand %xmm15,%xmm12
+ por %xmm11,%xmm4
+ prefetcht0 255(%rsi)
+ por %xmm12,%xmm5
+
+ decq %rax
+ jnz L$select_loop_sse_w7
+
+ movdqu %xmm2,0(%rdi)
+ movdqu %xmm3,16(%rdi)
+ movdqu %xmm4,32(%rdi)
+ movdqu %xmm5,48(%rdi)
+ .byte 0xf3,0xc3
+
+.globl _ecp_nistz256_avx2_select_w7
+.private_extern _ecp_nistz256_avx2_select_w7
+
+.p2align 5
+_ecp_nistz256_avx2_select_w7:
+.byte 0x0f,0x0b
+ .byte 0xf3,0xc3
+
+
+.p2align 5
+__ecp_nistz256_add_toq:
+ addq 0(%rbx),%r12
+ adcq 8(%rbx),%r13
+ movq %r12,%rax
+ adcq 16(%rbx),%r8
+ adcq 24(%rbx),%r9
+ movq %r13,%rbp
+ sbbq %r11,%r11
+
+ subq $-1,%r12
+ movq %r8,%rcx
+ sbbq %r14,%r13
+ sbbq $0,%r8
+ movq %r9,%r10
+ sbbq %r15,%r9
+ testq %r11,%r11
+
+ cmovzq %rax,%r12
+ cmovzq %rbp,%r13
+ movq %r12,0(%rdi)
+ cmovzq %rcx,%r8
+ movq %r13,8(%rdi)
+ cmovzq %r10,%r9
+ movq %r8,16(%rdi)
+ movq %r9,24(%rdi)
+
+ .byte 0xf3,0xc3
+
+
+
+.p2align 5
+__ecp_nistz256_sub_fromq:
+ subq 0(%rbx),%r12
+ sbbq 8(%rbx),%r13
+ movq %r12,%rax
+ sbbq 16(%rbx),%r8
+ sbbq 24(%rbx),%r9
+ movq %r13,%rbp
+ sbbq %r11,%r11
+
+ addq $-1,%r12
+ movq %r8,%rcx
+ adcq %r14,%r13
+ adcq $0,%r8
+ movq %r9,%r10
+ adcq %r15,%r9
+ testq %r11,%r11
+
+ cmovzq %rax,%r12
+ cmovzq %rbp,%r13
+ movq %r12,0(%rdi)
+ cmovzq %rcx,%r8
+ movq %r13,8(%rdi)
+ cmovzq %r10,%r9
+ movq %r8,16(%rdi)
+ movq %r9,24(%rdi)
+
+ .byte 0xf3,0xc3
+
+
+
+.p2align 5
+__ecp_nistz256_subq:
+ subq %r12,%rax
+ sbbq %r13,%rbp
+ movq %rax,%r12
+ sbbq %r8,%rcx
+ sbbq %r9,%r10
+ movq %rbp,%r13
+ sbbq %r11,%r11
+
+ addq $-1,%rax
+ movq %rcx,%r8
+ adcq %r14,%rbp
+ adcq $0,%rcx
+ movq %r10,%r9
+ adcq %r15,%r10
+ testq %r11,%r11
+
+ cmovnzq %rax,%r12
+ cmovnzq %rbp,%r13
+ cmovnzq %rcx,%r8
+ cmovnzq %r10,%r9
+
+ .byte 0xf3,0xc3
+
+
+
+.p2align 5
+__ecp_nistz256_mul_by_2q:
+ addq %r12,%r12
+ adcq %r13,%r13
+ movq %r12,%rax
+ adcq %r8,%r8
+ adcq %r9,%r9
+ movq %r13,%rbp
+ sbbq %r11,%r11
+
+ subq $-1,%r12
+ movq %r8,%rcx
+ sbbq %r14,%r13
+ sbbq $0,%r8
+ movq %r9,%r10
+ sbbq %r15,%r9
+ testq %r11,%r11
+
+ cmovzq %rax,%r12
+ cmovzq %rbp,%r13
+ movq %r12,0(%rdi)
+ cmovzq %rcx,%r8
+ movq %r13,8(%rdi)
+ cmovzq %r10,%r9
+ movq %r8,16(%rdi)
+ movq %r9,24(%rdi)
+
+ .byte 0xf3,0xc3
+
+.globl _ecp_nistz256_point_double
+.private_extern _ecp_nistz256_point_double
+
+.p2align 5
+_ecp_nistz256_point_double:
+ pushq %rbp
+ pushq %rbx
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ subq $160+8,%rsp
+
+ movdqu 0(%rsi),%xmm0
+ movq %rsi,%rbx
+ movdqu 16(%rsi),%xmm1
+ movq 32+0(%rsi),%r12
+ movq 32+8(%rsi),%r13
+ movq 32+16(%rsi),%r8
+ movq 32+24(%rsi),%r9
+ movq L$poly+8(%rip),%r14
+ movq L$poly+24(%rip),%r15
+ movdqa %xmm0,96(%rsp)
+ movdqa %xmm1,96+16(%rsp)
+ leaq 32(%rdi),%r10
+ leaq 64(%rdi),%r11
+.byte 102,72,15,110,199
+.byte 102,73,15,110,202
+.byte 102,73,15,110,211
+
+ leaq 0(%rsp),%rdi
+ call __ecp_nistz256_mul_by_2q
+
+ movq 64+0(%rsi),%rax
+ movq 64+8(%rsi),%r14
+ movq 64+16(%rsi),%r15
+ movq 64+24(%rsi),%r8
+ leaq 64-0(%rsi),%rsi
+ leaq 64(%rsp),%rdi
+ call __ecp_nistz256_sqr_montq
+
+ movq 0+0(%rsp),%rax
+ movq 8+0(%rsp),%r14
+ leaq 0+0(%rsp),%rsi
+ movq 16+0(%rsp),%r15
+ movq 24+0(%rsp),%r8
+ leaq 0(%rsp),%rdi
+ call __ecp_nistz256_sqr_montq
+
+ movq 32(%rbx),%rax
+ movq 64+0(%rbx),%r9
+ movq 64+8(%rbx),%r10
+ movq 64+16(%rbx),%r11
+ movq 64+24(%rbx),%r12
+ leaq 64-0(%rbx),%rsi
+ leaq 32(%rbx),%rbx
+.byte 102,72,15,126,215
+ call __ecp_nistz256_mul_montq
+ call __ecp_nistz256_mul_by_2q
+
+ movq 96+0(%rsp),%r12
+ movq 96+8(%rsp),%r13
+ leaq 64(%rsp),%rbx
+ movq 96+16(%rsp),%r8
+ movq 96+24(%rsp),%r9
+ leaq 32(%rsp),%rdi
+ call __ecp_nistz256_add_toq
+
+ movq 96+0(%rsp),%r12
+ movq 96+8(%rsp),%r13
+ leaq 64(%rsp),%rbx
+ movq 96+16(%rsp),%r8
+ movq 96+24(%rsp),%r9
+ leaq 64(%rsp),%rdi
+ call __ecp_nistz256_sub_fromq
+
+ movq 0+0(%rsp),%rax
+ movq 8+0(%rsp),%r14
+ leaq 0+0(%rsp),%rsi
+ movq 16+0(%rsp),%r15
+ movq 24+0(%rsp),%r8
+.byte 102,72,15,126,207
+ call __ecp_nistz256_sqr_montq
+ xorq %r9,%r9
+ movq %r12,%rax
+ addq $-1,%r12
+ movq %r13,%r10
+ adcq %rsi,%r13
+ movq %r14,%rcx
+ adcq $0,%r14
+ movq %r15,%r8
+ adcq %rbp,%r15
+ adcq $0,%r9
+ xorq %rsi,%rsi
+ testq $1,%rax
+
+ cmovzq %rax,%r12
+ cmovzq %r10,%r13
+ cmovzq %rcx,%r14
+ cmovzq %r8,%r15
+ cmovzq %rsi,%r9
+
+ movq %r13,%rax
+ shrq $1,%r12
+ shlq $63,%rax
+ movq %r14,%r10
+ shrq $1,%r13
+ orq %rax,%r12
+ shlq $63,%r10
+ movq %r15,%rcx
+ shrq $1,%r14
+ orq %r10,%r13
+ shlq $63,%rcx
+ movq %r12,0(%rdi)
+ shrq $1,%r15
+ movq %r13,8(%rdi)
+ shlq $63,%r9
+ orq %rcx,%r14
+ orq %r9,%r15
+ movq %r14,16(%rdi)
+ movq %r15,24(%rdi)
+ movq 64(%rsp),%rax
+ leaq 64(%rsp),%rbx
+ movq 0+32(%rsp),%r9
+ movq 8+32(%rsp),%r10
+ leaq 0+32(%rsp),%rsi
+ movq 16+32(%rsp),%r11
+ movq 24+32(%rsp),%r12
+ leaq 32(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ leaq 128(%rsp),%rdi
+ call __ecp_nistz256_mul_by_2q
+
+ leaq 32(%rsp),%rbx
+ leaq 32(%rsp),%rdi
+ call __ecp_nistz256_add_toq
+
+ movq 96(%rsp),%rax
+ leaq 96(%rsp),%rbx
+ movq 0+0(%rsp),%r9
+ movq 8+0(%rsp),%r10
+ leaq 0+0(%rsp),%rsi
+ movq 16+0(%rsp),%r11
+ movq 24+0(%rsp),%r12
+ leaq 0(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ leaq 128(%rsp),%rdi
+ call __ecp_nistz256_mul_by_2q
+
+ movq 0+32(%rsp),%rax
+ movq 8+32(%rsp),%r14
+ leaq 0+32(%rsp),%rsi
+ movq 16+32(%rsp),%r15
+ movq 24+32(%rsp),%r8
+.byte 102,72,15,126,199
+ call __ecp_nistz256_sqr_montq
+
+ leaq 128(%rsp),%rbx
+ movq %r14,%r8
+ movq %r15,%r9
+ movq %rsi,%r14
+ movq %rbp,%r15
+ call __ecp_nistz256_sub_fromq
+
+ movq 0+0(%rsp),%rax
+ movq 0+8(%rsp),%rbp
+ movq 0+16(%rsp),%rcx
+ movq 0+24(%rsp),%r10
+ leaq 0(%rsp),%rdi
+ call __ecp_nistz256_subq
+
+ movq 32(%rsp),%rax
+ leaq 32(%rsp),%rbx
+ movq %r12,%r14
+ xorl %ecx,%ecx
+ movq %r12,0+0(%rsp)
+ movq %r13,%r10
+ movq %r13,0+8(%rsp)
+ cmovzq %r8,%r11
+ movq %r8,0+16(%rsp)
+ leaq 0-0(%rsp),%rsi
+ cmovzq %r9,%r12
+ movq %r9,0+24(%rsp)
+ movq %r14,%r9
+ leaq 0(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+.byte 102,72,15,126,203
+.byte 102,72,15,126,207
+ call __ecp_nistz256_sub_fromq
+
+ addq $160+8,%rsp
+ popq %r15
+ popq %r14
+ popq %r13
+ popq %r12
+ popq %rbx
+ popq %rbp
+ .byte 0xf3,0xc3
+
+.globl _ecp_nistz256_point_add
+.private_extern _ecp_nistz256_point_add
+
+.p2align 5
+_ecp_nistz256_point_add:
+ pushq %rbp
+ pushq %rbx
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ subq $576+8,%rsp
+
+ movdqu 0(%rsi),%xmm0
+ movdqu 16(%rsi),%xmm1
+ movdqu 32(%rsi),%xmm2
+ movdqu 48(%rsi),%xmm3
+ movdqu 64(%rsi),%xmm4
+ movdqu 80(%rsi),%xmm5
+ movq %rsi,%rbx
+ movq %rdx,%rsi
+ movdqa %xmm0,384(%rsp)
+ movdqa %xmm1,384+16(%rsp)
+ por %xmm0,%xmm1
+ movdqa %xmm2,416(%rsp)
+ movdqa %xmm3,416+16(%rsp)
+ por %xmm2,%xmm3
+ movdqa %xmm4,448(%rsp)
+ movdqa %xmm5,448+16(%rsp)
+ por %xmm1,%xmm3
+
+ movdqu 0(%rsi),%xmm0
+ pshufd $177,%xmm3,%xmm5
+ movdqu 16(%rsi),%xmm1
+ movdqu 32(%rsi),%xmm2
+ por %xmm3,%xmm5
+ movdqu 48(%rsi),%xmm3
+ movq 64+0(%rsi),%rax
+ movq 64+8(%rsi),%r14
+ movq 64+16(%rsi),%r15
+ movq 64+24(%rsi),%r8
+ movdqa %xmm0,480(%rsp)
+ pshufd $30,%xmm5,%xmm4
+ movdqa %xmm1,480+16(%rsp)
+ por %xmm0,%xmm1
+.byte 102,72,15,110,199
+ movdqa %xmm2,512(%rsp)
+ movdqa %xmm3,512+16(%rsp)
+ por %xmm2,%xmm3
+ por %xmm4,%xmm5
+ pxor %xmm4,%xmm4
+ por %xmm1,%xmm3
+
+ leaq 64-0(%rsi),%rsi
+ movq %rax,544+0(%rsp)
+ movq %r14,544+8(%rsp)
+ movq %r15,544+16(%rsp)
+ movq %r8,544+24(%rsp)
+ leaq 96(%rsp),%rdi
+ call __ecp_nistz256_sqr_montq
+
+ pcmpeqd %xmm4,%xmm5
+ pshufd $177,%xmm3,%xmm4
+ por %xmm3,%xmm4
+ pshufd $0,%xmm5,%xmm5
+ pshufd $30,%xmm4,%xmm3
+ por %xmm3,%xmm4
+ pxor %xmm3,%xmm3
+ pcmpeqd %xmm3,%xmm4
+ pshufd $0,%xmm4,%xmm4
+ movq 64+0(%rbx),%rax
+ movq 64+8(%rbx),%r14
+ movq 64+16(%rbx),%r15
+ movq 64+24(%rbx),%r8
+
+ leaq 64-0(%rbx),%rsi
+ leaq 32(%rsp),%rdi
+ call __ecp_nistz256_sqr_montq
+
+ movq 544(%rsp),%rax
+ leaq 544(%rsp),%rbx
+ movq 0+96(%rsp),%r9
+ movq 8+96(%rsp),%r10
+ leaq 0+96(%rsp),%rsi
+ movq 16+96(%rsp),%r11
+ movq 24+96(%rsp),%r12
+ leaq 224(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ movq 448(%rsp),%rax
+ leaq 448(%rsp),%rbx
+ movq 0+32(%rsp),%r9
+ movq 8+32(%rsp),%r10
+ leaq 0+32(%rsp),%rsi
+ movq 16+32(%rsp),%r11
+ movq 24+32(%rsp),%r12
+ leaq 256(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ movq 416(%rsp),%rax
+ leaq 416(%rsp),%rbx
+ movq 0+224(%rsp),%r9
+ movq 8+224(%rsp),%r10
+ leaq 0+224(%rsp),%rsi
+ movq 16+224(%rsp),%r11
+ movq 24+224(%rsp),%r12
+ leaq 224(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ movq 512(%rsp),%rax
+ leaq 512(%rsp),%rbx
+ movq 0+256(%rsp),%r9
+ movq 8+256(%rsp),%r10
+ leaq 0+256(%rsp),%rsi
+ movq 16+256(%rsp),%r11
+ movq 24+256(%rsp),%r12
+ leaq 256(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ leaq 224(%rsp),%rbx
+ leaq 64(%rsp),%rdi
+ call __ecp_nistz256_sub_fromq
+
+ orq %r13,%r12
+ movdqa %xmm4,%xmm2
+ orq %r8,%r12
+ orq %r9,%r12
+ por %xmm5,%xmm2
+.byte 102,73,15,110,220
+
+ movq 384(%rsp),%rax
+ leaq 384(%rsp),%rbx
+ movq 0+96(%rsp),%r9
+ movq 8+96(%rsp),%r10
+ leaq 0+96(%rsp),%rsi
+ movq 16+96(%rsp),%r11
+ movq 24+96(%rsp),%r12
+ leaq 160(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ movq 480(%rsp),%rax
+ leaq 480(%rsp),%rbx
+ movq 0+32(%rsp),%r9
+ movq 8+32(%rsp),%r10
+ leaq 0+32(%rsp),%rsi
+ movq 16+32(%rsp),%r11
+ movq 24+32(%rsp),%r12
+ leaq 192(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ leaq 160(%rsp),%rbx
+ leaq 0(%rsp),%rdi
+ call __ecp_nistz256_sub_fromq
+
+ orq %r13,%r12
+ orq %r8,%r12
+ orq %r9,%r12
+
+.byte 0x3e
+ jnz L$add_proceedq
+.byte 102,73,15,126,208
+.byte 102,73,15,126,217
+ testq %r8,%r8
+ jnz L$add_proceedq
+ testq %r9,%r9
+ jz L$add_proceedq
+
+.byte 102,72,15,126,199
+ pxor %xmm0,%xmm0
+ movdqu %xmm0,0(%rdi)
+ movdqu %xmm0,16(%rdi)
+ movdqu %xmm0,32(%rdi)
+ movdqu %xmm0,48(%rdi)
+ movdqu %xmm0,64(%rdi)
+ movdqu %xmm0,80(%rdi)
+ jmp L$add_doneq
+
+.p2align 5
+L$add_proceedq:
+ movq 0+64(%rsp),%rax
+ movq 8+64(%rsp),%r14
+ leaq 0+64(%rsp),%rsi
+ movq 16+64(%rsp),%r15
+ movq 24+64(%rsp),%r8
+ leaq 96(%rsp),%rdi
+ call __ecp_nistz256_sqr_montq
+
+ movq 448(%rsp),%rax
+ leaq 448(%rsp),%rbx
+ movq 0+0(%rsp),%r9
+ movq 8+0(%rsp),%r10
+ leaq 0+0(%rsp),%rsi
+ movq 16+0(%rsp),%r11
+ movq 24+0(%rsp),%r12
+ leaq 352(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ movq 0+0(%rsp),%rax
+ movq 8+0(%rsp),%r14
+ leaq 0+0(%rsp),%rsi
+ movq 16+0(%rsp),%r15
+ movq 24+0(%rsp),%r8
+ leaq 32(%rsp),%rdi
+ call __ecp_nistz256_sqr_montq
+
+ movq 544(%rsp),%rax
+ leaq 544(%rsp),%rbx
+ movq 0+352(%rsp),%r9
+ movq 8+352(%rsp),%r10
+ leaq 0+352(%rsp),%rsi
+ movq 16+352(%rsp),%r11
+ movq 24+352(%rsp),%r12
+ leaq 352(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ movq 0(%rsp),%rax
+ leaq 0(%rsp),%rbx
+ movq 0+32(%rsp),%r9
+ movq 8+32(%rsp),%r10
+ leaq 0+32(%rsp),%rsi
+ movq 16+32(%rsp),%r11
+ movq 24+32(%rsp),%r12
+ leaq 128(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ movq 160(%rsp),%rax
+ leaq 160(%rsp),%rbx
+ movq 0+32(%rsp),%r9
+ movq 8+32(%rsp),%r10
+ leaq 0+32(%rsp),%rsi
+ movq 16+32(%rsp),%r11
+ movq 24+32(%rsp),%r12
+ leaq 192(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+
+
+
+ addq %r12,%r12
+ leaq 96(%rsp),%rsi
+ adcq %r13,%r13
+ movq %r12,%rax
+ adcq %r8,%r8
+ adcq %r9,%r9
+ movq %r13,%rbp
+ sbbq %r11,%r11
+
+ subq $-1,%r12
+ movq %r8,%rcx
+ sbbq %r14,%r13
+ sbbq $0,%r8
+ movq %r9,%r10
+ sbbq %r15,%r9
+ testq %r11,%r11
+
+ cmovzq %rax,%r12
+ movq 0(%rsi),%rax
+ cmovzq %rbp,%r13
+ movq 8(%rsi),%rbp
+ cmovzq %rcx,%r8
+ movq 16(%rsi),%rcx
+ cmovzq %r10,%r9
+ movq 24(%rsi),%r10
+
+ call __ecp_nistz256_subq
+
+ leaq 128(%rsp),%rbx
+ leaq 288(%rsp),%rdi
+ call __ecp_nistz256_sub_fromq
+
+ movq 192+0(%rsp),%rax
+ movq 192+8(%rsp),%rbp
+ movq 192+16(%rsp),%rcx
+ movq 192+24(%rsp),%r10
+ leaq 320(%rsp),%rdi
+
+ call __ecp_nistz256_subq
+
+ movq %r12,0(%rdi)
+ movq %r13,8(%rdi)
+ movq %r8,16(%rdi)
+ movq %r9,24(%rdi)
+ movq 128(%rsp),%rax
+ leaq 128(%rsp),%rbx
+ movq 0+224(%rsp),%r9
+ movq 8+224(%rsp),%r10
+ leaq 0+224(%rsp),%rsi
+ movq 16+224(%rsp),%r11
+ movq 24+224(%rsp),%r12
+ leaq 256(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ movq 320(%rsp),%rax
+ leaq 320(%rsp),%rbx
+ movq 0+64(%rsp),%r9
+ movq 8+64(%rsp),%r10
+ leaq 0+64(%rsp),%rsi
+ movq 16+64(%rsp),%r11
+ movq 24+64(%rsp),%r12
+ leaq 320(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ leaq 256(%rsp),%rbx
+ leaq 320(%rsp),%rdi
+ call __ecp_nistz256_sub_fromq
+
+.byte 102,72,15,126,199
+
+ movdqa %xmm5,%xmm0
+ movdqa %xmm5,%xmm1
+ pandn 352(%rsp),%xmm0
+ movdqa %xmm5,%xmm2
+ pandn 352+16(%rsp),%xmm1
+ movdqa %xmm5,%xmm3
+ pand 544(%rsp),%xmm2
+ pand 544+16(%rsp),%xmm3
+ por %xmm0,%xmm2
+ por %xmm1,%xmm3
+
+ movdqa %xmm4,%xmm0
+ movdqa %xmm4,%xmm1
+ pandn %xmm2,%xmm0
+ movdqa %xmm4,%xmm2
+ pandn %xmm3,%xmm1
+ movdqa %xmm4,%xmm3
+ pand 448(%rsp),%xmm2
+ pand 448+16(%rsp),%xmm3
+ por %xmm0,%xmm2
+ por %xmm1,%xmm3
+ movdqu %xmm2,64(%rdi)
+ movdqu %xmm3,80(%rdi)
+
+ movdqa %xmm5,%xmm0
+ movdqa %xmm5,%xmm1
+ pandn 288(%rsp),%xmm0
+ movdqa %xmm5,%xmm2
+ pandn 288+16(%rsp),%xmm1
+ movdqa %xmm5,%xmm3
+ pand 480(%rsp),%xmm2
+ pand 480+16(%rsp),%xmm3
+ por %xmm0,%xmm2
+ por %xmm1,%xmm3
+
+ movdqa %xmm4,%xmm0
+ movdqa %xmm4,%xmm1
+ pandn %xmm2,%xmm0
+ movdqa %xmm4,%xmm2
+ pandn %xmm3,%xmm1
+ movdqa %xmm4,%xmm3
+ pand 384(%rsp),%xmm2
+ pand 384+16(%rsp),%xmm3
+ por %xmm0,%xmm2
+ por %xmm1,%xmm3
+ movdqu %xmm2,0(%rdi)
+ movdqu %xmm3,16(%rdi)
+
+ movdqa %xmm5,%xmm0
+ movdqa %xmm5,%xmm1
+ pandn 320(%rsp),%xmm0
+ movdqa %xmm5,%xmm2
+ pandn 320+16(%rsp),%xmm1
+ movdqa %xmm5,%xmm3
+ pand 512(%rsp),%xmm2
+ pand 512+16(%rsp),%xmm3
+ por %xmm0,%xmm2
+ por %xmm1,%xmm3
+
+ movdqa %xmm4,%xmm0
+ movdqa %xmm4,%xmm1
+ pandn %xmm2,%xmm0
+ movdqa %xmm4,%xmm2
+ pandn %xmm3,%xmm1
+ movdqa %xmm4,%xmm3
+ pand 416(%rsp),%xmm2
+ pand 416+16(%rsp),%xmm3
+ por %xmm0,%xmm2
+ por %xmm1,%xmm3
+ movdqu %xmm2,32(%rdi)
+ movdqu %xmm3,48(%rdi)
+
+L$add_doneq:
+ addq $576+8,%rsp
+ popq %r15
+ popq %r14
+ popq %r13
+ popq %r12
+ popq %rbx
+ popq %rbp
+ .byte 0xf3,0xc3
+
+.globl _ecp_nistz256_point_add_affine
+.private_extern _ecp_nistz256_point_add_affine
+
+.p2align 5
+_ecp_nistz256_point_add_affine:
+ pushq %rbp
+ pushq %rbx
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ subq $480+8,%rsp
+
+ movdqu 0(%rsi),%xmm0
+ movq %rdx,%rbx
+ movdqu 16(%rsi),%xmm1
+ movdqu 32(%rsi),%xmm2
+ movdqu 48(%rsi),%xmm3
+ movdqu 64(%rsi),%xmm4
+ movdqu 80(%rsi),%xmm5
+ movq 64+0(%rsi),%rax
+ movq 64+8(%rsi),%r14
+ movq 64+16(%rsi),%r15
+ movq 64+24(%rsi),%r8
+ movdqa %xmm0,320(%rsp)
+ movdqa %xmm1,320+16(%rsp)
+ por %xmm0,%xmm1
+ movdqa %xmm2,352(%rsp)
+ movdqa %xmm3,352+16(%rsp)
+ por %xmm2,%xmm3
+ movdqa %xmm4,384(%rsp)
+ movdqa %xmm5,384+16(%rsp)
+ por %xmm1,%xmm3
+
+ movdqu 0(%rbx),%xmm0
+ pshufd $177,%xmm3,%xmm5
+ movdqu 16(%rbx),%xmm1
+ movdqu 32(%rbx),%xmm2
+ por %xmm3,%xmm5
+ movdqu 48(%rbx),%xmm3
+ movdqa %xmm0,416(%rsp)
+ pshufd $30,%xmm5,%xmm4
+ movdqa %xmm1,416+16(%rsp)
+ por %xmm0,%xmm1
+.byte 102,72,15,110,199
+ movdqa %xmm2,448(%rsp)
+ movdqa %xmm3,448+16(%rsp)
+ por %xmm2,%xmm3
+ por %xmm4,%xmm5
+ pxor %xmm4,%xmm4
+ por %xmm1,%xmm3
+
+ leaq 64-0(%rsi),%rsi
+ leaq 32(%rsp),%rdi
+ call __ecp_nistz256_sqr_montq
+
+ pcmpeqd %xmm4,%xmm5
+ pshufd $177,%xmm3,%xmm4
+ movq 0(%rbx),%rax
+
+ movq %r12,%r9
+ por %xmm3,%xmm4
+ pshufd $0,%xmm5,%xmm5
+ pshufd $30,%xmm4,%xmm3
+ movq %r13,%r10
+ por %xmm3,%xmm4
+ pxor %xmm3,%xmm3
+ movq %r14,%r11
+ pcmpeqd %xmm3,%xmm4
+ pshufd $0,%xmm4,%xmm4
+
+ leaq 32-0(%rsp),%rsi
+ movq %r15,%r12
+ leaq 0(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ leaq 320(%rsp),%rbx
+ leaq 64(%rsp),%rdi
+ call __ecp_nistz256_sub_fromq
+
+ movq 384(%rsp),%rax
+ leaq 384(%rsp),%rbx
+ movq 0+32(%rsp),%r9
+ movq 8+32(%rsp),%r10
+ leaq 0+32(%rsp),%rsi
+ movq 16+32(%rsp),%r11
+ movq 24+32(%rsp),%r12
+ leaq 32(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ movq 384(%rsp),%rax
+ leaq 384(%rsp),%rbx
+ movq 0+64(%rsp),%r9
+ movq 8+64(%rsp),%r10
+ leaq 0+64(%rsp),%rsi
+ movq 16+64(%rsp),%r11
+ movq 24+64(%rsp),%r12
+ leaq 288(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ movq 448(%rsp),%rax
+ leaq 448(%rsp),%rbx
+ movq 0+32(%rsp),%r9
+ movq 8+32(%rsp),%r10
+ leaq 0+32(%rsp),%rsi
+ movq 16+32(%rsp),%r11
+ movq 24+32(%rsp),%r12
+ leaq 32(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ leaq 352(%rsp),%rbx
+ leaq 96(%rsp),%rdi
+ call __ecp_nistz256_sub_fromq
+
+ movq 0+64(%rsp),%rax
+ movq 8+64(%rsp),%r14
+ leaq 0+64(%rsp),%rsi
+ movq 16+64(%rsp),%r15
+ movq 24+64(%rsp),%r8
+ leaq 128(%rsp),%rdi
+ call __ecp_nistz256_sqr_montq
+
+ movq 0+96(%rsp),%rax
+ movq 8+96(%rsp),%r14
+ leaq 0+96(%rsp),%rsi
+ movq 16+96(%rsp),%r15
+ movq 24+96(%rsp),%r8
+ leaq 192(%rsp),%rdi
+ call __ecp_nistz256_sqr_montq
+
+ movq 128(%rsp),%rax
+ leaq 128(%rsp),%rbx
+ movq 0+64(%rsp),%r9
+ movq 8+64(%rsp),%r10
+ leaq 0+64(%rsp),%rsi
+ movq 16+64(%rsp),%r11
+ movq 24+64(%rsp),%r12
+ leaq 160(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ movq 320(%rsp),%rax
+ leaq 320(%rsp),%rbx
+ movq 0+128(%rsp),%r9
+ movq 8+128(%rsp),%r10
+ leaq 0+128(%rsp),%rsi
+ movq 16+128(%rsp),%r11
+ movq 24+128(%rsp),%r12
+ leaq 0(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+
+
+
+ addq %r12,%r12
+ leaq 192(%rsp),%rsi
+ adcq %r13,%r13
+ movq %r12,%rax
+ adcq %r8,%r8
+ adcq %r9,%r9
+ movq %r13,%rbp
+ sbbq %r11,%r11
+
+ subq $-1,%r12
+ movq %r8,%rcx
+ sbbq %r14,%r13
+ sbbq $0,%r8
+ movq %r9,%r10
+ sbbq %r15,%r9
+ testq %r11,%r11
+
+ cmovzq %rax,%r12
+ movq 0(%rsi),%rax
+ cmovzq %rbp,%r13
+ movq 8(%rsi),%rbp
+ cmovzq %rcx,%r8
+ movq 16(%rsi),%rcx
+ cmovzq %r10,%r9
+ movq 24(%rsi),%r10
+
+ call __ecp_nistz256_subq
+
+ leaq 160(%rsp),%rbx
+ leaq 224(%rsp),%rdi
+ call __ecp_nistz256_sub_fromq
+
+ movq 0+0(%rsp),%rax
+ movq 0+8(%rsp),%rbp
+ movq 0+16(%rsp),%rcx
+ movq 0+24(%rsp),%r10
+ leaq 64(%rsp),%rdi
+
+ call __ecp_nistz256_subq
+
+ movq %r12,0(%rdi)
+ movq %r13,8(%rdi)
+ movq %r8,16(%rdi)
+ movq %r9,24(%rdi)
+ movq 352(%rsp),%rax
+ leaq 352(%rsp),%rbx
+ movq 0+160(%rsp),%r9
+ movq 8+160(%rsp),%r10
+ leaq 0+160(%rsp),%rsi
+ movq 16+160(%rsp),%r11
+ movq 24+160(%rsp),%r12
+ leaq 32(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ movq 96(%rsp),%rax
+ leaq 96(%rsp),%rbx
+ movq 0+64(%rsp),%r9
+ movq 8+64(%rsp),%r10
+ leaq 0+64(%rsp),%rsi
+ movq 16+64(%rsp),%r11
+ movq 24+64(%rsp),%r12
+ leaq 64(%rsp),%rdi
+ call __ecp_nistz256_mul_montq
+
+ leaq 32(%rsp),%rbx
+ leaq 256(%rsp),%rdi
+ call __ecp_nistz256_sub_fromq
+
+.byte 102,72,15,126,199
+
+ movdqa %xmm5,%xmm0
+ movdqa %xmm5,%xmm1
+ pandn 288(%rsp),%xmm0
+ movdqa %xmm5,%xmm2
+ pandn 288+16(%rsp),%xmm1
+ movdqa %xmm5,%xmm3
+ pand L$ONE_mont(%rip),%xmm2
+ pand L$ONE_mont+16(%rip),%xmm3
+ por %xmm0,%xmm2
+ por %xmm1,%xmm3
+
+ movdqa %xmm4,%xmm0
+ movdqa %xmm4,%xmm1
+ pandn %xmm2,%xmm0
+ movdqa %xmm4,%xmm2
+ pandn %xmm3,%xmm1
+ movdqa %xmm4,%xmm3
+ pand 384(%rsp),%xmm2
+ pand 384+16(%rsp),%xmm3
+ por %xmm0,%xmm2
+ por %xmm1,%xmm3
+ movdqu %xmm2,64(%rdi)
+ movdqu %xmm3,80(%rdi)
+
+ movdqa %xmm5,%xmm0
+ movdqa %xmm5,%xmm1
+ pandn 224(%rsp),%xmm0
+ movdqa %xmm5,%xmm2
+ pandn 224+16(%rsp),%xmm1
+ movdqa %xmm5,%xmm3
+ pand 416(%rsp),%xmm2
+ pand 416+16(%rsp),%xmm3
+ por %xmm0,%xmm2
+ por %xmm1,%xmm3
+
+ movdqa %xmm4,%xmm0
+ movdqa %xmm4,%xmm1
+ pandn %xmm2,%xmm0
+ movdqa %xmm4,%xmm2
+ pandn %xmm3,%xmm1
+ movdqa %xmm4,%xmm3
+ pand 320(%rsp),%xmm2
+ pand 320+16(%rsp),%xmm3
+ por %xmm0,%xmm2
+ por %xmm1,%xmm3
+ movdqu %xmm2,0(%rdi)
+ movdqu %xmm3,16(%rdi)
+
+ movdqa %xmm5,%xmm0
+ movdqa %xmm5,%xmm1
+ pandn 256(%rsp),%xmm0
+ movdqa %xmm5,%xmm2
+ pandn 256+16(%rsp),%xmm1
+ movdqa %xmm5,%xmm3
+ pand 448(%rsp),%xmm2
+ pand 448+16(%rsp),%xmm3
+ por %xmm0,%xmm2
+ por %xmm1,%xmm3
+
+ movdqa %xmm4,%xmm0
+ movdqa %xmm4,%xmm1
+ pandn %xmm2,%xmm0
+ movdqa %xmm4,%xmm2
+ pandn %xmm3,%xmm1
+ movdqa %xmm4,%xmm3
+ pand 352(%rsp),%xmm2
+ pand 352+16(%rsp),%xmm3
+ por %xmm0,%xmm2
+ por %xmm1,%xmm3
+ movdqu %xmm2,32(%rdi)
+ movdqu %xmm3,48(%rdi)
+
+ addq $480+8,%rsp
+ popq %r15
+ popq %r14
+ popq %r13
+ popq %r12
+ popq %rbx
+ popq %rbp
+ .byte 0xf3,0xc3
+
+#endif
diff --git a/mac-x86_64/crypto/rand/rdrand-x86_64.S b/mac-x86_64/crypto/rand/rdrand-x86_64.S
index 1ba990f..f0df296 100644
--- a/mac-x86_64/crypto/rand/rdrand-x86_64.S
+++ b/mac-x86_64/crypto/rand/rdrand-x86_64.S
@@ -1,11 +1,48 @@
#if defined(__x86_64__)
.text
+
+
+
.globl _CRYPTO_rdrand
.private_extern _CRYPTO_rdrand
.p2align 4
_CRYPTO_rdrand:
-.byte 0x48, 0x0f, 0xc7, 0xf0
+ xorq %rax,%rax
+
+
+.byte 0x48, 0x0f, 0xc7, 0xf1
+
+ adcq %rax,%rax
+ movq %rcx,0(%rdi)
+ .byte 0xf3,0xc3
+
+
+
+
+
+.globl _CRYPTO_rdrand_multiple8_buf
+.private_extern _CRYPTO_rdrand_multiple8_buf
+
+.p2align 4
+_CRYPTO_rdrand_multiple8_buf:
+ testq %rsi,%rsi
+ jz L$out
+ movq $8,%rdx
+L$loop:
+
+
+.byte 0x48, 0x0f, 0xc7, 0xf1
+ jnc L$err
+ movq %rcx,0(%rdi)
+ addq %rdx,%rdi
+ subq %rdx,%rsi
+ jnz L$loop
+L$out:
+ movq $1,%rax
+ .byte 0xf3,0xc3
+L$err:
+ xorq %rax,%rax
.byte 0xf3,0xc3
#endif
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/rules.mk b/rules.mk
index 5f4960b..e2d5ae3 100644
--- a/rules.mk
+++ b/rules.mk
@@ -20,12 +20,15 @@ LOCAL_PATH := $(GET_LOCAL_DIR)
MODULE := $(LOCAL_DIR)
+MODULE_STATIC_LIB := true
+
TARGET_ARCH := $(ARCH)
TARGET_2ND_ARCH := $(ARCH)
# Reset local variables
LOCAL_CFLAGS :=
LOCAL_C_INCLUDES :=
+LOCAL_SRC_FILES :=
LOCAL_SRC_FILES_$(TARGET_ARCH) :=
LOCAL_SRC_FILES_$(TARGET_2ND_ARCH) :=
LOCAL_CFLAGS_$(TARGET_ARCH) :=
@@ -57,6 +60,17 @@ LOCAL_SRC_FILES := $(filter-out src/crypto/x509v3/v3_utl.c,$(LOCAL_SRC_FILES))
# no-op threading functions.
MODULE_CFLAGS += -DTRUSTY
+# Define static armcap based on lk build variables
+MODULE_STATIC_ARMCAP := -DOPENSSL_STATIC_ARMCAP
+toarmcap = $(if $(filter-out 0 false,$(2)),-DOPENSSL_STATIC_ARMCAP_$(1),)
+MODULE_STATIC_ARMCAP += $(call toarmcap,NEON,$(USE_ARM_V7_NEON))
+MODULE_STATIC_ARMCAP += $(call toarmcap,AES,$(USE_ARM_V8_AES))
+MODULE_STATIC_ARMCAP += $(call toarmcap,PMULL,$(USE_ARM_V8_PMULL))
+MODULE_STATIC_ARMCAP += $(call toarmcap,SHA1,$(USE_ARM_V8_SHA1))
+MODULE_STATIC_ARMCAP += $(call toarmcap,SHA256,$(USE_ARM_V8_SHA2))
+MODULE_CFLAGS += $(MODULE_STATIC_ARMCAP)
+MODULE_ASMFLAGS += $(MODULE_STATIC_ARMCAP)
+
MODULE_SRCS += $(addprefix $(LOCAL_DIR)/,$(LOCAL_SRC_FILES))
MODULE_SRCS += $(addprefix $(LOCAL_DIR)/,$(LOCAL_SRC_FILES_$(ARCH)))
LOCAL_C_INCLUDES := src/crypto src/include
@@ -65,6 +79,5 @@ GLOBAL_INCLUDES += $(addprefix $(LOCAL_DIR)/,$(LOCAL_C_INCLUDES))
MODULE_DEPS := \
lib/openssl-stubs \
- lib/libc-trusty
include make/module.mk
diff --git a/sources.mk b/sources.mk
index cdb7abc..e82f3d5 100644
--- a/sources.mk
+++ b/sources.mk
@@ -70,6 +70,7 @@ crypto_sources := \
src/crypto/bn/add.c\
src/crypto/bn/asm/x86_64-gcc.c\
src/crypto/bn/bn.c\
+ src/crypto/bn/bn_asn1.c\
src/crypto/bn/cmp.c\
src/crypto/bn/convert.c\
src/crypto/bn/ctx.c\
@@ -108,11 +109,12 @@ 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\
src/crypto/dh/dh_asn1.c\
- src/crypto/dh/dh_impl.c\
src/crypto/dh/params.c\
src/crypto/digest/digest.c\
src/crypto/digest/digests.c\
@@ -120,13 +122,14 @@ crypto_sources := \
src/crypto/directory_win.c\
src/crypto/dsa/dsa.c\
src/crypto/dsa/dsa_asn1.c\
- src/crypto/dsa/dsa_impl.c\
src/crypto/ec/ec.c\
src/crypto/ec/ec_asn1.c\
src/crypto/ec/ec_key.c\
src/crypto/ec/ec_montgomery.c\
src/crypto/ec/oct.c\
+ src/crypto/ec/p224-64.c\
src/crypto/ec/p256-64.c\
+ src/crypto/ec/p256-x86_64.c\
src/crypto/ec/simple.c\
src/crypto/ec/util-64.c\
src/crypto/ec/wnaf.c\
@@ -136,15 +139,13 @@ crypto_sources := \
src/crypto/engine/engine.c\
src/crypto/err/err.c\
src/crypto/evp/algorithm.c\
- src/crypto/evp/asn1.c\
src/crypto/evp/digestsign.c\
src/crypto/evp/evp.c\
+ src/crypto/evp/evp_asn1.c\
src/crypto/evp/evp_ctx.c\
src/crypto/evp/p_dsa_asn1.c\
src/crypto/evp/p_ec.c\
src/crypto/evp/p_ec_asn1.c\
- src/crypto/evp/p_hmac.c\
- src/crypto/evp/p_hmac_asn1.c\
src/crypto/evp/p_rsa.c\
src/crypto/evp/p_rsa_asn1.c\
src/crypto/evp/pbkdf.c\
@@ -178,7 +179,6 @@ crypto_sources := \
src/crypto/poly1305/poly1305.c\
src/crypto/poly1305/poly1305_arm.c\
src/crypto/poly1305/poly1305_vec.c\
- src/crypto/rand/hwrand.c\
src/crypto/rand/rand.c\
src/crypto/rand/urandom.c\
src/crypto/rand/windows.c\
@@ -209,6 +209,7 @@ crypto_sources := \
src/crypto/x509/i2d_pr.c\
src/crypto/x509/pkcs7.c\
src/crypto/x509/t_crl.c\
+ src/crypto/x509/t_req.c\
src/crypto/x509/t_x509.c\
src/crypto/x509/t_x509a.c\
src/crypto/x509/x509.c\
@@ -281,6 +282,7 @@ crypto_sources := \
src/crypto/x509v3/v3_utl.c\
ssl_sources := \
+ src/ssl/custom_extensions.c\
src/ssl/d1_both.c\
src/ssl/d1_clnt.c\
src/ssl/d1_lib.c\
@@ -288,6 +290,7 @@ ssl_sources := \
src/ssl/d1_pkt.c\
src/ssl/d1_srtp.c\
src/ssl/d1_srvr.c\
+ src/ssl/dtls_record.c\
src/ssl/pqueue/pqueue.c\
src/ssl/s3_both.c\
src/ssl/s3_clnt.c\
@@ -297,24 +300,28 @@ ssl_sources := \
src/ssl/s3_pkt.c\
src/ssl/s3_srvr.c\
src/ssl/ssl_aead_ctx.c\
- src/ssl/ssl_algs.c\
src/ssl/ssl_asn1.c\
+ 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\
- src/ssl/ssl_sess.c\
+ src/ssl/ssl_session.c\
src/ssl/ssl_stat.c\
- src/ssl/ssl_txt.c\
src/ssl/t1_enc.c\
src/ssl/t1_lib.c\
- src/ssl/t1_reneg.c\
+ src/ssl/tls_record.c\
tool_sources := \
src/tool/args.cc\
+ src/tool/ciphers.cc\
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\
src/tool/server.cc\
@@ -323,24 +330,26 @@ tool_sources := \
src/tool/transport_common.cc\
linux_aarch64_sources := \
- linux-aarch64/crypto/aes/aesv8-armx.S\
- linux-aarch64/crypto/modes/ghashv8-armx.S\
+ linux-aarch64/crypto/aes/aesv8-armx64.S\
+ linux-aarch64/crypto/bn/armv8-mont.S\
+ linux-aarch64/crypto/modes/ghashv8-armx64.S\
linux-aarch64/crypto/sha/sha1-armv8.S\
linux-aarch64/crypto/sha/sha256-armv8.S\
linux-aarch64/crypto/sha/sha512-armv8.S\
linux_arm_sources := \
linux-arm/crypto/aes/aes-armv4.S\
- linux-arm/crypto/aes/aesv8-armx.S\
+ linux-arm/crypto/aes/aesv8-armx32.S\
linux-arm/crypto/aes/bsaes-armv7.S\
linux-arm/crypto/bn/armv4-mont.S\
linux-arm/crypto/modes/ghash-armv4.S\
- linux-arm/crypto/modes/ghashv8-armx.S\
+ linux-arm/crypto/modes/ghashv8-armx32.S\
linux-arm/crypto/sha/sha1-armv4-large.S\
linux-arm/crypto/sha/sha256-armv4.S\
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 := \
@@ -350,7 +359,6 @@ linux_x86_sources := \
linux-x86/crypto/bn/bn-586.S\
linux-x86/crypto/bn/co-586.S\
linux-x86/crypto/bn/x86-mont.S\
- linux-x86/crypto/cpu-x86-asm.S\
linux-x86/crypto/md5/md5-586.S\
linux-x86/crypto/modes/ghash-x86.S\
linux-x86/crypto/rc4/rc4-586.S\
@@ -367,12 +375,11 @@ linux_x86_64_sources := \
linux-x86_64/crypto/bn/rsaz-x86_64.S\
linux-x86_64/crypto/bn/x86_64-mont.S\
linux-x86_64/crypto/bn/x86_64-mont5.S\
- linux-x86_64/crypto/cpu-x86_64-asm.S\
+ linux-x86_64/crypto/ec/p256-x86_64-asm.S\
linux-x86_64/crypto/md5/md5-x86_64.S\
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\
@@ -385,7 +392,6 @@ mac_x86_sources := \
mac-x86/crypto/bn/bn-586.S\
mac-x86/crypto/bn/co-586.S\
mac-x86/crypto/bn/x86-mont.S\
- mac-x86/crypto/cpu-x86-asm.S\
mac-x86/crypto/md5/md5-586.S\
mac-x86/crypto/modes/ghash-x86.S\
mac-x86/crypto/rc4/rc4-586.S\
@@ -402,12 +408,11 @@ mac_x86_64_sources := \
mac-x86_64/crypto/bn/rsaz-x86_64.S\
mac-x86_64/crypto/bn/x86_64-mont.S\
mac-x86_64/crypto/bn/x86_64-mont5.S\
- mac-x86_64/crypto/cpu-x86_64-asm.S\
+ mac-x86_64/crypto/ec/p256-x86_64-asm.S\
mac-x86_64/crypto/md5/md5-x86_64.S\
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\
@@ -420,7 +425,6 @@ win_x86_sources := \
win-x86/crypto/bn/bn-586.asm\
win-x86/crypto/bn/co-586.asm\
win-x86/crypto/bn/x86-mont.asm\
- win-x86/crypto/cpu-x86-asm.asm\
win-x86/crypto/md5/md5-586.asm\
win-x86/crypto/modes/ghash-x86.asm\
win-x86/crypto/rc4/rc4-586.asm\
@@ -437,12 +441,11 @@ win_x86_64_sources := \
win-x86_64/crypto/bn/rsaz-x86_64.asm\
win-x86_64/crypto/bn/x86_64-mont.asm\
win-x86_64/crypto/bn/x86_64-mont5.asm\
- win-x86_64/crypto/cpu-x86_64-asm.asm\
+ win-x86_64/crypto/ec/p256-x86_64-asm.asm\
win-x86_64/crypto/md5/md5-x86_64.asm\
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/.gitignore b/src/.gitignore
index b54125f..a2e3ed2 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -3,3 +3,4 @@ ssl/test/runner/runner
*.swp
*.swo
doc/*.html
+doc/doc.css
diff --git a/src/BUILDING b/src/BUILDING
deleted file mode 100644
index d818f95..0000000
--- a/src/BUILDING
+++ /dev/null
@@ -1,96 +0,0 @@
-Build Prerequisites:
-
- * CMake[1] 2.8.8 or later is required.
-
- * Perl 5.6.1 or later is required. On Windows, Strawberry Perl and MSYS Perl
- have both been reported to work. If not found by CMake, it may be configured
- explicitly by setting PERL_EXECUTABLE.
-
- * On Windows you currently must use Ninja[2] to build; on other platforms,
- it is not required, but recommended, because it makes builds faster.
-
- * If you need to build Ninja from source, then a recent version of
- Python[3] is required (Python 2.7.5 works).
-
- * On Windows only, Yasm[4] is required. If not found by CMake, it may be
- configured explicitly by setting CMAKE_ASM_NASM_COMPILER.
-
- * A C compiler is required. On Windows, MSVC 12 (Visual Studio 2013) or later
- with Platform SDK 8.1 or later are supported. Recent versions of GCC and
- Clang should work on non-Windows platforms, and maybe on Windows too.
-
- * Go[5] is required. If not found by CMake, the go executable may be
- configured explicitly by setting GO_EXECUTABLE.
-
-Using Ninja (note the 'N' is capitalized in the cmake invocation):
-
- mkdir build
- cd build
- cmake -GNinja ..
- ninja
-
-Using makefiles (does not work on Windows):
-
- mkdir build
- cd build
- cmake ..
- make
-
-You usually don't need to run cmake again after changing CMakeLists.txt files
-because the build scripts will detect changes to them and rebuild themselves
-automatically.
-
-Note that the default build flags in the top-level CMakeLists.txt are for
-debugging - optimisation isn't enabled.
-
-If you want to cross-compile then there is an example toolchain file for
-32-bit Intel in util/. Wipe out the build directory, recreate it and run cmake
-like this:
-
- cmake -DCMAKE_TOOLCHAIN_FILE=../util/32-bit-toolchain.cmake -GNinja ..
-
-If you want to build as a shared library, pass -DBUILD_SHARED_LIBS=1. On
-Windows, where functions need to be tagged with "dllimport" when coming from a
-shared library, define BORINGSSL_SHARED_LIBRARY in any code which #includes the
-BoringSSL headers.
-
-
-Building for Android:
-
-It's possible to build BoringSSL with the Android NDK using CMake. This has
-been tested with version 10d of the NDK.
-
-Unpack the Android NDK somewhere and export ANDROID_NDK to point to the
-directory. Clone https://github.com/taka-no-me/android-cmake into util/.
-Then make a build directory as above and run CMake *twice* like this:
-
- cmake -DANDROID_NATIVE_API_LEVEL=android-9 \
- -DANDROID_ABI=armeabi-v7a \
- -DCMAKE_TOOLCHAIN_FILE=../util/android-cmake/android.toolchain.cmake \
- -GNinja ..
-
-Once you've run that twice, ninja should produce Android-compatible binaries.
-You can replace "armeabi-v7a" in the above with "arm64-v8a" to build aarch64
-binaries.
-
-
-Known Limitations on Windows:
-
- * Versions of cmake since 3.0.2 have a bug in its Ninja generator that causes
- yasm to output warnings "yasm: warning: can open only one input file, only
- the last file will be processed". These warnings can be safely ignored.
- The cmake bug is http://www.cmake.org/Bug/view.php?id=15253.
-
- * cmake can generate Visual Studio projects, but the generated project files
- don't have steps for assembling the assembly language source files, so they
- currently cannot be used to build BoringSSL.
-
-[1] http://www.cmake.org/download/
-
-[2] https://martine.github.io/ninja/
-
-[3] https://www.python.org/downloads/
-
-[4] http://yasm.tortall.net/
-
-[5] https://golang.org/dl/
diff --git a/src/BUILDING.md b/src/BUILDING.md
new file mode 100644
index 0000000..02f8f11
--- /dev/null
+++ b/src/BUILDING.md
@@ -0,0 +1,143 @@
+# Building BoringSSL
+
+## Build Prerequisites
+
+ * [CMake](http://www.cmake.org/download/) 2.8.8 or later is required.
+
+ * Perl 5.6.1 or later is required. On Windows,
+ [Strawberry Perl](http://strawberryperl.com/) and MSYS Perl have both been
+ reported to work. If not found by CMake, it may be configured explicitly by
+ setting `PERL_EXECUTABLE`.
+
+ * On Windows you currently must use [Ninja](https://martine.github.io/ninja/)
+ to build; on other platforms, it is not required, but recommended, because
+ it makes builds faster.
+
+ * If you need to build Ninja from source, then a recent version of
+ [Python](https://www.python.org/downloads/) is required (Python 2.7.5 works).
+
+ * On Windows only, [Yasm](http://yasm.tortall.net/) is required. If not found
+ by CMake, it may be configured explicitly by setting
+ `CMAKE_ASM_NASM_COMPILER`.
+
+ * A C compiler is required. On Windows, MSVC 12 (Visual Studio 2013) or later
+ with Platform SDK 8.1 or later are supported. Recent versions of GCC and
+ Clang should work on non-Windows platforms, and maybe on Windows too.
+
+ * [Go](https://golang.org/dl/) is required. If not found by CMake, the go
+ executable may be configured explicitly by setting `GO_EXECUTABLE`.
+
+ * If you change crypto/chacha/chacha\_vec.c, you will need the
+ arm-linux-gnueabihf-gcc compiler:
+
+ ```
+ wget https://releases.linaro.org/14.11/components/toolchain/binaries/arm-linux-gnueabihf/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf.tar.xz && \
+ echo bc4ca2ced084d2dc12424815a4442e19cb1422db87068830305d90075feb1a3b gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf.tar.xz | sha256sum -c && \
+ tar xf gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf.tar.xz && \
+ sudo mv gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf /opt/
+ ```
+
+## Building
+
+Using Ninja (note the 'N' is capitalized in the cmake invocation):
+
+ mkdir build
+ cd build
+ cmake -GNinja ..
+ ninja
+
+Using Make (does not work on Windows):
+
+ mkdir build
+ cd build
+ cmake ..
+ make
+
+You usually don't need to run `cmake` again after changing `CMakeLists.txt`
+files because the build scripts will detect changes to them and rebuild
+themselves automatically.
+
+Note that the default build flags in the top-level `CMakeLists.txt` are for
+debugging—optimisation isn't enabled.
+
+If you want to cross-compile then there is an example toolchain file for 32-bit
+Intel in `util/`. Wipe out the build directory, recreate it and run `cmake` like
+this:
+
+ cmake -DCMAKE_TOOLCHAIN_FILE=../util/32-bit-toolchain.cmake -GNinja ..
+
+If you want to build as a shared library, pass `-DBUILD_SHARED_LIBS=1`. On
+Windows, where functions need to be tagged with `dllimport` when coming from a
+shared library, define `BORINGSSL_SHARED_LIBRARY` in any code which `#include`s
+the BoringSSL headers.
+
+In order to serve environments where code-size is important as well as those
+where performance is the overriding concern, `OPENSSL_SMALL` can be defined to
+remove some code that is especially large.
+
+### Building for Android
+
+It's possible to build BoringSSL with the Android NDK using CMake. This has
+been tested with version 10d of the NDK.
+
+Unpack the Android NDK somewhere and export `ANDROID_NDK` to point to the
+directory. Clone https://github.com/taka-no-me/android-cmake into `util/`. Then
+make a build directory as above and run CMake *twice* like this:
+
+ cmake -DANDROID_NATIVE_API_LEVEL=android-9 \
+ -DANDROID_ABI=armeabi-v7a \
+ -DCMAKE_TOOLCHAIN_FILE=../util/android-cmake/android.toolchain.cmake \
+ -DANDROID_NATIVE_API_LEVEL=16 \
+ -GNinja ..
+
+Once you've run that twice, Ninja should produce Android-compatible binaries.
+You can replace `armeabi-v7a` in the above with `arm64-v8a` to build aarch64
+binaries.
+
+## Known Limitations on Windows
+
+ * Versions of CMake since 3.0.2 have a bug in its Ninja generator that causes
+ yasm to output warnings
+
+ yasm: warning: can open only one input file, only the last file will be processed
+
+ These warnings can be safely ignored. The cmake bug is
+ http://www.cmake.org/Bug/view.php?id=15253.
+
+ * CMake can generate Visual Studio projects, but the generated project files
+ don't have steps for assembling the assembly language source files, so they
+ currently cannot be used to build BoringSSL.
+
+## Embedded ARM
+
+ARM, unlike Intel, does not have an instruction that allows applications to
+discover the capabilities of the processor. Instead, the capability information
+has to be provided by the operating system somehow.
+
+BoringSSL will try to use `getauxval` to discover the capabilities and, failing
+that, will probe for NEON support by executing a NEON instruction and handling
+any illegal-instruction signal. But some environments don't support that sort
+of thing and, for them, it's possible to configure the CPU capabilities
+at compile time.
+
+If you define `OPENSSL_STATIC_ARMCAP` then you can define any of the following
+to enabling the corresponding ARM feature.
+
+ * `OPENSSL_STATIC_ARMCAP_NEON` or `__ARM_NEON__` (note that the latter is set by compilers when NEON support is enabled).
+ * `OPENSSL_STATIC_ARMCAP_AES`
+ * `OPENSSL_STATIC_ARMCAP_SHA1`
+ * `OPENSSL_STATIC_ARMCAP_SHA256`
+ * `OPENSSL_STATIC_ARMCAP_PMULL`
+
+Note that if a feature is enabled in this way, but not actually supported at
+run-time, BoringSSL will likely crash.
+
+# Running tests
+
+There are two sets of tests: the C/C++ tests and the blackbox tests. For former
+are built by Ninja and can be run from the top-level directory with `go run
+util/all_tests.go`. The latter have to be run separately by running `go test`
+from within `ssl/test/runner`.
+
+Both sets of tests may also be run with `ninja -C build run_tests`, but CMake
+3.2 or later is required to avoid Ninja's output buffering.
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c1a6a37..e07be54 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -17,15 +17,14 @@ if (NOT GO_EXECUTABLE)
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -ggdb -fvisibility=hidden")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -ggdb -std=c++0x -fvisibility=hidden")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -Wsign-compare -Wmissing-field-initializers -ggdb -fvisibility=hidden")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -Wsign-compare -Wmissing-field-initializers -ggdb -std=c++0x -fvisibility=hidden")
elseif(MSVC)
set(MSVC_DISABLED_WARNINGS_LIST
"C4100" # 'exarg' : unreferenced formal parameter
"C4127" # conditional expression is constant
"C4200" # nonstandard extension used : zero-sized array in
# struct/union.
- "C4210" # nonstandard extension used : function given file scope
"C4242" # 'function' : conversion from 'int' to 'uint8_t',
# possible loss of data
"C4244" # 'function' : conversion from 'int' to 'uint8_t',
@@ -81,6 +80,17 @@ if((CMAKE_COMPILER_IS_GNUCXX AND CMAKE_C_COMPILER_VERSION VERSION_GREATER "4.8.9
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -D_XOPEN_SOURCE=700")
endif()
+if(FUZZ)
+ if(!CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ message("You need to build with Clang for fuzzing to work")
+ endif()
+
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fsanitize-coverage=edge,indirect-calls")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fsanitize-coverage=edge,indirect-calls")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
+ link_directories(.)
+endif()
+
add_definitions(-DBORINGSSL_IMPLEMENTATION)
if (BUILD_SHARED_LIBS)
@@ -138,8 +148,31 @@ if (OPENSSL_NO_ASM)
set(ARCH "generic")
endif()
+# Declare a dummy target to build all unit tests. Test targets should inject
+# themselves as dependencies next to the target definition.
+add_custom_target(all_tests)
+
add_subdirectory(crypto)
add_subdirectory(ssl)
add_subdirectory(ssl/test)
add_subdirectory(tool)
add_subdirectory(decrepit)
+
+if(FUZZ)
+ add_subdirectory(fuzz)
+endif()
+
+if (NOT ${CMAKE_VERSION} VERSION_LESS "3.2")
+ # USES_TERMINAL is only available in CMake 3.2 or later.
+ set(MAYBE_USES_TERMINAL USES_TERMINAL)
+endif()
+
+add_custom_target(
+ run_tests
+ COMMAND ${GO_EXECUTABLE} run util/all_tests.go -build-dir
+ ${CMAKE_BINARY_DIR}
+ COMMAND cd ssl/test/runner
+ COMMAND ${GO_EXECUTABLE} test -shim-path $<TARGET_FILE:bssl_shim>
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ DEPENDS all_tests bssl_shim
+ ${MAYBE_USES_TERMINAL})
diff --git a/src/FUZZING.md b/src/FUZZING.md
new file mode 100644
index 0000000..4bd15a3
--- /dev/null
+++ b/src/FUZZING.md
@@ -0,0 +1,40 @@
+# Fuzz testing
+
+Modern fuzz testers are very effective and we wish to use them to ensure that no silly bugs creep into BoringSSL.
+
+We primarily use Clang's [libFuzzer](http://llvm.org/docs/LibFuzzer.html) for fuzz testing and there are a number of fuzz testing functions in `fuzz/`. They are not built by default because they require libFuzzer at build time.
+
+In order to build the fuzz tests you will need at least Clang 3.7. Pass `-DFUZZ=1` on the CMake command line to enable building BoringSSL with coverage and AddressSanitizer, and to build the fuzz test binaries. You'll probably need to set the `CC` and `CXX` environment variables too, like this:
+
+```
+CC=clang CXX=clang++ cmake -GNinja -DFUZZ=1 ..
+```
+
+In order for the fuzz tests to link, the linker needs to find libFuzzer. This is not commonly provided and you may need to download the [Clang source code](http://llvm.org/releases/download.html) and do the following:
+
+```
+cd llvm-3.7.0.src/lib
+clang -c -g -O2 -std=c++11 Fuzzer/*.cpp -IFuzzer
+ar q libFuzzer.a *.o
+```
+
+Then copy `libFuzzer.a` to the top-level of your BoringSSL source directory.
+
+From the `build/` directory, you can then run the fuzzers. For example:
+
+```
+./fuzz/cert -max_len=4000 -jobs=32 -workers=32 ../fuzz/cert_corpus/
+```
+
+The `max_len` argument is often important because, without it, libFuzzer defaults to limiting all test cases to 64 bytes, which is often insufficient for the formats that we wish to fuzz. The arguments to `jobs` and `workers` should be the number of cores that you wish to dedicate to fuzzing.
+
+There are directories in `fuzz/` for each of the fuzzing tests which contain seed files for fuzzing. Some of the seed files were generated manually but many of them are “interesting†results generated by the fuzzing itself. (Where “interesting†means that it triggered a previously unknown path in the code.)
+
+Here are the recommended values of `max_len` for each test.
+
+| Test | `max_len` value |
+|-----------|-----------------|
+| `privkey` | 2048 |
+| `cert` | 3072 |
+| `server` | 1024 |
+| `client` | 4096 |
diff --git a/src/LICENSE b/src/LICENSE
index 8ae5e77..b242dcb 100644
--- a/src/LICENSE
+++ b/src/LICENSE
@@ -5,6 +5,9 @@ license. This license is reproduced at the bottom of this file.
Contributors to BoringSSL are required to follow the CLA rules for Chromium:
https://cla.developers.google.com/clas
+Some files from Intel are under yet another license, which is also included
+underneath.
+
The OpenSSL toolkit stays under a dual license, i.e. both the conditions of the
OpenSSL License and the original SSLeay license apply to the toolkit. See below
for the actual license texts. Actually both licenses are BSD-style Open Source
@@ -144,3 +147,39 @@ ISC license used for completely new code in BoringSSL:
* 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. */
+
+
+Some files from Intel carry the following license:
+
+# Copyright (c) 2012, Intel Corporation
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * 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.
+#
+# * Neither the name of the Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+#
+# THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""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 INTEL CORPORATION 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.
diff --git a/src/PORTING.md b/src/PORTING.md
new file mode 100644
index 0000000..b3e50d7
--- /dev/null
+++ b/src/PORTING.md
@@ -0,0 +1,164 @@
+# Porting from OpenSSL to BoringSSL
+
+BoringSSL is an OpenSSL derivative and is mostly source-compatible, for the
+subset of OpenSSL retained. Libraries ideally need little to no changes for
+BoringSSL support, provided they do not use removed APIs. In general, see if the
+library compiles and, on failure, consult the documentation in the header files
+and see if problematic features can be removed.
+
+In some cases, BoringSSL-specific code may be necessary. In that case, the
+`OPENSSL_IS_BORINGSSL` preprocessor macro may be used in `#ifdef`s. This macro
+should also be used in lieu of the presence of any particular function to detect
+OpenSSL vs BoringSSL in configure scripts, etc., where those are necessary.
+
+For convenience, BoringSSL defines upstream's `OPENSSL_NO_*` feature macros
+corresponding to removed features. These may also be used to disable code which
+uses a removed feature.
+
+Note: BoringSSL does *not* have a stable API or ABI. It must be updated with its
+consumers. It is not suitable for, say, a system library in a traditional Linux
+distribution. For instance, Chromium statically links the specific revision of
+BoringSSL it was built against. Likewise, Android's system-internal copy of
+BoringSSL is not exposed by the NDK and must not be used by third-party
+applications.
+
+
+## Major API changes
+
+### Integer types
+
+Some APIs have been converted to use `size_t` for consistency and to avoid
+integer overflows at the API boundary. (Existing logic uses a mismash of `int`,
+`long`, and `unsigned`.) For the most part, implicit casts mean that existing
+code continues to compile. In some cases, this may require BoringSSL-specific
+code, particularly to avoid compiler warnings.
+
+Most notably, the `STACK_OF(T)` types have all been converted to use `size_t`
+instead of `int` for indices and lengths.
+
+### Reference counts
+
+Some external consumers increment reference counts directly by calling
+`CRYPTO_add` with the corresponding `CRYPTO_LOCK_*` value.
+
+These APIs no longer exist in BoringSSL. Instead, code which increments
+reference counts should call the corresponding `FOO_up_ref` function, such as
+`EVP_PKEY_up_ref`. Note that not all of these APIs are present in OpenSSL and
+may require `#ifdef`s.
+
+### Error codes
+
+OpenSSL's errors are extremely specific, leaking internals of the library,
+including even a function code for the function which emitted the error! As some
+logic in BoringSSL has been rewritten, code which conditions on the error may
+break (grep for `ERR_GET_REASON` and `ERR_GET_FUNC`). This danger also exists
+when upgrading OpenSSL versions.
+
+Where possible, avoid conditioning on the exact error reason. Otherwise, a
+BoringSSL `#ifdef` may be necessary. Exactly how best to resolve this issue is
+still being determined. It's possible some new APIs will be added in the future.
+
+Function codes have been completely removed. Remove code which conditions on
+these as it will break with the slightest change in the library, OpenSSL or
+BoringSSL.
+
+### `*_ctrl` functions
+
+Some OpenSSL APIs are implemented with `ioctl`-style functions such as
+`SSL_ctrl` and `EVP_PKEY_CTX_ctrl`, combined with convenience macros, such as
+
+ # define SSL_CTX_set_mode(ctx,op) \
+ SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL)
+
+In BoringSSL, these macros have been replaced with proper functions. The
+underlying `_ctrl` functions have been removed.
+
+For convenience, `SSL_CTRL_*` values are retained as macros to `doesnt_exist` so
+existing code which uses them (or the wrapper macros) in `#ifdef` expressions
+will continue to function. However, the macros themselves will not work.
+
+Switch any `*_ctrl` callers to the macro/function versions. This works in both
+OpenSSL and BoringSSL. Note that BoringSSL's function versions will be
+type-checked and may require more care with types.
+
+### HMAC `EVP_PKEY`s
+
+`EVP_PKEY_HMAC` is removed. Use the `HMAC_*` functions in `hmac.h` instead. This
+is compatible with OpenSSL.
+
+### DSA `EVP_PKEY`s
+
+`EVP_PKEY_DSA` is deprecated. It is currently still possible to parse DER into a
+DSA `EVP_PKEY`, but signing or verifying with those objects will not work.
+
+### DES
+
+The `DES_cblock` type has been switched from an array to a struct to avoid the
+pitfalls around array types in C. Where features which require DES cannot be
+disabled, BoringSSL-specific codepaths may be necessary.
+
+### TLS renegotiation
+
+OpenSSL enables TLS renegotiation by default and accepts renegotiation requests
+from the peer transparently. Renegotiation is an extremely problematic protocol
+feature, so BoringSSL rejects peer renegotiations by default.
+
+To enable renegotiation, call `SSL_set_renegotiate_mode` and set it to
+`ssl_renegotiate_once` or `ssl_renegotiate_freely`. Renegotiation is only
+supported as a client in SSL3/TLS and the HelloRequest must be received at a
+quiet point in the application protocol. This is sufficient to support the
+common use of requesting a new client certificate between an HTTP request and
+response in (unpipelined) HTTP/1.1.
+
+Things which do not work:
+
+* There is no support for renegotiation as a server.
+
+* There is no support for renegotiation in DTLS.
+
+* There is no support for initiating renegotiation; `SSL_renegotiate` always
+ fails and `SSL_set_state` does nothing.
+
+* Interleaving application data with the new handshake is forbidden.
+
+* If a HelloRequest is received while `SSL_write` has unsent application data,
+ the renegotiation is rejected.
+
+### Lowercase hexadecimal
+
+BoringSSL's `BN_bn2hex` function uses lowercase hexadecimal digits instead of
+uppercase. Some code may require changes to avoid being sensitive to this
+difference.
+
+
+## Optional BoringSSL-specific simplifications
+
+BoringSSL makes some changes to OpenSSL which simplify the API but remain
+compatible with OpenSSL consumers. In general, consult the BoringSSL
+documentation for any functions in new BoringSSL-only code.
+
+### Return values
+
+Most OpenSSL APIs return 1 on success and either 0 or -1 on failure. BoringSSL
+has narrowed most of these to 1 on success and 0 on failure. BoringSSL-specific
+code may take advantage of the less error-prone APIs and use `!` to check for
+errors.
+
+### Initialization
+
+OpenSSL has a number of different initialization functions for setting up error
+strings and loading algorithms, etc. All of these functions still exist in
+BoringSSL for convenience, but they do nothing and are not necessary.
+
+The one exception is `CRYPTO_library_init`. In `BORINGSSL_NO_STATIC_INITIALIZER`
+builds, it must be called to query CPU capabitilies before the rest of the
+library. In the default configuration, this is done with a static initializer
+and is also unnecessary.
+
+### Threading
+
+OpenSSL provides a number of APIs to configure threading callbacks and set up
+locks. Without initializing these, the library is not thread-safe. Configuring
+these does nothing in BoringSSL. Instead, BoringSSL calls pthreads and the
+corresponding Windows APIs internally and is always thread-safe where the API
+guarantees it.
diff --git a/src/README.md b/src/README.md
new file mode 100644
index 0000000..d8a65c2
--- /dev/null
+++ b/src/README.md
@@ -0,0 +1,30 @@
+# BoringSSL
+
+BoringSSL is a fork of OpenSSL that is designed to meet Google's needs.
+
+Although BoringSSL is an open source project, it is not intended for general
+use, as OpenSSL is. We don't recommend that third parties depend upon it. Doing
+so is likely to be frustrating because there are no guarantees of API or ABI
+stability.
+
+Programs ship their own copies of BoringSSL when they use it and we update
+everything as needed when deciding to make API changes. This allows us to
+mostly avoid compromises in the name of compatibility. It works for us, but it
+may not work for you.
+
+BoringSSL arose because Google used OpenSSL for many years in various ways and,
+over time, built up a large number of patches that were maintained while
+tracking upstream OpenSSL. As Google's product portfolio became more complex,
+more copies of OpenSSL sprung up and the effort involved in maintaining all
+these patches in multiple places was growing steadily.
+
+Currently BoringSSL is the SSL library in Chrome/Chromium, Android (but it's
+not part of the NDK) and a number of other apps/programs.
+
+There are other files in this directory which might be helpful:
+
+ * [PORTING.md](/PORTING.md): how to port OpenSSL-using code to BoringSSL.
+ * [BUILDING.md](/BUILDING.md): how to build BoringSSL
+ * [STYLE.md](/STYLE.md): rules and guidelines for coding style.
+ * include/openssl: public headers with API documentation in comments. Also [available online](https://commondatastorage.googleapis.com/chromium-boringssl-docs/headers.html).
+ * [FUZZING.md](/FUZZING.md): information about fuzzing BoringSSL.
diff --git a/src/STYLE b/src/STYLE
deleted file mode 100644
index 578da68..0000000
--- a/src/STYLE
+++ /dev/null
@@ -1,198 +0,0 @@
-BoringSSL Style Guide.
-
-BoringSSL usually follows the Google C++ style guide, found below. The
-rest of this document describes differences and clarifications on top
-of the base guide.
-
-https://google-styleguide.googlecode.com/svn/trunk/cppguide.html
-
-
-Legacy code.
-
-As a derivative of OpenSSL, BoringSSL contains a lot of legacy code
-that does not follow this style guide. Particularly where public API
-is concerned, balance consistency within a module with the benefits of
-a given rule. Module-wide deviations on naming should be respected
-while integer and return value conventions take precedence over
-consistency.
-
-Some modules have seen few changes, so they still retain the original
-indentation style for now. When editing these, try to retain the
-original style. For Emacs, doc/c-indentation.el from OpenSSL may be
-helpful in this.
-
-
-Language.
-
-The majority of the project is in C, so C++-specific rules in the
-Google style guide do not apply. Support for C99 features depends on
-our target platforms. Typically, Chromium's target MSVC is the most
-restrictive.
-
-Variable declarations in the middle of a function are allowed.
-
-Comments should be /* C-style */ for consistency.
-
-When declaration pointer types, * should be placed next to the variable
-name, not the type. So
-
- uint8_t *ptr;
-
-not
-
- uint8_t* ptr;
-
-Rather than malloc() and free(), use the wrappers OPENSSL_malloc() and
-OPENSSL_free(). Use the standard C assert() function freely.
-
-For new constants, prefer enums when the values are sequential and typed
-constants for flags. If adding values to an existing set of #defines, continue
-with #define.
-
-
-Formatting.
-
-Single-statement blocks are not allowed. All conditions and loops must
-use braces:
-
- if (foo) {
- do_something();
- }
-
-not
-
- if (foo)
- do_something();
-
-
-Integers.
-
-Prefer using explicitly-sized integers where appropriate rather than
-generic C ones. For instance, to represent a byte, use uint8_t, not
-unsigned char. Likewise, represent a two-byte field as uint16_t, not
-unsigned short.
-
-Sizes are represented as size_t.
-
-Within a struct that is retained across the lifetime of an SSL
-connection, if bounds of a size are known and it's easy, use a smaller
-integer type like uint8_t. This is a "free" connection footprint
-optimization for servers. Don't make code significantly more complex
-for it, and do still check the bounds when passing in and out of the
-struct. This narrowing should not propagate to local variables and
-function parameters.
-
-When doing arithmetic, account for overflow conditions.
-
-Except with platform APIs, do not use ssize_t. MSVC lacks it, and
-prefer out-of-band error signaling for size_t (see Return values).
-
-
-Naming.
-
-Follow Google naming conventions in C++ files. In C files, use the
-following naming conventions for consistency with existing OpenSSL and C
-styles:
-
-Define structs with typedef named TYPE_NAME. The corresponding struct
-should be named struct type_name_st.
-
-Name public functions as MODULE_function_name, unless the module
-already uses a different naming scheme for legacy reasons. The module
-name should be a type name if the function is a method of a particular
-type.
-
-Some types are allocated within the library while others are
-initialized into a struct allocated by the caller, often on the
-stack. Name these functions TYPE_NAME_new/TYPE_NAME_free and
-TYPE_NAME_init/TYPE_NAME_cleanup, respectively. All TYPE_NAME_free
-functions must do nothing on NULL input.
-
-If a variable is the length of a pointer value, it has the suffix
-_len. An output parameter is named out or has an out_ prefix. For
-instance, For instance:
-
- uint8_t *out,
- size_t *out_len,
- const uint8_t *in,
- size_t in_len,
-
-Name public headers like include/openssl/evp.h with header guards like
-OPENSSL_HEADER_EVP_H. Name internal headers like crypto/ec/internal.h
-with header guards like OPENSSL_HEADER_EC_INTERNAL_H.
-
-Name enums like unix_hacker_t. For instance:
-
-enum should_free_handshake_buffer_t {
- free_handshake_buffer,
- dont_free_handshake_buffer,
-};
-
-
-Return values.
-
-As even malloc may fail in BoringSSL, the vast majority of functions
-will have a failure case. Functions should return int with one on
-success and zero on error. Do not overload the return value to both
-signal success/failure and output an integer. For example:
-
- OPENSSL_EXPORT int CBS_get_u16(CBS *cbs, uint16_t *out);
-
-If a function needs more than a true/false result code, define an enum
-rather than arbitrarily assigning meaning to int values.
-
-If a function outputs a pointer to an object on success and there are no
-other outputs, return the pointer directly and NULL on error.
-
-
-Parameters.
-
-Where not constrained by legacy code, parameter order should be:
-
-1. context parameters
-2. output parameters
-3. input parameters
-
-For example,
-
-/* CBB_add_asn sets |*out_contents| to a |CBB| into which the contents of an
- * ASN.1 object can be written. The |tag| argument will be used as the tag for
- * the object. It returns one on success or zero on error. */
-OPENSSL_EXPORT int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag);
-
-
-Documentation.
-
-All public symbols must have a documentation comment in their header
-file. The style is based on that of Go. The first sentence begins with
-the symbol name, optionally prefixed with "A" or "An". Apart from the
-initial mention of symbol, references to other symbols or parameter
-names should be surrounded by |pipes|.
-
-Documentation should be concise but completely describe the exposed
-behavior of the function. Pay special note to success/failure behaviors
-and caller obligations on object lifetimes. If this sacrifices
-conciseness, consider simplifying the function's behavior.
-
-/* EVP_DigestVerifyUpdate appends |len| bytes from |data| to the data which
- * will be verified by |EVP_DigestVerifyFinal|. It returns one on success and
- * zero otherwise. */
-OPENSSL_EXPORT int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data,
- size_t len);
-
-Explicitly mention any surprising edge cases or deviations from common
-return value patterns in legacy functions.
-
-/* RSA_private_encrypt encrypts |flen| bytes from |from| with the private key in
- * |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.
- *
- * WARNING: this function is dangerous because it breaks the usual return value
- * convention. Use |RSA_sign_raw| instead. */
-OPENSSL_EXPORT int RSA_private_encrypt(int flen, const uint8_t *from,
- uint8_t *to, RSA *rsa, int padding);
-
-Document private functions in their internal.h header or, if static,
-where defined.
diff --git a/src/STYLE.md b/src/STYLE.md
new file mode 100644
index 0000000..4d2c5de
--- /dev/null
+++ b/src/STYLE.md
@@ -0,0 +1,197 @@
+# BoringSSL Style Guide
+
+BoringSSL usually follows the
+[Google C++ style guide](https://google.github.io/styleguide/cppguide.html),
+The rest of this document describes differences and clarifications on
+top of the base guide.
+
+
+## Legacy code
+
+As a derivative of OpenSSL, BoringSSL contains a lot of legacy code that
+does not follow this style guide. Particularly where public API is
+concerned, balance consistency within a module with the benefits of a
+given rule. Module-wide deviations on naming should be respected while
+integer and return value conventions take precedence over consistency.
+
+Some modules have seen few changes, so they still retain the original
+indentation style for now. When editing these, try to retain the
+original style. For Emacs, `doc/c-indentation.el` from OpenSSL may be
+helpful in this.
+
+
+## Language
+
+The majority of the project is in C, so C++-specific rules in the
+Google style guide do not apply. Support for C99 features depends on
+our target platforms. Typically, Chromium's target MSVC is the most
+restrictive.
+
+Variable declarations in the middle of a function are allowed.
+
+Comments should be `/* C-style */` for consistency.
+
+When declaration pointer types, `*` should be placed next to the variable
+name, not the type. So
+
+ uint8_t *ptr;
+
+not
+
+ uint8_t* ptr;
+
+Rather than `malloc()` and `free()`, use the wrappers `OPENSSL_malloc()`
+and `OPENSSL_free()`. Use the standard C `assert()` function freely.
+
+For new constants, prefer enums when the values are sequential and typed
+constants for flags. If adding values to an existing set of `#define`s,
+continue with `#define`.
+
+
+## Formatting
+
+Single-statement blocks are not allowed. All conditions and loops must
+use braces:
+
+ if (foo) {
+ do_something();
+ }
+
+not
+
+ if (foo)
+ do_something();
+
+
+## Integers
+
+Prefer using explicitly-sized integers where appropriate rather than
+generic C ones. For instance, to represent a byte, use `uint8_t`, not
+`unsigned char`. Likewise, represent a two-byte field as `uint16_t`, not
+`unsigned short`.
+
+Sizes are represented as `size_t`.
+
+Within a struct that is retained across the lifetime of an SSL
+connection, if bounds of a size are known and it's easy, use a smaller
+integer type like `uint8_t`. This is a "free" connection footprint
+optimization for servers. Don't make code significantly more complex for
+it, and do still check the bounds when passing in and out of the
+struct. This narrowing should not propagate to local variables and
+function parameters.
+
+When doing arithmetic, account for overflow conditions.
+
+Except with platform APIs, do not use `ssize_t`. MSVC lacks it, and
+prefer out-of-band error signaling for `size_t` (see Return values).
+
+
+## Naming
+
+Follow Google naming conventions in C++ files. In C files, use the
+following naming conventions for consistency with existing OpenSSL and C
+styles:
+
+Define structs with typedef named `TYPE_NAME`. The corresponding struct
+should be named `struct type_name_st`.
+
+Name public functions as `MODULE_function_name`, unless the module
+already uses a different naming scheme for legacy reasons. The module
+name should be a type name if the function is a method of a particular
+type.
+
+Some types are allocated within the library while others are initialized
+into a struct allocated by the caller, often on the stack. Name these
+functions `TYPE_NAME_new`/`TYPE_NAME_free` and
+`TYPE_NAME_init`/`TYPE_NAME_cleanup`, respectively. All `TYPE_NAME_free`
+functions must do nothing on `NULL` input.
+
+If a variable is the length of a pointer value, it has the suffix
+`_len`. An output parameter is named `out` or has an `out_` prefix. For
+instance, For instance:
+
+ uint8_t *out,
+ size_t *out_len,
+ const uint8_t *in,
+ size_t in_len,
+
+Name public headers like `include/openssl/evp.h` with header guards like
+`OPENSSL_HEADER_EVP_H`. Name internal headers like
+`crypto/ec/internal.h` with header guards like
+`OPENSSL_HEADER_EC_INTERNAL_H`.
+
+Name enums like `enum unix_hacker_t`. For instance:
+
+ enum should_free_handshake_buffer_t {
+ free_handshake_buffer,
+ dont_free_handshake_buffer,
+ };
+
+
+## Return values
+
+As even `malloc` may fail in BoringSSL, the vast majority of functions
+will have a failure case. Functions should return `int` with one on
+success and zero on error. Do not overload the return value to both
+signal success/failure and output an integer. For example:
+
+ OPENSSL_EXPORT int CBS_get_u16(CBS *cbs, uint16_t *out);
+
+If a function needs more than a true/false result code, define an enum
+rather than arbitrarily assigning meaning to int values.
+
+If a function outputs a pointer to an object on success and there are no
+other outputs, return the pointer directly and `NULL` on error.
+
+
+## Parameters
+
+Where not constrained by legacy code, parameter order should be:
+
+1. context parameters
+2. output parameters
+3. input parameters
+
+For example,
+
+ /* CBB_add_asn sets |*out_contents| to a |CBB| into which the contents of an
+ * ASN.1 object can be written. The |tag| argument will be used as the tag for
+ * the object. It returns one on success or zero on error. */
+ OPENSSL_EXPORT int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag);
+
+
+## Documentation
+
+All public symbols must have a documentation comment in their header
+file. The style is based on that of Go. The first sentence begins with
+the symbol name, optionally prefixed with "A" or "An". Apart from the
+initial mention of symbol, references to other symbols or parameter
+names should be surrounded by |pipes|.
+
+Documentation should be concise but completely describe the exposed
+behavior of the function. Pay special note to success/failure behaviors
+and caller obligations on object lifetimes. If this sacrifices
+conciseness, consider simplifying the function's behavior.
+
+ /* EVP_DigestVerifyUpdate appends |len| bytes from |data| to the data which
+ * will be verified by |EVP_DigestVerifyFinal|. It returns one on success and
+ * zero otherwise. */
+ OPENSSL_EXPORT int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data,
+ size_t len);
+
+Explicitly mention any surprising edge cases or deviations from common
+return value patterns in legacy functions.
+
+ /* RSA_private_encrypt encrypts |flen| bytes from |from| with the private key in
+ * |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.
+ *
+ * WARNING: this function is dangerous because it breaks the usual return value
+ * convention. Use |RSA_sign_raw| instead. */
+ OPENSSL_EXPORT int RSA_private_encrypt(int flen, const uint8_t *from,
+ uint8_t *to, RSA *rsa, int padding);
+
+Document private functions in their `internal.h` header or, if static,
+where defined.
diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt
index 6858cbb..6651f29 100644
--- a/src/crypto/CMakeLists.txt
+++ b/src/crypto/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. ../include)
+include_directories(../include)
if(APPLE)
if (${ARCH} STREQUAL "x86")
@@ -57,7 +57,6 @@ if (${ARCH} STREQUAL "x86_64")
set(
CRYPTO_ARCH_SOURCES
- cpu-x86_64-asm.${ASM_EXT}
cpu-intel.c
)
endif()
@@ -66,7 +65,6 @@ if (${ARCH} STREQUAL "x86")
set(
CRYPTO_ARCH_SOURCES
- cpu-x86-asm.${ASM_EXT}
cpu-intel.c
)
endif()
@@ -107,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)
@@ -176,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>
@@ -212,6 +212,7 @@ add_executable(
)
target_link_libraries(constant_time_test crypto)
+add_dependencies(all_tests constant_time_test)
add_executable(
thread_test
@@ -222,6 +223,7 @@ add_executable(
)
target_link_libraries(thread_test crypto)
+add_dependencies(all_tests thread_test)
add_executable(
refcount_test
@@ -230,6 +232,4 @@ add_executable(
)
target_link_libraries(refcount_test crypto)
-
-perlasm(cpu-x86_64-asm.${ASM_EXT} cpu-x86_64-asm.pl)
-perlasm(cpu-x86-asm.${ASM_EXT} cpu-x86-asm.pl)
+add_dependencies(all_tests refcount_test)
diff --git a/src/crypto/aes/CMakeLists.txt b/src/crypto/aes/CMakeLists.txt
index 490f40a..0566e39 100644
--- a/src/crypto/aes/CMakeLists.txt
+++ b/src/crypto/aes/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
if (${ARCH} STREQUAL "x86_64")
set(
@@ -60,3 +60,13 @@ perlasm(aesni-x86.${ASM_EXT} asm/aesni-x86.pl)
perlasm(aes-armv4.${ASM_EXT} asm/aes-armv4.pl)
perlasm(bsaes-armv7.${ASM_EXT} asm/bsaes-armv7.pl)
perlasm(aesv8-armx.${ASM_EXT} asm/aesv8-armx.pl)
+
+add_executable(
+ aes_test
+
+ aes_test.cc
+ $<TARGET_OBJECTS:test_support>
+)
+
+target_link_libraries(aes_test crypto)
+add_dependencies(all_tests aes_test)
diff --git a/src/crypto/aes/aes.c b/src/crypto/aes/aes.c
index 933aa07..8823919 100644
--- a/src/crypto/aes/aes.c
+++ b/src/crypto/aes/aes.c
@@ -49,6 +49,9 @@
#include <openssl/aes.h>
#include <assert.h>
+#include <stdlib.h>
+
+#include <openssl/cpu.h>
#include "internal.h"
@@ -1057,6 +1060,44 @@ void AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
#else
+#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
+
+static int hwaes_capable(void) {
+ return CRYPTO_is_ARMv8_AES_capable();
+}
+
+int aes_v8_set_encrypt_key(const uint8_t *user_key, const int bits,
+ AES_KEY *key);
+int aes_v8_set_decrypt_key(const uint8_t *user_key, const int bits,
+ AES_KEY *key);
+void aes_v8_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
+void aes_v8_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
+
+#else
+
+static int hwaes_capable(void) {
+ return 0;
+}
+
+static int aes_v8_set_encrypt_key(const uint8_t *user_key, int bits, AES_KEY *key) {
+ abort();
+}
+
+static int aes_v8_set_decrypt_key(const uint8_t *user_key, int bits, AES_KEY *key) {
+ abort();
+}
+
+static void aes_v8_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
+ abort();
+}
+
+static void aes_v8_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
+ abort();
+}
+
+#endif
+
+
/* In this case several functions are provided by asm code. However, one cannot
* control asm symbol visibility with command line flags and such so they are
* always hidden and wrapped by these C functions, which can be so
@@ -1064,22 +1105,38 @@ void AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
void asm_AES_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
void AES_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
- asm_AES_encrypt(in, out, key);
+ if (hwaes_capable()) {
+ aes_v8_encrypt(in, out, key);
+ } else {
+ asm_AES_encrypt(in, out, key);
+ }
}
void asm_AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
void AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
- asm_AES_decrypt(in, out, key);
+ if (hwaes_capable()) {
+ aes_v8_decrypt(in, out, key);
+ } else {
+ asm_AES_decrypt(in, out, key);
+ }
}
int asm_AES_set_encrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey);
int AES_set_encrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) {
- return asm_AES_set_encrypt_key(key, bits, aeskey);
+ if (hwaes_capable()) {
+ return aes_v8_set_encrypt_key(key, bits, aeskey);
+ } else {
+ return asm_AES_set_encrypt_key(key, bits, aeskey);
+ }
}
int asm_AES_set_decrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey);
int AES_set_decrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) {
- return asm_AES_set_decrypt_key(key, bits, aeskey);
+ if (hwaes_capable()) {
+ return aes_v8_set_decrypt_key(key, bits, aeskey);
+ } else {
+ return asm_AES_set_decrypt_key(key, bits, aeskey);
+ }
}
#endif /* OPENSSL_NO_ASM || (!OPENSSL_X86 && !OPENSSL_X86_64 && !OPENSSL_ARM) */
diff --git a/src/crypto/aes/aes_test.cc b/src/crypto/aes/aes_test.cc
new file mode 100644
index 0000000..e488d81
--- /dev/null
+++ b/src/crypto/aes/aes_test.cc
@@ -0,0 +1,102 @@
+/* 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 <stdio.h>
+#include <string.h>
+
+#include <openssl/aes.h>
+#include <openssl/crypto.h>
+
+
+static bool TestAES(const uint8_t *key, size_t key_len,
+ const uint8_t plaintext[AES_BLOCK_SIZE],
+ const uint8_t ciphertext[AES_BLOCK_SIZE]) {
+ AES_KEY aes_key;
+ if (AES_set_encrypt_key(key, key_len * 8, &aes_key) != 0) {
+ fprintf(stderr, "AES_set_encrypt_key failed\n");
+ return false;
+ }
+
+ // Test encryption.
+ uint8_t block[AES_BLOCK_SIZE];
+ AES_encrypt(plaintext, block, &aes_key);
+ if (memcmp(block, ciphertext, AES_BLOCK_SIZE) != 0) {
+ fprintf(stderr, "AES_encrypt gave the wrong output\n");
+ return false;
+ }
+
+ // Test in-place encryption.
+ memcpy(block, plaintext, AES_BLOCK_SIZE);
+ AES_encrypt(block, block, &aes_key);
+ if (memcmp(block, ciphertext, AES_BLOCK_SIZE) != 0) {
+ fprintf(stderr, "AES_encrypt gave the wrong output\n");
+ return false;
+ }
+
+ if (AES_set_decrypt_key(key, key_len * 8, &aes_key) != 0) {
+ fprintf(stderr, "AES_set_decrypt_key failed\n");
+ return false;
+ }
+
+ // Test decryption.
+ AES_decrypt(ciphertext, block, &aes_key);
+ if (memcmp(block, plaintext, AES_BLOCK_SIZE) != 0) {
+ fprintf(stderr, "AES_decrypt gave the wrong output\n");
+ return false;
+ }
+
+ // Test in-place decryption.
+ memcpy(block, ciphertext, AES_BLOCK_SIZE);
+ AES_decrypt(block, block, &aes_key);
+ if (memcmp(block, plaintext, AES_BLOCK_SIZE) != 0) {
+ fprintf(stderr, "AES_decrypt gave the wrong output\n");
+ return false;
+ }
+ return true;
+}
+
+int main() {
+ CRYPTO_library_init();
+
+ // Test vectors from FIPS-197, Appendix C.
+ if (!TestAES((const uint8_t *)"\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ 128 / 8,
+ (const uint8_t *)"\x00\x11\x22\x33\x44\x55\x66\x77"
+ "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+ (const uint8_t *)"\x69\xc4\xe0\xd8\x6a\x7b\x04\x30"
+ "\xd8\xcd\xb7\x80\x70\xb4\xc5\x5a") ||
+ !TestAES((const uint8_t *)"\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17",
+ 192 / 8,
+ (const uint8_t *)"\x00\x11\x22\x33\x44\x55\x66\x77"
+ "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+ (const uint8_t *)"\xdd\xa9\x7c\xa4\x86\x4c\xdf\xe0"
+ "\x6e\xaf\x70\xa0\xec\x0d\x71\x91") ||
+ !TestAES((const uint8_t *)"\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ 256 / 8,
+ (const uint8_t *)"\x00\x11\x22\x33\x44\x55\x66\x77"
+ "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+ (const uint8_t *)"\x8e\xa2\xb7\xca\x51\x67\x45\xbf"
+ "\xea\xfc\x49\x90\x4b\x49\x60\x89")) {
+ return false;
+ }
+
+ printf("PASS\n");
+ return 0;
+}
diff --git a/src/crypto/aes/asm/aes-586.pl b/src/crypto/aes/asm/aes-586.pl
index 07fb94c..6e8a6a8 100755
--- a/src/crypto/aes/asm/aes-586.pl
+++ b/src/crypto/aes/asm/aes-586.pl
@@ -45,7 +45,7 @@
# the undertaken effort was that it appeared that in tight IA-32
# register window little-endian flavor could achieve slightly higher
# Instruction Level Parallelism, and it indeed resulted in up to 15%
-# better performance on most recent µ-archs...
+# better performance on most recent µ-archs...
#
# Third version adds AES_cbc_encrypt implementation, which resulted in
# up to 40% performance imrovement of CBC benchmark results. 40% was
@@ -224,7 +224,7 @@ sub _data_word() { my $i; while(defined($i=shift)) { &data_word($i,$i); } }
$speed_limit=512; # chunks smaller than $speed_limit are
# processed with compact routine in CBC mode
$small_footprint=1; # $small_footprint=1 code is ~5% slower [on
- # recent µ-archs], but ~5 times smaller!
+ # recent µ-archs], but ~5 times smaller!
# I favor compact code to minimize cache
# contention and in hope to "collect" 5% back
# in real-life applications...
@@ -565,7 +565,7 @@ sub enctransform()
# Performance is not actually extraordinary in comparison to pure
# x86 code. In particular encrypt performance is virtually the same.
# Decrypt performance on the other hand is 15-20% better on newer
-# µ-archs [but we're thankful for *any* improvement here], and ~50%
+# µ-archs [but we're thankful for *any* improvement here], and ~50%
# better on PIII:-) And additionally on the pros side this code
# eliminates redundant references to stack and thus relieves/
# minimizes the pressure on the memory bus.
diff --git a/src/crypto/aes/asm/aes-armv4.pl b/src/crypto/aes/asm/aes-armv4.pl
index 36cd3b6..882017a 100644
--- a/src/crypto/aes/asm/aes-armv4.pl
+++ b/src/crypto/aes/asm/aes-armv4.pl
@@ -65,7 +65,7 @@ $rounds="r12";
$code=<<___;
#if defined(__arm__)
#ifndef __KERNEL__
-# include "arm_arch.h"
+# include <openssl/arm_arch.h>
#else
# define __ARM_ARCH__ __LINUX_ARM_ARCH__
#endif
diff --git a/src/crypto/aes/asm/aesni-x86.pl b/src/crypto/aes/asm/aesni-x86.pl
index f67df8c..9b2e37a 100644
--- a/src/crypto/aes/asm/aesni-x86.pl
+++ b/src/crypto/aes/asm/aesni-x86.pl
@@ -88,7 +88,7 @@ $inout3="xmm5"; $in1="xmm5";
$inout4="xmm6"; $in0="xmm6";
$inout5="xmm7"; $ivec="xmm7";
-# AESNI extenstion
+# AESNI extension
sub aeskeygenassist
{ my($dst,$src,$imm)=@_;
if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
diff --git a/src/crypto/aes/asm/aesv8-armx.pl b/src/crypto/aes/asm/aesv8-armx.pl
index b0916f6..121154a 100644
--- a/src/crypto/aes/asm/aesv8-armx.pl
+++ b/src/crypto/aes/asm/aesv8-armx.pl
@@ -45,7 +45,7 @@ open OUT,"| \"$^X\" $xlate $flavour $output";
$prefix="aes_v8";
$code=<<___;
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
#if __ARM_MAX_ARCH__>=7
.text
diff --git a/src/crypto/aes/asm/bsaes-armv7.pl b/src/crypto/aes/asm/bsaes-armv7.pl
index 273f0b9..2617fef 100644
--- a/src/crypto/aes/asm/bsaes-armv7.pl
+++ b/src/crypto/aes/asm/bsaes-armv7.pl
@@ -701,9 +701,8 @@ ___
}
$code.=<<___;
-#if defined(__arm__)
#ifndef __KERNEL__
-# include "arm_arch.h"
+# include <openssl/arm_arch.h>
# define VFP_ABI_PUSH vstmdb sp!,{d8-d15}
# define VFP_ABI_POP vldmia sp!,{d8-d15}
@@ -2497,7 +2496,6 @@ ___
}
$code.=<<___;
#endif
-#endif
___
$code =~ s/\`([^\`]*)\`/eval($1)/gem;
diff --git a/src/crypto/aes/mode_wrappers.c b/src/crypto/aes/mode_wrappers.c
index c706896..dc657dc 100644
--- a/src/crypto/aes/mode_wrappers.c
+++ b/src/crypto/aes/mode_wrappers.c
@@ -48,9 +48,9 @@
#include <openssl/aes.h>
-#include "assert.h"
+#include <assert.h>
-#include <openssl/modes.h>
+#include "../modes/internal.h"
void AES_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
diff --git a/src/crypto/asn1/CMakeLists.txt b/src/crypto/asn1/CMakeLists.txt
index 283636e..41e3122 100644
--- a/src/crypto/asn1/CMakeLists.txt
+++ b/src/crypto/asn1/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
asn1
diff --git a/src/crypto/asn1/a_bitstr.c b/src/crypto/asn1/a_bitstr.c
index 8055f0c..8bad339 100644
--- a/src/crypto/asn1/a_bitstr.c
+++ b/src/crypto/asn1/a_bitstr.c
@@ -125,8 +125,7 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
if (len < 1)
{
- OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_BIT_STRING,
- ASN1_R_STRING_TOO_SHORT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
goto err;
}
@@ -141,8 +140,7 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
padding = *(p++);
if (padding > 7)
{
- OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_BIT_STRING,
- ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
goto err;
}
@@ -157,8 +155,7 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
s=(unsigned char *)OPENSSL_malloc((int)len);
if (s == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_BIT_STRING,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
memcpy(s,p,(int)len);
@@ -209,7 +206,7 @@ int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
w+1);
if (c == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_BIT_STRING_set_bit, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return 0;
}
if (w+1-a->length > 0) memset(c+a->length, 0, w+1-a->length);
diff --git a/src/crypto/asn1/a_bool.c b/src/crypto/asn1/a_bool.c
index c30ee48..826bcf4 100644
--- a/src/crypto/asn1/a_bool.c
+++ b/src/crypto/asn1/a_bool.c
@@ -107,6 +107,6 @@ int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length)
*pp=p;
return(ret);
err:
- OPENSSL_PUT_ERROR(ASN1, d2i_ASN1_BOOLEAN, i);
+ OPENSSL_PUT_ERROR(ASN1, i);
return(ret);
}
diff --git a/src/crypto/asn1/a_bytes.c b/src/crypto/asn1/a_bytes.c
index 8874f48..1904375 100644
--- a/src/crypto/asn1/a_bytes.c
+++ b/src/crypto/asn1/a_bytes.c
@@ -125,7 +125,7 @@ ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp,
*pp=p;
return(ret);
err:
- OPENSSL_PUT_ERROR(ASN1, d2i_ASN1_type_bytes, i);
+ OPENSSL_PUT_ERROR(ASN1, i);
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
ASN1_STRING_free(ret);
return(NULL);
@@ -243,7 +243,7 @@ ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
err:
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
ASN1_STRING_free(ret);
- OPENSSL_PUT_ERROR(ASN1, d2i_ASN1_bytes, i);
+ OPENSSL_PUT_ERROR(ASN1, i);
return(NULL);
}
@@ -309,7 +309,7 @@ static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c)
if (os != NULL) ASN1_STRING_free(os);
return(1);
err:
- OPENSSL_PUT_ERROR(ASN1, asn1_collate_primitive, c->error);
+ OPENSSL_PUT_ERROR(ASN1, c->error);
if (os != NULL) ASN1_STRING_free(os);
if (b.data != NULL) OPENSSL_free(b.data);
return(0);
diff --git a/src/crypto/asn1/a_d2i_fp.c b/src/crypto/asn1/a_d2i_fp.c
index 6022c74..97ec75b 100644
--- a/src/crypto/asn1/a_d2i_fp.c
+++ b/src/crypto/asn1/a_d2i_fp.c
@@ -75,7 +75,7 @@ void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x)
if ((b=BIO_new(BIO_s_file())) == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_d2i_fp, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
return(NULL);
}
BIO_set_fp(b,in,BIO_NOCLOSE);
@@ -129,7 +129,7 @@ void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x)
if ((b=BIO_new(BIO_s_file())) == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_d2i_fp, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
return(NULL);
}
BIO_set_fp(b,in,BIO_NOCLOSE);
@@ -154,7 +154,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
b=BUF_MEM_new();
if (b == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return -1;
}
@@ -167,20 +167,20 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
if (len + want < len || !BUF_MEM_grow_clean(b,len+want))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
i=BIO_read(in,&(b->data[len]),want);
if ((i < 0) && ((len-off) == 0))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_NOT_ENOUGH_DATA);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
goto err;
}
if (i > 0)
{
if (len+i < len)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_TOO_LONG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
goto err;
}
len+=i;
@@ -211,7 +211,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
eos++;
if (eos < 0)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_HEADER_TOO_LONG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG);
goto err;
}
want=HEADER_SIZE;
@@ -235,12 +235,12 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
if (want > INT_MAX /* BIO_read takes an int length */ ||
len+want < len)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_TOO_LONG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
goto err;
}
if (!BUF_MEM_grow_clean(b,len+want))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
while (want > 0)
@@ -248,7 +248,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
i=BIO_read(in,&(b->data[len]),want);
if (i <= 0)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_NOT_ENOUGH_DATA);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
goto err;
}
/* This can't overflow because
@@ -259,7 +259,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
}
if (off + c.slen < off)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_TOO_LONG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
goto err;
}
off+=c.slen;
@@ -274,7 +274,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
if (off > INT_MAX)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_TOO_LONG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
goto err;
}
diff --git a/src/crypto/asn1/a_dup.c b/src/crypto/asn1/a_dup.c
index 8ec1c5f..5e87457 100644
--- a/src/crypto/asn1/a_dup.c
+++ b/src/crypto/asn1/a_dup.c
@@ -72,7 +72,7 @@ void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x)
i=i2d(x,NULL);
b=OPENSSL_malloc(i+10);
if (b == NULL)
- { OPENSSL_PUT_ERROR(ASN1, ASN1_dup, ERR_R_MALLOC_FAILURE); return(NULL); }
+ { OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); return(NULL); }
p= b;
i=i2d(x,&p);
p2= b;
@@ -95,7 +95,7 @@ void *ASN1_item_dup(const ASN1_ITEM *it, void *x)
i=ASN1_item_i2d(x,&b,it);
if (b == NULL)
- { OPENSSL_PUT_ERROR(ASN1, ASN1_item_dup, ERR_R_MALLOC_FAILURE); return(NULL); }
+ { OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); return(NULL); }
p= b;
ret=ASN1_item_d2i(NULL,&p,i, it);
OPENSSL_free(b);
diff --git a/src/crypto/asn1/a_enum.c b/src/crypto/asn1/a_enum.c
index a581a34..579dafd 100644
--- a/src/crypto/asn1/a_enum.c
+++ b/src/crypto/asn1/a_enum.c
@@ -84,7 +84,7 @@ int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
}
if (a->data == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_ENUMERATED_set, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return(0);
}
d=v;
@@ -147,7 +147,7 @@ ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
ret=ai;
if (ret == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, BN_to_ASN1_ENUMERATED, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
if(BN_is_negative(bn)) ret->type = V_ASN1_NEG_ENUMERATED;
@@ -159,7 +159,7 @@ ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
unsigned char *new_data=OPENSSL_realloc(ret->data, len+4);
if (!new_data)
{
- OPENSSL_PUT_ERROR(ASN1, BN_to_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
ret->data=new_data;
@@ -177,7 +177,7 @@ BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn)
BIGNUM *ret;
if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
- OPENSSL_PUT_ERROR(ASN1, ASN1_ENUMERATED_to_BN, ASN1_R_BN_LIB);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB);
else if(ai->type == V_ASN1_NEG_ENUMERATED) BN_set_negative(ret,1);
return(ret);
}
diff --git a/src/crypto/asn1/a_gentm.c b/src/crypto/asn1/a_gentm.c
index be093a4..7cb18a9 100644
--- a/src/crypto/asn1/a_gentm.c
+++ b/src/crypto/asn1/a_gentm.c
@@ -239,7 +239,7 @@ ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
p=OPENSSL_malloc(len);
if (p == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_GENERALIZEDTIME_adj, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return(NULL);
}
if (s->data != NULL)
diff --git a/src/crypto/asn1/a_i2d_fp.c b/src/crypto/asn1/a_i2d_fp.c
index 11e40d3..74ded78 100644
--- a/src/crypto/asn1/a_i2d_fp.c
+++ b/src/crypto/asn1/a_i2d_fp.c
@@ -67,7 +67,7 @@ int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x)
if ((b=BIO_new(BIO_s_file())) == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_i2d_fp, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,out,BIO_NOCLOSE);
@@ -76,7 +76,7 @@ int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x)
return(ret);
}
-int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x)
+int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, void *x)
{
char *b;
unsigned char *p;
@@ -86,7 +86,7 @@ int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x)
b=(char *)OPENSSL_malloc(n);
if (b == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_i2d_bio, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return(0);
}
@@ -116,7 +116,7 @@ int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x)
if ((b=BIO_new(BIO_s_file())) == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_i2d_fp, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,out,BIO_NOCLOSE);
@@ -133,7 +133,7 @@ int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x)
n = ASN1_item_i2d(x, &b, it);
if (b == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_i2d_bio, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return(0);
}
diff --git a/src/crypto/asn1/a_int.c b/src/crypto/asn1/a_int.c
index 16b8950..46855d9 100644
--- a/src/crypto/asn1/a_int.c
+++ b/src/crypto/asn1/a_int.c
@@ -259,7 +259,7 @@ ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
*pp=pend;
return(ret);
err:
- OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_INTEGER, i);
+ OPENSSL_PUT_ERROR(ASN1, i);
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
M_ASN1_INTEGER_free(ret);
return(NULL);
@@ -329,7 +329,7 @@ ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
*pp=p;
return(ret);
err:
- OPENSSL_PUT_ERROR(ASN1, d2i_ASN1_UINTEGER, i);
+ OPENSSL_PUT_ERROR(ASN1, i);
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
M_ASN1_INTEGER_free(ret);
return(NULL);
@@ -352,7 +352,7 @@ int ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
}
if (a->data == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_INTEGER_set, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return(0);
}
d=v;
@@ -415,7 +415,7 @@ ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
ret=ai;
if (ret == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, BN_to_ASN1_INTEGER, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
if (BN_is_negative(bn) && !BN_is_zero(bn))
@@ -428,7 +428,7 @@ ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
unsigned char *new_data=OPENSSL_realloc(ret->data, len+4);
if (!new_data)
{
- OPENSSL_PUT_ERROR(ASN1, BN_to_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
ret->data=new_data;
@@ -451,7 +451,7 @@ BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
BIGNUM *ret;
if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
- OPENSSL_PUT_ERROR(ASN1, ASN1_INTEGER_to_BN, ASN1_R_BN_LIB);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB);
else if(ai->type == V_ASN1_NEG_INTEGER)
BN_set_negative(ret, 1);
return(ret);
diff --git a/src/crypto/asn1/a_mbstr.c b/src/crypto/asn1/a_mbstr.c
index 9abe659..42806d1 100644
--- a/src/crypto/asn1/a_mbstr.c
+++ b/src/crypto/asn1/a_mbstr.c
@@ -108,7 +108,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
case MBSTRING_BMP:
if(len & 1) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ASN1_R_INVALID_BMPSTRING_LENGTH);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BMPSTRING_LENGTH);
return -1;
}
nchar = len >> 1;
@@ -116,7 +116,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
case MBSTRING_UNIV:
if(len & 3) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
return -1;
}
nchar = len >> 2;
@@ -127,7 +127,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
/* This counts the characters and does utf8 syntax checking */
ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar);
if(ret < 0) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ASN1_R_INVALID_UTF8STRING);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UTF8STRING);
return -1;
}
break;
@@ -137,19 +137,19 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
break;
default:
- OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ASN1_R_UNKNOWN_FORMAT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
return -1;
}
if((minsize > 0) && (nchar < minsize)) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ASN1_R_STRING_TOO_SHORT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
BIO_snprintf(strbuf, sizeof strbuf, "%ld", minsize);
ERR_add_error_data(2, "minsize=", strbuf);
return -1;
}
if((maxsize > 0) && (nchar > maxsize)) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ASN1_R_STRING_TOO_LONG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG);
BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize);
ERR_add_error_data(2, "maxsize=", strbuf);
return -1;
@@ -157,7 +157,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
/* Now work out minimal type (if any) */
if(traverse_string(in, len, inform, type_str, &mask) < 0) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ASN1_R_ILLEGAL_CHARACTERS);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_CHARACTERS);
return -1;
}
@@ -191,7 +191,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
free_out = 1;
dest = ASN1_STRING_type_new(str_type);
if(!dest) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return -1;
}
*out = dest;
@@ -199,7 +199,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
/* If both the same type just copy across */
if(inform == outform) {
if(!ASN1_STRING_set(dest, in, len)) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return -1;
}
return str_type;
@@ -230,7 +230,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
}
if(!(p = OPENSSL_malloc(outlen + 1))) {
if(free_out) ASN1_STRING_free(dest);
- OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return -1;
}
dest->length = outlen;
diff --git a/src/crypto/asn1/a_object.c b/src/crypto/asn1/a_object.c
index 189886c..6ddfca9 100644
--- a/src/crypto/asn1/a_object.c
+++ b/src/crypto/asn1/a_object.c
@@ -106,13 +106,13 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
}
else
{
- OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_FIRST_NUM_TOO_LARGE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_FIRST_NUM_TOO_LARGE);
goto err;
}
if (num <= 0)
{
- OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_MISSING_SECOND_NUMBER);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_SECOND_NUMBER);
goto err;
}
c= *(p++);
@@ -122,7 +122,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
if (num <= 0) break;
if ((c != '.') && (c != ' '))
{
- OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_INVALID_SEPARATOR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_SEPARATOR);
goto err;
}
l=0;
@@ -136,7 +136,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
break;
if ((c < '0') || (c > '9'))
{
- OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_INVALID_DIGIT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_DIGIT);
goto err;
}
if (!use_bn && l >= ((ULONG_MAX - 80) / 10L))
@@ -160,7 +160,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
{
if ((first < 2) && (l >= 40))
{
- OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_SECOND_NUMBER_TOO_LARGE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_SECOND_NUMBER_TOO_LARGE);
goto err;
}
if (use_bn)
@@ -204,7 +204,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
{
if (len+i > olen)
{
- OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_BUFFER_TOO_SMALL);
goto err;
}
while (--i > 0)
@@ -280,7 +280,7 @@ ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
if(ret) *pp = p;
return ret;
err:
- OPENSSL_PUT_ERROR(ASN1, d2i_ASN1_OBJECT, i);
+ OPENSSL_PUT_ERROR(ASN1, i);
return(NULL);
}
@@ -300,7 +300,7 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
p[len - 1] & 0x80)
{
- OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING);
return NULL;
}
/* Now 0 < len <= INT_MAX, so the cast is safe. */
@@ -309,7 +309,7 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
{
if (*p == 0x80 && (!i || !(p[-1] & 0x80)))
{
- OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING);
return NULL;
}
}
@@ -350,7 +350,7 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
*pp=p;
return(ret);
err:
- OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_OBJECT, i);
+ OPENSSL_PUT_ERROR(ASN1, i);
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
ASN1_OBJECT_free(ret);
return(NULL);
@@ -363,7 +363,7 @@ ASN1_OBJECT *ASN1_OBJECT_new(void)
ret=(ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT));
if (ret == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_OBJECT_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return(NULL);
}
ret->length=0;
diff --git a/src/crypto/asn1/a_strnid.c b/src/crypto/asn1/a_strnid.c
index df849e1..d4316f7 100644
--- a/src/crypto/asn1/a_strnid.c
+++ b/src/crypto/asn1/a_strnid.c
@@ -215,13 +215,13 @@ int ASN1_STRING_TABLE_add(int nid,
flags &= ~STABLE_FLAGS_MALLOC;
if(!stable) stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
if(!stable) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_STRING_TABLE_add, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return 0;
}
if(!(tmp = ASN1_STRING_TABLE_get(nid))) {
tmp = OPENSSL_malloc(sizeof(ASN1_STRING_TABLE));
if(!tmp) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_STRING_TABLE_add, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return 0;
}
tmp->flags = flags | STABLE_FLAGS_MALLOC;
diff --git a/src/crypto/asn1/a_time.c b/src/crypto/asn1/a_time.c
index e02e858..ac2cb48 100644
--- a/src/crypto/asn1/a_time.c
+++ b/src/crypto/asn1/a_time.c
@@ -85,7 +85,7 @@ int i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **pp)
if(a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME)
return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
a->type ,V_ASN1_UNIVERSAL));
- OPENSSL_PUT_ERROR(ASN1, XXX, ASN1_R_EXPECTING_A_TIME);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPECTING_A_TIME);
return -1;
}
#endif
@@ -105,7 +105,7 @@ ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t,
ts=OPENSSL_gmtime(&t,&data);
if (ts == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_TIME_adj, ASN1_R_ERROR_GETTING_TIME);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ERROR_GETTING_TIME);
return NULL;
}
if (offset_day || offset_sec)
diff --git a/src/crypto/asn1/a_utctm.c b/src/crypto/asn1/a_utctm.c
index 52b010f..dbbbecb 100644
--- a/src/crypto/asn1/a_utctm.c
+++ b/src/crypto/asn1/a_utctm.c
@@ -81,12 +81,12 @@ ASN1_UTCTIME *d2i_ASN1_UTCTIME(ASN1_UTCTIME **a, unsigned char **pp,
V_ASN1_UTCTIME,V_ASN1_UNIVERSAL);
if (ret == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, XXX, ERR_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_NESTED_ASN1_ERROR);
return(NULL);
}
if (!ASN1_UTCTIME_check(ret))
{
- OPENSSL_PUT_ERROR(ASN1, XXX, ASN1_R_INVALID_TIME_FORMAT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_TIME_FORMAT);
goto err;
}
@@ -257,7 +257,7 @@ ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
p=OPENSSL_malloc(len);
if (p == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_UTCTIME_adj, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
if (s->data != NULL)
diff --git a/src/crypto/asn1/asn1_lib.c b/src/crypto/asn1/asn1_lib.c
index 9aa2678..0f2ce50 100644
--- a/src/crypto/asn1/asn1_lib.c
+++ b/src/crypto/asn1/asn1_lib.c
@@ -64,22 +64,11 @@
#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_FUNCTION(ASN1, i2d_PrivateKey);
OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_PUBLIC_KEY_TYPE);
/* Cross-module errors from crypto/x509/asn1_gen.c.
* TODO(davidben): Remove these once asn1_gen.c is gone. */
-OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, ASN1_generate_v3);
-OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, asn1_cb);
-OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, parse_tagging);
-OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, append_exp);
-OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, asn1_str2type);
-OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, bitstr_cb);
OPENSSL_DECLARE_ERROR_REASON(ASN1, DEPTH_EXCEEDED);
OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BITSTRING_FORMAT);
OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BOOLEAN);
@@ -183,7 +172,7 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
#endif
if (*plength > (omax - (p - *pp)))
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_get_object, ASN1_R_TOO_LONG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
/* Set this so that even if things are not long enough
* the values are set correctly */
ret|=0x80;
@@ -191,7 +180,7 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
*pp=p;
return(ret|inf);
err:
- OPENSSL_PUT_ERROR(ASN1, ASN1_get_object, ASN1_R_HEADER_TOO_LONG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG);
return(0x80);
}
@@ -433,7 +422,7 @@ int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
if (str->data == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_STRING_set, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
str->data=c;
return(0);
}
@@ -469,7 +458,7 @@ ASN1_STRING *ASN1_STRING_type_new(int type)
ret=(ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING));
if (ret == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_STRING_type_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return(NULL);
}
ret->length=0;
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/asn_pack.c b/src/crypto/asn1/asn_pack.c
index ee58fa5..e842a10 100644
--- a/src/crypto/asn1/asn_pack.c
+++ b/src/crypto/asn1/asn_pack.c
@@ -68,7 +68,7 @@ ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct)
if (!oct || !*oct) {
if (!(octmp = ASN1_STRING_new ())) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_pack, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return NULL;
}
if (oct) *oct = octmp;
@@ -80,11 +80,11 @@ ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct)
}
if (!(octmp->length = ASN1_item_i2d(obj, &octmp->data, it))) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_pack, ASN1_R_ENCODE_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ENCODE_ERROR);
return NULL;
}
if (!octmp->data) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_pack, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return NULL;
}
return octmp;
@@ -99,6 +99,6 @@ void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it)
p = oct->data;
if(!(ret = ASN1_item_d2i(NULL, &p, oct->length, it)))
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_unpack, ASN1_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR);
return ret;
}
diff --git a/src/crypto/asn1/bio_ndef.c b/src/crypto/asn1/bio_ndef.c
index 2f7105d..f07d3de 100644
--- a/src/crypto/asn1/bio_ndef.c
+++ b/src/crypto/asn1/bio_ndef.c
@@ -112,7 +112,7 @@ BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
if (!aux || !aux->asn1_cb)
{
- OPENSSL_PUT_ERROR(ASN1, BIO_new_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_STREAMING_NOT_SUPPORTED);
return NULL;
}
ndef_aux = OPENSSL_malloc(sizeof(NDEF_SUPPORT));
diff --git a/src/crypto/asn1/f_enum.c b/src/crypto/asn1/f_enum.c
index 530afe5..bcdb773 100644
--- a/src/crypto/asn1/f_enum.c
+++ b/src/crypto/asn1/f_enum.c
@@ -144,7 +144,7 @@ int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
i-=again;
if (i%2 != 0)
{
- OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_ENUMERATED, ASN1_R_ODD_NUMBER_OF_CHARS);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
}
i/=2;
@@ -158,7 +158,7 @@ int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
(unsigned int)num+i*2);
if (sp == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
s=sp;
@@ -177,7 +177,7 @@ int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
m=m-'A'+10;
else
{
- OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_ENUMERATED, ASN1_R_NON_HEX_CHARACTERS);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
goto err;
}
s[num+j]<<=4;
@@ -197,7 +197,7 @@ err:
if (0)
{
err_sl:
- OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_ENUMERATED, ASN1_R_SHORT_LINE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
}
if (s != NULL)
OPENSSL_free(s);
diff --git a/src/crypto/asn1/f_int.c b/src/crypto/asn1/f_int.c
index 2c4fe6f..5186304 100644
--- a/src/crypto/asn1/f_int.c
+++ b/src/crypto/asn1/f_int.c
@@ -149,7 +149,7 @@ int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
i-=again;
if (i%2 != 0)
{
- OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_INTEGER, ASN1_R_ODD_NUMBER_OF_CHARS);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
}
i/=2;
@@ -162,7 +162,7 @@ int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
sp=OPENSSL_realloc_clean(s,slen,num+i*2);
if (sp == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
s=sp;
@@ -181,7 +181,7 @@ int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
m=m-'A'+10;
else
{
- OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_INTEGER, ASN1_R_NON_HEX_CHARACTERS);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
goto err;
}
s[num+j]<<=4;
@@ -201,7 +201,7 @@ err:
if (0)
{
err_sl:
- OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_INTEGER, ASN1_R_SHORT_LINE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
}
if (s != NULL)
OPENSSL_free(s);
diff --git a/src/crypto/asn1/f_string.c b/src/crypto/asn1/f_string.c
index 2f53670..5a7fe36 100644
--- a/src/crypto/asn1/f_string.c
+++ b/src/crypto/asn1/f_string.c
@@ -142,7 +142,7 @@ int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
i-=again;
if (i%2 != 0)
{
- OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_STRING, ASN1_R_ODD_NUMBER_OF_CHARS);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
}
i/=2;
@@ -156,7 +156,7 @@ int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
(unsigned int)num+i*2);
if (sp == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_STRING, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
s=sp;
@@ -175,7 +175,7 @@ int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
m=m-'A'+10;
else
{
- OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_STRING, ASN1_R_NON_HEX_CHARACTERS);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
goto err;
}
s[num+j]<<=4;
@@ -195,7 +195,7 @@ err:
if (0)
{
err_sl:
- OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_STRING, ASN1_R_SHORT_LINE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
}
if (s != NULL)
OPENSSL_free(s);
diff --git a/src/crypto/asn1/tasn_dec.c b/src/crypto/asn1/tasn_dec.c
index 73d3bb3..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)
@@ -189,7 +190,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
*/
if ((tag != -1) || opt)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
goto err;
}
return asn1_template_ex_d2i(pval, in, len,
@@ -206,7 +207,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
&p, len, -1, 0, 1, ctx);
if (!ret)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
@@ -215,7 +216,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
{
/* If OPTIONAL, assume this is OK */
if (opt) return -1;
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_MSTRING_NOT_UNIVERSAL);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_NOT_UNIVERSAL);
goto err;
}
/* Check tag matches bit map */
@@ -224,7 +225,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
/* If OPTIONAL, assume this is OK */
if (opt)
return -1;
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_MSTRING_WRONG_TAG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_WRONG_TAG);
goto err;
}
return asn1_d2i_ex_primitive(pval, in, len,
@@ -255,7 +256,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
&p, len, exptag, aclass, 1, ctx);
if (!ret)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
if (ret == -1)
@@ -283,7 +284,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
imphack = *wp;
if (p == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
*wp = (unsigned char)((*p & V_ASN1_CONSTRUCTED)
@@ -298,7 +299,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
if (ptmpval)
return 1;
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
@@ -320,7 +321,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
}
else if (!ASN1_item_ex_new(pval, it))
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
/* CHOICE type, try each possibility in turn */
@@ -340,7 +341,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
break;
/* Otherwise must be an ASN1 parsing error */
errtt = tt;
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
@@ -354,14 +355,14 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
ASN1_item_ex_free(pval, it);
return -1;
}
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NO_MATCHING_CHOICE_TYPE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NO_MATCHING_CHOICE_TYPE);
goto err;
}
asn1_set_choice_selector(pval, i, it);
- *in = p;
if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
goto auxerr;
+ *in = p;
return 1;
case ASN1_ITYPE_NDEF_SEQUENCE:
@@ -380,7 +381,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
&p, len, tag, aclass, opt, ctx);
if (!ret)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
else if (ret == -1)
@@ -394,13 +395,13 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
else seq_nolen = seq_eoc;
if (!cst)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
goto err;
}
if (!*pval && !ASN1_item_ex_new(pval, it))
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
@@ -437,7 +438,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
{
if (!seq_eoc)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_UNEXPECTED_EOC);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC);
goto err;
}
len -= p - q;
@@ -479,13 +480,13 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
/* Check for EOC if expecting one */
if (seq_eoc && !asn1_check_eoc(&p, len))
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_MISSING_EOC);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
goto err;
}
/* Check all data read */
if (!seq_nolen && len)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_SEQUENCE_LENGTH_MISMATCH);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_LENGTH_MISMATCH);
goto err;
}
@@ -508,25 +509,26 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
else
{
errtt = seqtt;
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_FIELD_MISSING);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_FIELD_MISSING);
goto err;
}
}
/* Save encoding */
if (!asn1_enc_save(pval, *in, p - *in, it))
goto auxerr;
- *in = p;
if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
goto auxerr;
+ *in = p;
return 1;
default:
return 0;
}
auxerr:
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_AUX_ERROR);
+ 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);
@@ -569,21 +571,21 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val,
q = p;
if (!ret)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_template_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
return 0;
}
else if (ret == -1)
return -1;
if (!cst)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_template_ex_d2i, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
return 0;
}
/* We've found the field so it can't be OPTIONAL now */
ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx);
if (!ret)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_template_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
return 0;
}
/* We read the field in OK so update length */
@@ -593,7 +595,7 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val,
/* If NDEF we must have an EOC here */
if (!asn1_check_eoc(&p, len))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_template_ex_d2i, ASN1_R_MISSING_EOC);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
goto err;
}
}
@@ -603,7 +605,7 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val,
* an error */
if (len)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_template_ex_d2i, ASN1_R_EXPLICIT_LENGTH_MISMATCH);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPLICIT_LENGTH_MISMATCH);
goto err;
}
}
@@ -659,7 +661,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
&p, len, sktag, skaclass, opt, ctx);
if (!ret)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
return 0;
}
else if (ret == -1)
@@ -682,7 +684,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
if (!*val)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -696,7 +698,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
{
if (!sk_eoc)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ASN1_R_UNEXPECTED_EOC);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC);
goto err;
}
len -= p - q;
@@ -708,20 +710,20 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
ASN1_ITEM_ptr(tt->item),
-1, 0, 0, ctx))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
len -= p - q;
if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val,
skfield))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
}
if (sk_eoc)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ASN1_R_MISSING_EOC);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
goto err;
}
}
@@ -732,7 +734,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, ctx);
if (!ret)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
else if (ret == -1)
@@ -742,10 +744,10 @@ 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_template_noexp_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
else if (ret == -1)
@@ -775,7 +777,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
long len;
if (!pval)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ASN1_R_ILLEGAL_NULL);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL);
return 0; /* Should never happen */
}
@@ -793,12 +795,12 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
unsigned char oclass;
if (tag >= 0)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ASN1_R_ILLEGAL_TAGGED_ANY);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TAGGED_ANY);
return 0;
}
if (opt)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ASN1_R_ILLEGAL_OPTIONAL_ANY);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONAL_ANY);
return 0;
}
p = *in;
@@ -806,7 +808,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
&p, inlen, -1, 0, 0, ctx);
if (!ret)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
return 0;
}
if (oclass != V_ASN1_UNIVERSAL)
@@ -823,7 +825,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
&p, inlen, tag, aclass, opt, ctx);
if (!ret)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
return 0;
}
else if (ret == -1)
@@ -843,7 +845,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
/* SEQUENCE and SET must be constructed */
else if (!cst)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ASN1_R_TYPE_NOT_CONSTRUCTED);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_CONSTRUCTED);
return 0;
}
@@ -869,8 +871,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
|| utype == V_ASN1_ENUMERATED)
{
/* These types only have primitive encodings. */
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive,
- ASN1_R_TYPE_NOT_PRIMITIVE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_PRIMITIVE);
return 0;
}
@@ -892,7 +893,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
/* Append a final null to string */
if (!BUF_MEM_grow_clean(&buf, len + 1))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return 0;
}
buf.data[len] = 0;
@@ -960,7 +961,7 @@ int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
case V_ASN1_NULL:
if (len)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i, ASN1_R_NULL_IS_WRONG_LENGTH);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NULL_IS_WRONG_LENGTH);
goto err;
}
*pval = (ASN1_VALUE *)1;
@@ -969,7 +970,7 @@ int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
case V_ASN1_BOOLEAN:
if (len != 1)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i, ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
goto err;
}
else
@@ -1016,12 +1017,12 @@ int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
default:
if (utype == V_ASN1_BMPSTRING && (len & 1))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i, ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
goto err;
}
if (utype == V_ASN1_UNIVERSALSTRING && (len & 3))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
goto err;
}
/* All based on ASN1_STRING and handled the same */
@@ -1030,7 +1031,7 @@ int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
stmp = ASN1_STRING_type_new(utype);
if (!stmp)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
*pval = (ASN1_VALUE *)stmp;
@@ -1053,7 +1054,7 @@ int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
{
if (!ASN1_STRING_set(stmp, cont, len))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
ASN1_STRING_free(stmp);
*pval = NULL;
goto err;
@@ -1115,7 +1116,7 @@ static int asn1_find_end(const unsigned char **in, long len, char inf)
if(!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len,
-1, 0, 0, NULL))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_find_end, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
return 0;
}
if (inf)
@@ -1126,7 +1127,7 @@ static int asn1_find_end(const unsigned char **in, long len, char inf)
}
if (expected_eoc)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_find_end, ASN1_R_MISSING_EOC);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
return 0;
}
*in = p;
@@ -1173,7 +1174,7 @@ static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
* constructed form */
if (!inf)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_collect, ASN1_R_UNEXPECTED_EOC);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC);
return 0;
}
inf = 0;
@@ -1183,7 +1184,7 @@ static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p,
len, tag, aclass, 0, NULL))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_collect, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
return 0;
}
@@ -1192,7 +1193,7 @@ static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
{
if (depth >= ASN1_MAX_STRING_NEST)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_collect, ASN1_R_NESTED_ASN1_STRING);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_STRING);
return 0;
}
if (!asn1_collect(buf, &p, plen, ininf, tag, aclass,
@@ -1205,7 +1206,7 @@ static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
}
if (inf)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_collect, ASN1_R_MISSING_EOC);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
return 0;
}
*in = p;
@@ -1220,7 +1221,7 @@ static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen)
len = buf->length;
if (!BUF_MEM_grow_clean(buf, len + plen))
{
- OPENSSL_PUT_ERROR(ASN1, collect_data, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return 0;
}
memcpy(buf->data + len, *p, plen);
@@ -1288,7 +1289,7 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
*/
if (!(i & 0x81) && ((plen + ctx->hdrlen) > len))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_check_tlen, ASN1_R_TOO_LONG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
asn1_tlc_clear(ctx);
return 0;
}
@@ -1297,7 +1298,7 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
if (i & 0x80)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_check_tlen, ASN1_R_BAD_OBJECT_HEADER);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_OBJECT_HEADER);
asn1_tlc_clear(ctx);
return 0;
}
@@ -1310,7 +1311,7 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
*/
if (opt) return -1;
asn1_tlc_clear(ctx);
- OPENSSL_PUT_ERROR(ASN1, asn1_check_tlen, ASN1_R_WRONG_TAG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TAG);
return 0;
}
/* We have a tag and class match:
diff --git a/src/crypto/asn1/tasn_new.c b/src/crypto/asn1/tasn_new.c
index 6d69dcb..c68fe06 100644
--- a/src/crypto/asn1/tasn_new.c
+++ b/src/crypto/asn1/tasn_new.c
@@ -209,7 +209,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
return 1;
memerr:
- OPENSSL_PUT_ERROR(ASN1, asn1_item_ex_combine_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
ASN1_item_ex_free(pval, it);
#ifdef CRYPTO_MDEBUG
if (it->sname) CRYPTO_pop_info();
@@ -217,7 +217,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
return 0;
auxerr:
- OPENSSL_PUT_ERROR(ASN1, asn1_item_ex_combine_new, ASN1_R_AUX_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
ASN1_item_ex_free(pval, it);
#ifdef CRYPTO_MDEBUG
if (it->sname) CRYPTO_pop_info();
@@ -289,7 +289,7 @@ int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
skval = sk_ASN1_VALUE_new_null();
if (!skval)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_template_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
ret = 0;
goto done;
}
diff --git a/src/crypto/asn1/tasn_prn.c b/src/crypto/asn1/tasn_prn.c
index df19ff0..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 */
@@ -88,7 +88,7 @@ ASN1_PCTX *ASN1_PCTX_new(void)
ret = OPENSSL_malloc(sizeof(ASN1_PCTX));
if (ret == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_PCTX_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return NULL;
}
ret->flags = 0;
diff --git a/src/crypto/asn1/tasn_utl.c b/src/crypto/asn1/tasn_utl.c
index ff3764e..960cdbb 100644
--- a/src/crypto/asn1/tasn_utl.c
+++ b/src/crypto/asn1/tasn_utl.c
@@ -260,8 +260,7 @@ const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
err:
/* FIXME: should log the value or OID of unsupported type */
if (nullerr) {
- OPENSSL_PUT_ERROR(ASN1, asn1_do_adb,
- ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
}
return NULL;
}
diff --git a/src/crypto/asn1/x_bignum.c b/src/crypto/asn1/x_bignum.c
index f8c62fd..5867c4f 100644
--- a/src/crypto/asn1/x_bignum.c
+++ b/src/crypto/asn1/x_bignum.c
@@ -80,7 +80,8 @@ static const ASN1_PRIMITIVE_FUNCS bignum_pf = {
bn_free,
0,
bn_c2i,
- bn_i2c
+ bn_i2c,
+ NULL /* prim_print */,
};
ASN1_ITEM_start(BIGNUM)
diff --git a/src/crypto/asn1/x_long.c b/src/crypto/asn1/x_long.c
index 5c2f96e..7b1a6fe 100644
--- a/src/crypto/asn1/x_long.c
+++ b/src/crypto/asn1/x_long.c
@@ -150,7 +150,7 @@ static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
unsigned long utmp = 0;
char *cp = (char *)pval;
if(len > (int)sizeof(long)) {
- OPENSSL_PUT_ERROR(ASN1, long_c2i, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
return 0;
}
/* Is it negative? */
@@ -168,7 +168,7 @@ static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
ltmp = -ltmp;
}
if(ltmp == it->size) {
- OPENSSL_PUT_ERROR(ASN1, long_c2i, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
return 0;
}
memcpy(cp, &ltmp, sizeof(long));
diff --git a/src/crypto/base64/CMakeLists.txt b/src/crypto/base64/CMakeLists.txt
index 42037a5..15ee691 100644
--- a/src/crypto/base64/CMakeLists.txt
+++ b/src/crypto/base64/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
base64
@@ -17,3 +17,4 @@ add_executable(
)
target_link_libraries(base64_test crypto)
+add_dependencies(all_tests base64_test)
diff --git a/src/crypto/bio/CMakeLists.txt b/src/crypto/bio/CMakeLists.txt
index dbf5951..7859b58 100644
--- a/src/crypto/bio/CMakeLists.txt
+++ b/src/crypto/bio/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
bio
@@ -30,3 +30,4 @@ target_link_libraries(bio_test crypto)
if (WIN32)
target_link_libraries(bio_test ws2_32)
endif()
+add_dependencies(all_tests bio_test)
diff --git a/src/crypto/bio/bio.c b/src/crypto/bio/bio.c
index 5ac5911..7a1a9e3 100644
--- a/src/crypto/bio/bio.c
+++ b/src/crypto/bio/bio.c
@@ -90,7 +90,7 @@ static int bio_set(BIO *bio, const BIO_METHOD *method) {
BIO *BIO_new(const BIO_METHOD *method) {
BIO *ret = OPENSSL_malloc(sizeof(BIO));
if (ret == NULL) {
- OPENSSL_PUT_ERROR(BIO, BIO_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -153,7 +153,7 @@ static int bio_io(BIO *bio, void *buf, int len, size_t method_offset,
}
if (io_func == NULL) {
- OPENSSL_PUT_ERROR(BIO, bio_io, BIO_R_UNSUPPORTED_METHOD);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return -2;
}
@@ -165,7 +165,7 @@ static int bio_io(BIO *bio, void *buf, int len, size_t method_offset,
}
if (!bio->init) {
- OPENSSL_PUT_ERROR(BIO, bio_io, BIO_R_UNINITIALIZED);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
return -2;
}
@@ -217,7 +217,7 @@ long BIO_ctrl(BIO *bio, int cmd, long larg, void *parg) {
}
if (bio->method == NULL || bio->method->ctrl == NULL) {
- OPENSSL_PUT_ERROR(BIO, BIO_ctrl, BIO_R_UNSUPPORTED_METHOD);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return -2;
}
@@ -323,7 +323,7 @@ long BIO_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp) {
}
if (bio->method == NULL || bio->method->callback_ctrl == NULL) {
- OPENSSL_PUT_ERROR(BIO, BIO_callback_ctrl, BIO_R_UNSUPPORTED_METHOD);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
@@ -462,6 +462,10 @@ void BIO_print_errors(BIO *bio) {
ERR_print_errors_cb(print_bio, bio);
}
+void ERR_print_errors(BIO *bio) {
+ BIO_print_errors(bio);
+}
+
/* bio_read_all reads everything from |bio| and prepends |prefix| to it. On
* success, |*out| is set to an allocated buffer (which should be freed with
* |OPENSSL_free|), |*out_len| is set to its length and one is returned. The
@@ -525,7 +529,7 @@ int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, size_t max_len) {
uint8_t header[6];
static const size_t kInitialHeaderLen = 2;
- if (BIO_read(bio, header, kInitialHeaderLen) != kInitialHeaderLen) {
+ if (BIO_read(bio, header, kInitialHeaderLen) != (int) kInitialHeaderLen) {
return 0;
}
@@ -555,7 +559,8 @@ int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, size_t max_len) {
return 0;
}
- if (BIO_read(bio, header + kInitialHeaderLen, num_bytes) != num_bytes) {
+ if (BIO_read(bio, header + kInitialHeaderLen, num_bytes) !=
+ (int)num_bytes) {
return 0;
}
header_len = kInitialHeaderLen + num_bytes;
@@ -581,7 +586,8 @@ int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, size_t max_len) {
}
if (len + header_len < len ||
- len + header_len > max_len) {
+ len + header_len > max_len ||
+ len > INT_MAX) {
return 0;
}
len += header_len;
@@ -593,7 +599,7 @@ int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, size_t max_len) {
}
memcpy(*out, header, header_len);
if (BIO_read(bio, (*out) + header_len, len - header_len) !=
- len - header_len) {
+ (int) (len - header_len)) {
OPENSSL_free(*out);
return 0;
}
diff --git a/src/crypto/bio/bio_mem.c b/src/crypto/bio/bio_mem.c
index f3aad6f..6864f6f 100644
--- a/src/crypto/bio/bio_mem.c
+++ b/src/crypto/bio/bio_mem.c
@@ -70,7 +70,7 @@ BIO *BIO_new_mem_buf(void *buf, int len) {
const size_t size = len < 0 ? strlen((char *)buf) : (size_t)len;
if (!buf && len != 0) {
- OPENSSL_PUT_ERROR(BIO, BIO_new_mem_buf, BIO_R_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_NULL_PARAMETER);
return NULL;
}
@@ -167,7 +167,7 @@ static int mem_write(BIO *bio, const char *in, int inl) {
b = (BUF_MEM *)bio->ptr;
if (bio->flags & BIO_FLAGS_MEM_RDONLY) {
- OPENSSL_PUT_ERROR(BIO, mem_write, BIO_R_WRITE_TO_READ_ONLY_BIO);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_WRITE_TO_READ_ONLY_BIO);
goto err;
}
@@ -176,7 +176,7 @@ static int mem_write(BIO *bio, const char *in, int inl) {
if (INT_MAX - blen < inl) {
goto err;
}
- if (BUF_MEM_grow_clean(b, blen + inl) != (blen + inl)) {
+ if (BUF_MEM_grow_clean(b, blen + inl) != ((size_t) blen) + inl) {
goto err;
}
memcpy(&b->data[blen], in, inl);
diff --git a/src/crypto/bio/buffer.c b/src/crypto/bio/buffer.c
index 3fc0685..9d0cb3c 100644
--- a/src/crypto/bio/buffer.c
+++ b/src/crypto/bio/buffer.c
@@ -406,7 +406,7 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) {
return ret;
malloc_error:
- OPENSSL_PUT_ERROR(BIO, buffer_ctrl, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
return 0;
}
diff --git a/src/crypto/bio/connect.c b/src/crypto/bio/connect.c
index 32361bf..0b0bf13 100644
--- a/src/crypto/bio/connect.c
+++ b/src/crypto/bio/connect.c
@@ -93,7 +93,6 @@ typedef struct bio_connect_st {
char *param_port;
int nbio;
- uint8_t ip[4];
unsigned short port;
struct sockaddr_storage them;
@@ -114,23 +113,59 @@ static int closesocket(int sock) {
}
#endif
-/* maybe_copy_ipv4_address sets |*ipv4| to the IPv4 address from |ss| (in
- * big-endian order), if |ss| contains an IPv4 socket address. */
-static void maybe_copy_ipv4_address(uint8_t *ipv4,
- const struct sockaddr_storage *ss) {
- const struct sockaddr_in *sin;
+/* split_host_and_port sets |*out_host| and |*out_port| to the host and port
+ * parsed from |name|. It returns one on success or zero on error. Even when
+ * successful, |*out_port| may be NULL on return if no port was specified. */
+static int split_host_and_port(char **out_host, char **out_port, const char *name) {
+ const char *host, *port = NULL;
+ size_t host_len = 0;
- if (ss->ss_family != AF_INET) {
- return;
+ *out_host = NULL;
+ *out_port = NULL;
+
+ if (name[0] == '[') { /* bracketed IPv6 address */
+ const char *close = strchr(name, ']');
+ if (close == NULL) {
+ return 0;
+ }
+ host = name + 1;
+ host_len = close - host;
+ if (close[1] == ':') { /* [IP]:port */
+ port = close + 2;
+ } else if (close[1] != 0) {
+ return 0;
+ }
+ } else {
+ const char *colon = strchr(name, ':');
+ if (colon == NULL || strchr(colon + 1, ':') != NULL) { /* IPv6 address */
+ host = name;
+ host_len = strlen(name);
+ } else { /* host:port */
+ host = name;
+ host_len = colon - name;
+ port = colon + 1;
+ }
}
- sin = (const struct sockaddr_in*) ss;
- memcpy(ipv4, &sin->sin_addr, 4);
+ *out_host = BUF_strndup(host, host_len);
+ if (*out_host == NULL) {
+ return 0;
+ }
+ if (port == NULL) {
+ *out_port = NULL;
+ return 1;
+ }
+ *out_port = OPENSSL_strdup(port);
+ if (*out_port == NULL) {
+ OPENSSL_free(*out_host);
+ *out_host = NULL;
+ return 0;
+ }
+ return 1;
}
static int conn_state(BIO *bio, BIO_CONNECT *c) {
int ret = -1, i;
- char *p, *q;
int (*cb)(const BIO *, int, int) = NULL;
if (c->info_callback != NULL) {
@@ -140,52 +175,43 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
for (;;) {
switch (c->state) {
case BIO_CONN_S_BEFORE:
- p = c->param_hostname;
- if (p == NULL) {
- OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_NO_HOSTNAME_SPECIFIED);
+ /* If there's a hostname and a port, assume that both are
+ * exactly what they say. If there is only a hostname, try
+ * (just once) to split it into a hostname and port. */
+
+ if (c->param_hostname == NULL) {
+ OPENSSL_PUT_ERROR(BIO, BIO_R_NO_HOSTNAME_SPECIFIED);
goto exit_loop;
}
- for (; *p != 0; p++) {
- if (*p == ':' || *p == '/') {
- break;
- }
- }
- i = *p;
- if (i == ':' || i == '/') {
- *(p++) = 0;
- if (i == ':') {
- for (q = p; *q; q++) {
- if (*q == '/') {
- *q = 0;
- break;
- }
- }
- OPENSSL_free(c->param_port);
- c->param_port = BUF_strdup(p);
+ if (c->param_port == NULL) {
+ char *host, *port;
+ if (!split_host_and_port(&host, &port, c->param_hostname) ||
+ port == NULL) {
+ OPENSSL_free(host);
+ OPENSSL_free(port);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_NO_PORT_SPECIFIED);
+ ERR_add_error_data(2, "host=", c->param_hostname);
+ goto exit_loop;
}
- }
- if (c->param_port == NULL) {
- OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_NO_PORT_SPECIFIED);
- ERR_add_error_data(2, "host=", c->param_hostname);
- goto exit_loop;
+ OPENSSL_free(c->param_port);
+ c->param_port = port;
+ OPENSSL_free(c->param_hostname);
+ c->param_hostname = host;
}
if (!bio_ip_and_port_to_socket_and_addr(
&bio->num, &c->them, &c->them_length, c->param_hostname,
c->param_port)) {
- OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_UNABLE_TO_CREATE_SOCKET);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNABLE_TO_CREATE_SOCKET);
ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port);
goto exit_loop;
}
- memset(c->ip, 0, 4);
- maybe_copy_ipv4_address(c->ip, &c->them);
-
if (c->nbio) {
if (!bio_socket_nbio(bio->num, 1)) {
- OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_ERROR_SETTING_NBIO);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_ERROR_SETTING_NBIO);
ERR_add_error_data(4, "host=", c->param_hostname, ":",
c->param_port);
goto exit_loop;
@@ -196,8 +222,8 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
ret = setsockopt(bio->num, SOL_SOCKET, SO_KEEPALIVE, (char *)&i,
sizeof(i));
if (ret < 0) {
- OPENSSL_PUT_SYSTEM_ERROR(setsockopt);
- OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_KEEPALIVE);
+ OPENSSL_PUT_SYSTEM_ERROR();
+ OPENSSL_PUT_ERROR(BIO, BIO_R_KEEPALIVE);
ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port);
goto exit_loop;
}
@@ -210,8 +236,8 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
c->state = BIO_CONN_S_BLOCKED_CONNECT;
bio->retry_reason = BIO_RR_CONNECT;
} else {
- OPENSSL_PUT_SYSTEM_ERROR(connect);
- OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_CONNECT_ERROR);
+ OPENSSL_PUT_SYSTEM_ERROR();
+ OPENSSL_PUT_ERROR(BIO, BIO_R_CONNECT_ERROR);
ERR_add_error_data(4, "host=", c->param_hostname, ":",
c->param_port);
}
@@ -231,8 +257,8 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
ret = -1;
} else {
BIO_clear_retry_flags(bio);
- OPENSSL_PUT_SYSTEM_ERROR(connect);
- OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_NBIO_CONNECT_ERROR);
+ OPENSSL_PUT_SYSTEM_ERROR();
+ OPENSSL_PUT_ERROR(BIO, BIO_R_NBIO_CONNECT_ERROR);
ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port);
ret = 0;
}
@@ -376,7 +402,6 @@ static int conn_write(BIO *bio, const char *in, int in_len) {
static long conn_ctrl(BIO *bio, int cmd, long num, void *ptr) {
int *ip;
- const char **pptr;
long ret = 1;
BIO_CONNECT *data;
@@ -397,25 +422,6 @@ static long conn_ctrl(BIO *bio, int cmd, long num, void *ptr) {
ret = 1;
}
break;
- case BIO_C_GET_CONNECT:
- /* TODO(fork): can this be removed? (Or maybe this whole file). */
- if (ptr != NULL) {
- pptr = (const char **)ptr;
- if (num == 0) {
- *pptr = data->param_hostname;
- } else if (num == 1) {
- *pptr = data->param_port;
- } else if (num == 2) {
- *pptr = (char *) &data->ip[0];
- } else if (num == 3) {
- *((int *)ptr) = data->port;
- }
- if (!bio->init) {
- *pptr = "not initialized";
- }
- ret = 1;
- }
- break;
case BIO_C_SET_CONNECT:
if (ptr != NULL) {
bio->init = 1;
@@ -445,9 +451,9 @@ static long conn_ctrl(BIO *bio, int cmd, long num, void *ptr) {
if (ip != NULL) {
*ip = bio->num;
}
- ret = 1;
+ ret = bio->num;
} else {
- ret = 0;
+ ret = -1;
}
break;
case BIO_CTRL_GET_CLOSE:
@@ -464,7 +470,7 @@ static long conn_ctrl(BIO *bio, int cmd, long num, void *ptr) {
break;
case BIO_CTRL_SET_CALLBACK: {
#if 0 /* FIXME: Should this be used? -- Richard Levitte */
- OPENSSL_PUT_ERROR(BIO, XXX, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(BIO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
ret = -1;
#else
ret = 0;
diff --git a/src/crypto/bio/fd.c b/src/crypto/bio/fd.c
index 0b5baca..0b3484c 100644
--- a/src/crypto/bio/fd.c
+++ b/src/crypto/bio/fd.c
@@ -208,9 +208,9 @@ static long fd_ctrl(BIO *b, int cmd, long num, void *ptr) {
if (ip != NULL) {
*ip = b->num;
}
- return 1;
+ return b->num;
} else {
- ret = 0;
+ ret = -1;
}
break;
case BIO_CTRL_GET_CLOSE:
diff --git a/src/crypto/bio/file.c b/src/crypto/bio/file.c
index 7f57aad..9e29b43 100644
--- a/src/crypto/bio/file.c
+++ b/src/crypto/bio/file.c
@@ -88,7 +88,7 @@
#define BIO_FP_APPEND 0x08
static FILE *open_file(const char *filename, const char *mode) {
-#if defined(_WIN32) && defined(CP_UTF8)
+#if defined(OPENSSL_WINDOWS) && defined(CP_UTF8)
int sz, len_0 = (int)strlen(filename) + 1;
DWORD flags;
@@ -129,13 +129,13 @@ BIO *BIO_new_file(const char *filename, const char *mode) {
file = open_file(filename, mode);
if (file == NULL) {
- OPENSSL_PUT_SYSTEM_ERROR(fopen);
+ OPENSSL_PUT_SYSTEM_ERROR();
ERR_add_error_data(5, "fopen('", filename, "','", mode, "')");
if (errno == ENOENT) {
- OPENSSL_PUT_ERROR(BIO, BIO_new_file, BIO_R_NO_SUCH_FILE);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_NO_SUCH_FILE);
} else {
- OPENSSL_PUT_ERROR(BIO, BIO_new_file, BIO_R_SYS_LIB);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_SYS_LIB);
}
return NULL;
}
@@ -182,20 +182,19 @@ static int file_free(BIO *bio) {
}
static int file_read(BIO *b, char *out, int outl) {
- int ret = 0;
-
if (!b->init) {
return 0;
}
- ret = fread(out, 1, outl, (FILE *)b->ptr);
+ size_t ret = fread(out, 1, outl, (FILE *)b->ptr);
if (ret == 0 && ferror((FILE *)b->ptr)) {
- OPENSSL_PUT_SYSTEM_ERROR(fread);
- OPENSSL_PUT_ERROR(BIO, file_read, ERR_R_SYS_LIB);
- ret = -1;
+ OPENSSL_PUT_SYSTEM_ERROR();
+ OPENSSL_PUT_ERROR(BIO, ERR_R_SYS_LIB);
+ return -1;
}
- return ret;
+ /* fread reads at most |outl| bytes, so |ret| fits in an int. */
+ return (int)ret;
}
static int file_write(BIO *b, const char *in, int inl) {
@@ -253,15 +252,15 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) {
} else if (num & BIO_FP_READ) {
BUF_strlcpy(p, "r", sizeof(p));
} else {
- OPENSSL_PUT_ERROR(BIO, file_ctrl, BIO_R_BAD_FOPEN_MODE);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_BAD_FOPEN_MODE);
ret = 0;
break;
}
fp = open_file(ptr, p);
if (fp == NULL) {
- OPENSSL_PUT_SYSTEM_ERROR(fopen);
+ OPENSSL_PUT_SYSTEM_ERROR();
ERR_add_error_data(5, "fopen('", ptr, "','", p, "')");
- OPENSSL_PUT_ERROR(BIO, file_ctrl, ERR_R_SYS_LIB);
+ OPENSSL_PUT_ERROR(BIO, ERR_R_SYS_LIB);
ret = 0;
break;
}
diff --git a/src/crypto/bio/pair.c b/src/crypto/bio/pair.c
index cc55950..fba4be2 100644
--- a/src/crypto/bio/pair.c
+++ b/src/crypto/bio/pair.c
@@ -181,27 +181,25 @@ int BIO_zero_copy_get_read_buf(BIO* bio, uint8_t** out_read_buf,
BIO_clear_retry_flags(bio);
if (!bio->init) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf, BIO_R_UNINITIALIZED);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
return 0;
}
b = bio->ptr;
if (!b || !b->peer) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf,
- BIO_R_UNSUPPORTED_METHOD);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
peer_b = b->peer->ptr;
if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf,
- BIO_R_UNSUPPORTED_METHOD);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
if (peer_b->zero_copy_read_lock) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf, BIO_R_INVALID_ARGUMENT);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
return 0;
}
@@ -229,42 +227,37 @@ int BIO_zero_copy_get_read_buf_done(BIO* bio, size_t bytes_read) {
assert(BIO_get_retry_flags(bio) == 0);
if (!bio->init) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
- BIO_R_UNINITIALIZED);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
return 0;
}
b = bio->ptr;
if (!b || !b->peer) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
- BIO_R_UNSUPPORTED_METHOD);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
peer_b = b->peer->ptr;
if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
- BIO_R_UNSUPPORTED_METHOD);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
if (!peer_b->zero_copy_read_lock) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
- BIO_R_INVALID_ARGUMENT);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
return 0;
}
max_available =
bio_zero_copy_get_read_buf(peer_b, &dummy_read_buf, &dummy_read_offset);
if (bytes_read > max_available) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
- BIO_R_INVALID_ARGUMENT);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
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
@@ -318,35 +311,33 @@ int BIO_zero_copy_get_write_buf(BIO* bio, uint8_t** out_write_buf,
BIO_clear_retry_flags(bio);
if (!bio->init) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf, BIO_R_UNINITIALIZED);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
return 0;
}
b = bio->ptr;
if (!b || !b->buf || !b->peer) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf,
- BIO_R_UNSUPPORTED_METHOD);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
peer_b = b->peer->ptr;
if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf,
- BIO_R_UNSUPPORTED_METHOD);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
assert(b->buf != NULL);
if (b->zero_copy_write_lock) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf, BIO_R_INVALID_ARGUMENT);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
return 0;
}
b->request = 0;
if (b->closed) {
/* Bio is already closed. */
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf, BIO_R_BROKEN_PIPE);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_BROKEN_PIPE);
return 0;
}
@@ -369,43 +360,38 @@ int BIO_zero_copy_get_write_buf_done(BIO* bio, size_t bytes_written) {
uint8_t* dummy_write_buf;
if (!bio->init) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
- BIO_R_UNINITIALIZED);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
return 0;
}
b = bio->ptr;
if (!b || !b->buf || !b->peer) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
- BIO_R_UNSUPPORTED_METHOD);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
peer_b = b->peer->ptr;
if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
- BIO_R_UNSUPPORTED_METHOD);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
b->request = 0;
if (b->closed) {
/* BIO is already closed. */
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done, BIO_R_BROKEN_PIPE);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_BROKEN_PIPE);
return 0;
}
if (!b->zero_copy_write_lock) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
- BIO_R_INVALID_ARGUMENT);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
return 0;
}
rest = bio_zero_copy_get_write_buf(b, &dummy_write_buf, &dummy_write_offset);
if (bytes_written > rest) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
- BIO_R_INVALID_ARGUMENT);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
return 0;
}
@@ -525,7 +511,7 @@ static int bio_write(BIO *bio, const char *buf, int num_) {
b->request = 0;
if (b->closed) {
/* we already closed */
- OPENSSL_PUT_ERROR(BIO, bio_write, BIO_R_BROKEN_PIPE);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_BROKEN_PIPE);
return -1;
}
@@ -590,7 +576,7 @@ static int bio_make_pair(BIO* bio1, BIO* bio2,
b2 = bio2->ptr;
if (b1->peer != NULL || b2->peer != NULL) {
- OPENSSL_PUT_ERROR(BIO, bio_make_pair, BIO_R_IN_USE);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_IN_USE);
return 0;
}
@@ -605,7 +591,7 @@ static int bio_make_pair(BIO* bio1, BIO* bio2,
b1->buf_externally_allocated = 0;
b1->buf = OPENSSL_malloc(b1->size);
if (b1->buf == NULL) {
- OPENSSL_PUT_ERROR(BIO, bio_make_pair, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
return 0;
}
} else {
@@ -624,7 +610,7 @@ static int bio_make_pair(BIO* bio1, BIO* bio2,
b2->buf_externally_allocated = 0;
b2->buf = OPENSSL_malloc(b2->size);
if (b2->buf == NULL) {
- OPENSSL_PUT_ERROR(BIO, bio_make_pair, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
return 0;
}
} else {
diff --git a/src/crypto/bio/printf.c b/src/crypto/bio/printf.c
index f51b396..3709fcb 100644
--- a/src/crypto/bio/printf.c
+++ b/src/crypto/bio/printf.c
@@ -87,7 +87,11 @@ int BIO_printf(BIO *bio, const char *format, ...) {
}
#endif
- if (out_len >= sizeof(buf)) {
+ if (out_len < 0) {
+ return -1;
+ }
+
+ if ((size_t) out_len >= sizeof(buf)) {
const int requested_len = out_len;
/* The output was truncated. Note that vsnprintf's return value
* does not include a trailing NUL, but the buffer must be sized
@@ -95,7 +99,7 @@ int BIO_printf(BIO *bio, const char *format, ...) {
out = OPENSSL_malloc(requested_len + 1);
out_malloced = 1;
if (out == NULL) {
- OPENSSL_PUT_ERROR(BIO, BIO_printf, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
return -1;
}
va_start(args, format);
diff --git a/src/crypto/bio/socket_helper.c b/src/crypto/bio/socket_helper.c
index b1cdd1a..4ddc094 100644
--- a/src/crypto/bio/socket_helper.c
+++ b/src/crypto/bio/socket_helper.c
@@ -12,7 +12,8 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
-#define _POSIX_SOURCE
+#undef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 200112L
#include <openssl/bio.h>
#include <openssl/err.h>
@@ -50,7 +51,7 @@ int bio_ip_and_port_to_socket_and_addr(int *out_sock,
ret = getaddrinfo(hostname, port_str, &hint, &result);
if (ret != 0) {
- OPENSSL_PUT_ERROR(SYS, getaddrinfo, 0);
+ OPENSSL_PUT_ERROR(SYS, 0);
ERR_add_error_data(1, gai_strerror(ret));
return 0;
}
@@ -58,7 +59,7 @@ int bio_ip_and_port_to_socket_and_addr(int *out_sock,
ret = 0;
for (cur = result; cur; cur = cur->ai_next) {
- if (cur->ai_addrlen > sizeof(struct sockaddr_storage)) {
+ if ((size_t) cur->ai_addrlen > sizeof(struct sockaddr_storage)) {
continue;
}
memset(out_addr, 0, sizeof(struct sockaddr_storage));
@@ -67,7 +68,7 @@ int bio_ip_and_port_to_socket_and_addr(int *out_sock,
*out_sock = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol);
if (*out_sock < 0) {
- OPENSSL_PUT_SYSTEM_ERROR(socket);
+ OPENSSL_PUT_SYSTEM_ERROR();
goto out;
}
diff --git a/src/crypto/bn/CMakeLists.txt b/src/crypto/bn/CMakeLists.txt
index 2e0cb45..b9875d6 100644
--- a/src/crypto/bn/CMakeLists.txt
+++ b/src/crypto/bn/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
if (${ARCH} STREQUAL "x86_64")
set(
@@ -31,6 +31,14 @@ if (${ARCH} STREQUAL "arm")
)
endif()
+if (${ARCH} STREQUAL "aarch64")
+ set(
+ BN_ARCH_SOURCES
+
+ armv8-mont.${ASM_EXT}
+ )
+endif()
+
add_library(
bn
@@ -39,6 +47,7 @@ add_library(
add.c
asm/x86_64-gcc.c
bn.c
+ bn_asn1.c
cmp.c
convert.c
ctx.c
@@ -65,6 +74,7 @@ perlasm(bn-586.${ASM_EXT} asm/bn-586.pl)
perlasm(co-586.${ASM_EXT} asm/co-586.pl)
perlasm(x86-mont.${ASM_EXT} asm/x86-mont.pl)
perlasm(armv4-mont.${ASM_EXT} asm/armv4-mont.pl)
+perlasm(armv8-mont.${ASM_EXT} asm/armv8-mont.pl)
add_executable(
bn_test
@@ -75,3 +85,4 @@ add_executable(
)
target_link_libraries(bn_test crypto)
+add_dependencies(all_tests bn_test)
diff --git a/src/crypto/bn/add.c b/src/crypto/bn/add.c
index 1c6b2d7..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>
@@ -267,7 +269,7 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
if (dif < 0) /* hmm... should not be happening */
{
- OPENSSL_PUT_ERROR(BN, BN_usub, BN_R_ARG2_LT_ARG3);
+ OPENSSL_PUT_ERROR(BN, BN_R_ARG2_LT_ARG3);
return 0;
}
@@ -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/armv4-mont.pl b/src/crypto/bn/asm/armv4-mont.pl
index 0f1b6a9..4206fd8 100644
--- a/src/crypto/bn/asm/armv4-mont.pl
+++ b/src/crypto/bn/asm/armv4-mont.pl
@@ -79,7 +79,7 @@ $_n0="$num,#14*4";
$_num="$num,#15*4"; $_bpend=$_num;
$code=<<___;
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
.text
.code 32
diff --git a/src/crypto/bn/asm/armv8-mont.pl b/src/crypto/bn/asm/armv8-mont.pl
new file mode 100644
index 0000000..f04aab1
--- /dev/null
+++ b/src/crypto/bn/asm/armv8-mont.pl
@@ -0,0 +1,1503 @@
+#!/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/.
+# ====================================================================
+
+# March 2015
+#
+# "Teaser" Montgomery multiplication module for ARMv8. Needs more
+# work. While it does improve RSA sign performance by 20-30% (less for
+# longer keys) on most processors, for some reason RSA2048 is not
+# faster and RSA4096 goes 15-20% slower on Cortex-A57. Multiplication
+# instruction issue rate is limited on processor in question, meaning
+# that dedicated squaring procedure is a must. Well, actually all
+# contemporary AArch64 processors seem to have limited multiplication
+# issue rate, i.e. they can't issue multiplication every cycle, which
+# explains moderate improvement coefficients in comparison to
+# compiler-generated code. Recall that compiler is instructed to use
+# umulh and therefore uses same amount of multiplication instructions
+# to do the job. Assembly's edge is to minimize number of "collateral"
+# instructions and of course instruction scheduling.
+#
+# April 2015
+#
+# Squaring procedure that handles lengths divisible by 8 improves
+# RSA/DSA performance by 25-40-60% depending on processor and key
+# length. Overall improvement coefficients are always positive in
+# comparison to compiler-generated code. On Cortex-A57 improvement
+# is still modest on longest key lengths, while others exhibit e.g.
+# 50-70% improvement for RSA4096 sign. RSA2048 sign is ~25% faster
+# on Cortex-A57 and ~60-100% faster on others.
+
+$flavour = shift;
+$output = shift;
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
+die "can't locate arm-xlate.pl";
+
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
+
+($lo0,$hi0,$aj,$m0,$alo,$ahi,
+ $lo1,$hi1,$nj,$m1,$nlo,$nhi,
+ $ovf, $i,$j,$tp,$tj) = map("x$_",6..17,19..24);
+
+# int bn_mul_mont(
+$rp="x0"; # BN_ULONG *rp,
+$ap="x1"; # const BN_ULONG *ap,
+$bp="x2"; # const BN_ULONG *bp,
+$np="x3"; # const BN_ULONG *np,
+$n0="x4"; # const BN_ULONG *n0,
+$num="x5"; # int num);
+
+$code.=<<___;
+.text
+
+.globl bn_mul_mont
+.type bn_mul_mont,%function
+.align 5
+bn_mul_mont:
+ tst $num,#7
+ b.eq __bn_sqr8x_mont
+ tst $num,#3
+ b.eq __bn_mul4x_mont
+.Lmul_mont:
+ stp x29,x30,[sp,#-64]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+
+ ldr $m0,[$bp],#8 // bp[0]
+ sub $tp,sp,$num,lsl#3
+ ldp $hi0,$aj,[$ap],#16 // ap[0..1]
+ lsl $num,$num,#3
+ ldr $n0,[$n0] // *n0
+ and $tp,$tp,#-16 // ABI says so
+ ldp $hi1,$nj,[$np],#16 // np[0..1]
+
+ mul $lo0,$hi0,$m0 // ap[0]*bp[0]
+ sub $j,$num,#16 // j=num-2
+ umulh $hi0,$hi0,$m0
+ mul $alo,$aj,$m0 // ap[1]*bp[0]
+ umulh $ahi,$aj,$m0
+
+ mul $m1,$lo0,$n0 // "tp[0]"*n0
+ mov sp,$tp // alloca
+
+ // (*) mul $lo1,$hi1,$m1 // np[0]*m1
+ umulh $hi1,$hi1,$m1
+ mul $nlo,$nj,$m1 // np[1]*m1
+ // (*) adds $lo1,$lo1,$lo0 // discarded
+ // (*) As for removal of first multiplication and addition
+ // instructions. The outcome of first addition is
+ // guaranteed to be zero, which leaves two computationally
+ // significant outcomes: it either carries or not. Then
+ // question is when does it carry? Is there alternative
+ // way to deduce it? If you follow operations, you can
+ // observe that condition for carry is quite simple:
+ // $lo0 being non-zero. So that carry can be calculated
+ // by adding -1 to $lo0. That's what next instruction does.
+ subs xzr,$lo0,#1 // (*)
+ umulh $nhi,$nj,$m1
+ adc $hi1,$hi1,xzr
+ cbz $j,.L1st_skip
+
+.L1st:
+ ldr $aj,[$ap],#8
+ adds $lo0,$alo,$hi0
+ sub $j,$j,#8 // j--
+ adc $hi0,$ahi,xzr
+
+ ldr $nj,[$np],#8
+ adds $lo1,$nlo,$hi1
+ mul $alo,$aj,$m0 // ap[j]*bp[0]
+ adc $hi1,$nhi,xzr
+ umulh $ahi,$aj,$m0
+
+ adds $lo1,$lo1,$lo0
+ mul $nlo,$nj,$m1 // np[j]*m1
+ adc $hi1,$hi1,xzr
+ umulh $nhi,$nj,$m1
+ str $lo1,[$tp],#8 // tp[j-1]
+ cbnz $j,.L1st
+
+.L1st_skip:
+ adds $lo0,$alo,$hi0
+ sub $ap,$ap,$num // rewind $ap
+ adc $hi0,$ahi,xzr
+
+ adds $lo1,$nlo,$hi1
+ sub $np,$np,$num // rewind $np
+ adc $hi1,$nhi,xzr
+
+ adds $lo1,$lo1,$lo0
+ sub $i,$num,#8 // i=num-1
+ adcs $hi1,$hi1,$hi0
+
+ adc $ovf,xzr,xzr // upmost overflow bit
+ stp $lo1,$hi1,[$tp]
+
+.Louter:
+ ldr $m0,[$bp],#8 // bp[i]
+ ldp $hi0,$aj,[$ap],#16
+ ldr $tj,[sp] // tp[0]
+ add $tp,sp,#8
+
+ mul $lo0,$hi0,$m0 // ap[0]*bp[i]
+ sub $j,$num,#16 // j=num-2
+ umulh $hi0,$hi0,$m0
+ ldp $hi1,$nj,[$np],#16
+ mul $alo,$aj,$m0 // ap[1]*bp[i]
+ adds $lo0,$lo0,$tj
+ umulh $ahi,$aj,$m0
+ adc $hi0,$hi0,xzr
+
+ mul $m1,$lo0,$n0
+ sub $i,$i,#8 // i--
+
+ // (*) mul $lo1,$hi1,$m1 // np[0]*m1
+ umulh $hi1,$hi1,$m1
+ mul $nlo,$nj,$m1 // np[1]*m1
+ // (*) adds $lo1,$lo1,$lo0
+ subs xzr,$lo0,#1 // (*)
+ umulh $nhi,$nj,$m1
+ cbz $j,.Linner_skip
+
+.Linner:
+ ldr $aj,[$ap],#8
+ adc $hi1,$hi1,xzr
+ ldr $tj,[$tp],#8 // tp[j]
+ adds $lo0,$alo,$hi0
+ sub $j,$j,#8 // j--
+ adc $hi0,$ahi,xzr
+
+ adds $lo1,$nlo,$hi1
+ ldr $nj,[$np],#8
+ adc $hi1,$nhi,xzr
+
+ mul $alo,$aj,$m0 // ap[j]*bp[i]
+ adds $lo0,$lo0,$tj
+ umulh $ahi,$aj,$m0
+ adc $hi0,$hi0,xzr
+
+ mul $nlo,$nj,$m1 // np[j]*m1
+ adds $lo1,$lo1,$lo0
+ umulh $nhi,$nj,$m1
+ str $lo1,[$tp,#-16] // tp[j-1]
+ cbnz $j,.Linner
+
+.Linner_skip:
+ ldr $tj,[$tp],#8 // tp[j]
+ adc $hi1,$hi1,xzr
+ adds $lo0,$alo,$hi0
+ sub $ap,$ap,$num // rewind $ap
+ adc $hi0,$ahi,xzr
+
+ adds $lo1,$nlo,$hi1
+ sub $np,$np,$num // rewind $np
+ adcs $hi1,$nhi,$ovf
+ adc $ovf,xzr,xzr
+
+ adds $lo0,$lo0,$tj
+ adc $hi0,$hi0,xzr
+
+ adds $lo1,$lo1,$lo0
+ adcs $hi1,$hi1,$hi0
+ adc $ovf,$ovf,xzr // upmost overflow bit
+ stp $lo1,$hi1,[$tp,#-16]
+
+ cbnz $i,.Louter
+
+ // Final step. We see if result is larger than modulus, and
+ // if it is, subtract the modulus. But comparison implies
+ // subtraction. So we subtract modulus, see if it borrowed,
+ // and conditionally copy original value.
+ ldr $tj,[sp] // tp[0]
+ add $tp,sp,#8
+ ldr $nj,[$np],#8 // np[0]
+ subs $j,$num,#8 // j=num-1 and clear borrow
+ mov $ap,$rp
+.Lsub:
+ sbcs $aj,$tj,$nj // tp[j]-np[j]
+ ldr $tj,[$tp],#8
+ sub $j,$j,#8 // j--
+ ldr $nj,[$np],#8
+ str $aj,[$ap],#8 // rp[j]=tp[j]-np[j]
+ cbnz $j,.Lsub
+
+ sbcs $aj,$tj,$nj
+ sbcs $ovf,$ovf,xzr // did it borrow?
+ str $aj,[$ap],#8 // rp[num-1]
+
+ ldr $tj,[sp] // tp[0]
+ add $tp,sp,#8
+ ldr $aj,[$rp],#8 // rp[0]
+ sub $num,$num,#8 // num--
+ nop
+.Lcond_copy:
+ sub $num,$num,#8 // num--
+ csel $nj,$tj,$aj,lo // did it borrow?
+ ldr $tj,[$tp],#8
+ ldr $aj,[$rp],#8
+ str xzr,[$tp,#-16] // wipe tp
+ str $nj,[$rp,#-16]
+ cbnz $num,.Lcond_copy
+
+ csel $nj,$tj,$aj,lo
+ str xzr,[$tp,#-8] // wipe tp
+ str $nj,[$rp,#-8]
+
+ ldp x19,x20,[x29,#16]
+ mov sp,x29
+ ldp x21,x22,[x29,#32]
+ mov x0,#1
+ ldp x23,x24,[x29,#48]
+ ldr x29,[sp],#64
+ ret
+.size bn_mul_mont,.-bn_mul_mont
+___
+{
+########################################################################
+# Following is ARMv8 adaptation of sqrx8x_mont from x86_64-mont5 module.
+
+my ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("x$_",(6..13));
+my ($t0,$t1,$t2,$t3)=map("x$_",(14..17));
+my ($acc0,$acc1,$acc2,$acc3,$acc4,$acc5,$acc6,$acc7)=map("x$_",(19..26));
+my ($cnt,$carry,$topmost)=("x27","x28","x30");
+my ($tp,$ap_end,$na0)=($bp,$np,$carry);
+
+$code.=<<___;
+.type __bn_sqr8x_mont,%function
+.align 5
+__bn_sqr8x_mont:
+ cmp $ap,$bp
+ b.ne __bn_mul4x_mont
+.Lsqr8x_mont:
+ stp x29,x30,[sp,#-128]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+ stp x25,x26,[sp,#64]
+ stp x27,x28,[sp,#80]
+ stp $rp,$np,[sp,#96] // offload rp and np
+
+ ldp $a0,$a1,[$ap,#8*0]
+ ldp $a2,$a3,[$ap,#8*2]
+ ldp $a4,$a5,[$ap,#8*4]
+ ldp $a6,$a7,[$ap,#8*6]
+
+ sub $tp,sp,$num,lsl#4
+ lsl $num,$num,#3
+ ldr $n0,[$n0] // *n0
+ mov sp,$tp // alloca
+ sub $cnt,$num,#8*8
+ b .Lsqr8x_zero_start
+
+.Lsqr8x_zero:
+ sub $cnt,$cnt,#8*8
+ stp xzr,xzr,[$tp,#8*0]
+ stp xzr,xzr,[$tp,#8*2]
+ stp xzr,xzr,[$tp,#8*4]
+ stp xzr,xzr,[$tp,#8*6]
+.Lsqr8x_zero_start:
+ stp xzr,xzr,[$tp,#8*8]
+ stp xzr,xzr,[$tp,#8*10]
+ stp xzr,xzr,[$tp,#8*12]
+ stp xzr,xzr,[$tp,#8*14]
+ add $tp,$tp,#8*16
+ cbnz $cnt,.Lsqr8x_zero
+
+ add $ap_end,$ap,$num
+ add $ap,$ap,#8*8
+ mov $acc0,xzr
+ mov $acc1,xzr
+ mov $acc2,xzr
+ mov $acc3,xzr
+ mov $acc4,xzr
+ mov $acc5,xzr
+ mov $acc6,xzr
+ mov $acc7,xzr
+ mov $tp,sp
+ str $n0,[x29,#112] // offload n0
+
+ // Multiply everything but a[i]*a[i]
+.align 4
+.Lsqr8x_outer_loop:
+ // a[1]a[0] (i)
+ // a[2]a[0]
+ // a[3]a[0]
+ // a[4]a[0]
+ // a[5]a[0]
+ // a[6]a[0]
+ // a[7]a[0]
+ // a[2]a[1] (ii)
+ // a[3]a[1]
+ // a[4]a[1]
+ // a[5]a[1]
+ // a[6]a[1]
+ // a[7]a[1]
+ // a[3]a[2] (iii)
+ // a[4]a[2]
+ // a[5]a[2]
+ // a[6]a[2]
+ // a[7]a[2]
+ // a[4]a[3] (iv)
+ // a[5]a[3]
+ // a[6]a[3]
+ // a[7]a[3]
+ // a[5]a[4] (v)
+ // a[6]a[4]
+ // a[7]a[4]
+ // a[6]a[5] (vi)
+ // a[7]a[5]
+ // a[7]a[6] (vii)
+
+ mul $t0,$a1,$a0 // lo(a[1..7]*a[0]) (i)
+ mul $t1,$a2,$a0
+ mul $t2,$a3,$a0
+ mul $t3,$a4,$a0
+ adds $acc1,$acc1,$t0 // t[1]+lo(a[1]*a[0])
+ mul $t0,$a5,$a0
+ adcs $acc2,$acc2,$t1
+ mul $t1,$a6,$a0
+ adcs $acc3,$acc3,$t2
+ mul $t2,$a7,$a0
+ adcs $acc4,$acc4,$t3
+ umulh $t3,$a1,$a0 // hi(a[1..7]*a[0])
+ adcs $acc5,$acc5,$t0
+ umulh $t0,$a2,$a0
+ adcs $acc6,$acc6,$t1
+ umulh $t1,$a3,$a0
+ adcs $acc7,$acc7,$t2
+ umulh $t2,$a4,$a0
+ stp $acc0,$acc1,[$tp],#8*2 // t[0..1]
+ adc $acc0,xzr,xzr // t[8]
+ adds $acc2,$acc2,$t3 // t[2]+lo(a[1]*a[0])
+ umulh $t3,$a5,$a0
+ adcs $acc3,$acc3,$t0
+ umulh $t0,$a6,$a0
+ adcs $acc4,$acc4,$t1
+ umulh $t1,$a7,$a0
+ adcs $acc5,$acc5,$t2
+ mul $t2,$a2,$a1 // lo(a[2..7]*a[1]) (ii)
+ adcs $acc6,$acc6,$t3
+ mul $t3,$a3,$a1
+ adcs $acc7,$acc7,$t0
+ mul $t0,$a4,$a1
+ adc $acc0,$acc0,$t1
+
+ mul $t1,$a5,$a1
+ adds $acc3,$acc3,$t2
+ mul $t2,$a6,$a1
+ adcs $acc4,$acc4,$t3
+ mul $t3,$a7,$a1
+ adcs $acc5,$acc5,$t0
+ umulh $t0,$a2,$a1 // hi(a[2..7]*a[1])
+ adcs $acc6,$acc6,$t1
+ umulh $t1,$a3,$a1
+ adcs $acc7,$acc7,$t2
+ umulh $t2,$a4,$a1
+ adcs $acc0,$acc0,$t3
+ umulh $t3,$a5,$a1
+ stp $acc2,$acc3,[$tp],#8*2 // t[2..3]
+ adc $acc1,xzr,xzr // t[9]
+ adds $acc4,$acc4,$t0
+ umulh $t0,$a6,$a1
+ adcs $acc5,$acc5,$t1
+ umulh $t1,$a7,$a1
+ adcs $acc6,$acc6,$t2
+ mul $t2,$a3,$a2 // lo(a[3..7]*a[2]) (iii)
+ adcs $acc7,$acc7,$t3
+ mul $t3,$a4,$a2
+ adcs $acc0,$acc0,$t0
+ mul $t0,$a5,$a2
+ adc $acc1,$acc1,$t1
+
+ mul $t1,$a6,$a2
+ adds $acc5,$acc5,$t2
+ mul $t2,$a7,$a2
+ adcs $acc6,$acc6,$t3
+ umulh $t3,$a3,$a2 // hi(a[3..7]*a[2])
+ adcs $acc7,$acc7,$t0
+ umulh $t0,$a4,$a2
+ adcs $acc0,$acc0,$t1
+ umulh $t1,$a5,$a2
+ adcs $acc1,$acc1,$t2
+ umulh $t2,$a6,$a2
+ stp $acc4,$acc5,[$tp],#8*2 // t[4..5]
+ adc $acc2,xzr,xzr // t[10]
+ adds $acc6,$acc6,$t3
+ umulh $t3,$a7,$a2
+ adcs $acc7,$acc7,$t0
+ mul $t0,$a4,$a3 // lo(a[4..7]*a[3]) (iv)
+ adcs $acc0,$acc0,$t1
+ mul $t1,$a5,$a3
+ adcs $acc1,$acc1,$t2
+ mul $t2,$a6,$a3
+ adc $acc2,$acc2,$t3
+
+ mul $t3,$a7,$a3
+ adds $acc7,$acc7,$t0
+ umulh $t0,$a4,$a3 // hi(a[4..7]*a[3])
+ adcs $acc0,$acc0,$t1
+ umulh $t1,$a5,$a3
+ adcs $acc1,$acc1,$t2
+ umulh $t2,$a6,$a3
+ adcs $acc2,$acc2,$t3
+ umulh $t3,$a7,$a3
+ stp $acc6,$acc7,[$tp],#8*2 // t[6..7]
+ adc $acc3,xzr,xzr // t[11]
+ adds $acc0,$acc0,$t0
+ mul $t0,$a5,$a4 // lo(a[5..7]*a[4]) (v)
+ adcs $acc1,$acc1,$t1
+ mul $t1,$a6,$a4
+ adcs $acc2,$acc2,$t2
+ mul $t2,$a7,$a4
+ adc $acc3,$acc3,$t3
+
+ umulh $t3,$a5,$a4 // hi(a[5..7]*a[4])
+ adds $acc1,$acc1,$t0
+ umulh $t0,$a6,$a4
+ adcs $acc2,$acc2,$t1
+ umulh $t1,$a7,$a4
+ adcs $acc3,$acc3,$t2
+ mul $t2,$a6,$a5 // lo(a[6..7]*a[5]) (vi)
+ adc $acc4,xzr,xzr // t[12]
+ adds $acc2,$acc2,$t3
+ mul $t3,$a7,$a5
+ adcs $acc3,$acc3,$t0
+ umulh $t0,$a6,$a5 // hi(a[6..7]*a[5])
+ adc $acc4,$acc4,$t1
+
+ umulh $t1,$a7,$a5
+ adds $acc3,$acc3,$t2
+ mul $t2,$a7,$a6 // lo(a[7]*a[6]) (vii)
+ adcs $acc4,$acc4,$t3
+ umulh $t3,$a7,$a6 // hi(a[7]*a[6])
+ adc $acc5,xzr,xzr // t[13]
+ adds $acc4,$acc4,$t0
+ sub $cnt,$ap_end,$ap // done yet?
+ adc $acc5,$acc5,$t1
+
+ adds $acc5,$acc5,$t2
+ sub $t0,$ap_end,$num // rewinded ap
+ adc $acc6,xzr,xzr // t[14]
+ add $acc6,$acc6,$t3
+
+ cbz $cnt,.Lsqr8x_outer_break
+
+ mov $n0,$a0
+ ldp $a0,$a1,[$tp,#8*0]
+ ldp $a2,$a3,[$tp,#8*2]
+ ldp $a4,$a5,[$tp,#8*4]
+ ldp $a6,$a7,[$tp,#8*6]
+ adds $acc0,$acc0,$a0
+ adcs $acc1,$acc1,$a1
+ ldp $a0,$a1,[$ap,#8*0]
+ adcs $acc2,$acc2,$a2
+ adcs $acc3,$acc3,$a3
+ ldp $a2,$a3,[$ap,#8*2]
+ adcs $acc4,$acc4,$a4
+ adcs $acc5,$acc5,$a5
+ ldp $a4,$a5,[$ap,#8*4]
+ adcs $acc6,$acc6,$a6
+ mov $rp,$ap
+ adcs $acc7,xzr,$a7
+ ldp $a6,$a7,[$ap,#8*6]
+ add $ap,$ap,#8*8
+ //adc $carry,xzr,xzr // moved below
+ mov $cnt,#-8*8
+
+ // a[8]a[0]
+ // a[9]a[0]
+ // a[a]a[0]
+ // a[b]a[0]
+ // a[c]a[0]
+ // a[d]a[0]
+ // a[e]a[0]
+ // a[f]a[0]
+ // a[8]a[1]
+ // a[f]a[1]........................
+ // a[8]a[2]
+ // a[f]a[2]........................
+ // a[8]a[3]
+ // a[f]a[3]........................
+ // a[8]a[4]
+ // a[f]a[4]........................
+ // a[8]a[5]
+ // a[f]a[5]........................
+ // a[8]a[6]
+ // a[f]a[6]........................
+ // a[8]a[7]
+ // a[f]a[7]........................
+.Lsqr8x_mul:
+ mul $t0,$a0,$n0
+ adc $carry,xzr,xzr // carry bit, modulo-scheduled
+ mul $t1,$a1,$n0
+ add $cnt,$cnt,#8
+ mul $t2,$a2,$n0
+ mul $t3,$a3,$n0
+ adds $acc0,$acc0,$t0
+ mul $t0,$a4,$n0
+ adcs $acc1,$acc1,$t1
+ mul $t1,$a5,$n0
+ adcs $acc2,$acc2,$t2
+ mul $t2,$a6,$n0
+ adcs $acc3,$acc3,$t3
+ mul $t3,$a7,$n0
+ adcs $acc4,$acc4,$t0
+ umulh $t0,$a0,$n0
+ adcs $acc5,$acc5,$t1
+ umulh $t1,$a1,$n0
+ adcs $acc6,$acc6,$t2
+ umulh $t2,$a2,$n0
+ adcs $acc7,$acc7,$t3
+ umulh $t3,$a3,$n0
+ adc $carry,$carry,xzr
+ str $acc0,[$tp],#8
+ adds $acc0,$acc1,$t0
+ umulh $t0,$a4,$n0
+ adcs $acc1,$acc2,$t1
+ umulh $t1,$a5,$n0
+ adcs $acc2,$acc3,$t2
+ umulh $t2,$a6,$n0
+ adcs $acc3,$acc4,$t3
+ umulh $t3,$a7,$n0
+ ldr $n0,[$rp,$cnt]
+ adcs $acc4,$acc5,$t0
+ adcs $acc5,$acc6,$t1
+ adcs $acc6,$acc7,$t2
+ adcs $acc7,$carry,$t3
+ //adc $carry,xzr,xzr // moved above
+ cbnz $cnt,.Lsqr8x_mul
+ // note that carry flag is guaranteed
+ // to be zero at this point
+ cmp $ap,$ap_end // done yet?
+ b.eq .Lsqr8x_break
+
+ ldp $a0,$a1,[$tp,#8*0]
+ ldp $a2,$a3,[$tp,#8*2]
+ ldp $a4,$a5,[$tp,#8*4]
+ ldp $a6,$a7,[$tp,#8*6]
+ adds $acc0,$acc0,$a0
+ ldr $n0,[$rp,#-8*8]
+ adcs $acc1,$acc1,$a1
+ ldp $a0,$a1,[$ap,#8*0]
+ adcs $acc2,$acc2,$a2
+ adcs $acc3,$acc3,$a3
+ ldp $a2,$a3,[$ap,#8*2]
+ adcs $acc4,$acc4,$a4
+ adcs $acc5,$acc5,$a5
+ ldp $a4,$a5,[$ap,#8*4]
+ adcs $acc6,$acc6,$a6
+ mov $cnt,#-8*8
+ adcs $acc7,$acc7,$a7
+ ldp $a6,$a7,[$ap,#8*6]
+ add $ap,$ap,#8*8
+ //adc $carry,xzr,xzr // moved above
+ b .Lsqr8x_mul
+
+.align 4
+.Lsqr8x_break:
+ ldp $a0,$a1,[$rp,#8*0]
+ add $ap,$rp,#8*8
+ ldp $a2,$a3,[$rp,#8*2]
+ sub $t0,$ap_end,$ap // is it last iteration?
+ ldp $a4,$a5,[$rp,#8*4]
+ sub $t1,$tp,$t0
+ ldp $a6,$a7,[$rp,#8*6]
+ cbz $t0,.Lsqr8x_outer_loop
+
+ stp $acc0,$acc1,[$tp,#8*0]
+ ldp $acc0,$acc1,[$t1,#8*0]
+ stp $acc2,$acc3,[$tp,#8*2]
+ ldp $acc2,$acc3,[$t1,#8*2]
+ stp $acc4,$acc5,[$tp,#8*4]
+ ldp $acc4,$acc5,[$t1,#8*4]
+ stp $acc6,$acc7,[$tp,#8*6]
+ mov $tp,$t1
+ ldp $acc6,$acc7,[$t1,#8*6]
+ b .Lsqr8x_outer_loop
+
+.align 4
+.Lsqr8x_outer_break:
+ // Now multiply above result by 2 and add a[n-1]*a[n-1]|...|a[0]*a[0]
+ ldp $a1,$a3,[$t0,#8*0] // recall that $t0 is &a[0]
+ ldp $t1,$t2,[sp,#8*1]
+ ldp $a5,$a7,[$t0,#8*2]
+ add $ap,$t0,#8*4
+ ldp $t3,$t0,[sp,#8*3]
+
+ stp $acc0,$acc1,[$tp,#8*0]
+ mul $acc0,$a1,$a1
+ stp $acc2,$acc3,[$tp,#8*2]
+ umulh $a1,$a1,$a1
+ stp $acc4,$acc5,[$tp,#8*4]
+ mul $a2,$a3,$a3
+ stp $acc6,$acc7,[$tp,#8*6]
+ mov $tp,sp
+ umulh $a3,$a3,$a3
+ adds $acc1,$a1,$t1,lsl#1
+ extr $t1,$t2,$t1,#63
+ sub $cnt,$num,#8*4
+
+.Lsqr4x_shift_n_add:
+ adcs $acc2,$a2,$t1
+ extr $t2,$t3,$t2,#63
+ sub $cnt,$cnt,#8*4
+ adcs $acc3,$a3,$t2
+ ldp $t1,$t2,[$tp,#8*5]
+ mul $a4,$a5,$a5
+ ldp $a1,$a3,[$ap],#8*2
+ umulh $a5,$a5,$a5
+ mul $a6,$a7,$a7
+ umulh $a7,$a7,$a7
+ extr $t3,$t0,$t3,#63
+ stp $acc0,$acc1,[$tp,#8*0]
+ adcs $acc4,$a4,$t3
+ extr $t0,$t1,$t0,#63
+ stp $acc2,$acc3,[$tp,#8*2]
+ adcs $acc5,$a5,$t0
+ ldp $t3,$t0,[$tp,#8*7]
+ extr $t1,$t2,$t1,#63
+ adcs $acc6,$a6,$t1
+ extr $t2,$t3,$t2,#63
+ adcs $acc7,$a7,$t2
+ ldp $t1,$t2,[$tp,#8*9]
+ mul $a0,$a1,$a1
+ ldp $a5,$a7,[$ap],#8*2
+ umulh $a1,$a1,$a1
+ mul $a2,$a3,$a3
+ umulh $a3,$a3,$a3
+ stp $acc4,$acc5,[$tp,#8*4]
+ extr $t3,$t0,$t3,#63
+ stp $acc6,$acc7,[$tp,#8*6]
+ add $tp,$tp,#8*8
+ adcs $acc0,$a0,$t3
+ extr $t0,$t1,$t0,#63
+ adcs $acc1,$a1,$t0
+ ldp $t3,$t0,[$tp,#8*3]
+ extr $t1,$t2,$t1,#63
+ cbnz $cnt,.Lsqr4x_shift_n_add
+___
+my ($np,$np_end)=($ap,$ap_end);
+$code.=<<___;
+ ldp $np,$n0,[x29,#104] // pull np and n0
+
+ adcs $acc2,$a2,$t1
+ extr $t2,$t3,$t2,#63
+ adcs $acc3,$a3,$t2
+ ldp $t1,$t2,[$tp,#8*5]
+ mul $a4,$a5,$a5
+ umulh $a5,$a5,$a5
+ stp $acc0,$acc1,[$tp,#8*0]
+ mul $a6,$a7,$a7
+ umulh $a7,$a7,$a7
+ stp $acc2,$acc3,[$tp,#8*2]
+ extr $t3,$t0,$t3,#63
+ adcs $acc4,$a4,$t3
+ extr $t0,$t1,$t0,#63
+ ldp $acc0,$acc1,[sp,#8*0]
+ adcs $acc5,$a5,$t0
+ extr $t1,$t2,$t1,#63
+ ldp $a0,$a1,[$np,#8*0]
+ adcs $acc6,$a6,$t1
+ extr $t2,xzr,$t2,#63
+ ldp $a2,$a3,[$np,#8*2]
+ adc $acc7,$a7,$t2
+ ldp $a4,$a5,[$np,#8*4]
+
+ // Reduce by 512 bits per iteration
+ mul $na0,$n0,$acc0 // t[0]*n0
+ ldp $a6,$a7,[$np,#8*6]
+ add $np_end,$np,$num
+ ldp $acc2,$acc3,[sp,#8*2]
+ stp $acc4,$acc5,[$tp,#8*4]
+ ldp $acc4,$acc5,[sp,#8*4]
+ stp $acc6,$acc7,[$tp,#8*6]
+ ldp $acc6,$acc7,[sp,#8*6]
+ add $np,$np,#8*8
+ mov $topmost,xzr // initial top-most carry
+ mov $tp,sp
+ mov $cnt,#8
+
+.Lsqr8x_reduction:
+ // (*) mul $t0,$a0,$na0 // lo(n[0-7])*lo(t[0]*n0)
+ mul $t1,$a1,$na0
+ sub $cnt,$cnt,#1
+ mul $t2,$a2,$na0
+ str $na0,[$tp],#8 // put aside t[0]*n0 for tail processing
+ mul $t3,$a3,$na0
+ // (*) adds xzr,$acc0,$t0
+ subs xzr,$acc0,#1 // (*)
+ mul $t0,$a4,$na0
+ adcs $acc0,$acc1,$t1
+ mul $t1,$a5,$na0
+ adcs $acc1,$acc2,$t2
+ mul $t2,$a6,$na0
+ adcs $acc2,$acc3,$t3
+ mul $t3,$a7,$na0
+ adcs $acc3,$acc4,$t0
+ umulh $t0,$a0,$na0 // hi(n[0-7])*lo(t[0]*n0)
+ adcs $acc4,$acc5,$t1
+ umulh $t1,$a1,$na0
+ adcs $acc5,$acc6,$t2
+ umulh $t2,$a2,$na0
+ adcs $acc6,$acc7,$t3
+ umulh $t3,$a3,$na0
+ adc $acc7,xzr,xzr
+ adds $acc0,$acc0,$t0
+ umulh $t0,$a4,$na0
+ adcs $acc1,$acc1,$t1
+ umulh $t1,$a5,$na0
+ adcs $acc2,$acc2,$t2
+ umulh $t2,$a6,$na0
+ adcs $acc3,$acc3,$t3
+ umulh $t3,$a7,$na0
+ mul $na0,$n0,$acc0 // next t[0]*n0
+ adcs $acc4,$acc4,$t0
+ adcs $acc5,$acc5,$t1
+ adcs $acc6,$acc6,$t2
+ adc $acc7,$acc7,$t3
+ cbnz $cnt,.Lsqr8x_reduction
+
+ ldp $t0,$t1,[$tp,#8*0]
+ ldp $t2,$t3,[$tp,#8*2]
+ mov $rp,$tp
+ sub $cnt,$np_end,$np // done yet?
+ adds $acc0,$acc0,$t0
+ adcs $acc1,$acc1,$t1
+ ldp $t0,$t1,[$tp,#8*4]
+ adcs $acc2,$acc2,$t2
+ adcs $acc3,$acc3,$t3
+ ldp $t2,$t3,[$tp,#8*6]
+ adcs $acc4,$acc4,$t0
+ adcs $acc5,$acc5,$t1
+ adcs $acc6,$acc6,$t2
+ adcs $acc7,$acc7,$t3
+ //adc $carry,xzr,xzr // moved below
+ cbz $cnt,.Lsqr8x8_post_condition
+
+ ldr $n0,[$tp,#-8*8]
+ ldp $a0,$a1,[$np,#8*0]
+ ldp $a2,$a3,[$np,#8*2]
+ ldp $a4,$a5,[$np,#8*4]
+ mov $cnt,#-8*8
+ ldp $a6,$a7,[$np,#8*6]
+ add $np,$np,#8*8
+
+.Lsqr8x_tail:
+ mul $t0,$a0,$n0
+ adc $carry,xzr,xzr // carry bit, modulo-scheduled
+ mul $t1,$a1,$n0
+ add $cnt,$cnt,#8
+ mul $t2,$a2,$n0
+ mul $t3,$a3,$n0
+ adds $acc0,$acc0,$t0
+ mul $t0,$a4,$n0
+ adcs $acc1,$acc1,$t1
+ mul $t1,$a5,$n0
+ adcs $acc2,$acc2,$t2
+ mul $t2,$a6,$n0
+ adcs $acc3,$acc3,$t3
+ mul $t3,$a7,$n0
+ adcs $acc4,$acc4,$t0
+ umulh $t0,$a0,$n0
+ adcs $acc5,$acc5,$t1
+ umulh $t1,$a1,$n0
+ adcs $acc6,$acc6,$t2
+ umulh $t2,$a2,$n0
+ adcs $acc7,$acc7,$t3
+ umulh $t3,$a3,$n0
+ adc $carry,$carry,xzr
+ str $acc0,[$tp],#8
+ adds $acc0,$acc1,$t0
+ umulh $t0,$a4,$n0
+ adcs $acc1,$acc2,$t1
+ umulh $t1,$a5,$n0
+ adcs $acc2,$acc3,$t2
+ umulh $t2,$a6,$n0
+ adcs $acc3,$acc4,$t3
+ umulh $t3,$a7,$n0
+ ldr $n0,[$rp,$cnt]
+ adcs $acc4,$acc5,$t0
+ adcs $acc5,$acc6,$t1
+ adcs $acc6,$acc7,$t2
+ adcs $acc7,$carry,$t3
+ //adc $carry,xzr,xzr // moved above
+ cbnz $cnt,.Lsqr8x_tail
+ // note that carry flag is guaranteed
+ // to be zero at this point
+ ldp $a0,$a1,[$tp,#8*0]
+ sub $cnt,$np_end,$np // done yet?
+ sub $t2,$np_end,$num // rewinded np
+ ldp $a2,$a3,[$tp,#8*2]
+ ldp $a4,$a5,[$tp,#8*4]
+ ldp $a6,$a7,[$tp,#8*6]
+ cbz $cnt,.Lsqr8x_tail_break
+
+ ldr $n0,[$rp,#-8*8]
+ adds $acc0,$acc0,$a0
+ adcs $acc1,$acc1,$a1
+ ldp $a0,$a1,[$np,#8*0]
+ adcs $acc2,$acc2,$a2
+ adcs $acc3,$acc3,$a3
+ ldp $a2,$a3,[$np,#8*2]
+ adcs $acc4,$acc4,$a4
+ adcs $acc5,$acc5,$a5
+ ldp $a4,$a5,[$np,#8*4]
+ adcs $acc6,$acc6,$a6
+ mov $cnt,#-8*8
+ adcs $acc7,$acc7,$a7
+ ldp $a6,$a7,[$np,#8*6]
+ add $np,$np,#8*8
+ //adc $carry,xzr,xzr // moved above
+ b .Lsqr8x_tail
+
+.align 4
+.Lsqr8x_tail_break:
+ ldr $n0,[x29,#112] // pull n0
+ add $cnt,$tp,#8*8 // end of current t[num] window
+
+ subs xzr,$topmost,#1 // "move" top-most carry to carry bit
+ adcs $t0,$acc0,$a0
+ adcs $t1,$acc1,$a1
+ ldp $acc0,$acc1,[$rp,#8*0]
+ adcs $acc2,$acc2,$a2
+ ldp $a0,$a1,[$t2,#8*0] // recall that $t2 is &n[0]
+ adcs $acc3,$acc3,$a3
+ ldp $a2,$a3,[$t2,#8*2]
+ adcs $acc4,$acc4,$a4
+ adcs $acc5,$acc5,$a5
+ ldp $a4,$a5,[$t2,#8*4]
+ adcs $acc6,$acc6,$a6
+ adcs $acc7,$acc7,$a7
+ ldp $a6,$a7,[$t2,#8*6]
+ add $np,$t2,#8*8
+ adc $topmost,xzr,xzr // top-most carry
+ mul $na0,$n0,$acc0
+ stp $t0,$t1,[$tp,#8*0]
+ stp $acc2,$acc3,[$tp,#8*2]
+ ldp $acc2,$acc3,[$rp,#8*2]
+ stp $acc4,$acc5,[$tp,#8*4]
+ ldp $acc4,$acc5,[$rp,#8*4]
+ cmp $cnt,x29 // did we hit the bottom?
+ stp $acc6,$acc7,[$tp,#8*6]
+ mov $tp,$rp // slide the window
+ ldp $acc6,$acc7,[$rp,#8*6]
+ mov $cnt,#8
+ b.ne .Lsqr8x_reduction
+
+ // Final step. We see if result is larger than modulus, and
+ // if it is, subtract the modulus. But comparison implies
+ // subtraction. So we subtract modulus, see if it borrowed,
+ // and conditionally copy original value.
+ ldr $rp,[x29,#96] // pull rp
+ add $tp,$tp,#8*8
+ subs $t0,$acc0,$a0
+ sbcs $t1,$acc1,$a1
+ sub $cnt,$num,#8*8
+ mov $ap_end,$rp // $rp copy
+
+.Lsqr8x_sub:
+ sbcs $t2,$acc2,$a2
+ ldp $a0,$a1,[$np,#8*0]
+ sbcs $t3,$acc3,$a3
+ stp $t0,$t1,[$rp,#8*0]
+ sbcs $t0,$acc4,$a4
+ ldp $a2,$a3,[$np,#8*2]
+ sbcs $t1,$acc5,$a5
+ stp $t2,$t3,[$rp,#8*2]
+ sbcs $t2,$acc6,$a6
+ ldp $a4,$a5,[$np,#8*4]
+ sbcs $t3,$acc7,$a7
+ ldp $a6,$a7,[$np,#8*6]
+ add $np,$np,#8*8
+ ldp $acc0,$acc1,[$tp,#8*0]
+ sub $cnt,$cnt,#8*8
+ ldp $acc2,$acc3,[$tp,#8*2]
+ ldp $acc4,$acc5,[$tp,#8*4]
+ ldp $acc6,$acc7,[$tp,#8*6]
+ add $tp,$tp,#8*8
+ stp $t0,$t1,[$rp,#8*4]
+ sbcs $t0,$acc0,$a0
+ stp $t2,$t3,[$rp,#8*6]
+ add $rp,$rp,#8*8
+ sbcs $t1,$acc1,$a1
+ cbnz $cnt,.Lsqr8x_sub
+
+ sbcs $t2,$acc2,$a2
+ mov $tp,sp
+ add $ap,sp,$num
+ ldp $a0,$a1,[$ap_end,#8*0]
+ sbcs $t3,$acc3,$a3
+ stp $t0,$t1,[$rp,#8*0]
+ sbcs $t0,$acc4,$a4
+ ldp $a2,$a3,[$ap_end,#8*2]
+ sbcs $t1,$acc5,$a5
+ stp $t2,$t3,[$rp,#8*2]
+ sbcs $t2,$acc6,$a6
+ ldp $acc0,$acc1,[$ap,#8*0]
+ sbcs $t3,$acc7,$a7
+ ldp $acc2,$acc3,[$ap,#8*2]
+ sbcs xzr,$topmost,xzr // did it borrow?
+ ldr x30,[x29,#8] // pull return address
+ stp $t0,$t1,[$rp,#8*4]
+ stp $t2,$t3,[$rp,#8*6]
+
+ sub $cnt,$num,#8*4
+.Lsqr4x_cond_copy:
+ sub $cnt,$cnt,#8*4
+ csel $t0,$acc0,$a0,lo
+ stp xzr,xzr,[$tp,#8*0]
+ csel $t1,$acc1,$a1,lo
+ ldp $a0,$a1,[$ap_end,#8*4]
+ ldp $acc0,$acc1,[$ap,#8*4]
+ csel $t2,$acc2,$a2,lo
+ stp xzr,xzr,[$tp,#8*2]
+ add $tp,$tp,#8*4
+ csel $t3,$acc3,$a3,lo
+ ldp $a2,$a3,[$ap_end,#8*6]
+ ldp $acc2,$acc3,[$ap,#8*6]
+ add $ap,$ap,#8*4
+ stp $t0,$t1,[$ap_end,#8*0]
+ stp $t2,$t3,[$ap_end,#8*2]
+ add $ap_end,$ap_end,#8*4
+ stp xzr,xzr,[$ap,#8*0]
+ stp xzr,xzr,[$ap,#8*2]
+ cbnz $cnt,.Lsqr4x_cond_copy
+
+ csel $t0,$acc0,$a0,lo
+ stp xzr,xzr,[$tp,#8*0]
+ csel $t1,$acc1,$a1,lo
+ stp xzr,xzr,[$tp,#8*2]
+ csel $t2,$acc2,$a2,lo
+ csel $t3,$acc3,$a3,lo
+ stp $t0,$t1,[$ap_end,#8*0]
+ stp $t2,$t3,[$ap_end,#8*2]
+
+ b .Lsqr8x_done
+
+.align 4
+.Lsqr8x8_post_condition:
+ adc $carry,xzr,xzr
+ ldr x30,[x29,#8] // pull return address
+ // $acc0-7,$carry hold result, $a0-7 hold modulus
+ subs $a0,$acc0,$a0
+ ldr $ap,[x29,#96] // pull rp
+ sbcs $a1,$acc1,$a1
+ stp xzr,xzr,[sp,#8*0]
+ sbcs $a2,$acc2,$a2
+ stp xzr,xzr,[sp,#8*2]
+ sbcs $a3,$acc3,$a3
+ stp xzr,xzr,[sp,#8*4]
+ sbcs $a4,$acc4,$a4
+ stp xzr,xzr,[sp,#8*6]
+ sbcs $a5,$acc5,$a5
+ stp xzr,xzr,[sp,#8*8]
+ sbcs $a6,$acc6,$a6
+ stp xzr,xzr,[sp,#8*10]
+ sbcs $a7,$acc7,$a7
+ stp xzr,xzr,[sp,#8*12]
+ sbcs $carry,$carry,xzr // did it borrow?
+ stp xzr,xzr,[sp,#8*14]
+
+ // $a0-7 hold result-modulus
+ csel $a0,$acc0,$a0,lo
+ csel $a1,$acc1,$a1,lo
+ csel $a2,$acc2,$a2,lo
+ csel $a3,$acc3,$a3,lo
+ stp $a0,$a1,[$ap,#8*0]
+ csel $a4,$acc4,$a4,lo
+ csel $a5,$acc5,$a5,lo
+ stp $a2,$a3,[$ap,#8*2]
+ csel $a6,$acc6,$a6,lo
+ csel $a7,$acc7,$a7,lo
+ stp $a4,$a5,[$ap,#8*4]
+ stp $a6,$a7,[$ap,#8*6]
+
+.Lsqr8x_done:
+ ldp x19,x20,[x29,#16]
+ mov sp,x29
+ ldp x21,x22,[x29,#32]
+ mov x0,#1
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x27,x28,[x29,#80]
+ ldr x29,[sp],#128
+ ret
+.size __bn_sqr8x_mont,.-__bn_sqr8x_mont
+___
+}
+
+{
+########################################################################
+# Even though this might look as ARMv8 adaptation of mulx4x_mont from
+# x86_64-mont5 module, it's different in sense that it performs
+# reduction 256 bits at a time.
+
+my ($a0,$a1,$a2,$a3,
+ $t0,$t1,$t2,$t3,
+ $m0,$m1,$m2,$m3,
+ $acc0,$acc1,$acc2,$acc3,$acc4,
+ $bi,$mi,$tp,$ap_end,$cnt) = map("x$_",(6..17,19..28));
+my $bp_end=$rp;
+my ($carry,$topmost) = ($rp,"x30");
+
+$code.=<<___;
+.type __bn_mul4x_mont,%function
+.align 5
+__bn_mul4x_mont:
+ stp x29,x30,[sp,#-128]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+ stp x25,x26,[sp,#64]
+ stp x27,x28,[sp,#80]
+
+ sub $tp,sp,$num,lsl#3
+ lsl $num,$num,#3
+ ldr $n0,[$n0] // *n0
+ sub sp,$tp,#8*4 // alloca
+
+ add $t0,$bp,$num
+ add $ap_end,$ap,$num
+ stp $rp,$t0,[x29,#96] // offload rp and &b[num]
+
+ ldr $bi,[$bp,#8*0] // b[0]
+ ldp $a0,$a1,[$ap,#8*0] // a[0..3]
+ ldp $a2,$a3,[$ap,#8*2]
+ add $ap,$ap,#8*4
+ mov $acc0,xzr
+ mov $acc1,xzr
+ mov $acc2,xzr
+ mov $acc3,xzr
+ ldp $m0,$m1,[$np,#8*0] // n[0..3]
+ ldp $m2,$m3,[$np,#8*2]
+ adds $np,$np,#8*4 // clear carry bit
+ mov $carry,xzr
+ mov $cnt,#0
+ mov $tp,sp
+
+.Loop_mul4x_1st_reduction:
+ mul $t0,$a0,$bi // lo(a[0..3]*b[0])
+ adc $carry,$carry,xzr // modulo-scheduled
+ mul $t1,$a1,$bi
+ add $cnt,$cnt,#8
+ mul $t2,$a2,$bi
+ and $cnt,$cnt,#31
+ mul $t3,$a3,$bi
+ adds $acc0,$acc0,$t0
+ umulh $t0,$a0,$bi // hi(a[0..3]*b[0])
+ adcs $acc1,$acc1,$t1
+ mul $mi,$acc0,$n0 // t[0]*n0
+ adcs $acc2,$acc2,$t2
+ umulh $t1,$a1,$bi
+ adcs $acc3,$acc3,$t3
+ umulh $t2,$a2,$bi
+ adc $acc4,xzr,xzr
+ umulh $t3,$a3,$bi
+ ldr $bi,[$bp,$cnt] // next b[i] (or b[0])
+ adds $acc1,$acc1,$t0
+ // (*) mul $t0,$m0,$mi // lo(n[0..3]*t[0]*n0)
+ str $mi,[$tp],#8 // put aside t[0]*n0 for tail processing
+ adcs $acc2,$acc2,$t1
+ mul $t1,$m1,$mi
+ adcs $acc3,$acc3,$t2
+ mul $t2,$m2,$mi
+ adc $acc4,$acc4,$t3 // can't overflow
+ mul $t3,$m3,$mi
+ // (*) adds xzr,$acc0,$t0
+ subs xzr,$acc0,#1 // (*)
+ umulh $t0,$m0,$mi // hi(n[0..3]*t[0]*n0)
+ adcs $acc0,$acc1,$t1
+ umulh $t1,$m1,$mi
+ adcs $acc1,$acc2,$t2
+ umulh $t2,$m2,$mi
+ adcs $acc2,$acc3,$t3
+ umulh $t3,$m3,$mi
+ adcs $acc3,$acc4,$carry
+ adc $carry,xzr,xzr
+ adds $acc0,$acc0,$t0
+ sub $t0,$ap_end,$ap
+ adcs $acc1,$acc1,$t1
+ adcs $acc2,$acc2,$t2
+ adcs $acc3,$acc3,$t3
+ //adc $carry,$carry,xzr
+ cbnz $cnt,.Loop_mul4x_1st_reduction
+
+ cbz $t0,.Lmul4x4_post_condition
+
+ ldp $a0,$a1,[$ap,#8*0] // a[4..7]
+ ldp $a2,$a3,[$ap,#8*2]
+ add $ap,$ap,#8*4
+ ldr $mi,[sp] // a[0]*n0
+ ldp $m0,$m1,[$np,#8*0] // n[4..7]
+ ldp $m2,$m3,[$np,#8*2]
+ add $np,$np,#8*4
+
+.Loop_mul4x_1st_tail:
+ mul $t0,$a0,$bi // lo(a[4..7]*b[i])
+ adc $carry,$carry,xzr // modulo-scheduled
+ mul $t1,$a1,$bi
+ add $cnt,$cnt,#8
+ mul $t2,$a2,$bi
+ and $cnt,$cnt,#31
+ mul $t3,$a3,$bi
+ adds $acc0,$acc0,$t0
+ umulh $t0,$a0,$bi // hi(a[4..7]*b[i])
+ adcs $acc1,$acc1,$t1
+ umulh $t1,$a1,$bi
+ adcs $acc2,$acc2,$t2
+ umulh $t2,$a2,$bi
+ adcs $acc3,$acc3,$t3
+ umulh $t3,$a3,$bi
+ adc $acc4,xzr,xzr
+ ldr $bi,[$bp,$cnt] // next b[i] (or b[0])
+ adds $acc1,$acc1,$t0
+ mul $t0,$m0,$mi // lo(n[4..7]*a[0]*n0)
+ adcs $acc2,$acc2,$t1
+ mul $t1,$m1,$mi
+ adcs $acc3,$acc3,$t2
+ mul $t2,$m2,$mi
+ adc $acc4,$acc4,$t3 // can't overflow
+ mul $t3,$m3,$mi
+ adds $acc0,$acc0,$t0
+ umulh $t0,$m0,$mi // hi(n[4..7]*a[0]*n0)
+ adcs $acc1,$acc1,$t1
+ umulh $t1,$m1,$mi
+ adcs $acc2,$acc2,$t2
+ umulh $t2,$m2,$mi
+ adcs $acc3,$acc3,$t3
+ adcs $acc4,$acc4,$carry
+ umulh $t3,$m3,$mi
+ adc $carry,xzr,xzr
+ ldr $mi,[sp,$cnt] // next t[0]*n0
+ str $acc0,[$tp],#8 // result!!!
+ adds $acc0,$acc1,$t0
+ sub $t0,$ap_end,$ap // done yet?
+ adcs $acc1,$acc2,$t1
+ adcs $acc2,$acc3,$t2
+ adcs $acc3,$acc4,$t3
+ //adc $carry,$carry,xzr
+ cbnz $cnt,.Loop_mul4x_1st_tail
+
+ sub $t1,$ap_end,$num // rewinded $ap
+ cbz $t0,.Lmul4x_proceed
+
+ ldp $a0,$a1,[$ap,#8*0]
+ ldp $a2,$a3,[$ap,#8*2]
+ add $ap,$ap,#8*4
+ ldp $m0,$m1,[$np,#8*0]
+ ldp $m2,$m3,[$np,#8*2]
+ add $np,$np,#8*4
+ b .Loop_mul4x_1st_tail
+
+.align 5
+.Lmul4x_proceed:
+ ldr $bi,[$bp,#8*4]! // *++b
+ adc $topmost,$carry,xzr
+ ldp $a0,$a1,[$t1,#8*0] // a[0..3]
+ sub $np,$np,$num // rewind np
+ ldp $a2,$a3,[$t1,#8*2]
+ add $ap,$t1,#8*4
+
+ stp $acc0,$acc1,[$tp,#8*0] // result!!!
+ ldp $acc0,$acc1,[sp,#8*4] // t[0..3]
+ stp $acc2,$acc3,[$tp,#8*2] // result!!!
+ ldp $acc2,$acc3,[sp,#8*6]
+
+ ldp $m0,$m1,[$np,#8*0] // n[0..3]
+ mov $tp,sp
+ ldp $m2,$m3,[$np,#8*2]
+ adds $np,$np,#8*4 // clear carry bit
+ mov $carry,xzr
+
+.align 4
+.Loop_mul4x_reduction:
+ mul $t0,$a0,$bi // lo(a[0..3]*b[4])
+ adc $carry,$carry,xzr // modulo-scheduled
+ mul $t1,$a1,$bi
+ add $cnt,$cnt,#8
+ mul $t2,$a2,$bi
+ and $cnt,$cnt,#31
+ mul $t3,$a3,$bi
+ adds $acc0,$acc0,$t0
+ umulh $t0,$a0,$bi // hi(a[0..3]*b[4])
+ adcs $acc1,$acc1,$t1
+ mul $mi,$acc0,$n0 // t[0]*n0
+ adcs $acc2,$acc2,$t2
+ umulh $t1,$a1,$bi
+ adcs $acc3,$acc3,$t3
+ umulh $t2,$a2,$bi
+ adc $acc4,xzr,xzr
+ umulh $t3,$a3,$bi
+ ldr $bi,[$bp,$cnt] // next b[i]
+ adds $acc1,$acc1,$t0
+ // (*) mul $t0,$m0,$mi
+ str $mi,[$tp],#8 // put aside t[0]*n0 for tail processing
+ adcs $acc2,$acc2,$t1
+ mul $t1,$m1,$mi // lo(n[0..3]*t[0]*n0
+ adcs $acc3,$acc3,$t2
+ mul $t2,$m2,$mi
+ adc $acc4,$acc4,$t3 // can't overflow
+ mul $t3,$m3,$mi
+ // (*) adds xzr,$acc0,$t0
+ subs xzr,$acc0,#1 // (*)
+ umulh $t0,$m0,$mi // hi(n[0..3]*t[0]*n0
+ adcs $acc0,$acc1,$t1
+ umulh $t1,$m1,$mi
+ adcs $acc1,$acc2,$t2
+ umulh $t2,$m2,$mi
+ adcs $acc2,$acc3,$t3
+ umulh $t3,$m3,$mi
+ adcs $acc3,$acc4,$carry
+ adc $carry,xzr,xzr
+ adds $acc0,$acc0,$t0
+ adcs $acc1,$acc1,$t1
+ adcs $acc2,$acc2,$t2
+ adcs $acc3,$acc3,$t3
+ //adc $carry,$carry,xzr
+ cbnz $cnt,.Loop_mul4x_reduction
+
+ adc $carry,$carry,xzr
+ ldp $t0,$t1,[$tp,#8*4] // t[4..7]
+ ldp $t2,$t3,[$tp,#8*6]
+ ldp $a0,$a1,[$ap,#8*0] // a[4..7]
+ ldp $a2,$a3,[$ap,#8*2]
+ add $ap,$ap,#8*4
+ adds $acc0,$acc0,$t0
+ adcs $acc1,$acc1,$t1
+ adcs $acc2,$acc2,$t2
+ adcs $acc3,$acc3,$t3
+ //adc $carry,$carry,xzr
+
+ ldr $mi,[sp] // t[0]*n0
+ ldp $m0,$m1,[$np,#8*0] // n[4..7]
+ ldp $m2,$m3,[$np,#8*2]
+ add $np,$np,#8*4
+
+.align 4
+.Loop_mul4x_tail:
+ mul $t0,$a0,$bi // lo(a[4..7]*b[4])
+ adc $carry,$carry,xzr // modulo-scheduled
+ mul $t1,$a1,$bi
+ add $cnt,$cnt,#8
+ mul $t2,$a2,$bi
+ and $cnt,$cnt,#31
+ mul $t3,$a3,$bi
+ adds $acc0,$acc0,$t0
+ umulh $t0,$a0,$bi // hi(a[4..7]*b[4])
+ adcs $acc1,$acc1,$t1
+ umulh $t1,$a1,$bi
+ adcs $acc2,$acc2,$t2
+ umulh $t2,$a2,$bi
+ adcs $acc3,$acc3,$t3
+ umulh $t3,$a3,$bi
+ adc $acc4,xzr,xzr
+ ldr $bi,[$bp,$cnt] // next b[i]
+ adds $acc1,$acc1,$t0
+ mul $t0,$m0,$mi // lo(n[4..7]*t[0]*n0)
+ adcs $acc2,$acc2,$t1
+ mul $t1,$m1,$mi
+ adcs $acc3,$acc3,$t2
+ mul $t2,$m2,$mi
+ adc $acc4,$acc4,$t3 // can't overflow
+ mul $t3,$m3,$mi
+ adds $acc0,$acc0,$t0
+ umulh $t0,$m0,$mi // hi(n[4..7]*t[0]*n0)
+ adcs $acc1,$acc1,$t1
+ umulh $t1,$m1,$mi
+ adcs $acc2,$acc2,$t2
+ umulh $t2,$m2,$mi
+ adcs $acc3,$acc3,$t3
+ umulh $t3,$m3,$mi
+ adcs $acc4,$acc4,$carry
+ ldr $mi,[sp,$cnt] // next a[0]*n0
+ adc $carry,xzr,xzr
+ str $acc0,[$tp],#8 // result!!!
+ adds $acc0,$acc1,$t0
+ sub $t0,$ap_end,$ap // done yet?
+ adcs $acc1,$acc2,$t1
+ adcs $acc2,$acc3,$t2
+ adcs $acc3,$acc4,$t3
+ //adc $carry,$carry,xzr
+ cbnz $cnt,.Loop_mul4x_tail
+
+ sub $t1,$np,$num // rewinded np?
+ adc $carry,$carry,xzr
+ cbz $t0,.Loop_mul4x_break
+
+ ldp $t0,$t1,[$tp,#8*4]
+ ldp $t2,$t3,[$tp,#8*6]
+ ldp $a0,$a1,[$ap,#8*0]
+ ldp $a2,$a3,[$ap,#8*2]
+ add $ap,$ap,#8*4
+ adds $acc0,$acc0,$t0
+ adcs $acc1,$acc1,$t1
+ adcs $acc2,$acc2,$t2
+ adcs $acc3,$acc3,$t3
+ //adc $carry,$carry,xzr
+ ldp $m0,$m1,[$np,#8*0]
+ ldp $m2,$m3,[$np,#8*2]
+ add $np,$np,#8*4
+ b .Loop_mul4x_tail
+
+.align 4
+.Loop_mul4x_break:
+ ldp $t2,$t3,[x29,#96] // pull rp and &b[num]
+ adds $acc0,$acc0,$topmost
+ add $bp,$bp,#8*4 // bp++
+ adcs $acc1,$acc1,xzr
+ sub $ap,$ap,$num // rewind ap
+ adcs $acc2,$acc2,xzr
+ stp $acc0,$acc1,[$tp,#8*0] // result!!!
+ adcs $acc3,$acc3,xzr
+ ldp $acc0,$acc1,[sp,#8*4] // t[0..3]
+ adc $topmost,$carry,xzr
+ stp $acc2,$acc3,[$tp,#8*2] // result!!!
+ cmp $bp,$t3 // done yet?
+ ldp $acc2,$acc3,[sp,#8*6]
+ ldp $m0,$m1,[$t1,#8*0] // n[0..3]
+ ldp $m2,$m3,[$t1,#8*2]
+ add $np,$t1,#8*4
+ b.eq .Lmul4x_post
+
+ ldr $bi,[$bp]
+ ldp $a0,$a1,[$ap,#8*0] // a[0..3]
+ ldp $a2,$a3,[$ap,#8*2]
+ adds $ap,$ap,#8*4 // clear carry bit
+ mov $carry,xzr
+ mov $tp,sp
+ b .Loop_mul4x_reduction
+
+.align 4
+.Lmul4x_post:
+ // Final step. We see if result is larger than modulus, and
+ // if it is, subtract the modulus. But comparison implies
+ // subtraction. So we subtract modulus, see if it borrowed,
+ // and conditionally copy original value.
+ mov $rp,$t2
+ mov $ap_end,$t2 // $rp copy
+ subs $t0,$acc0,$m0
+ add $tp,sp,#8*8
+ sbcs $t1,$acc1,$m1
+ sub $cnt,$num,#8*4
+
+.Lmul4x_sub:
+ sbcs $t2,$acc2,$m2
+ ldp $m0,$m1,[$np,#8*0]
+ sub $cnt,$cnt,#8*4
+ ldp $acc0,$acc1,[$tp,#8*0]
+ sbcs $t3,$acc3,$m3
+ ldp $m2,$m3,[$np,#8*2]
+ add $np,$np,#8*4
+ ldp $acc2,$acc3,[$tp,#8*2]
+ add $tp,$tp,#8*4
+ stp $t0,$t1,[$rp,#8*0]
+ sbcs $t0,$acc0,$m0
+ stp $t2,$t3,[$rp,#8*2]
+ add $rp,$rp,#8*4
+ sbcs $t1,$acc1,$m1
+ cbnz $cnt,.Lmul4x_sub
+
+ sbcs $t2,$acc2,$m2
+ mov $tp,sp
+ add $ap,sp,#8*4
+ ldp $a0,$a1,[$ap_end,#8*0]
+ sbcs $t3,$acc3,$m3
+ stp $t0,$t1,[$rp,#8*0]
+ ldp $a2,$a3,[$ap_end,#8*2]
+ stp $t2,$t3,[$rp,#8*2]
+ ldp $acc0,$acc1,[$ap,#8*0]
+ ldp $acc2,$acc3,[$ap,#8*2]
+ sbcs xzr,$topmost,xzr // did it borrow?
+ ldr x30,[x29,#8] // pull return address
+
+ sub $cnt,$num,#8*4
+.Lmul4x_cond_copy:
+ sub $cnt,$cnt,#8*4
+ csel $t0,$acc0,$a0,lo
+ stp xzr,xzr,[$tp,#8*0]
+ csel $t1,$acc1,$a1,lo
+ ldp $a0,$a1,[$ap_end,#8*4]
+ ldp $acc0,$acc1,[$ap,#8*4]
+ csel $t2,$acc2,$a2,lo
+ stp xzr,xzr,[$tp,#8*2]
+ add $tp,$tp,#8*4
+ csel $t3,$acc3,$a3,lo
+ ldp $a2,$a3,[$ap_end,#8*6]
+ ldp $acc2,$acc3,[$ap,#8*6]
+ add $ap,$ap,#8*4
+ stp $t0,$t1,[$ap_end,#8*0]
+ stp $t2,$t3,[$ap_end,#8*2]
+ add $ap_end,$ap_end,#8*4
+ cbnz $cnt,.Lmul4x_cond_copy
+
+ csel $t0,$acc0,$a0,lo
+ stp xzr,xzr,[$tp,#8*0]
+ csel $t1,$acc1,$a1,lo
+ stp xzr,xzr,[$tp,#8*2]
+ csel $t2,$acc2,$a2,lo
+ stp xzr,xzr,[$tp,#8*3]
+ csel $t3,$acc3,$a3,lo
+ stp xzr,xzr,[$tp,#8*4]
+ stp $t0,$t1,[$ap_end,#8*0]
+ stp $t2,$t3,[$ap_end,#8*2]
+
+ b .Lmul4x_done
+
+.align 4
+.Lmul4x4_post_condition:
+ adc $carry,$carry,xzr
+ ldr $ap,[x29,#96] // pull rp
+ // $acc0-3,$carry hold result, $m0-7 hold modulus
+ subs $a0,$acc0,$m0
+ ldr x30,[x29,#8] // pull return address
+ sbcs $a1,$acc1,$m1
+ stp xzr,xzr,[sp,#8*0]
+ sbcs $a2,$acc2,$m2
+ stp xzr,xzr,[sp,#8*2]
+ sbcs $a3,$acc3,$m3
+ stp xzr,xzr,[sp,#8*4]
+ sbcs xzr,$carry,xzr // did it borrow?
+ stp xzr,xzr,[sp,#8*6]
+
+ // $a0-3 hold result-modulus
+ csel $a0,$acc0,$a0,lo
+ csel $a1,$acc1,$a1,lo
+ csel $a2,$acc2,$a2,lo
+ csel $a3,$acc3,$a3,lo
+ stp $a0,$a1,[$ap,#8*0]
+ stp $a2,$a3,[$ap,#8*2]
+
+.Lmul4x_done:
+ ldp x19,x20,[x29,#16]
+ mov sp,x29
+ ldp x21,x22,[x29,#32]
+ mov x0,#1
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x27,x28,[x29,#80]
+ ldr x29,[sp],#128
+ ret
+.size __bn_mul4x_mont,.-__bn_mul4x_mont
+___
+}
+$code.=<<___;
+.asciz "Montgomery Multiplication for ARMv8, CRYPTOGAMS by <appro\@openssl.org>"
+.align 4
+___
+
+print $code;
+
+close STDOUT;
diff --git a/src/crypto/bn/asm/rsaz-avx2.pl b/src/crypto/bn/asm/rsaz-avx2.pl
index 3b6ccf8..bbceccb 100644
--- a/src/crypto/bn/asm/rsaz-avx2.pl
+++ b/src/crypto/bn/asm/rsaz-avx2.pl
@@ -79,29 +79,13 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
-if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
- =~ /GNU assembler version ([2-9]\.[0-9]+)/) {
- $avx = ($1>=2.19) + ($1>=2.22);
- $addx = ($1>=2.23);
-}
-
-if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
- `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
- $avx = ($1>=2.09) + ($1>=2.10);
- $addx = ($1>=2.10);
-}
-
-if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
- `ml64 2>&1` =~ /Version ([0-9]+)\./) {
- $avx = ($1>=10) + ($1>=11);
- $addx = ($1>=11);
-}
-
-if (!$avx && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9])\.([0-9]+)/) {
- my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10
- $avx = ($ver>=3.0) + ($ver>=3.01);
- $addx = ($ver>=3.03);
-}
+# 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 these after testing. $avx goes up to 2 and $addx to 1.
+$avx = 0;
+$addx = 0;
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT = *OUT;
diff --git a/src/crypto/bn/asm/rsaz-x86_64.pl b/src/crypto/bn/asm/rsaz-x86_64.pl
index 3bd45db..4113d53 100644
--- a/src/crypto/bn/asm/rsaz-x86_64.pl
+++ b/src/crypto/bn/asm/rsaz-x86_64.pl
@@ -98,25 +98,12 @@ die "can't locate x86_64-xlate.pl";
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT=*OUT;
-if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
- =~ /GNU assembler version ([2-9]\.[0-9]+)/) {
- $addx = ($1>=2.23);
-}
-
-if (!$addx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
- `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
- $addx = ($1>=2.10);
-}
-
-if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
- `ml64 2>&1` =~ /Version ([0-9]+)\./) {
- $addx = ($1>=12);
-}
-
-if (!$addx && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9])\.([0-9]+)/) {
- my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10
- $addx = ($ver>=3.03);
-}
+# 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. $addx goes up to 1.
+$addx = 0;
($out, $inp, $mod) = ("%rdi", "%rsi", "%rbp"); # common internal API
{
diff --git a/src/crypto/bn/asm/x86_64-mont.pl b/src/crypto/bn/asm/x86_64-mont.pl
index 39476ab..04c4bea 100644
--- a/src/crypto/bn/asm/x86_64-mont.pl
+++ b/src/crypto/bn/asm/x86_64-mont.pl
@@ -53,20 +53,12 @@ die "can't locate x86_64-xlate.pl";
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT=*OUT;
-if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
- =~ /GNU assembler version ([2-9]\.[0-9]+)/) {
- $addx = ($1>=2.23);
-}
-
-if (!$addx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
- `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
- $addx = ($1>=2.10);
-}
-
-if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
- `ml64 2>&1` =~ /Version ([0-9]+)\./) {
- $addx = ($1>=12);
-}
+# 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 option after testing. $addx goes up to 1.
+$addx = 0;
# int bn_mul_mont(
$rp="%rdi"; # BN_ULONG *rp,
diff --git a/src/crypto/bn/asm/x86_64-mont5.pl b/src/crypto/bn/asm/x86_64-mont5.pl
index 80e9126..3c5a8fc 100644
--- a/src/crypto/bn/asm/x86_64-mont5.pl
+++ b/src/crypto/bn/asm/x86_64-mont5.pl
@@ -38,20 +38,12 @@ die "can't locate x86_64-xlate.pl";
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT=*OUT;
-if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
- =~ /GNU assembler version ([2-9]\.[0-9]+)/) {
- $addx = ($1>=2.23);
-}
-
-if (!$addx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
- `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
- $addx = ($1>=2.10);
-}
-
-if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
- `ml64 2>&1` =~ /Version ([0-9]+)\./) {
- $addx = ($1>=12);
-}
+# 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. $addx goes up to 1.
+$addx = 0;
# int bn_mul_mont_gather5(
$rp="%rdi"; # BN_ULONG *rp,
@@ -1778,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
@@ -3124,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
@@ -3167,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 f32d6b0..543c148 100644
--- a/src/crypto/bn/bn.c
+++ b/src/crypto/bn/bn.c
@@ -69,7 +69,7 @@ BIGNUM *BN_new(void) {
BIGNUM *bn = OPENSSL_malloc(sizeof(BIGNUM));
if (bn == NULL) {
- OPENSSL_PUT_ERROR(BN, BN_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -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) {
@@ -279,26 +278,26 @@ void BN_set_negative(BIGNUM *bn, int sign) {
}
}
-BIGNUM *bn_wexpand(BIGNUM *bn, unsigned words) {
+BIGNUM *bn_wexpand(BIGNUM *bn, size_t words) {
BN_ULONG *a;
- if (words <= (unsigned) bn->dmax) {
+ if (words <= (size_t)bn->dmax) {
return bn;
}
if (words > (INT_MAX / (4 * BN_BITS2))) {
- OPENSSL_PUT_ERROR(BN, bn_wexpand, BN_R_BIGNUM_TOO_LONG);
+ OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG);
return NULL;
}
if (bn->flags & BN_FLG_STATIC_DATA) {
- OPENSSL_PUT_ERROR(BN, bn_wexpand, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
+ OPENSSL_PUT_ERROR(BN, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
return NULL;
}
a = (BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG) * words);
if (a == NULL) {
- OPENSSL_PUT_ERROR(BN, bn_wexpand, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -306,12 +305,16 @@ BIGNUM *bn_wexpand(BIGNUM *bn, unsigned words) {
OPENSSL_free(bn->d);
bn->d = a;
- bn->dmax = words;
+ bn->dmax = (int)words;
return bn;
}
-BIGNUM *bn_expand(BIGNUM *bn, unsigned bits) {
+BIGNUM *bn_expand(BIGNUM *bn, size_t bits) {
+ if (bits + BN_BITS2 - 1 < bits) {
+ OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG);
+ return NULL;
+ }
return bn_wexpand(bn, (bits+BN_BITS2-1)/BN_BITS2);
}
diff --git a/src/crypto/bn/bn_asn1.c b/src/crypto/bn/bn_asn1.c
new file mode 100644
index 0000000..9d70ba8
--- /dev/null
+++ b/src/crypto/bn/bn_asn1.c
@@ -0,0 +1,93 @@
+/* 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/bn.h>
+
+#include <openssl/bytestring.h>
+#include <openssl/err.h>
+
+
+int BN_cbs2unsigned(CBS *cbs, BIGNUM *ret) {
+ CBS child;
+ if (!CBS_get_asn1(cbs, &child, CBS_ASN1_INTEGER) ||
+ CBS_len(&child) == 0) {
+ OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING);
+ return 0;
+ }
+
+ if (CBS_data(&child)[0] & 0x80) {
+ OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
+ return 0;
+ }
+
+ /* INTEGERs must be minimal. */
+ if (CBS_data(&child)[0] == 0x00 &&
+ CBS_len(&child) > 1 &&
+ !(CBS_data(&child)[1] & 0x80)) {
+ OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING);
+ return 0;
+ }
+
+ return BN_bin2bn(CBS_data(&child), CBS_len(&child), ret) != NULL;
+}
+
+int BN_cbs2unsigned_buggy(CBS *cbs, BIGNUM *ret) {
+ CBS child;
+ if (!CBS_get_asn1(cbs, &child, CBS_ASN1_INTEGER) ||
+ CBS_len(&child) == 0) {
+ OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING);
+ return 0;
+ }
+
+ /* This function intentionally does not reject negative numbers or non-minimal
+ * encodings. Estonian IDs issued between September 2014 to September 2015 are
+ * broken. See https://crbug.com/532048 and https://crbug.com/534766.
+ *
+ * TODO(davidben): Remove this code and callers in March 2016. */
+ return BN_bin2bn(CBS_data(&child), CBS_len(&child), ret) != NULL;
+}
+
+int BN_bn2cbb(CBB *cbb, const BIGNUM *bn) {
+ /* Negative numbers are unsupported. */
+ if (BN_is_negative(bn)) {
+ OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
+ return 0;
+ }
+
+ CBB child;
+ if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) {
+ OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR);
+ return 0;
+ }
+
+ /* The number must be padded with a leading zero if the high bit would
+ * otherwise be set (or |bn| is zero). */
+ if (BN_num_bits(bn) % 8 == 0 &&
+ !CBB_add_u8(&child, 0x00)) {
+ OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR);
+ return 0;
+ }
+
+ uint8_t *out;
+ if (!CBB_add_space(&child, &out, BN_num_bytes(bn))) {
+ OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR);
+ return 0;
+ }
+ BN_bn2bin(bn, out);
+ if (!CBB_flush(cbb)) {
+ OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR);
+ return 0;
+ }
+ return 1;
+}
diff --git a/src/crypto/bn/bn_test.cc b/src/crypto/bn/bn_test.cc
index 6a7d48c..e7e04f1 100644
--- a/src/crypto/bn/bn_test.cc
+++ b/src/crypto/bn/bn_test.cc
@@ -76,12 +76,15 @@
#include <stdio.h>
#include <string.h>
+#include <utility>
+
#include <openssl/bn.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include "../crypto/test/scoped_types.h"
+#include "../crypto/test/test_util.h"
// This program tests the BIGNUM implementation. It takes an optional -bc
@@ -117,11 +120,13 @@ static bool test_exp_mod_zero(void);
static bool test_small_prime(FILE *fp, BN_CTX *ctx);
static bool test_mod_exp_mont5(FILE *fp, BN_CTX *ctx);
static bool test_sqrt(FILE *fp, BN_CTX *ctx);
-static bool test_bn2bin_padded(FILE *fp, BN_CTX *ctx);
-static bool test_dec2bn(FILE *fp, BN_CTX *ctx);
-static bool test_hex2bn(FILE *fp, BN_CTX *ctx);
-static bool test_asc2bn(FILE *fp, BN_CTX *ctx);
+static bool test_bn2bin_padded(BN_CTX *ctx);
+static bool test_dec2bn(BN_CTX *ctx);
+static bool test_hex2bn(BN_CTX *ctx);
+static bool test_asc2bn(BN_CTX *ctx);
+static bool test_mpi();
static bool test_rand();
+static bool test_asn1();
static const uint8_t kSample[] =
"\xC6\x4F\x43\x04\x2A\xEA\xCA\x6E\x58\x36\x80\x5B\xE8\xC9"
@@ -208,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());
@@ -311,40 +316,27 @@ int main(int argc, char *argv[]) {
}
flush_fp(bc_file.get());
- message(bc_file.get(), "BN_bn2bin_padded");
- if (!test_bn2bin_padded(bc_file.get(), ctx.get())) {
- return 1;
- }
- flush_fp(bc_file.get());
-
- message(bc_file.get(), "BN_dec2bn");
- if (!test_dec2bn(bc_file.get(), ctx.get())) {
- return 1;
- }
- flush_fp(bc_file.get());
-
- message(bc_file.get(), "BN_hex2bn");
- if (!test_hex2bn(bc_file.get(), ctx.get())) {
- return 1;
- }
- flush_fp(bc_file.get());
-
- message(bc_file.get(), "BN_asc2bn");
- if (!test_asc2bn(bc_file.get(), ctx.get())) {
+ if (!test_bn2bin_padded(ctx.get()) ||
+ !test_dec2bn(ctx.get()) ||
+ !test_hex2bn(ctx.get()) ||
+ !test_asc2bn(ctx.get()) ||
+ !test_mpi() ||
+ !test_rand() ||
+ !test_asn1()) {
return 1;
}
- flush_fp(bc_file.get());
-
- message(bc_file.get(), "BN_rand");
- if (!test_rand()) {
- return 1;
- }
- flush_fp(bc_file.get());
printf("PASS\n");
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());
@@ -440,6 +432,16 @@ static bool test_div(FILE *fp, BN_CTX *ctx) {
return false;
}
+ if (!BN_one(a.get())) {
+ return false;
+ }
+ BN_zero(b.get());
+ if (BN_div(d.get(), c.get(), a.get(), b.get(), ctx)) {
+ fprintf(stderr, "Division by zero succeeded!\n");
+ return false;
+ }
+ ERR_clear_error();
+
for (int i = 0; i < num0 + num1; i++) {
if (i < num1) {
if (!BN_rand(a.get(), 400, 0, 0) ||
@@ -837,18 +839,17 @@ static bool test_div_word(FILE *fp) {
}
for (int i = 0; i < num0; i++) {
- BN_ULONG s;
do {
if (!BN_rand(a.get(), 512, -1, 0) ||
!BN_rand(b.get(), BN_BITS2, -1, 0)) {
return false;
}
- s = b->d[0];
- } while (!s);
+ } while (BN_is_zero(b.get()));
if (!BN_copy(b.get(), a.get())) {
return false;
}
+ BN_ULONG s = b->d[0];
BN_ULONG r = BN_div_word(b.get(), s);
if (r == (BN_ULONG)-1) {
return false;
@@ -891,8 +892,27 @@ static bool test_mont(FILE *fp, BN_CTX *ctx) {
ScopedBIGNUM B(BN_new());
ScopedBIGNUM n(BN_new());
ScopedBN_MONT_CTX mont(BN_MONT_CTX_new());
- if (!a || !b || !c || !d || !A || !B || !n || !mont ||
- !BN_rand(a.get(), 100, 0, 0) ||
+ if (!a || !b || !c || !d || !A || !B || !n || !mont) {
+ return false;
+ }
+
+ BN_zero(n.get());
+ if (BN_MONT_CTX_set(mont.get(), n.get(), ctx)) {
+ fprintf(stderr, "BN_MONT_CTX_set succeeded for zero modulus!\n");
+ return false;
+ }
+ ERR_clear_error();
+
+ if (!BN_set_word(n.get(), 16)) {
+ return false;
+ }
+ if (BN_MONT_CTX_set(mont.get(), n.get(), ctx)) {
+ fprintf(stderr, "BN_MONT_CTX_set succeeded for even modulus!\n");
+ return false;
+ }
+ ERR_clear_error();
+
+ if (!BN_rand(a.get(), 100, 0, 0) ||
!BN_rand(b.get(), 100, 0, 0)) {
return false;
}
@@ -932,6 +952,7 @@ static bool test_mont(FILE *fp, BN_CTX *ctx) {
return false;
}
}
+
return true;
}
@@ -985,6 +1006,16 @@ static bool test_mod_mul(FILE *fp, BN_CTX *ctx) {
return false;
}
+ if (!BN_one(a.get()) || !BN_one(b.get())) {
+ return false;
+ }
+ BN_zero(c.get());
+ if (BN_mod_mul(e.get(), a.get(), b.get(), c.get(), ctx)) {
+ fprintf(stderr, "BN_mod_mul with zero modulus succeeded!\n");
+ return false;
+ }
+ ERR_clear_error();
+
for (int j = 0; j < 3; j++) {
if (!BN_rand(c.get(), 1024, 0, 0)) {
return false;
@@ -1039,8 +1070,21 @@ static bool test_mod_exp(FILE *fp, BN_CTX *ctx) {
ScopedBIGNUM c(BN_new());
ScopedBIGNUM d(BN_new());
ScopedBIGNUM e(BN_new());
- if (!a || !b || !c || !d || !e ||
- !BN_rand(c.get(), 30, 0, 1)) { // must be odd for montgomery
+ if (!a || !b || !c || !d || !e) {
+ return false;
+ }
+
+ if (!BN_one(a.get()) || !BN_one(b.get())) {
+ return false;
+ }
+ BN_zero(c.get());
+ if (BN_mod_exp(d.get(), a.get(), b.get(), c.get(), ctx)) {
+ fprintf(stderr, "BN_mod_exp with zero modulus succeeded!\n");
+ return 0;
+ }
+ ERR_clear_error();
+
+ if (!BN_rand(c.get(), 30, 0, 1)) { // must be odd for montgomery
return false;
}
for (int i = 0; i < num2; i++) {
@@ -1070,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;
}
@@ -1079,8 +1144,32 @@ static bool test_mod_exp_mont_consttime(FILE *fp, BN_CTX *ctx) {
ScopedBIGNUM c(BN_new());
ScopedBIGNUM d(BN_new());
ScopedBIGNUM e(BN_new());
- if (!a || !b || !c || !d || !e ||
- !BN_rand(c.get(), 30, 0, 1)) { // must be odd for montgomery
+ if (!a || !b || !c || !d || !e) {
+ return false;
+ }
+
+ if (!BN_one(a.get()) || !BN_one(b.get())) {
+ return false;
+ }
+ BN_zero(c.get());
+ if (BN_mod_exp_mont_consttime(d.get(), a.get(), b.get(), c.get(), ctx,
+ nullptr)) {
+ fprintf(stderr, "BN_mod_exp_mont_consttime with zero modulus succeeded!\n");
+ return 0;
+ }
+ ERR_clear_error();
+
+ if (!BN_set_word(c.get(), 16)) {
+ return false;
+ }
+ if (BN_mod_exp_mont_consttime(d.get(), a.get(), b.get(), c.get(), ctx,
+ nullptr)) {
+ fprintf(stderr, "BN_mod_exp_mont_consttime with even modulus succeeded!\n");
+ return 0;
+ }
+ ERR_clear_error();
+
+ if (!BN_rand(c.get(), 30, 0, 1)) { // must be odd for montgomery
return false;
}
for (int i = 0; i < num2; i++) {
@@ -1208,8 +1297,9 @@ static bool test_exp(FILE *fp, BN_CTX *ctx) {
if (!BN_one(e.get())) {
return false;
}
- for (; !BN_is_zero(b.get()); BN_sub(b.get(), b.get(), BN_value_one())) {
- if (!BN_mul(e.get(), e.get(), a.get(), ctx)) {
+ while (!BN_is_zero(b.get())) {
+ if (!BN_mul(e.get(), e.get(), a.get(), ctx) ||
+ !BN_sub(b.get(), b.get(), BN_value_one())) {
return false;
}
}
@@ -1226,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;
}
@@ -1371,7 +1461,7 @@ static bool test_sqrt(FILE *fp, BN_CTX *ctx) {
return true;
}
-static bool test_bn2bin_padded(FILE *fp, BN_CTX *ctx) {
+static bool test_bn2bin_padded(BN_CTX *ctx) {
uint8_t zeros[256], out[256], reference[128];
memset(zeros, 0, sizeof(zeros));
@@ -1448,7 +1538,7 @@ static int DecimalToBIGNUM(ScopedBIGNUM *out, const char *in) {
return ret;
}
-static bool test_dec2bn(FILE *fp, BN_CTX *ctx) {
+static bool test_dec2bn(BN_CTX *ctx) {
ScopedBIGNUM bn;
int ret = DecimalToBIGNUM(&bn, "0");
if (ret != 1 || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
@@ -1483,14 +1573,7 @@ static bool test_dec2bn(FILE *fp, 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(FILE *fp, BN_CTX *ctx) {
+static bool test_hex2bn(BN_CTX *ctx) {
ScopedBIGNUM bn;
int ret = HexToBIGNUM(&bn, "0");
if (ret != 1 || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
@@ -1533,7 +1616,7 @@ static ScopedBIGNUM ASCIIToBIGNUM(const char *in) {
return ScopedBIGNUM(raw);
}
-static bool test_asc2bn(FILE *fp, BN_CTX *ctx) {
+static bool test_asc2bn(BN_CTX *ctx) {
ScopedBIGNUM bn = ASCIIToBIGNUM("0");
if (!bn || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
fprintf(stderr, "BN_asc2bn gave a bad result.\n");
@@ -1585,6 +1668,63 @@ static bool test_asc2bn(FILE *fp, BN_CTX *ctx) {
return true;
}
+struct MPITest {
+ const char *base10;
+ const char *mpi;
+ size_t mpi_len;
+};
+
+static const MPITest kMPITests[] = {
+ { "0", "\x00\x00\x00\x00", 4 },
+ { "1", "\x00\x00\x00\x01\x01", 5 },
+ { "-1", "\x00\x00\x00\x01\x81", 5 },
+ { "128", "\x00\x00\x00\x02\x00\x80", 6 },
+ { "256", "\x00\x00\x00\x02\x01\x00", 6 },
+ { "-256", "\x00\x00\x00\x02\x81\x00", 6 },
+};
+
+static bool test_mpi() {
+ uint8_t scratch[8];
+
+ for (size_t i = 0; i < sizeof(kMPITests) / sizeof(kMPITests[0]); i++) {
+ const MPITest &test = kMPITests[i];
+ ScopedBIGNUM bn(ASCIIToBIGNUM(test.base10));
+ const size_t mpi_len = BN_bn2mpi(bn.get(), NULL);
+ if (mpi_len > sizeof(scratch)) {
+ fprintf(stderr, "MPI test #%u: MPI size is too large to test.\n",
+ (unsigned)i);
+ return false;
+ }
+
+ const size_t mpi_len2 = BN_bn2mpi(bn.get(), scratch);
+ if (mpi_len != mpi_len2) {
+ fprintf(stderr, "MPI test #%u: length changes.\n", (unsigned)i);
+ return false;
+ }
+
+ if (mpi_len != test.mpi_len ||
+ memcmp(test.mpi, scratch, mpi_len) != 0) {
+ fprintf(stderr, "MPI test #%u failed:\n", (unsigned)i);
+ hexdump(stderr, "Expected: ", test.mpi, test.mpi_len);
+ hexdump(stderr, "Got: ", scratch, mpi_len);
+ return false;
+ }
+
+ ScopedBIGNUM bn2(BN_mpi2bn(scratch, mpi_len, NULL));
+ if (bn2.get() == nullptr) {
+ fprintf(stderr, "MPI test #%u: failed to parse\n", (unsigned)i);
+ return false;
+ }
+
+ if (BN_cmp(bn.get(), bn2.get()) != 0) {
+ fprintf(stderr, "MPI test #%u: wrong result\n", (unsigned)i);
+ return false;
+ }
+ }
+
+ return true;
+}
+
static bool test_rand() {
ScopedBIGNUM bn(BN_new());
if (!bn) {
@@ -1628,3 +1768,170 @@ static bool test_rand() {
return true;
}
+
+struct ASN1Test {
+ const char *value_ascii;
+ const char *der;
+ size_t der_len;
+};
+
+static const ASN1Test kASN1Tests[] = {
+ {"0", "\x02\x01\x00", 3},
+ {"1", "\x02\x01\x01", 3},
+ {"127", "\x02\x01\x7f", 3},
+ {"128", "\x02\x02\x00\x80", 4},
+ {"0xdeadbeef", "\x02\x05\x00\xde\xad\xbe\xef", 7},
+ {"0x0102030405060708",
+ "\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10},
+ {"0xffffffffffffffff",
+ "\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11},
+};
+
+struct ASN1InvalidTest {
+ const char *der;
+ size_t der_len;
+};
+
+static const ASN1InvalidTest kASN1InvalidTests[] = {
+ // Bad tag.
+ {"\x03\x01\x00", 3},
+ // Empty contents.
+ {"\x02\x00", 2},
+};
+
+// kASN1BuggyTests are incorrect encodings and how |BN_cbs2unsigned_buggy|
+// should interpret them.
+static const ASN1Test kASN1BuggyTests[] = {
+ // Negative numbers.
+ {"128", "\x02\x01\x80", 3},
+ {"255", "\x02\x01\xff", 3},
+ // Unnecessary leading zeros.
+ {"1", "\x02\x02\x00\x01", 4},
+};
+
+static bool test_asn1() {
+ for (const ASN1Test &test : kASN1Tests) {
+ ScopedBIGNUM bn = ASCIIToBIGNUM(test.value_ascii);
+ if (!bn) {
+ return false;
+ }
+
+ // Test that the input is correctly parsed.
+ ScopedBIGNUM bn2(BN_new());
+ if (!bn2) {
+ return false;
+ }
+ CBS cbs;
+ CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
+ if (!BN_cbs2unsigned(&cbs, bn2.get()) || CBS_len(&cbs) != 0) {
+ fprintf(stderr, "Parsing ASN.1 INTEGER failed.\n");
+ return false;
+ }
+ if (BN_cmp(bn.get(), bn2.get()) != 0) {
+ fprintf(stderr, "Bad parse.\n");
+ return false;
+ }
+
+ // Test the value serializes correctly.
+ CBB cbb;
+ uint8_t *der;
+ size_t der_len;
+ CBB_zero(&cbb);
+ if (!CBB_init(&cbb, 0) ||
+ !BN_bn2cbb(&cbb, bn.get()) ||
+ !CBB_finish(&cbb, &der, &der_len)) {
+ CBB_cleanup(&cbb);
+ return false;
+ }
+ ScopedOpenSSLBytes delete_der(der);
+ if (der_len != test.der_len ||
+ memcmp(der, reinterpret_cast<const uint8_t*>(test.der), der_len) != 0) {
+ fprintf(stderr, "Bad serialization.\n");
+ return false;
+ }
+
+ // |BN_cbs2unsigned_buggy| parses all valid input.
+ CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
+ if (!BN_cbs2unsigned_buggy(&cbs, bn2.get()) || CBS_len(&cbs) != 0) {
+ fprintf(stderr, "Parsing ASN.1 INTEGER failed.\n");
+ return false;
+ }
+ if (BN_cmp(bn.get(), bn2.get()) != 0) {
+ fprintf(stderr, "Bad parse.\n");
+ return false;
+ }
+ }
+
+ for (const ASN1InvalidTest &test : kASN1InvalidTests) {
+ ScopedBIGNUM bn(BN_new());
+ if (!bn) {
+ return false;
+ }
+ CBS cbs;
+ CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
+ if (BN_cbs2unsigned(&cbs, bn.get())) {
+ fprintf(stderr, "Parsed invalid input.\n");
+ return false;
+ }
+ ERR_clear_error();
+
+ // All tests in kASN1InvalidTests are also rejected by
+ // |BN_cbs2unsigned_buggy|.
+ CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
+ if (BN_cbs2unsigned_buggy(&cbs, bn.get())) {
+ fprintf(stderr, "Parsed invalid input.\n");
+ return false;
+ }
+ ERR_clear_error();
+ }
+
+ for (const ASN1Test &test : kASN1BuggyTests) {
+ // These broken encodings are rejected by |BN_cbs2unsigned|.
+ ScopedBIGNUM bn(BN_new());
+ if (!bn) {
+ return false;
+ }
+
+ CBS cbs;
+ CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
+ if (BN_cbs2unsigned(&cbs, bn.get())) {
+ fprintf(stderr, "Parsed invalid input.\n");
+ return false;
+ }
+ ERR_clear_error();
+
+ // However |BN_cbs2unsigned_buggy| accepts them.
+ ScopedBIGNUM bn2 = ASCIIToBIGNUM(test.value_ascii);
+ if (!bn2) {
+ return false;
+ }
+
+ CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
+ if (!BN_cbs2unsigned_buggy(&cbs, bn.get()) || CBS_len(&cbs) != 0) {
+ fprintf(stderr, "Parsing (invalid) ASN.1 INTEGER failed.\n");
+ return false;
+ }
+
+ if (BN_cmp(bn.get(), bn2.get()) != 0) {
+ fprintf(stderr, "\"Bad\" parse.\n");
+ return false;
+ }
+ }
+
+ // Serializing negative numbers is not supported.
+ ScopedBIGNUM bn = ASCIIToBIGNUM("-1");
+ if (!bn) {
+ return false;
+ }
+ CBB cbb;
+ CBB_zero(&cbb);
+ if (!CBB_init(&cbb, 0) ||
+ BN_bn2cbb(&cbb, bn.get())) {
+ fprintf(stderr, "Serialized negative number.\n");
+ CBB_cleanup(&cbb);
+ return false;
+ }
+ CBB_cleanup(&cbb);
+
+ return true;
+}
diff --git a/src/crypto/bn/convert.c b/src/crypto/bn/convert.c
index 531b661..1f7af64 100644
--- a/src/crypto/bn/convert.c
+++ b/src/crypto/bn/convert.c
@@ -56,18 +56,22 @@
#include <openssl/bn.h>
+#include <assert.h>
#include <ctype.h>
+#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <openssl/bio.h>
+#include <openssl/bytestring.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include "internal.h"
BIGNUM *BN_bin2bn(const uint8_t *in, size_t len, BIGNUM *ret) {
- unsigned num_words, m;
+ size_t num_words;
+ unsigned m;
BN_ULONG word = 0;
BIGNUM *bn = NULL;
@@ -93,7 +97,10 @@ BIGNUM *BN_bin2bn(const uint8_t *in, size_t len, BIGNUM *ret) {
return NULL;
}
- ret->top = num_words;
+ /* |bn_wexpand| must check bounds on |num_words| to write it into
+ * |ret->dmax|. */
+ assert(num_words <= INT_MAX);
+ ret->top = (int)num_words;
ret->neg = 0;
while (len--) {
@@ -189,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) {
@@ -198,7 +210,7 @@ char *BN_bn2hex(const BIGNUM *bn) {
buf = (char *)OPENSSL_malloc(bn->top * BN_BYTES * 2 + 2);
if (buf == NULL) {
- OPENSSL_PUT_ERROR(BN, BN_bn2hex, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -227,47 +239,59 @@ char *BN_bn2hex(const BIGNUM *bn) {
return buf;
}
-/* decode_hex decodes |i| bytes of hex data from |in| and updates |bn|. */
-static void decode_hex(BIGNUM *bn, const char *in, int i) {
- int h, m, j, k, c;
- BN_ULONG l=0;
-
- j = i; /* least significant 'hex' */
- h = 0;
- while (j > 0) {
- m = ((BN_BYTES * 2) <= j) ? (BN_BYTES * 2) : j;
- l = 0;
- for (;;) {
- c = in[j - m];
- if ((c >= '0') && (c <= '9')) {
- k = c - '0';
- } else if ((c >= 'a') && (c <= 'f')) {
- k = c - 'a' + 10;
- } else if ((c >= 'A') && (c <= 'F')) {
- k = c - 'A' + 10;
- } else {
- k = 0; /* paranoia */
- }
+/* decode_hex decodes |in_len| bytes of hex data from |in| and updates |bn|. */
+static int decode_hex(BIGNUM *bn, const char *in, int in_len) {
+ if (in_len > INT_MAX/4) {
+ OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG);
+ return 0;
+ }
+ /* |in_len| is the number of hex digits. */
+ if (bn_expand(bn, in_len * 4) == NULL) {
+ return 0;
+ }
- l = (l << 4) | k;
+ int i = 0;
+ while (in_len > 0) {
+ /* Decode one |BN_ULONG| at a time. */
+ int todo = BN_BYTES * 2;
+ if (todo > in_len) {
+ todo = in_len;
+ }
- if (--m <= 0) {
- bn->d[h++] = l;
- break;
+ BN_ULONG word = 0;
+ int j;
+ for (j = todo; j > 0; j--) {
+ char c = in[in_len - j];
+
+ BN_ULONG hex;
+ if (c >= '0' && c <= '9') {
+ hex = c - '0';
+ } else if (c >= 'a' && c <= 'f') {
+ hex = c - 'a' + 10;
+ } else if (c >= 'A' && c <= 'F') {
+ hex = c - 'A' + 10;
+ } else {
+ hex = 0;
+ /* This shouldn't happen. The caller checks |isxdigit|. */
+ assert(0);
}
+ word = (word << 4) | hex;
}
- j -= (BN_BYTES * 2);
+ bn->d[i++] = word;
+ in_len -= todo;
}
-
- bn->top = h;
+ assert(i <= bn->dmax);
+ bn->top = i;
+ return 1;
}
/* decode_dec decodes |in_len| bytes of decimal data from |in| and updates |bn|. */
-static void decode_dec(BIGNUM *bn, const char *in, int in_len) {
+static int decode_dec(BIGNUM *bn, const char *in, int in_len) {
int i, j;
BN_ULONG l = 0;
+ /* Decode |BN_DEC_NUM| digits at a time. */
j = BN_DEC_NUM - (in_len % BN_DEC_NUM);
if (j == BN_DEC_NUM) {
j = 0;
@@ -277,15 +301,18 @@ static void decode_dec(BIGNUM *bn, const char *in, int in_len) {
l *= 10;
l += in[i] - '0';
if (++j == BN_DEC_NUM) {
- BN_mul_word(bn, BN_DEC_CONV);
- BN_add_word(bn, l);
+ if (!BN_mul_word(bn, BN_DEC_CONV) ||
+ !BN_add_word(bn, l)) {
+ return 0;
+ }
l = 0;
j = 0;
}
}
+ return 1;
}
-typedef void (*decode_func) (BIGNUM *bn, const char *in, int i);
+typedef int (*decode_func) (BIGNUM *bn, const char *in, int in_len);
typedef int (*char_test_func) (int c);
static int bn_x2bn(BIGNUM **outp, const char *in, decode_func decode, char_test_func want_char) {
@@ -302,7 +329,7 @@ static int bn_x2bn(BIGNUM **outp, const char *in, decode_func decode, char_test_
in++;
}
- for (i = 0; want_char((unsigned char)in[i]); i++) {}
+ for (i = 0; want_char((unsigned char)in[i]) && i + neg < INT_MAX; i++) {}
num = i + neg;
if (outp == NULL) {
@@ -320,13 +347,10 @@ static int bn_x2bn(BIGNUM **outp, const char *in, decode_func decode, char_test_
BN_zero(ret);
}
- /* i is the number of hex digests; */
- if (bn_expand(ret, i * 4) == NULL) {
+ if (!decode(ret, in, i)) {
goto err;
}
- decode(ret, in, i);
-
bn_correct_top(ret);
if (!BN_is_zero(ret)) {
ret->neg = neg;
@@ -365,7 +389,7 @@ char *BN_bn2dec(const BIGNUM *a) {
(BN_ULONG *)OPENSSL_malloc((num / BN_DEC_NUM + 1) * sizeof(BN_ULONG));
buf = (char *)OPENSSL_malloc(num + 3);
if ((buf == NULL) || (bn_data == NULL)) {
- OPENSSL_PUT_ERROR(BN, BN_bn2dec, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
goto err;
}
t = BN_dup(a);
@@ -499,3 +523,81 @@ BN_ULONG BN_get_word(const BIGNUM *bn) {
return BN_MASK2;
}
}
+
+size_t BN_bn2mpi(const BIGNUM *in, uint8_t *out) {
+ const size_t bits = BN_num_bits(in);
+ const size_t bytes = (bits + 7) / 8;
+ /* If the number of bits is a multiple of 8, i.e. if the MSB is set,
+ * prefix with a zero byte. */
+ int extend = 0;
+ if (bytes != 0 && (bits & 0x07) == 0) {
+ extend = 1;
+ }
+
+ const size_t len = bytes + extend;
+ if (len < bytes ||
+ 4 + len < len ||
+ (len & 0xffffffff) != len) {
+ /* If we cannot represent the number then we emit zero as the interface
+ * doesn't allow an error to be signalled. */
+ if (out) {
+ memset(out, 0, 4);
+ }
+ return 4;
+ }
+
+ if (out == NULL) {
+ return 4 + len;
+ }
+
+ out[0] = len >> 24;
+ out[1] = len >> 16;
+ out[2] = len >> 8;
+ out[3] = len;
+ if (extend) {
+ out[4] = 0;
+ }
+ BN_bn2bin(in, out + 4 + extend);
+ if (in->neg && len > 0) {
+ out[4] |= 0x80;
+ }
+ return len + 4;
+}
+
+BIGNUM *BN_mpi2bn(const uint8_t *in, size_t len, BIGNUM *out) {
+ if (len < 4) {
+ OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING);
+ return NULL;
+ }
+ const size_t in_len = ((size_t)in[0] << 24) |
+ ((size_t)in[1] << 16) |
+ ((size_t)in[2] << 8) |
+ ((size_t)in[3]);
+ if (in_len != len - 4) {
+ OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING);
+ return NULL;
+ }
+
+ if (out == NULL) {
+ out = BN_new();
+ }
+ if (out == NULL) {
+ OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ if (in_len == 0) {
+ BN_zero(out);
+ return out;
+ }
+
+ in += 4;
+ if (BN_bin2bn(in, in_len, out) == NULL) {
+ return NULL;
+ }
+ out->neg = ((*in) & 0x80) != 0;
+ if (out->neg) {
+ BN_clear_bit(out, BN_num_bits(out) - 1);
+ }
+ return out;
+}
diff --git a/src/crypto/bn/ctx.c b/src/crypto/bn/ctx.c
index 0578376..48d9adf 100644
--- a/src/crypto/bn/ctx.c
+++ b/src/crypto/bn/ctx.c
@@ -124,7 +124,7 @@ struct bignum_ctx {
BN_CTX *BN_CTX_new(void) {
BN_CTX *ret = OPENSSL_malloc(sizeof(BN_CTX));
if (!ret) {
- OPENSSL_PUT_ERROR(BN, BN_CTX_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -153,7 +153,7 @@ void BN_CTX_start(BN_CTX *ctx) {
ctx->err_stack++;
} else if (!BN_STACK_push(&ctx->stack, ctx->used)) {
/* (Try to) get a new frame pointer */
- OPENSSL_PUT_ERROR(BN, BN_CTX_start, BN_R_TOO_MANY_TEMPORARY_VARIABLES);
+ OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_TEMPORARY_VARIABLES);
ctx->err_stack++;
}
}
@@ -169,7 +169,7 @@ BIGNUM *BN_CTX_get(BN_CTX *ctx) {
/* Setting too_many prevents repeated "get" attempts from
* cluttering the error stack. */
ctx->too_many = 1;
- OPENSSL_PUT_ERROR(BN, BN_CTX_get, BN_R_TOO_MANY_TEMPORARY_VARIABLES);
+ OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_TEMPORARY_VARIABLES);
return NULL;
}
diff --git a/src/crypto/bn/div.c b/src/crypto/bn/div.c
index 3588ea1..f9e144a 100644
--- a/src/crypto/bn/div.c
+++ b/src/crypto/bn/div.c
@@ -125,7 +125,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
* so don't just rely on bn_check_top() here */
if ((num->top > 0 && num->d[num->top - 1] == 0) ||
(divisor->top > 0 && divisor->d[divisor->top - 1] == 0)) {
- OPENSSL_PUT_ERROR(BN, BN_div, BN_R_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(BN, BN_R_NOT_INITIALIZED);
return 0;
}
@@ -135,7 +135,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
}
if (BN_is_zero(divisor)) {
- OPENSSL_PUT_ERROR(BN, BN_div, BN_R_DIV_BY_ZERO);
+ OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO);
return 0;
}
@@ -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);
@@ -511,7 +511,7 @@ int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m) {
/* max_shift >= 0 */
if (max_shift < 0) {
- OPENSSL_PUT_ERROR(BN, BN_mod_lshift_quick, BN_R_INPUT_NOT_REDUCED);
+ OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED);
return 0;
}
@@ -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 d3063c9..72a8db4 100644
--- a/src/crypto/bn/exponentiation.c
+++ b/src/crypto/bn/exponentiation.c
@@ -123,6 +123,17 @@
#define RSAZ_ENABLED
#include "rsaz_exp.h"
+
+void bn_mul_mont_gather5(BN_ULONG *rp, const BN_ULONG *ap, const void *table,
+ const BN_ULONG *np, const BN_ULONG *n0, int num,
+ int power);
+void bn_scatter5(const BN_ULONG *inp, size_t num, void *table, size_t power);
+void bn_gather5(BN_ULONG *out, size_t num, void *table, size_t power);
+void bn_power5(BN_ULONG *rp, const BN_ULONG *ap, const void *table,
+ const BN_ULONG *np, const BN_ULONG *n0, int num, int power);
+int bn_from_montgomery(BN_ULONG *rp, const BN_ULONG *ap,
+ const BN_ULONG *not_used, const BN_ULONG *np,
+ const BN_ULONG *n0, int num);
#endif
int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
@@ -131,7 +142,7 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
if ((p->flags & BN_FLG_CONSTTIME) != 0) {
/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
- OPENSSL_PUT_ERROR(BN, BN_exp, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
@@ -173,8 +184,8 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
}
}
- if (r != rr) {
- BN_copy(r, rr);
+ if (r != rr && !BN_copy(r, rr)) {
+ goto err;
}
ret = 1;
@@ -274,10 +285,10 @@ static int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
goto err;
}
- if (BN_ucmp(m, &(recp->N)) < 0) {
+ if (BN_ucmp(m, &recp->N) < 0) {
BN_zero(d);
if (!BN_copy(r, m)) {
- return 0;
+ goto err;
}
BN_CTX_end(ctx);
return 1;
@@ -333,7 +344,7 @@ static int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
j = 0;
while (BN_ucmp(r, &(recp->N)) >= 0) {
if (j++ > 2) {
- OPENSSL_PUT_ERROR(BN, BN_div_recp, BN_R_BAD_RECIPROCAL);
+ OPENSSL_PUT_ERROR(BN, BN_R_BAD_RECIPROCAL);
goto err;
}
if (!BN_usub(r, r, &(recp->N))) {
@@ -427,15 +438,19 @@ static int mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
- OPENSSL_PUT_ERROR(BN, mod_exp_recp, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
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);
@@ -602,27 +617,31 @@ int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
}
int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
- const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) {
+ const BIGNUM *m, BN_CTX *ctx, const BN_MONT_CTX *mont) {
int i, j, bits, ret = 0, wstart, window;
int start = 1;
BIGNUM *d, *r;
const BIGNUM *aa;
/* Table of variables obtained from 'ctx' */
BIGNUM *val[TABLE_SIZE];
- BN_MONT_CTX *mont = NULL;
+ BN_MONT_CTX *new_mont = NULL;
if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
- return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont);
+ return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, mont);
}
if (!BN_is_odd(m)) {
- OPENSSL_PUT_ERROR(BN, BN_mod_exp_mont, BN_R_CALLED_WITH_EVEN_MODULUS);
+ OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
return 0;
}
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);
@@ -633,18 +652,13 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
goto err;
}
- /* If this is not done, things will break in the montgomery part */
-
- if (in_mont != NULL) {
- mont = in_mont;
- } else {
- mont = BN_MONT_CTX_new();
- if (mont == NULL) {
- goto err;
- }
- if (!BN_MONT_CTX_set(mont, m, ctx)) {
+ /* Allocate a montgomery context if it was not supplied by the caller. */
+ if (mont == NULL) {
+ new_mont = BN_MONT_CTX_new();
+ if (new_mont == NULL || !BN_MONT_CTX_set(new_mont, m, ctx)) {
goto err;
}
+ mont = new_mont;
}
if (a->neg || BN_ucmp(a, m) >= 0) {
@@ -763,9 +777,7 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
ret = 1;
err:
- if (in_mont == NULL) {
- BN_MONT_CTX_free(mont);
- }
+ BN_MONT_CTX_free(new_mont);
BN_CTX_end(ctx);
return ret;
}
@@ -851,10 +863,10 @@ static int copy_from_prebuf(BIGNUM *b, int top, unsigned char *buf, int idx,
*/
int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx,
- BN_MONT_CTX *in_mont) {
+ const BN_MONT_CTX *mont) {
int i, bits, ret = 0, window, wvalue;
int top;
- BN_MONT_CTX *mont = NULL;
+ BN_MONT_CTX *new_mont = NULL;
int numPowers;
unsigned char *powerbufFree = NULL;
@@ -862,30 +874,32 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
unsigned char *powerbuf = NULL;
BIGNUM tmp, am;
- top = m->top;
-
- if (!(m->d[0] & 1)) {
- OPENSSL_PUT_ERROR(BN, BN_mod_exp_mont_consttime,
- BN_R_CALLED_WITH_EVEN_MODULUS);
+ if (!BN_is_odd(m)) {
+ OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
return 0;
}
+
+ top = m->top;
+
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);
- /* Allocate a montgomery context if it was not supplied by the caller.
- * If this is not done, things will break in the montgomery part. */
- if (in_mont != NULL) {
- mont = in_mont;
- } else {
- mont = BN_MONT_CTX_new();
- if (mont == NULL || !BN_MONT_CTX_set(mont, m, ctx)) {
+ /* Allocate a montgomery context if it was not supplied by the caller. */
+ if (mont == NULL) {
+ new_mont = BN_MONT_CTX_new();
+ if (new_mont == NULL || !BN_MONT_CTX_set(new_mont, m, ctx)) {
goto err;
}
+ mont = new_mont;
}
#ifdef RSAZ_ENABLED
@@ -926,7 +940,6 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
}
}
#endif
- (void)0;
/* Allocate a buffer large enough to hold all of the pre-computed
* powers of am, am itself and tmp.
@@ -995,20 +1008,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
/* Dedicated window==4 case improves 512-bit RSA sign by ~15%, but as
* 512-bit RSA is hardly relevant, we omit it to spare size... */
if (window == 5 && top > 1) {
- void bn_mul_mont_gather5(BN_ULONG * rp, const BN_ULONG * ap,
- const void * table, const BN_ULONG * np,
- const BN_ULONG * n0, int num, int power);
- void bn_scatter5(const BN_ULONG * inp, size_t num, void * table,
- size_t power);
- void bn_gather5(BN_ULONG * out, size_t num, void * table, size_t power);
- void bn_power5(BN_ULONG * rp, const BN_ULONG * ap, const void * table,
- const BN_ULONG * np, const BN_ULONG * n0, int num,
- int power);
- int bn_from_montgomery(BN_ULONG * rp, const BN_ULONG * ap,
- const BN_ULONG * not_used, const BN_ULONG * np,
- const BN_ULONG * n0, int num);
-
- BN_ULONG *np = mont->N.d, *n0 = mont->n0, *np2;
+ const BN_ULONG *np = mont->N.d, *n0 = mont->n0, *np2;
/* BN_to_montgomery can contaminate words above .top
* [in BN_DEBUG[_DEBUG] build]... */
@@ -1022,9 +1022,11 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
if (top & 7) {
np2 = np;
} else {
- for (np2 = am.d + top, i = 0; i < top; i++) {
- np2[2 * i] = np[i];
+ BN_ULONG *np_double = am.d + top;
+ for (i = 0; i < top; i++) {
+ np_double[2 * i] = np[i];
}
+ np2 = np_double;
}
bn_scatter5(tmp.d, top, powerbuf, 0);
@@ -1189,10 +1191,9 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
goto err;
}
ret = 1;
+
err:
- if (in_mont == NULL) {
- BN_MONT_CTX_free(mont);
- }
+ BN_MONT_CTX_free(new_mont);
if (powerbuf != NULL) {
OPENSSL_cleanse(powerbuf, powerbufLen);
OPENSSL_free(powerbufFree);
@@ -1202,8 +1203,9 @@ err:
}
int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
- const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) {
- BN_MONT_CTX *mont = NULL;
+ const BIGNUM *m, BN_CTX *ctx,
+ const BN_MONT_CTX *mont) {
+ BN_MONT_CTX *new_mont = NULL;
int b, bits, ret = 0;
int r_is_one;
BN_ULONG w, next_w;
@@ -1223,13 +1225,12 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
- OPENSSL_PUT_ERROR(BN, BN_mod_exp_mont_word,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (!BN_is_odd(m)) {
- OPENSSL_PUT_ERROR(BN, BN_mod_exp_mont_word, BN_R_CALLED_WITH_EVEN_MODULUS);
+ OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
return 0;
}
@@ -1241,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);
@@ -1262,13 +1260,13 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
goto err;
}
- if (in_mont != NULL) {
- mont = in_mont;
- } else {
- mont = BN_MONT_CTX_new();
- if (mont == NULL || !BN_MONT_CTX_set(mont, m, ctx)) {
+ /* Allocate a montgomery context if it was not supplied by the caller. */
+ if (mont == NULL) {
+ new_mont = BN_MONT_CTX_new();
+ if (new_mont == NULL || !BN_MONT_CTX_set(new_mont, m, ctx)) {
goto err;
}
+ mont = new_mont;
}
r_is_one = 1; /* except for Montgomery factor */
@@ -1350,9 +1348,7 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
ret = 1;
err:
- if (in_mont == NULL) {
- BN_MONT_CTX_free(mont);
- }
+ BN_MONT_CTX_free(new_mont);
BN_CTX_end(ctx);
return ret;
}
@@ -1361,7 +1357,7 @@ err:
int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m,
- BN_CTX *ctx, BN_MONT_CTX *in_mont) {
+ BN_CTX *ctx, const BN_MONT_CTX *mont) {
int i, j, bits, b, bits1, bits2, ret = 0, wpos1, wpos2, window1, window2,
wvalue1, wvalue2;
int r_is_one = 1;
@@ -1369,10 +1365,10 @@ int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
const BIGNUM *a_mod_m;
/* Tables of variables obtained from 'ctx' */
BIGNUM *val1[TABLE_SIZE], *val2[TABLE_SIZE];
- BN_MONT_CTX *mont = NULL;
+ BN_MONT_CTX *new_mont = NULL;
if (!(m->d[0] & 1)) {
- OPENSSL_PUT_ERROR(BN, BN_mod_exp2_mont, BN_R_CALLED_WITH_EVEN_MODULUS);
+ OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
return 0;
}
bits1 = BN_num_bits(p1);
@@ -1393,16 +1389,13 @@ int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
goto err;
}
- if (in_mont != NULL) {
- mont = in_mont;
- } else {
- mont = BN_MONT_CTX_new();
- if (mont == NULL) {
- goto err;
- }
- if (!BN_MONT_CTX_set(mont, m, ctx)) {
+ /* Allocate a montgomery context if it was not supplied by the caller. */
+ if (mont == NULL) {
+ new_mont = BN_MONT_CTX_new();
+ if (new_mont == NULL || !BN_MONT_CTX_set(new_mont, m, ctx)) {
goto err;
}
+ mont = new_mont;
}
window1 = BN_window_bits_for_exponent_size(bits1);
@@ -1554,9 +1547,7 @@ int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
ret = 1;
err:
- if (in_mont == NULL) {
- BN_MONT_CTX_free(mont);
- }
+ BN_MONT_CTX_free(new_mont);
BN_CTX_end(ctx);
return ret;
}
diff --git a/src/crypto/bn/gcd.c b/src/crypto/bn/gcd.c
index 3132c29..41ca6d2 100644
--- a/src/crypto/bn/gcd.c
+++ b/src/crypto/bn/gcd.c
@@ -223,20 +223,23 @@ err:
}
/* solves ax == 1 (mod n) */
-static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, const BIGNUM *a,
- const BIGNUM *n, BN_CTX *ctx);
+static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, int *out_no_inverse,
+ const BIGNUM *a, const BIGNUM *n,
+ BN_CTX *ctx);
-BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n,
- BN_CTX *ctx) {
+BIGNUM *BN_mod_inverse_ex(BIGNUM *out, int *out_no_inverse, const BIGNUM *a,
+ const BIGNUM *n, BN_CTX *ctx) {
BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
BIGNUM *ret = NULL;
int sign;
if ((a->flags & BN_FLG_CONSTTIME) != 0 ||
(n->flags & BN_FLG_CONSTTIME) != 0) {
- return BN_mod_inverse_no_branch(out, a, n, ctx);
+ return BN_mod_inverse_no_branch(out, out_no_inverse, a, n, ctx);
}
+ *out_no_inverse = 0;
+
BN_CTX_start(ctx);
A = BN_CTX_get(ctx);
B = BN_CTX_get(ctx);
@@ -276,7 +279,7 @@ BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n,
* 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
@@ -522,7 +525,8 @@ BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n,
}
}
} else {
- OPENSSL_PUT_ERROR(BN, BN_mod_inverse, BN_R_NO_INVERSE);
+ *out_no_inverse = 1;
+ OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE);
goto err;
}
ret = R;
@@ -535,16 +539,25 @@ err:
return ret;
}
+BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n,
+ BN_CTX *ctx) {
+ int no_inverse;
+ return BN_mod_inverse_ex(out, &no_inverse, a, n, ctx);
+}
+
/* BN_mod_inverse_no_branch is a special version of BN_mod_inverse.
* It does not contain branches that may leak sensitive information. */
-static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, const BIGNUM *a,
- const BIGNUM *n, BN_CTX *ctx) {
+static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, int *out_no_inverse,
+ const BIGNUM *a, const BIGNUM *n,
+ BN_CTX *ctx) {
BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
BIGNUM local_A, local_B;
BIGNUM *pA, *pB;
BIGNUM *ret = NULL;
int sign;
+ *out_no_inverse = 0;
+
BN_CTX_start(ctx);
A = BN_CTX_get(ctx);
B = BN_CTX_get(ctx);
@@ -682,7 +695,8 @@ static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, const BIGNUM *a,
}
}
} else {
- OPENSSL_PUT_ERROR(BN, BN_mod_inverse_no_branch, BN_R_NO_INVERSE);
+ *out_no_inverse = 1;
+ OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE);
goto err;
}
ret = R;
diff --git a/src/crypto/bn/generic.c b/src/crypto/bn/generic.c
index 0e7d867..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;
@@ -1022,110 +1016,4 @@ void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) {
r[7] = c2;
}
-#if defined(OPENSSL_NO_ASM) || (!defined(OPENSSL_ARM) && !defined(OPENSSL_X86_64))
-/* This is essentially reference implementation, which may or may not
- * result in performance improvement. E.g. on IA-32 this routine was
- * observed to give 40% faster rsa1024 private key operations and 10%
- * faster rsa4096 ones, while on AMD64 it improves rsa1024 sign only
- * by 10% and *worsens* rsa4096 sign by 15%. Once again, it's a
- * reference implementation, one to be used as starting point for
- * platform-specific assembler. Mentioned numbers apply to compiler
- * generated code compiled with and without -DOPENSSL_BN_ASM_MONT and
- * can vary not only from platform to platform, but even for compiler
- * versions. Assembler vs. assembler improvement coefficients can
- * [and are known to] differ and are to be documented elsewhere. */
-int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
- const BN_ULONG *np, const BN_ULONG *n0p, int num) {
- BN_ULONG c0, c1, ml, *tp, n0;
-#ifdef mul64
- BN_ULONG mh;
-#endif
- volatile BN_ULONG *vp;
- int i = 0, j;
-
-#if 0 /* template for platform-specific implementation */
- if (ap==bp) return bn_sqr_mont(rp,ap,np,n0p,num);
-#endif
- vp = tp = alloca((num + 2) * sizeof(BN_ULONG));
-
- n0 = *n0p;
-
- c0 = 0;
- ml = bp[0];
-#ifdef mul64
- mh = HBITS(ml);
- ml = LBITS(ml);
- for (j = 0; j < num; ++j) {
- mul(tp[j], ap[j], ml, mh, c0);
- }
-#else
- for (j = 0; j < num; ++j) {
- mul(tp[j], ap[j], ml, c0);
- }
-#endif
-
- tp[num] = c0;
- tp[num + 1] = 0;
- goto enter;
-
- for (i = 0; i < num; i++) {
- c0 = 0;
- ml = bp[i];
-#ifdef mul64
- mh = HBITS(ml);
- ml = LBITS(ml);
- for (j = 0; j < num; ++j) {
- mul_add(tp[j], ap[j], ml, mh, c0);
- }
-#else
- for (j = 0; j < num; ++j) {
- mul_add(tp[j], ap[j], ml, c0);
- }
-#endif
- c1 = (tp[num] + c0) & BN_MASK2;
- tp[num] = c1;
- tp[num + 1] = (c1 < c0 ? 1 : 0);
- enter:
- c1 = tp[0];
- ml = (c1 * n0) & BN_MASK2;
- c0 = 0;
-#ifdef mul64
- mh = HBITS(ml);
- ml = LBITS(ml);
- mul_add(c1, np[0], ml, mh, c0);
-#else
- mul_add(c1, ml, np[0], c0);
-#endif
- for (j = 1; j < num; j++) {
- c1 = tp[j];
-#ifdef mul64
- mul_add(c1, np[j], ml, mh, c0);
-#else
- mul_add(c1, ml, np[j], c0);
-#endif
- tp[j - 1] = c1 & BN_MASK2;
- }
- c1 = (tp[num] + c0) & BN_MASK2;
- tp[num - 1] = c1;
- tp[num] = tp[num + 1] + (c1 < c0 ? 1 : 0);
- }
-
- if (tp[num] != 0 || tp[num - 1] >= np[num - 1]) {
- c0 = bn_sub_words(rp, tp, np, num);
- if (tp[num] != 0 || c0 == 0) {
- for (i = 0; i < num + 2; i++) {
- vp[i] = 0;
- }
- return 1;
- }
- }
- for (i = 0; i < num; i++) {
- rp[i] = tp[i], vp[i] = 0;
- }
- vp[num] = 0;
- vp[num + 1] = 0;
- return 1;
-}
-#endif
-
#endif
diff --git a/src/crypto/bn/internal.h b/src/crypto/bn/internal.h
index 2674b3c..72ef4e9 100644
--- a/src/crypto/bn/internal.h
+++ b/src/crypto/bn/internal.h
@@ -136,52 +136,49 @@
extern "C" {
#endif
-/* bn_expand acts the same as |BN_wexpand|, but takes a number of bits rather
+/* bn_expand acts the same as |bn_wexpand|, but takes a number of bits rather
* than a number of words. */
-BIGNUM *bn_expand(BIGNUM *bn, unsigned bits);
+BIGNUM *bn_expand(BIGNUM *bn, size_t bits);
#if defined(OPENSSL_64_BIT)
#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, unsigned 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 152cf2d..18da0da 100644
--- a/src/crypto/bn/montgomery.c
+++ b/src/crypto/bn/montgomery.c
@@ -110,6 +110,7 @@
#include <string.h>
+#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/thread.h>
@@ -117,8 +118,9 @@
#include "../internal.h"
-#if !defined(OPENSSL_NO_ASM) && \
- (defined(OPENSSL_X86) || defined(OPENSSL_X86_64))
+#if !defined(OPENSSL_NO_ASM) && \
+ (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \
+ defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))
#define OPENSSL_BN_ASM_MONT
#endif
@@ -129,16 +131,11 @@ BN_MONT_CTX *BN_MONT_CTX_new(void) {
return NULL;
}
- BN_MONT_CTX_init(ret);
- ret->flags = BN_FLG_MALLOCED;
- return ret;
-}
+ memset(ret, 0, sizeof(BN_MONT_CTX));
+ BN_init(&ret->RR);
+ BN_init(&ret->N);
-void BN_MONT_CTX_init(BN_MONT_CTX *mont) {
- memset(mont, 0, sizeof(BN_MONT_CTX));
- BN_init(&mont->RR);
- BN_init(&mont->N);
- BN_init(&mont->Ni);
+ return ret;
}
void BN_MONT_CTX_free(BN_MONT_CTX *mont) {
@@ -148,23 +145,18 @@ void BN_MONT_CTX_free(BN_MONT_CTX *mont) {
BN_free(&mont->RR);
BN_free(&mont->N);
- BN_free(&mont->Ni);
- if (mont->flags & BN_FLG_MALLOCED) {
- OPENSSL_free(mont);
- }
+ OPENSSL_free(mont);
}
-BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from) {
+BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, const BN_MONT_CTX *from) {
if (to == from) {
return to;
}
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;
@@ -176,6 +168,11 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) {
BIGNUM tmod;
BN_ULONG buf[2];
+ if (BN_is_zero(mod)) {
+ OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO);
+ return 0;
+ }
+
BN_CTX_start(ctx);
Ri = BN_CTX_get(ctx);
if (Ri == NULL) {
@@ -192,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
@@ -277,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/bn/mul.c b/src/crypto/bn/mul.c
index a17d766..029a59e 100644
--- a/src/crypto/bn/mul.c
+++ b/src/crypto/bn/mul.c
@@ -666,8 +666,8 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) {
end:
bn_correct_top(rr);
- if (r != rr) {
- BN_copy(r, rr);
+ if (r != rr && !BN_copy(r, rr)) {
+ goto err;
}
ret = 1;
@@ -877,8 +877,8 @@ int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) {
rr->top = max;
}
- if (rr != r) {
- BN_copy(r, rr);
+ if (rr != r && !BN_copy(r, rr)) {
+ goto err;
}
ret = 1;
diff --git a/src/crypto/bn/prime.c b/src/crypto/bn/prime.c
index cf3afcf..d07e609 100644
--- a/src/crypto/bn/prime.c
+++ b/src/crypto/bn/prime.c
@@ -362,11 +362,11 @@ int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add,
if (bits < 2) {
/* There are no prime numbers this small. */
- OPENSSL_PUT_ERROR(BN, BN_generate_prime_ex, BN_R_BITS_TOO_SMALL);
+ OPENSSL_PUT_ERROR(BN, BN_R_BITS_TOO_SMALL);
return 0;
} else if (bits == 2 && safe) {
/* The smallest safe prime (7) is three bits. */
- OPENSSL_PUT_ERROR(BN, BN_generate_prime_ex, BN_R_BITS_TOO_SMALL);
+ OPENSSL_PUT_ERROR(BN, BN_R_BITS_TOO_SMALL);
return 0;
}
@@ -515,11 +515,10 @@ int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
/* A := abs(a) */
if (a->neg) {
- BIGNUM *t;
- if ((t = BN_CTX_get(ctx)) == NULL) {
+ BIGNUM *t = BN_CTX_get(ctx);
+ if (t == NULL || !BN_copy(t, a)) {
goto err;
}
- BN_copy(t, a);
t->neg = 0;
A = t;
} else {
@@ -711,7 +710,7 @@ loop:
if (!BN_add_word(rnd, delta)) {
return 0;
}
- if (BN_num_bits(rnd) != bits) {
+ if (BN_num_bits(rnd) != (unsigned)bits) {
goto again;
}
diff --git a/src/crypto/bn/random.c b/src/crypto/bn/random.c
index 549ac48..3116e54 100644
--- a/src/crypto/bn/random.c
+++ b/src/crypto/bn/random.c
@@ -134,7 +134,7 @@ int BN_rand(BIGNUM *rnd, int bits, int top, int bottom) {
buf = OPENSSL_malloc(bytes);
if (buf == NULL) {
- OPENSSL_PUT_ERROR(BN, BN_rand, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -186,7 +186,7 @@ int BN_rand_range(BIGNUM *r, const BIGNUM *range) {
unsigned count = 100;
if (range->neg || BN_is_zero(range)) {
- OPENSSL_PUT_ERROR(BN, BN_rand_range, BN_R_INVALID_RANGE);
+ OPENSSL_PUT_ERROR(BN, BN_R_INVALID_RANGE);
return 0;
}
@@ -219,7 +219,7 @@ int BN_rand_range(BIGNUM *r, const BIGNUM *range) {
}
if (!--count) {
- OPENSSL_PUT_ERROR(BN, BN_rand_range, BN_R_TOO_MANY_ITERATIONS);
+ OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_ITERATIONS);
return 0;
}
} while (BN_cmp(r, range) >= 0);
@@ -231,7 +231,7 @@ int BN_rand_range(BIGNUM *r, const BIGNUM *range) {
}
if (!--count) {
- OPENSSL_PUT_ERROR(BN, BN_rand_range, BN_R_TOO_MANY_ITERATIONS);
+ OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_ITERATIONS);
return 0;
}
} while (BN_cmp(r, range) >= 0);
@@ -264,13 +264,13 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, const BIGNUM *priv,
}
if (BN_is_zero(range)) {
- OPENSSL_PUT_ERROR(BN, BN_generate_dsa_nonce, BN_R_DIV_BY_ZERO);
+ OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO);
goto err;
}
k_bytes = OPENSSL_malloc(num_k_bytes);
if (!k_bytes) {
- OPENSSL_PUT_ERROR(BN, BN_generate_dsa_nonce, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -281,7 +281,7 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, const BIGNUM *priv,
/* No reasonable DSA or ECDSA key should have a private key
* this large and we don't handle this case in order to avoid
* leaking the length of the private key. */
- OPENSSL_PUT_ERROR(BN, BN_generate_dsa_nonce, BN_R_PRIVATE_KEY_TOO_LARGE);
+ OPENSSL_PUT_ERROR(BN, BN_R_PRIVATE_KEY_TOO_LARGE);
goto err;
}
memcpy(private_bytes, priv->d, todo);
diff --git a/src/crypto/bn/rsaz_exp.h b/src/crypto/bn/rsaz_exp.h
index 0bb6b0c..c752b45 100644
--- a/src/crypto/bn/rsaz_exp.h
+++ b/src/crypto/bn/rsaz_exp.h
@@ -1,32 +1,44 @@
-/******************************************************************************
-* Copyright(c) 2012, Intel Corp.
-* Developers and authors:
-* Shay Gueron (1, 2), and Vlad Krasnov (1)
-* (1) Intel Corporation, Israel Development Center, Haifa, Israel
-* (2) University of Haifa, Israel
+/*****************************************************************************
+* *
+* Copyright (c) 2012, Intel Corporation *
+* *
+* All rights reserved. *
+* *
+* Redistribution and use in source and binary forms, with or without *
+* modification, are permitted provided that the following conditions are *
+* met: *
+* *
+* * Redistributions of source code must retain the above copyright *
+* notice, this list of conditions and the following disclaimer. *
+* *
+* * 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. *
+* *
+* * Neither the name of the Intel Corporation nor the names of its *
+* contributors may be used to endorse or promote products derived from *
+* this software without specific prior written permission. *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""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 INTEL CORPORATION 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. *
+* *
******************************************************************************
-* LICENSE:
-* This submission to OpenSSL is to be made available under the OpenSSL
-* license, and only to the OpenSSL project, in order to allow integration
-* into the publicly distributed code.
-* The use of this code, or portions of this code, or concepts embedded in
-* this code, or modification of this code and/or algorithm(s) in it, or the
-* use of this code for any other purpose than stated above, requires special
-* licensing.
-******************************************************************************
-* DISCLAIMER:
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS AND THE COPYRIGHT OWNERS
-* ``AS IS''. ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS OR THE COPYRIGHT
-* OWNERS 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.
-******************************************************************************/
+* Developers and authors: *
+* Shay Gueron (1, 2), and Vlad Krasnov (1) *
+* (1) Intel Corporation, Israel Development Center, Haifa, Israel *
+* (2) University of Haifa, Israel *
+*****************************************************************************/
#ifndef RSAZ_EXP_H
#define RSAZ_EXP_H
diff --git a/src/crypto/bn/shift.c b/src/crypto/bn/shift.c
index f143996..defec92 100644
--- a/src/crypto/bn/shift.c
+++ b/src/crypto/bn/shift.c
@@ -69,7 +69,7 @@ int BN_lshift(BIGNUM *r, const BIGNUM *a, int n) {
BN_ULONG l;
if (n < 0) {
- OPENSSL_PUT_ERROR(BN, BN_lshift, BN_R_NEGATIVE_NUMBER);
+ OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
return 0;
}
@@ -138,7 +138,7 @@ int BN_rshift(BIGNUM *r, const BIGNUM *a, int n) {
BN_ULONG l, tmp;
if (n < 0) {
- OPENSSL_PUT_ERROR(BN, BN_rshift, BN_R_NEGATIVE_NUMBER);
+ OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
return 0;
}
diff --git a/src/crypto/bn/sqrt.c b/src/crypto/bn/sqrt.c
index e71a818..2ed66c2 100644
--- a/src/crypto/bn/sqrt.c
+++ b/src/crypto/bn/sqrt.c
@@ -86,7 +86,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
return ret;
}
- OPENSSL_PUT_ERROR(BN, BN_mod_sqrt, BN_R_P_IS_NOT_PRIME);
+ OPENSSL_PUT_ERROR(BN, BN_R_P_IS_NOT_PRIME);
return (NULL);
}
@@ -260,7 +260,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
}
if (r == 0) {
/* m divides p */
- OPENSSL_PUT_ERROR(BN, BN_mod_sqrt, BN_R_P_IS_NOT_PRIME);
+ OPENSSL_PUT_ERROR(BN, BN_R_P_IS_NOT_PRIME);
goto end;
}
} while (r == 1 && ++i < 82);
@@ -271,7 +271,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
* Even if p is not prime, we should have found some y
* such that r == -1.
*/
- OPENSSL_PUT_ERROR(BN, BN_mod_sqrt, BN_R_TOO_MANY_ITERATIONS);
+ OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_ITERATIONS);
goto end;
}
@@ -286,7 +286,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
goto end;
}
if (BN_is_one(y)) {
- OPENSSL_PUT_ERROR(BN, BN_mod_sqrt, BN_R_P_IS_NOT_PRIME);
+ OPENSSL_PUT_ERROR(BN, BN_R_P_IS_NOT_PRIME);
goto end;
}
@@ -377,7 +377,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
while (!BN_is_one(t)) {
i++;
if (i == e) {
- OPENSSL_PUT_ERROR(BN, BN_mod_sqrt, BN_R_NOT_A_SQUARE);
+ OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE);
goto end;
}
if (!BN_mod_mul(t, t, t, p, ctx)) {
@@ -413,7 +413,7 @@ vrfy:
}
if (!err && 0 != BN_cmp(x, A)) {
- OPENSSL_PUT_ERROR(BN, BN_mod_sqrt, BN_R_NOT_A_SQUARE);
+ OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE);
err = 1;
}
}
@@ -434,7 +434,7 @@ int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx) {
int ok = 0, last_delta_valid = 0;
if (in->neg) {
- OPENSSL_PUT_ERROR(BN, BN_sqrt, BN_R_NEGATIVE_NUMBER);
+ OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
return 0;
}
if (BN_is_zero(in)) {
@@ -452,7 +452,7 @@ int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx) {
last_delta = BN_CTX_get(ctx);
delta = BN_CTX_get(ctx);
if (estimate == NULL || tmp == NULL || last_delta == NULL || delta == NULL) {
- OPENSSL_PUT_ERROR(BN, BN_sqrt, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -470,7 +470,7 @@ int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx) {
!BN_sqr(tmp, estimate, ctx) ||
/* |delta| = |in| - |tmp| */
!BN_sub(delta, in, tmp)) {
- OPENSSL_PUT_ERROR(BN, BN_sqrt, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(BN, ERR_R_BN_LIB);
goto err;
}
@@ -490,15 +490,15 @@ int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx) {
}
if (BN_cmp(tmp, in) != 0) {
- OPENSSL_PUT_ERROR(BN, BN_sqrt, BN_R_NOT_A_SQUARE);
+ OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE);
goto err;
}
ok = 1;
err:
- if (ok && out_sqrt == in) {
- BN_copy(out_sqrt, estimate);
+ if (ok && out_sqrt == in && !BN_copy(out_sqrt, estimate)) {
+ ok = 0;
}
BN_CTX_end(ctx);
return ok;
diff --git a/src/crypto/buf/CMakeLists.txt b/src/crypto/buf/CMakeLists.txt
index 19edf7d..63f1025 100644
--- a/src/crypto/buf/CMakeLists.txt
+++ b/src/crypto/buf/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
buf
diff --git a/src/crypto/buf/buf.c b/src/crypto/buf/buf.c
index 5769e77..b918f01 100644
--- a/src/crypto/buf/buf.c
+++ b/src/crypto/buf/buf.c
@@ -67,7 +67,7 @@ BUF_MEM *BUF_MEM_new(void) {
ret = OPENSSL_malloc(sizeof(BUF_MEM));
if (ret == NULL) {
- OPENSSL_PUT_ERROR(BUF, BUF_MEM_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -105,14 +105,14 @@ static size_t buf_mem_grow(BUF_MEM *buf, size_t len, char clean) {
n = len + 3;
if (n < len) {
/* overflow */
- OPENSSL_PUT_ERROR(BUF, buf_mem_grow, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
return 0;
}
n = n / 3;
alloc_size = n * 4;
if (alloc_size / 4 != n) {
/* overflow */
- OPENSSL_PUT_ERROR(BUF, buf_mem_grow, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -127,7 +127,7 @@ static size_t buf_mem_grow(BUF_MEM *buf, size_t len, char clean) {
}
if (new_buf == NULL) {
- OPENSSL_PUT_ERROR(BUF, buf_mem_grow, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
len = 0;
} else {
buf->data = new_buf;
@@ -180,12 +180,12 @@ char *BUF_strndup(const char *buf, size_t size) {
alloc_size = size + 1;
if (alloc_size < size) {
/* overflow */
- OPENSSL_PUT_ERROR(BUF, BUF_strndup, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
return NULL;
}
ret = OPENSSL_malloc(alloc_size);
if (ret == NULL) {
- OPENSSL_PUT_ERROR(BUF, BUF_strndup, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -220,13 +220,13 @@ size_t BUF_strlcat(char *dst, const char *src, size_t dst_size) {
void *BUF_memdup(const void *data, size_t dst_size) {
void *ret;
- if (data == NULL) {
+ if (dst_size == 0) {
return NULL;
}
ret = OPENSSL_malloc(dst_size);
if (ret == NULL) {
- OPENSSL_PUT_ERROR(BUF, BUF_memdup, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
return NULL;
}
diff --git a/src/crypto/bytestring/CMakeLists.txt b/src/crypto/bytestring/CMakeLists.txt
index cbbacf2..33d3c21 100644
--- a/src/crypto/bytestring/CMakeLists.txt
+++ b/src/crypto/bytestring/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
bytestring
@@ -19,3 +19,4 @@ add_executable(
)
target_link_libraries(bytestring_test crypto)
+add_dependencies(all_tests bytestring_test)
diff --git a/src/crypto/bytestring/ber.c b/src/crypto/bytestring/ber.c
index e3b150c..9e8daaa 100644
--- a/src/crypto/bytestring/ber.c
+++ b/src/crypto/bytestring/ber.c
@@ -119,7 +119,7 @@ static int cbs_convert_ber(CBS *in, CBB *out, char squash_header,
char squash_child_headers = is_primitive_type(tag);
/* This is a hack, but it sufficies to handle NSS's output. If we find
- * an indefinite length, context-specific tag with a definite, primtive
+ * an indefinite length, context-specific tag with a definite, primitive
* tag inside it, then we assume that the context-specific tag is
* implicit and the tags within are fragments of a primitive type that
* need to be concatenated. */
diff --git a/src/crypto/bytestring/bytestring_test.cc b/src/crypto/bytestring/bytestring_test.cc
index 66e9c1e..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"
@@ -109,7 +112,7 @@ static bool TestGetASN1() {
static const uint8_t kData2[] = {0x30, 3, 1, 2};
static const uint8_t kData3[] = {0x30, 0x80};
static const uint8_t kData4[] = {0x30, 0x81, 1, 1};
- static const uint8_t kData5[] = {0x30, 0x82, 0, 1, 1};
+ static const uint8_t kData5[4 + 0x80] = {0x30, 0x82, 0, 0x80};
static const uint8_t kData6[] = {0xa1, 3, 0x4, 1, 1};
static const uint8_t kData7[] = {0xa1, 3, 0x4, 2, 1};
static const uint8_t kData8[] = {0xa1, 3, 0x2, 1, 1};
@@ -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) ||
@@ -365,6 +370,55 @@ static bool TestCBBPrefixed() {
return buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
}
+static bool TestCBBDiscardChild() {
+ ScopedCBB cbb;
+ CBB contents, inner_contents, inner_inner_contents;
+
+ if (!CBB_init(cbb.get(), 0) ||
+ !CBB_add_u8(cbb.get(), 0xaa)) {
+ return false;
+ }
+
+ // Discarding |cbb|'s children preserves the byte written.
+ CBB_discard_child(cbb.get());
+
+ if (!CBB_add_u8_length_prefixed(cbb.get(), &contents) ||
+ !CBB_add_u8_length_prefixed(cbb.get(), &contents) ||
+ !CBB_add_u8(&contents, 0xbb) ||
+ !CBB_add_u16_length_prefixed(cbb.get(), &contents) ||
+ !CBB_add_u16(&contents, 0xcccc) ||
+ !CBB_add_u24_length_prefixed(cbb.get(), &contents) ||
+ !CBB_add_u24(&contents, 0xdddddd) ||
+ !CBB_add_u8_length_prefixed(cbb.get(), &contents) ||
+ !CBB_add_u8(&contents, 0xff) ||
+ !CBB_add_u8_length_prefixed(&contents, &inner_contents) ||
+ !CBB_add_u8(&inner_contents, 0x42) ||
+ !CBB_add_u16_length_prefixed(&inner_contents, &inner_inner_contents) ||
+ !CBB_add_u8(&inner_inner_contents, 0x99)) {
+ return false;
+ }
+
+ // Discard everything from |inner_contents| down.
+ CBB_discard_child(&contents);
+
+ uint8_t *buf;
+ size_t buf_len;
+ if (!CBB_finish(cbb.get(), &buf, &buf_len)) {
+ return false;
+ }
+ ScopedOpenSSLBytes scoper(buf);
+
+ static const uint8_t kExpected[] = {
+ 0xaa,
+ 0,
+ 1, 0xbb,
+ 0, 2, 0xcc, 0xcc,
+ 0, 0, 3, 0xdd, 0xdd, 0xdd,
+ 1, 0xff,
+ };
+ return buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
+}
+
static bool TestCBBMisuse() {
CBB cbb, child, contents;
uint8_t *buf;
@@ -434,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;
@@ -443,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;
}
@@ -451,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;
@@ -460,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;
}
@@ -469,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;
@@ -478,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;
}
@@ -578,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},
};
@@ -649,6 +703,34 @@ static bool TestASN1Uint64() {
return true;
}
+static bool TestZero() {
+ CBB cbb;
+ CBB_zero(&cbb);
+ // Calling |CBB_cleanup| on a zero-state |CBB| must not crash.
+ CBB_cleanup(&cbb);
+ 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) {
CRYPTO_library_init();
@@ -662,10 +744,13 @@ int main(void) {
!TestCBBFinishChild() ||
!TestCBBMisuse() ||
!TestCBBPrefixed() ||
+ !TestCBBDiscardChild() ||
!TestCBBASN1() ||
!TestBerConvert() ||
!TestASN1Uint64() ||
- !TestGetOptionalASN1Bool()) {
+ !TestGetOptionalASN1Bool() ||
+ !TestZero() ||
+ !TestCBBReserve()) {
return 1;
}
diff --git a/src/crypto/bytestring/cbb.c b/src/crypto/bytestring/cbb.c
index f1e09a2..8fc5187 100644
--- a/src/crypto/bytestring/cbb.c
+++ b/src/crypto/bytestring/cbb.c
@@ -20,7 +20,12 @@
#include <openssl/mem.h>
+void CBB_zero(CBB *cbb) {
+ memset(cbb, 0, sizeof(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));
@@ -33,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;
}
@@ -56,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;
}
@@ -66,6 +72,10 @@ int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len) {
void CBB_cleanup(CBB *cbb) {
if (cbb->base) {
+ /* Only top-level |CBB|s are cleaned up. Child |CBB|s are non-owning. They
+ * are implicitly discarded when the parent is flushed or cleaned up. */
+ assert(cbb->is_top_level);
+
if (cbb->base->can_resize) {
OPENSSL_free(cbb->base->buf);
}
@@ -74,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) {
@@ -111,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;
}
@@ -169,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. */
@@ -222,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) {
@@ -236,13 +257,21 @@ 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 - cbb->offset - cbb->pending_len_len;
+}
static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents,
size_t len_len) {
@@ -252,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;
}
@@ -261,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;
}
@@ -290,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;
}
@@ -298,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;
}
@@ -323,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;
@@ -347,6 +397,17 @@ int CBB_add_u24(CBB *cbb, uint32_t value) {
return cbb_buffer_add_u(cbb->base, value, 3);
}
+void CBB_discard_child(CBB *cbb) {
+ if (cbb->child == NULL) {
+ return;
+ }
+
+ cbb->base->len = cbb->child->offset;
+
+ cbb->child->base = NULL;
+ cbb->child = NULL;
+}
+
int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) {
CBB child;
size_t i;
diff --git a/src/crypto/bytestring/cbs.c b/src/crypto/bytestring/cbs.c
index b8caedd..5e0c538 100644
--- a/src/crypto/bytestring/cbs.c
+++ b/src/crypto/bytestring/cbs.c
@@ -137,6 +137,15 @@ int CBS_get_bytes(CBS *cbs, CBS *out, size_t len) {
return 1;
}
+int CBS_copy_bytes(CBS *cbs, uint8_t *out, size_t len) {
+ const uint8_t *v;
+ if (!cbs_get(cbs, &v, len)) {
+ return 0;
+ }
+ memcpy(out, v, len);
+ return 1;
+}
+
static int cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len) {
uint32_t len;
if (!cbs_get_u(cbs, &len, len_len)) {
@@ -320,14 +329,19 @@ int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out) {
}
int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned tag) {
+ int present = 0;
+
if (CBS_peek_asn1_tag(cbs, tag)) {
if (!CBS_get_asn1(cbs, out, tag)) {
return 0;
}
- *out_present = 1;
- } else {
- *out_present = 0;
+ present = 1;
+ }
+
+ if (out_present != NULL) {
+ *out_present = present;
}
+
return 1;
}
diff --git a/src/crypto/bytestring/internal.h b/src/crypto/bytestring/internal.h
index 391ad19..b4ea7e5 100644
--- a/src/crypto/bytestring/internal.h
+++ b/src/crypto/bytestring/internal.h
@@ -38,14 +38,6 @@ extern "C" {
* It returns one on success and zero otherwise. */
OPENSSL_EXPORT int CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len);
-/* CBS_get_any_ber_asn1_element acts the same as |CBS_get_any_asn1_element| but
- * also allows indefinite-length elements to be returned. In that case,
- * |*out_header_len| and |CBS_len(out)| will both be two as only the header is
- * returned. */
-OPENSSL_EXPORT int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out,
- unsigned *out_tag,
- size_t *out_header_len);
-
#if defined(__cplusplus)
} /* extern C */
diff --git a/src/crypto/chacha/CMakeLists.txt b/src/crypto/chacha/CMakeLists.txt
index 6c3f87e..266e869 100644
--- a/src/crypto/chacha/CMakeLists.txt
+++ b/src/crypto/chacha/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
if (${ARCH} STREQUAL "arm")
set(
diff --git a/src/crypto/chacha/chacha_generic.c b/src/crypto/chacha/chacha_generic.c
index 31cf4f0..f262033 100644
--- a/src/crypto/chacha/chacha_generic.c
+++ b/src/crypto/chacha/chacha_generic.c
@@ -54,8 +54,8 @@ static const uint8_t sigma[16] = { 'e', 'x', 'p', 'a', 'n', 'd', ' ', '3',
#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM)
/* Defined in chacha_vec.c */
void CRYPTO_chacha_20_neon(uint8_t *out, const uint8_t *in, size_t in_len,
- const uint8_t key[32], const uint8_t nonce[8],
- size_t counter);
+ const uint8_t key[32], const uint8_t nonce[12],
+ uint32_t counter);
#endif
/* chacha_core performs 20 rounds of ChaCha on the input words in
@@ -85,8 +85,8 @@ static void chacha_core(uint8_t output[64], const uint32_t input[16]) {
}
void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len,
- const uint8_t key[32], const uint8_t nonce[8],
- size_t counter) {
+ const uint8_t key[32], const uint8_t nonce[12],
+ uint32_t counter) {
uint32_t input[16];
uint8_t buf[64];
size_t todo, i;
@@ -114,9 +114,9 @@ void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len,
input[11] = U8TO32_LITTLE(key + 28);
input[12] = counter;
- input[13] = ((uint64_t)counter) >> 32;
- input[14] = U8TO32_LITTLE(nonce + 0);
- input[15] = U8TO32_LITTLE(nonce + 4);
+ input[13] = U8TO32_LITTLE(nonce + 0);
+ input[14] = U8TO32_LITTLE(nonce + 4);
+ input[15] = U8TO32_LITTLE(nonce + 8);
while (in_len > 0) {
todo = sizeof(buf);
@@ -134,9 +134,6 @@ void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len,
in_len -= todo;
input[12]++;
- if (input[12] == 0) {
- input[13]++;
- }
}
}
diff --git a/src/crypto/chacha/chacha_vec.c b/src/crypto/chacha/chacha_vec.c
index 14b54a7..addbaa3 100644
--- a/src/crypto/chacha/chacha_vec.c
+++ b/src/crypto/chacha/chacha_vec.c
@@ -154,12 +154,12 @@ void CRYPTO_chacha_20(
const uint8_t *in,
size_t inlen,
const uint8_t key[32],
- const uint8_t nonce[8],
- size_t counter)
+ const uint8_t nonce[12],
+ uint32_t counter)
{
unsigned iters, i, *op=(unsigned *)out, *ip=(unsigned *)in, *kp;
#if defined(__ARM_NEON__)
- uint32_t np[2];
+ uint32_t np[3];
uint8_t alignment_buffer[16] __attribute__((aligned(16)));
#endif
vec s0, s1, s2, s3;
@@ -167,20 +167,16 @@ void CRYPTO_chacha_20(
{0x61707865,0x3320646E,0x79622D32,0x6B206574};
kp = (unsigned *)key;
#if defined(__ARM_NEON__)
- memcpy(np, nonce, 8);
+ memcpy(np, nonce, 12);
#endif
s0 = LOAD_ALIGNED(chacha_const);
s1 = LOAD(&((vec*)kp)[0]);
s2 = LOAD(&((vec*)kp)[1]);
s3 = (vec){
- counter & 0xffffffff,
-#if __ARM_NEON__ || defined(OPENSSL_X86)
- 0, /* can't right-shift 32 bits on a 32-bit system. */
-#else
- counter >> 32,
-#endif
+ counter,
((uint32_t*)nonce)[0],
- ((uint32_t*)nonce)[1]
+ ((uint32_t*)nonce)[1],
+ ((uint32_t*)nonce)[2]
};
for (iters = 0; iters < inlen/(BPI*64); iters++)
@@ -212,8 +208,8 @@ void CRYPTO_chacha_20(
x2 = chacha_const[2]; x3 = chacha_const[3];
x4 = kp[0]; x5 = kp[1]; x6 = kp[2]; x7 = kp[3];
x8 = kp[4]; x9 = kp[5]; x10 = kp[6]; x11 = kp[7];
- x12 = counter+BPI*iters+(BPI-1); x13 = 0;
- x14 = np[0]; x15 = np[1];
+ x12 = counter+BPI*iters+(BPI-1); x13 = np[0];
+ x14 = np[1]; x15 = np[2];
#endif
for (i = CHACHA_RNDS/2; i; i--)
{
@@ -265,9 +261,9 @@ void CRYPTO_chacha_20(
op[10] = REVW_BE(REVW_BE(ip[10]) ^ (x10 + kp[6]));
op[11] = REVW_BE(REVW_BE(ip[11]) ^ (x11 + kp[7]));
op[12] = REVW_BE(REVW_BE(ip[12]) ^ (x12 + counter+BPI*iters+(BPI-1)));
- op[13] = REVW_BE(REVW_BE(ip[13]) ^ (x13));
- op[14] = REVW_BE(REVW_BE(ip[14]) ^ (x14 + np[0]));
- op[15] = REVW_BE(REVW_BE(ip[15]) ^ (x15 + np[1]));
+ op[13] = REVW_BE(REVW_BE(ip[13]) ^ (x13 + np[0]));
+ op[14] = REVW_BE(REVW_BE(ip[14]) ^ (x14 + np[1]));
+ op[15] = REVW_BE(REVW_BE(ip[15]) ^ (x15 + np[2]));
s3 += ONE;
ip += 16;
op += 16;
diff --git a/src/crypto/chacha/chacha_vec_arm.S b/src/crypto/chacha/chacha_vec_arm.S
index ddc374e..f18c867 100644
--- a/src/crypto/chacha/chacha_vec_arm.S
+++ b/src/crypto/chacha/chacha_vec_arm.S
@@ -23,6 +23,7 @@
# /opt/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc -O3 -mcpu=cortex-a8 -mfpu=neon -fpic -DASM_GEN -I ../../include -S chacha_vec.c -o -
#if !defined(OPENSSL_NO_ASM)
+#if defined(__arm__)
.syntax unified
.cpu cortex-a8
@@ -59,137 +60,138 @@
.thumb_func
.type CRYPTO_chacha_20_neon, %function
CRYPTO_chacha_20_neon:
- @ args = 8, pretend = 0, frame = 152
+ @ args = 8, pretend = 0, frame = 160
@ frame_needed = 1, uses_anonymous_args = 0
push {r4, r5, r6, r7, r8, r9, r10, fp, lr}
- mov r8, r3
+ mov r9, r3
vpush.64 {d8, d9, d10, d11, d12, d13, d14, d15}
- mov r9, r2
+ mov r10, r2
ldr r4, .L91+16
- mov fp, r0
- mov r10, r1
- mov lr, r8
+ mov fp, r1
+ mov r8, r9
.LPIC16:
add r4, pc
- sub sp, sp, #156
+ sub sp, sp, #164
add r7, sp, #0
sub sp, sp, #112
- add r6, r7, #144
- str r0, [r7, #88]
+ add lr, r7, #148
+ str r0, [r7, #80]
str r1, [r7, #12]
str r2, [r7, #8]
ldmia r4, {r0, r1, r2, r3}
add r4, sp, #15
bic r4, r4, #15
- ldr ip, [r7, #256]
- str r4, [r7, #84]
+ ldr r6, [r7, #264]
+ str r4, [r7, #88]
mov r5, r4
adds r4, r4, #64
- adds r5, r5, #80
- str r8, [r7, #68]
+ add ip, r5, #80
+ str r9, [r7, #56]
stmia r4, {r0, r1, r2, r3}
movw r4, #43691
- ldr r0, [ip] @ unaligned
+ ldr r0, [r6] @ unaligned
movt r4, 43690
- ldr r1, [ip, #4] @ unaligned
- ldr r3, [r7, #84]
- ldr r2, [r8, #8] @ unaligned
- mov r8, #0
- stmia r6!, {r0, r1}
- mov r6, r5
- ldr r1, [lr, #4] @ unaligned
- ldr r0, [lr] @ unaligned
- vldr d24, [r3, #64]
- vldr d25, [r3, #72]
- ldr r3, [lr, #12] @ unaligned
- str r5, [r7, #80]
- stmia r5!, {r0, r1, r2, r3}
- ldr r0, [lr, #16]! @ unaligned
- ldr r2, [r7, #84]
- umull r4, r5, r9, r4
+ ldr r1, [r6, #4] @ unaligned
+ ldr r2, [r6, #8] @ unaligned
+ ldr r3, [r9, #12] @ unaligned
+ str ip, [r7, #84]
+ stmia lr!, {r0, r1, r2}
+ mov lr, ip
+ ldr r1, [r9, #4] @ unaligned
+ ldr r2, [r9, #8] @ unaligned
+ ldr r0, [r9] @ unaligned
+ vldr d24, [r5, #64]
+ vldr d25, [r5, #72]
+ umull r4, r5, r10, r4
+ stmia ip!, {r0, r1, r2, r3}
+ ldr r0, [r8, #16]! @ unaligned
+ ldr r2, [r7, #88]
+ ldr r4, [r7, #268]
+ ldr r1, [r8, #4] @ unaligned
vldr d26, [r2, #80]
vldr d27, [r2, #88]
- ldr r1, [lr, #4] @ unaligned
- ldr r2, [lr, #8] @ unaligned
- ldr r3, [lr, #12] @ unaligned
- ldr r4, [r7, #260]
- stmia r6!, {r0, r1, r2, r3}
- ldr r3, [ip]
- ldr r1, [r7, #84]
- ldr r2, [ip, #4]
- str r3, [r7, #64]
- vldr d28, [r1, #80]
- vldr d29, [r1, #88]
- str r3, [r7, #136]
+ ldr r3, [r8, #12] @ unaligned
+ ldr r2, [r8, #8] @ unaligned
+ stmia lr!, {r0, r1, r2, r3}
+ ldr r3, [r6]
+ ldr r1, [r6, #4]
+ ldr r6, [r6, #8]
+ str r3, [r7, #68]
+ str r3, [r7, #132]
lsrs r3, r5, #7
+ str r6, [r7, #140]
+ str r6, [r7, #60]
+ ldr r6, [r7, #88]
str r4, [r7, #128]
- str r2, [r7, #140]
- str r8, [r7, #132]
- str r2, [r7, #60]
+ str r1, [r7, #136]
+ str r1, [r7, #64]
+ vldr d28, [r6, #80]
+ vldr d29, [r6, #88]
vldr d22, [r7, #128]
vldr d23, [r7, #136]
beq .L26
+ mov r5, r6
lsls r2, r3, #8
- ldr r5, [r1, #64]
sub r3, r2, r3, lsl #6
- ldr r2, [r1, #68]
+ ldr r2, [r5, #68]
+ ldr r6, [r6, #64]
vldr d0, .L91
vldr d1, .L91+8
- adds r4, r4, #2
- str r5, [r7, #56]
- str r2, [r7, #52]
- ldr r5, [r1, #72]
- ldr r2, [r1, #76]
+ str r2, [r7, #48]
+ ldr r2, [r5, #72]
str r3, [r7, #4]
- str r5, [r7, #48]
+ str r6, [r7, #52]
str r2, [r7, #44]
- mov r2, fp
- str r4, [r7, #72]
+ adds r2, r4, #2
+ str r2, [r7, #72]
+ ldr r2, [r5, #76]
+ str fp, [r7, #76]
+ str r2, [r7, #40]
+ ldr r2, [r7, #80]
adds r3, r2, r3
- str r10, [r7, #76]
str r3, [r7, #16]
.L4:
- ldr r5, [r7, #68]
- add r8, r7, #44
- ldr r4, [r7, #72]
+ ldr r5, [r7, #56]
+ add r8, r7, #40
+ ldr r4, [r7, #68]
vadd.i32 q3, q11, q0
ldmia r8, {r8, r9, r10, fp}
- vmov q8, q14 @ v4si
+ mov r1, r5
ldr r2, [r5, #4]
- vmov q1, q13 @ v4si
+ vmov q8, q14 @ v4si
ldr r3, [r5]
+ vmov q1, q13 @ v4si
+ ldr r6, [r1, #28]
vmov q9, q12 @ v4si
- ldr lr, [r5, #20]
- vmov q2, q11 @ v4si
mov r0, r2
ldr r2, [r5, #8]
- str r3, [r7, #108]
- mov r3, r5
- ldr ip, [r5, #16]
+ str r4, [r7, #112]
+ movs r1, #10
+ ldr r4, [r7, #72]
+ vmov q2, q11 @ v4si
+ ldr lr, [r5, #20]
vmov q15, q14 @ v4si
- mov r1, r2
- ldr r2, [r5, #12]
- ldr r5, [r5, #24]
+ str r3, [r7, #108]
vmov q5, q13 @ v4si
- ldr r6, [r3, #28]
+ str r2, [r7, #116]
vmov q10, q12 @ v4si
+ ldr r2, [r5, #12]
+ ldr ip, [r5, #16]
ldr r3, [r7, #64]
- str r5, [r7, #116]
- movs r5, #10
+ ldr r5, [r5, #24]
str r6, [r7, #120]
- str r4, [r7, #112]
+ str r1, [r7, #92]
ldr r6, [r7, #60]
+ str r4, [r7, #100]
+ ldr r1, [r7, #116]
+ ldr r4, [r7, #108]
str r8, [r7, #96]
mov r8, r10
- ldr r4, [r7, #108]
- mov r10, r9
- ldr r9, [r7, #116]
str lr, [r7, #104]
+ mov r10, r9
mov lr, r3
- str r5, [r7, #92]
- movs r5, #0
+ mov r9, r5
str r6, [r7, #124]
- str r5, [r7, #100]
b .L92
.L93:
.align 3
@@ -212,25 +214,24 @@ CRYPTO_chacha_20_neon:
str r5, [r7, #116]
add r10, r10, r1
vrev32.16 q3, q3
- eor lr, lr, r10
+ str r6, [r7, #108]
vadd.i32 q8, q8, q3
vrev32.16 q2, q2
vadd.i32 q15, q15, q2
mov fp, r3
- ldr r3, [r7, #112]
+ ldr r3, [r7, #100]
veor q4, q8, q1
- str r6, [r7, #112]
veor q6, q15, q5
+ add fp, fp, r2
eors r3, r3, r5
mov r5, r6
- ldr r6, [r7, #100]
+ ldr r6, [r7, #112]
vshl.i32 q1, q4, #12
vshl.i32 q5, q6, #12
- add fp, fp, r2
- eors r6, r6, r5
ror r3, r3, #16
+ eors r6, r6, r5
+ eor lr, lr, r10
vsri.32 q1, q4, #20
- ror lr, lr, #16
mov r5, r6
ldr r6, [r7, #124]
vsri.32 q5, q6, #20
@@ -238,25 +239,26 @@ CRYPTO_chacha_20_neon:
eor r6, r6, fp
ror r5, r5, #16
vadd.i32 q9, q9, q1
- add r9, r9, lr
+ ror lr, lr, #16
ror r3, r6, #16
ldr r6, [r7, #124]
vadd.i32 q10, q10, q5
- str r3, [r7, #108]
+ add r9, r9, lr
veor q4, q9, q3
add ip, ip, r6
ldr r6, [r7, #104]
veor q6, q10, q2
eor r4, ip, r4
- eor r1, r9, r1
+ str r3, [r7, #104]
vshl.i32 q3, q4, #8
+ eor r1, r9, r1
mov r8, r6
ldr r6, [r7, #120]
vshl.i32 q2, q6, #8
ror r4, r4, #20
add r6, r6, r3
vsri.32 q3, q4, #24
- str r6, [r7, #104]
+ str r6, [r7, #100]
eors r2, r2, r6
ldr r6, [r7, #116]
vsri.32 q2, q6, #24
@@ -267,7 +269,7 @@ CRYPTO_chacha_20_neon:
eor r0, r8, r0
vadd.i32 q15, q15, q2
mov r3, r6
- ldr r6, [r7, #112]
+ ldr r6, [r7, #108]
veor q6, q4, q1
ror r0, r0, #20
str r3, [r7, #112]
@@ -284,7 +286,7 @@ CRYPTO_chacha_20_neon:
ror r1, r1, #20
eors r5, r5, r6
vsri.32 q8, q6, #25
- ldr r6, [r7, #108]
+ ldr r6, [r7, #104]
ror r3, r3, #24
ror r5, r5, #24
vsri.32 q1, q5, #25
@@ -296,7 +298,7 @@ CRYPTO_chacha_20_neon:
vext.32 q8, q8, q8, #1
str ip, [r7, #124]
add ip, r5, r8
- ldr r5, [r7, #104]
+ ldr r5, [r7, #100]
eor lr, r10, lr
ror r6, r6, #24
vext.32 q1, q1, q1, #1
@@ -409,7 +411,7 @@ CRYPTO_chacha_20_neon:
veor q6, q15, q1
ldr r3, [r7, #116]
vshl.i32 q1, q4, #7
- str r2, [r7, #112]
+ str r2, [r7, #100]
add r3, r3, r2
str r3, [r7, #120]
vshl.i32 q5, q6, #7
@@ -422,7 +424,7 @@ CRYPTO_chacha_20_neon:
vsri.32 q5, q6, #25
ldr r3, [r7, #92]
ror r4, r4, #25
- str r6, [r7, #100]
+ str r6, [r7, #112]
ror r0, r0, #25
subs r3, r3, #1
str r5, [r7, #104]
@@ -436,308 +438,325 @@ CRYPTO_chacha_20_neon:
vext.32 q5, q5, q5, #3
vext.32 q1, q1, q1, #3
bne .L3
- ldr r3, [r7, #80]
+ ldr r3, [r7, #84]
vadd.i32 q4, q12, q10
- str r9, [r7, #116]
+ str r9, [r7, #92]
mov r9, r10
mov r10, r8
ldr r8, [r7, #96]
str lr, [r7, #96]
mov lr, r5
- ldr r5, [r7, #56]
+ ldr r5, [r7, #52]
vadd.i32 q5, q13, q5
ldr r6, [r7, #76]
vadd.i32 q15, q14, q15
add fp, fp, r5
- ldr r5, [r7, #52]
- str r4, [r7, #108]
+ ldr r5, [r7, #48]
+ str r3, [r7, #104]
vadd.i32 q7, q14, q8
- ldr r4, [r7, #112]
- add r5, r10, r5
- str r3, [r7, #112]
- vadd.i32 q2, q11, q2
ldr r3, [r6, #12] @ unaligned
+ add r10, r10, r5
+ str r0, [r7, #36]
+ vadd.i32 q2, q11, q2
+ ldr r0, [r6] @ unaligned
vadd.i32 q6, q12, q9
- str r0, [r7, #92]
+ ldr r5, [r7, #104]
vadd.i32 q1, q13, q1
- ldr r0, [r6] @ unaligned
+ str r1, [r7, #116]
vadd.i32 q11, q11, q0
- str r1, [r7, #40]
- str r2, [r7, #36]
- vadd.i32 q3, q11, q3
ldr r1, [r6, #4] @ unaligned
- vadd.i32 q11, q11, q0
+ str r2, [r7, #32]
+ vadd.i32 q3, q11, q3
ldr r2, [r6, #8] @ unaligned
- str r5, [r7, #104]
vadd.i32 q11, q11, q0
- ldr r5, [r7, #112]
- ldr r10, [r7, #80]
+ str r4, [r7, #108]
+ ldr r4, [r7, #100]
+ vadd.i32 q11, q11, q0
stmia r5!, {r0, r1, r2, r3}
- mov r5, r10
- ldr r0, [r7, #84]
- ldr r2, [r7, #48]
- ldr r3, [r7, #72]
- vldr d20, [r0, #80]
- vldr d21, [r0, #88]
- add r9, r9, r2
+ ldr r2, [r7, #88]
+ ldr r3, [r7, #44]
+ ldr r5, [r7, #84]
+ vldr d20, [r2, #80]
+ vldr d21, [r2, #88]
+ add r3, r9, r3
+ str r3, [r7, #104]
veor q10, q10, q4
- ldr r2, [r7, #44]
+ ldr r3, [r7, #40]
+ add r3, r8, r3
+ str r3, [r7, #100]
+ ldr r3, [r7, #72]
+ vstr d20, [r2, #80]
+ vstr d21, [r2, #88]
adds r1, r4, r3
str r1, [r7, #28]
- add r2, r8, r2
- str r2, [r7, #32]
- vstr d20, [r0, #80]
- vstr d21, [r0, #88]
ldmia r5!, {r0, r1, r2, r3}
+ ldr r4, [r7, #68]
+ ldr r5, [r7, #112]
+ ldr r8, [r7, #84]
+ add r5, r5, r4
ldr r4, [r7, #96]
+ str r5, [r7, #24]
ldr r5, [r7, #64]
add r4, r4, r5
- ldr r5, [r7, #124]
+ ldr r5, [r7, #60]
str r4, [r7, #96]
- ldr r4, [r7, #60]
- add r5, r5, r4
- ldr r4, [r7, #88]
- str r5, [r7, #24]
- mov r5, r10
+ ldr r4, [r7, #124]
+ add r4, r4, r5
+ str r4, [r7, #20]
+ ldr r4, [r7, #80]
+ mov r5, r8
str r0, [r4] @ unaligned
mov r0, r4
str r1, [r4, #4] @ unaligned
- mov r8, r0
+ mov r4, r8
str r2, [r0, #8] @ unaligned
- mov r4, r10
+ mov r8, r0
str r3, [r0, #12] @ unaligned
+ mov r9, r4
ldr r0, [r6, #16]! @ unaligned
+ ldr r3, [r6, #12] @ unaligned
ldr r1, [r6, #4] @ unaligned
ldr r2, [r6, #8] @ unaligned
- ldr r3, [r6, #12] @ unaligned
ldr r6, [r7, #76]
stmia r5!, {r0, r1, r2, r3}
- mov r5, r10
- ldr r3, [r7, #84]
+ mov r5, r8
+ ldr r3, [r7, #88]
vldr d20, [r3, #80]
vldr d21, [r3, #88]
veor q10, q10, q5
vstr d20, [r3, #80]
vstr d21, [r3, #88]
ldmia r4!, {r0, r1, r2, r3}
- mov r4, r8
+ mov r4, r9
str r0, [r8, #16] @ unaligned
str r1, [r8, #20] @ unaligned
str r2, [r8, #24] @ unaligned
str r3, [r8, #28] @ unaligned
- mov r8, r4
+ mov r8, r5
ldr r0, [r6, #32]! @ unaligned
- str r10, [r7, #124]
+ mov r5, r9
ldr r1, [r6, #4] @ unaligned
ldr r2, [r6, #8] @ unaligned
ldr r3, [r6, #12] @ unaligned
ldr r6, [r7, #76]
stmia r5!, {r0, r1, r2, r3}
- mov r5, r10
- ldr r2, [r7, #84]
- vldr d16, [r2, #80]
- vldr d17, [r2, #88]
+ mov r5, r8
+ ldr r1, [r7, #88]
+ vldr d16, [r1, #80]
+ vldr d17, [r1, #88]
veor q15, q8, q15
- vstr d30, [r2, #80]
- vstr d31, [r2, #88]
- ldmia r10!, {r0, r1, r2, r3}
- str r0, [r4, #32] @ unaligned
- str r1, [r4, #36] @ unaligned
- str r2, [r4, #40] @ unaligned
- str r3, [r4, #44] @ unaligned
+ vstr d30, [r1, #80]
+ vstr d31, [r1, #88]
+ ldmia r4!, {r0, r1, r2, r3}
+ mov r4, r9
+ str r0, [r8, #32] @ unaligned
+ str r1, [r8, #36] @ unaligned
+ str r2, [r8, #40] @ unaligned
+ str r3, [r8, #44] @ unaligned
+ mov r8, r5
ldr r0, [r6, #48]! @ unaligned
ldr r1, [r6, #4] @ unaligned
ldr r2, [r6, #8] @ unaligned
ldr r3, [r6, #12] @ unaligned
ldr r6, [r7, #76]
- stmia r5!, {r0, r1, r2, r3}
- ldr r1, [r7, #84]
+ stmia r4!, {r0, r1, r2, r3}
+ mov r4, r9
+ ldr r1, [r7, #88]
+ str r9, [r7, #112]
vldr d18, [r1, #80]
vldr d19, [r1, #88]
veor q9, q9, q2
vstr d18, [r1, #80]
vstr d19, [r1, #88]
- ldr r3, [r7, #112]
- ldr r5, [r7, #80]
- mov r10, r3
- ldmia r10!, {r0, r1, r2, r3}
- str r0, [r4, #48] @ unaligned
- str r1, [r4, #52] @ unaligned
- str r2, [r4, #56] @ unaligned
- str r3, [r4, #60] @ unaligned
+ ldmia r9!, {r0, r1, r2, r3}
+ str r0, [r5, #48] @ unaligned
+ str r1, [r5, #52] @ unaligned
+ str r2, [r5, #56] @ unaligned
+ str r3, [r5, #60] @ unaligned
ldr r0, [r6, #64]! @ unaligned
ldr r1, [r6, #4] @ unaligned
ldr r2, [r6, #8] @ unaligned
ldr r3, [r6, #12] @ unaligned
ldr r6, [r7, #76]
- stmia r5!, {r0, r1, r2, r3}
- ldr r1, [r7, #84]
- ldr r3, [r7, #112]
- ldr r5, [r7, #80]
+ mov r9, r6
+ mov r6, r4
+ stmia r6!, {r0, r1, r2, r3}
+ mov r6, r4
+ ldr r1, [r7, #88]
vldr d18, [r1, #80]
vldr d19, [r1, #88]
veor q9, q9, q6
- mov r10, r3
- str r5, [r7, #20]
vstr d18, [r1, #80]
vstr d19, [r1, #88]
- ldmia r10!, {r0, r1, r2, r3}
- str r1, [r4, #68] @ unaligned
- str r2, [r4, #72] @ unaligned
- str r3, [r4, #76] @ unaligned
- str r0, [r4, #64] @ unaligned
- ldr r0, [r6, #80]! @ unaligned
- ldr r1, [r6, #4] @ unaligned
- ldr r2, [r6, #8] @ unaligned
- ldr r3, [r6, #12] @ unaligned
+ ldmia r4!, {r0, r1, r2, r3}
+ mov r4, r6
+ str r3, [r5, #76] @ unaligned
+ mov r3, r9
+ str r2, [r5, #72] @ unaligned
+ str r0, [r5, #64] @ unaligned
+ str r1, [r5, #68] @ unaligned
+ mov r5, r4
+ ldr r0, [r3, #80]! @ unaligned
+ mov r9, r3
+ ldr r1, [r9, #4] @ unaligned
+ ldr r2, [r9, #8] @ unaligned
+ ldr r3, [r9, #12] @ unaligned
+ mov r9, r4
ldr r6, [r7, #76]
+ str r9, [r7, #124]
stmia r5!, {r0, r1, r2, r3}
- ldr r1, [r7, #84]
- ldr r3, [r7, #20]
- ldr r5, [r7, #80]
+ mov r5, r8
+ ldr r1, [r7, #88]
vldr d18, [r1, #80]
vldr d19, [r1, #88]
veor q1, q9, q1
- mov r10, r3
vstr d2, [r1, #80]
vstr d3, [r1, #88]
- ldmia r10!, {r0, r1, r2, r3}
- mov r10, r5
- str r0, [r4, #80] @ unaligned
- str r1, [r4, #84] @ unaligned
- str r2, [r4, #88] @ unaligned
- str r3, [r4, #92] @ unaligned
+ ldmia r4!, {r0, r1, r2, r3}
+ mov r4, r9
+ str r0, [r8, #80] @ unaligned
+ str r1, [r8, #84] @ unaligned
+ str r2, [r8, #88] @ unaligned
+ str r3, [r8, #92] @ unaligned
ldr r0, [r6, #96]! @ unaligned
+ ldr r3, [r6, #12] @ unaligned
ldr r1, [r6, #4] @ unaligned
ldr r2, [r6, #8] @ unaligned
- ldr r3, [r6, #12] @ unaligned
ldr r6, [r7, #76]
- stmia r5!, {r0, r1, r2, r3}
- mov r5, r10
- ldr r3, [r7, #84]
+ stmia r4!, {r0, r1, r2, r3}
+ mov r4, r9
+ ldr r3, [r7, #88]
vldr d16, [r3, #80]
vldr d17, [r3, #88]
veor q8, q8, q7
vstr d16, [r3, #80]
vstr d17, [r3, #88]
- ldmia r10!, {r0, r1, r2, r3}
- str r0, [r4, #96] @ unaligned
- str r1, [r4, #100] @ unaligned
- str r2, [r4, #104] @ unaligned
- str r3, [r4, #108] @ unaligned
+ ldmia r9!, {r0, r1, r2, r3}
+ str r0, [r5, #96] @ unaligned
+ str r1, [r5, #100] @ unaligned
+ str r2, [r5, #104] @ unaligned
+ str r3, [r5, #108] @ unaligned
ldr r0, [r6, #112]! @ unaligned
ldr r1, [r6, #4] @ unaligned
ldr r2, [r6, #8] @ unaligned
ldr r3, [r6, #12] @ unaligned
- mov r6, r5
+ mov r6, r4
stmia r6!, {r0, r1, r2, r3}
- ldr r3, [r7, #84]
+ mov r6, r5
+ ldr r3, [r7, #88]
vldr d16, [r3, #80]
vldr d17, [r3, #88]
veor q8, q8, q3
vstr d16, [r3, #80]
vstr d17, [r3, #88]
- ldmia r5!, {r0, r1, r2, r3}
- str r1, [r4, #116] @ unaligned
- ldr r1, [r7, #76]
- str r0, [r4, #112] @ unaligned
- str r2, [r4, #120] @ unaligned
- str r3, [r4, #124] @ unaligned
- ldr r3, [r1, #128]
- ldr r2, [r7, #104]
+ ldmia r4!, {r0, r1, r2, r3}
+ mov r4, r5
+ mov r8, r4
+ str r2, [r5, #120] @ unaligned
+ ldr r2, [r7, #76]
+ str r0, [r5, #112] @ unaligned
+ str r1, [r5, #116] @ unaligned
+ str r3, [r5, #124] @ unaligned
+ ldr r3, [r2, #128]
+ ldr r1, [r7, #104]
eor r3, fp, r3
- str r3, [r4, #128]
- ldr r3, [r1, #132]
- eors r2, r2, r3
- str r2, [r8, #132]
- ldr r3, [r1, #136]
- ldr r5, [r7, #68]
- ldr r6, [r7, #32]
- eor r3, r9, r3
- str r3, [r4, #136]
- ldr r3, [r1, #140]
- ldr r0, [r7, #92]
- eors r3, r3, r6
- ldr r6, [r7, #108]
+ str r3, [r5, #128]
+ ldr r3, [r2, #132]
+ mov r5, r2
+ eor r3, r10, r3
+ str r3, [r6, #132]
+ ldr r3, [r2, #136]
+ mov r6, r5
+ eors r1, r1, r3
+ str r1, [r8, #136]
+ ldr r1, [r7, #56]
+ ldr r3, [r2, #140]
+ ldr r2, [r7, #100]
+ ldr r0, [r7, #108]
+ eors r3, r3, r2
str r3, [r4, #140]
- ldr r3, [r5]
- ldr r2, [r1, #144]
- add r6, r6, r3
- eors r2, r2, r6
+ ldr r3, [r1]
+ ldr r2, [r5, #144]
+ mov r8, r0
+ add r8, r8, r3
+ mov r5, r6
+ mov r3, r8
+ eors r2, r2, r3
str r2, [r4, #144]
- ldr r2, [r5, #4]
- ldr r3, [r1, #148]
- add r0, r0, r2
+ ldr r3, [r6, #148]
+ ldr r2, [r1, #4]
ldr r6, [r7, #36]
- eors r3, r3, r0
- ldr r0, [r7, #40]
- str r3, [r4, #148]
- ldr r2, [r5, #8]
- ldr r3, [r1, #152]
- add r0, r0, r2
- eors r3, r3, r0
- str r3, [r4, #152]
- ldr r2, [r5, #12]
- mov r0, r4
- ldr r3, [r1, #156]
- mov r4, r1
add r6, r6, r2
- mov r1, r0
eors r3, r3, r6
- str r3, [r0, #156]
- ldr r2, [r5, #16]
- ldr r3, [r4, #160]
+ mov r6, r1
+ str r3, [r4, #148]
+ ldr r2, [r1, #8]
+ ldr r1, [r7, #116]
+ ldr r3, [r5, #152]
+ mov r8, r1
+ add r8, r8, r2
+ ldr r1, [r7, #32]
+ mov r2, r8
+ eors r3, r3, r2
+ str r3, [r4, #152]
+ mov r8, r4
+ ldr r2, [r6, #12]
+ ldr r3, [r5, #156]
+ add r1, r1, r2
+ eors r3, r3, r1
+ str r3, [r4, #156]
+ ldr r2, [r6, #16]
+ mov r1, r4
+ ldr r3, [r5, #160]
+ mov r4, r5
add ip, ip, r2
+ mov r5, r6
eor r3, ip, r3
str r3, [r1, #160]
- ldr r2, [r5, #20]
+ ldr r2, [r6, #20]
ldr r3, [r4, #164]
add lr, lr, r2
- ldr r2, [r7, #116]
+ ldr r2, [r7, #92]
eor r3, lr, r3
str r3, [r1, #164]
ldr r6, [r5, #24]
mov lr, r4
ldr r3, [r4, #168]
add r2, r2, r6
- mov r6, r4
+ ldr r6, [r7, #120]
eors r3, r3, r2
str r3, [r1, #168]
ldr r5, [r5, #28]
- mov r2, r1
ldr r3, [r4, #172]
- ldr r0, [r7, #120]
- add r0, r0, r5
- ldr r5, [r7, #24]
- eors r3, r3, r0
+ add r6, r6, r5
+ eors r3, r3, r6
str r3, [r1, #172]
- ldr r3, [r7, #72]
ldr r4, [r4, #176]
- ldr r1, [r7, #28]
- eors r4, r4, r1
- adds r1, r3, #3
- str r4, [r2, #176]
- ldr r3, [r7, #100]
+ ldr r0, [r7, #28]
+ ldr r5, [r7, #24]
+ eors r4, r4, r0
+ str r4, [r8, #176]
ldr r0, [lr, #180]
- str r1, [r7, #72]
- eors r3, r3, r0
- mov r0, r3
- mov r3, r2
- str r0, [r2, #180]
- adds r3, r3, #192
- ldr r1, [lr, #184]
ldr r2, [r7, #96]
+ eors r0, r0, r5
+ str r0, [r8, #180]
+ ldr r1, [lr, #184]
+ ldr r4, [r7, #20]
eors r1, r1, r2
- str r1, [r3, #-8]
+ str r1, [r8, #184]
ldr r2, [lr, #188]
- mov r1, r6
- adds r1, r1, #192
- str r1, [r7, #76]
- eors r2, r2, r5
- str r2, [r3, #-4]
+ add r1, lr, #192
+ ldr r3, [r7, #72]
+ eors r2, r2, r4
+ str r2, [r8, #188]
ldr r2, [r7, #16]
- str r3, [r7, #88]
+ adds r3, r3, #3
+ str r3, [r7, #72]
+ mov r3, r8
+ adds r3, r3, #192
+ str r1, [r7, #76]
cmp r2, r3
+ str r3, [r7, #80]
bne .L4
ldr r3, [r7, #12]
ldr r2, [r7, #4]
@@ -756,8 +775,8 @@ CRYPTO_chacha_20_neon:
beq .L6
ldr r5, [r7, #12]
ldr r4, [r7, #16]
- ldr r6, [r7, #84]
- ldr lr, [r7, #80]
+ ldr r6, [r7, #88]
+ ldr lr, [r7, #84]
vldr d30, .L94
vldr d31, .L94+8
str fp, [r7, #120]
@@ -963,7 +982,7 @@ CRYPTO_chacha_20_neon:
mov r9, r5
bhi .L88
vadd.i32 q12, q12, q10
- ldr r3, [r7, #84]
+ ldr r3, [r7, #88]
vst1.64 {d24-d25}, [r3:128]
.L14:
ldr r3, [r7, #8]
@@ -1000,7 +1019,7 @@ CRYPTO_chacha_20_neon:
movcs r1, ip
cmp r1, #0
beq .L17
- ldr r5, [r7, #84]
+ ldr r5, [r7, #88]
cmp r1, #1
ldrb r0, [r0] @ zero_extendqisi2
add r3, r2, #1
@@ -1135,7 +1154,7 @@ CRYPTO_chacha_20_neon:
ldr r5, [r7, #16]
cmp r6, #1
add r0, r1, r2
- ldr r1, [r7, #84]
+ ldr r1, [r7, #88]
add r1, r1, r2
vld1.64 {d18-d19}, [r0:64]
add r2, r2, r5
@@ -1173,7 +1192,7 @@ CRYPTO_chacha_20_neon:
add r3, r3, lr
beq .L1
.L19:
- ldr r4, [r7, #84]
+ ldr r4, [r7, #88]
adds r2, r3, #1
ldr r1, [r7, #12]
cmp r2, r9
@@ -1288,7 +1307,7 @@ CRYPTO_chacha_20_neon:
eor r1, r1, r0
strb r1, [r5, r2]
bls .L1
- ldr r2, [r7, #84]
+ ldr r2, [r7, #88]
ldrb r1, [r2, r3] @ zero_extendqisi2
ldr r2, [r7, #12]
ldrb r2, [r2, r3] @ zero_extendqisi2
@@ -1296,7 +1315,7 @@ CRYPTO_chacha_20_neon:
ldr r1, [r7, #16]
strb r2, [r1, r3]
.L1:
- adds r7, r7, #156
+ adds r7, r7, #164
mov sp, r7
@ sp needed
vldm sp!, {d8-d15}
@@ -1304,7 +1323,7 @@ CRYPTO_chacha_20_neon:
.L88:
ldr r5, [r7, #12]
vadd.i32 q12, q12, q10
- ldr r4, [r7, #80]
+ ldr r4, [r7, #84]
cmp r9, #31
ldr r0, [r5] @ unaligned
ldr r1, [r5, #4] @ unaligned
@@ -1312,7 +1331,7 @@ CRYPTO_chacha_20_neon:
ldr r2, [r5, #8] @ unaligned
ldr r3, [r5, #12] @ unaligned
stmia r6!, {r0, r1, r2, r3}
- ldr r2, [r7, #84]
+ ldr r2, [r7, #88]
ldr r6, [r7, #16]
vldr d18, [r2, #80]
vldr d19, [r2, #88]
@@ -1327,7 +1346,7 @@ CRYPTO_chacha_20_neon:
str r3, [r6, #12] @ unaligned
bhi .L89
vadd.i32 q13, q13, q15
- ldr r3, [r7, #84]
+ ldr r3, [r7, #88]
vstr d26, [r3, #16]
vstr d27, [r3, #24]
b .L14
@@ -1336,7 +1355,7 @@ CRYPTO_chacha_20_neon:
ldr r2, [r7, #12]
add r2, r2, r9
mov r5, r2
- ldr r2, [r7, #84]
+ ldr r2, [r7, #88]
add r2, r2, r3
mov r3, r2
.L24:
@@ -1346,17 +1365,18 @@ CRYPTO_chacha_20_neon:
eor r2, r2, r1
strb r2, [r4], #1
bne .L24
- adds r7, r7, #156
+ adds r7, r7, #164
mov sp, r7
@ sp needed
vldm sp!, {d8-d15}
pop {r4, r5, r6, r7, r8, r9, r10, fp, pc}
.L26:
- str fp, [r7, #16]
+ ldr r3, [r7, #80]
+ str r3, [r7, #16]
b .L2
.L89:
mov r3, r5
- ldr r4, [r7, #80]
+ ldr r4, [r7, #84]
ldr r0, [r3, #16]! @ unaligned
add lr, r1, #16
mov r5, r1
@@ -1367,7 +1387,7 @@ CRYPTO_chacha_20_neon:
ldr r2, [r3, #8] @ unaligned
ldr r3, [r3, #12] @ unaligned
stmia r6!, {r0, r1, r2, r3}
- ldr r2, [r7, #84]
+ ldr r2, [r7, #88]
vldr d18, [r2, #80]
vldr d19, [r2, #88]
veor q13, q9, q13
@@ -1380,16 +1400,16 @@ CRYPTO_chacha_20_neon:
str r3, [lr, #12] @ unaligned
bhi .L90
vadd.i32 q8, q14, q8
- ldr r3, [r7, #84]
+ ldr r3, [r7, #88]
vstr d16, [r3, #32]
vstr d17, [r3, #40]
b .L14
.L90:
ldr r3, [r7, #12]
add lr, r5, #32
- ldr r4, [r7, #80]
+ ldr r4, [r7, #84]
vadd.i32 q8, q14, q8
- ldr r5, [r7, #84]
+ ldr r5, [r7, #88]
vadd.i32 q11, q11, q3
ldr r0, [r3, #32]! @ unaligned
mov r6, r4
@@ -1423,4 +1443,5 @@ CRYPTO_chacha_20_neon:
.ident "GCC: (Linaro GCC 2014.11) 4.9.3 20141031 (prerelease)"
.section .note.GNU-stack,"",%progbits
+#endif /* __arm__ */
#endif /* !OPENSSL_NO_ASM */
diff --git a/src/crypto/chacha/chacha_vec_arm_generate.go b/src/crypto/chacha/chacha_vec_arm_generate.go
index d681e8a..82aa847 100644
--- a/src/crypto/chacha/chacha_vec_arm_generate.go
+++ b/src/crypto/chacha/chacha_vec_arm_generate.go
@@ -12,7 +12,10 @@
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-// This package generates chacha_vec_arm.S from chacha_vec.c.
+// This package generates chacha_vec_arm.S from chacha_vec.c. Install the
+// arm-linux-gnueabihf-gcc compiler as described in BUILDING.md. Then:
+// `(cd crypto/chacha && go run chacha_vec_arm_generate.go)`.
+
package main
import (
@@ -52,7 +55,8 @@ func main() {
output.WriteString(compiler)
output.WriteString(" ")
output.WriteString(strings.Join(args, " "))
- output.WriteString("\n\n#if !defined(OPENSSL_NO_ASM)\n\n")
+ output.WriteString("\n\n#if !defined(OPENSSL_NO_ASM)\n")
+ output.WriteString("#if defined(__arm__)\n\n")
cmd := exec.Command(compiler, args...)
cmd.Stderr = os.Stderr
@@ -144,5 +148,6 @@ const attr28Block = `
`
const trailer = `
+#endif /* __arm__ */
#endif /* !OPENSSL_NO_ASM */
`
diff --git a/src/crypto/cipher/CMakeLists.txt b/src/crypto/cipher/CMakeLists.txt
index 2775698..52b87b6 100644
--- a/src/crypto/cipher/CMakeLists.txt
+++ b/src/crypto/cipher/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
cipher
@@ -37,3 +37,4 @@ add_executable(
target_link_libraries(cipher_test crypto)
target_link_libraries(aead_test crypto)
+add_dependencies(all_tests cipher_test aead_test)
diff --git a/src/crypto/cipher/aead.c b/src/crypto/cipher/aead.c
index 20d699d..b1db83d 100644
--- a/src/crypto/cipher/aead.c
+++ b/src/crypto/cipher/aead.c
@@ -30,11 +30,15 @@ size_t EVP_AEAD_max_overhead(const EVP_AEAD *aead) { return aead->overhead; }
size_t EVP_AEAD_max_tag_len(const EVP_AEAD *aead) { return aead->max_tag_len; }
+void EVP_AEAD_CTX_zero(EVP_AEAD_CTX *ctx) {
+ memset(ctx, 0, sizeof(EVP_AEAD_CTX));
+}
+
int EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead,
const uint8_t *key, size_t key_len, size_t tag_len,
ENGINE *impl) {
if (!aead->init) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_AEAD_CTX_init, CIPHER_R_NO_DIRECTION_SET);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_NO_DIRECTION_SET);
ctx->aead = NULL;
return 0;
}
@@ -47,8 +51,7 @@ int EVP_AEAD_CTX_init_with_direction(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead,
size_t tag_len,
enum evp_aead_direction_t dir) {
if (key_len != aead->key_len) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_AEAD_CTX_init_with_direction,
- CIPHER_R_UNSUPPORTED_KEY_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_KEY_SIZE);
ctx->aead = NULL;
return 0;
}
@@ -101,12 +104,12 @@ int EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
size_t possible_out_len = in_len + ctx->aead->overhead;
if (possible_out_len < in_len /* overflow */) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_AEAD_CTX_seal, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
goto error;
}
if (!check_alias(in, in_len, out)) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_AEAD_CTX_seal, CIPHER_R_OUTPUT_ALIASES_INPUT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_OUTPUT_ALIASES_INPUT);
goto error;
}
@@ -128,7 +131,7 @@ int EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
size_t nonce_len, const uint8_t *in, size_t in_len,
const uint8_t *ad, size_t ad_len) {
if (!check_alias(in, in_len, out)) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_AEAD_CTX_open, CIPHER_R_OUTPUT_ALIASES_INPUT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_OUTPUT_ALIASES_INPUT);
goto error;
}
@@ -153,3 +156,12 @@ int EVP_AEAD_CTX_get_rc4_state(const EVP_AEAD_CTX *ctx, const RC4_KEY **out_key)
return ctx->aead->get_rc4_state(ctx, out_key);
}
+
+int EVP_AEAD_CTX_get_iv(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv,
+ size_t *out_len) {
+ if (ctx->aead->get_iv == NULL) {
+ return 0;
+ }
+
+ return ctx->aead->get_iv(ctx, out_iv, out_len);
+}
diff --git a/src/crypto/cipher/aead_test.cc b/src/crypto/cipher/aead_test.cc
index e4b75d6..79d7110 100644
--- a/src/crypto/cipher/aead_test.cc
+++ b/src/crypto/cipher/aead_test.cc
@@ -22,7 +22,7 @@
#include <openssl/err.h>
#include "../test/file_test.h"
-#include "../test/stl_compat.h"
+#include "../test/scoped_types.h"
// This program tests an AEAD against a series of test vectors from a file,
@@ -35,18 +35,6 @@
// CT: 5294265a60
// TAG: 1d45758621762e061368e68868e2f929
-// EVP_AEAD_CTX lacks a zero state, so it doesn't fit easily into
-// ScopedOpenSSLContext.
-class EVP_AEAD_CTXScoper {
- public:
- EVP_AEAD_CTXScoper(EVP_AEAD_CTX *ctx) : ctx_(ctx) {}
- ~EVP_AEAD_CTXScoper() {
- EVP_AEAD_CTX_cleanup(ctx_);
- }
- private:
- EVP_AEAD_CTX *ctx_;
-};
-
static bool TestAEAD(FileTest *t, void *arg) {
const EVP_AEAD *aead = reinterpret_cast<const EVP_AEAD*>(arg);
@@ -60,22 +48,19 @@ static bool TestAEAD(FileTest *t, void *arg) {
return false;
}
- EVP_AEAD_CTX ctx;
- if (!EVP_AEAD_CTX_init_with_direction(&ctx, aead, bssl::vector_data(&key),
- key.size(), tag.size(),
- evp_aead_seal)) {
+ ScopedEVP_AEAD_CTX ctx;
+ 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;
}
- EVP_AEAD_CTXScoper cleanup(&ctx);
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, 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;
}
@@ -86,36 +71,31 @@ 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.
- EVP_AEAD_CTX_cleanup(&ctx);
- if (!EVP_AEAD_CTX_init_with_direction(&ctx, aead, bssl::vector_data(&key),
- key.size(), tag.size(),
- evp_aead_open)) {
+ ctx.Reset();
+ 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;
}
std::vector<uint8_t> out2(out.size());
size_t out2_len;
- int ret = EVP_AEAD_CTX_open(&ctx,
- 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.");
@@ -130,17 +110,15 @@ 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.
- EVP_AEAD_CTX_cleanup(&ctx);
- if (!EVP_AEAD_CTX_init_with_direction(&ctx, aead, bssl::vector_data(&key),
- key.size(), tag.size(),
- evp_aead_open)) {
+ ctx.Reset();
+ 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;
}
@@ -148,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, 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;
}
@@ -159,10 +136,9 @@ static bool TestAEAD(FileTest *t, void *arg) {
// The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
// reset after each operation.
- EVP_AEAD_CTX_cleanup(&ctx);
- if (!EVP_AEAD_CTX_init_with_direction(&ctx, aead, bssl::vector_data(&key),
- key.size(), tag.size(),
- evp_aead_open)) {
+ ctx.Reset();
+ 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;
}
@@ -171,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, 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;
}
@@ -200,6 +175,7 @@ static int TestCleanupAfterInitFailure(const EVP_AEAD *aead) {
fprintf(stderr, "A silly tag length didn't trigger an error!\n");
return 0;
}
+ ERR_clear_error();
/* Running a second, failed _init should not cause a memory leak. */
if (EVP_AEAD_CTX_init(&ctx, aead, key, key_len,
@@ -208,6 +184,7 @@ static int TestCleanupAfterInitFailure(const EVP_AEAD *aead) {
fprintf(stderr, "A silly tag length didn't trigger an error!\n");
return 0;
}
+ ERR_clear_error();
/* Calling _cleanup on an |EVP_AEAD_CTX| after a failed _init should be a
* no-op. */
@@ -224,6 +201,7 @@ 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 },
+ { "chacha20-poly1305-old", EVP_aead_chacha20_poly1305_old },
{ "rc4-md5-tls", EVP_aead_rc4_md5_tls },
{ "rc4-sha1-tls", EVP_aead_rc4_sha1_tls },
{ "aes-128-cbc-sha1-tls", EVP_aead_aes_128_cbc_sha1_tls },
diff --git a/src/crypto/cipher/cipher.c b/src/crypto/cipher/cipher.c
index 400c3f5..4401867 100644
--- a/src/crypto/cipher/cipher.c
+++ b/src/crypto/cipher/cipher.c
@@ -68,12 +68,18 @@
const EVP_CIPHER *EVP_get_cipherbynid(int nid) {
switch (nid) {
+ case NID_rc2_cbc:
+ return EVP_rc2_cbc();
+ case NID_rc2_40_cbc:
+ return EVP_rc2_40_cbc();
case NID_des_ede3_cbc:
return EVP_des_ede3_cbc();
case NID_des_ede_cbc:
return EVP_des_cbc();
case NID_aes_128_cbc:
return EVP_aes_128_cbc();
+ case NID_aes_192_cbc:
+ return EVP_aes_192_cbc();
case NID_aes_256_cbc:
return EVP_aes_256_cbc();
default:
@@ -115,7 +121,7 @@ void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) {
int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) {
if (in == NULL || in->cipher == NULL) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_CIPHER_CTX_copy, CIPHER_R_INPUT_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INPUT_NOT_INITIALIZED);
return 0;
}
@@ -125,7 +131,7 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) {
if (in->cipher_data && in->cipher->ctx_size) {
out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size);
if (!out->cipher_data) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_CIPHER_CTX_copy, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
return 0;
}
memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size);
@@ -165,7 +171,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
ctx->cipher_data = OPENSSL_malloc(ctx->cipher->ctx_size);
if (!ctx->cipher_data) {
ctx->cipher = NULL;
- OPENSSL_PUT_ERROR(CIPHER, EVP_CipherInit_ex, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
return 0;
}
} else {
@@ -178,12 +184,12 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
if (ctx->cipher->flags & EVP_CIPH_CTRL_INIT) {
if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) {
ctx->cipher = NULL;
- OPENSSL_PUT_ERROR(CIPHER, EVP_CipherInit_ex, CIPHER_R_INITIALIZATION_ERROR);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INITIALIZATION_ERROR);
return 0;
}
}
} else if (!ctx->cipher) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_CipherInit_ex, CIPHER_R_NO_CIPHER_SET);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_NO_CIPHER_SET);
return 0;
}
@@ -338,8 +344,7 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len) {
bl = ctx->buf_len;
if (ctx->flags & EVP_CIPH_NO_PADDING) {
if (bl) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_EncryptFinal_ex,
- CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
return 0;
}
*out_len = 0;
@@ -434,8 +439,7 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len) {
b = ctx->cipher->block_size;
if (ctx->flags & EVP_CIPH_NO_PADDING) {
if (ctx->buf_len) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_DecryptFinal_ex,
- CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
return 0;
}
*out_len = 0;
@@ -444,8 +448,7 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len) {
if (b > 1) {
if (ctx->buf_len || !ctx->final_used) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_DecryptFinal_ex,
- CIPHER_R_WRONG_FINAL_BLOCK_LENGTH);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_WRONG_FINAL_BLOCK_LENGTH);
return 0;
}
assert(b <= sizeof(ctx->final));
@@ -454,13 +457,13 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len) {
* Otherwise it provides a padding oracle. */
n = ctx->final[b - 1];
if (n == 0 || n > (int)b) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_DecryptFinal_ex, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
for (i = 0; i < n; i++) {
if (ctx->final[--b] != n) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_DecryptFinal_ex, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
}
@@ -538,19 +541,18 @@ uint32_t EVP_CIPHER_CTX_mode(const EVP_CIPHER_CTX *ctx) {
int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int command, int arg, void *ptr) {
int ret;
if (!ctx->cipher) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_CIPHER_CTX_ctrl, CIPHER_R_NO_CIPHER_SET);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_NO_CIPHER_SET);
return 0;
}
if (!ctx->cipher->ctrl) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_CIPHER_CTX_ctrl, CIPHER_R_CTRL_NOT_IMPLEMENTED);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_CTRL_NOT_IMPLEMENTED);
return 0;
}
ret = ctx->cipher->ctrl(ctx, command, arg, ptr);
if (ret == -1) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_CIPHER_CTX_ctrl,
- CIPHER_R_CTRL_OPERATION_NOT_IMPLEMENTED);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_CTRL_OPERATION_NOT_IMPLEMENTED);
return 0;
}
@@ -572,8 +574,7 @@ int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, unsigned key_len) {
}
if (key_len == 0 || !(c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH)) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_CIPHER_CTX_set_key_length,
- CIPHER_R_INVALID_KEY_LENGTH);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_KEY_LENGTH);
return 0;
}
@@ -630,7 +631,7 @@ const EVP_CIPHER *EVP_get_cipherbyname(const char *name) {
return EVP_rc4();
} else if (OPENSSL_strcasecmp(name, "des-cbc") == 0) {
return EVP_des_cbc();
- } else if (OPENSSL_strcasecmp(name, "3des-cbc") == 0 ||
+ } else if (OPENSSL_strcasecmp(name, "des-ede3-cbc") == 0 ||
OPENSSL_strcasecmp(name, "3des") == 0) {
return EVP_des_ede3_cbc();
} else if (OPENSSL_strcasecmp(name, "aes-128-cbc") == 0) {
diff --git a/src/crypto/cipher/cipher_test.cc b/src/crypto/cipher/cipher_test.cc
index 97a84e0..1cbfae9 100644
--- a/src/crypto/cipher/cipher_test.cc
+++ b/src/crypto/cipher/cipher_test.cc
@@ -63,12 +63,17 @@
#include "../test/file_test.h"
#include "../test/scoped_types.h"
-#include "../test/stl_compat.h"
static const EVP_CIPHER *GetCipher(const std::string &name) {
if (name == "DES-CBC") {
return EVP_des_cbc();
+ } else if (name == "DES-ECB") {
+ return EVP_des_ecb();
+ } else if (name == "DES-EDE") {
+ return EVP_des_ede();
+ } else if (name == "DES-EDE-CBC") {
+ return EVP_des_ede_cbc();
} else if (name == "DES-EDE3-CBC") {
return EVP_des_ede3_cbc();
} else if (name == "RC4") {
@@ -104,6 +109,7 @@ static const EVP_CIPHER *GetCipher(const std::string &name) {
static bool TestOperation(FileTest *t,
const EVP_CIPHER *cipher,
bool encrypt,
+ bool streaming,
const std::vector<uint8_t> &key,
const std::vector<uint8_t> &iv,
const std::vector<uint8_t> &plaintext,
@@ -139,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
@@ -155,23 +161,40 @@ 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) ||
- (!in->empty() &&
- !EVP_CipherUpdate(ctx.get(), bssl::vector_data(&result), &result_len1,
- bssl::vector_data(in), in->size())) ||
- !EVP_CipherFinal_ex(ctx.get(), bssl::vector_data(&result) + result_len1,
+ !EVP_CIPHER_CTX_set_padding(ctx.get(), 0)) {
+ t->PrintLine("Operation failed.");
+ return false;
+ }
+ if (streaming) {
+ for (size_t i = 0; i < in->size(); i++) {
+ uint8_t c = (*in)[i];
+ int len;
+ 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(), result.data(), &result_len1,
+ in->data(), in->size())) {
+ t->PrintLine("Operation failed.");
+ return false;
+ }
+ 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) {
@@ -182,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;
}
@@ -236,15 +259,21 @@ static bool TestCipher(FileTest *t, void *arg) {
}
// By default, both directions are run, unless overridden by the operation.
- if (operation != kDecrypt &&
- !TestOperation(t, cipher, true /* encrypt */, key, iv, plaintext,
- ciphertext, aad, tag)) {
- return false;
+ if (operation != kDecrypt) {
+ if (!TestOperation(t, cipher, true /* encrypt */, false /* single-shot */,
+ key, iv, plaintext, ciphertext, aad, tag) ||
+ !TestOperation(t, cipher, true /* encrypt */, true /* streaming */, key,
+ iv, plaintext, ciphertext, aad, tag)) {
+ return false;
+ }
}
- if (operation != kEncrypt &&
- !TestOperation(t, cipher, false /* decrypt */, key, iv, plaintext,
- ciphertext, aad, tag)) {
- return false;
+ if (operation != kEncrypt) {
+ if (!TestOperation(t, cipher, false /* decrypt */, false /* single-shot */,
+ key, iv, plaintext, ciphertext, aad, tag) ||
+ !TestOperation(t, cipher, false /* decrypt */, true /* streaming */,
+ key, iv, plaintext, ciphertext, aad, tag)) {
+ return false;
+ }
}
return true;
diff --git a/src/crypto/cipher/e_aes.c b/src/crypto/cipher/e_aes.c
index 41d0aec..e5104b4 100644
--- a/src/crypto/cipher/e_aes.c
+++ b/src/crypto/cipher/e_aes.c
@@ -54,7 +54,6 @@
#include <openssl/cpu.h>
#include <openssl/err.h>
#include <openssl/mem.h>
-#include <openssl/modes.h>
#include <openssl/obj.h>
#include <openssl/rand.h>
#include <openssl/sha.h>
@@ -64,7 +63,7 @@
#include "../modes/internal.h"
#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
-#include "../arm_arch.h"
+#include <openssl/arm_arch.h>
#endif
@@ -98,8 +97,6 @@ typedef struct {
#if !defined(OPENSSL_NO_ASM) && \
(defined(OPENSSL_X86_64) || defined(OPENSSL_X86))
#define VPAES
-extern unsigned int OPENSSL_ia32cap_P[];
-
static char vpaes_capable(void) {
return (OPENSSL_ia32cap_P[1] & (1 << (41 - 32))) != 0;
}
@@ -113,7 +110,6 @@ static char bsaes_capable(void) {
#elif !defined(OPENSSL_NO_ASM) && \
(defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))
-#include "../arm_arch.h"
#if defined(OPENSSL_ARM) && __ARM_MAX_ARCH__ >= 7
#define BSAES
@@ -123,8 +119,8 @@ static char bsaes_capable(void) {
#endif
#define HWAES
-static char hwaes_capable(void) {
- return (OPENSSL_armcap_P & ARMV8_AES) != 0;
+static int hwaes_capable(void) {
+ return CRYPTO_is_ARMv8_AES_capable();
}
int aes_v8_set_encrypt_key(const uint8_t *user_key, const int bits,
@@ -154,13 +150,14 @@ static char bsaes_capable(void) {
/* On other platforms, bsaes_capable() will always return false and so the
* following will never be called. */
-void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
- const AES_KEY *key, uint8_t ivec[16], int enc) {
+static void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
+ const AES_KEY *key, uint8_t ivec[16], int enc) {
abort();
}
-void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len,
- const AES_KEY *key, const uint8_t ivec[16]) {
+static void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
+ size_t len, const AES_KEY *key,
+ const uint8_t ivec[16]) {
abort();
}
#endif
@@ -183,20 +180,22 @@ static char vpaes_capable(void) {
/* On other platforms, vpaes_capable() will always return false and so the
* following will never be called. */
-int vpaes_set_encrypt_key(const uint8_t *userKey, int bits, AES_KEY *key) {
+static int vpaes_set_encrypt_key(const uint8_t *userKey, int bits,
+ AES_KEY *key) {
abort();
}
-int vpaes_set_decrypt_key(const uint8_t *userKey, int bits, AES_KEY *key) {
+static int vpaes_set_decrypt_key(const uint8_t *userKey, int bits,
+ AES_KEY *key) {
abort();
}
-void vpaes_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
+static void vpaes_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
abort();
}
-void vpaes_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
+static void vpaes_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
abort();
}
-void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
- const AES_KEY *key, uint8_t *ivec, int enc) {
+static void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
+ const AES_KEY *key, uint8_t *ivec, int enc) {
abort();
}
#endif
@@ -204,34 +203,38 @@ void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
#if !defined(HWAES)
/* If HWAES isn't defined then we provide dummy functions for each of the hwaes
* functions. */
-int hwaes_capable(void) {
+static int hwaes_capable(void) {
return 0;
}
-int aes_v8_set_encrypt_key(const uint8_t *user_key, int bits,
- AES_KEY *key) {
+static int aes_v8_set_encrypt_key(const uint8_t *user_key, int bits,
+ AES_KEY *key) {
abort();
}
-int aes_v8_set_decrypt_key(const uint8_t *user_key, int bits, AES_KEY *key) {
+static int aes_v8_set_decrypt_key(const uint8_t *user_key, int bits,
+ AES_KEY *key) {
abort();
}
-void aes_v8_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
+static void aes_v8_encrypt(const uint8_t *in, uint8_t *out,
+ const AES_KEY *key) {
abort();
}
-void aes_v8_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
+static void aes_v8_decrypt(const uint8_t *in, uint8_t *out,
+ const AES_KEY *key) {
abort();
}
-void aes_v8_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
- const AES_KEY *key, uint8_t *ivec, int enc) {
+static void aes_v8_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
+ const AES_KEY *key, uint8_t *ivec, int enc) {
abort();
}
-void aes_v8_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len,
- const AES_KEY *key, const uint8_t ivec[16]) {
+static void aes_v8_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
+ size_t len, const AES_KEY *key,
+ const uint8_t ivec[16]) {
abort();
}
#endif
@@ -269,14 +272,16 @@ void gcm_ghash_avx(uint64_t Xi[2], const u128 Htable[16], const uint8_t *in,
/* On other platforms, aesni_capable() will always return false and so the
* following will never be called. */
-void aesni_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
+static void aesni_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
abort();
}
-int aesni_set_encrypt_key(const uint8_t *userKey, int bits, AES_KEY *key) {
+static int aesni_set_encrypt_key(const uint8_t *userKey, int bits,
+ AES_KEY *key) {
abort();
}
-void aesni_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t blocks,
- const void *key, const uint8_t *ivec) {
+static void aesni_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
+ size_t blocks, const void *key,
+ const uint8_t *ivec) {
abort();
}
@@ -338,7 +343,7 @@ static int aes_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
}
if (ret < 0) {
- OPENSSL_PUT_ERROR(CIPHER, aes_init_key, CIPHER_R_AES_KEY_SETUP_FAILED);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_AES_KEY_SETUP_FAILED);
return 0;
}
@@ -475,14 +480,14 @@ static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
iv = gctx->iv;
}
if (iv) {
- CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, iv, gctx->ivlen);
gctx->iv_set = 1;
}
gctx->key_set = 1;
} else {
/* If key set use IV, otherwise copy */
if (gctx->key_set) {
- CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, iv, gctx->ivlen);
} else {
memcpy(gctx->iv, iv, gctx->ivlen);
}
@@ -586,7 +591,7 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) {
if (gctx->iv_gen == 0 || gctx->key_set == 0) {
return 0;
}
- CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
+ CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, gctx->iv, gctx->ivlen);
if (arg <= 0 || arg > gctx->ivlen) {
arg = gctx->ivlen;
}
@@ -603,19 +608,13 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) {
return 0;
}
memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg);
- CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
+ CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, gctx->iv, gctx->ivlen);
gctx->iv_set = 1;
return 1;
case EVP_CTRL_COPY: {
EVP_CIPHER_CTX *out = ptr;
EVP_AES_GCM_CTX *gctx_out = out->cipher_data;
- if (gctx->gcm.key) {
- if (gctx->gcm.key != &gctx->ks) {
- return 0;
- }
- gctx_out->gcm.key = &gctx_out->ks;
- }
if (gctx->iv == c->iv) {
gctx_out->iv = out->iv;
} else {
@@ -657,24 +656,24 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
if (len >= 32 && AES_GCM_ASM(gctx)) {
size_t res = (16 - gctx->gcm.mres) % 16;
- if (!CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, res)) {
+ if (!CRYPTO_gcm128_encrypt(&gctx->gcm, &gctx->ks.ks, in, out, res)) {
return -1;
}
- bulk = AES_gcm_encrypt(in + res, out + res, len - res, gctx->gcm.key,
+ bulk = AES_gcm_encrypt(in + res, out + res, len - res, &gctx->ks.ks,
gctx->gcm.Yi.c, gctx->gcm.Xi.u);
gctx->gcm.len.u[1] += bulk;
bulk += res;
}
#endif
- if (!CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, in + bulk, out + bulk,
- len - bulk, gctx->ctr)) {
+ if (!CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, &gctx->ks.ks, in + bulk,
+ out + bulk, len - bulk, gctx->ctr)) {
return -1;
}
} else {
size_t bulk = 0;
- if (!CRYPTO_gcm128_encrypt(&gctx->gcm, in + bulk, out + bulk,
- len - bulk)) {
+ if (!CRYPTO_gcm128_encrypt(&gctx->gcm, &gctx->ks.ks, in + bulk,
+ out + bulk, len - bulk)) {
return -1;
}
}
@@ -685,24 +684,24 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
if (len >= 16 && AES_GCM_ASM(gctx)) {
size_t res = (16 - gctx->gcm.mres) % 16;
- if (!CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, res)) {
+ if (!CRYPTO_gcm128_decrypt(&gctx->gcm, &gctx->ks.ks, in, out, res)) {
return -1;
}
- bulk = AES_gcm_decrypt(in + res, out + res, len - res, gctx->gcm.key,
+ bulk = AES_gcm_decrypt(in + res, out + res, len - res, &gctx->ks.ks,
gctx->gcm.Yi.c, gctx->gcm.Xi.u);
gctx->gcm.len.u[1] += bulk;
bulk += res;
}
#endif
- if (!CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, in + bulk, out + bulk,
- len - bulk, gctx->ctr)) {
+ if (!CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, &gctx->ks.ks, in + bulk,
+ out + bulk, len - bulk, gctx->ctr)) {
return -1;
}
} else {
size_t bulk = 0;
- if (!CRYPTO_gcm128_decrypt(&gctx->gcm, in + bulk, out + bulk,
- len - bulk)) {
+ if (!CRYPTO_gcm128_decrypt(&gctx->gcm, &gctx->ks.ks, in + bulk,
+ out + bulk, len - bulk)) {
return -1;
}
}
@@ -711,7 +710,7 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
} else {
if (!ctx->encrypt) {
if (gctx->taglen < 0 ||
- !CRYPTO_gcm128_finish(&gctx->gcm, ctx->buf, gctx->taglen) != 0) {
+ !CRYPTO_gcm128_finish(&gctx->gcm, ctx->buf, gctx->taglen)) {
return -1;
}
gctx->iv_set = 0;
@@ -853,7 +852,7 @@ static int aesni_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
}
if (ret < 0) {
- OPENSSL_PUT_ERROR(CIPHER, aesni_init_key, CIPHER_R_AES_KEY_SETUP_FAILED);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_AES_KEY_SETUP_FAILED);
return 0;
}
@@ -896,14 +895,14 @@ static int aesni_gcm_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
iv = gctx->iv;
}
if (iv) {
- CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, iv, gctx->ivlen);
gctx->iv_set = 1;
}
gctx->key_set = 1;
} else {
/* If key set use IV, otherwise copy */
if (gctx->key_set) {
- CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, iv, gctx->ivlen);
} else {
memcpy(gctx->iv, iv, gctx->ivlen);
}
@@ -1066,7 +1065,7 @@ static int aead_aes_gcm_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
const size_t key_bits = key_len * 8;
if (key_bits != 128 && key_bits != 256) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_init, CIPHER_R_BAD_KEY_LENGTH);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
return 0; /* EVP_AEAD_CTX_init should catch this. */
}
@@ -1075,7 +1074,7 @@ static int aead_aes_gcm_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
}
if (tag_len > EVP_AEAD_AES_GCM_TAG_LEN) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_init, CIPHER_R_TAG_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE);
return 0;
}
@@ -1103,34 +1102,35 @@ static int aead_aes_gcm_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
const uint8_t *nonce, size_t nonce_len,
const uint8_t *in, size_t in_len,
const uint8_t *ad, size_t ad_len) {
- size_t bulk = 0;
const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state;
GCM128_CONTEXT gcm;
if (in_len + gcm_ctx->tag_len < in_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_seal, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
if (max_out_len < in_len + gcm_ctx->tag_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_seal, CIPHER_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
+ const AES_KEY *key = &gcm_ctx->ks.ks;
+
memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
- CRYPTO_gcm128_setiv(&gcm, nonce, nonce_len);
+ CRYPTO_gcm128_setiv(&gcm, key, nonce, nonce_len);
if (ad_len > 0 && !CRYPTO_gcm128_aad(&gcm, ad, ad_len)) {
return 0;
}
if (gcm_ctx->ctr) {
- if (!CRYPTO_gcm128_encrypt_ctr32(&gcm, in + bulk, out + bulk, in_len - bulk,
+ if (!CRYPTO_gcm128_encrypt_ctr32(&gcm, key, in, out, in_len,
gcm_ctx->ctr)) {
return 0;
}
} else {
- if (!CRYPTO_gcm128_encrypt(&gcm, in + bulk, out + bulk, in_len - bulk)) {
+ if (!CRYPTO_gcm128_encrypt(&gcm, key, in, out, in_len)) {
return 0;
}
}
@@ -1145,47 +1145,46 @@ static int aead_aes_gcm_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
const uint8_t *nonce, size_t nonce_len,
const uint8_t *in, size_t in_len,
const uint8_t *ad, size_t ad_len) {
- size_t bulk = 0;
const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state;
uint8_t tag[EVP_AEAD_AES_GCM_TAG_LEN];
size_t plaintext_len;
GCM128_CONTEXT gcm;
if (in_len < gcm_ctx->tag_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
plaintext_len = in_len - gcm_ctx->tag_len;
if (max_out_len < plaintext_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_open, CIPHER_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
+ const AES_KEY *key = &gcm_ctx->ks.ks;
+
memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
- CRYPTO_gcm128_setiv(&gcm, nonce, nonce_len);
+ CRYPTO_gcm128_setiv(&gcm, key, nonce, nonce_len);
if (!CRYPTO_gcm128_aad(&gcm, ad, ad_len)) {
return 0;
}
if (gcm_ctx->ctr) {
- if (!CRYPTO_gcm128_decrypt_ctr32(&gcm, in + bulk, out + bulk,
- in_len - bulk - gcm_ctx->tag_len,
- gcm_ctx->ctr)) {
+ if (!CRYPTO_gcm128_decrypt_ctr32(&gcm, key, in, out,
+ in_len - gcm_ctx->tag_len, gcm_ctx->ctr)) {
return 0;
}
} else {
- if (!CRYPTO_gcm128_decrypt(&gcm, in + bulk, out + bulk,
- in_len - bulk - gcm_ctx->tag_len)) {
+ if (!CRYPTO_gcm128_decrypt(&gcm, key, in, out, in_len - gcm_ctx->tag_len)) {
return 0;
}
}
CRYPTO_gcm128_tag(&gcm, tag, gcm_ctx->tag_len);
if (CRYPTO_memcmp(tag, in + plaintext_len, gcm_ctx->tag_len) != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
@@ -1204,6 +1203,7 @@ static const EVP_AEAD aead_aes_128_gcm = {
aead_aes_gcm_seal,
aead_aes_gcm_open,
NULL, /* get_rc4_state */
+ NULL, /* get_iv */
};
static const EVP_AEAD aead_aes_256_gcm = {
@@ -1217,6 +1217,7 @@ static const EVP_AEAD aead_aes_256_gcm = {
aead_aes_gcm_seal,
aead_aes_gcm_open,
NULL, /* get_rc4_state */
+ NULL, /* get_iv */
};
const EVP_AEAD *EVP_aead_aes_128_gcm(void) { return &aead_aes_128_gcm; }
@@ -1239,7 +1240,7 @@ static int aead_aes_key_wrap_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
const size_t key_bits = key_len * 8;
if (key_bits != 128 && key_bits != 256) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_init, CIPHER_R_BAD_KEY_LENGTH);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
return 0; /* EVP_AEAD_CTX_init should catch this. */
}
@@ -1248,14 +1249,13 @@ static int aead_aes_key_wrap_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
}
if (tag_len != 8) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_init,
- CIPHER_R_UNSUPPORTED_TAG_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_TAG_SIZE);
return 0;
}
kw_ctx = OPENSSL_malloc(sizeof(struct aead_aes_key_wrap_ctx));
if (kw_ctx == NULL) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_init, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -1293,8 +1293,7 @@ static int aead_aes_key_wrap_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
uint8_t A[AES_BLOCK_SIZE];
if (ad_len != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_seal,
- CIPHER_R_UNSUPPORTED_AD_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_AD_SIZE);
return 0;
}
@@ -1304,14 +1303,12 @@ static int aead_aes_key_wrap_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
}
if (nonce_len != 8) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_seal,
- CIPHER_R_UNSUPPORTED_NONCE_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
return 0;
}
if (in_len % 8 != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_seal,
- CIPHER_R_UNSUPPORTED_INPUT_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_INPUT_SIZE);
return 0;
}
@@ -1320,32 +1317,29 @@ static int aead_aes_key_wrap_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
* conservatively cap it to 2^32-16 to stop 32-bit platforms complaining that
* a comparison is always true. */
if (in_len > 0xfffffff0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_seal, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
n = in_len / 8;
if (n < 2) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_seal,
- CIPHER_R_UNSUPPORTED_INPUT_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_INPUT_SIZE);
return 0;
}
if (in_len + 8 < in_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_seal, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
if (max_out_len < in_len + 8) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_seal,
- CIPHER_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
if (AES_set_encrypt_key(kw_ctx->key, kw_ctx->key_bits, &ks.ks) < 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_seal,
- CIPHER_R_AES_KEY_SETUP_FAILED);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_AES_KEY_SETUP_FAILED);
return 0;
}
@@ -1388,8 +1382,7 @@ static int aead_aes_key_wrap_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
uint8_t A[AES_BLOCK_SIZE];
if (ad_len != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open,
- CIPHER_R_UNSUPPORTED_AD_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_AD_SIZE);
return 0;
}
@@ -1399,14 +1392,12 @@ static int aead_aes_key_wrap_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
}
if (nonce_len != 8) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open,
- CIPHER_R_UNSUPPORTED_NONCE_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
return 0;
}
if (in_len % 8 != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open,
- CIPHER_R_UNSUPPORTED_INPUT_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_INPUT_SIZE);
return 0;
}
@@ -1415,26 +1406,24 @@ static int aead_aes_key_wrap_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
* conservatively cap it to 2^32-8 to stop 32-bit platforms complaining that
* a comparison is always true. */
if (in_len > 0xfffffff8) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
if (in_len < 24) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
n = (in_len / 8) - 1;
if (max_out_len < in_len - 8) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open,
- CIPHER_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
if (AES_set_decrypt_key(kw_ctx->key, kw_ctx->key_bits, &ks.ks) < 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open,
- CIPHER_R_AES_KEY_SETUP_FAILED);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_AES_KEY_SETUP_FAILED);
return 0;
}
@@ -1457,7 +1446,7 @@ static int aead_aes_key_wrap_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
}
if (CRYPTO_memcmp(A, nonce, 8) != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
@@ -1475,7 +1464,8 @@ static const EVP_AEAD aead_aes_128_key_wrap = {
aead_aes_key_wrap_cleanup,
aead_aes_key_wrap_seal,
aead_aes_key_wrap_open,
- NULL, /* get_rc4_state */
+ NULL, /* get_rc4_state */
+ NULL, /* get_iv */
};
static const EVP_AEAD aead_aes_256_key_wrap = {
@@ -1488,7 +1478,8 @@ static const EVP_AEAD aead_aes_256_key_wrap = {
aead_aes_key_wrap_cleanup,
aead_aes_key_wrap_seal,
aead_aes_key_wrap_open,
- NULL, /* get_rc4_state */
+ NULL, /* get_rc4_state */
+ NULL, /* get_iv */
};
const EVP_AEAD *EVP_aead_aes_128_key_wrap(void) { return &aead_aes_128_key_wrap; }
@@ -1541,15 +1532,13 @@ static int aead_aes_ctr_hmac_sha256_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
static const size_t hmac_key_len = 32;
if (key_len < hmac_key_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_init,
- CIPHER_R_BAD_KEY_LENGTH);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
return 0; /* EVP_AEAD_CTX_init should catch this. */
}
const size_t aes_key_len = key_len - hmac_key_len;
if (aes_key_len != 16 && aes_key_len != 32) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_init,
- CIPHER_R_BAD_KEY_LENGTH);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
return 0; /* EVP_AEAD_CTX_init should catch this. */
}
@@ -1558,15 +1547,13 @@ static int aead_aes_ctr_hmac_sha256_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
}
if (tag_len > EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_init,
- CIPHER_R_TAG_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE);
return 0;
}
aes_ctx = OPENSSL_malloc(sizeof(struct aead_aes_ctr_hmac_sha256_ctx));
if (aes_ctx == NULL) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_init,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -1665,21 +1652,18 @@ 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) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_seal,
- CIPHER_R_TOO_LARGE);
+ in_len_64 >= (UINT64_C(1) << 32) * AES_BLOCK_SIZE) {
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
if (max_out_len < in_len + aes_ctx->tag_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_seal,
- CIPHER_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
if (nonce_len != EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_seal,
- CIPHER_R_UNSUPPORTED_NONCE_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
return 0;
}
@@ -1703,22 +1687,19 @@ static int aead_aes_ctr_hmac_sha256_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
size_t plaintext_len;
if (in_len < aes_ctx->tag_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_open,
- CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
plaintext_len = in_len - aes_ctx->tag_len;
if (max_out_len < plaintext_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_open,
- CIPHER_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
if (nonce_len != EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_open,
- CIPHER_R_UNSUPPORTED_NONCE_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
return 0;
}
@@ -1727,8 +1708,7 @@ static int aead_aes_ctr_hmac_sha256_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
&aes_ctx->outer_init_state, ad, ad_len, nonce, in,
plaintext_len);
if (CRYPTO_memcmp(hmac_result, in + plaintext_len, aes_ctx->tag_len) != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_open,
- CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
@@ -1750,6 +1730,7 @@ static const EVP_AEAD aead_aes_128_ctr_hmac_sha256 = {
aead_aes_ctr_hmac_sha256_seal,
aead_aes_ctr_hmac_sha256_open,
NULL /* get_rc4_state */,
+ NULL /* get_iv */,
};
static const EVP_AEAD aead_aes_256_ctr_hmac_sha256 = {
@@ -1764,6 +1745,7 @@ static const EVP_AEAD aead_aes_256_ctr_hmac_sha256 = {
aead_aes_ctr_hmac_sha256_seal,
aead_aes_ctr_hmac_sha256_open,
NULL /* get_rc4_state */,
+ NULL /* get_iv */,
};
const EVP_AEAD *EVP_aead_aes_128_ctr_hmac_sha256(void) {
@@ -1778,7 +1760,7 @@ int EVP_has_aes_hardware(void) {
#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
return aesni_capable() && crypto_gcm_clmul_enabled();
#elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
- return hwaes_capable() && (OPENSSL_armcap_P & ARMV8_PMULL);
+ return hwaes_capable() && CRYPTO_is_ARMv8_PMULL_capable();
#else
return 0;
#endif
diff --git a/src/crypto/cipher/e_chacha20poly1305.c b/src/crypto/cipher/e_chacha20poly1305.c
index ebf0088..f384950 100644
--- a/src/crypto/cipher/e_chacha20poly1305.c
+++ b/src/crypto/cipher/e_chacha20poly1305.c
@@ -26,7 +26,6 @@
#define POLY1305_TAG_LEN 16
-#define CHACHA20_NONCE_LEN 8
struct aead_chacha20_poly1305_ctx {
unsigned char key[32];
@@ -42,7 +41,7 @@ static int aead_chacha20_poly1305_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
}
if (tag_len > POLY1305_TAG_LEN) {
- OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_init, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
@@ -68,18 +67,15 @@ static void aead_chacha20_poly1305_cleanup(EVP_AEAD_CTX *ctx) {
OPENSSL_free(c20_ctx);
}
-static void poly1305_update_with_length(poly1305_state *poly1305,
- const uint8_t *data, size_t data_len) {
- size_t j = data_len;
+static void poly1305_update_length(poly1305_state *poly1305, size_t data_len) {
uint8_t length_bytes[8];
unsigned i;
for (i = 0; i < sizeof(length_bytes); i++) {
- length_bytes[i] = j;
- j >>= 8;
+ length_bytes[i] = data_len;
+ data_len >>= 8;
}
- CRYPTO_poly1305_update(poly1305, data, data_len);
CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes));
}
@@ -89,124 +85,155 @@ static void poly1305_update_with_length(poly1305_state *poly1305,
#define ALIGNED
#endif
-static int aead_chacha20_poly1305_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) {
- const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
+typedef void (*aead_poly1305_update)(poly1305_state *ctx, const uint8_t *ad,
+ size_t ad_len, const uint8_t *ciphertext,
+ size_t ciphertext_len);
+
+/* aead_poly1305 fills |tag| with the authentication tag for the given
+ * inputs, using |update| to control the order and format that the inputs are
+ * signed/authenticated. */
+static void aead_poly1305(aead_poly1305_update update,
+ uint8_t tag[POLY1305_TAG_LEN],
+ const struct aead_chacha20_poly1305_ctx *c20_ctx,
+ const uint8_t nonce[12], const uint8_t *ad,
+ size_t ad_len, const uint8_t *ciphertext,
+ size_t ciphertext_len) {
uint8_t poly1305_key[32] ALIGNED;
- poly1305_state poly1305;
+ memset(poly1305_key, 0, sizeof(poly1305_key));
+ CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key),
+ c20_ctx->key, nonce, 0);
+ poly1305_state ctx;
+ CRYPTO_poly1305_init(&ctx, poly1305_key);
+ update(&ctx, ad, ad_len, ciphertext, ciphertext_len);
+ CRYPTO_poly1305_finish(&ctx, tag);
+}
+
+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;
- /* The underlying ChaCha implementation may not overflow the block
- * counter into the second counter word. Therefore we disallow
+ /* |CRYPTO_chacha_20| uses a 32-bit block counter. Therefore we disallow
* individual operations that work on more than 256GB at a time.
* |in_len_64| is needed because, on 32-bit platforms, size_t is only
* 32-bits and this produces a warning because it's always false.
* Casting to uint64_t inside the conditional is not sufficient to stop
* the warning. */
if (in_len_64 >= (1ull << 32) * 64 - 64) {
- OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_seal, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
if (in_len + c20_ctx->tag_len < in_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_seal, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
if (max_out_len < in_len + c20_ctx->tag_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_seal,
- CIPHER_R_BUFFER_TOO_SMALL);
- return 0;
- }
-
- if (nonce_len != CHACHA20_NONCE_LEN) {
- OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_seal, CIPHER_R_IV_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
- memset(poly1305_key, 0, sizeof(poly1305_key));
- CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key),
- c20_ctx->key, nonce, 0);
-
- CRYPTO_poly1305_init(&poly1305, poly1305_key);
- poly1305_update_with_length(&poly1305, ad, ad_len);
CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1);
- poly1305_update_with_length(&poly1305, out, in_len);
uint8_t tag[POLY1305_TAG_LEN] ALIGNED;
- CRYPTO_poly1305_finish(&poly1305, tag);
+ aead_poly1305(poly1305_update, tag, c20_ctx, nonce, ad, ad_len, out, in_len);
+
memcpy(out + in_len, tag, c20_ctx->tag_len);
*out_len = in_len + c20_ctx->tag_len;
return 1;
}
-static int aead_chacha20_poly1305_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) {
+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;
- uint8_t mac[POLY1305_TAG_LEN];
- uint8_t poly1305_key[32] ALIGNED;
size_t plaintext_len;
- poly1305_state poly1305;
const uint64_t in_len_64 = in_len;
if (in_len < c20_ctx->tag_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
- /* The underlying ChaCha implementation may not overflow the block
- * counter into the second counter word. Therefore we disallow
+ /* |CRYPTO_chacha_20| uses a 32-bit block counter. Therefore we disallow
* individual operations that work on more than 256GB at a time.
* |in_len_64| is needed because, on 32-bit platforms, size_t is only
* 32-bits and this produces a warning because it's always false.
* Casting to uint64_t inside the conditional is not sufficient to stop
* the warning. */
if (in_len_64 >= (1ull << 32) * 64 - 64) {
- OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_open, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
- if (nonce_len != CHACHA20_NONCE_LEN) {
- OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_open, CIPHER_R_IV_TOO_LARGE);
+ plaintext_len = in_len - c20_ctx->tag_len;
+ uint8_t tag[POLY1305_TAG_LEN] ALIGNED;
+ aead_poly1305(poly1305_update, tag, c20_ctx, nonce, ad, ad_len, in,
+ plaintext_len);
+ if (CRYPTO_memcmp(tag, in + plaintext_len, c20_ctx->tag_len) != 0) {
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
- plaintext_len = in_len - c20_ctx->tag_len;
+ CRYPTO_chacha_20(out, in, plaintext_len, c20_ctx->key, nonce, 1);
+ *out_len = plaintext_len;
+ return 1;
+}
- if (max_out_len < plaintext_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_open,
- CIPHER_R_BUFFER_TOO_SMALL);
- return 0;
- }
+static void poly1305_update_padded_16(poly1305_state *poly1305,
+ const uint8_t *data, size_t data_len) {
+ static const uint8_t padding[16] = { 0 }; /* Padding is all zeros. */
- memset(poly1305_key, 0, sizeof(poly1305_key));
- CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key),
- c20_ctx->key, nonce, 0);
+ CRYPTO_poly1305_update(poly1305, data, data_len);
+ if (data_len % 16 != 0) {
+ CRYPTO_poly1305_update(poly1305, padding, sizeof(padding) - (data_len % 16));
+ }
+}
- CRYPTO_poly1305_init(&poly1305, poly1305_key);
- poly1305_update_with_length(&poly1305, ad, ad_len);
- poly1305_update_with_length(&poly1305, in, plaintext_len);
- CRYPTO_poly1305_finish(&poly1305, mac);
+static void poly1305_update(poly1305_state *ctx, const uint8_t *ad,
+ size_t ad_len, const uint8_t *ciphertext,
+ size_t ciphertext_len) {
+ poly1305_update_padded_16(ctx, ad, ad_len);
+ poly1305_update_padded_16(ctx, ciphertext, ciphertext_len);
+ poly1305_update_length(ctx, ad_len);
+ poly1305_update_length(ctx, ciphertext_len);
+}
- if (CRYPTO_memcmp(mac, in + plaintext_len, c20_ctx->tag_len) != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_open, CIPHER_R_BAD_DECRYPT);
+static int aead_chacha20_poly1305_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) {
+ if (nonce_len != 12) {
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
return 0;
}
+ return seal_impl(poly1305_update, ctx, out, out_len, max_out_len, nonce, in,
+ in_len, ad, ad_len);
+}
- CRYPTO_chacha_20(out, in, plaintext_len, c20_ctx->key, nonce, 1);
- *out_len = plaintext_len;
- return 1;
+static int aead_chacha20_poly1305_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) {
+ if (nonce_len != 12) {
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
+ return 0;
+ }
+ 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 = {
32, /* key len */
- CHACHA20_NONCE_LEN, /* nonce len */
+ 12, /* nonce len */
POLY1305_TAG_LEN, /* overhead */
POLY1305_TAG_LEN, /* max tag length */
aead_chacha20_poly1305_init,
@@ -215,8 +242,70 @@ static const EVP_AEAD aead_chacha20_poly1305 = {
aead_chacha20_poly1305_seal,
aead_chacha20_poly1305_open,
NULL, /* get_rc4_state */
+ NULL, /* get_iv */
};
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) {
+ CRYPTO_poly1305_update(ctx, ad, ad_len);
+ poly1305_update_length(ctx, ad_len);
+ CRYPTO_poly1305_update(ctx, ciphertext, ciphertext_len);
+ poly1305_update_length(ctx, ciphertext_len);
+}
+
+static int aead_chacha20_poly1305_old_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) {
+ if (nonce_len != 8) {
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
+ return 0;
+ }
+ uint8_t nonce_96[12];
+ memset(nonce_96, 0, 4);
+ memcpy(nonce_96 + 4, nonce, 8);
+ 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(
+ 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) {
+ if (nonce_len != 8) {
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
+ return 0;
+ }
+ uint8_t nonce_96[12];
+ memset(nonce_96, 0, 4);
+ memcpy(nonce_96 + 4, nonce, 8);
+ 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 = {
+ 32, /* key len */
+ 8, /* nonce len */
+ POLY1305_TAG_LEN, /* overhead */
+ POLY1305_TAG_LEN, /* max tag length */
+ aead_chacha20_poly1305_init,
+ NULL, /* init_with_direction */
+ aead_chacha20_poly1305_cleanup,
+ aead_chacha20_poly1305_old_seal,
+ aead_chacha20_poly1305_old_open,
+ NULL, /* get_rc4_state */
+ NULL, /* get_iv */
+};
+
+const EVP_AEAD *EVP_aead_chacha20_poly1305_old(void) {
+ return &aead_chacha20_poly1305_old;
+}
diff --git a/src/crypto/cipher/e_des.c b/src/crypto/cipher/e_des.c
index 4c09a81..b1d312c 100644
--- a/src/crypto/cipher/e_des.c
+++ b/src/crypto/cipher/e_des.c
@@ -96,6 +96,31 @@ static const EVP_CIPHER des_cbc = {
const EVP_CIPHER *EVP_des_cbc(void) { return &des_cbc; }
+static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
+ size_t in_len) {
+ if (in_len < ctx->cipher->block_size) {
+ return 1;
+ }
+ in_len -= ctx->cipher->block_size;
+
+ EVP_DES_KEY *dat = (EVP_DES_KEY *) ctx->cipher_data;
+ size_t i;
+ for (i = 0; i <= in_len; i += ctx->cipher->block_size) {
+ DES_ecb_encrypt((DES_cblock *) (in + i), (DES_cblock *) (out + i),
+ &dat->ks.ks, ctx->encrypt);
+ }
+ return 1;
+}
+
+static const EVP_CIPHER des_ecb = {
+ NID_des_ecb, 8 /* block_size */, 8 /* key_size */,
+ 0 /* iv_len */, sizeof(EVP_DES_KEY), EVP_CIPH_ECB_MODE,
+ NULL /* app_data */, des_init_key, des_ecb_cipher,
+ NULL /* cleanup */, NULL /* ctrl */, };
+
+const EVP_CIPHER *EVP_des_ecb(void) { return &des_ecb; }
+
+
typedef struct {
union {
double align;
@@ -126,10 +151,57 @@ static int des_ede3_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out,
return 1;
}
-static const EVP_CIPHER des3_cbc = {
+static const EVP_CIPHER des_ede3_cbc = {
NID_des_ede3_cbc, 8 /* block_size */, 24 /* key_size */,
8 /* iv_len */, sizeof(DES_EDE_KEY), EVP_CIPH_CBC_MODE,
NULL /* app_data */, des_ede3_init_key, des_ede3_cbc_cipher,
NULL /* cleanup */, NULL /* ctrl */, };
-const EVP_CIPHER *EVP_des_ede3_cbc(void) { return &des3_cbc; }
+const EVP_CIPHER *EVP_des_ede3_cbc(void) { return &des_ede3_cbc; }
+
+
+static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
+ const uint8_t *iv, int enc) {
+ DES_cblock *deskey = (DES_cblock *) key;
+ DES_EDE_KEY *dat = (DES_EDE_KEY *) ctx->cipher_data;
+
+ DES_set_key(&deskey[0], &dat->ks.ks[0]);
+ DES_set_key(&deskey[1], &dat->ks.ks[1]);
+ DES_set_key(&deskey[0], &dat->ks.ks[2]);
+
+ return 1;
+}
+
+static const EVP_CIPHER des_ede_cbc = {
+ NID_des_ede_cbc, 8 /* block_size */, 16 /* key_size */,
+ 8 /* iv_len */, sizeof(DES_EDE_KEY), EVP_CIPH_CBC_MODE,
+ NULL /* app_data */, des_ede_init_key , des_ede3_cbc_cipher,
+ NULL /* cleanup */, NULL /* ctrl */, };
+
+const EVP_CIPHER *EVP_des_ede_cbc(void) { return &des_ede_cbc; }
+
+
+static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out,
+ const uint8_t *in, size_t in_len) {
+ if (in_len < ctx->cipher->block_size) {
+ return 1;
+ }
+ in_len -= ctx->cipher->block_size;
+
+ DES_EDE_KEY *dat = (DES_EDE_KEY *) ctx->cipher_data;
+ size_t i;
+ for (i = 0; i <= in_len; i += ctx->cipher->block_size) {
+ DES_ecb3_encrypt((DES_cblock *) (in + i), (DES_cblock *) (out + i),
+ &dat->ks.ks[0], &dat->ks.ks[1], &dat->ks.ks[2],
+ ctx->encrypt);
+ }
+ return 1;
+}
+
+static const EVP_CIPHER des_ede_ecb = {
+ NID_des_ede_cbc, 8 /* block_size */, 16 /* key_size */,
+ 0 /* iv_len */, sizeof(DES_EDE_KEY), EVP_CIPH_ECB_MODE,
+ NULL /* app_data */, des_ede_init_key , des_ede_ecb_cipher,
+ NULL /* cleanup */, NULL /* ctrl */, };
+
+const EVP_CIPHER *EVP_des_ede(void) { return &des_ede_ecb; }
diff --git a/src/crypto/cipher/e_rc2.c b/src/crypto/cipher/e_rc2.c
index c90ab93..8ca7bba 100644
--- a/src/crypto/cipher/e_rc2.c
+++ b/src/crypto/cipher/e_rc2.c
@@ -395,13 +395,18 @@ static int rc2_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) {
case EVP_CTRL_INIT:
key->key_bits = EVP_CIPHER_CTX_key_length(ctx) * 8;
return 1;
+ case EVP_CTRL_SET_RC2_KEY_BITS:
+ /* Should be overridden by later call to |EVP_CTRL_INIT|, but
+ * people call it, so it may as well work. */
+ key->key_bits = arg;
+ return 1;
default:
return -1;
}
}
-static const EVP_CIPHER rc2_40_cbc_cipher = {
+static const EVP_CIPHER rc2_40_cbc = {
NID_rc2_40_cbc,
8 /* block size */,
5 /* 40 bit */,
@@ -416,5 +421,23 @@ static const EVP_CIPHER rc2_40_cbc_cipher = {
};
const EVP_CIPHER *EVP_rc2_40_cbc(void) {
- return &rc2_40_cbc_cipher;
+ return &rc2_40_cbc;
+}
+
+static const EVP_CIPHER rc2_cbc = {
+ NID_rc2_cbc,
+ 8 /* block size */,
+ 16 /* 128 bit */,
+ 8 /* iv len */,
+ sizeof(EVP_RC2_KEY),
+ EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
+ NULL /* app_data */,
+ rc2_init_key,
+ rc2_cbc_cipher,
+ NULL,
+ rc2_ctrl,
+};
+
+const EVP_CIPHER *EVP_rc2_cbc(void) {
+ return &rc2_cbc;
}
diff --git a/src/crypto/cipher/e_rc4.c b/src/crypto/cipher/e_rc4.c
index 80dea36..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,305 +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, aead_rc4_md5_tls_init, 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, aead_rc4_md5_tls_init, 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, aead_rc4_md5_tls_init, 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, aead_rc4_md5_tls_seal, CIPHER_R_TOO_LARGE);
- return 0;
- }
-
- if (nonce_len != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_seal, CIPHER_R_IV_TOO_LARGE);
- return 0;
- }
-
- if (max_out_len < in_len + rc4_ctx->tag_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_seal, CIPHER_R_BUFFER_TOO_SMALL);
- return 0;
- }
-
- if (nonce_len != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_seal, 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, aead_rc4_md5_tls_open, CIPHER_R_BAD_DECRYPT);
- return 0;
- }
-
- plaintext_len = in_len - rc4_ctx->tag_len;
-
- if (nonce_len != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_open, 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, aead_rc4_md5_tls_open, 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, aead_rc4_md5_tls_open, 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,
-};
-
-const EVP_AEAD *EVP_aead_rc4_md5_tls(void) { return &aead_rc4_md5_tls; }
diff --git a/src/crypto/cipher/e_ssl3.c b/src/crypto/cipher/e_ssl3.c
index 1031d9b..7dddf24 100644
--- a/src/crypto/cipher/e_ssl3.c
+++ b/src/crypto/cipher/e_ssl3.c
@@ -85,12 +85,12 @@ static int aead_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len,
const EVP_CIPHER *cipher, const EVP_MD *md) {
if (tag_len != EVP_AEAD_DEFAULT_TAG_LENGTH &&
tag_len != EVP_MD_size(md)) {
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_init, CIPHER_R_UNSUPPORTED_TAG_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_TAG_SIZE);
return 0;
}
if (key_len != EVP_AEAD_key_length(ctx->aead)) {
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_init, CIPHER_R_BAD_KEY_LENGTH);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
return 0;
}
@@ -102,7 +102,7 @@ static int aead_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len,
AEAD_SSL3_CTX *ssl3_ctx = OPENSSL_malloc(sizeof(AEAD_SSL3_CTX));
if (ssl3_ctx == NULL) {
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_init, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
return 0;
}
EVP_CIPHER_CTX_init(&ssl3_ctx->cipher_ctx);
@@ -133,29 +133,29 @@ static int aead_ssl3_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
if (!ssl3_ctx->cipher_ctx.encrypt) {
/* Unlike a normal AEAD, an SSL3 AEAD may only be used in one direction. */
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_seal, CIPHER_R_INVALID_OPERATION);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION);
return 0;
}
if (in_len + EVP_AEAD_max_overhead(ctx->aead) < in_len ||
in_len > INT_MAX) {
/* EVP_CIPHER takes int as input. */
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_seal, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
if (max_out_len < in_len + EVP_AEAD_max_overhead(ctx->aead)) {
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_seal, CIPHER_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
if (nonce_len != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_seal, CIPHER_R_IV_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_IV_TOO_LARGE);
return 0;
}
if (ad_len != 11 - 2 /* length bytes */) {
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_seal, CIPHER_R_INVALID_AD_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_AD_SIZE);
return 0;
}
@@ -217,36 +217,36 @@ static int aead_ssl3_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
if (ssl3_ctx->cipher_ctx.encrypt) {
/* Unlike a normal AEAD, an SSL3 AEAD may only be used in one direction. */
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_INVALID_OPERATION);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION);
return 0;
}
size_t mac_len = EVP_MD_CTX_size(&ssl3_ctx->md_ctx);
if (in_len < mac_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
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, aead_ssl3_open, CIPHER_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
if (nonce_len != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
if (ad_len != 11 - 2 /* length bytes */) {
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_INVALID_AD_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_AD_SIZE);
return 0;
}
if (in_len > INT_MAX) {
/* EVP_CIPHER takes int as input. */
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
@@ -270,12 +270,12 @@ static int aead_ssl3_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
if (EVP_CIPHER_CTX_mode(&ssl3_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE) {
unsigned padding_length = out[total - 1];
if (total < padding_length + 1 + mac_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
/* The padding must be minimal. */
if (padding_length + 1 > EVP_CIPHER_CTX_block_size(&ssl3_ctx->cipher_ctx)) {
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
data_len = total - padding_length - 1 - mac_len;
@@ -289,7 +289,7 @@ static int aead_ssl3_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
return 0;
}
if (CRYPTO_memcmp(&out[data_len], mac, mac_len) != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
@@ -307,6 +307,19 @@ static int aead_ssl3_get_rc4_state(const EVP_AEAD_CTX *ctx, const RC4_KEY **out_
return 1;
}
+static int aead_ssl3_get_iv(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv,
+ size_t *out_iv_len) {
+ AEAD_SSL3_CTX *ssl3_ctx = (AEAD_SSL3_CTX *)ctx->aead_state;
+ const size_t iv_len = EVP_CIPHER_CTX_iv_length(&ssl3_ctx->cipher_ctx);
+ if (iv_len <= 1) {
+ return 0;
+ }
+
+ *out_iv = ssl3_ctx->cipher_ctx.iv;
+ *out_iv_len = iv_len;
+ return 1;
+}
+
static int aead_rc4_md5_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
size_t key_len, size_t tag_len,
enum evp_aead_direction_t dir) {
@@ -340,6 +353,13 @@ static int aead_des_ede3_cbc_sha1_ssl3_init(EVP_AEAD_CTX *ctx,
EVP_sha1());
}
+static int aead_null_sha1_ssl3_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_ssl3_init(ctx, key, key_len, tag_len, dir, EVP_enc_null(),
+ EVP_sha1());
+}
+
static const EVP_AEAD aead_rc4_md5_ssl3 = {
MD5_DIGEST_LENGTH + 16, /* key len (MD5 + RC4) */
0, /* nonce len */
@@ -351,6 +371,7 @@ static const EVP_AEAD aead_rc4_md5_ssl3 = {
aead_ssl3_seal,
aead_ssl3_open,
aead_ssl3_get_rc4_state,
+ NULL, /* get_iv */
};
static const EVP_AEAD aead_rc4_sha1_ssl3 = {
@@ -364,6 +385,7 @@ static const EVP_AEAD aead_rc4_sha1_ssl3 = {
aead_ssl3_seal,
aead_ssl3_open,
aead_ssl3_get_rc4_state,
+ NULL, /* get_iv */
};
static const EVP_AEAD aead_aes_128_cbc_sha1_ssl3 = {
@@ -377,6 +399,7 @@ static const EVP_AEAD aead_aes_128_cbc_sha1_ssl3 = {
aead_ssl3_seal,
aead_ssl3_open,
NULL, /* get_rc4_state */
+ aead_ssl3_get_iv,
};
static const EVP_AEAD aead_aes_256_cbc_sha1_ssl3 = {
@@ -390,6 +413,7 @@ static const EVP_AEAD aead_aes_256_cbc_sha1_ssl3 = {
aead_ssl3_seal,
aead_ssl3_open,
NULL, /* get_rc4_state */
+ aead_ssl3_get_iv,
};
static const EVP_AEAD aead_des_ede3_cbc_sha1_ssl3 = {
@@ -403,6 +427,21 @@ static const EVP_AEAD aead_des_ede3_cbc_sha1_ssl3 = {
aead_ssl3_seal,
aead_ssl3_open,
NULL, /* get_rc4_state */
+ aead_ssl3_get_iv,
+};
+
+static const EVP_AEAD aead_null_sha1_ssl3 = {
+ SHA_DIGEST_LENGTH, /* key len */
+ 0, /* nonce len */
+ SHA_DIGEST_LENGTH, /* overhead (SHA1) */
+ SHA_DIGEST_LENGTH, /* max tag length */
+ NULL, /* init */
+ aead_null_sha1_ssl3_init,
+ aead_ssl3_cleanup,
+ aead_ssl3_seal,
+ aead_ssl3_open,
+ NULL, /* get_rc4_state */
+ NULL, /* get_iv */
};
const EVP_AEAD *EVP_aead_rc4_md5_ssl3(void) { return &aead_rc4_md5_ssl3; }
@@ -420,3 +459,5 @@ const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_ssl3(void) {
const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_ssl3(void) {
return &aead_des_ede3_cbc_sha1_ssl3;
}
+
+const EVP_AEAD *EVP_aead_null_sha1_ssl3(void) { return &aead_null_sha1_ssl3; }
diff --git a/src/crypto/cipher/e_tls.c b/src/crypto/cipher/e_tls.c
index bed02cb..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>
@@ -57,12 +58,12 @@ static int aead_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len,
char implicit_iv) {
if (tag_len != EVP_AEAD_DEFAULT_TAG_LENGTH &&
tag_len != EVP_MD_size(md)) {
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_init, CIPHER_R_UNSUPPORTED_TAG_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_TAG_SIZE);
return 0;
}
if (key_len != EVP_AEAD_key_length(ctx->aead)) {
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_init, CIPHER_R_BAD_KEY_LENGTH);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
return 0;
}
@@ -75,7 +76,7 @@ static int aead_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len,
AEAD_TLS_CTX *tls_ctx = OPENSSL_malloc(sizeof(AEAD_TLS_CTX));
if (tls_ctx == NULL) {
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_init, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
return 0;
}
EVP_CIPHER_CTX_init(&tls_ctx->cipher_ctx);
@@ -109,30 +110,29 @@ static int aead_tls_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
if (!tls_ctx->cipher_ctx.encrypt) {
/* Unlike a normal AEAD, a TLS AEAD may only be used in one direction. */
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_seal, CIPHER_R_INVALID_OPERATION);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION);
return 0;
-
}
if (in_len + EVP_AEAD_max_overhead(ctx->aead) < in_len ||
in_len > INT_MAX) {
/* EVP_CIPHER takes int as input. */
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_seal, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
if (max_out_len < in_len + EVP_AEAD_max_overhead(ctx->aead)) {
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_seal, CIPHER_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) {
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_seal, CIPHER_R_INVALID_NONCE_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE);
return 0;
}
if (ad_len != 13 - 2 /* length bytes */) {
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_seal, CIPHER_R_INVALID_AD_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_AD_SIZE);
return 0;
}
@@ -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 &&
@@ -214,36 +210,35 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
if (tls_ctx->cipher_ctx.encrypt) {
/* Unlike a normal AEAD, a TLS AEAD may only be used in one direction. */
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_INVALID_OPERATION);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION);
return 0;
-
}
if (in_len < HMAC_size(&tls_ctx->hmac_ctx)) {
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
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, aead_tls_open, CIPHER_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) {
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_INVALID_NONCE_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE);
return 0;
}
if (ad_len != 13 - 2 /* length bytes */) {
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_INVALID_AD_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_AD_SIZE);
return 0;
}
if (in_len > INT_MAX) {
/* EVP_CIPHER takes int as input. */
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
@@ -278,7 +273,7 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
(unsigned)HMAC_size(&tls_ctx->hmac_ctx));
/* Publicly invalid. This can be rejected in non-constant time. */
if (padding_ok == 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
} else {
@@ -312,7 +307,7 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
if (!EVP_tls_cbc_digest_record(tls_ctx->hmac_ctx.md, mac, &mac_len,
ad_fixed, out, data_plus_mac_len, total,
tls_ctx->mac_key, tls_ctx->mac_key_len)) {
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
assert(mac_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];
@@ -349,7 +340,7 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
0);
good &= constant_time_eq_int(padding_ok, 1);
if (!good) {
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
@@ -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;
@@ -444,17 +442,52 @@ static int aead_rc4_sha1_tls_get_rc4_state(const EVP_AEAD_CTX *ctx,
return 1;
}
+static int aead_tls_get_iv(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv,
+ size_t *out_iv_len) {
+ const AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX*) ctx->aead_state;
+ const size_t iv_len = EVP_CIPHER_CTX_iv_length(&tls_ctx->cipher_ctx);
+ if (iv_len <= 1) {
+ return 0;
+ }
+
+ *out_iv = tls_ctx->cipher_ctx.iv;
+ *out_iv_len = iv_len;
+ return 1;
+}
+
+static int aead_null_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) {
+ return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_enc_null(),
+ 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 */
+ aead_rc4_tls_get_rc4_state, /* get_rc4_state */
+ NULL, /* get_iv */
};
static const EVP_AEAD aead_aes_128_cbc_sha1_tls = {
@@ -468,6 +501,7 @@ static const EVP_AEAD aead_aes_128_cbc_sha1_tls = {
aead_tls_seal,
aead_tls_open,
NULL, /* get_rc4_state */
+ NULL, /* get_iv */
};
static const EVP_AEAD aead_aes_128_cbc_sha1_tls_implicit_iv = {
@@ -481,19 +515,21 @@ static const EVP_AEAD aead_aes_128_cbc_sha1_tls_implicit_iv = {
aead_tls_seal,
aead_tls_open,
NULL, /* get_rc4_state */
+ aead_tls_get_iv, /* get_iv */
};
static const EVP_AEAD aead_aes_128_cbc_sha256_tls = {
SHA256_DIGEST_LENGTH + 16, /* key len (SHA256 + AES128) */
16, /* nonce len (IV) */
16 + SHA256_DIGEST_LENGTH, /* overhead (padding + SHA256) */
- SHA_DIGEST_LENGTH, /* max tag length */
+ SHA256_DIGEST_LENGTH, /* max tag length */
NULL, /* init */
aead_aes_128_cbc_sha256_tls_init,
aead_tls_cleanup,
aead_tls_seal,
aead_tls_open,
NULL, /* get_rc4_state */
+ NULL, /* get_iv */
};
static const EVP_AEAD aead_aes_256_cbc_sha1_tls = {
@@ -507,6 +543,7 @@ static const EVP_AEAD aead_aes_256_cbc_sha1_tls = {
aead_tls_seal,
aead_tls_open,
NULL, /* get_rc4_state */
+ NULL, /* get_iv */
};
static const EVP_AEAD aead_aes_256_cbc_sha1_tls_implicit_iv = {
@@ -520,32 +557,35 @@ static const EVP_AEAD aead_aes_256_cbc_sha1_tls_implicit_iv = {
aead_tls_seal,
aead_tls_open,
NULL, /* get_rc4_state */
+ aead_tls_get_iv, /* get_iv */
};
static const EVP_AEAD aead_aes_256_cbc_sha256_tls = {
SHA256_DIGEST_LENGTH + 32, /* key len (SHA256 + AES256) */
16, /* nonce len (IV) */
16 + SHA256_DIGEST_LENGTH, /* overhead (padding + SHA256) */
- SHA_DIGEST_LENGTH, /* max tag length */
+ SHA256_DIGEST_LENGTH, /* max tag length */
NULL, /* init */
aead_aes_256_cbc_sha256_tls_init,
aead_tls_cleanup,
aead_tls_seal,
aead_tls_open,
NULL, /* get_rc4_state */
+ NULL, /* get_iv */
};
static const EVP_AEAD aead_aes_256_cbc_sha384_tls = {
SHA384_DIGEST_LENGTH + 32, /* key len (SHA384 + AES256) */
16, /* nonce len (IV) */
16 + SHA384_DIGEST_LENGTH, /* overhead (padding + SHA384) */
- SHA_DIGEST_LENGTH, /* max tag length */
+ SHA384_DIGEST_LENGTH, /* max tag length */
NULL, /* init */
aead_aes_256_cbc_sha384_tls_init,
aead_tls_cleanup,
aead_tls_seal,
aead_tls_open,
NULL, /* get_rc4_state */
+ NULL, /* get_iv */
};
static const EVP_AEAD aead_des_ede3_cbc_sha1_tls = {
@@ -559,6 +599,7 @@ static const EVP_AEAD aead_des_ede3_cbc_sha1_tls = {
aead_tls_seal,
aead_tls_open,
NULL, /* get_rc4_state */
+ NULL, /* get_iv */
};
static const EVP_AEAD aead_des_ede3_cbc_sha1_tls_implicit_iv = {
@@ -572,8 +613,25 @@ static const EVP_AEAD aead_des_ede3_cbc_sha1_tls_implicit_iv = {
aead_tls_seal,
aead_tls_open,
NULL, /* get_rc4_state */
+ aead_tls_get_iv, /* get_iv */
+};
+
+static const EVP_AEAD aead_null_sha1_tls = {
+ SHA_DIGEST_LENGTH, /* key len */
+ 0, /* nonce len */
+ SHA_DIGEST_LENGTH, /* overhead (SHA1) */
+ SHA_DIGEST_LENGTH, /* max tag length */
+ NULL, /* init */
+ aead_null_sha1_tls_init,
+ aead_tls_cleanup,
+ aead_tls_seal,
+ aead_tls_open,
+ NULL, /* get_rc4_state */
+ 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) {
@@ -611,3 +669,5 @@ const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls(void) {
const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv(void) {
return &aead_des_ede3_cbc_sha1_tls_implicit_iv;
}
+
+const EVP_AEAD *EVP_aead_null_sha1_tls(void) { return &aead_null_sha1_tls; }
diff --git a/src/crypto/cipher/internal.h b/src/crypto/cipher/internal.h
index b2a94f4..72ac118 100644
--- a/src/crypto/cipher/internal.h
+++ b/src/crypto/cipher/internal.h
@@ -96,6 +96,9 @@ struct evp_aead_st {
size_t ad_len);
int (*get_rc4_state)(const EVP_AEAD_CTX *ctx, const RC4_KEY **out_key);
+
+ int (*get_iv)(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv,
+ size_t *out_len);
};
diff --git a/src/crypto/cipher/test/aes_128_gcm_tests.txt b/src/crypto/cipher/test/aes_128_gcm_tests.txt
index 5f7ad35..0e33c91 100644
--- a/src/crypto/cipher/test/aes_128_gcm_tests.txt
+++ b/src/crypto/cipher/test/aes_128_gcm_tests.txt
@@ -1,3 +1,6 @@
+# The AES-128-GCM test cases from cipher_test.txt have been merged into this
+# file.
+
KEY: d480429666d48b400633921c5407d1d1
NONCE: 3388c676dc754acfa66e172a
IN:
@@ -418,3 +421,111 @@ AD: 18e2ed6d500b176e49f7e1b5074c0b7dbfdefdf00a63d9fa2fea8c5e78a1c4ae00f17b234429
CT: 5f3627bd53f8da0bbe6f3c9246d6f96fe9abb91cdecf66ddd42f833d98f4d4634c2e1e1ad4088c84c22191bdb9d99ef227320e455dd112c4a9e9cca95724fcc9ae024ed12bf60a802d0b87b99d9bf22590786567c2962171d2b05bec9754c627608e9eba7bccc70540aa4da72e1e04b26d8f968b10230f707501c0091a8ac118f86e87aae1ac00257aee29c3345bd3839154977acd378fc1b2197f5c1fd8e12262f9c2974fb92dc481eeb51aadd44a8851f61b93a84ba57f2870df0423d289bfdcfe634f9ecb7d7c6110a95b49418a2dd6663377690275c205b3efa79a0a77c92567fb429d8ee437312a39df7516dc238f7b9414938223d7ec24d256d3fb3a5954a7c75dbd79486d49ba6bb38a7ccce0f58700260b71319adf98ab8684e34913abe2d9d97193e2
TAG: e690e89af39ff367f5d40a1b7c7ccd4f
+KEY: 31323334353637383930313233343536
+NONCE: 31323334353637383930313233343536
+IN: 48656c6c6f2c20576f726c64
+AD:
+CT: cec189d0e8419b90fb16d555
+TAG: 32893832a8d609224d77c2e56a922282
+
+# AES GCM test vectors from http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf
+
+KEY: 00000000000000000000000000000000
+NONCE: 000000000000000000000000
+IN: ""
+CT: ""
+AD: ""
+TAG: 58e2fccefa7e3061367f1d57a4e7455a
+
+KEY: 00000000000000000000000000000000
+NONCE: 000000000000000000000000
+IN: 00000000000000000000000000000000
+CT: 0388dace60b6a392f328c2b971b2fe78
+AD: ""
+TAG: ab6e47d42cec13bdf53a67b21257bddf
+
+KEY: feffe9928665731c6d6a8f9467308308
+NONCE: cafebabefacedbaddecaf888
+IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255
+CT: 42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985
+AD: ""
+TAG: 4d5c2af327cd64a62cf35abd2ba6fab4
+
+KEY: feffe9928665731c6d6a8f9467308308
+NONCE: cafebabefacedbaddecaf888
+IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+CT: 42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091
+AD: feedfacedeadbeeffeedfacedeadbeefabaddad2
+TAG: 5bc94fbc3221a5db94fae95ae7121a47
+
+KEY: feffe9928665731c6d6a8f9467308308
+NONCE: cafebabefacedbad
+IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+CT: 61353b4c2806934a777ff51fa22a4755699b2a714fcdc6f83766e5f97b6c742373806900e49f24b22b097544d4896b424989b5e1ebac0f07c23f4598
+AD: feedfacedeadbeeffeedfacedeadbeefabaddad2
+TAG: 3612d2e79e3b0785561be14aaca2fccb
+
+KEY: feffe9928665731c6d6a8f9467308308
+NONCE: 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b
+IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+CT: 8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5
+AD: feedfacedeadbeeffeedfacedeadbeefabaddad2
+TAG: 619cc5aefffe0bfa462af43c1699d050
+
+# local add-ons, primarily streaming ghash tests
+
+# 128 bytes AD
+KEY: 00000000000000000000000000000000
+NONCE: 000000000000000000000000
+IN: ""
+CT: ""
+AD: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad
+TAG: 5fea793a2d6f974d37e68e0cb8ff9492
+
+# 48 bytes plaintext
+KEY: 00000000000000000000000000000000
+NONCE: 000000000000000000000000
+IN: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+CT: 0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0
+AD: ""
+TAG: 9dd0a376b08e40eb00c35f29f9ea61a4
+
+# 80 bytes plaintext
+KEY: 00000000000000000000000000000000
+NONCE: 000000000000000000000000
+IN: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+CT: 0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0c94da219118e297d7b7ebcbcc9c388f28ade7d85a8ee35616f7124a9d5270291
+AD: ""
+TAG: 98885a3a22bd4742fe7b72172193b163
+
+# 128 bytes plaintext
+KEY: 00000000000000000000000000000000
+NONCE: 000000000000000000000000
+IN: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+CT: 0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0c94da219118e297d7b7ebcbcc9c388f28ade7d85a8ee35616f7124a9d527029195b84d1b96c690ff2f2de30bf2ec89e00253786e126504f0dab90c48a30321de3345e6b0461e7c9e6c6b7afedde83f40
+AD: ""
+TAG: cac45f60e31efd3b5a43b98a22ce1aa1
+
+# 192 bytes plaintext, iv is chosen so that initial counter LSB is 0xFF
+KEY: 00000000000000000000000000000000
+NONCE: ffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+IN: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+CT: 56b3373ca9ef6e4a2b64fe1e9a17b61425f10d47a75a5fce13efc6bc784af24f4141bdd48cf7c770887afd573cca5418a9aeffcd7c5ceddfc6a78397b9a85b499da558257267caab2ad0b23ca476a53cb17fb41c4b8b475cb4f3f7165094c229c9e8c4dc0a2a5ff1903e501511221376a1cdb8364c5061a20cae74bc4acd76ceb0abc9fd3217ef9f8c90be402ddf6d8697f4f880dff15bfb7a6b28241ec8fe183c2d59e3f9dfff653c7126f0acb9e64211f42bae12af462b1070bef1ab5e3606
+AD: ""
+TAG: 566f8ef683078bfdeeffa869d751a017
+
+# 288 bytes plaintext, iv is chosen so that initial counter LSB is 0xFF
+KEY: 00000000000000000000000000000000
+NONCE: ffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+IN: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+CT: 56b3373ca9ef6e4a2b64fe1e9a17b61425f10d47a75a5fce13efc6bc784af24f4141bdd48cf7c770887afd573cca5418a9aeffcd7c5ceddfc6a78397b9a85b499da558257267caab2ad0b23ca476a53cb17fb41c4b8b475cb4f3f7165094c229c9e8c4dc0a2a5ff1903e501511221376a1cdb8364c5061a20cae74bc4acd76ceb0abc9fd3217ef9f8c90be402ddf6d8697f4f880dff15bfb7a6b28241ec8fe183c2d59e3f9dfff653c7126f0acb9e64211f42bae12af462b1070bef1ab5e3606872ca10dee15b3249b1a1b958f23134c4bccb7d03200bce420a2f8eb66dcf3644d1423c1b5699003c13ecef4bf38a3b60eedc34033bac1902783dc6d89e2e774188a439c7ebcc0672dbda4ddcfb2794613b0be41315ef778708a70ee7d75165c
+AD: ""
+TAG: 8b307f6b33286d0ab026a9ed3fe1e85f
+
+# 80 bytes plaintext, submitted by Intel
+KEY: 843ffcf5d2b72694d19ed01d01249412
+NONCE: dbcca32ebf9b804617c3aa9e
+IN: 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f
+AD: 00000000000000000000000000000000101112131415161718191a1b1c1d1e1f
+CT: 6268c6fa2a80b2d137467f092f657ac04d89be2beaa623d61b5a868c8f03ff95d3dcee23ad2f1ab3a6c80eaf4b140eb05de3457f0fbc111a6b43d0763aa422a3013cf1dc37fe417d1fbfc449b75d4cc5
+TAG: 3b629ccfbc1119b7319e1dce2cd6fd6d
diff --git a/src/crypto/cipher/test/aes_256_gcm_tests.txt b/src/crypto/cipher/test/aes_256_gcm_tests.txt
index 021c275..dbcee81 100644
--- a/src/crypto/cipher/test/aes_256_gcm_tests.txt
+++ b/src/crypto/cipher/test/aes_256_gcm_tests.txt
@@ -1,3 +1,6 @@
+# The AES-256-GCM test cases from cipher_test.txt have been merged into this
+# file.
+
KEY: e5ac4a32c67e425ac4b143c83c6f161312a97d88d634afdf9f4da5bd35223f01
NONCE: 5bf11a0951f0bfc7ea5c9e58
IN:
@@ -418,3 +421,46 @@ AD: 2134f74e882a44e457c38b6580cd58ce20e81267baeb4a9d50c41ababc2a91ddf300c3996364
CT: 0fe35823610ea698aeb5b571f3ebbaf0ac3586ecb3b24fcc7c56943d4426f7fdf4e4a53fb430751456d41551f8e5502faa0e1ac5f452b27b13c1dc63e9231c6b192f8dd2978300293298acb6293459d3204429e374881085d49ed6ad76f1d85e3f6dd5455a7a5a9d7127386a30f80658395dc8eb158e5ca052a7137feef28aa247e176cceb9c031f73fb8d48139e3bdb30e2e19627f7fc3501a6d6287e2fb89ad184cefa1774585aa663586f289c778462eee3cd88071140274770e4ed98b9b83cd4fa659fcdd2d1fde7e58333c6cf7f83fe285b97ad8f276a375fafa15f88e6167f5f2bfb95af1aefee80b0620a9bc09402ab79036e716f0c8d518ae2fa15094f6ea4c5e8b283f97cc27f2f1d0b6367b4b508c7bad16f1539325751bd785e9e08cd508bdb3b84
TAG: 1976d7e121704ce463a8d4fe1b93d90f
+# AES GCM test vectors from http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf
+
+KEY: 0000000000000000000000000000000000000000000000000000000000000000
+NONCE: 000000000000000000000000
+IN: ""
+CT: ""
+AD: ""
+TAG: 530f8afbc74536b9a963b4f1c4cb738b
+
+KEY: 0000000000000000000000000000000000000000000000000000000000000000
+NONCE: 000000000000000000000000
+IN: 00000000000000000000000000000000
+CT: cea7403d4d606b6e074ec5d3baf39d18
+AD: ""
+TAG: d0d1c8a799996bf0265b98b5d48ab919
+
+KEY: feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308
+NONCE: cafebabefacedbaddecaf888
+IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255
+CT: 522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad
+AD: ""
+TAG: b094dac5d93471bdec1a502270e3cc6c
+
+KEY: feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308
+NONCE: cafebabefacedbaddecaf888
+IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+CT: 522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662
+AD: feedfacedeadbeeffeedfacedeadbeefabaddad2
+TAG: 76fc6ece0f4e1768cddf8853bb2d551b
+
+KEY: feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308
+NONCE: cafebabefacedbad
+IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+CT: c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0feb582d33934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f
+AD: feedfacedeadbeeffeedfacedeadbeefabaddad2
+TAG: 3a337dbf46a792c45e454913fe2ea8f2
+
+KEY: feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308
+NONCE: 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b
+IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+CT: 5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf40fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3f
+AD: feedfacedeadbeeffeedfacedeadbeefabaddad2
+TAG: a44a8266ee1c8eb0c8b5d4cf5ae9f19a
diff --git a/src/crypto/cipher/test/chacha20_poly1305_old_tests.txt b/src/crypto/cipher/test/chacha20_poly1305_old_tests.txt
new file mode 100644
index 0000000..d40b21c
--- /dev/null
+++ b/src/crypto/cipher/test/chacha20_poly1305_old_tests.txt
@@ -0,0 +1,524 @@
+KEY: 9a97f65b9b4c721b960a672145fca8d4e32e67f9111ea979ce9c4826806aeee6
+NONCE: 3de9c0da2bd7f91e
+IN: ""
+AD: ""
+CT: ""
+TAG: 5a6e21f4ba6dbee57380e79e79c30def
+
+KEY: bcb2639bf989c6251b29bf38d39a9bdce7c55f4b2ac12a39c8a37b5d0a5cc2b5
+NONCE: 1e8b4c510f5ca083
+IN: 8c8419bc27
+AD: 34ab88c265
+CT: 1a7c2f33f5
+TAG: 2875c659d0f2808de3a40027feff91a4
+
+KEY: 4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd1100a1007
+NONCE: cd7cf67be39c794a
+IN: 86d09974840bded2a5ca
+AD: 87e229d4500845a079c0
+CT: e3e446f7ede9a19b62a4
+TAG: 677dabf4e3d24b876bb284753896e1d6
+
+KEY: 422a5355b56dcf2b436aa8152858106a88d9ba23cdfe087b5e74e817a52388b3
+NONCE: 1d12d6d91848f2ea
+IN: 537a645387f22d6f6dbbea568d3feb
+AD: bef267c99aec8af56bc238612bfea6
+CT: 281a366705c5a24b94e56146681e44
+TAG: 38f2b8ee3be44abba3c010d9cab6e042
+
+KEY: ec7b864a078c3d05d970b6ea3ba6d33d6bb73dfa64c622a4727a96ede876f685
+NONCE: 2bca0e59e39508d3
+IN: b76733895c871edd728a45ed1a21f15a9597d49d
+AD: cc1243ea54272db602fb0853c8e7027c56338b6c
+CT: 1fb9b2958fce47a5cada9d895fbb0c00d3569858
+TAG: 042ad5042c89ebc1aad57d3fb703d314
+
+KEY: 2c4c0fdb611df2d4d5e7898c6af0022795364adb8749155e2c68776a090e7d5c
+NONCE: 13ce7382734c4a71
+IN: 0dc6ff21a346e1337dd0db81d8f7d9f6fd1864418b98aadcdb
+AD: 0115edcb176ab8bfa947d1f7c3a86a845d310bf6706c59a8f9
+CT: dad65e4244a1a17ce59d88b00af4f7434bd7830ffdd4c5558f
+TAG: ac1437b45d8eacf9c0fe547c84fb82a2
+
+KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
+NONCE: 5d9856060c54ab06
+IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
+AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
+CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
+TAG: 6dd98710d8a889dceea0d0a936f98617
+
+KEY: a8b9766f404dea8cf7d7dfaf5822f53df9ccd092e332a57f007b301b507d5e14
+NONCE: c7f2f7a233104a2d
+IN: 4d6faeaee39179a7c892faae3719656cc614c7e6ecd8fcb570a3b82c4dace969090338
+AD: c6d83b6a56408a356e68d0494d4eff150530b09551d008373d6dee2b8d6b5619d67fdb
+CT: a15443f083316eef627a371f4c9ac654d0dd75255d8a303125e9f51af4233ff4ceb7fe
+TAG: 52504e880f6792a60708cc6db72eae42
+
+KEY: 5e8d0e5f1467f7a750c55144d0c670f7d91075f386795b230c9bf1c04ba250bc
+NONCE: 88049f44ba61b88f
+IN: 51a1eebcc348e0582196a0bce16ed1f8ac2e91c3e8a690e04a9f4b5cf63313d7ad08d1efbff85c89
+AD: 5d09bf0be90026f9fc51f73418d6d864b6d197ea030b3de072bd2c2f5cab5860a342abbd29dba9dc
+CT: 35aa4bd4537aa611fd7578fc227df50ebcb00c692a1cf6f02e50ed9270bd93af3bc68f4c75b96638
+TAG: ccea1cbbc83944cc66df4dbf6fb7fc46
+
+KEY: 21a9f07ec891d488805e9b92bb1b2286f3f0410c323b07fee1dc6f7379e22e48
+NONCE: 066215be6567377a
+IN: c1b0affaf2b8d7ef51cca9aacf7969f92f928c2e3cc7db2e15f47ee1f65023910d09f209d007b7436ee898133d
+AD: dfdfdf4d3a68b47ad0d48828dc17b2585da9c81c3a8d71d826b5fa8020fee002397e91fc9658e9d61d728b93eb
+CT: 8ff4ceb600e7d45696d02467f8e30df0d33864a040a41ffb9e4c2da09b92e88b6f6b850e9f7258d827b9aaf346
+TAG: 4eeddc99784011f0758ba5ebfba61827
+
+KEY: 54c93db9aa0e00d10b45041c7a7e41ee9f90ab78ae4c1bba18d673c3b370abde
+NONCE: 3f2d44e7b352360f
+IN: 1241e7d6fbe5eef5d8af9c2fb8b516e0f1dd49aa4ebe5491205194fe5aea3704efaf30d392f44cc99e0925b84460d4873344
+AD: f1d1b08dd6fe96c46578c1d1ad38881840b10cb5eae41e5f05fe5287223fa72242aea48cb374a80be937b541f9381efa66bb
+CT: 027b86865b80b4c4da823a7d3dbcf5845bf57d58ee334eb357e82369cc628979e2947830d9d4817efd3d0bc4779f0b388943
+TAG: 4303fa0174ac2b9916bf89c593baee37
+
+KEY: 808e0e73e9bcd274d4c6f65df2fe957822a602f039d4752616ba29a28926ef4a
+NONCE: 1b9cd73d2fc3cb8e
+IN: 3436c7b5be2394af7e88320c82326a6db37887ff9de41961c7d654dd22dd1f7d40444d48f5c663b86ff41f3e15b5c8ca1337f97635858f
+AD: d57cfbe5f2538044282e53b2f0bb4e86ea2233041fb36adb8338ded092148f8c2e894ef8766a7ec2dd02c6ac5dbab0c3703c5e9119e37c
+CT: 9b950b3caf7d25eaf5fca6fa3fe12ed077d80dcd5579851233c766bb8bb613ec91d925a939bb52fb88d5eda803cfe2a8cda2e055b962fd
+TAG: 6bf5b718f5bbe1395a5fdfcbbef752f5
+
+KEY: 4adfe1a26c5636536cd7cb72aa5bded0b1aa64487ad0e4078f311e8782768e97
+NONCE: d69e54badec11560
+IN: 19b3f9411ce875fcb684cbdc07938c4c1347e164f9640d37b22f975b4b9a373c4302ae0e7dfdeba1e0d00ced446e338f4c5bc01b4becef5115825276
+AD: bda1b0f6c2f4eb8121dcbd2eebd91a03ae1d6e0523b9b6f34b6f16ceca0d086654fb0552bfd5c8e1887730e1449ea02d7f647ae835bc2dab4bbc65b9
+CT: ea765a829d961e08bacaed801237ef4067df38ad3737b7c6de4db587a102a86fc4abbaabea0ee97c95ca7f571c7bab6f38cbae60cd6e6a4ce3c7a320
+TAG: b425cdf10cd0123a7e64b347c6b4b1f0
+
+KEY: eb3db86c14b7cc2e494345d0dfb4841bbd3aa1e2bc640cca0c6c405520685639
+NONCE: 88b54b28d6da8c81
+IN: f75c0a357271430b1ecff07a307b6c29325c6e66935046704a19845e629f87a9e3b8aa6c1df55dd426a487d533bb333e46f0d3418464ac1bef059231f8e87e6284
+AD: 34b08bb0df821c573dcb56f5b8b4a9920465067f3b5bf3e3254ea1da1a7fc9847fd38bdfe6b30927945263a91fa288c7cf1bee0fddb0fadf5948c5d83eb4623575
+CT: 146ec84f5dc1c9fe9de3307a9182dbaa75965bf85f5e64563e68d039a5b659aa8863b89228edb93ff3d8c3323ab0d03300476aa4aca206d4626a6b269b2078912d
+TAG: 0058a8dff32c29935c62210c359bd281
+
+KEY: dd5b49b5953e04d926d664da3b65ebcffbbf06abbe93a3819dfc1abbecbaab13
+NONCE: c5c8009459b9e31a
+IN: f21f6706a4dc33a361362c214defd56d353bcb29811e5819ab3c5c2c13950c7aa0000b9d1fe69bb46454514dcce88a4a5eda097c281b81e51d6a4dba47c80326ba6cea8e2bab
+AD: fe6f4cbb00794adea59e9de8b03c7fdf482e46f6c47a35f96997669c735ed5e729a49416b42468777e6a8d7aa173c18b8177418ded600124a98cbb65489f9c24a04f1e7127ce
+CT: 911ead61b2aa81d00c5eff53aeea3ab713709ed571765890d558fb59d3993b45f598a39e5eff4be844c4d4bd1ef9622e60412b21140007d54dcf31b2c0e3e98cf33a00fd27f0
+TAG: d38d672665e2c8c4a07954b10ecff7d9
+
+KEY: 3b319e40148a67dc0bb19271d9272b327bc5eee087173d3d134ad56c8c7dc020
+NONCE: ce5cf6fef84d0010
+IN: 27b5627b17a2de31ad00fc2ecb347da0a399bb75cc6eadd4d6ee02de8fbd6a2168d4763ba9368ba982e97a2db8126df0343cdad06d2bc7d7e12eec731d130f8b8745c1954bfd1d717b4ea2
+AD: a026b6638f2939ec9cc28d935fb7113157f3b5b7e26c12f8f25b36412b0cd560b7f11b62788a76bd171342e2ae858bcecb8266ff8482bbaed593afe818b9829e05e8e2b281ae7799580142
+CT: 368fb69892447b75778f1c5236e1e9d5d89255c3d68d565a5bba4f524d6ad27de13087f301e2ef4c08f5e2c6128b1d3e26de845c4ac4869e4c8bd8858ad0d26dec3b5d61a9e3666a3911ba
+TAG: 2e70564c3999c448d92cc6df29d095c4
+
+KEY: 43bf97407a82d0f684bb85342380d66b85fcc81c3e22f1c0d972cd5bfdf407f4
+NONCE: 8b6ba494c540fba4
+IN: 4b4c7e292a357f56fdf567c32fc0f33608110d7ce5c69112987d7b5a0bd46d8627a721b0aed070b54ea9726084188c518cba829f3920365afc9382c6a5eb0dd332b84612366735be2479b63c9efc7ff5
+AD: 1e0acf4070e8d6758b60d81b6d289a4ecdc30e3de4f9090c13691d5b93d5bbcef984f90956de53c5cf44be6c70440661fa58e65dec2734ff51d6d03f57bddda1f47807247e3194e2f7ddd5f3cafd250f
+CT: d0076c88ad4bc12d77eb8ae8d9b5bf3a2c5888a8d4c15297b38ece5d64f673191dc81547240a0cbe066c9c563f5c3424809971b5a07dcc70b107305561ce85aecb0b0ea0e8b4ff4d1e4f84836955a945
+TAG: 75c9347425b459af6d99b17345c61ff7
+
+KEY: 12fc0bc94104ed8150bde1e56856ce3c57cd1cf633954d22552140e1f4e7c65d
+NONCE: d3875d1b6c808353
+IN: 24592082d6e73eb65c409b26ceae032e57f6877514947fc45eb007b8a6034494dde5563ac586ea081dc12fa6cda32266be858e4748be40bb20f71320711bf84c3f0e2783a63ad6e25a63b44c373a99af845cdf452c
+AD: b8be08463e84a909d071f5ff87213391b7da889dc56fd2f1e3cf86a0a03e2c8eaa2f539bf73f90f5298c26f27ef4a673a12784833acb4d0861562142c974ee37b09ae7708a19f14d1ad8c402bd1ecf5ea280fab280
+CT: 9d9ae6328711fb897a88462d20b8aa1b278134cdf7b23e1f1c809fa408b68a7bfc2be61a790008edaa98823381f45ae65f71042689d88acfa5f63332f0fba737c4772c972eba266640056452903d6522cefd3f264e
+TAG: e9c982d4ade7397bcfaa1e4c5a6cd578
+
+KEY: 7b6300f7dc21c9fddeaa71f439d53b553a7bf3e69ff515b5cb6495d652a0f99c
+NONCE: 40b32e3fdc646453
+IN: 572f60d98c8becc8ba80dd6b8d2d0f7b7bbfd7e4abc235f374abd44d9035c7650a79d1dd545fa2f6fb0b5eba271779913e5c5eb450528e4128909a96d11a652bf3f7ae9d0d17adbf612ec9ca32e73ef6e87d7f4e21fe3412ce14
+AD: 9ff377545a35cf1bfb77c734ad900c703aee6c3174fdb3736664863036a3a9d09163c2992f093e2408911b8751f001e493decc41e4eeeed04f698b6daed48452a7e1a74ec3b4f3dcf2151ca249fa568aa084c8428a41f20be5fd
+CT: 229da76844426639e2fd3ef253a195e0a93f08452ba37219b6773f103134f3f87b1345f9b4bf8cfc11277c311780a2b6e19a363b6ac2efe6c4cc54a39b144e29c94b9ebbde6fd094c30f59d1b770ebf9fcad2a5c695dc003bf51
+TAG: b72acab50131a29558d56ae7b9d48e4e
+
+KEY: 4aeb62f024e187606ee7cc9f5865c391c43df1963f459c87ba00e44bb163a866
+NONCE: 9559bd08718b75af
+IN: c5d586ceece6f41812c969bcf1e727fe6ff8d1ae8c8c52367c612caa7cdf50e0662f5dffc5ea7d3cc39400dfe3dc1897905f6490fd7747b5f5f9842739c67d07ce7c339a5b3997a7fb4cd0d8e4817ff8916b251c11ef919167f858e41504b9
+AD: 51f5b503b73a5de8b96534c2a3f2d859ece0bd063ea6dfa486a7eec99f6c020983f7148cccb86202cf9685cc1cc266930f04e536ad8bc26094252baa4606d883bd2aeed6b430152202e9b6cc797ff24fc365315ed67391374c1357c9a845f2
+CT: 252ea42b6e5740306816974a4fe67b66e793ebe0914778ef485d55288eb6c9c45fa34ac853dc7a39252520514c3cb34c72b973b14b32bc257687d398f36f64cc2a668faffa7305ab240171343b5f9f49b6c2197e4fbe187b10540d7cdcfa37
+TAG: 711ff33ef8d2b067a1b85c64f32f1814
+
+KEY: 9a19e72f005cae1ae78b8e350d7aabe59fc8845999e8c52fad545b942c225eaf
+NONCE: d9dae2ea8d2ffc31
+IN: 2110378d856ded07eb2be8e8f43308e0c75bc8a3fcc7b1773b0725b7de49f6a166c4528e64120bdf7c9776615d3ce6feeb03de964a7b919206a77392f80437faceb6745845cafc166e1c13b68e70ca2a1d00c71737b8fcbbbd50902565c32159e05fcd23
+AD: 1cd73b72c4e103afbefd7c777e0480f3f5e68c60b85bd2e71ef5caebb175d7fc6535d39f38f92c24f2eb0fe97d878ed3d5967c0bb4394a5d41f7d34cda6e1523d3848f049cde554a7d31e1afeab5d3e6150f85858335cbd28c8a7f87d528058df50eea06
+CT: 5f009fbce4ec8e4ca9d8d42258b1a3e4e920b2fbad33d5e9f07557d9595e841025193b521ba440110dd83958e8ee30219d952b418e98a6c624894aa248aedc0678f2d263e7bfaf54ca379fef6c5d2f7ac422ea4b4369408b82d6225a7a2cf9a9f46fd4ef
+TAG: aa0a5fa7d3cf717a4704a59973b1cd15
+
+KEY: ba1d0b3329ecc009f1da0fab4c854b00ad944870fdca561838e38bad364da507
+NONCE: 8a81c92b37221f2f
+IN: 6289944ffa3ccea4bf25cd601b271f64e6deb0eba77d65efb4d69ca93e01996e4727168b6f74f3ccf17bd44715f23ceb8fc030c0e035e77f53263db025021fd2d04b87a1b54b12229c5e860481452a80a125cb0693a2ba1b47e28ee7cbaf9e683c178232c7f6d34f97
+AD: e57883961b8d041d9b9eeaddcfd61fa9f59213f66571fadffffdd1498b9b014f1ef2e7e56c3044d7f9fa7a1403a1169e86430a2a782137093f5456e142aad03a5f7a66d38009dd01b7fc02c9cf61642dedaf7cc8d46066c281ee17780674c3a36eae66c58d2d765075
+CT: 9c44d9135db0dbf81c862c1f69bec55a279794cdd29a58e61909aa29ec4c120c9c5a508d856b9e56138095714a4bb58402a1ad06774cf4ecdf2273839c0007cb88b5444b25c76f6d2424281101d043fc6369ebb3b2ff63cdb0f11a6ea1b8a7dafc80cdaef2813fa661
+TAG: 65c746f659bcbdcd054e768c57c848c9
+
+KEY: 0cf8c73a6cffc1b8b2f5d320da1d859d314374e4a9468db7fd42c8d270b7613a
+NONCE: 3c4c6f0281841aff
+IN: 4434728d234603c916e2faa06b25d83bad3348990ecde2344368d1a7af1309bd04251bb2e0b72044948f8dea33cce2618283b6af742073a9586b26c1089335fe735141e099785a1235810a3a67ff309e2f0ce68220ba0077ad1a5dc1a4aef898a3b9ff8f5ad7fe60149bd0bd6d83
+AD: a38d09a4f1c9241623c639b7688d8d35345ea5824080c9d74e4352919db63c74d318f19e1cbb9b14eebd7c74b0ad0119247651911f3551583e749ea50ff648858dcaaa789b7419d9e93a5bf6c8167188dbac2f36804380db325201982b8b06597efeb7684546b272642941591e92
+CT: bdfbfea261b1f4c134445321db9e6e40476e2dd2f4e4dbe86e31d6a116d25830762e065b07b11a3799aab93a94b4f98c31c0faeb77ec52c02048e9579257e67f5a6bae9bc65210c25b37fc16ee93bda88fd5f30a533e470b6188c6ce5739fa3e90f77120b490fc1027964f277f40
+TAG: 4993ee9582f58eabdb26b98c4d56a244
+
+KEY: 69f4e5788d486a75adf9207df1bd262dd2fe3dd3a0236420390d16e2a3040466
+NONCE: 6255bf5c71bb27d1
+IN: c15048ca2941ef9600e767a5045aa98ac615225b805a9fbda3ac6301cd5a66aef611400fa3bc04838ead9924d382bef8251a47f1e487d2f3ca4bccd3476a6ca7f13e94fd639a259ef23cc2f8b8d248a471d30ac9219631c3e6985100dc45e0b59b8fc62046309165ddb6f092da3a4f067c8a44
+AD: 0c83039504c8464b49d63b7f944802f0d39c85e9f3745e250f10119fa2c960490f75ae4dced8503b156d072a69f20400e9494ab2fa58446c255d82ff0be4b7e43046580bc1cf34060c6f076c72ea455c3687381a3b908e152b10c95c7b94155b0b4b303b7764a8a27d1db0a885f1040d5dbcc3
+CT: f0bb2b73d94f2a7cef70fe77e054f206998eacf2b86c05c4fa3f40f2b8cebf034fe17bcbee4dea821f51c18c0aa85b160f8508bd1dc455cc7f49668b1fb25557cdae147bf2399e07fcacaca18eccded741e026ef25365a6b0f44a6b3dd975ee6bb580f5fccd040b73c18b0fbf8f63199ba10fe
+TAG: 4236a8750f0cafee3c4a06a577a85cb3
+
+KEY: ad7b9409147a896648a2a2fe2128f79022a70d96dc482730cd85c70db492b638
+NONCE: a28a6dedf3f2b01a
+IN: 791d293ff0a3b8510b4d494b30f50b38a01638bf130e58c7601904f12cb8900871e8cf3d50abd4d34fda122c76dfee5b7f82cd6e8590647535c915ae08714e427da52f80aef09f40040036034ca52718ea68313c534e7a045cd51745ec52f2e1b59463db07de7ca401c6f6453841d247f370341b2dbc1212
+AD: 9a6defddb9b8d5c24a26dd8096f5b8c3af7a89e1f7d886f560fabbe64f14db838d6eb9d6879f4f0b769fe1f9eebf67fcd47b6f9ceb4840b2dba7587e98dc5cae186ef2a0f8601060e8058d9dda812d91387c583da701d2ba3347f285c5d44385a2b0bf07150cbc95e7fcfa8ae07132849a023c98817c03d2
+CT: c2f109d6d94f77a7289c8a2ab33bc6a98d976554721b0c726cbf4121069473e62ba36e7090e02414f3edc25c5d83ac80b49ad528cda1e3ad815b5a8c8ae9ad0753de725319df236983abd3f69ab4465d9b806c075b1896d40bdba72d73ba84c4a530896eb94ffccf5fb67eb59119e66a1861872218f928cf
+TAG: e48dc0153d5b0f7edb76fc97a0224987
+
+KEY: 48470da98228c9b53f58747673504f74ca1737d7d4bb6dbf7c0cba6ca42f80b9
+NONCE: 56fb4923a97e9320
+IN: bc6626d651e2b237f22ee51608ddcffeba5f31c26df72f443f701f2b085d6f34f806e29673584cb21522179edb62a82427d946acabce065b88b2878e9eb87ed1004e55ef58f51ec46375ac542c5782725ff013136cb506fcf99496e13fcd224b8a74a971cc8ddb8b393ccc6ac910bd1906ea9f2ed8a5d066dc639c20cd
+AD: df8ab634d3dca14e2e091b15ecc78f91e229a1a13cba5edd6526d182525ec575aa45bc70fb6193ffcd59bad3c347159099c4f139c323c30a230753d070018786b2e59b758dd4a97d1a88e8f672092bef780b451fd66ba7431cbb5660ea7816cdf26e19a6ebb9aadc3088e6923f29f53f877a6758068f79a6f2a182b4bf
+CT: a62e313ecf258cc9087cbb94fcc12643eb722d255c3f98c39f130e10058a375f0809662442c7b18044feb1602d89be40facae8e89ca967015f0b7f8c2e4e4a3855dbb46a066e49abf9cef67e6036400c8ff46b241fc99ba1974ba3ba6ea20dc52ec6753f6fc7697adbccd02b0bbea1df8352629b03b43cc3d632576787
+TAG: 675287f8143b9b976e50a80f8531bd39
+
+KEY: b62fb85c1decd0faf242ce662140ad1b82975e99a3fa01666cac2385ab91da54
+NONCE: 2f4a5ca096a4faf8
+IN: 03b14f13c0065e4a4421de62ab1d842bffb80f3da30bf47d115c09857f5bdd5756fd7c9ac3d9af1c9fb94f2640f7f4386cfba74db468e5288dbe4dd78bfe4f69e41480ca6138e8beacc6eaa3374157c713cfa900c07dd836eaecc8827fa3e70e052ae09e8473e2ae1a10b1bb669ef60a8dd957f6553daa8114918e17371f2ac327bd
+AD: cfe3b7ab7550b0e8e2e8235fa0dcef95647ce6814abd3dc3f5a3bd7d6d282504660c34ad8341e4d11402c7d46c83a494d7ddb105e1002979023e0e3dc2978c9ae53e10eb8567e7a02b60e51e945c7040d832ca900d132b4205a35034fed939a1b7965183c25654931a9b744401c4649c945710b0d9733b87451348b32ba81de30ea7
+CT: 8965db3d3ae4fb483208f147276e7d81b71a86e7202ffc9b1eaade009bc016838dc09ca4bcf30887b2f4243fbd652cd90ebed1ceef8151ff17ea70518d03b0f2a24960aa7de9b30fa65c2e2d57360061aae6d9376e984e9fcd5e5dd0911a4bc8deca832ffb76f252bd7da523076593ba6b174f7d9fb0377e066ecbb6638036241e86
+TAG: 3d0fc53e9058c2be32aa0850e0fab5a6
+
+KEY: de9c657258774d4ebc09d109a0fc79d66493ae578797cac4eb8830a6a4b547e0
+NONCE: b5e35fe3398efa34
+IN: 4d68fb683aa4f4c7a16ba1114fc0b1b8d8898610fa2763e435ded8771b3651078bef73d4dfd14e76a34cd5eb9ef4db4ead4da9e83f4ce50fe059977b2d17d687c29335a04d87389d211f8215449749969f7652dc1935a0f9a94538dc81dc9a39af63446a6517609076987920547d0098a9c6766cf5e704883ea32feaea1889b1554b5eb0ce5ecc
+AD: 436ea5a5fee8293b93e4e8488116c94d3269c19f1d5050def23d280515457b931bbed64a542b317cc5023d648330a4b7adca14dd6f3783207b94f86ccaa0a0ac39b7db00ac87a99e3cd8a764ed9c75da8454479636ab2b29e770b166a5b75cacc425c919bf1ce9ac34afe6b4425c3d9fd2e48bc81e7d15516d60e592bfcc2ebefb660f0995f2b5
+CT: 97a97b8f0f5420845ae8d57567f9bba693d30e6db916fad0b971f553ad7d993f806f27ab8b458d8046062ced4778c004b4f958a4436141637c6039963308dea2f54008b7feab79650295ed41bf9e65e1a2d75ab1c7b2a70ebb9e9f38d07a9a672d3e95ea78afe9ac02f2566b48b0251aef6eeeca8bd15bd8d43b559426aa9d15d960ee35cb3edf
+TAG: e55dbb21851e8a5b365f86d02518331c
+
+KEY: 6885bd333c336c7672db8ebdf24c1a1b605c5a4ae279f0f698162f47e6c73401
+NONCE: f0c4a213a6168aab
+IN: fa905a2bfa5b5bad767239fb070a7bc0b303d1503ecd2b429418cc8feba843e5444ed89022fdb379c3b155a0f9ceab2979000a0f60292a631771f2fde4ef065aa746426609082969530a9c70ad145308c30ba389ea122fd766081511a031ce3a0bd9f9f583c7000b333b79ac004fbde6ec3eb2d905977ff95dcff77858e3c424fe8932a6a12139e6ec8d5e98
+AD: 8ded368f919efb522bb6a9ad009e02ffbc6a16536e34d95cdb34f1153d7cb7b0f3c2b13dd05cedae27cfe68ec3aca8047e0930a29c9d0770c1b83c234dcb0385deae7ae85da73a5f8de3dfb28612a001f4e552c4f67ae0e2ec53853289b7017a58591fd6f70b0e954876bb2f7ec33001e298856a64bb16181017ba924648c09fc63c62eff262c80d614679bd
+CT: 0cb3d6c31e0f4029eca5524f951244df042fc637c4162511fea512a52d3f7581af097eb642e79e48666cb1086edbd38c4777c535a20945fabc23e7c9277e2b960aac46865f1026eb6da82759108b9baece5da930ccfc1052b1656b0eadaa120ed0c45ad04b24ae8cdb22ceab76c5f180b46a392ab45b1b99c612546e6b947f4d5c06ad5abee92ff96345ad43
+TAG: d3b541ac446c84626daf800c0172eec6
+
+KEY: fbc978abb1240a6937ccc16735b8d6ed5411cdbc1897214165a174e16f4e699b
+NONCE: 7968379a8ce88117
+IN: 1a8196cd4a1389ec916ef8b7da5078a2afa8e9f1081223fa72f6524ac0a1a8019e44a09563a953615587429295052cc904b89f778ef446ed341430d7d8f747cf2db4308478524639f44457253ae5a4451c7efca8ae0b6c5c051aaa781e9c505489b381a6dcba87b157edc7f820a8fbaf2a52e484dc121f33d9d8b9ac59d4901d6ed8996ed4f62d9d4d82274c449cd74efa
+AD: 3913cd01299b8a4e507f067d887d7e9a6ded16dd9f9bb3115c5779aa14239fd33ee9f25756d45262dc3011069356425b5c81a4729594e17c9747119f81463e85625d5603d05e00f568b0c800bb181eb717be8d7a93166a504ce1bc817e15530c5bd2b3df1d4222245ea78a38bc10f66c5cf68d661503131f11af885c8a910b6dce70bc3a7448dfae00595beb707fe054d3
+CT: d152bcb4c24c3711b0fad28548dc4db605bbc89237cdbea7dbf956b8855d1161a0781f27bd56d798141e2ace339955efb98fe05d9b44cd011e645106bf47726183958cb6df34ce5766695f60bc70b6fe0fabb9afa009a8ef043dbf75f861881368fa07726625448fe608d578cdc48277f2dc53eaaf1bdc075269a42f9302a57cad387a82c6969608acacda20e1cac4596c
+TAG: 945dca73cf2f007ae243991c4fbe0479
+
+KEY: 77d1a857fbadfe01aba7974eea2dfb3dc7bf41de73686aece403993e5016c714
+NONCE: fdd913a321c40eb0
+IN: db8915bfe651e2ecb3ce0b27d99a6bfa7a7c507cfcb2987293018636c365a459c6a138b4428be538413db15bda69e697cbb92b154b7f4d2cbb07965225aa6865d7dcd1ba2c17c484b00b1986fed63e889f25a4966dc3ed4273f1577768f665362d7d3e824484f0dded7f82b8be8797ad951719719365e45abbf76324bc7d657799d4d4f4bb1dba67d96ab1c88519a5bee704f7214814
+AD: 3cb2c06c20cb0832bbacebfc205d77393ca1816346ea2681de4d3ab1fadb774ad273e4713290454496f5281ebc65e04cfe84ed37cd0aedc4bbe3decbd8d79d04a4e434876650e0d64309e336bfb10e924066a64acb92260b2dbd96735d03af03909aa6a80a6e89fda81037257aec21fe9be7e91a64e88e0a58fa38ecba4c4c4cffb61958f3c486cbb0b1d0b0014a2d1d3df248eec1ca
+CT: acb825e6023b44b03b2efc265603e887954e8612b2ee134bdcb61501cfb9492952bf67be597c3a005b09af74d9e421a576d2c65e98104780feab838d8cb1bd135452ea39dc8907a4c1a6a9161805e4fa3e16989e6a418a7eea2582bf895da967028eab7c95d846a6de4b9980785814cf00484baa2f6de609912fff689bce6e854261ffe866bd8e63274605c7c5ad677bd7897ade543e
+TAG: 938478a41a3223a2199f9276d116210f
+
+KEY: b7e9b90dc02b5cd6df5df7283ef293ed4dc07513d9e67331b606f4d42dec7d29
+NONCE: a6c191f6d1818f8e
+IN: 2ada0e3c7ca6db1f780ce8c79472af4e8e951ddc828e0d6e8a67df520638ff5f14a2f95a5e5931749ae2c4e9946ae4d5eb5de42fb5b77d2236e2e2bd817df51be40b1b8a6c21015a7c79fe06dba4a08b34013dfa02747b5f03930268404c455dc54a74d9c6e35485e10026da573cb41cd50b64cfafe4cfcdf3c9684ef877e45d84e22bd5e15fa6c8fd5be921366ff0dc6fe2df45f7252972c9b303
+AD: 0f4269ed5ef0bfff7be39946a4e86e8bf79f84b70cd0b14fecb7be3c071316ce86de3d99d6871e0ba5667d9d7bba7dcaba10cb2a36668b6c3e2fb6c102938b75008bb9c213ebf9b85b5e91a802df0d31d7f11d764b2289f6225212694ab6b7c0e3ff36e84245d9f4f43fc5f98e654dea7ba9bd918658879c5bb4a1642af0d83113e3cf935d3c0d5208318f66f654eb17d8c28a602543e77ad3e815
+CT: 22586fe7338e99cdaad9f85bd724ba4cfe6249b8a71399f9a3707b5c4323b8d96679568dfc8d230aefb453df596e13eb3e8a439249bd64bc93a58f95089a62b94f6562b821c83d91f56c55147381e9de4beb4ae81bd6fe7caef7e7e9a2078f2fba8f3e70d4910da9accc92b8e81a61b0fefbece4bd89443e66e8ddda8e47a66a62f17fd0e7d0a4852ce1a4d43d72a0b5e8914bbec698f060f2b092
+TAG: c082470297da8c5f682a169d28bc0239
+
+KEY: 6b2cb2678d1102f2fbbd028794a79f14585c223d405e1ae904c0361e9b241e99
+NONCE: 7b3ae31f8f938251
+IN: b3cb745930e05f3ab8c926c0a343a6eb14809fd21b8390a6fcc58adb5579e5432021765b2d249a0ecf6ba678634c4f53f71495865f031ee97aa159f9ead3a3fcb823ee5238bdf12706a9c6137d236e2e7110ce650c321e41daf0afd62bab2a8fe55d7018de49a14efe6d83a15b2f256d595e998d25309f23633360f5745c50c4e5af8ccc9a8a2cb47064105a023e919c7795d2dc331d3f2afb8c42e5c0bcc26d
+AD: 1c32fd3df22b3e440e2a3c7a7624990194cb16a5f74af36f87fd6ca7d410ce9064316a2d091945deef7d9b35ceec8396069307caced2b80afd7d53ec479c35cedf2dfd4c95c3dd8400f71ad34028c6e4f8681d93d0774064ba38f3fb9b0c1dfa1f5f0c7d20676a5911d999fb6a1d41367a8e99d852bf3d3b7b3f4c233249ed1ca135389a674ff48232ded3f6800a97b6d409c40e6cd70d09bf9d2ad25d9b9485
+CT: ef70c7de98ab1d4ad817024a970be463443640eb0cd7ff234bdd00e653074a77a1d5749e698bd526dc709f82df06f4c0e64046b3dc5f3c7044aef53aebb807d32239d0652dd990362c44ec25bf5aeae641e27bf716e0c4a1c9fbd37bbf602bb0d0c35b0638be20dd5d5891d446137e842f92c0ee075c68225e4dbacb63cc6fb32442b4bcda5e62cb500a4df2741a4059034d2ccb71b0b8b0112bf1c4ca6eec74
+TAG: 393ae233848034248c191ac0e36b6123
+
+KEY: 4dbc80a402c9fceaa755e1105dc49ef6489016776883e06fcf3aed93bf7f6af7
+NONCE: 2358ae0ce3fb8e9f
+IN: 197c06403eb896d2fa6465e4d64426d24cc7476aa1ae4127cd2bd8a48ce2c99c16b1cbf3064856e84073b6cf12e7406698ef3dd1240c026cbd1ab04ee603e1e6e735c9b7551fd0d355202b4f64b482dd4a7c7d82c4fe2eb494d0d5e17788982d704c1356c41a94655530deda23118cba281d0f717e149fbeb2c59b22d0c0574c1a2e640afad1a6ceb92e1bf1dde71752a1c991e9a5517fe98688a16b073dbf6884cfde61ac
+AD: cf6ce7b899fb700a90d2a5466d54d31358ecf0562e02b330a27ba0138006b342b7ed6349d73c4c5c6d29bde75a25089b11dac5b27adea7e7640ca1a7ceb050e3aae84a47e11640a6e485bd54ae9fdb547edc7313d24a0328429fcffd8b18f39880edd616447344ebeec9eadb2dcb1fa7e67179e7f913c194ebd8f5a58aea73b0c5d1133561245b6d9c5cfd8bb0c25b38ffb37db5e2de5cdded6b57355e9d215cb095b8731f
+CT: aa87f9a83048b6919c8f2b050315db4e2adae4a9c2ca0109b81961b520e63299dcb028cec0b9d3249a945ee67dd029b40f361245c740f004f8cf0d2214fcfa65e6124a3e74b78aa94345c46fdc158d34823ed249ee550431eaae9218367321cdd6e6a477650469bb3cc137a8f48d9cf27934b16703608b383d2145659922fb83bb2e7ee2ef938a90f2ff846a4a949129b1fb74dde55c5ae013c2f285de84f7dac7d1662f23
+TAG: 06b4318ac7f65d556f781428a0514ffe
+
+KEY: 9e4a62016dae4b3223fed1d01d0787e31d30694f79e8142224fe4c4735248a83
+NONCE: 263a2fc06a2872e7
+IN: 5a46946601f93a0cee5993c69575e599cc24f51aafa2d7c28d816a5b9b4decda2e59c111075fb60a903d701ad2680bb14aeda14af2ae9c07a759d8388b30446f28b85f0a05cd150050bd2e715ff550ebbd24da3ebb1eac15aba23d448659de34be962ab3ab31cb1758db76c468b5bb8ce44b06c4e4db9bd2f0615b1e727f053f6b4ffb6358d248f022bcad6ca973044bed23d3920906a89a9a9c5d8024ec67d7f061f64529a955ce16b3
+AD: 4cd65f68f9f88c0516231f2a425c8f8a287de47d409d5ecde3ad151e906b3839fb01bb91a456f20ea9d394d4b06604ab1f9009ef29019af7968d965d1643161ab33a5354cda2fdc9f1d21ec9cb71c325c65964a14f9b26eb16560beb9792075a1597394000fd5f331bd8b7d20d88e5f89cf8d0b33e4e78e4904bb59c9c8d5d31ac86b893e4a0667af1be85fdb77f7ec3e2594a68048d20c2fb9422f5879078772ee26a1c560cbcbb2113
+CT: e944bb2ab06d138ad633c16ce82706ecf0ef5d119be1f3460c9ce101d9c4e04ef1677707fca40d1f8ca181e07273707b06624d6d7063c3b7b0bb0151b757b3e5237fb8004c161233d8bc7e5f28ea1c18da1874b3d54c5ad6ff0835eed35c8853704585cf83996e5e7cec68180af414e04f08134d3b0384ebdf0393c9310b55d8698fe10cb362defc0995e9a13b48b42cff61ffd9fe4c3c8c6dab355713b88f6e98a02e7231a0c6644ec4
+TAG: 27de0d4ca7648f6396d5419a7b1243b7
+
+KEY: 18ca3ea3e8baeed1b341189297d33cef7f4e0a2fab40ec3b6bb67385d0969cfe
+NONCE: b6aef34c75818e7c
+IN: ef6d1bb4094782f602fcf41561cba4970679661c63befe35ff2ca7ad1a280bf6b1e7f153fa848edfeffe25153f540b71253e8baba9aeb719a02752cda60ea5938aab339eead5aabf81b19b0fc5c1ed556be6ad8970ea43c303d3046205b12c419dea71c4245cfedd0a31b0f4150b5a9fe80052790188529ab32f5e61d8ccde5973ed30bdf290cbfbd5f073c0c6a020eac0332fced17a9a08cef6f9217bd6bef68c1505d6eed40953e15508d87f08fc
+AD: f40f03beaa023db6311bad9b4d5d0d66a58d978e0bcbbf78acebde1f4eb9a284095628955a0b15afc454152f962ec3ea2b9a3b089b99658e68ede4dee5acd56672025eb7323bcbc6ba5d91c94310f18c918e3914bbbf869e1b8721476f9def31b9d32c471a54132481aa89f6c735ab193369496d8dbeb49b130d85fbff3f9cb7dccea4c1da7a2846eef5e6929d9009a9149e39c6c8ec150c9ab49a09c18c4749a0a9fcba77057cdea6efd4d142256c
+CT: c531633c0c98230dcf059c1081d1d69c96bab71c3143ae60f9fc2b9cd18762314496ab6e90bf6796252cb9f667a1f08da47fc2b0eecda813228cae00d4c0d71f5e01b6ce762fa636efffe55d0e89fdc89ba42521cc019ab9d408fcd79c14914e8bbf0ea44d8a1d35743ad628327e432fdcfeb0b6679ddca8c92b998473732abd55dba54eefff83c78488eee5f92b145a74b6866531476fc46279d4fde24d049c1ce2b42358ff3ab2ba3a8866e547af
+TAG: a0a5242759a6d9b1aa5baf9a4ef895a2
+
+KEY: 95fdd2d3d4296069055b6b79e5d1387628254a7be647baafdf99dd8af354d817
+NONCE: cd7ed9e70f608613
+IN: 0248284acffa4b2c46636bdf8cc70028dd151a6d8e7a5a5bc2d39acc1020e736885031b252bfe9f96490921f41d1e174bf1ac03707bc2ae5088a1208a7c664583835e8bb93c787b96dea9fc4b884930c57799e7b7a6649c61340376d042b9f5faee8956c70a63cf1cff4fc2c7cb8535c10214e73cec6b79669d824f23ff8c8a2ca1c05974dd6189cfee484d0906df487b6bd85671ce2b23825052e44b84803e2839a96391abc25945cb867b527cdd9b373fbfb83
+AD: 24a45a3a0076a5bcfd5afe1c54f7b77496117d29f4c0909f1e6940b81dde3abacb71ec71f0f4db8a7e540bd4c2c60faee21dd3ce72963855be1b0ce54fb20ad82dbc45be20cd6c171e2bebb79e65e7d01567ad0eeb869883e4e814c93688607a12b3b732c1703b09566c308d29ce676a5c762a85700639b70d82aaef408cf98821a372c6a0614a73ba9918a7951ea8b2bb77cd9896d26988086d8586d72edc92af2042ff5e5f1429a22f61065e03cfcd7edc2a93
+CT: 40c6318d9e383e107cdd3e1c8951562193c3ef64ee442432a63e2edefc78f32ab07772aeac172cb67ecf4d21f8b448423527bbeb9d8ddd0b46bdb27f74096ceb24e41963b4cdca176676a75bdbe3abc270b349ac0c6cbd9c3a5cd5bce20202fc5cc0c1bdd4fd25e121e0a24bd7bbeb9b19b1912467bf5338ee2ce88aa383c082b42cc399c9654ca325f35523e81438beb3f8926be79c378822d7c8f785614408a5f7cac49e4543188725643e6c1a70b46d0ec400
+TAG: 5801e84192c7267f66b0e04607a39a3e
+
+KEY: 6ae1102f84ed4dc114bb9d63f4dc78d7dbb1ab63f1659dd95f47940a7b7a811f
+NONCE: c965d578ba91d227
+IN: b82a8a9209618f1f5be9c2c32aba3dc45b4947007b14c851cd694456b303ad59a465662803006705673d6c3e29f1d3510dfc0405463c03414e0e07e359f1f1816c68b2434a19d3eee0464873e23c43f3ab60a3f606a0e5be81e3ab4aa27fb7707a57b949f00d6cd3a11ae4827d4889dd455a0b6d39e99012fd40db23fb50e79e11f8a6451669beb2fbd913effd49ad1b43926311f6e13a6e7a09cf4bebb1c0bf63ce59cd5a08e4b8d8dbf9d002e8a3d9e80c7995bb0b485280
+AD: dfd4ac3e80b2904623ff79ea8ee87862268939decf5306c07a175b6b9da0eb13ac209b4d164755929e03240a0fe26599f136fb2afdffd12bb20354aa1d20e5799839abb68ae46d50c8974e13e361d87ef550fe6d82e8b5b172cf5cd08482efdef793ede3530d24667faf3a1e96348867c2942641f4c036981b83f50236b8e8a10b83ebf6909aad0076302f1083f72de4cf4a1a3183fe6ec6bfe2e73e2af8e1e8c9d85079083fd179ccc2ee9ff002f213dbd7333053a46c5e43
+CT: a9aeb8f0a2b3ca141ac71a808dcc0c9798ac117c5d2bd09b3cfe622693a9f8ca62e841b58bddb2042f888e3099b53638b88dfc930b7a6ee4272d77e4b1d7e442bab6afbde96ab0b432f0092d9ca50eef42f63c60c09e7b8de019b32ebe4030c37b8183cc1e3b913b0ce4ee4d744398fa03f9af1c070bed8cdafd65b3a84140cb4deadc70184de757332ce3780af84353f540755227e886a8d7ad980f3dd6fd68263d82e93f883381dec888bc9f4f48349aa2b4c342cb9f48c6
+TAG: f26b3af8a45c416291ce66330733b2f8
+
+KEY: 405bb7b94715b875df068655f00513cb1ae23ffaac977ce273e57d3f83b43663
+NONCE: 5c6da1259451119a
+IN: f9f143c0c52c94b4ba7b0608b144156a49e7b5d27c97315743d171911e3645ab7957c80924e3c6b9c22ab7a1cac4b7e9c0de84e49fd5e4a2d1ab51d764fc5670318688ec942f7ab34c331dce8f90fea6972e07f0dadec29d8eb3b7b6521ddd678a6527a962f4d8af78c077e27f7a0b2ef7eabd19e92b7f8c1e8fb166d4763ce9c40c888cf49aa9cdfc3e997c8fe1cce3fe802441bbd698de269ff316f31c196e62d12c6bb5cd93fb3c79ca6369f8c1ac9102daf818975ea7f513bb38576a
+AD: 6fe6446505677bf08b385e2f6d83ef70e1547712208d9cebc010cba8c16ea4ece058d73c72273eed650afdc9f954f35aa1bdf90f1118b1173368acbc8d38d93ebf85bd30d6dc6d1b90913790c3efa55f34d31531f70c958759b2ba6f956c6fcdd289b58cb4c26e9515bf550f0fd71ab8527f062c9505cbb16e8e037d34de1756bef02a133dbf4a9c00ac03befc3fb7f137af04e12595ce9560f98b612480fcdba3b8be01db56ebec40f9deae532c3b0370b5c23a2a6b02a4de69efa8900c
+CT: 1a4b073881922c6366680cc9c2a127b26f264148651b29abb0c388cf6c9b1865dba5a991e1f8309efbdb91bce44b278772c58fd41273526c33fec84beb53d1689b9da8483f71be6db73a73417069bb4cd3f195236e8d0a00d124eed3a6b6f89415b19a27fbe35774f6a1a6ee4bd4350b252b975f0db2d2eea82f4836350850d6290901e726e8af13644e2d98bc1d569c20800521e6affe976bd407049a2e6d9dd23f88d52e651391ecd2fc45b864310824aaadfa203762a77c1d64562dae
+TAG: 0060026d3efc120f11c0739959ae0066
+
+KEY: 8c602bd94c630cd00c7a9c508067a5a9f133d12f06d9f6fe2a7b68dce4786d8a
+NONCE: 760de0f7b7cb67e2
+IN: c3ff559cf1d6ba6c0cc793ca09a0ba573a28359386a6ec93e1bacd8e630209e0b477a20aedec3c9cbf513ee6a1e3887112218d6155b9875f7e6c4bbba2c31972e905d19f529f4f0f9502996199f94f8728ba8d6424bb15f87fcacd88bb42c63fcc513759712bd0172b1e87c9da122f1993ffb7efd3a5c34b240dd3db89dddea36dbeb2836d9f8648f8e7cd428c0f948097af753b35f9876059e7702027bb00dc69071206e785f48fcbf81b39cc0343974ac70784a2e60c0df93b40379bea4ad8cac625
+AD: 9e14907c3a8e96c2636db1f3d78eb1f673d6ef043cbbb349467f1fe29bf60f23d5d5d1c3b133a8ad72065d822347541c13d1574baf737eb3cc3382fb479e6d5193b9c8e7d2444c66971ef099dc7f37f6cd97b9f7959d46e2cf25e8a5b3111b4d9e2ef906d905f0ee2d17587f7082d7c8e9a51509bde03d3d64338e1838d71700f1b4fcb100b5e0402969da462f26f974b4f9e766121f8fd54be99fc10beb9a606e13fbb1f960062815d19e67f80093360324013095719273c65542b0e31b1a2a3d928f
+CT: 2794e6e133f6892f23837fff60cf7c28ee9942f8982ef8089db117903d0143293fdf12ea1cc014bcd8806fb83c19570eed7af522db0de489bbc87133a13434518bcfb9cda4d9f6d832a69209657a447abf8afd816ae15f313c7ea95ec4bc694efc2386cdd8d915dc475e8fadf3421fbb0319a3c0b3b6dfa80ca3bb22c7aab07fe14a3fea5f0aee17ab1302338eeac010a04e505e20096a95f3347dc2b4510f62d6a4c1fae6b36939503a6ac22780a62d72f2fc3849d4ef21267fffdef23196d88fbb9b
+TAG: 457cce6e075ffdb180765ab2e105c707
+
+KEY: bd68ff5eb296c71cfe6bc903c14907f7726bcb1331f0c75f7801cd1b7948f3a1
+NONCE: 65a748004b352ba6
+IN: 52bf78c00f6e5dca2fc60e2e9a52e827df97808e9cf727773860cafc89f4b64178a19b30b46ed813fe00c8f09b25a6a1b6e350d5b005122934a59bfbd5e6e0c635c84a5226c3f2f7dcf951560f18ac220453d583015fdb2e446c69c6e6fdecf2e595e04fab1b0c506e3c6bd5e4414a35f15021e97f447aa334f54a8f1ef942dec6273511b5668b696fca97188ff15ed84b2f46145cce031c1a7f00bd88bb83d90797edc46161b3fda7a2299173496d73b812139556e8b4eb318078b9eb2ae5046e83b79dd3d45950
+AD: 5557b08a5010cbc9f46bb140c2505f68684eb24889324bff44b27234fd7a95a99cfb4ff90a8f9982085b725f78ac42eca6ce7f3314e457dc41f404008681a9d29ba765660de2e05bb679d65b81f5e797d8417b94eb9aabbd0576b5c57f86eae25f6050a7918e4c8021a85b47f7a83b4c8446898441c5cc4e0229776ef3e809cb085d71f3c75ec03378730cb066150f07e60f96aec983c0e7e72bf6bf87ae42228dfda195f97855fcdf4e6d1c4479d978abcfa276d16ed60ecbfbfc664041335ce65a40a2ca3424df
+CT: a5c8cf42287d4760fca755e2111817b981c47e85b0047de270ec301ca5f7b3679f4749210892b6ea6568f3a6a4344734a0efc0120ffedecf212d55cbcbb67815ac964875af45f735b70092a8f8435f52fc01b981ae971d486026fb69a9c3927acfe1f2eab0340ae95f8dbee41b2548e400805ece191db5fd1f0804053f1dbfaf7f8d6fded3874cb92d99a2729d3faaa60522060cf0b8101b463b3eb35b380fcddb6406c027d73fe701a5090c8dd531c203ce979e26b9ced3431e2b726a7244a20d9377bd62951bf5
+TAG: 4579fa1fdb4c674cc3cd232b8da52a97
+
+KEY: 934fd043c32d16a88fad01c3506469b077cb79d258b5664fa55ad8521afdcaa2
+NONCE: c7091f6afbbeb360
+IN: 2bdd1fc4f011ef97ea52ec643819941c7e0fb39023c2f3c7683804a0ddee14a5d1784a5246966d533b3538edc7d8742d27061c3cab88df0318ab242102de3a54d03632eeb871b72c7e8f8065b49f4a91e95e15f3f46b29fd76b8fcea0d23570c5530e3bbb8a6aafa9ae32c1b3eac653c5ed5fdb2da5a986075808f6385870c85b1913e26042a9d8e78f5bc2ea6de5a64f8aeafa22adcffc7f6932d543c29bb3a04614783f948680e433a71573568d2ce984d249fb4fc06a9f358c76aa3e64a357f4eae924c1356bd5baccf7e0f
+AD: f737dd85638eb324dd3891219c5eef7c2dd053cfd055d447a411eba304a4b27dce981d112c4540590933c153d603022c91ebd2b4a58069d27e6ca17a462ef822ca41bffa80b43a68b1b564644cb3c5a7f0fddf7a13a30ff24437fddd8ef93c6f6f205d054f81890d982bd4d4ece0b1563677e843fe48c1f54e9a57ed4da66061482712e710a401073be5080d5b8b96525bffa67de5af31d50385fbbf1a87c21bf0e0a1fdff69ec32c7b7103e0b8ee6c844245e0fc84b9f89fcce62966cea68e2871d3b82e8df424c76309fc88d
+CT: dd13fbf22c8d18354d774bcd18f7eb814e9b528e9e424abc4e3f2463195e8018576565d16ab48845d11c9277f2865ebb4dc412fd5b27078f8325eadf971e6944c66542e34d9dda971e2aba70dbd3e94a1e638d521477a027776b52acf90520ca229ebc760b73128879475d1cbe1f70fc598b549cd92d8a9ac6833e500c138c56474db84cb3d70b7aa4f293a4c2b4d818b0ff9fd85918dc590a12a8c0e375c4d98b7fc87596547eb960676aad5559834588f00f251a9d53f95c47af4df3c4299175d5211779c148cfc988a5e9d9
+TAG: 476616ea15190c1093fdc4a087643cae
+
+KEY: f9f6eb9ad736a8f66e7459fef5ec2890188dc26baf34a95f6f0384e79f5c6559
+NONCE: 7858dfc084fe4b0f
+IN: a644ca6e7cc076e87eb2929fd257693fce0f6fb64fd632f7f07c648ebd03696c8e262e6a810d7b7c4e5eef8c65b5323c99dbba50a70b4a9e5c2a9e7315973cd67f35d8052ce9a85a206416dd3031929f4f929b13d0a5fb10cb73c65f6c0ace019da146b51c5274a099f44e3669d26add6f2ff081e886f3cf952fe0dbbe6b0534c23e307574bd35fbd657f5fcbd5dc19fb382a1dc0a2dc8285a0350f71554e4c601497749e35567dd4a273cddc9a48ce53a5f1d297fd8baf8d1b9feb35d9151114345abada4d90db947bb9a743c175f5653d1
+AD: 2048d1c2ddfb5ec385b201832c7a993f229ba72ec16d6ebf723ef0c5032b9966209a9e8a63151b40412e96b82f86728ea6588c7e8e11ac71cc8eabab8c4b54de866658d9c5011def61fb3dbe4e630158a45ea41a2ed55ebd1efb1abeda7637de6fa5fd2f151c6d2f385bf6cd002ca8b4a2896e0d65944ee913e3c784669dd201b1985ef3577f7f123a5f9bcffa176c8f557c4f729133cac518642f27d9b22ca9b97faaafe5b669a10b79ace4a7d5727df146c77ce681357d69f9c2d65b4401bd73cd113387e3b3a05d897adad7a24c485e7b
+CT: 4146faffd7313f5d9f625370d20413cc62ab65f4acfa3c7ee1125b937dd7a39f638fc46c8ed004fb525698de5d8620ec153435571817c3de257b0d0e648ebb92940c86a98262d54e764f28cbdd4f7d9bea970291f2110414f62064d7229c6332236c507b3dac742e651d85a2a22fb243c0cc7cc2d016e5bea38f33f9a9ce048944a5fe8b078d71d23168e12dfe5a0f0b829771edc7073fb96032b7be471337a37aca0cf7c0cdd543eed686cd34934717fd79a3f18492eef72f9f450b880aa7e2e1b65e3b04c22e72301338b43aa32ceec2e6
+TAG: 10ffaf2be316676da02d7473a9df87b9
+
+KEY: 29b19636cdd32507fd98ec4ee26caab1a917646fb8f05b0dc01728a9f4a127f0
+NONCE: 06699d245916686d
+IN: 5fdf913aceab1d6dbaf7d9a29352fa8a3eb22718043a79cffa2fe8c35c820aec7c07644b8785dcf7a433b4189abb257fb12b06fae0662641011a069873c3e3c5ccc78e7358184a62c2005c44b8a92254958eb5ff460d73cd80284d6daba22c3faba046c5426fe8b7cacec64b235a8f8d3e2641e5bc378830594bcfb27c177aea745951ee5780a63705727ef42c4ad3abf556d88e3830f3db6b09e93edd09485cbf907f79de61f8dc5cb5fb7665ffa0ef53cb48702f6a81d8ad421cef20c1dbdf402b8fafed56a5361b2f93f914a2380fdd0557faf1f4de
+AD: 39116c49cc13adb065b92cb7635f73d5f6bf6b5ccbf72a3f65a5df6bd4a661105015358d9e69f42e98aed795e8161282bc113058b7ef3b9e23fcd8eeab34a392e03f4d6329c112cb968385ec52a7afc98bb8695785af6b27b700973cc952630b7247ce226b4fbb99b8a486370bf6345d4516c52c64e33f407c4f2d1ba90545c88732d98bbd97972ac5e94c694624a9b3782b0099824651cb7567914d25b3e13181a791dbcd40e76e836b3350d310a52151bf835d3c357c9871482c2928e8404c6e533406d4d6fa8f63366f2c4ed828141f1ff00f01a536
+CT: 01e237220b619054a1f3670928fe67d40484b5af40fbd04d032500aac5acaa3b4584dd99a58c390627636a50de5d744f76a56a33205f9e3b00e16162eb47ff3333e1e208ca200f1a5338a86e17bd92dd2d16af8bb022a7dc05b923d019e05247f1a0d0b4bfcfce58dd6d83830705707676d55739abee89fcd5cb94b8fde006a5da02df64b00a467f45970b5ca440f22319b9735a55d454b9fba0588fef0c59d3d83823eba6e0601a96e10233826c5adeea6b2a51d386a07a9e047ad405b23d4c3d89f30c31e3199f0c8f927bfac43ceea1f969de0a8c0f
+TAG: 092f9f3c5d4f2570c9946c87967f4579
+
+KEY: bae06b9b5456707551c7b0e207aae02a19b4848ad8ca4ce40705bf8c856a6e52
+NONCE: 9c27065c3ef2d522
+IN: 50cdd88137ff428a88e87b5845be4924f6387537bb5c0b654c80107ab5698db75b2e131848e7aec156d31aed0766d31c379fece4095d38264c6d5945974d25f729c3b0ba11ea853e9cebdb6f03bb670fce08adff74d0a8f02d633fb34e0fb7337a8e66e1c12084d914fb6173b8105684db822752c6751a372bb16690284d661b8b8bc6a6dfbddf45ebc2219596f9f2f878c118df69030de38b4d99dde43b9b9e20a3dab691645dd518342f49b06a0fe0a397adf261e99f07af5b0b3798b1022ba0939c42a54d3b93641cffa3c2e174bce9ab7ad7e7c7924308d1a77a
+AD: 5d5590db1bd316eb7a0e30e4c7a6dfdbef9d3287fdb8d824389599c3c2ee262b2192eb5b9708e66e22dbc7eca83fa1a995da3ce64c86fe5aa08b826d476dc439497e2d12e2702c63c8d27aa7f09fedee816dc8bffe1351d53271a34d4292b613b7efcedb7e3cf3e6ad389eef12471e9e20e38e7ae22a323abbadfe8f2e84271bffb1819feb4f77b82843cb8757cfae293631bc6d39669107e7015c85d7343ffa6fc1bbe6f5ab4de30cd752a281e03061ea89de2a3f5e90e20da22fd6e8525c100738667f42212b2cf45fcb23bbb54b21c117484b22c6e514685314df
+CT: 66b7f69ac49fab4e5975aeb6fa9287d8eac02ac312c4de78f77f59da16cbcf87274e66801c4b862c33ea79cdc76528862bb2956c06db8b8acfac4794ebf39e35ac03cc73a4351a4ff762f681a48d6f25cad36e2814c9b5c40b9ae92509e58429106847789454d376836936bebc7a80e6c66e7aa52936d6b361378a41f849ad4e48f9ee2d3e92217a908fa8eb35736ac8ada7d32ae05391f2d807be3512543c36138a5fe660dd4cd4cd184bb43b6ba6bc0bae634e2fa9669304cd510ed5103f630068ff76d3375738de60a381842b421477e25a490cdd6894b2704125
+TAG: c9998a677dfb0e91924aec9de0afd585
+
+KEY: 2cb374cb048c168f2e43597f028d9e73cade1b458284ffc260d4fc6b9011c414
+NONCE: 9fb909169bc9f4e9
+IN: 39eb929482784b463546f5d84f80510f2019923d465b99d194246d68c7ae343f91971d8f7059cebb86aa5dd099289aa648248b8c5ca04e66ac5e9bf06776e3883495397618a0227f035666806e636836b47d3d2d255a49db79866cf00d9ddabda259c4f968a1e01e651c7811cebbee2ee71803ea1d9d23487eb221f2d9555756800aba5e6abbefd6fb72b3151cc99ced599cd86df2a9b1ce94f89f347eeb124d9e7f0d9cc48d3dedd819e6d3dbac57ecee199547b266116a2035c9acc4c8ca3271ac74952372897c4a5f2cb84e2d81817fec9d6774f6d8a5b2021684132db4fca3
+AD: 0c7bd4f3a30ee944ccf9489181e6911684dcffad4593a9b65a67dfc80718c69b35897d01281016b7731e12c15cad8482e79458e08a755622e3f3f22a23ef6c8487a36ad1771ba06c641f06f85de0db3776cc6df06ad8fe3b4d60d58508de943083f17cbb9dc0d390ac94d8429e8c6fcfe063f424fbde0f62f6a7f91a626d195dc498a6e69bd93109c4e9ba13e7330aba456d710a4b0cc279d4045660406e26d61dff70d4a33c4f1052869f9248024e7a0f85f1effb32f6f7ccb1f860f3ef04e8f7b29096e6bcf9d4b3e0ce703e9bf228fdf515c2ff9cbabd16987be0f9babd3d8a
+CT: 91ddadb86b7ebef798ddaa59da51d71316fcf6c9678143178227d778750dc9827fc6cc21e605c505023e6db25849df7fb6fc1ca4d223aa215f8c85b724643c83bf8218815a9f9e2952384e0ca6a80a3760b39daf91a3c6154c4728c2371fd181fa3764753d0b0c23808a82cd8f0497246e3a0f17f8906a07c725d2891ce968a9d432c2b102d85c05510b28e715bb60d0403a77490e7f18be81218bc4f39287b9bb09f50227dd2f55e4fb70c4438da8ba3c8ffbced87d90155913faa9979fc57e6cbeddfaba3d3ab4163c0eebc7d94279c27d3ed56338893dba542eaefba30f8c3b
+TAG: 728e60f8124effbac234f70da925881c
+
+KEY: f0f16b6f12b3840bbd1c4a6a0811eef237f1521b45de9986daec9f28fca6485c
+NONCE: 7ac93e754e290323
+IN: 0530556424d823f90a7f1c524c4baa706aad2807e289e9479301e3e7a71f2a5e14e6232ea785f339c669af2e6d25f1d5a261096a548d23864945c3a589b67b09b0304a784d61b42b2419139485242e0d51fcbe9e8fed996d214de8717e6a71f8987ccad65eb92e66707034a5ae38e6486e26eb4374c565aad5df949dab209f7f7bcd8eb6fc52761a26cfe5d01fd349e59f4042e6dbe6b232f9301b971dee121d8aa1e62d40f043a42f3aa859d867eb809b1ced5ae1ec62cacf94a69fafd0631a8b5dfd66d855900fb295eec90ae5fcbf77beae267a79d24081bb322d8c4e0630fed252541b36
+AD: 13bfcc17b810099cda31ca53a1323db9b07633ceb2088a42263a4cbd6a4d47978776005c9a20203319c3a3ae434e9a26fb541047dc9df38dc36c095267272e203d0b24d119a70a7e96041b6d82b7c4d5570e1e4a1cf2f6e44ae63fe005a1f5b900778c482f7bd89e2e02305e35b8f61b7bb2c78a13aebfce0145d1c5aa0bf1d10d23616d5a3a446de550302f56f81dc56fe4f3700f14242688d9b92d8a427979b403c8de8c493a2cde510eaf6b285e6675b173aa0314a386b635c7577d5aff0d868a0cb3f73c8d2005f8c7c9dab5a060ef80102c9d4a4af988838afe87aff04c0689e8c3c7f9
+CT: 2c14c3931e98e84507c4c165c2ed47ad4a178f0e216cd7ac2453bbbf9f85dd06bd8ef54a9ff1fd3dd8e0cafb635d8f2de861a0db5b14d03f17aaea8c89b3010797c71c13a0e666899d7ff6e53c4f08be8ddb3e37688b5afa088079b6c7519b833e16560073e699530302028a3496e05edddec01a23a4c7983956250e8d9e616f7b940856955cde81c1efabf6b7b92f153d03f4cd17e7f7d2907670cfc84d45c1d7936775a3fce47968504278ffaecacea0871b227f250e2979516f6fa310fec0d8df1af7872e5a534e82870aa05f43ef0a455846b93ce938064fa33e92de262e4156dae56775
+TAG: d95d73bf9aeb71eba9042396f3725424
+
+KEY: 3792943c0396f1840496917ce8ad89608385007e796febeea3805f3f4cbeccf7
+NONCE: 23b2f9068b2c4c85
+IN: be6b67eb943ee7b5c785cd882f653e73a8f75b4a41a2a7c56ae5a10f729caf39948fe48ad0e51240e2e7aa43193c7ec6ce7f4909fc94c9f99e38e6a0ad7e98eb29c5c2e61c99e9cbe890f154185cec213a74725d23c1a4e4d0cb9b1a36b78c87e5eee20d2aa29aae80d4759eb0c51c5dc3a95bdbbf7e14eb434419a6c88a954ac03d0c98739f4211b8732acd71c297f578b8cb64ccac45f7235ddc7f2a3f5f997525c1ed39dc550126cdf9cedaf55425489085e91b170be6205a5a395f2dd4084a3e8dbc4fd8b13252f7effae067b571cb94a1e54aba45b1b9841308db0cc75b03cfce4ddafe89ce20f2d1
+AD: 7eb6d7b7bbaaa3c202a4f0f1de2263767169eb4a64853240d48c0f8d5d31b08d5baf42977614a57aad99426cde76d242cb37d2956d8c77dc4fd62a3abf30e8ac6cd58c8ef35e67497022960138c57787818892460f3bfc16e37ff388b1edc6ce2bc53c22717edc7a03d4c78b0dbbe9121c7fd8a3e3993b87a4fe389bff13bdae3b349de0b6db561602c53f746022aeb4483c723b67825042f4af20b7dd1e6031cf54215266295c524ac8e1370424c5c5e607fb3e23e97c8eebe64656775edf616422a8b974e1acf13ab45c9a367a7dd9b2d62f48bbc05819b65eccb813ca813f57b22ee4c280dbb5a9d8d5
+CT: 0b316ab2bcf5359900fa4082d5d253b49ad94b70e3fab544f98bd111cbcef6766cf953deec08cae1f489fe12f7acc0032db8a6b0c0eee0c206ea5fb973feaebf90f690e840094db5e13fdd7157ba127368c995b426529435a1bcdd1f14ce9125b8a0e4c96b6ec09e3c36a180adf81941c002d19c19d53c2009be803b987504606b7d43bdee5e0b32ff23c466b6cccfcd0d4e88fd1332e73712b5ab725c1a383e584f34f80daff29d285ae5e43cf1d0cc7a828e75c25daced3a581a93d7a50f313b33f38dddfaa23cd5b9914797db820ee2400d52bf5fa982277fe9b5881ac42981633b3957b0e935051828
+TAG: 01973ee2e81cef22751a6a8831d752ef
+
+KEY: fe4be6054773f634356ac328591fbc6f833b0d1beeb38dd5b6feb7481b4489d4
+NONCE: 0b3f16f898a5a7d5
+IN: 76ced1ade6d1ef4069afddb32e7432d4ff2fd06685121f7b16464e7a72d365744f547d2ccf53486310e38b42d8bacaf711e54c5458d2d68c4dbcc8de31ab6732f4430e88a64565f5b287640775aaa2af1cc461d3e415bb275c6246b1b58517aa72667eae291a2982eda175d1b22c5a58e6fec2b3743d55712f201ca24ba5c0ae8c25724871b2ec2fb914a8da5a52670ab9b43a83b8568ce74db5c634061cb80530c8070c38b8f48c33ba136cb9f2158ee7eda8b65f2192fc94d1291f182f101795b7190c74b319d2d3e02a97c824d9c9471a83797e4936310b207e3a1e0bcf75f7c3e3ee48a747641cdc4377f2d55082
+AD: 834cd775cbefe4b33a3ca53a00c06a3c4a666983e4115a029f15729460daa45d1505e95172d3695625a186b28b8be173a925af04665f209267b3c5123e8be13da447ee1ae856bb0925f35aaa76e04a7bca8460f76c2024de2149f38a8cfba81694b854885d72568105571b6b213a0bc188a44cc7fe13153cbf261401b238cf12a95e23cb56f240114f16e2f1e3a514615aab4449c0c49e4d900b0e17d1a8dabb53d43dca32fa052d576b73dd9b40856b515d6d7efc2a5c17e0ebcb17bd59dc86f22ce909301a2652f134e82ef0e4519487ed12d51536024f2ae8f75d937c42d003076e5dea8de0c684cda1f34253d8fc
+CT: f8defb6fe95dfec499b909996a1f75a198a90e4d6c6464d00a357a555311c42fe92dbbc4b79c935e4f0b1a95e44fdbc1380bebabca28db4dd0d2870daaafc38ef27908c3509e945714801cc51f1a07b2430c74fa64f2a7c2f7fd1551d258c9c3be020873fc1bf19f33ab6c660911dcf2317195d0efee82d20ec26d22611f9cf86c51a64e28b3a1f344500018e0855c88dae3c07acaeaa10b60388484dce93e16e6e1a6e69e899806648a92568c8780e9f4baacd98cbb353ac2f908e775d92303cfab843f15be0e0c322a958802fb1a60fcc7631f151f4c2b8cb965d2d296acef250275a2fecc0cea803ce7c058b12dd2
+TAG: ade515091930dd7861b27f78a87ef60c
+
+KEY: a288b11ce5382ec724ce4ab2d7efa8e777e91ebd04367935e15f9dac483e9596
+NONCE: 874144dbf648b325
+IN: 4c9195280a79a509919af4947e9e07231695fd7c5088539f23936ce88770ce07d9ad3ae4a463b3a57d0634d3a77ceaadf347a334682b04be8e58b8e86fb94a1f93255132b8cdb0df86f5bea354eea4e8315fea83e3fdf6e58aa9f26e93caa08e5e2551a94bd916a51fed29ec16f66800cda6a0aa24ec308bf5fb885afba272685de27c1edcdd3668048ef07b06e90d464a8aa28664903cac45e154e8e1e39c257e1ff506b9d95cef4f300bb73b899e7828602c3c1d290b8cf55ee5fd72ecce9e6efc9293aebf674a70e2a7673e75629c12950622dff71d3ec0992e57776c788c6927d30b4e24b749191c3ce8017f0ada6276e43720
+AD: 04abe8588c8c8c39a182092e5e7840442bd1c1149da102c4ee412bd8b82baa5087ef7291b5cd077c177c42770b0023e0e462b06e7553f191bcb0315a34918dcdbffe2b99c3e011b4220cc1775debcc0db55fa60df9b52234f3d3fa9606508badc26f30b47cdb4f1c0f4708d417b6853e66c2f1f67f6200daf760ceb64ffc43db27f057ad3ee973e31d7e5d5deb050315c1c687980c0c148ee1a492d47acfcd6132334176c11258c89b19ba02e6acc55d852f87b6a2169ed34a6147caa60906ac8c0813c0f05522af7b7f0faddb4bc297405e28ecf5a0f6aac6258422d29cfe250d61402840f3c27d0ce39b3e2d5f1e520541d2965e
+CT: 0afce770a12f15d67ac104ba0640aab95922390607473cbda71321156a5559906be933fb0980da56f27e89796eaa1054f5aacf1668d9f273cc69071b9e8e22af6a205a6a88f7ad918e22f616bddbb07c78913c7e056e769e6fcf91c7600c2740212e3a176e4110cac9e361a59a773457064d2dc652dd115d04f1c3756c0e1d39f6737a16b4508663e310934c49c58058b3c7b9af7bb2334c8a163608c42499658986927cda365e2aead3ac29de16e47e954383ea566f8fb245a4e5a934c767bb3bf7e0eb8a477fd0e1f61bcb238462a0d19c5cea9293ca58ade76829413216a7882cd2846323046694f78cd8b0347792ebb75abdc1
+TAG: 973e58b1b8adb176a6f1e5c963bfdc5c
+
+KEY: 65b63ed53750c88c508c44881ae59e6fff69c66288f3c14cfec503391262cafc
+NONCE: 7f5e560a1de434ba
+IN: 845ef27b6615fb699d37971db6b597930a7ef1e6f90054791eb04ddfe7252b5f88fd60eba5af469bc09661c0987a496fa540621afeec51bebda786826800943d977039dee76235248112ff8b743f25ed5f3cb0d3307f5e118d84fdbb9c3f5531bc177fb84549c994ea4496c65e5249da987dd755d46dc1788f582410266a10f291c1474f732183a2a39afe603771bb9c423fe3e8906f2be44a0c9a7c3f0ceb09d1d0f92d942383a875c0567c7869f045e56dd1a4d6e90c58d44fe0c5760bb4fd01de55439db52b56831e5a26a47de14249453a4f8e7da3cb3282c6622916197ebfaad85dd65c61e7d2d3ba626276366746f396394c1bf75f51ce
+AD: 51a3588398808e1d6a98505c6e5601ae2a2766f1f28f8f69d1ccbcad18038c157b41525be58ae4527a073748b7a04809e52a5df0c7988417607738e63d7ead47db795a346b04e740186e73ccad79f725b58ee22dc6e30d1f0a218eda1791e2229b253d4ab2b963a43e12318c8b0785c20fca3abcf220c08745d9f9602f0ece544a05736d76b12d249699c9e3e99f3f13cf4e5dc13a04125c949a5b30d034b23cb364c8781964bc6c30e5e5ca9673d517ef5f35965d8a8cf1be017e343df97b6bee37b30638b154286d1f36d2f9a0eaa23cc484eac5a05b15d9efc537d989dbc8b3106c0dc1a56e97e6aec2eff54a82cf7ae9df2af46b4c860f83
+CT: 027b14197b4012256b133b78ddc94e72fb4d724fefa4ae329f5a5fa3fa784fe6d7e1e805e3f7a75557de64de506d38237b467fa577efb59e7cfe2356bed6655c5aa4e238dcfeb75c16549a0917268768a96acb5e20546a1fb7e3a7cff887f49f2cd7a135f72a98a779150f3207bf733e88861fd79eadbf77fa3bfe97bfe8b6a991cb3bcc2cde8287f7e89384846561934b0f3e05e0646e0e1907770df67a7594161a4d0763faa6fa844080932159999d528ee0558710058ce16f97d13ac9fd9bf5044191188bbfb598d0fafbdf790b61ce0781ecc04218a30ded45efd498cc9ba03562ed2b4a993ee98876b3ab7a9bc07829f1c4ca6ead98c06b
+TAG: e4d18a701b8308697b5e79141ed783c1
+
+KEY: 4986fd62d6cb86b2eaf219174bec681bebcdef86c8be291f27d3e5dc69e2feba
+NONCE: d08d486620ed2e84
+IN: 3a22ad5de387db4fdd5d62a1b728c23a8dddc50b1e89f54f6198b90499f9da3122ebeb38ebf5fdfe30309734f79aff01e3de1e196b35bffa33bae451f31f74b8aec03763f9e0861a34fe5db0b40c76e57c7fc582bfa19c94ee25b5e168270f379bf9f8a0a18bed05de256f8f0dd7c23ba2ff1c7f721409462f04cc611ad9bd4c3c9acf30742acfb9518a6375cbb15d65a1bc6993ea434894f93d4f6e05996ebc1bd56579296309a2c6b8fde95072168b5fd31927c4c0abaa056bcd16221d5f220be47591f43255013a262dce439817f534830ba82155347e5fe3101f8011b89365a6568214ed0661914e8cb3431d6c8f2347dfc1209a3eca4aaf0a111f47fe
+AD: 7dd3f656a03c001b45ca0680bc3ac9d68c6e96b591d3c69eb8c65e489009d845cb331c98b82e627e06d5bf01e74c573df268c2386f12628c019951d42f55991ff20d72a7b2c45f41d0be7af428c92f324aaab8df70d900301cdf09a3d93eb711c919d34a86fff9cb078322ee2e0ad48dbdf3b7884f0f2dc5c36262c59bcfd75ac6200f59c6fcd0ce10ff5005fef5df8f0432377dfbfc1db8f559e27e1aeef3380ea3864867d36a25a18654779a751586cad3b8a46b90864ee697b08605673b8d2123433c020a21c4db243dde2420c12fd4d54a2704a0c8c376454a1b5e80fd6db89aabd56d9b421f29649e474824dfa56cb5c673c504d10be52b53751709fe
+CT: c40180afd53001663ff4834110f56e6b0f178cd3c0e7f7de5d0089ee41d8403ffb98e84922706544a344d7e2625b12cf66b9c966f9f57d7b94e3e4b34e6f0aaed1763ce012782e2f5e1682e6c343fc7961fedddd0919d0b910e9923c17e36406979b256b85aec24ee352f03b48c1302eab419c83dccc5372cc059e9de596224fa70098eb32fc9579e97917b923914fa2efc30ab29b457bf14e45583b3771486bdc0876f3ea6e1a646746c4f8c5cb2641a1557c8473e6ea67d4811a67485ae9a678ff3a2408ca845c3b51957e189eef47dfc1d46bde4b9d754d7df13f828ddadb06e4ebddb5f0dafbdb28de4c5e6078926f20cdf9e97ecd58e309e640f74f06
+TAG: fd5e29332832a14a31a9ce2ca8568498
+
+KEY: 7d28a60810e43d3dfa32e97c07957ec069fc80cc6a50061830aa29b3aa777dfc
+NONCE: 47738ac8f10f2c3a
+IN: b50278ae0f0fa2f918bb9a5ed3a0797c328e452974d33cbf26a1e213aa20c03d0d89490869754abf84dbbe231d7bccdced77d53fd4527356d8e02b681fc89a535ae87308bf7fbc26197a5ea85bdb3aa033b8da5cd197ea6d72f96f63b03f4ecc7adedf399a5043776cdb32c08f30b77f34df85f8adb8e02649a04b020b03e17d445ca63e4ed73ae432c481392e031eba2f9d2f7f981d1e50917822bd6ff71c239d33444ada3523a59dfbce5457eadec1ab926c9e6c5299c7521e3f204b96901a712504fcc782e8cea80ba12a7f7e71cec3d0871899b6ca059061da037715f7d13fed01c9cade1e687b4fbb1f4ac4b040db3b43800f112fb900e4f772d61b921cbce4da6f
+AD: 324292813b7df15bc070cc5d8a4bf74ead036430be63abc43304cf653959a24a91c7de5a671c50fa8a87e21bb82b069999aadfb6895d8bda4c3083d17b8ca55b9ab1511ed8c4b39d8c28c11a22ef90c08a983e3fe2d988df9e02b16a20b24f39ddb28429625f511db08298c4dc321f6c268fc836a6191df6232f51c463a397a8d8b33374abe94e62c0f5c322387e1fc4a1c1980a04a1a3c2c31b32f183a11c3268c6dca521149dc16af120a78be6627210e8ddbc44472bc24d66ce3681c7579b3d9a425212a704a4f5105cb80f0d18ee860953d10b59c114826779bbc368d7a0eece9f223e47cd8e5fd453607d101d9d9c2bd9a658d6520b87d7b4263f6d845a524a36e4
+CT: 2c217e969c04740a1acfa30117eb5b32dc573df3354f4cc3bf8f696ff905f1e640f3b2c250473b376622e0c9bda13b94640521be1ef0fc660b4c10dbe2bfc093030753e04f6aaecf813b43b61f960455974b8bb8a9b461d1e8fd3802315e863c00448f24dd38deb90e135493274eb14ccbde15c50dcad734ed815a806be6622492a84cd062e3ba567b909a205a1d0d2bedd40169697d261c7b6c2e0b1f069853fd470e8f364a142c386c439a6dbe192ded5a3d0fbf73799f588c59e58c60249d980ddcf0d9693631cd9b3f972509c3a77123d38d9e267ecad06e1208e3f1c0a69fbca7c3bb1a48fda19493d0f8f48398820057b94120f3ef97d87e9e8a1b301a2534c68f
+TAG: 1fdd2dcd935f55822bf7231a516ca841
+
+KEY: a76e9b916f5a67b78a5949651c8c3a9741a1bc3c41cdf85fd2c8f3e9a0616098
+NONCE: 0808da8292dc14e0
+IN: 9c149eeb09345c3c22462b03e49eb4dba6bc98b269b1086d752bcd8eea53b8977b238a04a994baf915591686baab90b79a3bf7d9adb2c6c2e31acd3e72f0813fb745aa5fb2e3da408f78001c9c09bd26a1a2646011b6120aaa2bbacc4a16c39fb5257b9b2ea2ad8bf70bcc9855cf11841116c2767310cf3cd49d1aa44cd505f079761e064d5bc7cea4a7173b086882a77d3fc179efc86fc4db8a373491d2ed81eabc63c950e832db17d09f474d4ec46bde47830caf26fabaa0372b81fccc449c0e19ccd630caf693a7b43bb1c408a54e03f50c44280a05ad89fb6e8f01d8ac278edf556e5d86ceb4b614fb2ef133819c6e1ff6abb86c54a135256204b5cd400b93624d3932e7c2b046
+AD: 6aeb7031e4a2e23eea93f05fdc562aa2bf43b8998bea7344377aaddc60fbdb7bcb1491d379ed0cb613ee757cfb66490db61bb431d2fad34b38ddd55bc5b22aa6c4773b9992f34b878c5663f6e8cdb5f80a17f4d312bf342492e48d1ce4c6d754076a634fece61500acf8168d47381af4faf980c6cac2bfd5da8c09b6edb0f543bf0fe02643e38d73fa37d8ae87fb66193f22e57faf4393c007d48c8631a685d520578f8f89db684fb371ea02f3a58b1e2168f0216321139472e0d03b6d90ba8aab65402e1c1ac4f9172a60e27e3d997b9b05e2f672120d6c87bcafa6d4c9b4cf8ba8a82932d92840368fc53dc5b48526103dcab5f1531038aabe89171327ac559b98a3cf4ea70bf051
+CT: 9c3faab9261a63cea9477b3269007283995b06ba77ef83d9e693f7e4ee9855550eef94855be39a7a435b6a3584b202973777c7b2482376ba47b49311947a64983b60236756ee4455d4cfada8c36af8eb06b06ba2f6b79ffb1185c89f2b2a831cfaa3855fc1841d8910908be5078352011168a67d36372d851a3217cabf593ea462dcd325cf9a4f67e85418fd5c924e9b92ab026cbee4e7ab1067066cb5949dfc699a68fe539e1abb13cec33904e5207e6963d24f5a0b770613b8b00014e791bfff88f9c25ca126127a2f8d1d1e9794efd28dce98b53e228073faae8d5047530d502184fc341321c3f55fcbf41187fc31262c325b97f519959b6a29b36c71f76f60196bb1457b77c8bb
+TAG: b45df119043d29008fcef36a169ef886
+
+KEY: 98cd2477a7a072c69f375b88d09ed9d7b9c3df3f87e36ce621726f76e3b41a1d
+NONCE: 77d185aaf715aa48
+IN: 42b31eefdacab0f03ef6060156000c8195adb0976cabbe1a42bfcc09f85659c60b98638401f2d2e2facfb9a97a62926bb0cecaf3af0180a01bfb6e576babf7fc43331937a92abd30cddfa3e450f895e9dd914dea3fafd759c136d685310ebce28ac0613ccdbf30115946c9634b67510b77d0e37f07714b2ddac9d7095b8d4bd887c132c4a9127eb01c8dedb4c39c87b98a741316656f9a8d5a5b0c0ac84789aa2347a5f99ca5ad55cd1bcf98f703eb4b00badb8a8555f38b3b368db8ba7ceea94e8b219f51edce75d84166b5602156ed5962a93a51db73c59d87e906179d7a74a2a2a69d8ad99f323225c87e475d3f771b4a203a2e2b03b458401044649fa6536dfab24d7037807dcbf6518e6578
+AD: f5bb1496052a4361dddf72a288e36953a3d815d6876c013f1d6ba839e127f721b052b1f7d8ca20c7dc0386a7d459ebd7eb9fc8cb08941e6ca9ddb980f3115f65bc1928a414d441ae71dcb879d5bfe0cde0562bc37f8fde0d5291ad405c92fcbb860c43b55ac0fe663b54b3d0616aca13a5c82b7b5d34125a05c2acb5530141030e6f2aa0c8322b2c8fa307e7518918e550e9f48921c6168f094d8758e16b9f815fd0458095c4143f0922adb1840d0e685636825a9c90ee90ee537f4b8dceecbc4287c82dc9a00d7e51671e37ea284ee3ca501b1b2596459d3f592f70186f41125739e342c9f6be9241973b1414dfe5fb8cba1af82e679278cfcf95420df0c5364af4d7e72ad57d5c871fcbc35462
+CT: 7a3bf3e3ad5ae3ab71fb1f7121c3d8fb511099484b50af7ca128ee0337ed4b828dc4cde0b88dc1e8089101fa82c9beb3eb48fdcf0f5b16da441f5a3fce9a590022af95a94aed6a3e71e505f60f303c78c356f274ea85a55354078530664ecda32c80e77dc20974b3b38f4825b8fbee8c3970769a2f42c5181608a8d7d76ef4d093961b665ee42b9708fcafe2c82d3a307173e2a25ad2528c3bf83352b9265e45b70722d7cf8c9b80826d21335234ee3db69d0d37871c83222365900c96c17a7e9f5742d0bfe383be24d0d44590d4b0f29f7abe0c65daaffb968b3f2657b1eb300534eacb52ec7a6b6f9f57a50a91b1799f491361cf613c934b7f520dc4eeeb40ffc45e10be0a95e76f366d4eac14
+TAG: f613b65226afb64c614fe60d9c71ed74
+
+KEY: 2f0f4631ab1c1bcf8f3ad0559c818d50e0af7d8cd63faa357f2069f30881d9cb
+NONCE: 7d0ced2fdb1c9173
+IN: 6516ba1d29357144eebfa486d21decf223da3aa76ec29bbfcbe7f1eeaf4a847710e5080177f7e5a7c8b4752c219b1cc70aef4db861ba67d0fa6222d9f4a1dc756a0ba44e62906f9374a960c16198866d867854d88f528a60e212eb91645787e75685b2e215c0a41990abc344a77236ec0186ba63a664592938cc5a8ac1d3eb99c95ce00e19fbe249263083d85b052d48bfdffc01585dc57bb2a2c6c4a819604c1ec0548c6f0f78dc05e4418b36277dc07233c7532f9c289d6aed0cc6bc7df4fd0a536c497b982e2dad2c30d2db1c6545a845c5dfa83a4ac49ef06fc9c919079d3e299e31b5c3be370814ae5022ae469d3ee55246a41bd0dc4e64351cc38c3c09af0a1aee3b388a6892deff0df3f93cd92d722b
+AD: 1ccfa1ececc8de1e200d0ecc19dcf67b7c96bea3a282c2bccba61035db5c14776387b8b8f58e5757deb0129d4e5e315f64df354a5985d2e47ebbbeafe0c914f7cf1d63dd0311ace19e69a8b6ff0ab25cc8df0408d22132205e89e5eb679268d82b2913e64e3f885bbf4a6d379b760b94590e3140dd7275ab4713cb56d0b716e2718f11316640cb394802862d39e77a46d0c065af3caf7dec14e887039d8aa8c3d3a8ac1ee06026f49d00b2f59d971b54735e95a51f199389a93a4fc24ebaba1f7a2eef7412f61febf79084fbf481afc6fb6b204084e5ef5df71f30506459dea074f11fc055cd2a8c0fc922c4811a849984352a56a15659b7d07a4cc90b88623638ea00c4c8bc13884df2237b359f2877aa41d6
+CT: e580093789ba17ffb46672dc326f09278aca08598d3e5458eaa53e6ed45d5c71a396e35b5ea3fe7b7c0496a734d24f1c75420694be2ff095d5172fd3407794e4b99fd7c374fbe8d1564a048614d3f355bfb5866de1a53e1a51f9f5e8312253cfd82f36efaa1898c850ca0d975ad1e8b0d9597a5a9e6516fe2a3c92efb7495557a8afc3da15b0d3e2ba58f612519836946cf2d15b898320d16a026c8c00a1be2e35f0ebe68f28d91c6c45d24c3f3c157cb132fa659b7794df883d90741fa2d2afcc4f27858e13ecd41b154a35d24947ae7361170060c107d8ecacb393ea67104b60457278a392fdf1794bab97d3b02b71a4eb015eaa38a4b4c944c2bc7cd5e329da4a1ab2937a6af81a6caa5fce752331fdefd4
+TAG: 0fd7419c54bc84265ed310a3411a3f2e
+
+KEY: a48b9b6df475e566aba7671fbd76772cb0eff0b12499967978ce3e25fac92feb
+NONCE: 2ccbf0d6c40cb302
+IN: 09da1cacd001dce4f7573a065a4406fe0da04ab367a2d87780a2762e168957a88d3fa78f0a4b6978d449026e5a801d32884b6e14fdaaaf864214f928ebc03dead081fee96683ebb032362d5088c4c2a3b1e242f055f2604919f4dd551db777a258cf9da6d95a2bde249247812b9efc7985cf08707620808524d6dd3079b0b63bf0f71ea5de834ccb8b7c6a97125fd6ca49148e866d3134bbf1d8a6b714e9a80fe549c8bfefe342f41be2ba2300e0028f78cefab65274632dfdbe70bf7d655ec4036df561f2d4fc4d56a482bbe2f9f2ae279b3aa216b39afee75e53602de319484db89a51e844f38c361634e474f8f1f01c340f3f3594860d671346449c6d08ee38de22d246309bc7e4a252a29c86aa6d94b5b4fa58904c70
+AD: 1c2503d5aa1aad193f0da12874074ea0432bb76a61cd43a3017061514da0759846a0f3ae3a49fdb0b6d29f713de665beacb6568f2694112ca380d13f3c1698316866a7a7f87f1d7503a92176ab84fc08977b46ba664508a858e7525753c45511b3d2f407d5e993c6ede77f13d12975707e5195704970a89f71fc30828049f92f944f3aa93d6a5297e678e08952919beb7eac5919df1919cab3c3da6aa696a1eeab6371f310f7e81143e7d240b0213ae554524b52000306160dd4877bf13ba0f13bbe867da7c7d707f31335eef4cd942938ac890a0829ec66bd30ae01a2188a6e5ea0f17cd7dc875e17f03c0ab5dd18e36db8a1fc1f72859ee046b62368f168b3bea2234e0432c07b7d8e1b9277f21e692c513b9e816e6860
+CT: 7d35cfe4be56bd6e0e09dedcd01735b915bc1891a4d1f6a541abc4bcd0ebe89dcb8e365e5813742e8ec65777b6159422fada747da99394252baf8a046fc1b60ad79755f545f4448627b7acaf403000894f5641e78d3f946dfca29ec617f0660dcd6e8d8827e67e1022a245c595d86e60fbd176bf721b171bbe5ecaf4ae671b9f3dd3920146e6ad431bd8fc431820e19454b6ca209723d80fdbee187fca9c937c979206ae97be55f6ba7366a5608770a11d537396485eb0a66586385f4d4cf3905d1fc90831c3e136d5d513fa22be285193142994a3ed477145bacdcbdd791e8b3b88b0d4f1d18b27382550a818c4fd8884bf36f677c6c3ff5677406e510911e696af75e5b3f859bef699bdd16e6215fdb98d874025eada50
+TAG: 2aabff35611b3e0013f6ae0df130799b
+
+KEY: 923d4b086b9e43b986f7b65e4cea6113a3d8aabefa89323c5e4d5b6f158bb7e0
+NONCE: a0f73297b87f5deb
+IN: 21435e8d5c8edf0684f58c2cba4070c10b4801adf46b6c4d322eb3990a38a9ad338ad704b9df6597f3e68d66cd5b56290c8466db2231e56d6bcb9c44e1bd081f42ca2a894dad369df2bd0d2c63d6c881732d6ea22bb22b5bc9a62eaffa1b094d0845f6b966d2cb095e7b3b8bcbc15e707449d35c8df4aea30c3b7243e977fffd59c80f1c5c9af4bb5a54b9c786fbbe8d21b2b906a87a786caed841a34a3e0cc0ac3209d83c58afba19edd63622dd261532d2cfb0b49d527d8eaa0887a087f5129d897f665264b229f860363d71a88b7d49c8dc6360182b357b0662391bb41337f46010ac32b9fada2d60a2efcb99365d3b27b7ac396900d1c821d0df8b86cc9cc1f2673259a33efea610bf8e1d00d7e9db2afea21da8f58c55f799999d
+AD: c853a8b39c0dc597d562f123cd221e4104b65423a062a4f4ba890ba344feb84290f61817e23330c365f58c3583ce08360d3c1171982ead5496d525ac878f23a57480a6ee39d4e65afd6268245bb982a2545fa1195427cdbbcd404cdad5198f55cce2a5a028fae435f71b15921d066e8d43766c32b2f2c3f57c0674e129607dcd3703eca529414adaee79d81fed432153cceb6f3fc53404810d8ec878f7d94be5d379d0e0e1aa9bc404b4b5d396038a9d76a5ce53c9f3759b8e50fb331858ca58cee81bfc3ee58baef5d19c402a3dc8b36370ec1ace5a4aa2527fb94b4f933a4ab8ccaaf6a5af5a779eae5667c2a24ab027e781c8d4f30c377aa5885a2fdaf6507d18cd824a847c35368b4ea984d2c3c3824a5b8ba3042e1852504a21a3
+CT: f2e21052eebbb86a4f5e803360855d8632aa727dca6f5e79dd74d7aff106e442001928d113005b030f8446f8eff2ee951db663978abe43090dd5ad2c51ba97a0ecf988c607d95e486d02524f690fa3c28d5c48c1f75c1f555e7b43fe7e46f2ca2b9fdb408ec4ba18b6cdde2af673183cb7b1a3c23ae77eddd4cac75e1ea14743fc571f8d31ce2e96787524cd48aadaa474181c096a032184574ddc25a6e0ac8441c212bc36298708e33c963ae931e6c6241d1affeef7b6ef759495df44b6ab647447693cf703569e69aa72f1def9a342b8978c1edea9703a421ca75b92cac4de14b88c693200022b8a2ed22b1c4678b99f4d695e080dd1196d7168e14f0d0f8ff880d742e97b9f6d00af1f7118e10b77c5ef3ea6c52f84a20fd6ea46dc
+TAG: fa8ee13400fb3f63b899df582f2fec45
+
+KEY: df73adab2768559ea983cce85453fe81d79be3b3c57f202b31b94d6635cf2e4b
+NONCE: e7a87e6bf6b5a354
+IN: 0032a37abf661faa18c587fd2aa88885c061deeba81105dd221969bed5d59c7204b09b1a8c4c8de3b9f748c7fc70626ebeaca060233a57b102221b1bf0f3d9fdaaad3d2b1439c24d08f9c67f49f3c47128f92ee530abf4c4f4573bc60ae4b38109f55bca3ca9e1ba9f9fd6e34ba0d174892977a53356e1f5c88c614fe3ff3b3dd0818e7a2285412e3b37444bbe8a80942efcfd03958809a6966cda9430b2f0c9e552f4bced6e19eb3e85fc5758bd7b588297ccbed37ed94c3adc8c08ea8b058462aac9d57a939ec711bc4ecfec944d2b653b7cfc7b02a65d7057c9fdadd51b9da8cc4a3c68dae9da8b9c5319c1a2baa3d6c891c5ac4a39461484b5a01abc64df447ada24c04a4363e605eaccf339a9aa515e724206206da6d22bbd2f52e64cd7c895
+AD: f833e5ab4f8bc89167f80f576b1d6b22cdd0e30721f5f735799746cf645b6eff531d4c7b03584f3dfcb73cbd35ac42736216dc7f0de098a4f42c61ceb4b227ee288e47d697a0a76afc762f084e8fdbf9351c28340c324771c109a469341ab10ca10483ed2af5e878d7d3dc2bced2f72da3d1a25852b103ee9878e8158eb4309c1ce528f3a178ace153b6d3ae0af0d577cb3cb1540489e80427f792217ad8a09b84f027fca7ceb651b4264e98e94b4cb8a37b133390897233e8ba9103628d05b9609e8552c4a4b11e3f2fa8d56af36957390e88cba44656be3edace798cf8cdf7771bac338a256bc3cba6df97728f222f423ca7c6d149c9372d66163a98f79a234b00d4b75fb2ec860dcc2d1998105e4b9c01d68f079f3e0aa21cc534047fc7b858f8
+CT: b842eadfdf431c135bd6581d3eccae54e2267d8890036aa33dfe2d2d9715c44625441210a3a0d666d708d30588fe851ec36e10d8fa3584ed77b095149494b7c54379d62c8935e1d2b9a8f47e4759ad0b3437fdf2cc2fb6c5ea25ad10e0bdc9dc5b0517fc237eb783cc461c46665e2b1d1a5b8008dbf409ea2a63fea0276de23a32c99d92a498807a0f95e208fc6262321a78aafaf0cc3f833fff37bd4efa66f6023a25cdc6702cee3912799563d908a5183c9956a06aa71085d855dc7c809ed6e2889592b361ab3ab39060f8e419152187a794a19c2a1128882201900ea2cd597860674bf78d9720643df8701676718fd201baed4935a88e50558daf86edd08a9ab227ac7afae55c974b68de8dacad4a4d79b13ed6dfe74017a4cb9148e033436fb6
+TAG: 184095b7a8190abec08bb72d19eeb103
+
+KEY: 55a4be2448b464c2ea52a2f2664ed6aba865c14ea1fea77f4689331fd105c8d4
+NONCE: db37c0a405b4626d
+IN: d266e66272e5d3462081b004cb42429c8b9741e9f678153754d726f6f9aa513464763c5e793b482fe512fece97585f1426120d4cefb3d0a8cc0a8db4bde93fc72c78f44d4fecca14650c660d3e285b327e7cdd813063e7e867b8a2d059a41bab70432b7f857199894da90dca3fe5272bae1ec694a1a07b60b05df275784d4975637e4673109f3ba846dfd1a048b202ed8e89973be608b91ee4743b1e759900f1443038951fe6189e806638985f3c16338c3c60695df58e621154d79bb973859c4558e9dca90470f77c73f004443ad5db0717abbe43266f90e57397b83ac34d1fef2e897e2483d5bcdcb627abd64b0d1aef525835f25e76d6e9158232cdde6dce970b59f58de8a98e653be32fb58edabbcefa5065d73afdf1c9c4fbf50c1022bd22bfcb98e4b422
+AD: fd6a3fdd879f8880843eac20ae01c1b9dc3487d270a806572088ef2ddc1f1e0de495e71d4813bf5c501ad31e5d791c4b5b3a0a71b63fdddcc8de4b056064ef467989ecccc5d0160d403bf3a025d4892b3b1de3e062bc3581d4410f273338311eb4637529e4a680a6e4a5e26e308630a5b6d49ead6d543f8f2bf9050aa94ce091318721e1d8b96e279f34b9759b65037bec4bf6ccda6929705aeeeebe49e327e4d7a916620c9faf3765120658af34c53fbb97ec07657b3f088fcbdc401aa7949ddeda34d885018c2c23f4f0bb8218bf0d4fc90643658b4d8834f4a8c08e590c2a790995baa9e77627c342d283e454f84fcc05be15e9627a2d9be340c9d72f222bbdfc47905f56616cd9f936d49e4732f319f020513340fb8b22828db251b102b6b137c9533936d6
+CT: bd11ed07b7b4b30eeaf25d6a41a549cca0a5aee71f990ac566a37265d7af2ce3c03703427ee0b2755c2bdfc29f9d826aec6ee4ad28af48079ac23db16580b97424f3a4e35cc23625d39f95699d9ff5143e9a2bc26fcfee4f125f5aa2d968ccfc2faaf9db3c28850f6757f735cbc50c94c498bcde4f23bffafa8dd5f70d1a011e35eb26e905d4e68848fedebeb197be595c085ba33f11ba8398258445051751888e9bba111f800f31b37c447074ca6dce6d54b4dfad6cee5138643d4f6ac045e8047248924e88ea4294c7878bc22c9b41924ce301f22693c33733107bf1ba85e34806c5e4366ea66fc52a5f89dd9bf213239158b3d4d2600dde696c61d76c398b9bf10de9118e812e891c8f3355c0ecc6405f79bc32a58905e37888a1d8395fbedc3ac54eca569f
+TAG: f7d3b58a34a86e99267e5db206f17bbe
+
+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 b7f1cc6..103c196 100644
--- a/src/crypto/cipher/test/chacha20_poly1305_tests.txt
+++ b/src/crypto/cipher/test/chacha20_poly1305_tests.txt
@@ -1,524 +1,578 @@
+# Test vector from RFC 7539 Section 2.8.1.
+
+KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f
+NONCE: 070000004041424344454647
+IN: "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it."
+AD: 50515253c0c1c2c3c4c5c6c7
+CT: d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116
+TAG: 1ae10b594f09e26a7e902ecbd0600691
+
+# Test padding AD with 15 zeros in the tag calculation.
+KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f
+NONCE: 070000004041424344454647
+IN: "123456789abcdef0"
+AD: "1"
+CT: ae49da6934cb77822c83ed9852e46c9e
+TAG: dac9c841c168379dcf8f2bb8e22d6da2
+
+# Test padding IN with 15 zeros in the tag calculation.
+KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f
+NONCE: 070000004041424344454647
+IN: "1"
+AD: "123456789abcdef0"
+CT: ae
+TAG: 3ed2f824f901a8994052f852127c196a
+
+# Test padding AD with 1 zero in the tag calculation.
+KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f
+NONCE: 070000004041424344454647
+IN: "123456789abcdef0"
+AD: "123456789abcdef"
+CT: ae49da6934cb77822c83ed9852e46c9e
+TAG: 2e9c9b1689adb5ec444002eb920efb66
+
+# Test padding IN with 1 zero in the tag calculation.
+KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f
+NONCE: 070000004041424344454647
+IN: "123456789abcdef"
+AD: "123456789abcdef0"
+CT: ae49da6934cb77822c83ed9852e46c
+TAG: 05b2937f8bbc64fed21f0fb74cd7147c
+
+# Test maximal nonce value.
+KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f
+NONCE: ffffffffffffffffffffffff
+IN: "123456789abcdef0"
+AD: "123456789abcdef0"
+CT: e275aeb341e1fc9a70c4fd4496fc7cdb
+TAG: 41acd0560ea6843d3e5d4e5babf6e946
+
+# Test vectors from chacha20_poly1305_old_tests.txt, modified for the RFC 7539
+# AEAD construction.
+
KEY: 9a97f65b9b4c721b960a672145fca8d4e32e67f9111ea979ce9c4826806aeee6
-NONCE: 3de9c0da2bd7f91e
-IN:
-AD:
-CT:
+NONCE: 000000003de9c0da2bd7f91e
+IN: ""
+AD: ""
+CT: ""
TAG: 5a6e21f4ba6dbee57380e79e79c30def
KEY: bcb2639bf989c6251b29bf38d39a9bdce7c55f4b2ac12a39c8a37b5d0a5cc2b5
-NONCE: 1e8b4c510f5ca083
+NONCE: 000000001e8b4c510f5ca083
IN: 8c8419bc27
AD: 34ab88c265
CT: 1a7c2f33f5
-TAG: 2875c659d0f2808de3a40027feff91a4
+TAG: 2a63876a887f4f080c9df418813fc1fd
KEY: 4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd1100a1007
-NONCE: cd7cf67be39c794a
+NONCE: 00000000cd7cf67be39c794a
IN: 86d09974840bded2a5ca
AD: 87e229d4500845a079c0
CT: e3e446f7ede9a19b62a4
-TAG: 677dabf4e3d24b876bb284753896e1d6
+TAG: 356d9eda66d08016b853d87c08b5c1b3
KEY: 422a5355b56dcf2b436aa8152858106a88d9ba23cdfe087b5e74e817a52388b3
-NONCE: 1d12d6d91848f2ea
+NONCE: 000000001d12d6d91848f2ea
IN: 537a645387f22d6f6dbbea568d3feb
AD: bef267c99aec8af56bc238612bfea6
CT: 281a366705c5a24b94e56146681e44
-TAG: 38f2b8ee3be44abba3c010d9cab6e042
+TAG: 59143dab187449060a3ec2a1681613cc
KEY: ec7b864a078c3d05d970b6ea3ba6d33d6bb73dfa64c622a4727a96ede876f685
-NONCE: 2bca0e59e39508d3
+NONCE: 000000002bca0e59e39508d3
IN: b76733895c871edd728a45ed1a21f15a9597d49d
AD: cc1243ea54272db602fb0853c8e7027c56338b6c
CT: 1fb9b2958fce47a5cada9d895fbb0c00d3569858
-TAG: 042ad5042c89ebc1aad57d3fb703d314
+TAG: 219b4252deb16a43b292165aabc5d5ce
KEY: 2c4c0fdb611df2d4d5e7898c6af0022795364adb8749155e2c68776a090e7d5c
-NONCE: 13ce7382734c4a71
+NONCE: 0000000013ce7382734c4a71
IN: 0dc6ff21a346e1337dd0db81d8f7d9f6fd1864418b98aadcdb
AD: 0115edcb176ab8bfa947d1f7c3a86a845d310bf6706c59a8f9
CT: dad65e4244a1a17ce59d88b00af4f7434bd7830ffdd4c5558f
-TAG: ac1437b45d8eacf9c0fe547c84fb82a2
+TAG: 7ae32f186cf9ec59b41b764b34307d4f
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
-NONCE: 5d9856060c54ab06
+NONCE: 000000005d9856060c54ab06
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
-TAG: 6dd98710d8a889dceea0d0a936f98617
+TAG: d3f7b9c295f374651a84138648a5919a
KEY: a8b9766f404dea8cf7d7dfaf5822f53df9ccd092e332a57f007b301b507d5e14
-NONCE: c7f2f7a233104a2d
+NONCE: 00000000c7f2f7a233104a2d
IN: 4d6faeaee39179a7c892faae3719656cc614c7e6ecd8fcb570a3b82c4dace969090338
AD: c6d83b6a56408a356e68d0494d4eff150530b09551d008373d6dee2b8d6b5619d67fdb
CT: a15443f083316eef627a371f4c9ac654d0dd75255d8a303125e9f51af4233ff4ceb7fe
-TAG: 52504e880f6792a60708cc6db72eae42
+TAG: 63c2b4e0973096299488b0a66ffa54c1
KEY: 5e8d0e5f1467f7a750c55144d0c670f7d91075f386795b230c9bf1c04ba250bc
-NONCE: 88049f44ba61b88f
+NONCE: 0000000088049f44ba61b88f
IN: 51a1eebcc348e0582196a0bce16ed1f8ac2e91c3e8a690e04a9f4b5cf63313d7ad08d1efbff85c89
AD: 5d09bf0be90026f9fc51f73418d6d864b6d197ea030b3de072bd2c2f5cab5860a342abbd29dba9dc
CT: 35aa4bd4537aa611fd7578fc227df50ebcb00c692a1cf6f02e50ed9270bd93af3bc68f4c75b96638
-TAG: ccea1cbbc83944cc66df4dbf6fb7fc46
+TAG: 4461139c4055333106cf7f7556fd4171
KEY: 21a9f07ec891d488805e9b92bb1b2286f3f0410c323b07fee1dc6f7379e22e48
-NONCE: 066215be6567377a
+NONCE: 00000000066215be6567377a
IN: c1b0affaf2b8d7ef51cca9aacf7969f92f928c2e3cc7db2e15f47ee1f65023910d09f209d007b7436ee898133d
AD: dfdfdf4d3a68b47ad0d48828dc17b2585da9c81c3a8d71d826b5fa8020fee002397e91fc9658e9d61d728b93eb
CT: 8ff4ceb600e7d45696d02467f8e30df0d33864a040a41ffb9e4c2da09b92e88b6f6b850e9f7258d827b9aaf346
-TAG: 4eeddc99784011f0758ba5ebfba61827
+TAG: b2ad07b86aca1b3ab34033c12d6a08cc
KEY: 54c93db9aa0e00d10b45041c7a7e41ee9f90ab78ae4c1bba18d673c3b370abde
-NONCE: 3f2d44e7b352360f
+NONCE: 000000003f2d44e7b352360f
IN: 1241e7d6fbe5eef5d8af9c2fb8b516e0f1dd49aa4ebe5491205194fe5aea3704efaf30d392f44cc99e0925b84460d4873344
AD: f1d1b08dd6fe96c46578c1d1ad38881840b10cb5eae41e5f05fe5287223fa72242aea48cb374a80be937b541f9381efa66bb
CT: 027b86865b80b4c4da823a7d3dbcf5845bf57d58ee334eb357e82369cc628979e2947830d9d4817efd3d0bc4779f0b388943
-TAG: 4303fa0174ac2b9916bf89c593baee37
+TAG: 6de01091d749f189c4e25aa315b31495
KEY: 808e0e73e9bcd274d4c6f65df2fe957822a602f039d4752616ba29a28926ef4a
-NONCE: 1b9cd73d2fc3cb8e
+NONCE: 000000001b9cd73d2fc3cb8e
IN: 3436c7b5be2394af7e88320c82326a6db37887ff9de41961c7d654dd22dd1f7d40444d48f5c663b86ff41f3e15b5c8ca1337f97635858f
AD: d57cfbe5f2538044282e53b2f0bb4e86ea2233041fb36adb8338ded092148f8c2e894ef8766a7ec2dd02c6ac5dbab0c3703c5e9119e37c
CT: 9b950b3caf7d25eaf5fca6fa3fe12ed077d80dcd5579851233c766bb8bb613ec91d925a939bb52fb88d5eda803cfe2a8cda2e055b962fd
-TAG: 6bf5b718f5bbe1395a5fdfcbbef752f5
+TAG: 0887ec7d5e1a4e532746ec247a30825a
KEY: 4adfe1a26c5636536cd7cb72aa5bded0b1aa64487ad0e4078f311e8782768e97
-NONCE: d69e54badec11560
+NONCE: 00000000d69e54badec11560
IN: 19b3f9411ce875fcb684cbdc07938c4c1347e164f9640d37b22f975b4b9a373c4302ae0e7dfdeba1e0d00ced446e338f4c5bc01b4becef5115825276
AD: bda1b0f6c2f4eb8121dcbd2eebd91a03ae1d6e0523b9b6f34b6f16ceca0d086654fb0552bfd5c8e1887730e1449ea02d7f647ae835bc2dab4bbc65b9
CT: ea765a829d961e08bacaed801237ef4067df38ad3737b7c6de4db587a102a86fc4abbaabea0ee97c95ca7f571c7bab6f38cbae60cd6e6a4ce3c7a320
-TAG: b425cdf10cd0123a7e64b347c6b4b1f0
+TAG: a27f18846f5a4f7fcc724656c91cf4f3
KEY: eb3db86c14b7cc2e494345d0dfb4841bbd3aa1e2bc640cca0c6c405520685639
-NONCE: 88b54b28d6da8c81
+NONCE: 0000000088b54b28d6da8c81
IN: f75c0a357271430b1ecff07a307b6c29325c6e66935046704a19845e629f87a9e3b8aa6c1df55dd426a487d533bb333e46f0d3418464ac1bef059231f8e87e6284
AD: 34b08bb0df821c573dcb56f5b8b4a9920465067f3b5bf3e3254ea1da1a7fc9847fd38bdfe6b30927945263a91fa288c7cf1bee0fddb0fadf5948c5d83eb4623575
CT: 146ec84f5dc1c9fe9de3307a9182dbaa75965bf85f5e64563e68d039a5b659aa8863b89228edb93ff3d8c3323ab0d03300476aa4aca206d4626a6b269b2078912d
-TAG: 0058a8dff32c29935c62210c359bd281
+TAG: 854cbb42bade86a09597482c8604681a
KEY: dd5b49b5953e04d926d664da3b65ebcffbbf06abbe93a3819dfc1abbecbaab13
-NONCE: c5c8009459b9e31a
+NONCE: 00000000c5c8009459b9e31a
IN: f21f6706a4dc33a361362c214defd56d353bcb29811e5819ab3c5c2c13950c7aa0000b9d1fe69bb46454514dcce88a4a5eda097c281b81e51d6a4dba47c80326ba6cea8e2bab
AD: fe6f4cbb00794adea59e9de8b03c7fdf482e46f6c47a35f96997669c735ed5e729a49416b42468777e6a8d7aa173c18b8177418ded600124a98cbb65489f9c24a04f1e7127ce
CT: 911ead61b2aa81d00c5eff53aeea3ab713709ed571765890d558fb59d3993b45f598a39e5eff4be844c4d4bd1ef9622e60412b21140007d54dcf31b2c0e3e98cf33a00fd27f0
-TAG: d38d672665e2c8c4a07954b10ecff7d9
+TAG: 2865d2a26f413cc92416340f9491e1be
KEY: 3b319e40148a67dc0bb19271d9272b327bc5eee087173d3d134ad56c8c7dc020
-NONCE: ce5cf6fef84d0010
+NONCE: 00000000ce5cf6fef84d0010
IN: 27b5627b17a2de31ad00fc2ecb347da0a399bb75cc6eadd4d6ee02de8fbd6a2168d4763ba9368ba982e97a2db8126df0343cdad06d2bc7d7e12eec731d130f8b8745c1954bfd1d717b4ea2
AD: a026b6638f2939ec9cc28d935fb7113157f3b5b7e26c12f8f25b36412b0cd560b7f11b62788a76bd171342e2ae858bcecb8266ff8482bbaed593afe818b9829e05e8e2b281ae7799580142
CT: 368fb69892447b75778f1c5236e1e9d5d89255c3d68d565a5bba4f524d6ad27de13087f301e2ef4c08f5e2c6128b1d3e26de845c4ac4869e4c8bd8858ad0d26dec3b5d61a9e3666a3911ba
-TAG: 2e70564c3999c448d92cc6df29d095c4
+TAG: 1414f1b91966340417c38226ccca9d3d
KEY: 43bf97407a82d0f684bb85342380d66b85fcc81c3e22f1c0d972cd5bfdf407f4
-NONCE: 8b6ba494c540fba4
+NONCE: 000000008b6ba494c540fba4
IN: 4b4c7e292a357f56fdf567c32fc0f33608110d7ce5c69112987d7b5a0bd46d8627a721b0aed070b54ea9726084188c518cba829f3920365afc9382c6a5eb0dd332b84612366735be2479b63c9efc7ff5
AD: 1e0acf4070e8d6758b60d81b6d289a4ecdc30e3de4f9090c13691d5b93d5bbcef984f90956de53c5cf44be6c70440661fa58e65dec2734ff51d6d03f57bddda1f47807247e3194e2f7ddd5f3cafd250f
CT: d0076c88ad4bc12d77eb8ae8d9b5bf3a2c5888a8d4c15297b38ece5d64f673191dc81547240a0cbe066c9c563f5c3424809971b5a07dcc70b107305561ce85aecb0b0ea0e8b4ff4d1e4f84836955a945
-TAG: 75c9347425b459af6d99b17345c61ff7
+TAG: c5ca34599c6a8b357c6723ee12b24da8
KEY: 12fc0bc94104ed8150bde1e56856ce3c57cd1cf633954d22552140e1f4e7c65d
-NONCE: d3875d1b6c808353
+NONCE: 00000000d3875d1b6c808353
IN: 24592082d6e73eb65c409b26ceae032e57f6877514947fc45eb007b8a6034494dde5563ac586ea081dc12fa6cda32266be858e4748be40bb20f71320711bf84c3f0e2783a63ad6e25a63b44c373a99af845cdf452c
AD: b8be08463e84a909d071f5ff87213391b7da889dc56fd2f1e3cf86a0a03e2c8eaa2f539bf73f90f5298c26f27ef4a673a12784833acb4d0861562142c974ee37b09ae7708a19f14d1ad8c402bd1ecf5ea280fab280
CT: 9d9ae6328711fb897a88462d20b8aa1b278134cdf7b23e1f1c809fa408b68a7bfc2be61a790008edaa98823381f45ae65f71042689d88acfa5f63332f0fba737c4772c972eba266640056452903d6522cefd3f264e
-TAG: e9c982d4ade7397bcfaa1e4c5a6cd578
+TAG: e84211b6cfd43543f8b1b4db07a494d1
KEY: 7b6300f7dc21c9fddeaa71f439d53b553a7bf3e69ff515b5cb6495d652a0f99c
-NONCE: 40b32e3fdc646453
+NONCE: 0000000040b32e3fdc646453
IN: 572f60d98c8becc8ba80dd6b8d2d0f7b7bbfd7e4abc235f374abd44d9035c7650a79d1dd545fa2f6fb0b5eba271779913e5c5eb450528e4128909a96d11a652bf3f7ae9d0d17adbf612ec9ca32e73ef6e87d7f4e21fe3412ce14
AD: 9ff377545a35cf1bfb77c734ad900c703aee6c3174fdb3736664863036a3a9d09163c2992f093e2408911b8751f001e493decc41e4eeeed04f698b6daed48452a7e1a74ec3b4f3dcf2151ca249fa568aa084c8428a41f20be5fd
CT: 229da76844426639e2fd3ef253a195e0a93f08452ba37219b6773f103134f3f87b1345f9b4bf8cfc11277c311780a2b6e19a363b6ac2efe6c4cc54a39b144e29c94b9ebbde6fd094c30f59d1b770ebf9fcad2a5c695dc003bf51
-TAG: b72acab50131a29558d56ae7b9d48e4e
+TAG: 55e025a1eb87bc84d4be00c775c92ad2
KEY: 4aeb62f024e187606ee7cc9f5865c391c43df1963f459c87ba00e44bb163a866
-NONCE: 9559bd08718b75af
+NONCE: 000000009559bd08718b75af
IN: c5d586ceece6f41812c969bcf1e727fe6ff8d1ae8c8c52367c612caa7cdf50e0662f5dffc5ea7d3cc39400dfe3dc1897905f6490fd7747b5f5f9842739c67d07ce7c339a5b3997a7fb4cd0d8e4817ff8916b251c11ef919167f858e41504b9
AD: 51f5b503b73a5de8b96534c2a3f2d859ece0bd063ea6dfa486a7eec99f6c020983f7148cccb86202cf9685cc1cc266930f04e536ad8bc26094252baa4606d883bd2aeed6b430152202e9b6cc797ff24fc365315ed67391374c1357c9a845f2
CT: 252ea42b6e5740306816974a4fe67b66e793ebe0914778ef485d55288eb6c9c45fa34ac853dc7a39252520514c3cb34c72b973b14b32bc257687d398f36f64cc2a668faffa7305ab240171343b5f9f49b6c2197e4fbe187b10540d7cdcfa37
-TAG: 711ff33ef8d2b067a1b85c64f32f1814
+TAG: ab1d8a5a1f3eda9b5609c0028737477f
KEY: 9a19e72f005cae1ae78b8e350d7aabe59fc8845999e8c52fad545b942c225eaf
-NONCE: d9dae2ea8d2ffc31
+NONCE: 00000000d9dae2ea8d2ffc31
IN: 2110378d856ded07eb2be8e8f43308e0c75bc8a3fcc7b1773b0725b7de49f6a166c4528e64120bdf7c9776615d3ce6feeb03de964a7b919206a77392f80437faceb6745845cafc166e1c13b68e70ca2a1d00c71737b8fcbbbd50902565c32159e05fcd23
AD: 1cd73b72c4e103afbefd7c777e0480f3f5e68c60b85bd2e71ef5caebb175d7fc6535d39f38f92c24f2eb0fe97d878ed3d5967c0bb4394a5d41f7d34cda6e1523d3848f049cde554a7d31e1afeab5d3e6150f85858335cbd28c8a7f87d528058df50eea06
CT: 5f009fbce4ec8e4ca9d8d42258b1a3e4e920b2fbad33d5e9f07557d9595e841025193b521ba440110dd83958e8ee30219d952b418e98a6c624894aa248aedc0678f2d263e7bfaf54ca379fef6c5d2f7ac422ea4b4369408b82d6225a7a2cf9a9f46fd4ef
-TAG: aa0a5fa7d3cf717a4704a59973b1cd15
+TAG: 1c6bdff7d8b9554dc7bf40e50b37d352
KEY: ba1d0b3329ecc009f1da0fab4c854b00ad944870fdca561838e38bad364da507
-NONCE: 8a81c92b37221f2f
+NONCE: 000000008a81c92b37221f2f
IN: 6289944ffa3ccea4bf25cd601b271f64e6deb0eba77d65efb4d69ca93e01996e4727168b6f74f3ccf17bd44715f23ceb8fc030c0e035e77f53263db025021fd2d04b87a1b54b12229c5e860481452a80a125cb0693a2ba1b47e28ee7cbaf9e683c178232c7f6d34f97
AD: e57883961b8d041d9b9eeaddcfd61fa9f59213f66571fadffffdd1498b9b014f1ef2e7e56c3044d7f9fa7a1403a1169e86430a2a782137093f5456e142aad03a5f7a66d38009dd01b7fc02c9cf61642dedaf7cc8d46066c281ee17780674c3a36eae66c58d2d765075
CT: 9c44d9135db0dbf81c862c1f69bec55a279794cdd29a58e61909aa29ec4c120c9c5a508d856b9e56138095714a4bb58402a1ad06774cf4ecdf2273839c0007cb88b5444b25c76f6d2424281101d043fc6369ebb3b2ff63cdb0f11a6ea1b8a7dafc80cdaef2813fa661
-TAG: 65c746f659bcbdcd054e768c57c848c9
+TAG: 689a141bc11159d306dad7a4ecf6ad9d
KEY: 0cf8c73a6cffc1b8b2f5d320da1d859d314374e4a9468db7fd42c8d270b7613a
-NONCE: 3c4c6f0281841aff
+NONCE: 000000003c4c6f0281841aff
IN: 4434728d234603c916e2faa06b25d83bad3348990ecde2344368d1a7af1309bd04251bb2e0b72044948f8dea33cce2618283b6af742073a9586b26c1089335fe735141e099785a1235810a3a67ff309e2f0ce68220ba0077ad1a5dc1a4aef898a3b9ff8f5ad7fe60149bd0bd6d83
AD: a38d09a4f1c9241623c639b7688d8d35345ea5824080c9d74e4352919db63c74d318f19e1cbb9b14eebd7c74b0ad0119247651911f3551583e749ea50ff648858dcaaa789b7419d9e93a5bf6c8167188dbac2f36804380db325201982b8b06597efeb7684546b272642941591e92
CT: bdfbfea261b1f4c134445321db9e6e40476e2dd2f4e4dbe86e31d6a116d25830762e065b07b11a3799aab93a94b4f98c31c0faeb77ec52c02048e9579257e67f5a6bae9bc65210c25b37fc16ee93bda88fd5f30a533e470b6188c6ce5739fa3e90f77120b490fc1027964f277f40
-TAG: 4993ee9582f58eabdb26b98c4d56a244
+TAG: 780cc54bb6f1c9b78545c1562cd9d550
KEY: 69f4e5788d486a75adf9207df1bd262dd2fe3dd3a0236420390d16e2a3040466
-NONCE: 6255bf5c71bb27d1
+NONCE: 000000006255bf5c71bb27d1
IN: c15048ca2941ef9600e767a5045aa98ac615225b805a9fbda3ac6301cd5a66aef611400fa3bc04838ead9924d382bef8251a47f1e487d2f3ca4bccd3476a6ca7f13e94fd639a259ef23cc2f8b8d248a471d30ac9219631c3e6985100dc45e0b59b8fc62046309165ddb6f092da3a4f067c8a44
AD: 0c83039504c8464b49d63b7f944802f0d39c85e9f3745e250f10119fa2c960490f75ae4dced8503b156d072a69f20400e9494ab2fa58446c255d82ff0be4b7e43046580bc1cf34060c6f076c72ea455c3687381a3b908e152b10c95c7b94155b0b4b303b7764a8a27d1db0a885f1040d5dbcc3
CT: f0bb2b73d94f2a7cef70fe77e054f206998eacf2b86c05c4fa3f40f2b8cebf034fe17bcbee4dea821f51c18c0aa85b160f8508bd1dc455cc7f49668b1fb25557cdae147bf2399e07fcacaca18eccded741e026ef25365a6b0f44a6b3dd975ee6bb580f5fccd040b73c18b0fbf8f63199ba10fe
-TAG: 4236a8750f0cafee3c4a06a577a85cb3
+TAG: 2ecccea4607d14dbb2d2475792aeb468
KEY: ad7b9409147a896648a2a2fe2128f79022a70d96dc482730cd85c70db492b638
-NONCE: a28a6dedf3f2b01a
+NONCE: 00000000a28a6dedf3f2b01a
IN: 791d293ff0a3b8510b4d494b30f50b38a01638bf130e58c7601904f12cb8900871e8cf3d50abd4d34fda122c76dfee5b7f82cd6e8590647535c915ae08714e427da52f80aef09f40040036034ca52718ea68313c534e7a045cd51745ec52f2e1b59463db07de7ca401c6f6453841d247f370341b2dbc1212
AD: 9a6defddb9b8d5c24a26dd8096f5b8c3af7a89e1f7d886f560fabbe64f14db838d6eb9d6879f4f0b769fe1f9eebf67fcd47b6f9ceb4840b2dba7587e98dc5cae186ef2a0f8601060e8058d9dda812d91387c583da701d2ba3347f285c5d44385a2b0bf07150cbc95e7fcfa8ae07132849a023c98817c03d2
CT: c2f109d6d94f77a7289c8a2ab33bc6a98d976554721b0c726cbf4121069473e62ba36e7090e02414f3edc25c5d83ac80b49ad528cda1e3ad815b5a8c8ae9ad0753de725319df236983abd3f69ab4465d9b806c075b1896d40bdba72d73ba84c4a530896eb94ffccf5fb67eb59119e66a1861872218f928cf
-TAG: e48dc0153d5b0f7edb76fc97a0224987
+TAG: 17ec6cf2b172f01e3c456ad047196805
KEY: 48470da98228c9b53f58747673504f74ca1737d7d4bb6dbf7c0cba6ca42f80b9
-NONCE: 56fb4923a97e9320
+NONCE: 0000000056fb4923a97e9320
IN: bc6626d651e2b237f22ee51608ddcffeba5f31c26df72f443f701f2b085d6f34f806e29673584cb21522179edb62a82427d946acabce065b88b2878e9eb87ed1004e55ef58f51ec46375ac542c5782725ff013136cb506fcf99496e13fcd224b8a74a971cc8ddb8b393ccc6ac910bd1906ea9f2ed8a5d066dc639c20cd
AD: df8ab634d3dca14e2e091b15ecc78f91e229a1a13cba5edd6526d182525ec575aa45bc70fb6193ffcd59bad3c347159099c4f139c323c30a230753d070018786b2e59b758dd4a97d1a88e8f672092bef780b451fd66ba7431cbb5660ea7816cdf26e19a6ebb9aadc3088e6923f29f53f877a6758068f79a6f2a182b4bf
CT: a62e313ecf258cc9087cbb94fcc12643eb722d255c3f98c39f130e10058a375f0809662442c7b18044feb1602d89be40facae8e89ca967015f0b7f8c2e4e4a3855dbb46a066e49abf9cef67e6036400c8ff46b241fc99ba1974ba3ba6ea20dc52ec6753f6fc7697adbccd02b0bbea1df8352629b03b43cc3d632576787
-TAG: 675287f8143b9b976e50a80f8531bd39
+TAG: d29a8968067aeb457ffc114c3a9efb95
KEY: b62fb85c1decd0faf242ce662140ad1b82975e99a3fa01666cac2385ab91da54
-NONCE: 2f4a5ca096a4faf8
+NONCE: 000000002f4a5ca096a4faf8
IN: 03b14f13c0065e4a4421de62ab1d842bffb80f3da30bf47d115c09857f5bdd5756fd7c9ac3d9af1c9fb94f2640f7f4386cfba74db468e5288dbe4dd78bfe4f69e41480ca6138e8beacc6eaa3374157c713cfa900c07dd836eaecc8827fa3e70e052ae09e8473e2ae1a10b1bb669ef60a8dd957f6553daa8114918e17371f2ac327bd
AD: cfe3b7ab7550b0e8e2e8235fa0dcef95647ce6814abd3dc3f5a3bd7d6d282504660c34ad8341e4d11402c7d46c83a494d7ddb105e1002979023e0e3dc2978c9ae53e10eb8567e7a02b60e51e945c7040d832ca900d132b4205a35034fed939a1b7965183c25654931a9b744401c4649c945710b0d9733b87451348b32ba81de30ea7
CT: 8965db3d3ae4fb483208f147276e7d81b71a86e7202ffc9b1eaade009bc016838dc09ca4bcf30887b2f4243fbd652cd90ebed1ceef8151ff17ea70518d03b0f2a24960aa7de9b30fa65c2e2d57360061aae6d9376e984e9fcd5e5dd0911a4bc8deca832ffb76f252bd7da523076593ba6b174f7d9fb0377e066ecbb6638036241e86
-TAG: 3d0fc53e9058c2be32aa0850e0fab5a6
+TAG: 28a5284696ed82714eaa94c9ebe6e815
KEY: de9c657258774d4ebc09d109a0fc79d66493ae578797cac4eb8830a6a4b547e0
-NONCE: b5e35fe3398efa34
+NONCE: 00000000b5e35fe3398efa34
IN: 4d68fb683aa4f4c7a16ba1114fc0b1b8d8898610fa2763e435ded8771b3651078bef73d4dfd14e76a34cd5eb9ef4db4ead4da9e83f4ce50fe059977b2d17d687c29335a04d87389d211f8215449749969f7652dc1935a0f9a94538dc81dc9a39af63446a6517609076987920547d0098a9c6766cf5e704883ea32feaea1889b1554b5eb0ce5ecc
AD: 436ea5a5fee8293b93e4e8488116c94d3269c19f1d5050def23d280515457b931bbed64a542b317cc5023d648330a4b7adca14dd6f3783207b94f86ccaa0a0ac39b7db00ac87a99e3cd8a764ed9c75da8454479636ab2b29e770b166a5b75cacc425c919bf1ce9ac34afe6b4425c3d9fd2e48bc81e7d15516d60e592bfcc2ebefb660f0995f2b5
CT: 97a97b8f0f5420845ae8d57567f9bba693d30e6db916fad0b971f553ad7d993f806f27ab8b458d8046062ced4778c004b4f958a4436141637c6039963308dea2f54008b7feab79650295ed41bf9e65e1a2d75ab1c7b2a70ebb9e9f38d07a9a672d3e95ea78afe9ac02f2566b48b0251aef6eeeca8bd15bd8d43b559426aa9d15d960ee35cb3edf
-TAG: e55dbb21851e8a5b365f86d02518331c
+TAG: 4ef49e8a0c2ef85826d7f03e81c577f2
KEY: 6885bd333c336c7672db8ebdf24c1a1b605c5a4ae279f0f698162f47e6c73401
-NONCE: f0c4a213a6168aab
+NONCE: 00000000f0c4a213a6168aab
IN: fa905a2bfa5b5bad767239fb070a7bc0b303d1503ecd2b429418cc8feba843e5444ed89022fdb379c3b155a0f9ceab2979000a0f60292a631771f2fde4ef065aa746426609082969530a9c70ad145308c30ba389ea122fd766081511a031ce3a0bd9f9f583c7000b333b79ac004fbde6ec3eb2d905977ff95dcff77858e3c424fe8932a6a12139e6ec8d5e98
AD: 8ded368f919efb522bb6a9ad009e02ffbc6a16536e34d95cdb34f1153d7cb7b0f3c2b13dd05cedae27cfe68ec3aca8047e0930a29c9d0770c1b83c234dcb0385deae7ae85da73a5f8de3dfb28612a001f4e552c4f67ae0e2ec53853289b7017a58591fd6f70b0e954876bb2f7ec33001e298856a64bb16181017ba924648c09fc63c62eff262c80d614679bd
CT: 0cb3d6c31e0f4029eca5524f951244df042fc637c4162511fea512a52d3f7581af097eb642e79e48666cb1086edbd38c4777c535a20945fabc23e7c9277e2b960aac46865f1026eb6da82759108b9baece5da930ccfc1052b1656b0eadaa120ed0c45ad04b24ae8cdb22ceab76c5f180b46a392ab45b1b99c612546e6b947f4d5c06ad5abee92ff96345ad43
-TAG: d3b541ac446c84626daf800c0172eec6
+TAG: fad7d5a5193dfb121c68529ba8c0c35d
KEY: fbc978abb1240a6937ccc16735b8d6ed5411cdbc1897214165a174e16f4e699b
-NONCE: 7968379a8ce88117
+NONCE: 000000007968379a8ce88117
IN: 1a8196cd4a1389ec916ef8b7da5078a2afa8e9f1081223fa72f6524ac0a1a8019e44a09563a953615587429295052cc904b89f778ef446ed341430d7d8f747cf2db4308478524639f44457253ae5a4451c7efca8ae0b6c5c051aaa781e9c505489b381a6dcba87b157edc7f820a8fbaf2a52e484dc121f33d9d8b9ac59d4901d6ed8996ed4f62d9d4d82274c449cd74efa
AD: 3913cd01299b8a4e507f067d887d7e9a6ded16dd9f9bb3115c5779aa14239fd33ee9f25756d45262dc3011069356425b5c81a4729594e17c9747119f81463e85625d5603d05e00f568b0c800bb181eb717be8d7a93166a504ce1bc817e15530c5bd2b3df1d4222245ea78a38bc10f66c5cf68d661503131f11af885c8a910b6dce70bc3a7448dfae00595beb707fe054d3
CT: d152bcb4c24c3711b0fad28548dc4db605bbc89237cdbea7dbf956b8855d1161a0781f27bd56d798141e2ace339955efb98fe05d9b44cd011e645106bf47726183958cb6df34ce5766695f60bc70b6fe0fabb9afa009a8ef043dbf75f861881368fa07726625448fe608d578cdc48277f2dc53eaaf1bdc075269a42f9302a57cad387a82c6969608acacda20e1cac4596c
-TAG: 945dca73cf2f007ae243991c4fbe0479
+TAG: 96ae06cd7c72456e5568a42317046158
KEY: 77d1a857fbadfe01aba7974eea2dfb3dc7bf41de73686aece403993e5016c714
-NONCE: fdd913a321c40eb0
+NONCE: 00000000fdd913a321c40eb0
IN: db8915bfe651e2ecb3ce0b27d99a6bfa7a7c507cfcb2987293018636c365a459c6a138b4428be538413db15bda69e697cbb92b154b7f4d2cbb07965225aa6865d7dcd1ba2c17c484b00b1986fed63e889f25a4966dc3ed4273f1577768f665362d7d3e824484f0dded7f82b8be8797ad951719719365e45abbf76324bc7d657799d4d4f4bb1dba67d96ab1c88519a5bee704f7214814
AD: 3cb2c06c20cb0832bbacebfc205d77393ca1816346ea2681de4d3ab1fadb774ad273e4713290454496f5281ebc65e04cfe84ed37cd0aedc4bbe3decbd8d79d04a4e434876650e0d64309e336bfb10e924066a64acb92260b2dbd96735d03af03909aa6a80a6e89fda81037257aec21fe9be7e91a64e88e0a58fa38ecba4c4c4cffb61958f3c486cbb0b1d0b0014a2d1d3df248eec1ca
CT: acb825e6023b44b03b2efc265603e887954e8612b2ee134bdcb61501cfb9492952bf67be597c3a005b09af74d9e421a576d2c65e98104780feab838d8cb1bd135452ea39dc8907a4c1a6a9161805e4fa3e16989e6a418a7eea2582bf895da967028eab7c95d846a6de4b9980785814cf00484baa2f6de609912fff689bce6e854261ffe866bd8e63274605c7c5ad677bd7897ade543e
-TAG: 938478a41a3223a2199f9276d116210f
+TAG: bcf523a9bcf772e157941753c6d7401e
KEY: b7e9b90dc02b5cd6df5df7283ef293ed4dc07513d9e67331b606f4d42dec7d29
-NONCE: a6c191f6d1818f8e
+NONCE: 00000000a6c191f6d1818f8e
IN: 2ada0e3c7ca6db1f780ce8c79472af4e8e951ddc828e0d6e8a67df520638ff5f14a2f95a5e5931749ae2c4e9946ae4d5eb5de42fb5b77d2236e2e2bd817df51be40b1b8a6c21015a7c79fe06dba4a08b34013dfa02747b5f03930268404c455dc54a74d9c6e35485e10026da573cb41cd50b64cfafe4cfcdf3c9684ef877e45d84e22bd5e15fa6c8fd5be921366ff0dc6fe2df45f7252972c9b303
AD: 0f4269ed5ef0bfff7be39946a4e86e8bf79f84b70cd0b14fecb7be3c071316ce86de3d99d6871e0ba5667d9d7bba7dcaba10cb2a36668b6c3e2fb6c102938b75008bb9c213ebf9b85b5e91a802df0d31d7f11d764b2289f6225212694ab6b7c0e3ff36e84245d9f4f43fc5f98e654dea7ba9bd918658879c5bb4a1642af0d83113e3cf935d3c0d5208318f66f654eb17d8c28a602543e77ad3e815
CT: 22586fe7338e99cdaad9f85bd724ba4cfe6249b8a71399f9a3707b5c4323b8d96679568dfc8d230aefb453df596e13eb3e8a439249bd64bc93a58f95089a62b94f6562b821c83d91f56c55147381e9de4beb4ae81bd6fe7caef7e7e9a2078f2fba8f3e70d4910da9accc92b8e81a61b0fefbece4bd89443e66e8ddda8e47a66a62f17fd0e7d0a4852ce1a4d43d72a0b5e8914bbec698f060f2b092
-TAG: c082470297da8c5f682a169d28bc0239
+TAG: bd05336ed6426de412aac37661953052
KEY: 6b2cb2678d1102f2fbbd028794a79f14585c223d405e1ae904c0361e9b241e99
-NONCE: 7b3ae31f8f938251
+NONCE: 000000007b3ae31f8f938251
IN: b3cb745930e05f3ab8c926c0a343a6eb14809fd21b8390a6fcc58adb5579e5432021765b2d249a0ecf6ba678634c4f53f71495865f031ee97aa159f9ead3a3fcb823ee5238bdf12706a9c6137d236e2e7110ce650c321e41daf0afd62bab2a8fe55d7018de49a14efe6d83a15b2f256d595e998d25309f23633360f5745c50c4e5af8ccc9a8a2cb47064105a023e919c7795d2dc331d3f2afb8c42e5c0bcc26d
AD: 1c32fd3df22b3e440e2a3c7a7624990194cb16a5f74af36f87fd6ca7d410ce9064316a2d091945deef7d9b35ceec8396069307caced2b80afd7d53ec479c35cedf2dfd4c95c3dd8400f71ad34028c6e4f8681d93d0774064ba38f3fb9b0c1dfa1f5f0c7d20676a5911d999fb6a1d41367a8e99d852bf3d3b7b3f4c233249ed1ca135389a674ff48232ded3f6800a97b6d409c40e6cd70d09bf9d2ad25d9b9485
CT: ef70c7de98ab1d4ad817024a970be463443640eb0cd7ff234bdd00e653074a77a1d5749e698bd526dc709f82df06f4c0e64046b3dc5f3c7044aef53aebb807d32239d0652dd990362c44ec25bf5aeae641e27bf716e0c4a1c9fbd37bbf602bb0d0c35b0638be20dd5d5891d446137e842f92c0ee075c68225e4dbacb63cc6fb32442b4bcda5e62cb500a4df2741a4059034d2ccb71b0b8b0112bf1c4ca6eec74
-TAG: 393ae233848034248c191ac0e36b6123
+TAG: d48657033095db3f873c33445fec8d35
KEY: 4dbc80a402c9fceaa755e1105dc49ef6489016776883e06fcf3aed93bf7f6af7
-NONCE: 2358ae0ce3fb8e9f
+NONCE: 000000002358ae0ce3fb8e9f
IN: 197c06403eb896d2fa6465e4d64426d24cc7476aa1ae4127cd2bd8a48ce2c99c16b1cbf3064856e84073b6cf12e7406698ef3dd1240c026cbd1ab04ee603e1e6e735c9b7551fd0d355202b4f64b482dd4a7c7d82c4fe2eb494d0d5e17788982d704c1356c41a94655530deda23118cba281d0f717e149fbeb2c59b22d0c0574c1a2e640afad1a6ceb92e1bf1dde71752a1c991e9a5517fe98688a16b073dbf6884cfde61ac
AD: cf6ce7b899fb700a90d2a5466d54d31358ecf0562e02b330a27ba0138006b342b7ed6349d73c4c5c6d29bde75a25089b11dac5b27adea7e7640ca1a7ceb050e3aae84a47e11640a6e485bd54ae9fdb547edc7313d24a0328429fcffd8b18f39880edd616447344ebeec9eadb2dcb1fa7e67179e7f913c194ebd8f5a58aea73b0c5d1133561245b6d9c5cfd8bb0c25b38ffb37db5e2de5cdded6b57355e9d215cb095b8731f
CT: aa87f9a83048b6919c8f2b050315db4e2adae4a9c2ca0109b81961b520e63299dcb028cec0b9d3249a945ee67dd029b40f361245c740f004f8cf0d2214fcfa65e6124a3e74b78aa94345c46fdc158d34823ed249ee550431eaae9218367321cdd6e6a477650469bb3cc137a8f48d9cf27934b16703608b383d2145659922fb83bb2e7ee2ef938a90f2ff846a4a949129b1fb74dde55c5ae013c2f285de84f7dac7d1662f23
-TAG: 06b4318ac7f65d556f781428a0514ffe
+TAG: 298f84c8312029a7b1f38c5ea6021f57
KEY: 9e4a62016dae4b3223fed1d01d0787e31d30694f79e8142224fe4c4735248a83
-NONCE: 263a2fc06a2872e7
+NONCE: 00000000263a2fc06a2872e7
IN: 5a46946601f93a0cee5993c69575e599cc24f51aafa2d7c28d816a5b9b4decda2e59c111075fb60a903d701ad2680bb14aeda14af2ae9c07a759d8388b30446f28b85f0a05cd150050bd2e715ff550ebbd24da3ebb1eac15aba23d448659de34be962ab3ab31cb1758db76c468b5bb8ce44b06c4e4db9bd2f0615b1e727f053f6b4ffb6358d248f022bcad6ca973044bed23d3920906a89a9a9c5d8024ec67d7f061f64529a955ce16b3
AD: 4cd65f68f9f88c0516231f2a425c8f8a287de47d409d5ecde3ad151e906b3839fb01bb91a456f20ea9d394d4b06604ab1f9009ef29019af7968d965d1643161ab33a5354cda2fdc9f1d21ec9cb71c325c65964a14f9b26eb16560beb9792075a1597394000fd5f331bd8b7d20d88e5f89cf8d0b33e4e78e4904bb59c9c8d5d31ac86b893e4a0667af1be85fdb77f7ec3e2594a68048d20c2fb9422f5879078772ee26a1c560cbcbb2113
CT: e944bb2ab06d138ad633c16ce82706ecf0ef5d119be1f3460c9ce101d9c4e04ef1677707fca40d1f8ca181e07273707b06624d6d7063c3b7b0bb0151b757b3e5237fb8004c161233d8bc7e5f28ea1c18da1874b3d54c5ad6ff0835eed35c8853704585cf83996e5e7cec68180af414e04f08134d3b0384ebdf0393c9310b55d8698fe10cb362defc0995e9a13b48b42cff61ffd9fe4c3c8c6dab355713b88f6e98a02e7231a0c6644ec4
-TAG: 27de0d4ca7648f6396d5419a7b1243b7
+TAG: 6234e81e089b779d0d509d14e566b5d7
KEY: 18ca3ea3e8baeed1b341189297d33cef7f4e0a2fab40ec3b6bb67385d0969cfe
-NONCE: b6aef34c75818e7c
+NONCE: 00000000b6aef34c75818e7c
IN: ef6d1bb4094782f602fcf41561cba4970679661c63befe35ff2ca7ad1a280bf6b1e7f153fa848edfeffe25153f540b71253e8baba9aeb719a02752cda60ea5938aab339eead5aabf81b19b0fc5c1ed556be6ad8970ea43c303d3046205b12c419dea71c4245cfedd0a31b0f4150b5a9fe80052790188529ab32f5e61d8ccde5973ed30bdf290cbfbd5f073c0c6a020eac0332fced17a9a08cef6f9217bd6bef68c1505d6eed40953e15508d87f08fc
AD: f40f03beaa023db6311bad9b4d5d0d66a58d978e0bcbbf78acebde1f4eb9a284095628955a0b15afc454152f962ec3ea2b9a3b089b99658e68ede4dee5acd56672025eb7323bcbc6ba5d91c94310f18c918e3914bbbf869e1b8721476f9def31b9d32c471a54132481aa89f6c735ab193369496d8dbeb49b130d85fbff3f9cb7dccea4c1da7a2846eef5e6929d9009a9149e39c6c8ec150c9ab49a09c18c4749a0a9fcba77057cdea6efd4d142256c
CT: c531633c0c98230dcf059c1081d1d69c96bab71c3143ae60f9fc2b9cd18762314496ab6e90bf6796252cb9f667a1f08da47fc2b0eecda813228cae00d4c0d71f5e01b6ce762fa636efffe55d0e89fdc89ba42521cc019ab9d408fcd79c14914e8bbf0ea44d8a1d35743ad628327e432fdcfeb0b6679ddca8c92b998473732abd55dba54eefff83c78488eee5f92b145a74b6866531476fc46279d4fde24d049c1ce2b42358ff3ab2ba3a8866e547af
-TAG: a0a5242759a6d9b1aa5baf9a4ef895a2
+TAG: e3b4192f6e50528c4f4f70267f094c56
KEY: 95fdd2d3d4296069055b6b79e5d1387628254a7be647baafdf99dd8af354d817
-NONCE: cd7ed9e70f608613
+NONCE: 00000000cd7ed9e70f608613
IN: 0248284acffa4b2c46636bdf8cc70028dd151a6d8e7a5a5bc2d39acc1020e736885031b252bfe9f96490921f41d1e174bf1ac03707bc2ae5088a1208a7c664583835e8bb93c787b96dea9fc4b884930c57799e7b7a6649c61340376d042b9f5faee8956c70a63cf1cff4fc2c7cb8535c10214e73cec6b79669d824f23ff8c8a2ca1c05974dd6189cfee484d0906df487b6bd85671ce2b23825052e44b84803e2839a96391abc25945cb867b527cdd9b373fbfb83
AD: 24a45a3a0076a5bcfd5afe1c54f7b77496117d29f4c0909f1e6940b81dde3abacb71ec71f0f4db8a7e540bd4c2c60faee21dd3ce72963855be1b0ce54fb20ad82dbc45be20cd6c171e2bebb79e65e7d01567ad0eeb869883e4e814c93688607a12b3b732c1703b09566c308d29ce676a5c762a85700639b70d82aaef408cf98821a372c6a0614a73ba9918a7951ea8b2bb77cd9896d26988086d8586d72edc92af2042ff5e5f1429a22f61065e03cfcd7edc2a93
CT: 40c6318d9e383e107cdd3e1c8951562193c3ef64ee442432a63e2edefc78f32ab07772aeac172cb67ecf4d21f8b448423527bbeb9d8ddd0b46bdb27f74096ceb24e41963b4cdca176676a75bdbe3abc270b349ac0c6cbd9c3a5cd5bce20202fc5cc0c1bdd4fd25e121e0a24bd7bbeb9b19b1912467bf5338ee2ce88aa383c082b42cc399c9654ca325f35523e81438beb3f8926be79c378822d7c8f785614408a5f7cac49e4543188725643e6c1a70b46d0ec400
-TAG: 5801e84192c7267f66b0e04607a39a3e
+TAG: 874875c9a0ba3060a0680291c3dc85a2
KEY: 6ae1102f84ed4dc114bb9d63f4dc78d7dbb1ab63f1659dd95f47940a7b7a811f
-NONCE: c965d578ba91d227
+NONCE: 00000000c965d578ba91d227
IN: b82a8a9209618f1f5be9c2c32aba3dc45b4947007b14c851cd694456b303ad59a465662803006705673d6c3e29f1d3510dfc0405463c03414e0e07e359f1f1816c68b2434a19d3eee0464873e23c43f3ab60a3f606a0e5be81e3ab4aa27fb7707a57b949f00d6cd3a11ae4827d4889dd455a0b6d39e99012fd40db23fb50e79e11f8a6451669beb2fbd913effd49ad1b43926311f6e13a6e7a09cf4bebb1c0bf63ce59cd5a08e4b8d8dbf9d002e8a3d9e80c7995bb0b485280
AD: dfd4ac3e80b2904623ff79ea8ee87862268939decf5306c07a175b6b9da0eb13ac209b4d164755929e03240a0fe26599f136fb2afdffd12bb20354aa1d20e5799839abb68ae46d50c8974e13e361d87ef550fe6d82e8b5b172cf5cd08482efdef793ede3530d24667faf3a1e96348867c2942641f4c036981b83f50236b8e8a10b83ebf6909aad0076302f1083f72de4cf4a1a3183fe6ec6bfe2e73e2af8e1e8c9d85079083fd179ccc2ee9ff002f213dbd7333053a46c5e43
CT: a9aeb8f0a2b3ca141ac71a808dcc0c9798ac117c5d2bd09b3cfe622693a9f8ca62e841b58bddb2042f888e3099b53638b88dfc930b7a6ee4272d77e4b1d7e442bab6afbde96ab0b432f0092d9ca50eef42f63c60c09e7b8de019b32ebe4030c37b8183cc1e3b913b0ce4ee4d744398fa03f9af1c070bed8cdafd65b3a84140cb4deadc70184de757332ce3780af84353f540755227e886a8d7ad980f3dd6fd68263d82e93f883381dec888bc9f4f48349aa2b4c342cb9f48c6
-TAG: f26b3af8a45c416291ce66330733b2f8
+TAG: f6dcad5412b95994f5e4d6829c2eba98
KEY: 405bb7b94715b875df068655f00513cb1ae23ffaac977ce273e57d3f83b43663
-NONCE: 5c6da1259451119a
+NONCE: 000000005c6da1259451119a
IN: f9f143c0c52c94b4ba7b0608b144156a49e7b5d27c97315743d171911e3645ab7957c80924e3c6b9c22ab7a1cac4b7e9c0de84e49fd5e4a2d1ab51d764fc5670318688ec942f7ab34c331dce8f90fea6972e07f0dadec29d8eb3b7b6521ddd678a6527a962f4d8af78c077e27f7a0b2ef7eabd19e92b7f8c1e8fb166d4763ce9c40c888cf49aa9cdfc3e997c8fe1cce3fe802441bbd698de269ff316f31c196e62d12c6bb5cd93fb3c79ca6369f8c1ac9102daf818975ea7f513bb38576a
AD: 6fe6446505677bf08b385e2f6d83ef70e1547712208d9cebc010cba8c16ea4ece058d73c72273eed650afdc9f954f35aa1bdf90f1118b1173368acbc8d38d93ebf85bd30d6dc6d1b90913790c3efa55f34d31531f70c958759b2ba6f956c6fcdd289b58cb4c26e9515bf550f0fd71ab8527f062c9505cbb16e8e037d34de1756bef02a133dbf4a9c00ac03befc3fb7f137af04e12595ce9560f98b612480fcdba3b8be01db56ebec40f9deae532c3b0370b5c23a2a6b02a4de69efa8900c
CT: 1a4b073881922c6366680cc9c2a127b26f264148651b29abb0c388cf6c9b1865dba5a991e1f8309efbdb91bce44b278772c58fd41273526c33fec84beb53d1689b9da8483f71be6db73a73417069bb4cd3f195236e8d0a00d124eed3a6b6f89415b19a27fbe35774f6a1a6ee4bd4350b252b975f0db2d2eea82f4836350850d6290901e726e8af13644e2d98bc1d569c20800521e6affe976bd407049a2e6d9dd23f88d52e651391ecd2fc45b864310824aaadfa203762a77c1d64562dae
-TAG: 0060026d3efc120f11c0739959ae0066
+TAG: 90fcc2544880250f1c3abe8a3761ba08
KEY: 8c602bd94c630cd00c7a9c508067a5a9f133d12f06d9f6fe2a7b68dce4786d8a
-NONCE: 760de0f7b7cb67e2
+NONCE: 00000000760de0f7b7cb67e2
IN: c3ff559cf1d6ba6c0cc793ca09a0ba573a28359386a6ec93e1bacd8e630209e0b477a20aedec3c9cbf513ee6a1e3887112218d6155b9875f7e6c4bbba2c31972e905d19f529f4f0f9502996199f94f8728ba8d6424bb15f87fcacd88bb42c63fcc513759712bd0172b1e87c9da122f1993ffb7efd3a5c34b240dd3db89dddea36dbeb2836d9f8648f8e7cd428c0f948097af753b35f9876059e7702027bb00dc69071206e785f48fcbf81b39cc0343974ac70784a2e60c0df93b40379bea4ad8cac625
AD: 9e14907c3a8e96c2636db1f3d78eb1f673d6ef043cbbb349467f1fe29bf60f23d5d5d1c3b133a8ad72065d822347541c13d1574baf737eb3cc3382fb479e6d5193b9c8e7d2444c66971ef099dc7f37f6cd97b9f7959d46e2cf25e8a5b3111b4d9e2ef906d905f0ee2d17587f7082d7c8e9a51509bde03d3d64338e1838d71700f1b4fcb100b5e0402969da462f26f974b4f9e766121f8fd54be99fc10beb9a606e13fbb1f960062815d19e67f80093360324013095719273c65542b0e31b1a2a3d928f
CT: 2794e6e133f6892f23837fff60cf7c28ee9942f8982ef8089db117903d0143293fdf12ea1cc014bcd8806fb83c19570eed7af522db0de489bbc87133a13434518bcfb9cda4d9f6d832a69209657a447abf8afd816ae15f313c7ea95ec4bc694efc2386cdd8d915dc475e8fadf3421fbb0319a3c0b3b6dfa80ca3bb22c7aab07fe14a3fea5f0aee17ab1302338eeac010a04e505e20096a95f3347dc2b4510f62d6a4c1fae6b36939503a6ac22780a62d72f2fc3849d4ef21267fffdef23196d88fbb9b
-TAG: 457cce6e075ffdb180765ab2e105c707
+TAG: 7fa630c9bcb455e89f13d7a99d5e8dbe
KEY: bd68ff5eb296c71cfe6bc903c14907f7726bcb1331f0c75f7801cd1b7948f3a1
-NONCE: 65a748004b352ba6
+NONCE: 0000000065a748004b352ba6
IN: 52bf78c00f6e5dca2fc60e2e9a52e827df97808e9cf727773860cafc89f4b64178a19b30b46ed813fe00c8f09b25a6a1b6e350d5b005122934a59bfbd5e6e0c635c84a5226c3f2f7dcf951560f18ac220453d583015fdb2e446c69c6e6fdecf2e595e04fab1b0c506e3c6bd5e4414a35f15021e97f447aa334f54a8f1ef942dec6273511b5668b696fca97188ff15ed84b2f46145cce031c1a7f00bd88bb83d90797edc46161b3fda7a2299173496d73b812139556e8b4eb318078b9eb2ae5046e83b79dd3d45950
AD: 5557b08a5010cbc9f46bb140c2505f68684eb24889324bff44b27234fd7a95a99cfb4ff90a8f9982085b725f78ac42eca6ce7f3314e457dc41f404008681a9d29ba765660de2e05bb679d65b81f5e797d8417b94eb9aabbd0576b5c57f86eae25f6050a7918e4c8021a85b47f7a83b4c8446898441c5cc4e0229776ef3e809cb085d71f3c75ec03378730cb066150f07e60f96aec983c0e7e72bf6bf87ae42228dfda195f97855fcdf4e6d1c4479d978abcfa276d16ed60ecbfbfc664041335ce65a40a2ca3424df
CT: a5c8cf42287d4760fca755e2111817b981c47e85b0047de270ec301ca5f7b3679f4749210892b6ea6568f3a6a4344734a0efc0120ffedecf212d55cbcbb67815ac964875af45f735b70092a8f8435f52fc01b981ae971d486026fb69a9c3927acfe1f2eab0340ae95f8dbee41b2548e400805ece191db5fd1f0804053f1dbfaf7f8d6fded3874cb92d99a2729d3faaa60522060cf0b8101b463b3eb35b380fcddb6406c027d73fe701a5090c8dd531c203ce979e26b9ced3431e2b726a7244a20d9377bd62951bf5
-TAG: 4579fa1fdb4c674cc3cd232b8da52a97
+TAG: 82c6194de4d27aac4c54b023b9831634
KEY: 934fd043c32d16a88fad01c3506469b077cb79d258b5664fa55ad8521afdcaa2
-NONCE: c7091f6afbbeb360
+NONCE: 00000000c7091f6afbbeb360
IN: 2bdd1fc4f011ef97ea52ec643819941c7e0fb39023c2f3c7683804a0ddee14a5d1784a5246966d533b3538edc7d8742d27061c3cab88df0318ab242102de3a54d03632eeb871b72c7e8f8065b49f4a91e95e15f3f46b29fd76b8fcea0d23570c5530e3bbb8a6aafa9ae32c1b3eac653c5ed5fdb2da5a986075808f6385870c85b1913e26042a9d8e78f5bc2ea6de5a64f8aeafa22adcffc7f6932d543c29bb3a04614783f948680e433a71573568d2ce984d249fb4fc06a9f358c76aa3e64a357f4eae924c1356bd5baccf7e0f
AD: f737dd85638eb324dd3891219c5eef7c2dd053cfd055d447a411eba304a4b27dce981d112c4540590933c153d603022c91ebd2b4a58069d27e6ca17a462ef822ca41bffa80b43a68b1b564644cb3c5a7f0fddf7a13a30ff24437fddd8ef93c6f6f205d054f81890d982bd4d4ece0b1563677e843fe48c1f54e9a57ed4da66061482712e710a401073be5080d5b8b96525bffa67de5af31d50385fbbf1a87c21bf0e0a1fdff69ec32c7b7103e0b8ee6c844245e0fc84b9f89fcce62966cea68e2871d3b82e8df424c76309fc88d
CT: dd13fbf22c8d18354d774bcd18f7eb814e9b528e9e424abc4e3f2463195e8018576565d16ab48845d11c9277f2865ebb4dc412fd5b27078f8325eadf971e6944c66542e34d9dda971e2aba70dbd3e94a1e638d521477a027776b52acf90520ca229ebc760b73128879475d1cbe1f70fc598b549cd92d8a9ac6833e500c138c56474db84cb3d70b7aa4f293a4c2b4d818b0ff9fd85918dc590a12a8c0e375c4d98b7fc87596547eb960676aad5559834588f00f251a9d53f95c47af4df3c4299175d5211779c148cfc988a5e9d9
-TAG: 476616ea15190c1093fdc4a087643cae
+TAG: aeb0a4eb29886f0a7a12ec0516bd4af5
KEY: f9f6eb9ad736a8f66e7459fef5ec2890188dc26baf34a95f6f0384e79f5c6559
-NONCE: 7858dfc084fe4b0f
+NONCE: 000000007858dfc084fe4b0f
IN: a644ca6e7cc076e87eb2929fd257693fce0f6fb64fd632f7f07c648ebd03696c8e262e6a810d7b7c4e5eef8c65b5323c99dbba50a70b4a9e5c2a9e7315973cd67f35d8052ce9a85a206416dd3031929f4f929b13d0a5fb10cb73c65f6c0ace019da146b51c5274a099f44e3669d26add6f2ff081e886f3cf952fe0dbbe6b0534c23e307574bd35fbd657f5fcbd5dc19fb382a1dc0a2dc8285a0350f71554e4c601497749e35567dd4a273cddc9a48ce53a5f1d297fd8baf8d1b9feb35d9151114345abada4d90db947bb9a743c175f5653d1
AD: 2048d1c2ddfb5ec385b201832c7a993f229ba72ec16d6ebf723ef0c5032b9966209a9e8a63151b40412e96b82f86728ea6588c7e8e11ac71cc8eabab8c4b54de866658d9c5011def61fb3dbe4e630158a45ea41a2ed55ebd1efb1abeda7637de6fa5fd2f151c6d2f385bf6cd002ca8b4a2896e0d65944ee913e3c784669dd201b1985ef3577f7f123a5f9bcffa176c8f557c4f729133cac518642f27d9b22ca9b97faaafe5b669a10b79ace4a7d5727df146c77ce681357d69f9c2d65b4401bd73cd113387e3b3a05d897adad7a24c485e7b
CT: 4146faffd7313f5d9f625370d20413cc62ab65f4acfa3c7ee1125b937dd7a39f638fc46c8ed004fb525698de5d8620ec153435571817c3de257b0d0e648ebb92940c86a98262d54e764f28cbdd4f7d9bea970291f2110414f62064d7229c6332236c507b3dac742e651d85a2a22fb243c0cc7cc2d016e5bea38f33f9a9ce048944a5fe8b078d71d23168e12dfe5a0f0b829771edc7073fb96032b7be471337a37aca0cf7c0cdd543eed686cd34934717fd79a3f18492eef72f9f450b880aa7e2e1b65e3b04c22e72301338b43aa32ceec2e6
-TAG: 10ffaf2be316676da02d7473a9df87b9
+TAG: 61c6d4d6918b04fc1b72a7a0e9a3b799
KEY: 29b19636cdd32507fd98ec4ee26caab1a917646fb8f05b0dc01728a9f4a127f0
-NONCE: 06699d245916686d
+NONCE: 0000000006699d245916686d
IN: 5fdf913aceab1d6dbaf7d9a29352fa8a3eb22718043a79cffa2fe8c35c820aec7c07644b8785dcf7a433b4189abb257fb12b06fae0662641011a069873c3e3c5ccc78e7358184a62c2005c44b8a92254958eb5ff460d73cd80284d6daba22c3faba046c5426fe8b7cacec64b235a8f8d3e2641e5bc378830594bcfb27c177aea745951ee5780a63705727ef42c4ad3abf556d88e3830f3db6b09e93edd09485cbf907f79de61f8dc5cb5fb7665ffa0ef53cb48702f6a81d8ad421cef20c1dbdf402b8fafed56a5361b2f93f914a2380fdd0557faf1f4de
AD: 39116c49cc13adb065b92cb7635f73d5f6bf6b5ccbf72a3f65a5df6bd4a661105015358d9e69f42e98aed795e8161282bc113058b7ef3b9e23fcd8eeab34a392e03f4d6329c112cb968385ec52a7afc98bb8695785af6b27b700973cc952630b7247ce226b4fbb99b8a486370bf6345d4516c52c64e33f407c4f2d1ba90545c88732d98bbd97972ac5e94c694624a9b3782b0099824651cb7567914d25b3e13181a791dbcd40e76e836b3350d310a52151bf835d3c357c9871482c2928e8404c6e533406d4d6fa8f63366f2c4ed828141f1ff00f01a536
CT: 01e237220b619054a1f3670928fe67d40484b5af40fbd04d032500aac5acaa3b4584dd99a58c390627636a50de5d744f76a56a33205f9e3b00e16162eb47ff3333e1e208ca200f1a5338a86e17bd92dd2d16af8bb022a7dc05b923d019e05247f1a0d0b4bfcfce58dd6d83830705707676d55739abee89fcd5cb94b8fde006a5da02df64b00a467f45970b5ca440f22319b9735a55d454b9fba0588fef0c59d3d83823eba6e0601a96e10233826c5adeea6b2a51d386a07a9e047ad405b23d4c3d89f30c31e3199f0c8f927bfac43ceea1f969de0a8c0f
-TAG: 092f9f3c5d4f2570c9946c87967f4579
+TAG: b9fec6da464c7b85b2a4726694562fe9
KEY: bae06b9b5456707551c7b0e207aae02a19b4848ad8ca4ce40705bf8c856a6e52
-NONCE: 9c27065c3ef2d522
+NONCE: 000000009c27065c3ef2d522
IN: 50cdd88137ff428a88e87b5845be4924f6387537bb5c0b654c80107ab5698db75b2e131848e7aec156d31aed0766d31c379fece4095d38264c6d5945974d25f729c3b0ba11ea853e9cebdb6f03bb670fce08adff74d0a8f02d633fb34e0fb7337a8e66e1c12084d914fb6173b8105684db822752c6751a372bb16690284d661b8b8bc6a6dfbddf45ebc2219596f9f2f878c118df69030de38b4d99dde43b9b9e20a3dab691645dd518342f49b06a0fe0a397adf261e99f07af5b0b3798b1022ba0939c42a54d3b93641cffa3c2e174bce9ab7ad7e7c7924308d1a77a
AD: 5d5590db1bd316eb7a0e30e4c7a6dfdbef9d3287fdb8d824389599c3c2ee262b2192eb5b9708e66e22dbc7eca83fa1a995da3ce64c86fe5aa08b826d476dc439497e2d12e2702c63c8d27aa7f09fedee816dc8bffe1351d53271a34d4292b613b7efcedb7e3cf3e6ad389eef12471e9e20e38e7ae22a323abbadfe8f2e84271bffb1819feb4f77b82843cb8757cfae293631bc6d39669107e7015c85d7343ffa6fc1bbe6f5ab4de30cd752a281e03061ea89de2a3f5e90e20da22fd6e8525c100738667f42212b2cf45fcb23bbb54b21c117484b22c6e514685314df
CT: 66b7f69ac49fab4e5975aeb6fa9287d8eac02ac312c4de78f77f59da16cbcf87274e66801c4b862c33ea79cdc76528862bb2956c06db8b8acfac4794ebf39e35ac03cc73a4351a4ff762f681a48d6f25cad36e2814c9b5c40b9ae92509e58429106847789454d376836936bebc7a80e6c66e7aa52936d6b361378a41f849ad4e48f9ee2d3e92217a908fa8eb35736ac8ada7d32ae05391f2d807be3512543c36138a5fe660dd4cd4cd184bb43b6ba6bc0bae634e2fa9669304cd510ed5103f630068ff76d3375738de60a381842b421477e25a490cdd6894b2704125
-TAG: c9998a677dfb0e91924aec9de0afd585
+TAG: 94118ccc68de1921d480aab43d1ef0d1
KEY: 2cb374cb048c168f2e43597f028d9e73cade1b458284ffc260d4fc6b9011c414
-NONCE: 9fb909169bc9f4e9
+NONCE: 000000009fb909169bc9f4e9
IN: 39eb929482784b463546f5d84f80510f2019923d465b99d194246d68c7ae343f91971d8f7059cebb86aa5dd099289aa648248b8c5ca04e66ac5e9bf06776e3883495397618a0227f035666806e636836b47d3d2d255a49db79866cf00d9ddabda259c4f968a1e01e651c7811cebbee2ee71803ea1d9d23487eb221f2d9555756800aba5e6abbefd6fb72b3151cc99ced599cd86df2a9b1ce94f89f347eeb124d9e7f0d9cc48d3dedd819e6d3dbac57ecee199547b266116a2035c9acc4c8ca3271ac74952372897c4a5f2cb84e2d81817fec9d6774f6d8a5b2021684132db4fca3
AD: 0c7bd4f3a30ee944ccf9489181e6911684dcffad4593a9b65a67dfc80718c69b35897d01281016b7731e12c15cad8482e79458e08a755622e3f3f22a23ef6c8487a36ad1771ba06c641f06f85de0db3776cc6df06ad8fe3b4d60d58508de943083f17cbb9dc0d390ac94d8429e8c6fcfe063f424fbde0f62f6a7f91a626d195dc498a6e69bd93109c4e9ba13e7330aba456d710a4b0cc279d4045660406e26d61dff70d4a33c4f1052869f9248024e7a0f85f1effb32f6f7ccb1f860f3ef04e8f7b29096e6bcf9d4b3e0ce703e9bf228fdf515c2ff9cbabd16987be0f9babd3d8a
CT: 91ddadb86b7ebef798ddaa59da51d71316fcf6c9678143178227d778750dc9827fc6cc21e605c505023e6db25849df7fb6fc1ca4d223aa215f8c85b724643c83bf8218815a9f9e2952384e0ca6a80a3760b39daf91a3c6154c4728c2371fd181fa3764753d0b0c23808a82cd8f0497246e3a0f17f8906a07c725d2891ce968a9d432c2b102d85c05510b28e715bb60d0403a77490e7f18be81218bc4f39287b9bb09f50227dd2f55e4fb70c4438da8ba3c8ffbced87d90155913faa9979fc57e6cbeddfaba3d3ab4163c0eebc7d94279c27d3ed56338893dba542eaefba30f8c3b
-TAG: 728e60f8124effbac234f70da925881c
+TAG: 8980e8e4fe796428b733f4f8e1954a45
KEY: f0f16b6f12b3840bbd1c4a6a0811eef237f1521b45de9986daec9f28fca6485c
-NONCE: 7ac93e754e290323
+NONCE: 000000007ac93e754e290323
IN: 0530556424d823f90a7f1c524c4baa706aad2807e289e9479301e3e7a71f2a5e14e6232ea785f339c669af2e6d25f1d5a261096a548d23864945c3a589b67b09b0304a784d61b42b2419139485242e0d51fcbe9e8fed996d214de8717e6a71f8987ccad65eb92e66707034a5ae38e6486e26eb4374c565aad5df949dab209f7f7bcd8eb6fc52761a26cfe5d01fd349e59f4042e6dbe6b232f9301b971dee121d8aa1e62d40f043a42f3aa859d867eb809b1ced5ae1ec62cacf94a69fafd0631a8b5dfd66d855900fb295eec90ae5fcbf77beae267a79d24081bb322d8c4e0630fed252541b36
AD: 13bfcc17b810099cda31ca53a1323db9b07633ceb2088a42263a4cbd6a4d47978776005c9a20203319c3a3ae434e9a26fb541047dc9df38dc36c095267272e203d0b24d119a70a7e96041b6d82b7c4d5570e1e4a1cf2f6e44ae63fe005a1f5b900778c482f7bd89e2e02305e35b8f61b7bb2c78a13aebfce0145d1c5aa0bf1d10d23616d5a3a446de550302f56f81dc56fe4f3700f14242688d9b92d8a427979b403c8de8c493a2cde510eaf6b285e6675b173aa0314a386b635c7577d5aff0d868a0cb3f73c8d2005f8c7c9dab5a060ef80102c9d4a4af988838afe87aff04c0689e8c3c7f9
CT: 2c14c3931e98e84507c4c165c2ed47ad4a178f0e216cd7ac2453bbbf9f85dd06bd8ef54a9ff1fd3dd8e0cafb635d8f2de861a0db5b14d03f17aaea8c89b3010797c71c13a0e666899d7ff6e53c4f08be8ddb3e37688b5afa088079b6c7519b833e16560073e699530302028a3496e05edddec01a23a4c7983956250e8d9e616f7b940856955cde81c1efabf6b7b92f153d03f4cd17e7f7d2907670cfc84d45c1d7936775a3fce47968504278ffaecacea0871b227f250e2979516f6fa310fec0d8df1af7872e5a534e82870aa05f43ef0a455846b93ce938064fa33e92de262e4156dae56775
-TAG: d95d73bf9aeb71eba9042396f3725424
+TAG: 16c972829819b8fb030b2c5f40dab717
KEY: 3792943c0396f1840496917ce8ad89608385007e796febeea3805f3f4cbeccf7
-NONCE: 23b2f9068b2c4c85
+NONCE: 0000000023b2f9068b2c4c85
IN: be6b67eb943ee7b5c785cd882f653e73a8f75b4a41a2a7c56ae5a10f729caf39948fe48ad0e51240e2e7aa43193c7ec6ce7f4909fc94c9f99e38e6a0ad7e98eb29c5c2e61c99e9cbe890f154185cec213a74725d23c1a4e4d0cb9b1a36b78c87e5eee20d2aa29aae80d4759eb0c51c5dc3a95bdbbf7e14eb434419a6c88a954ac03d0c98739f4211b8732acd71c297f578b8cb64ccac45f7235ddc7f2a3f5f997525c1ed39dc550126cdf9cedaf55425489085e91b170be6205a5a395f2dd4084a3e8dbc4fd8b13252f7effae067b571cb94a1e54aba45b1b9841308db0cc75b03cfce4ddafe89ce20f2d1
AD: 7eb6d7b7bbaaa3c202a4f0f1de2263767169eb4a64853240d48c0f8d5d31b08d5baf42977614a57aad99426cde76d242cb37d2956d8c77dc4fd62a3abf30e8ac6cd58c8ef35e67497022960138c57787818892460f3bfc16e37ff388b1edc6ce2bc53c22717edc7a03d4c78b0dbbe9121c7fd8a3e3993b87a4fe389bff13bdae3b349de0b6db561602c53f746022aeb4483c723b67825042f4af20b7dd1e6031cf54215266295c524ac8e1370424c5c5e607fb3e23e97c8eebe64656775edf616422a8b974e1acf13ab45c9a367a7dd9b2d62f48bbc05819b65eccb813ca813f57b22ee4c280dbb5a9d8d5
CT: 0b316ab2bcf5359900fa4082d5d253b49ad94b70e3fab544f98bd111cbcef6766cf953deec08cae1f489fe12f7acc0032db8a6b0c0eee0c206ea5fb973feaebf90f690e840094db5e13fdd7157ba127368c995b426529435a1bcdd1f14ce9125b8a0e4c96b6ec09e3c36a180adf81941c002d19c19d53c2009be803b987504606b7d43bdee5e0b32ff23c466b6cccfcd0d4e88fd1332e73712b5ab725c1a383e584f34f80daff29d285ae5e43cf1d0cc7a828e75c25daced3a581a93d7a50f313b33f38dddfaa23cd5b9914797db820ee2400d52bf5fa982277fe9b5881ac42981633b3957b0e935051828
-TAG: 01973ee2e81cef22751a6a8831d752ef
+TAG: c549aa944d6d97e52e0793ed572682c0
KEY: fe4be6054773f634356ac328591fbc6f833b0d1beeb38dd5b6feb7481b4489d4
-NONCE: 0b3f16f898a5a7d5
+NONCE: 000000000b3f16f898a5a7d5
IN: 76ced1ade6d1ef4069afddb32e7432d4ff2fd06685121f7b16464e7a72d365744f547d2ccf53486310e38b42d8bacaf711e54c5458d2d68c4dbcc8de31ab6732f4430e88a64565f5b287640775aaa2af1cc461d3e415bb275c6246b1b58517aa72667eae291a2982eda175d1b22c5a58e6fec2b3743d55712f201ca24ba5c0ae8c25724871b2ec2fb914a8da5a52670ab9b43a83b8568ce74db5c634061cb80530c8070c38b8f48c33ba136cb9f2158ee7eda8b65f2192fc94d1291f182f101795b7190c74b319d2d3e02a97c824d9c9471a83797e4936310b207e3a1e0bcf75f7c3e3ee48a747641cdc4377f2d55082
AD: 834cd775cbefe4b33a3ca53a00c06a3c4a666983e4115a029f15729460daa45d1505e95172d3695625a186b28b8be173a925af04665f209267b3c5123e8be13da447ee1ae856bb0925f35aaa76e04a7bca8460f76c2024de2149f38a8cfba81694b854885d72568105571b6b213a0bc188a44cc7fe13153cbf261401b238cf12a95e23cb56f240114f16e2f1e3a514615aab4449c0c49e4d900b0e17d1a8dabb53d43dca32fa052d576b73dd9b40856b515d6d7efc2a5c17e0ebcb17bd59dc86f22ce909301a2652f134e82ef0e4519487ed12d51536024f2ae8f75d937c42d003076e5dea8de0c684cda1f34253d8fc
CT: f8defb6fe95dfec499b909996a1f75a198a90e4d6c6464d00a357a555311c42fe92dbbc4b79c935e4f0b1a95e44fdbc1380bebabca28db4dd0d2870daaafc38ef27908c3509e945714801cc51f1a07b2430c74fa64f2a7c2f7fd1551d258c9c3be020873fc1bf19f33ab6c660911dcf2317195d0efee82d20ec26d22611f9cf86c51a64e28b3a1f344500018e0855c88dae3c07acaeaa10b60388484dce93e16e6e1a6e69e899806648a92568c8780e9f4baacd98cbb353ac2f908e775d92303cfab843f15be0e0c322a958802fb1a60fcc7631f151f4c2b8cb965d2d296acef250275a2fecc0cea803ce7c058b12dd2
-TAG: ade515091930dd7861b27f78a87ef60c
+TAG: baf9a51180f172e5c0cc2c946ce55055
KEY: a288b11ce5382ec724ce4ab2d7efa8e777e91ebd04367935e15f9dac483e9596
-NONCE: 874144dbf648b325
+NONCE: 00000000874144dbf648b325
IN: 4c9195280a79a509919af4947e9e07231695fd7c5088539f23936ce88770ce07d9ad3ae4a463b3a57d0634d3a77ceaadf347a334682b04be8e58b8e86fb94a1f93255132b8cdb0df86f5bea354eea4e8315fea83e3fdf6e58aa9f26e93caa08e5e2551a94bd916a51fed29ec16f66800cda6a0aa24ec308bf5fb885afba272685de27c1edcdd3668048ef07b06e90d464a8aa28664903cac45e154e8e1e39c257e1ff506b9d95cef4f300bb73b899e7828602c3c1d290b8cf55ee5fd72ecce9e6efc9293aebf674a70e2a7673e75629c12950622dff71d3ec0992e57776c788c6927d30b4e24b749191c3ce8017f0ada6276e43720
AD: 04abe8588c8c8c39a182092e5e7840442bd1c1149da102c4ee412bd8b82baa5087ef7291b5cd077c177c42770b0023e0e462b06e7553f191bcb0315a34918dcdbffe2b99c3e011b4220cc1775debcc0db55fa60df9b52234f3d3fa9606508badc26f30b47cdb4f1c0f4708d417b6853e66c2f1f67f6200daf760ceb64ffc43db27f057ad3ee973e31d7e5d5deb050315c1c687980c0c148ee1a492d47acfcd6132334176c11258c89b19ba02e6acc55d852f87b6a2169ed34a6147caa60906ac8c0813c0f05522af7b7f0faddb4bc297405e28ecf5a0f6aac6258422d29cfe250d61402840f3c27d0ce39b3e2d5f1e520541d2965e
CT: 0afce770a12f15d67ac104ba0640aab95922390607473cbda71321156a5559906be933fb0980da56f27e89796eaa1054f5aacf1668d9f273cc69071b9e8e22af6a205a6a88f7ad918e22f616bddbb07c78913c7e056e769e6fcf91c7600c2740212e3a176e4110cac9e361a59a773457064d2dc652dd115d04f1c3756c0e1d39f6737a16b4508663e310934c49c58058b3c7b9af7bb2334c8a163608c42499658986927cda365e2aead3ac29de16e47e954383ea566f8fb245a4e5a934c767bb3bf7e0eb8a477fd0e1f61bcb238462a0d19c5cea9293ca58ade76829413216a7882cd2846323046694f78cd8b0347792ebb75abdc1
-TAG: 973e58b1b8adb176a6f1e5c963bfdc5c
+TAG: eb9b2ee43e9a3ae1e33561800169d868
KEY: 65b63ed53750c88c508c44881ae59e6fff69c66288f3c14cfec503391262cafc
-NONCE: 7f5e560a1de434ba
+NONCE: 000000007f5e560a1de434ba
IN: 845ef27b6615fb699d37971db6b597930a7ef1e6f90054791eb04ddfe7252b5f88fd60eba5af469bc09661c0987a496fa540621afeec51bebda786826800943d977039dee76235248112ff8b743f25ed5f3cb0d3307f5e118d84fdbb9c3f5531bc177fb84549c994ea4496c65e5249da987dd755d46dc1788f582410266a10f291c1474f732183a2a39afe603771bb9c423fe3e8906f2be44a0c9a7c3f0ceb09d1d0f92d942383a875c0567c7869f045e56dd1a4d6e90c58d44fe0c5760bb4fd01de55439db52b56831e5a26a47de14249453a4f8e7da3cb3282c6622916197ebfaad85dd65c61e7d2d3ba626276366746f396394c1bf75f51ce
AD: 51a3588398808e1d6a98505c6e5601ae2a2766f1f28f8f69d1ccbcad18038c157b41525be58ae4527a073748b7a04809e52a5df0c7988417607738e63d7ead47db795a346b04e740186e73ccad79f725b58ee22dc6e30d1f0a218eda1791e2229b253d4ab2b963a43e12318c8b0785c20fca3abcf220c08745d9f9602f0ece544a05736d76b12d249699c9e3e99f3f13cf4e5dc13a04125c949a5b30d034b23cb364c8781964bc6c30e5e5ca9673d517ef5f35965d8a8cf1be017e343df97b6bee37b30638b154286d1f36d2f9a0eaa23cc484eac5a05b15d9efc537d989dbc8b3106c0dc1a56e97e6aec2eff54a82cf7ae9df2af46b4c860f83
CT: 027b14197b4012256b133b78ddc94e72fb4d724fefa4ae329f5a5fa3fa784fe6d7e1e805e3f7a75557de64de506d38237b467fa577efb59e7cfe2356bed6655c5aa4e238dcfeb75c16549a0917268768a96acb5e20546a1fb7e3a7cff887f49f2cd7a135f72a98a779150f3207bf733e88861fd79eadbf77fa3bfe97bfe8b6a991cb3bcc2cde8287f7e89384846561934b0f3e05e0646e0e1907770df67a7594161a4d0763faa6fa844080932159999d528ee0558710058ce16f97d13ac9fd9bf5044191188bbfb598d0fafbdf790b61ce0781ecc04218a30ded45efd498cc9ba03562ed2b4a993ee98876b3ab7a9bc07829f1c4ca6ead98c06b
-TAG: e4d18a701b8308697b5e79141ed783c1
+TAG: e0bf9b6837428843f5a233ee5ddb8a1e
KEY: 4986fd62d6cb86b2eaf219174bec681bebcdef86c8be291f27d3e5dc69e2feba
-NONCE: d08d486620ed2e84
+NONCE: 00000000d08d486620ed2e84
IN: 3a22ad5de387db4fdd5d62a1b728c23a8dddc50b1e89f54f6198b90499f9da3122ebeb38ebf5fdfe30309734f79aff01e3de1e196b35bffa33bae451f31f74b8aec03763f9e0861a34fe5db0b40c76e57c7fc582bfa19c94ee25b5e168270f379bf9f8a0a18bed05de256f8f0dd7c23ba2ff1c7f721409462f04cc611ad9bd4c3c9acf30742acfb9518a6375cbb15d65a1bc6993ea434894f93d4f6e05996ebc1bd56579296309a2c6b8fde95072168b5fd31927c4c0abaa056bcd16221d5f220be47591f43255013a262dce439817f534830ba82155347e5fe3101f8011b89365a6568214ed0661914e8cb3431d6c8f2347dfc1209a3eca4aaf0a111f47fe
AD: 7dd3f656a03c001b45ca0680bc3ac9d68c6e96b591d3c69eb8c65e489009d845cb331c98b82e627e06d5bf01e74c573df268c2386f12628c019951d42f55991ff20d72a7b2c45f41d0be7af428c92f324aaab8df70d900301cdf09a3d93eb711c919d34a86fff9cb078322ee2e0ad48dbdf3b7884f0f2dc5c36262c59bcfd75ac6200f59c6fcd0ce10ff5005fef5df8f0432377dfbfc1db8f559e27e1aeef3380ea3864867d36a25a18654779a751586cad3b8a46b90864ee697b08605673b8d2123433c020a21c4db243dde2420c12fd4d54a2704a0c8c376454a1b5e80fd6db89aabd56d9b421f29649e474824dfa56cb5c673c504d10be52b53751709fe
CT: c40180afd53001663ff4834110f56e6b0f178cd3c0e7f7de5d0089ee41d8403ffb98e84922706544a344d7e2625b12cf66b9c966f9f57d7b94e3e4b34e6f0aaed1763ce012782e2f5e1682e6c343fc7961fedddd0919d0b910e9923c17e36406979b256b85aec24ee352f03b48c1302eab419c83dccc5372cc059e9de596224fa70098eb32fc9579e97917b923914fa2efc30ab29b457bf14e45583b3771486bdc0876f3ea6e1a646746c4f8c5cb2641a1557c8473e6ea67d4811a67485ae9a678ff3a2408ca845c3b51957e189eef47dfc1d46bde4b9d754d7df13f828ddadb06e4ebddb5f0dafbdb28de4c5e6078926f20cdf9e97ecd58e309e640f74f06
-TAG: fd5e29332832a14a31a9ce2ca8568498
+TAG: 2e8eb9ff4467c0f61c2abf6ca10893ef
KEY: 7d28a60810e43d3dfa32e97c07957ec069fc80cc6a50061830aa29b3aa777dfc
-NONCE: 47738ac8f10f2c3a
+NONCE: 0000000047738ac8f10f2c3a
IN: b50278ae0f0fa2f918bb9a5ed3a0797c328e452974d33cbf26a1e213aa20c03d0d89490869754abf84dbbe231d7bccdced77d53fd4527356d8e02b681fc89a535ae87308bf7fbc26197a5ea85bdb3aa033b8da5cd197ea6d72f96f63b03f4ecc7adedf399a5043776cdb32c08f30b77f34df85f8adb8e02649a04b020b03e17d445ca63e4ed73ae432c481392e031eba2f9d2f7f981d1e50917822bd6ff71c239d33444ada3523a59dfbce5457eadec1ab926c9e6c5299c7521e3f204b96901a712504fcc782e8cea80ba12a7f7e71cec3d0871899b6ca059061da037715f7d13fed01c9cade1e687b4fbb1f4ac4b040db3b43800f112fb900e4f772d61b921cbce4da6f
AD: 324292813b7df15bc070cc5d8a4bf74ead036430be63abc43304cf653959a24a91c7de5a671c50fa8a87e21bb82b069999aadfb6895d8bda4c3083d17b8ca55b9ab1511ed8c4b39d8c28c11a22ef90c08a983e3fe2d988df9e02b16a20b24f39ddb28429625f511db08298c4dc321f6c268fc836a6191df6232f51c463a397a8d8b33374abe94e62c0f5c322387e1fc4a1c1980a04a1a3c2c31b32f183a11c3268c6dca521149dc16af120a78be6627210e8ddbc44472bc24d66ce3681c7579b3d9a425212a704a4f5105cb80f0d18ee860953d10b59c114826779bbc368d7a0eece9f223e47cd8e5fd453607d101d9d9c2bd9a658d6520b87d7b4263f6d845a524a36e4
CT: 2c217e969c04740a1acfa30117eb5b32dc573df3354f4cc3bf8f696ff905f1e640f3b2c250473b376622e0c9bda13b94640521be1ef0fc660b4c10dbe2bfc093030753e04f6aaecf813b43b61f960455974b8bb8a9b461d1e8fd3802315e863c00448f24dd38deb90e135493274eb14ccbde15c50dcad734ed815a806be6622492a84cd062e3ba567b909a205a1d0d2bedd40169697d261c7b6c2e0b1f069853fd470e8f364a142c386c439a6dbe192ded5a3d0fbf73799f588c59e58c60249d980ddcf0d9693631cd9b3f972509c3a77123d38d9e267ecad06e1208e3f1c0a69fbca7c3bb1a48fda19493d0f8f48398820057b94120f3ef97d87e9e8a1b301a2534c68f
-TAG: 1fdd2dcd935f55822bf7231a516ca841
+TAG: ce507bdb0c71f8e89f5078495f7995b8
KEY: a76e9b916f5a67b78a5949651c8c3a9741a1bc3c41cdf85fd2c8f3e9a0616098
-NONCE: 0808da8292dc14e0
+NONCE: 000000000808da8292dc14e0
IN: 9c149eeb09345c3c22462b03e49eb4dba6bc98b269b1086d752bcd8eea53b8977b238a04a994baf915591686baab90b79a3bf7d9adb2c6c2e31acd3e72f0813fb745aa5fb2e3da408f78001c9c09bd26a1a2646011b6120aaa2bbacc4a16c39fb5257b9b2ea2ad8bf70bcc9855cf11841116c2767310cf3cd49d1aa44cd505f079761e064d5bc7cea4a7173b086882a77d3fc179efc86fc4db8a373491d2ed81eabc63c950e832db17d09f474d4ec46bde47830caf26fabaa0372b81fccc449c0e19ccd630caf693a7b43bb1c408a54e03f50c44280a05ad89fb6e8f01d8ac278edf556e5d86ceb4b614fb2ef133819c6e1ff6abb86c54a135256204b5cd400b93624d3932e7c2b046
AD: 6aeb7031e4a2e23eea93f05fdc562aa2bf43b8998bea7344377aaddc60fbdb7bcb1491d379ed0cb613ee757cfb66490db61bb431d2fad34b38ddd55bc5b22aa6c4773b9992f34b878c5663f6e8cdb5f80a17f4d312bf342492e48d1ce4c6d754076a634fece61500acf8168d47381af4faf980c6cac2bfd5da8c09b6edb0f543bf0fe02643e38d73fa37d8ae87fb66193f22e57faf4393c007d48c8631a685d520578f8f89db684fb371ea02f3a58b1e2168f0216321139472e0d03b6d90ba8aab65402e1c1ac4f9172a60e27e3d997b9b05e2f672120d6c87bcafa6d4c9b4cf8ba8a82932d92840368fc53dc5b48526103dcab5f1531038aabe89171327ac559b98a3cf4ea70bf051
CT: 9c3faab9261a63cea9477b3269007283995b06ba77ef83d9e693f7e4ee9855550eef94855be39a7a435b6a3584b202973777c7b2482376ba47b49311947a64983b60236756ee4455d4cfada8c36af8eb06b06ba2f6b79ffb1185c89f2b2a831cfaa3855fc1841d8910908be5078352011168a67d36372d851a3217cabf593ea462dcd325cf9a4f67e85418fd5c924e9b92ab026cbee4e7ab1067066cb5949dfc699a68fe539e1abb13cec33904e5207e6963d24f5a0b770613b8b00014e791bfff88f9c25ca126127a2f8d1d1e9794efd28dce98b53e228073faae8d5047530d502184fc341321c3f55fcbf41187fc31262c325b97f519959b6a29b36c71f76f60196bb1457b77c8bb
-TAG: b45df119043d29008fcef36a169ef886
+TAG: 73b00b1705602479aab944dcc1b282a2
KEY: 98cd2477a7a072c69f375b88d09ed9d7b9c3df3f87e36ce621726f76e3b41a1d
-NONCE: 77d185aaf715aa48
+NONCE: 0000000077d185aaf715aa48
IN: 42b31eefdacab0f03ef6060156000c8195adb0976cabbe1a42bfcc09f85659c60b98638401f2d2e2facfb9a97a62926bb0cecaf3af0180a01bfb6e576babf7fc43331937a92abd30cddfa3e450f895e9dd914dea3fafd759c136d685310ebce28ac0613ccdbf30115946c9634b67510b77d0e37f07714b2ddac9d7095b8d4bd887c132c4a9127eb01c8dedb4c39c87b98a741316656f9a8d5a5b0c0ac84789aa2347a5f99ca5ad55cd1bcf98f703eb4b00badb8a8555f38b3b368db8ba7ceea94e8b219f51edce75d84166b5602156ed5962a93a51db73c59d87e906179d7a74a2a2a69d8ad99f323225c87e475d3f771b4a203a2e2b03b458401044649fa6536dfab24d7037807dcbf6518e6578
AD: f5bb1496052a4361dddf72a288e36953a3d815d6876c013f1d6ba839e127f721b052b1f7d8ca20c7dc0386a7d459ebd7eb9fc8cb08941e6ca9ddb980f3115f65bc1928a414d441ae71dcb879d5bfe0cde0562bc37f8fde0d5291ad405c92fcbb860c43b55ac0fe663b54b3d0616aca13a5c82b7b5d34125a05c2acb5530141030e6f2aa0c8322b2c8fa307e7518918e550e9f48921c6168f094d8758e16b9f815fd0458095c4143f0922adb1840d0e685636825a9c90ee90ee537f4b8dceecbc4287c82dc9a00d7e51671e37ea284ee3ca501b1b2596459d3f592f70186f41125739e342c9f6be9241973b1414dfe5fb8cba1af82e679278cfcf95420df0c5364af4d7e72ad57d5c871fcbc35462
CT: 7a3bf3e3ad5ae3ab71fb1f7121c3d8fb511099484b50af7ca128ee0337ed4b828dc4cde0b88dc1e8089101fa82c9beb3eb48fdcf0f5b16da441f5a3fce9a590022af95a94aed6a3e71e505f60f303c78c356f274ea85a55354078530664ecda32c80e77dc20974b3b38f4825b8fbee8c3970769a2f42c5181608a8d7d76ef4d093961b665ee42b9708fcafe2c82d3a307173e2a25ad2528c3bf83352b9265e45b70722d7cf8c9b80826d21335234ee3db69d0d37871c83222365900c96c17a7e9f5742d0bfe383be24d0d44590d4b0f29f7abe0c65daaffb968b3f2657b1eb300534eacb52ec7a6b6f9f57a50a91b1799f491361cf613c934b7f520dc4eeeb40ffc45e10be0a95e76f366d4eac14
-TAG: f613b65226afb64c614fe60d9c71ed74
+TAG: 69302888812eea030d621b640e7bcf7c
KEY: 2f0f4631ab1c1bcf8f3ad0559c818d50e0af7d8cd63faa357f2069f30881d9cb
-NONCE: 7d0ced2fdb1c9173
+NONCE: 000000007d0ced2fdb1c9173
IN: 6516ba1d29357144eebfa486d21decf223da3aa76ec29bbfcbe7f1eeaf4a847710e5080177f7e5a7c8b4752c219b1cc70aef4db861ba67d0fa6222d9f4a1dc756a0ba44e62906f9374a960c16198866d867854d88f528a60e212eb91645787e75685b2e215c0a41990abc344a77236ec0186ba63a664592938cc5a8ac1d3eb99c95ce00e19fbe249263083d85b052d48bfdffc01585dc57bb2a2c6c4a819604c1ec0548c6f0f78dc05e4418b36277dc07233c7532f9c289d6aed0cc6bc7df4fd0a536c497b982e2dad2c30d2db1c6545a845c5dfa83a4ac49ef06fc9c919079d3e299e31b5c3be370814ae5022ae469d3ee55246a41bd0dc4e64351cc38c3c09af0a1aee3b388a6892deff0df3f93cd92d722b
AD: 1ccfa1ececc8de1e200d0ecc19dcf67b7c96bea3a282c2bccba61035db5c14776387b8b8f58e5757deb0129d4e5e315f64df354a5985d2e47ebbbeafe0c914f7cf1d63dd0311ace19e69a8b6ff0ab25cc8df0408d22132205e89e5eb679268d82b2913e64e3f885bbf4a6d379b760b94590e3140dd7275ab4713cb56d0b716e2718f11316640cb394802862d39e77a46d0c065af3caf7dec14e887039d8aa8c3d3a8ac1ee06026f49d00b2f59d971b54735e95a51f199389a93a4fc24ebaba1f7a2eef7412f61febf79084fbf481afc6fb6b204084e5ef5df71f30506459dea074f11fc055cd2a8c0fc922c4811a849984352a56a15659b7d07a4cc90b88623638ea00c4c8bc13884df2237b359f2877aa41d6
CT: e580093789ba17ffb46672dc326f09278aca08598d3e5458eaa53e6ed45d5c71a396e35b5ea3fe7b7c0496a734d24f1c75420694be2ff095d5172fd3407794e4b99fd7c374fbe8d1564a048614d3f355bfb5866de1a53e1a51f9f5e8312253cfd82f36efaa1898c850ca0d975ad1e8b0d9597a5a9e6516fe2a3c92efb7495557a8afc3da15b0d3e2ba58f612519836946cf2d15b898320d16a026c8c00a1be2e35f0ebe68f28d91c6c45d24c3f3c157cb132fa659b7794df883d90741fa2d2afcc4f27858e13ecd41b154a35d24947ae7361170060c107d8ecacb393ea67104b60457278a392fdf1794bab97d3b02b71a4eb015eaa38a4b4c944c2bc7cd5e329da4a1ab2937a6af81a6caa5fce752331fdefd4
-TAG: 0fd7419c54bc84265ed310a3411a3f2e
+TAG: 19bbacfac768bb0ce71e39c5d4d3e9a0
KEY: a48b9b6df475e566aba7671fbd76772cb0eff0b12499967978ce3e25fac92feb
-NONCE: 2ccbf0d6c40cb302
+NONCE: 000000002ccbf0d6c40cb302
IN: 09da1cacd001dce4f7573a065a4406fe0da04ab367a2d87780a2762e168957a88d3fa78f0a4b6978d449026e5a801d32884b6e14fdaaaf864214f928ebc03dead081fee96683ebb032362d5088c4c2a3b1e242f055f2604919f4dd551db777a258cf9da6d95a2bde249247812b9efc7985cf08707620808524d6dd3079b0b63bf0f71ea5de834ccb8b7c6a97125fd6ca49148e866d3134bbf1d8a6b714e9a80fe549c8bfefe342f41be2ba2300e0028f78cefab65274632dfdbe70bf7d655ec4036df561f2d4fc4d56a482bbe2f9f2ae279b3aa216b39afee75e53602de319484db89a51e844f38c361634e474f8f1f01c340f3f3594860d671346449c6d08ee38de22d246309bc7e4a252a29c86aa6d94b5b4fa58904c70
AD: 1c2503d5aa1aad193f0da12874074ea0432bb76a61cd43a3017061514da0759846a0f3ae3a49fdb0b6d29f713de665beacb6568f2694112ca380d13f3c1698316866a7a7f87f1d7503a92176ab84fc08977b46ba664508a858e7525753c45511b3d2f407d5e993c6ede77f13d12975707e5195704970a89f71fc30828049f92f944f3aa93d6a5297e678e08952919beb7eac5919df1919cab3c3da6aa696a1eeab6371f310f7e81143e7d240b0213ae554524b52000306160dd4877bf13ba0f13bbe867da7c7d707f31335eef4cd942938ac890a0829ec66bd30ae01a2188a6e5ea0f17cd7dc875e17f03c0ab5dd18e36db8a1fc1f72859ee046b62368f168b3bea2234e0432c07b7d8e1b9277f21e692c513b9e816e6860
CT: 7d35cfe4be56bd6e0e09dedcd01735b915bc1891a4d1f6a541abc4bcd0ebe89dcb8e365e5813742e8ec65777b6159422fada747da99394252baf8a046fc1b60ad79755f545f4448627b7acaf403000894f5641e78d3f946dfca29ec617f0660dcd6e8d8827e67e1022a245c595d86e60fbd176bf721b171bbe5ecaf4ae671b9f3dd3920146e6ad431bd8fc431820e19454b6ca209723d80fdbee187fca9c937c979206ae97be55f6ba7366a5608770a11d537396485eb0a66586385f4d4cf3905d1fc90831c3e136d5d513fa22be285193142994a3ed477145bacdcbdd791e8b3b88b0d4f1d18b27382550a818c4fd8884bf36f677c6c3ff5677406e510911e696af75e5b3f859bef699bdd16e6215fdb98d874025eada50
-TAG: 2aabff35611b3e0013f6ae0df130799b
+TAG: 0fa4cb2bab84336409aa4349ab99a8bd
KEY: 923d4b086b9e43b986f7b65e4cea6113a3d8aabefa89323c5e4d5b6f158bb7e0
-NONCE: a0f73297b87f5deb
+NONCE: 00000000a0f73297b87f5deb
IN: 21435e8d5c8edf0684f58c2cba4070c10b4801adf46b6c4d322eb3990a38a9ad338ad704b9df6597f3e68d66cd5b56290c8466db2231e56d6bcb9c44e1bd081f42ca2a894dad369df2bd0d2c63d6c881732d6ea22bb22b5bc9a62eaffa1b094d0845f6b966d2cb095e7b3b8bcbc15e707449d35c8df4aea30c3b7243e977fffd59c80f1c5c9af4bb5a54b9c786fbbe8d21b2b906a87a786caed841a34a3e0cc0ac3209d83c58afba19edd63622dd261532d2cfb0b49d527d8eaa0887a087f5129d897f665264b229f860363d71a88b7d49c8dc6360182b357b0662391bb41337f46010ac32b9fada2d60a2efcb99365d3b27b7ac396900d1c821d0df8b86cc9cc1f2673259a33efea610bf8e1d00d7e9db2afea21da8f58c55f799999d
AD: c853a8b39c0dc597d562f123cd221e4104b65423a062a4f4ba890ba344feb84290f61817e23330c365f58c3583ce08360d3c1171982ead5496d525ac878f23a57480a6ee39d4e65afd6268245bb982a2545fa1195427cdbbcd404cdad5198f55cce2a5a028fae435f71b15921d066e8d43766c32b2f2c3f57c0674e129607dcd3703eca529414adaee79d81fed432153cceb6f3fc53404810d8ec878f7d94be5d379d0e0e1aa9bc404b4b5d396038a9d76a5ce53c9f3759b8e50fb331858ca58cee81bfc3ee58baef5d19c402a3dc8b36370ec1ace5a4aa2527fb94b4f933a4ab8ccaaf6a5af5a779eae5667c2a24ab027e781c8d4f30c377aa5885a2fdaf6507d18cd824a847c35368b4ea984d2c3c3824a5b8ba3042e1852504a21a3
CT: f2e21052eebbb86a4f5e803360855d8632aa727dca6f5e79dd74d7aff106e442001928d113005b030f8446f8eff2ee951db663978abe43090dd5ad2c51ba97a0ecf988c607d95e486d02524f690fa3c28d5c48c1f75c1f555e7b43fe7e46f2ca2b9fdb408ec4ba18b6cdde2af673183cb7b1a3c23ae77eddd4cac75e1ea14743fc571f8d31ce2e96787524cd48aadaa474181c096a032184574ddc25a6e0ac8441c212bc36298708e33c963ae931e6c6241d1affeef7b6ef759495df44b6ab647447693cf703569e69aa72f1def9a342b8978c1edea9703a421ca75b92cac4de14b88c693200022b8a2ed22b1c4678b99f4d695e080dd1196d7168e14f0d0f8ff880d742e97b9f6d00af1f7118e10b77c5ef3ea6c52f84a20fd6ea46dc
-TAG: fa8ee13400fb3f63b899df582f2fec45
+TAG: 9bd8b7743c056bb2334833afd6143e18
KEY: df73adab2768559ea983cce85453fe81d79be3b3c57f202b31b94d6635cf2e4b
-NONCE: e7a87e6bf6b5a354
+NONCE: 00000000e7a87e6bf6b5a354
IN: 0032a37abf661faa18c587fd2aa88885c061deeba81105dd221969bed5d59c7204b09b1a8c4c8de3b9f748c7fc70626ebeaca060233a57b102221b1bf0f3d9fdaaad3d2b1439c24d08f9c67f49f3c47128f92ee530abf4c4f4573bc60ae4b38109f55bca3ca9e1ba9f9fd6e34ba0d174892977a53356e1f5c88c614fe3ff3b3dd0818e7a2285412e3b37444bbe8a80942efcfd03958809a6966cda9430b2f0c9e552f4bced6e19eb3e85fc5758bd7b588297ccbed37ed94c3adc8c08ea8b058462aac9d57a939ec711bc4ecfec944d2b653b7cfc7b02a65d7057c9fdadd51b9da8cc4a3c68dae9da8b9c5319c1a2baa3d6c891c5ac4a39461484b5a01abc64df447ada24c04a4363e605eaccf339a9aa515e724206206da6d22bbd2f52e64cd7c895
AD: f833e5ab4f8bc89167f80f576b1d6b22cdd0e30721f5f735799746cf645b6eff531d4c7b03584f3dfcb73cbd35ac42736216dc7f0de098a4f42c61ceb4b227ee288e47d697a0a76afc762f084e8fdbf9351c28340c324771c109a469341ab10ca10483ed2af5e878d7d3dc2bced2f72da3d1a25852b103ee9878e8158eb4309c1ce528f3a178ace153b6d3ae0af0d577cb3cb1540489e80427f792217ad8a09b84f027fca7ceb651b4264e98e94b4cb8a37b133390897233e8ba9103628d05b9609e8552c4a4b11e3f2fa8d56af36957390e88cba44656be3edace798cf8cdf7771bac338a256bc3cba6df97728f222f423ca7c6d149c9372d66163a98f79a234b00d4b75fb2ec860dcc2d1998105e4b9c01d68f079f3e0aa21cc534047fc7b858f8
CT: b842eadfdf431c135bd6581d3eccae54e2267d8890036aa33dfe2d2d9715c44625441210a3a0d666d708d30588fe851ec36e10d8fa3584ed77b095149494b7c54379d62c8935e1d2b9a8f47e4759ad0b3437fdf2cc2fb6c5ea25ad10e0bdc9dc5b0517fc237eb783cc461c46665e2b1d1a5b8008dbf409ea2a63fea0276de23a32c99d92a498807a0f95e208fc6262321a78aafaf0cc3f833fff37bd4efa66f6023a25cdc6702cee3912799563d908a5183c9956a06aa71085d855dc7c809ed6e2889592b361ab3ab39060f8e419152187a794a19c2a1128882201900ea2cd597860674bf78d9720643df8701676718fd201baed4935a88e50558daf86edd08a9ab227ac7afae55c974b68de8dacad4a4d79b13ed6dfe74017a4cb9148e033436fb6
-TAG: 184095b7a8190abec08bb72d19eeb103
+TAG: ee1ec36804e1d5cdbddb52608c711fd8
KEY: 55a4be2448b464c2ea52a2f2664ed6aba865c14ea1fea77f4689331fd105c8d4
-NONCE: db37c0a405b4626d
+NONCE: 00000000db37c0a405b4626d
IN: d266e66272e5d3462081b004cb42429c8b9741e9f678153754d726f6f9aa513464763c5e793b482fe512fece97585f1426120d4cefb3d0a8cc0a8db4bde93fc72c78f44d4fecca14650c660d3e285b327e7cdd813063e7e867b8a2d059a41bab70432b7f857199894da90dca3fe5272bae1ec694a1a07b60b05df275784d4975637e4673109f3ba846dfd1a048b202ed8e89973be608b91ee4743b1e759900f1443038951fe6189e806638985f3c16338c3c60695df58e621154d79bb973859c4558e9dca90470f77c73f004443ad5db0717abbe43266f90e57397b83ac34d1fef2e897e2483d5bcdcb627abd64b0d1aef525835f25e76d6e9158232cdde6dce970b59f58de8a98e653be32fb58edabbcefa5065d73afdf1c9c4fbf50c1022bd22bfcb98e4b422
AD: fd6a3fdd879f8880843eac20ae01c1b9dc3487d270a806572088ef2ddc1f1e0de495e71d4813bf5c501ad31e5d791c4b5b3a0a71b63fdddcc8de4b056064ef467989ecccc5d0160d403bf3a025d4892b3b1de3e062bc3581d4410f273338311eb4637529e4a680a6e4a5e26e308630a5b6d49ead6d543f8f2bf9050aa94ce091318721e1d8b96e279f34b9759b65037bec4bf6ccda6929705aeeeebe49e327e4d7a916620c9faf3765120658af34c53fbb97ec07657b3f088fcbdc401aa7949ddeda34d885018c2c23f4f0bb8218bf0d4fc90643658b4d8834f4a8c08e590c2a790995baa9e77627c342d283e454f84fcc05be15e9627a2d9be340c9d72f222bbdfc47905f56616cd9f936d49e4732f319f020513340fb8b22828db251b102b6b137c9533936d6
CT: bd11ed07b7b4b30eeaf25d6a41a549cca0a5aee71f990ac566a37265d7af2ce3c03703427ee0b2755c2bdfc29f9d826aec6ee4ad28af48079ac23db16580b97424f3a4e35cc23625d39f95699d9ff5143e9a2bc26fcfee4f125f5aa2d968ccfc2faaf9db3c28850f6757f735cbc50c94c498bcde4f23bffafa8dd5f70d1a011e35eb26e905d4e68848fedebeb197be595c085ba33f11ba8398258445051751888e9bba111f800f31b37c447074ca6dce6d54b4dfad6cee5138643d4f6ac045e8047248924e88ea4294c7878bc22c9b41924ce301f22693c33733107bf1ba85e34806c5e4366ea66fc52a5f89dd9bf213239158b3d4d2600dde696c61d76c398b9bf10de9118e812e891c8f3355c0ecc6405f79bc32a58905e37888a1d8395fbedc3ac54eca569f
-TAG: f7d3b58a34a86e99267e5db206f17bbe
-
-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
+TAG: 296a397d280d026fc3627f4718971be9
+
+# 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/cipher/test/cipher_test.txt b/src/crypto/cipher/test/cipher_test.txt
index 93cb8f3..21fffdb 100644
--- a/src/crypto/cipher/test/cipher_test.txt
+++ b/src/crypto/cipher/test/cipher_test.txt
@@ -38,6 +38,22 @@ Plaintext = 37363534333231204E6F77206973207468652074696D6520666F722000000000
Ciphertext = 3FE301C962AC01D02213763C1CBD4CDC799657C064ECF5D41C673812CFDE9675
+# DES EDE CBC tests
+Cipher = DES-EDE-CBC
+Key = 0123456789abcdeff1e0d3c2b5a49786
+IV = fedcba9876543210
+Plaintext = 37363534333231204E6F77206973207468652074696D6520666F722000000000
+Ciphertext = 7948C0DA4FE91CD815DCA96DBC9B60A857EB954F4DEB08EB98722642AE69257B
+
+
+# DES EDE tests
+Cipher = DES-EDE
+Key = 0123456789abcdeff1e0d3c2b5a49786
+IV = fedcba9876543210
+Plaintext = 37363534333231204E6F77206973207468652074696D6520666F722000000000
+Ciphertext = 22E889402E28422F8167AD279D90A566DA75B734E12C671FC2669AECB3E4FE8F
+
+
# AES 128 ECB tests (from FIPS-197 test vectors, encrypt)
Cipher = AES-128-ECB
Key = 000102030405060708090A0B0C0D0E0F
@@ -360,6 +376,13 @@ Ciphertext = 6268c6fa2a80b2d137467f092f657ac04d89be2beaa623d61b5a868c8f03ff95d3d
AAD = 00000000000000000000000000000000101112131415161718191a1b1c1d1e1f
Tag = 3b629ccfbc1119b7319e1dce2cd6fd6d
+Cipher = AES-128-GCM
+Key = 31323334353637383930313233343536
+IV = 31323334353637383930313233343536
+Plaintext = 48656c6c6f2c20576f726c64
+Ciphertext = cec189d0e8419b90fb16d555
+Tag = 32893832a8d609224d77c2e56a922282
+AAD =
# OFB tests from OpenSSL upstream.
@@ -535,3 +558,40 @@ Cipher = AES-192-ECB
Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B
Plaintext = F69F2445DF4F9B17AD2B417BE66C3710
Ciphertext = 9A4B41BA738D6C72FB16691603C18E0E
+
+# DES ECB tests
+
+Cipher = DES-ECB
+Key = 0000000000000000
+Plaintext = 0000000000000000
+Ciphertext = 8CA64DE9C1B123A7
+
+Cipher = DES-ECB
+Key = FFFFFFFFFFFFFFFF
+Plaintext = FFFFFFFFFFFFFFFF
+Ciphertext = 7359B2163E4EDC58
+
+Cipher = DES-ECB
+Key = 3000000000000000
+Plaintext = 1000000000000001
+Ciphertext = 958E6E627A05557B
+
+Cipher = DES-ECB
+Key = 1111111111111111
+Plaintext = 1111111111111111
+Ciphertext = F40379AB9E0EC533
+
+Cipher = DES-ECB
+Key = 0123456789ABCDEF
+Plaintext = 1111111111111111
+Ciphertext = 17668DFC7292532D
+
+Cipher = DES-ECB
+Key = 1111111111111111
+Plaintext = 0123456789ABCDEF
+Ciphertext = 8A5AE1F81AB8F2DD
+
+Cipher = DES-ECB
+Key = FEDCBA9876543210
+Plaintext = 0123456789ABCDEF
+Ciphertext = ED39D950FA74BCC4
diff --git a/src/crypto/cipher/tls_cbc.c b/src/crypto/cipher/tls_cbc.c
index 8bca2f3..c541db3 100644
--- a/src/crypto/cipher/tls_cbc.c
+++ b/src/crypto/cipher/tls_cbc.c
@@ -229,11 +229,11 @@ void EVP_tls_cbc_copy_mac(uint8_t *out, unsigned md_size,
* typically does. */
static void tls1_sha1_final_raw(void *ctx, uint8_t *md_out) {
SHA_CTX *sha1 = ctx;
- u32toBE(sha1->h0, md_out);
- u32toBE(sha1->h1, md_out);
- u32toBE(sha1->h2, md_out);
- u32toBE(sha1->h3, md_out);
- u32toBE(sha1->h4, md_out);
+ u32toBE(sha1->h[0], md_out);
+ u32toBE(sha1->h[1], md_out);
+ u32toBE(sha1->h[2], md_out);
+ u32toBE(sha1->h[3], md_out);
+ u32toBE(sha1->h[4], md_out);
}
#define LARGEST_DIGEST_CTX SHA_CTX
diff --git a/src/crypto/cmac/CMakeLists.txt b/src/crypto/cmac/CMakeLists.txt
index 8ebd80c..a346b24 100644
--- a/src/crypto/cmac/CMakeLists.txt
+++ b/src/crypto/cmac/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
cmac
@@ -12,6 +12,9 @@ add_executable(
cmac_test
cmac_test.cc
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(cmac_test crypto)
+add_dependencies(all_tests cmac_test)
diff --git a/src/crypto/cmac/cmac_test.cc b/src/crypto/cmac/cmac_test.cc
index 0f06860..53f45d1 100644
--- a/src/crypto/cmac/cmac_test.cc
+++ b/src/crypto/cmac/cmac_test.cc
@@ -19,16 +19,13 @@
#include <openssl/cmac.h>
#include "../test/scoped_types.h"
+#include "../test/test_util.h"
-static void dump(const uint8_t *got, const uint8_t *expected, size_t len) {
- ScopedBIO bio(BIO_new_fp(stderr, 0 /* don't close */));
-
- BIO_puts(bio.get(), "\nGot:\n");
- BIO_hexdump(bio.get(), got, len, 2 /* indent */);
- BIO_puts(bio.get(), "Expected:\n");
- BIO_hexdump(bio.get(), expected, len, 2 /* indent */);
- BIO_flush(bio.get());
+static void dump(const uint8_t *got, const uint8_t *want, size_t len) {
+ hexdump(stderr, "got :", got, len);
+ hexdump(stderr, "want:", want, len);
+ fflush(stderr);
}
static int test(const char *name, const uint8_t *key, size_t key_len,
diff --git a/src/crypto/conf/CMakeLists.txt b/src/crypto/conf/CMakeLists.txt
index 8046bb8..0a3c795 100644
--- a/src/crypto/conf/CMakeLists.txt
+++ b/src/crypto/conf/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
conf
diff --git a/src/crypto/conf/conf.c b/src/crypto/conf/conf.c
index 213efc5..e098a2c 100644
--- a/src/crypto/conf/conf.c
+++ b/src/crypto/conf/conf.c
@@ -111,6 +111,16 @@ CONF *NCONF_new(void *method) {
return conf;
}
+CONF_VALUE *CONF_VALUE_new(void) {
+ CONF_VALUE *v = OPENSSL_malloc(sizeof(CONF_VALUE));
+ if (!v) {
+ OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ memset(v, 0, sizeof(CONF_VALUE));
+ return v;
+}
+
static void value_free_contents(CONF_VALUE *value) {
if (value->section) {
OPENSSL_free(value->section);
@@ -137,29 +147,26 @@ void NCONF_free(CONF *conf) {
return;
}
- lh_CONF_VALUE_doall(conf->data, value_free_contents);
+ lh_CONF_VALUE_doall(conf->data, value_free);
lh_CONF_VALUE_free(conf->data);
OPENSSL_free(conf);
}
CONF_VALUE *NCONF_new_section(const CONF *conf, const char *section) {
STACK_OF(CONF_VALUE) *sk = NULL;
- int ok = 0, i;
+ int ok = 0;
CONF_VALUE *v = NULL, *old_value;
sk = sk_CONF_VALUE_new_null();
- v = OPENSSL_malloc(sizeof(CONF_VALUE));
+ v = CONF_VALUE_new();
if (sk == NULL || v == NULL) {
goto err;
}
- i = strlen(section) + 1;
- v->section = OPENSSL_malloc(i);
+ v->section = OPENSSL_strdup(section);
if (v->section == NULL) {
goto err;
}
- memcpy(v->section, section, i);
- v->section[i-1] = 0;
v->name = NULL;
v->value = (char *)sk;
@@ -285,7 +292,7 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from) {
rp = e;
if (q) {
if (r != q) {
- OPENSSL_PUT_ERROR(CONF, str_copy, CONF_R_NO_CLOSE_BRACE);
+ OPENSSL_PUT_ERROR(CONF, CONF_R_NO_CLOSE_BRACE);
goto err;
}
e++;
@@ -304,7 +311,7 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from) {
}
*rp = r;
if (p == NULL) {
- OPENSSL_PUT_ERROR(CONF, str_copy, CONF_R_VARIABLE_HAS_NO_VALUE);
+ OPENSSL_PUT_ERROR(CONF, CONF_R_VARIABLE_HAS_NO_VALUE);
goto err;
}
BUF_MEM_grow_clean(buf, (strlen(p) + buf->length - (e - from)));
@@ -372,11 +379,12 @@ const char *NCONF_get_string(const CONF *conf, const char *section,
return value->value;
}
-int add_string(const CONF *conf, CONF_VALUE *section, CONF_VALUE *value) {
+static int add_string(const CONF *conf, CONF_VALUE *section,
+ CONF_VALUE *value) {
STACK_OF(CONF_VALUE) *section_stack = (STACK_OF(CONF_VALUE)*) section->value;
CONF_VALUE *old_value;
- value->section = section->section;
+ value->section = OPENSSL_strdup(section->section);
if (!sk_CONF_VALUE_push(section_stack, value)) {
return 0;
}
@@ -505,20 +513,19 @@ static int def_load_bio(CONF *conf, BIO *in, long *out_error_line) {
char *start, *psection, *pname;
if ((buff = BUF_MEM_new()) == NULL) {
- OPENSSL_PUT_ERROR(CONF, def_load_bio, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(CONF, ERR_R_BUF_LIB);
goto err;
}
- section = (char *)OPENSSL_malloc(10);
+ section = OPENSSL_strdup("default");
if (section == NULL) {
- OPENSSL_PUT_ERROR(CONF, def_load_bio, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE);
goto err;
}
- BUF_strlcpy(section, "default", 10);
sv = NCONF_new_section(conf, section);
if (sv == NULL) {
- OPENSSL_PUT_ERROR(CONF, def_load_bio, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
+ OPENSSL_PUT_ERROR(CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
goto err;
}
@@ -526,7 +533,7 @@ static int def_load_bio(CONF *conf, BIO *in, long *out_error_line) {
again = 0;
for (;;) {
if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) {
- OPENSSL_PUT_ERROR(CONF, def_load_bio, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(CONF, ERR_R_BUF_LIB);
goto err;
}
p = &(buff->data[bufnum]);
@@ -595,7 +602,7 @@ static int def_load_bio(CONF *conf, BIO *in, long *out_error_line) {
ss = p;
goto again;
}
- OPENSSL_PUT_ERROR(CONF, def_load_bio, CONF_R_MISSING_CLOSE_SQUARE_BRACKET);
+ OPENSSL_PUT_ERROR(CONF, CONF_R_MISSING_CLOSE_SQUARE_BRACKET);
goto err;
}
*end = '\0';
@@ -606,7 +613,7 @@ static int def_load_bio(CONF *conf, BIO *in, long *out_error_line) {
sv = NCONF_new_section(conf, section);
}
if (sv == NULL) {
- OPENSSL_PUT_ERROR(CONF, def_load_bio, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
+ OPENSSL_PUT_ERROR(CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
goto err;
}
continue;
@@ -623,7 +630,7 @@ static int def_load_bio(CONF *conf, BIO *in, long *out_error_line) {
}
p = eat_ws(conf, end);
if (*p != '=') {
- OPENSSL_PUT_ERROR(CONF, def_load_bio, CONF_R_MISSING_EQUAL_SIGN);
+ OPENSSL_PUT_ERROR(CONF, CONF_R_MISSING_EQUAL_SIGN);
goto err;
}
*end = '\0';
@@ -639,20 +646,17 @@ static int def_load_bio(CONF *conf, BIO *in, long *out_error_line) {
p++;
*p = '\0';
- if (!(v = (CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE)))) {
- OPENSSL_PUT_ERROR(CONF, def_load_bio, ERR_R_MALLOC_FAILURE);
+ if (!(v = CONF_VALUE_new())) {
goto err;
}
if (psection == NULL) {
psection = section;
}
- v->name = (char *)OPENSSL_malloc(strlen(pname) + 1);
- v->value = NULL;
+ v->name = OPENSSL_strdup(pname);
if (v->name == NULL) {
- OPENSSL_PUT_ERROR(CONF, def_load_bio, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE);
goto err;
}
- BUF_strlcpy(v->name, pname, strlen(pname) + 1);
if (!str_copy(conf, psection, &(v->value), start)) {
goto err;
}
@@ -662,14 +666,14 @@ static int def_load_bio(CONF *conf, BIO *in, long *out_error_line) {
tv = NCONF_new_section(conf, psection);
}
if (tv == NULL) {
- OPENSSL_PUT_ERROR(CONF, def_load_bio, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
+ OPENSSL_PUT_ERROR(CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
goto err;
}
} else {
tv = sv;
}
if (add_string(conf, tv, v) == 0) {
- OPENSSL_PUT_ERROR(CONF, def_load_bio, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE);
goto err;
}
v = NULL;
@@ -715,7 +719,7 @@ int NCONF_load(CONF *conf, const char *filename, long *out_error_line) {
int ret;
if (in == NULL) {
- OPENSSL_PUT_ERROR(CONF, NCONF_load, ERR_R_SYS_LIB);
+ OPENSSL_PUT_ERROR(CONF, ERR_R_SYS_LIB);
return 0;
}
@@ -736,7 +740,7 @@ int CONF_parse_list(const char *list, char sep, int remove_whitespace,
const char *lstart, *tmpend, *p;
if (list == NULL) {
- OPENSSL_PUT_ERROR(CONF, CONF_parse_list, CONF_R_LIST_CANNOT_BE_NULL);
+ OPENSSL_PUT_ERROR(CONF, CONF_R_LIST_CANNOT_BE_NULL);
return 0;
}
diff --git a/src/crypto/conf/internal.h b/src/crypto/conf/internal.h
new file mode 100644
index 0000000..03d1a8f
--- /dev/null
+++ b/src/crypto/conf/internal.h
@@ -0,0 +1,31 @@
+/* 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_CONF_INTERNAL_H
+#define OPENSSL_HEADER_CRYPTO_CONF_INTERNAL_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/* CONF_VALUE_new returns a freshly allocated and zeroed |CONF_VALUE|. */
+CONF_VALUE *CONF_VALUE_new(void);
+
+
+#if defined(__cplusplus)
+} /* extern C */
+#endif
+
+#endif /* OPENSSL_HEADER_CRYPTO_CONF_INTERNAL_H */
diff --git a/src/crypto/cpu-arm.c b/src/crypto/cpu-arm.c
index 74e937b..675d174 100644
--- a/src/crypto/cpu-arm.c
+++ b/src/crypto/cpu-arm.c
@@ -14,17 +14,16 @@
#include <openssl/cpu.h>
-#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
+#if (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) && \
+ !defined(OPENSSL_STATIC_ARMCAP)
#include <inttypes.h>
#include <string.h>
-#if !defined(OPENSSL_TRUSTY)
#include <setjmp.h>
#include <signal.h>
-#endif
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
/* We can't include <sys/auxv.h> because the Android SDK version against which
@@ -33,7 +32,9 @@
unsigned long getauxval(unsigned long type) __attribute__((weak));
-char CRYPTO_is_NEON_capable(void) {
+extern uint32_t OPENSSL_armcap_P;
+
+char CRYPTO_is_NEON_capable_at_runtime(void) {
return (OPENSSL_armcap_P & ARMV7_NEON) != 0;
}
@@ -62,7 +63,15 @@ void CRYPTO_set_NEON_functional(char neon_functional) {
}
}
-#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_ARM) && !defined(OPENSSL_TRUSTY)
+int CRYPTO_is_ARMv8_AES_capable(void) {
+ return (OPENSSL_armcap_P & ARMV8_AES) != 0;
+}
+
+int CRYPTO_is_ARMv8_PMULL_capable(void) {
+ return (OPENSSL_armcap_P & ARMV8_PMULL) != 0;
+}
+
+#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_ARM)
static sigjmp_buf sigill_jmp;
@@ -70,12 +79,12 @@ static void sigill_handler(int signal) {
siglongjmp(sigill_jmp, signal);
}
-void CRYPTO_arm_neon_probe();
+void CRYPTO_arm_neon_probe(void);
// probe_for_NEON returns 1 if a NEON instruction runs successfully. Because
// getauxval doesn't exist on Android until Jelly Bean, supporting NEON on
// older devices requires this.
-static int probe_for_NEON() {
+static int probe_for_NEON(void) {
int supported = 0;
sigset_t sigmask;
@@ -120,7 +129,7 @@ static int probe_for_NEON(void) {
return 0;
}
-#endif /* !OPENSSL_NO_ASM && OPENSSL_ARM && !OPENSSL_TRUSTY */
+#endif /* !OPENSSL_NO_ASM && OPENSSL_ARM */
void OPENSSL_cpuid_setup(void) {
if (getauxval == NULL) {
@@ -186,4 +195,5 @@ void OPENSSL_cpuid_setup(void) {
}
}
-#endif /* defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) */
+#endif /* (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) &&
+ !defined(OPENSSL_STATIC_ARMCAP) */
diff --git a/src/crypto/cpu-intel.c b/src/crypto/cpu-intel.c
index df0e127..924bab0 100644
--- a/src/crypto/cpu-intel.c
+++ b/src/crypto/cpu-intel.c
@@ -68,8 +68,58 @@
#include <stdio.h>
#include <string.h>
-/* OPENSSL_ia32_cpuid is defined in cpu-x86_64-asm.pl. */
-extern uint64_t OPENSSL_ia32_cpuid(uint32_t*);
+#if defined(OPENSSL_WINDOWS)
+#pragma warning(push, 3)
+#include <immintrin.h>
+#include <intrin.h>
+#pragma warning(pop)
+#endif
+
+
+/* OPENSSL_cpuid runs the cpuid instruction. |leaf| is passed in as EAX and ECX
+ * is set to zero. It writes EAX, EBX, ECX, and EDX to |*out_eax| through
+ * |*out_edx|. */
+static void OPENSSL_cpuid(uint32_t *out_eax, uint32_t *out_ebx,
+ uint32_t *out_ecx, uint32_t *out_edx, uint32_t leaf) {
+#if defined(OPENSSL_WINDOWS)
+ int tmp[4];
+ __cpuid(tmp, (int)leaf);
+ *out_eax = (uint32_t)tmp[0];
+ *out_ebx = (uint32_t)tmp[1];
+ *out_ecx = (uint32_t)tmp[2];
+ *out_edx = (uint32_t)tmp[3];
+#elif defined(__pic__) && defined(OPENSSL_32_BIT)
+ /* Inline assembly may not clobber the PIC register. For 32-bit, this is EBX.
+ * See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47602. */
+ __asm__ volatile (
+ "xor %%ecx, %%ecx\n"
+ "mov %%ebx, %%edi\n"
+ "cpuid\n"
+ "xchg %%edi, %%ebx\n"
+ : "=a"(*out_eax), "=D"(*out_ebx), "=c"(*out_ecx), "=d"(*out_edx)
+ : "a"(leaf)
+ );
+#else
+ __asm__ volatile (
+ "xor %%ecx, %%ecx\n"
+ "cpuid\n"
+ : "=a"(*out_eax), "=b"(*out_ebx), "=c"(*out_ecx), "=d"(*out_edx)
+ : "a"(leaf)
+ );
+#endif
+}
+
+/* OPENSSL_xgetbv returns the value of an Intel Extended Control Register (XCR).
+ * Currently only XCR0 is defined by Intel so |xcr| should always be zero. */
+static uint64_t OPENSSL_xgetbv(uint32_t xcr) {
+#if defined(OPENSSL_WINDOWS)
+ return (uint64_t)_xgetbv(xcr);
+#else
+ uint32_t eax, edx;
+ __asm__ volatile ("xgetbv" : "=a"(eax), "=d"(edx) : "c"(xcr));
+ return (((uint64_t)edx) << 32) | eax;
+#endif
+}
/* handle_cpu_env applies the value from |in| to the CPUID values in |out[0]|
* and |out[1]|. See the comment in |OPENSSL_cpuid_setup| about this. */
@@ -91,18 +141,101 @@ static void handle_cpu_env(uint32_t *out, const char *in) {
}
void OPENSSL_cpuid_setup(void) {
- const char *env1, *env2;
+ /* Determine the vendor and maximum input value. */
+ uint32_t eax, ebx, ecx, edx;
+ OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 0);
-#if defined(OPENSSL_X86_64)
- OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
-#else
- uint64_t vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
- /* 1<<10 sets a reserved bit to indicate that the variable
- * was already initialised. */
- OPENSSL_ia32cap_P[0] = ((uint32_t)vec) | (1 << 10);
- OPENSSL_ia32cap_P[1] = vec >> 32;
-#endif
+ uint32_t num_ids = eax;
+
+ int is_intel = ebx == 0x756e6547 /* Genu */ &&
+ edx == 0x49656e69 /* ineI */ &&
+ ecx == 0x6c65746e /* ntel */;
+ int is_amd = ebx == 0x68747541 /* Auth */ &&
+ edx == 0x69746e65 /* enti */ &&
+ ecx == 0x444d4163 /* cAMD */;
+
+ int has_amd_xop = 0;
+ if (is_amd) {
+ /* AMD-specific logic.
+ * See http://developer.amd.com/wordpress/media/2012/10/254811.pdf */
+ OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 0x80000000);
+ uint32_t num_extended_ids = eax;
+ if (num_extended_ids >= 0x80000001) {
+ OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 0x80000001);
+ if (ecx & (1 << 11)) {
+ has_amd_xop = 1;
+ }
+ }
+ }
+
+ uint32_t extended_features = 0;
+ if (num_ids >= 7) {
+ OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 7);
+ extended_features = ebx;
+ }
+ /* Determine the number of cores sharing an L1 data cache to adjust the
+ * hyper-threading bit. */
+ uint32_t cores_per_cache = 0;
+ if (is_amd) {
+ /* AMD CPUs never share an L1 data cache between threads but do set the HTT
+ * bit on multi-core CPUs. */
+ cores_per_cache = 1;
+ } else if (num_ids >= 4) {
+ /* TODO(davidben): The Intel manual says this CPUID leaf enumerates all
+ * caches using ECX and doesn't say which is first. Does this matter? */
+ OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 4);
+ cores_per_cache = 1 + ((eax >> 14) & 0xfff);
+ }
+
+ OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 1);
+
+ /* Adjust the hyper-threading bit. */
+ if (edx & (1 << 28)) {
+ uint32_t num_logical_cores = (ebx >> 16) & 0xff;
+ if (cores_per_cache == 1 || num_logical_cores <= 1) {
+ edx &= ~(1 << 28);
+ }
+ }
+
+ /* Reserved bit #20 was historically repurposed to control the in-memory
+ * representation of RC4 state. Always set it to zero. */
+ edx &= ~(1 << 20);
+
+ /* Reserved bit #30 is repurposed to signal an Intel CPU. */
+ if (is_intel) {
+ edx |= (1 << 30);
+ } else {
+ edx &= ~(1 << 30);
+ }
+
+ /* The SDBG bit is repurposed to denote AMD XOP support. */
+ if (has_amd_xop) {
+ ecx |= (1 << 11);
+ } else {
+ ecx &= ~(1 << 11);
+ }
+
+ uint64_t xcr0 = 0;
+ if (ecx & (1 << 27)) {
+ /* XCR0 may only be queried if the OSXSAVE bit is set. */
+ xcr0 = OPENSSL_xgetbv(0);
+ }
+ /* See Intel manual, section 14.3. */
+ if ((xcr0 & 6) != 6) {
+ /* YMM registers cannot be used. */
+ ecx &= ~(1 << 28); /* AVX */
+ ecx &= ~(1 << 12); /* FMA */
+ ecx &= ~(1 << 11); /* AMD XOP */
+ extended_features &= ~(1 << 5); /* AVX2 */
+ }
+
+ OPENSSL_ia32cap_P[0] = edx;
+ OPENSSL_ia32cap_P[1] = ecx;
+ OPENSSL_ia32cap_P[2] = extended_features;
+ OPENSSL_ia32cap_P[3] = 0;
+
+ const char *env1, *env2;
env1 = getenv("OPENSSL_ia32cap");
if (env1 == NULL) {
return;
diff --git a/src/crypto/cpu-x86-asm.pl b/src/crypto/cpu-x86-asm.pl
deleted file mode 100644
index 319c436..0000000
--- a/src/crypto/cpu-x86-asm.pl
+++ /dev/null
@@ -1,334 +0,0 @@
-#!/usr/bin/env perl
-
-$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-push(@INC, "${dir}perlasm", "perlasm");
-require "x86asm.pl";
-
-&asm_init($ARGV[0],"crypto/cpu-x86-asm");
-
-for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
-
-&function_begin("OPENSSL_ia32_cpuid");
- &xor ("edx","edx");
- &pushf ();
- &pop ("eax");
- &mov ("ecx","eax");
- &xor ("eax",1<<21);
- &push ("eax");
- &popf ();
- &pushf ();
- &pop ("eax");
- &xor ("ecx","eax");
- &xor ("eax","eax");
- &bt ("ecx",21);
- &jnc (&label("nocpuid"));
- &mov ("esi",&wparam(0));
- &mov (&DWP(8,"esi"),"eax"); # clear 3rd word
- &cpuid ();
- &mov ("edi","eax"); # max value for standard query level
-
- &xor ("eax","eax");
- &cmp ("ebx",0x756e6547); # "Genu"
- &setne (&LB("eax"));
- &mov ("ebp","eax");
- &cmp ("edx",0x49656e69); # "ineI"
- &setne (&LB("eax"));
- &or ("ebp","eax");
- &cmp ("ecx",0x6c65746e); # "ntel"
- &setne (&LB("eax"));
- &or ("ebp","eax"); # 0 indicates Intel CPU
- &jz (&label("intel"));
-
- &cmp ("ebx",0x68747541); # "Auth"
- &setne (&LB("eax"));
- &mov ("esi","eax");
- &cmp ("edx",0x69746E65); # "enti"
- &setne (&LB("eax"));
- &or ("esi","eax");
- &cmp ("ecx",0x444D4163); # "cAMD"
- &setne (&LB("eax"));
- &or ("esi","eax"); # 0 indicates AMD CPU
- &jnz (&label("intel"));
-
- # AMD specific
- &mov ("eax",0x80000000);
- &cpuid ();
- &cmp ("eax",0x80000001);
- &jb (&label("intel"));
- &mov ("esi","eax");
- &mov ("eax",0x80000001);
- &cpuid ();
- &or ("ebp","ecx");
- &and ("ebp",1<<11|1); # isolate XOP bit
- &cmp ("esi",0x80000008);
- &jb (&label("intel"));
-
- &mov ("eax",0x80000008);
- &cpuid ();
- &movz ("esi",&LB("ecx")); # number of cores - 1
- &inc ("esi"); # number of cores
-
- &mov ("eax",1);
- &xor ("ecx","ecx");
- &cpuid ();
- &bt ("edx",28);
- &jnc (&label("generic"));
- &shr ("ebx",16);
- &and ("ebx",0xff);
- &cmp ("ebx","esi");
- &ja (&label("generic"));
- &and ("edx",0xefffffff); # clear hyper-threading bit
- &jmp (&label("generic"));
-
-&set_label("intel");
- &cmp ("edi",7);
- &jb (&label("cacheinfo"));
-
- &mov ("esi",&wparam(0));
- &mov ("eax",7);
- &xor ("ecx","ecx");
- &cpuid ();
- &mov (&DWP(8,"esi"),"ebx");
-
-&set_label("cacheinfo");
- &cmp ("edi",4);
- &mov ("edi",-1);
- &jb (&label("nocacheinfo"));
-
- &mov ("eax",4);
- &mov ("ecx",0); # query L1D
- &cpuid ();
- &mov ("edi","eax");
- &shr ("edi",14);
- &and ("edi",0xfff); # number of cores -1 per L1D
-
-&set_label("nocacheinfo");
- &mov ("eax",1);
- &xor ("ecx","ecx");
- &cpuid ();
- &and ("edx",0xbfefffff); # force reserved bits #20, #30 to 0
- &cmp ("ebp",0);
- &jne (&label("notintel"));
- &or ("edx",1<<30); # set reserved bit#30 on Intel CPUs
-&set_label("notintel");
- &bt ("edx",28); # test hyper-threading bit
- &jnc (&label("generic"));
- &and ("edx",0xefffffff);
- &cmp ("edi",0);
- &je (&label("generic"));
-
- &or ("edx",0x10000000);
- &shr ("ebx",16);
- &cmp (&LB("ebx"),1);
- &ja (&label("generic"));
- &and ("edx",0xefffffff); # clear hyper-threading bit if not
-
-&set_label("generic");
- &and ("ebp",1<<11); # isolate AMD XOP flag
- &and ("ecx",0xfffff7ff); # force 11th bit to 0
- &mov ("esi","edx");
- &or ("ebp","ecx"); # merge AMD XOP flag
-
- &bt ("ecx",27); # check OSXSAVE bit
- &jnc (&label("clear_avx"));
- &xor ("ecx","ecx");
- &data_byte(0x0f,0x01,0xd0); # xgetbv
- &and ("eax",6);
- &cmp ("eax",6);
- &je (&label("done"));
- &cmp ("eax",2);
- &je (&label("clear_avx"));
-&set_label("clear_xmm");
- &and ("ebp",0xfdfffffd); # clear AESNI and PCLMULQDQ bits
- &and ("esi",0xfeffffff); # clear FXSR
-&set_label("clear_avx");
- &and ("ebp",0xefffe7ff); # clear AVX, FMA and AMD XOP bits
- &mov ("edi",&wparam(0));
- &and (&DWP(8,"edi"),0xffffffdf); # clear AVX2
-&set_label("done");
- &mov ("eax","esi");
- &mov ("edx","ebp");
-&set_label("nocpuid");
-&function_end("OPENSSL_ia32_cpuid");
-
-&external_label("OPENSSL_ia32cap_P");
-
-&function_begin_B("OPENSSL_rdtsc","EXTRN\t_OPENSSL_ia32cap_P:DWORD");
- &xor ("eax","eax");
- &xor ("edx","edx");
- &picmeup("ecx","OPENSSL_ia32cap_P");
- &bt (&DWP(0,"ecx"),4);
- &jnc (&label("notsc"));
- &rdtsc ();
-&set_label("notsc");
- &ret ();
-&function_end_B("OPENSSL_rdtsc");
-
-# This works in Ring 0 only [read DJGPP+MS-DOS+privileged DPMI host],
-# but it's safe to call it on any [supported] 32-bit platform...
-# Just check for [non-]zero return value...
-&function_begin_B("OPENSSL_instrument_halt","EXTRN\t_OPENSSL_ia32cap_P:DWORD");
- &picmeup("ecx","OPENSSL_ia32cap_P");
- &bt (&DWP(0,"ecx"),4);
- &jnc (&label("nohalt")); # no TSC
-
- &data_word(0x9058900e); # push %cs; pop %eax
- &and ("eax",3);
- &jnz (&label("nohalt")); # not enough privileges
-
- &pushf ();
- &pop ("eax");
- &bt ("eax",9);
- &jnc (&label("nohalt")); # interrupts are disabled
-
- &rdtsc ();
- &push ("edx");
- &push ("eax");
- &halt ();
- &rdtsc ();
-
- &sub ("eax",&DWP(0,"esp"));
- &sbb ("edx",&DWP(4,"esp"));
- &add ("esp",8);
- &ret ();
-
-&set_label("nohalt");
- &xor ("eax","eax");
- &xor ("edx","edx");
- &ret ();
-&function_end_B("OPENSSL_instrument_halt");
-
-# Essentially there is only one use for this function. Under DJGPP:
-#
-# #include <go32.h>
-# ...
-# i=OPENSSL_far_spin(_dos_ds,0x46c);
-# ...
-# to obtain the number of spins till closest timer interrupt.
-
-&function_begin_B("OPENSSL_far_spin");
- &pushf ();
- &pop ("eax");
- &bt ("eax",9);
- &jnc (&label("nospin")); # interrupts are disabled
-
- &mov ("eax",&DWP(4,"esp"));
- &mov ("ecx",&DWP(8,"esp"));
- &data_word (0x90d88e1e); # push %ds, mov %eax,%ds
- &xor ("eax","eax");
- &mov ("edx",&DWP(0,"ecx"));
- &jmp (&label("spin"));
-
- &align (16);
-&set_label("spin");
- &inc ("eax");
- &cmp ("edx",&DWP(0,"ecx"));
- &je (&label("spin"));
-
- &data_word (0x1f909090); # pop %ds
- &ret ();
-
-&set_label("nospin");
- &xor ("eax","eax");
- &xor ("edx","edx");
- &ret ();
-&function_end_B("OPENSSL_far_spin");
-
-&function_begin_B("OPENSSL_wipe_cpu","EXTRN\t_OPENSSL_ia32cap_P:DWORD");
- &xor ("eax","eax");
- &xor ("edx","edx");
- &picmeup("ecx","OPENSSL_ia32cap_P");
- &mov ("ecx",&DWP(0,"ecx"));
- &bt (&DWP(0,"ecx"),1);
- &jnc (&label("no_x87"));
- if ($sse2) {
- &and ("ecx",1<<26|1<<24); # check SSE2 and FXSR bits
- &cmp ("ecx",1<<26|1<<24);
- &jne (&label("no_sse2"));
- &pxor ("xmm0","xmm0");
- &pxor ("xmm1","xmm1");
- &pxor ("xmm2","xmm2");
- &pxor ("xmm3","xmm3");
- &pxor ("xmm4","xmm4");
- &pxor ("xmm5","xmm5");
- &pxor ("xmm6","xmm6");
- &pxor ("xmm7","xmm7");
- &set_label("no_sse2");
- }
- # just a bunch of fldz to zap the fp/mm bank followed by finit...
- &data_word(0xeed9eed9,0xeed9eed9,0xeed9eed9,0xeed9eed9,0x90e3db9b);
-&set_label("no_x87");
- &lea ("eax",&DWP(4,"esp"));
- &ret ();
-&function_end_B("OPENSSL_wipe_cpu");
-
-&function_begin_B("OPENSSL_atomic_add");
- &mov ("edx",&DWP(4,"esp")); # fetch the pointer, 1st arg
- &mov ("ecx",&DWP(8,"esp")); # fetch the increment, 2nd arg
- &push ("ebx");
- &nop ();
- &mov ("eax",&DWP(0,"edx"));
-&set_label("spin");
- &lea ("ebx",&DWP(0,"eax","ecx"));
- &nop ();
- &data_word(0x1ab10ff0); # lock; cmpxchg %ebx,(%edx) # %eax is envolved and is always reloaded
- &jne (&label("spin"));
- &mov ("eax","ebx"); # OpenSSL expects the new value
- &pop ("ebx");
- &ret ();
-&function_end_B("OPENSSL_atomic_add");
-
-# This function can become handy under Win32 in situations when
-# we don't know which calling convention, __stdcall or __cdecl(*),
-# indirect callee is using. In C it can be deployed as
-#
-#ifdef OPENSSL_CPUID_OBJ
-# type OPENSSL_indirect_call(void *f,...);
-# ...
-# OPENSSL_indirect_call(func,[up to $max arguments]);
-#endif
-#
-# (*) it's designed to work even for __fastcall if number of
-# arguments is 1 or 2!
-&function_begin_B("OPENSSL_indirect_call");
- {
- my ($max,$i)=(7,); # $max has to be chosen as 4*n-1
- # in order to preserve eventual
- # stack alignment
- &push ("ebp");
- &mov ("ebp","esp");
- &sub ("esp",$max*4);
- &mov ("ecx",&DWP(12,"ebp"));
- &mov (&DWP(0,"esp"),"ecx");
- &mov ("edx",&DWP(16,"ebp"));
- &mov (&DWP(4,"esp"),"edx");
- for($i=2;$i<$max;$i++)
- {
- # Some copies will be redundant/bogus...
- &mov ("eax",&DWP(12+$i*4,"ebp"));
- &mov (&DWP(0+$i*4,"esp"),"eax");
- }
- &call_ptr (&DWP(8,"ebp"));# make the call...
- &mov ("esp","ebp"); # ... and just restore the stack pointer
- # without paying attention to what we called,
- # (__cdecl *func) or (__stdcall *one).
- &pop ("ebp");
- &ret ();
- }
-&function_end_B("OPENSSL_indirect_call");
-
-&function_begin_B("OPENSSL_ia32_rdrand");
- &mov ("ecx",8);
-&set_label("loop");
- &rdrand ("eax");
- &jc (&label("break"));
- &loop (&label("loop"));
-&set_label("break");
- &cmp ("eax",0);
- &cmove ("eax","ecx");
- &ret ();
-&function_end_B("OPENSSL_ia32_rdrand");
-
-&hidden("OPENSSL_ia32cap_P");
-
-&asm_finish();
diff --git a/src/crypto/cpu-x86_64-asm.pl b/src/crypto/cpu-x86_64-asm.pl
deleted file mode 100644
index 89d7a6c..0000000
--- a/src/crypto/cpu-x86_64-asm.pl
+++ /dev/null
@@ -1,163 +0,0 @@
-#!/usr/bin/env perl
-
-$flavour = shift;
-$output = shift;
-if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-
-$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-
-$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-( $xlate="${dir}perlasm/x86_64-xlate.pl" and -f $xlate) or
-die "can't locate x86_64-xlate.pl";
-
-open OUT,"| \"$^X\" $xlate $flavour $output";
-*STDOUT=*OUT;
-
-($arg1,$arg2,$arg3,$arg4)=$win64?("%rcx","%rdx","%r8", "%r9") : # Win64 order
- ("%rdi","%rsi","%rdx","%rcx"); # Unix order
-
-print<<___;
-.text
-
-.globl OPENSSL_ia32_cpuid
-.type OPENSSL_ia32_cpuid,\@function,1
-.align 16
-OPENSSL_ia32_cpuid:
- # On Windows, $arg1 is rcx, but that will be clobbered. So make Windows
- # use the same register as Unix.
- mov $arg1,%rdi
- mov %rbx,%r8 # save %rbx
-
- xor %eax,%eax
- mov %eax,8(%rdi) # clear 3rd word
- cpuid
- mov %eax,%r11d # max value for standard query level
-
- xor %eax,%eax
- cmp \$0x756e6547,%ebx # "Genu"
- setne %al
- mov %eax,%r9d
- cmp \$0x49656e69,%edx # "ineI"
- setne %al
- or %eax,%r9d
- cmp \$0x6c65746e,%ecx # "ntel"
- setne %al
- or %eax,%r9d # 0 indicates Intel CPU
- jz .Lintel
-
- cmp \$0x68747541,%ebx # "Auth"
- setne %al
- mov %eax,%r10d
- cmp \$0x69746E65,%edx # "enti"
- setne %al
- or %eax,%r10d
- cmp \$0x444D4163,%ecx # "cAMD"
- setne %al
- or %eax,%r10d # 0 indicates AMD CPU
- jnz .Lintel
-
- # AMD specific
- # See http://developer.amd.com/wordpress/media/2012/10/254811.pdf (1)
-
- mov \$0x80000000,%eax
- cpuid
- # Returns "The largest CPUID extended function input value supported by
- # the processor implementation." in EAX.
- cmp \$0x80000001,%eax
- jb .Lintel
- mov %eax,%r10d
- mov \$0x80000001,%eax
- cpuid
- # Returns feature bits in ECX. See page 20 of [1].
- # TODO(fork): I think this should be a MOV.
- or %ecx,%r9d
- and \$0x00000801,%r9d # isolate AMD XOP bit, 1<<11
-
- cmp \$0x80000008,%r10d
- jb .Lintel
-
- mov \$0x80000008,%eax
- cpuid
- # Returns APIC ID and number of cores in ECX. See page 27 of [1].
- movzb %cl,%r10 # number of cores - 1
- inc %r10 # number of cores
-
- mov \$1,%eax
- cpuid
- # See page 13 of [1].
- bt \$28,%edx # test hyper-threading bit
- jnc .Lgeneric
- shr \$16,%ebx # number of logical processors
- cmp %r10b,%bl
- ja .Lgeneric
- and \$0xefffffff,%edx # Clear hyper-threading bit.
- jmp .Lgeneric
-
-.Lintel:
- cmp \$4,%r11d
- mov \$-1,%r10d
- jb .Lnocacheinfo
-
- mov \$4,%eax
- mov \$0,%ecx # query L1D
- cpuid
- mov %eax,%r10d
- shr \$14,%r10d
- and \$0xfff,%r10d # number of cores -1 per L1D
-
- cmp \$7,%r11d
- jb .Lnocacheinfo
-
- mov \$7,%eax
- xor %ecx,%ecx
- cpuid
- mov %ebx,8(%rdi)
-
-.Lnocacheinfo:
- mov \$1,%eax
- cpuid
- # Gets feature information. See table 3-21 in the Intel manual.
- and \$0xbfefffff,%edx # force reserved bits to 0
- cmp \$0,%r9d
- jne .Lnotintel
- or \$0x40000000,%edx # set reserved bit#30 on Intel CPUs
-.Lnotintel:
- bt \$28,%edx # test hyper-threading bit
- jnc .Lgeneric
- and \$0xefffffff,%edx # ~(1<<28) - clear hyper-threading.
- cmp \$0,%r10d
- je .Lgeneric
-
- or \$0x10000000,%edx # 1<<28
- shr \$16,%ebx
- cmp \$1,%bl # see if cache is shared
- ja .Lgeneric
- and \$0xefffffff,%edx # ~(1<<28)
-.Lgeneric:
- and \$0x00000800,%r9d # isolate AMD XOP flag
- and \$0xfffff7ff,%ecx
- or %ecx,%r9d # merge AMD XOP flag
-
- mov %edx,%r10d # %r9d:%r10d is copy of %ecx:%edx
- bt \$27,%r9d # check OSXSAVE bit
- jnc .Lclear_avx
- xor %ecx,%ecx # XCR0
- .byte 0x0f,0x01,0xd0 # xgetbv
- and \$6,%eax # isolate XMM and YMM state support
- cmp \$6,%eax
- je .Ldone
-.Lclear_avx:
- mov \$0xefffe7ff,%eax # ~(1<<28|1<<12|1<<11)
- and %eax,%r9d # clear AVX, FMA and AMD XOP bits
- andl \$0xffffffdf,8(%rdi) # cleax AVX2, ~(1<<5)
-.Ldone:
- movl %r9d,4(%rdi)
- movl %r10d,0(%rdi)
- mov %r8,%rbx # restore %rbx
- ret
-.size OPENSSL_ia32_cpuid,.-OPENSSL_ia32_cpuid
-
-___
-
-close STDOUT; # flush
diff --git a/src/crypto/crypto.c b/src/crypto/crypto.c
index d9bb07e..ace1c82 100644
--- a/src/crypto/crypto.c
+++ b/src/crypto/crypto.c
@@ -14,10 +14,12 @@
#include <openssl/crypto.h>
+#include <openssl/cpu.h>
+
#include "internal.h"
-#if !defined(OPENSSL_NO_ASM) && \
+#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_STATIC_ARMCAP) && \
(defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \
defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))
/* x86, x86_64 and the ARMs need to record the result of a cpuid call for the
@@ -55,9 +57,29 @@
uint32_t OPENSSL_ia32cap_P[4] = {0};
#elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
+
+#if defined(OPENSSL_STATIC_ARMCAP)
-#if defined(__ARM_NEON__)
+uint32_t OPENSSL_armcap_P =
+#if defined(OPENSSL_STATIC_ARMCAP_NEON) || defined(__ARM_NEON__)
+ ARMV7_NEON | ARMV7_NEON_FUNCTIONAL |
+#endif
+#if defined(OPENSSL_STATIC_ARMCAP_AES)
+ ARMV8_AES |
+#endif
+#if defined(OPENSSL_STATIC_ARMCAP_SHA1)
+ ARMV8_SHA1 |
+#endif
+#if defined(OPENSSL_STATIC_ARMCAP_SHA256)
+ ARMV8_SHA256 |
+#endif
+#if defined(OPENSSL_STATIC_ARMCAP_PMULL)
+ ARMV8_PMULL |
+#endif
+ 0;
+
+#elif defined(__ARM_NEON__)
uint32_t OPENSSL_armcap_P = ARMV7_NEON | ARMV7_NEON_FUNCTIONAL;
#else
uint32_t OPENSSL_armcap_P = ARMV7_NEON_FUNCTIONAL;
@@ -66,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
@@ -97,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
}
@@ -110,3 +132,9 @@ const char *SSLeay_version(int unused) {
unsigned long SSLeay(void) {
return OPENSSL_VERSION_NUMBER;
}
+
+int CRYPTO_malloc_init(void) {
+ return 1;
+}
+
+void ENGINE_load_builtin_engines(void) {}
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/CMakeLists.txt b/src/crypto/des/CMakeLists.txt
index 7d49ff3..f61fa14 100644
--- a/src/crypto/des/CMakeLists.txt
+++ b/src/crypto/des/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
des
diff --git a/src/crypto/des/des.c b/src/crypto/des/des.c
index 9cd75f5..1d27ebe 100644
--- a/src/crypto/des/des.c
+++ b/src/crypto/des/des.c
@@ -298,10 +298,8 @@ void DES_set_key(const DES_cblock *key, DES_key_schedule *schedule) {
0, 1, 1, 1, 1, 1, 1, 0};
uint32_t c, d, t, s, t2;
const uint8_t *in;
- uint32_t *k;
int i;
- k = &schedule->ks->deslong[0];
in = key->bytes;
c2l(in, c);
@@ -344,10 +342,10 @@ void DES_set_key(const DES_cblock *key, DES_key_schedule *schedule) {
/* table contained 0213 4657 */
t2 = ((t << 16L) | (s & 0x0000ffffL)) & 0xffffffffL;
- *(k++) = ROTATE(t2, 30) & 0xffffffffL;
+ schedule->subkeys[i][0] = ROTATE(t2, 30) & 0xffffffffL;
t2 = ((s >> 16L) | (t & 0xffff0000L));
- *(k++) = ROTATE(t2, 26) & 0xffffffffL;
+ schedule->subkeys[i][1] = ROTATE(t2, 26) & 0xffffffffL;
}
}
@@ -382,7 +380,6 @@ void DES_set_odd_parity(DES_cblock *key) {
static void DES_encrypt1(uint32_t *data, const DES_key_schedule *ks, int enc) {
uint32_t l, r, t, u;
- const uint32_t *s;
r = data[0];
l = data[1];
@@ -398,43 +395,42 @@ static void DES_encrypt1(uint32_t *data, const DES_key_schedule *ks, int enc) {
r = ROTATE(r, 29) & 0xffffffffL;
l = ROTATE(l, 29) & 0xffffffffL;
- s = ks->ks->deslong;
/* I don't know if it is worth the effort of loop unrolling the
* inner loop */
if (enc) {
- D_ENCRYPT(l, r, 0); /* 1 */
- D_ENCRYPT(r, l, 2); /* 2 */
- D_ENCRYPT(l, r, 4); /* 3 */
- D_ENCRYPT(r, l, 6); /* 4 */
- D_ENCRYPT(l, r, 8); /* 5 */
- D_ENCRYPT(r, l, 10); /* 6 */
- D_ENCRYPT(l, r, 12); /* 7 */
- D_ENCRYPT(r, l, 14); /* 8 */
- D_ENCRYPT(l, r, 16); /* 9 */
- D_ENCRYPT(r, l, 18); /* 10 */
- D_ENCRYPT(l, r, 20); /* 11 */
- D_ENCRYPT(r, l, 22); /* 12 */
- D_ENCRYPT(l, r, 24); /* 13 */
- D_ENCRYPT(r, l, 26); /* 14 */
- D_ENCRYPT(l, r, 28); /* 15 */
- D_ENCRYPT(r, l, 30); /* 16 */
+ D_ENCRYPT(ks, l, r, 0);
+ D_ENCRYPT(ks, r, l, 1);
+ D_ENCRYPT(ks, l, r, 2);
+ D_ENCRYPT(ks, r, l, 3);
+ D_ENCRYPT(ks, l, r, 4);
+ D_ENCRYPT(ks, r, l, 5);
+ D_ENCRYPT(ks, l, r, 6);
+ D_ENCRYPT(ks, r, l, 7);
+ D_ENCRYPT(ks, l, r, 8);
+ D_ENCRYPT(ks, r, l, 9);
+ D_ENCRYPT(ks, l, r, 10);
+ D_ENCRYPT(ks, r, l, 11);
+ D_ENCRYPT(ks, l, r, 12);
+ D_ENCRYPT(ks, r, l, 13);
+ D_ENCRYPT(ks, l, r, 14);
+ D_ENCRYPT(ks, r, l, 15);
} else {
- D_ENCRYPT(l, r, 30); /* 16 */
- D_ENCRYPT(r, l, 28); /* 15 */
- D_ENCRYPT(l, r, 26); /* 14 */
- D_ENCRYPT(r, l, 24); /* 13 */
- D_ENCRYPT(l, r, 22); /* 12 */
- D_ENCRYPT(r, l, 20); /* 11 */
- D_ENCRYPT(l, r, 18); /* 10 */
- D_ENCRYPT(r, l, 16); /* 9 */
- D_ENCRYPT(l, r, 14); /* 8 */
- D_ENCRYPT(r, l, 12); /* 7 */
- D_ENCRYPT(l, r, 10); /* 6 */
- D_ENCRYPT(r, l, 8); /* 5 */
- D_ENCRYPT(l, r, 6); /* 4 */
- D_ENCRYPT(r, l, 4); /* 3 */
- D_ENCRYPT(l, r, 2); /* 2 */
- D_ENCRYPT(r, l, 0); /* 1 */
+ D_ENCRYPT(ks, l, r, 15);
+ D_ENCRYPT(ks, r, l, 14);
+ D_ENCRYPT(ks, l, r, 13);
+ D_ENCRYPT(ks, r, l, 12);
+ D_ENCRYPT(ks, l, r, 11);
+ D_ENCRYPT(ks, r, l, 10);
+ D_ENCRYPT(ks, l, r, 9);
+ D_ENCRYPT(ks, r, l, 8);
+ D_ENCRYPT(ks, l, r, 7);
+ D_ENCRYPT(ks, r, l, 6);
+ D_ENCRYPT(ks, l, r, 5);
+ D_ENCRYPT(ks, r, l, 4);
+ D_ENCRYPT(ks, l, r, 3);
+ D_ENCRYPT(ks, r, l, 2);
+ D_ENCRYPT(ks, l, r, 1);
+ D_ENCRYPT(ks, r, l, 0);
}
/* rotate and clear the top bits on machines with 8byte longs */
@@ -448,7 +444,6 @@ static void DES_encrypt1(uint32_t *data, const DES_key_schedule *ks, int enc) {
static void DES_encrypt2(uint32_t *data, const DES_key_schedule *ks, int enc) {
uint32_t l, r, t, u;
- const uint32_t *s;
r = data[0];
l = data[1];
@@ -462,52 +457,50 @@ static void DES_encrypt2(uint32_t *data, const DES_key_schedule *ks, int enc) {
r = ROTATE(r, 29) & 0xffffffffL;
l = ROTATE(l, 29) & 0xffffffffL;
- s = ks->ks->deslong;
/* I don't know if it is worth the effort of loop unrolling the
* inner loop */
if (enc) {
- D_ENCRYPT(l, r, 0); /* 1 */
- D_ENCRYPT(r, l, 2); /* 2 */
- D_ENCRYPT(l, r, 4); /* 3 */
- D_ENCRYPT(r, l, 6); /* 4 */
- D_ENCRYPT(l, r, 8); /* 5 */
- D_ENCRYPT(r, l, 10); /* 6 */
- D_ENCRYPT(l, r, 12); /* 7 */
- D_ENCRYPT(r, l, 14); /* 8 */
- D_ENCRYPT(l, r, 16); /* 9 */
- D_ENCRYPT(r, l, 18); /* 10 */
- D_ENCRYPT(l, r, 20); /* 11 */
- D_ENCRYPT(r, l, 22); /* 12 */
- D_ENCRYPT(l, r, 24); /* 13 */
- D_ENCRYPT(r, l, 26); /* 14 */
- D_ENCRYPT(l, r, 28); /* 15 */
- D_ENCRYPT(r, l, 30); /* 16 */
+ D_ENCRYPT(ks, l, r, 0);
+ D_ENCRYPT(ks, r, l, 1);
+ D_ENCRYPT(ks, l, r, 2);
+ D_ENCRYPT(ks, r, l, 3);
+ D_ENCRYPT(ks, l, r, 4);
+ D_ENCRYPT(ks, r, l, 5);
+ D_ENCRYPT(ks, l, r, 6);
+ D_ENCRYPT(ks, r, l, 7);
+ D_ENCRYPT(ks, l, r, 8);
+ D_ENCRYPT(ks, r, l, 9);
+ D_ENCRYPT(ks, l, r, 10);
+ D_ENCRYPT(ks, r, l, 11);
+ D_ENCRYPT(ks, l, r, 12);
+ D_ENCRYPT(ks, r, l, 13);
+ D_ENCRYPT(ks, l, r, 14);
+ D_ENCRYPT(ks, r, l, 15);
} else {
- D_ENCRYPT(l, r, 30); /* 16 */
- D_ENCRYPT(r, l, 28); /* 15 */
- D_ENCRYPT(l, r, 26); /* 14 */
- D_ENCRYPT(r, l, 24); /* 13 */
- D_ENCRYPT(l, r, 22); /* 12 */
- D_ENCRYPT(r, l, 20); /* 11 */
- D_ENCRYPT(l, r, 18); /* 10 */
- D_ENCRYPT(r, l, 16); /* 9 */
- D_ENCRYPT(l, r, 14); /* 8 */
- D_ENCRYPT(r, l, 12); /* 7 */
- D_ENCRYPT(l, r, 10); /* 6 */
- D_ENCRYPT(r, l, 8); /* 5 */
- D_ENCRYPT(l, r, 6); /* 4 */
- D_ENCRYPT(r, l, 4); /* 3 */
- D_ENCRYPT(l, r, 2); /* 2 */
- D_ENCRYPT(r, l, 0); /* 1 */
+ D_ENCRYPT(ks, l, r, 15);
+ D_ENCRYPT(ks, r, l, 14);
+ D_ENCRYPT(ks, l, r, 13);
+ D_ENCRYPT(ks, r, l, 12);
+ D_ENCRYPT(ks, l, r, 11);
+ D_ENCRYPT(ks, r, l, 10);
+ D_ENCRYPT(ks, l, r, 9);
+ D_ENCRYPT(ks, r, l, 8);
+ D_ENCRYPT(ks, l, r, 7);
+ D_ENCRYPT(ks, r, l, 6);
+ D_ENCRYPT(ks, l, r, 5);
+ D_ENCRYPT(ks, r, l, 4);
+ D_ENCRYPT(ks, l, r, 3);
+ D_ENCRYPT(ks, r, l, 2);
+ D_ENCRYPT(ks, l, r, 1);
+ D_ENCRYPT(ks, r, l, 0);
}
/* rotate and clear the top bits on machines with 8byte longs */
data[0] = ROTATE(l, 3) & 0xffffffffL;
data[1] = ROTATE(r, 3) & 0xffffffffL;
}
-static void DES_encrypt3(uint32_t *data, const DES_key_schedule *ks1,
- const DES_key_schedule *ks2,
- const DES_key_schedule *ks3) {
+void DES_encrypt3(uint32_t *data, const DES_key_schedule *ks1,
+ const DES_key_schedule *ks2, const DES_key_schedule *ks3) {
uint32_t l, r;
l = data[0];
@@ -525,9 +518,8 @@ static void DES_encrypt3(uint32_t *data, const DES_key_schedule *ks1,
data[1] = r;
}
-static void DES_decrypt3(uint32_t *data, const DES_key_schedule *ks1,
- const DES_key_schedule *ks2,
- const DES_key_schedule *ks3) {
+void DES_decrypt3(uint32_t *data, const DES_key_schedule *ks1,
+ const DES_key_schedule *ks2, const DES_key_schedule *ks3) {
uint32_t l, r;
l = data[0];
@@ -770,3 +762,10 @@ void DES_ede2_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
int enc) {
DES_ede3_cbc_encrypt(in, out, len, ks1, ks2, ks1, ivec, enc);
}
+
+
+/* Deprecated functions. */
+
+void DES_set_key_unchecked(const DES_cblock *key, DES_key_schedule *schedule) {
+ DES_set_key(key, schedule);
+}
diff --git a/src/crypto/des/internal.h b/src/crypto/des/internal.h
index d3a5cec..00b4558 100644
--- a/src/crypto/des/internal.h
+++ b/src/crypto/des/internal.h
@@ -183,13 +183,13 @@ how to use xors :-) I got it to its final state.
PERM_OP(l, r, tt, 4, 0x0f0f0f0fL); \
}
-#define LOAD_DATA(R, S, u, t, E0, E1) \
- u = R ^ s[S]; \
- t = R ^ s[S + 1]
+#define LOAD_DATA(ks, R, S, u, t, E0, E1) \
+ u = R ^ ks->subkeys[S][0]; \
+ t = R ^ ks->subkeys[S][1]
-#define D_ENCRYPT(LL, R, S) \
+#define D_ENCRYPT(ks, LL, R, S) \
{ \
- LOAD_DATA(R, S, u, t, E0, E1); \
+ LOAD_DATA(ks, R, S, u, t, E0, E1); \
t = ROTATE(t, 4); \
LL ^= \
DES_SPtrans[0][(u >> 2L) & 0x3f] ^ DES_SPtrans[2][(u >> 10L) & 0x3f] ^ \
@@ -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/CMakeLists.txt b/src/crypto/dh/CMakeLists.txt
index d0c1da7..f1e8616 100644
--- a/src/crypto/dh/CMakeLists.txt
+++ b/src/crypto/dh/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
dh
@@ -6,7 +6,6 @@ add_library(
OBJECT
dh.c
- dh_impl.c
params.c
check.c
dh_asn1.c
@@ -21,3 +20,4 @@ add_executable(
)
target_link_libraries(dh_test crypto)
+add_dependencies(all_tests dh_test)
diff --git a/src/crypto/dh/dh.c b/src/crypto/dh/dh.c
index 96b85f3..bf6196c 100644
--- a/src/crypto/dh/dh.c
+++ b/src/crypto/dh/dh.c
@@ -69,44 +69,23 @@
#include "../internal.h"
-extern const DH_METHOD DH_default_method;
+#define OPENSSL_DH_MAX_MODULUS_BITS 10000
static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
-DH *DH_new(void) { return DH_new_method(NULL); }
-
-DH *DH_new_method(const ENGINE *engine) {
+DH *DH_new(void) {
DH *dh = (DH *)OPENSSL_malloc(sizeof(DH));
if (dh == NULL) {
- OPENSSL_PUT_ERROR(DH, DH_new_method, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(DH, ERR_R_MALLOC_FAILURE);
return NULL;
}
memset(dh, 0, sizeof(DH));
- if (engine) {
- dh->meth = ENGINE_get_DH_method(engine);
- }
-
- if (dh->meth == NULL) {
- dh->meth = (DH_METHOD*) &DH_default_method;
- }
- METHOD_ref(dh->meth);
-
CRYPTO_MUTEX_init(&dh->method_mont_p_lock);
dh->references = 1;
- if (!CRYPTO_new_ex_data(&g_ex_data_class, dh, &dh->ex_data)) {
- OPENSSL_free(dh);
- return NULL;
- }
-
- if (dh->meth->init && !dh->meth->init(dh)) {
- CRYPTO_free_ex_data(&g_ex_data_class, dh, &dh->ex_data);
- METHOD_unref(dh->meth);
- OPENSSL_free(dh);
- return NULL;
- }
+ CRYPTO_new_ex_data(&dh->ex_data);
return dh;
}
@@ -120,46 +99,278 @@ void DH_free(DH *dh) {
return;
}
- if (dh->meth->finish) {
- dh->meth->finish(dh);
- }
- METHOD_unref(dh->meth);
-
CRYPTO_free_ex_data(&g_ex_data_class, dh, &dh->ex_data);
- if (dh->method_mont_p) BN_MONT_CTX_free(dh->method_mont_p);
- if (dh->p != NULL) BN_clear_free(dh->p);
- if (dh->g != NULL) BN_clear_free(dh->g);
- if (dh->q != NULL) BN_clear_free(dh->q);
- if (dh->j != NULL) BN_clear_free(dh->j);
- if (dh->seed) OPENSSL_free(dh->seed);
- if (dh->counter != NULL) BN_clear_free(dh->counter);
- if (dh->pub_key != NULL) BN_clear_free(dh->pub_key);
- if (dh->priv_key != NULL) BN_clear_free(dh->priv_key);
+ BN_MONT_CTX_free(dh->method_mont_p);
+ BN_clear_free(dh->p);
+ BN_clear_free(dh->g);
+ BN_clear_free(dh->q);
+ BN_clear_free(dh->j);
+ OPENSSL_free(dh->seed);
+ BN_clear_free(dh->counter);
+ BN_clear_free(dh->pub_key);
+ BN_clear_free(dh->priv_key);
CRYPTO_MUTEX_cleanup(&dh->method_mont_p_lock);
OPENSSL_free(dh);
}
int DH_generate_parameters_ex(DH *dh, int prime_bits, int generator, BN_GENCB *cb) {
- if (dh->meth->generate_parameters) {
- return dh->meth->generate_parameters(dh, prime_bits, generator, cb);
+ /* We generate DH parameters as follows
+ * find a prime q which is prime_bits/2 bits long.
+ * p=(2*q)+1 or (p-1)/2 = q
+ * For this case, g is a generator if
+ * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1.
+ * Since the factors of p-1 are q and 2, we just need to check
+ * g^2 mod p != 1 and g^q mod p != 1.
+ *
+ * Having said all that,
+ * there is another special case method for the generators 2, 3 and 5.
+ * for 2, p mod 24 == 11
+ * for 3, p mod 12 == 5 <<<<< does not work for safe primes.
+ * for 5, p mod 10 == 3 or 7
+ *
+ * Thanks to Phil Karn <karn@qualcomm.com> for the pointers about the
+ * special generators and for answering some of my questions.
+ *
+ * I've implemented the second simple method :-).
+ * Since DH should be using a safe prime (both p and q are prime),
+ * this generator function can take a very very long time to run.
+ */
+
+ /* Actually there is no reason to insist that 'generator' be a generator.
+ * It's just as OK (and in some sense better) to use a generator of the
+ * order-q subgroup.
+ */
+
+ BIGNUM *t1, *t2;
+ int g, ok = 0;
+ BN_CTX *ctx = NULL;
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL) {
+ goto err;
+ }
+ BN_CTX_start(ctx);
+ t1 = BN_CTX_get(ctx);
+ t2 = BN_CTX_get(ctx);
+ if (t1 == NULL || t2 == NULL) {
+ goto err;
+ }
+
+ /* Make sure |dh| has the necessary elements */
+ if (dh->p == NULL) {
+ dh->p = BN_new();
+ if (dh->p == NULL) {
+ goto err;
+ }
+ }
+ if (dh->g == NULL) {
+ dh->g = BN_new();
+ if (dh->g == NULL) {
+ goto err;
+ }
}
- return DH_default_method.generate_parameters(dh, prime_bits, generator, cb);
+
+ if (generator <= 1) {
+ OPENSSL_PUT_ERROR(DH, DH_R_BAD_GENERATOR);
+ goto err;
+ }
+ if (generator == DH_GENERATOR_2) {
+ if (!BN_set_word(t1, 24)) {
+ goto err;
+ }
+ if (!BN_set_word(t2, 11)) {
+ goto err;
+ }
+ g = 2;
+ } else if (generator == DH_GENERATOR_5) {
+ if (!BN_set_word(t1, 10)) {
+ goto err;
+ }
+ if (!BN_set_word(t2, 3)) {
+ goto err;
+ }
+ /* BN_set_word(t3,7); just have to miss
+ * out on these ones :-( */
+ g = 5;
+ } else {
+ /* in the general case, don't worry if 'generator' is a
+ * generator or not: since we are using safe primes,
+ * it will generate either an order-q or an order-2q group,
+ * which both is OK */
+ if (!BN_set_word(t1, 2)) {
+ goto err;
+ }
+ if (!BN_set_word(t2, 1)) {
+ goto err;
+ }
+ g = generator;
+ }
+
+ if (!BN_generate_prime_ex(dh->p, prime_bits, 1, t1, t2, cb)) {
+ goto err;
+ }
+ if (!BN_GENCB_call(cb, 3, 0)) {
+ goto err;
+ }
+ if (!BN_set_word(dh->g, g)) {
+ goto err;
+ }
+ ok = 1;
+
+err:
+ if (!ok) {
+ OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB);
+ }
+
+ if (ctx != NULL) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ return ok;
}
int DH_generate_key(DH *dh) {
- if (dh->meth->generate_key) {
- return dh->meth->generate_key(dh);
+ int ok = 0;
+ int generate_new_key = 0;
+ unsigned l;
+ 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;
+ }
+
+ if (dh->priv_key == NULL) {
+ priv_key = BN_new();
+ if (priv_key == NULL) {
+ goto err;
+ }
+ generate_new_key = 1;
+ } else {
+ priv_key = dh->priv_key;
+ }
+
+ if (dh->pub_key == NULL) {
+ pub_key = BN_new();
+ if (pub_key == NULL) {
+ goto err;
+ }
+ } else {
+ pub_key = dh->pub_key;
+ }
+
+ mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock,
+ dh->p, ctx);
+ if (!mont) {
+ goto err;
+ }
+
+ if (generate_new_key) {
+ if (dh->q) {
+ do {
+ if (!BN_rand_range(priv_key, dh->q)) {
+ goto err;
+ }
+ } while (BN_is_zero(priv_key) || BN_is_one(priv_key));
+ } else {
+ /* secret exponent length */
+ DH_check_standard_parameters(dh);
+ l = dh->priv_length ? dh->priv_length : BN_num_bits(dh->p) - 1;
+ if (!BN_rand(priv_key, l, 0, 0)) {
+ goto err;
+ }
+ }
+ }
+
+ BN_with_flags(&local_priv, priv_key, BN_FLG_CONSTTIME);
+ if (!BN_mod_exp_mont(pub_key, dh->g, &local_priv, dh->p, ctx, mont)) {
+ goto err;
+ }
+
+ dh->pub_key = pub_key;
+ dh->priv_key = priv_key;
+ ok = 1;
+
+err:
+ if (ok != 1) {
+ OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB);
+ }
+
+ if (dh->pub_key == NULL) {
+ BN_free(pub_key);
+ }
+ if (dh->priv_key == NULL) {
+ BN_free(priv_key);
}
- return DH_default_method.generate_key(dh);
+ BN_CTX_free(ctx);
+ return ok;
}
int DH_compute_key(unsigned char *out, const BIGNUM *peers_key, DH *dh) {
- if (dh->meth->compute_key) {
- return dh->meth->compute_key(dh, out, peers_key);
+ BN_CTX *ctx = NULL;
+ BN_MONT_CTX *mont = NULL;
+ BIGNUM *shared_key;
+ int ret = -1;
+ int check_result;
+ 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;
+ }
+ BN_CTX_start(ctx);
+ shared_key = BN_CTX_get(ctx);
+ if (shared_key == NULL) {
+ goto err;
+ }
+
+ if (dh->priv_key == NULL) {
+ OPENSSL_PUT_ERROR(DH, DH_R_NO_PRIVATE_VALUE);
+ goto err;
+ }
+
+ mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock,
+ dh->p, ctx);
+ if (!mont) {
+ goto err;
}
- return DH_default_method.compute_key(dh, out, peers_key);
+
+ if (!DH_check_pub_key(dh, peers_key, &check_result) || check_result) {
+ OPENSSL_PUT_ERROR(DH, DH_R_INVALID_PUBKEY);
+ goto err;
+ }
+
+ BN_with_flags(&local_priv, dh->priv_key, BN_FLG_CONSTTIME);
+ if (!BN_mod_exp_mont(shared_key, peers_key, &local_priv, dh->p, ctx,
+ mont)) {
+ OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB);
+ goto err;
+ }
+
+ ret = BN_bn2bin(shared_key, out);
+
+err:
+ if (ctx != NULL) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+
+ return ret;
}
int DH_size(const DH *dh) { return BN_num_bytes(dh->p); }
@@ -233,20 +444,20 @@ 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;
}
int DH_set_ex_data(DH *d, int idx, void *arg) {
- return (CRYPTO_set_ex_data(&d->ex_data, idx, arg));
+ return CRYPTO_set_ex_data(&d->ex_data, idx, arg);
}
void *DH_get_ex_data(DH *d, int idx) {
- return (CRYPTO_get_ex_data(&d->ex_data, idx));
+ return CRYPTO_get_ex_data(&d->ex_data, idx);
}
diff --git a/src/crypto/dh/dh_impl.c b/src/crypto/dh/dh_impl.c
deleted file mode 100644
index f269412..0000000
--- a/src/crypto/dh/dh_impl.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/* 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.] */
-
-#include <openssl/dh.h>
-
-#include <openssl/bn.h>
-#include <openssl/err.h>
-#include <openssl/thread.h>
-
-#include "internal.h"
-
-
-#define OPENSSL_DH_MAX_MODULUS_BITS 10000
-
-static int generate_parameters(DH *ret, int prime_bits, int generator, BN_GENCB *cb) {
- /* We generate DH parameters as follows
- * find a prime q which is prime_bits/2 bits long.
- * p=(2*q)+1 or (p-1)/2 = q
- * For this case, g is a generator if
- * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1.
- * Since the factors of p-1 are q and 2, we just need to check
- * g^2 mod p != 1 and g^q mod p != 1.
- *
- * Having said all that,
- * there is another special case method for the generators 2, 3 and 5.
- * for 2, p mod 24 == 11
- * for 3, p mod 12 == 5 <<<<< does not work for safe primes.
- * for 5, p mod 10 == 3 or 7
- *
- * Thanks to Phil Karn <karn@qualcomm.com> for the pointers about the
- * special generators and for answering some of my questions.
- *
- * I've implemented the second simple method :-).
- * Since DH should be using a safe prime (both p and q are prime),
- * this generator function can take a very very long time to run.
- */
-
- /* Actually there is no reason to insist that 'generator' be a generator.
- * It's just as OK (and in some sense better) to use a generator of the
- * order-q subgroup.
- */
-
- BIGNUM *t1, *t2;
- int g, ok = 0;
- BN_CTX *ctx = NULL;
-
- ctx = BN_CTX_new();
- if (ctx == NULL) {
- goto err;
- }
- BN_CTX_start(ctx);
- t1 = BN_CTX_get(ctx);
- t2 = BN_CTX_get(ctx);
- if (t1 == NULL || t2 == NULL) {
- goto err;
- }
-
- /* Make sure 'ret' has the necessary elements */
- if (!ret->p && ((ret->p = BN_new()) == NULL)) {
- goto err;
- }
- if (!ret->g && ((ret->g = BN_new()) == NULL)) {
- goto err;
- }
-
- if (generator <= 1) {
- OPENSSL_PUT_ERROR(DH, generate_parameters, DH_R_BAD_GENERATOR);
- goto err;
- }
- if (generator == DH_GENERATOR_2) {
- if (!BN_set_word(t1, 24)) {
- goto err;
- }
- if (!BN_set_word(t2, 11)) {
- goto err;
- }
- g = 2;
- } else if (generator == DH_GENERATOR_5) {
- if (!BN_set_word(t1, 10)) {
- goto err;
- }
- if (!BN_set_word(t2, 3)) {
- goto err;
- }
- /* BN_set_word(t3,7); just have to miss
- * out on these ones :-( */
- g = 5;
- } else {
- /* in the general case, don't worry if 'generator' is a
- * generator or not: since we are using safe primes,
- * it will generate either an order-q or an order-2q group,
- * which both is OK */
- if (!BN_set_word(t1, 2)) {
- goto err;
- }
- if (!BN_set_word(t2, 1)) {
- goto err;
- }
- g = generator;
- }
-
- if (!BN_generate_prime_ex(ret->p, prime_bits, 1, t1, t2, cb)) {
- goto err;
- }
- if (!BN_GENCB_call(cb, 3, 0)) {
- goto err;
- }
- if (!BN_set_word(ret->g, g)) {
- goto err;
- }
- ok = 1;
-
-err:
- if (!ok) {
- OPENSSL_PUT_ERROR(DH, generate_parameters, ERR_R_BN_LIB);
- }
-
- if (ctx != NULL) {
- BN_CTX_end(ctx);
- BN_CTX_free(ctx);
- }
- return ok;
-}
-
-static int generate_key(DH *dh) {
- int ok = 0;
- int generate_new_key = 0;
- unsigned l;
- BN_CTX *ctx;
- BN_MONT_CTX *mont = NULL;
- BIGNUM *pub_key = NULL, *priv_key = NULL;
- BIGNUM local_priv;
-
- ctx = BN_CTX_new();
- if (ctx == NULL) {
- goto err;
- }
-
- if (dh->priv_key == NULL) {
- priv_key = BN_new();
- if (priv_key == NULL) {
- goto err;
- }
- generate_new_key = 1;
- } else {
- priv_key = dh->priv_key;
- }
-
- if (dh->pub_key == NULL) {
- pub_key = BN_new();
- if (pub_key == NULL) {
- goto err;
- }
- } else {
- pub_key = dh->pub_key;
- }
-
- mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock,
- dh->p, ctx);
- if (!mont) {
- goto err;
- }
-
- if (generate_new_key) {
- if (dh->q) {
- do {
- if (!BN_rand_range(priv_key, dh->q)) {
- goto err;
- }
- } while (BN_is_zero(priv_key) || BN_is_one(priv_key));
- } else {
- /* secret exponent length */
- DH_check_standard_parameters(dh);
- l = dh->priv_length ? dh->priv_length : BN_num_bits(dh->p) - 1;
- if (!BN_rand(priv_key, l, 0, 0)) {
- goto err;
- }
- }
- }
-
- BN_with_flags(&local_priv, priv_key, BN_FLG_CONSTTIME);
- if (!BN_mod_exp_mont(pub_key, dh->g, &local_priv, dh->p, ctx, mont)) {
- goto err;
- }
-
- dh->pub_key = pub_key;
- dh->priv_key = priv_key;
- ok = 1;
-
-err:
- if (ok != 1) {
- OPENSSL_PUT_ERROR(DH, generate_key, ERR_R_BN_LIB);
- }
-
- if (dh->pub_key == NULL) {
- BN_free(pub_key);
- }
- if (dh->priv_key == NULL) {
- BN_free(priv_key);
- }
- BN_CTX_free(ctx);
- return ok;
-}
-
-static int compute_key(DH *dh, unsigned char *out, const BIGNUM *pub_key) {
- BN_CTX *ctx = NULL;
- BN_MONT_CTX *mont = NULL;
- BIGNUM *shared_key;
- int ret = -1;
- int check_result;
- BIGNUM local_priv;
-
- if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) {
- OPENSSL_PUT_ERROR(DH, compute_key, DH_R_MODULUS_TOO_LARGE);
- goto err;
- }
-
- ctx = BN_CTX_new();
- if (ctx == NULL) {
- goto err;
- }
- BN_CTX_start(ctx);
- shared_key = BN_CTX_get(ctx);
- if (shared_key == NULL) {
- goto err;
- }
-
- if (dh->priv_key == NULL) {
- OPENSSL_PUT_ERROR(DH, compute_key, DH_R_NO_PRIVATE_VALUE);
- goto err;
- }
-
- mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock,
- dh->p, ctx);
- if (!mont) {
- goto err;
- }
-
- if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result) {
- OPENSSL_PUT_ERROR(DH, compute_key, DH_R_INVALID_PUBKEY);
- goto err;
- }
-
- BN_with_flags(&local_priv, dh->priv_key, BN_FLG_CONSTTIME);
- if (!BN_mod_exp_mont(shared_key, pub_key, &local_priv, dh->p, ctx,
- mont)) {
- OPENSSL_PUT_ERROR(DH, compute_key, ERR_R_BN_LIB);
- goto err;
- }
-
- ret = BN_bn2bin(shared_key, out);
-
-err:
- if (ctx != NULL) {
- BN_CTX_end(ctx);
- BN_CTX_free(ctx);
- }
-
- return ret;
-}
-
-const struct dh_method DH_default_method = {
- {
- 0 /* references */,
- 1 /* is_static */,
- },
- NULL /* app_data */,
- NULL /* init */,
- NULL /* finish */,
- generate_parameters,
- generate_key,
- compute_key,
-};
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 82d1d92..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,13 +247,11 @@ 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) {
- DH *dh;
-
- dh = DH_new_method(engine);
+ DH *dh = DH_new();
if (!dh) {
return NULL;
}
@@ -295,7 +280,7 @@ DH *DH_get_2048_256(const ENGINE *engine) {
}
void DH_check_standard_parameters(DH *dh) {
- int i;
+ unsigned i;
if (dh->p == NULL ||
dh->g == NULL ||
diff --git a/src/crypto/digest/CMakeLists.txt b/src/crypto/digest/CMakeLists.txt
index 816d116..7a68f6f 100644
--- a/src/crypto/digest/CMakeLists.txt
+++ b/src/crypto/digest/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
digest
@@ -18,3 +18,4 @@ add_executable(
)
target_link_libraries(digest_test crypto)
+add_dependencies(all_tests digest_test)
diff --git a/src/crypto/digest/digest.c b/src/crypto/digest/digest.c
index f09948b..eb71b07 100644
--- a/src/crypto/digest/digest.c
+++ b/src/crypto/digest/digest.c
@@ -116,8 +116,7 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) {
uint8_t *tmp_buf = NULL;
if (in == NULL || in->digest == NULL) {
- OPENSSL_PUT_ERROR(DIGEST, EVP_MD_CTX_copy_ex,
- DIGEST_R_INPUT_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_INPUT_NOT_INITIALIZED);
return 0;
}
@@ -130,15 +129,15 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) {
}
EVP_MD_CTX_cleanup(out);
- memcpy(out, in, sizeof(EVP_MD_CTX));
+ out->digest = in->digest;
if (in->md_data && in->digest->ctx_size) {
if (tmp_buf) {
out->md_data = tmp_buf;
} else {
out->md_data = OPENSSL_malloc(in->digest->ctx_size);
if (!out->md_data) {
- OPENSSL_PUT_ERROR(DIGEST, EVP_MD_CTX_copy_ex, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE);
return 0;
}
}
@@ -146,6 +145,7 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) {
}
assert(in->pctx == NULL || in->pctx_ops != NULL);
+ out->pctx_ops = in->pctx_ops;
if (in->pctx && in->pctx_ops) {
out->pctx = in->pctx_ops->dup(in->pctx);
if (!out->pctx) {
@@ -164,30 +164,20 @@ int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in) {
int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *engine) {
if (ctx->digest != type) {
- if (ctx->digest && ctx->digest->ctx_size) {
+ if (ctx->digest && ctx->digest->ctx_size > 0) {
OPENSSL_free(ctx->md_data);
}
ctx->digest = type;
- if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) {
- ctx->update = type->update;
+ if (type->ctx_size > 0) {
ctx->md_data = OPENSSL_malloc(type->ctx_size);
if (ctx->md_data == NULL) {
- OPENSSL_PUT_ERROR(DIGEST, EVP_DigestInit_ex, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE);
return 0;
}
}
}
assert(ctx->pctx == NULL || ctx->pctx_ops != NULL);
- if (ctx->pctx_ops) {
- if (!ctx->pctx_ops->begin_digest(ctx)) {
- return 0;
- }
- }
-
- if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) {
- return 1;
- }
ctx->digest->init(ctx);
return 1;
@@ -199,7 +189,7 @@ int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) {
}
int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) {
- ctx->update(ctx, data, len);
+ ctx->digest->update(ctx, data, len);
return 1;
}
@@ -214,7 +204,7 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, uint8_t *md_out, unsigned int *size) {
}
int EVP_DigestFinal(EVP_MD_CTX *ctx, uint8_t *md, unsigned int *size) {
- EVP_DigestFinal_ex(ctx, md, size);
+ (void)EVP_DigestFinal_ex(ctx, md, size);
EVP_MD_CTX_cleanup(ctx);
return 1;
}
@@ -253,10 +243,6 @@ int EVP_MD_CTX_type(const EVP_MD_CTX *ctx) {
return EVP_MD_type(EVP_MD_CTX_md(ctx));
}
-void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, uint32_t flags) {
- ctx->flags |= flags;
-}
-
int EVP_add_digest(const EVP_MD *digest) {
return 1;
}
diff --git a/src/crypto/digest/digests.c b/src/crypto/digest/digests.c
index f5eda36..3307f26 100644
--- a/src/crypto/digest/digests.c
+++ b/src/crypto/digest/digests.c
@@ -67,7 +67,7 @@
#include "internal.h"
#if defined(NDEBUG)
-#define CHECK(x) x
+#define CHECK(x) (void) (x)
#else
#define CHECK(x) assert(x)
#endif
@@ -262,6 +262,7 @@ struct nid_to_digest {
};
static const struct nid_to_digest nid_to_digest_mapping[] = {
+ { NID_md4, EVP_md4, SN_md4, LN_md4 },
{ NID_md5, EVP_md5, SN_md5, LN_md5 },
{ NID_sha1, EVP_sha1, SN_sha1, LN_sha1 },
{ NID_sha224, EVP_sha224, SN_sha224, LN_sha224 },
diff --git a/src/crypto/digest/internal.h b/src/crypto/digest/internal.h
index 1572fa8..e3d812a 100644
--- a/src/crypto/digest/internal.h
+++ b/src/crypto/digest/internal.h
@@ -92,7 +92,7 @@ struct env_md_st {
};
/* evp_md_pctx_ops contains function pointers to allow the |pctx| member of
- * |EVP_MD_CTX| to be manipulated without breaking laying by calling EVP
+ * |EVP_MD_CTX| to be manipulated without breaking layering by calling EVP
* functions. */
struct evp_md_pctx_ops {
/* free is called when an |EVP_MD_CTX| is being freed and the |pctx| also
@@ -102,23 +102,8 @@ struct evp_md_pctx_ops {
/* dup is called when an |EVP_MD_CTX| is copied and so the |pctx| also needs
* to be copied. */
EVP_PKEY_CTX* (*dup) (EVP_PKEY_CTX *pctx);
-
- /* begin_digest is called when a new digest operation is started. It returns
- * one on success and zero otherwise. */
- int (*begin_digest) (EVP_MD_CTX *ctx);
};
-/* EVP_MD_CTX_set_flags ORs |flags| into the flags member of |ctx|. */
-OPENSSL_EXPORT void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, uint32_t flags);
-
-/* EVP_MD_CTX_FLAG_NO_INIT causes the |EVP_MD|'s |init| function not to be
- * called, the |update| member not to be copied from the |EVP_MD| in
- * |EVP_DigestInit_ex| and for |md_data| not to be initialised.
- *
- * TODO(davidben): This is an implementation detail of |EVP_PKEY_HMAC| and can
- * be removed when it is gone. */
-#define EVP_MD_CTX_FLAG_NO_INIT 1
-
#if defined(__cplusplus)
} /* extern C */
diff --git a/src/crypto/digest/md32_common.h b/src/crypto/digest/md32_common.h
index 14607fb..9db8c54 100644
--- a/src/crypto/digest/md32_common.h
+++ b/src/crypto/digest/md32_common.h
@@ -51,56 +51,62 @@
#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.
- * Whenever needed it collects input character stream into chunks of
- * 32 bit values and invokes a block function that performs actual hash
- * calculations.
+/* 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
+ * block function that performs the actual hash calculations. To make use of
+ * this mechanism, the following macros must be defined before including
+ * md32_common.h.
*
- * Porting guide.
+ * One of |DATA_ORDER_IS_BIG_ENDIAN| or |DATA_ORDER_IS_LITTLE_ENDIAN| must be
+ * defined to specify the byte order of the input stream.
*
- * Obligatory macros:
+ * |HASH_CBLOCK| must be defined as the integer block size, in bytes.
*
- * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN
- * this macro defines byte order of input stream.
- * HASH_CBLOCK
- * size of a unit chunk HASH_BLOCK operates on.
- * HASH_LONG
- * has to be at least 32 bit wide.
- * HASH_CTX
- * context structure that at least contains following
- * members:
- * typedef struct {
- * ...
- * HASH_LONG Nl,Nh;
- * either {
- * HASH_LONG data[HASH_LBLOCK];
- * unsigned char data[HASH_CBLOCK];
- * };
- * unsigned int num;
- * ...
- * } HASH_CTX;
- * data[] vector is expected to be zeroed upon first call to
- * HASH_UPDATE.
- * HASH_UPDATE
- * name of "Update" function, implemented here.
- * HASH_TRANSFORM
- * name of "Transform" function, implemented here.
- * HASH_FINAL
- * name of "Final" function, implemented here.
- * HASH_BLOCK_DATA_ORDER
- * name of "block" function capable of treating *unaligned* input
- * message in original (data) byte order, implemented externally.
- * HASH_MAKE_STRING
- * macro convering context variables to an ASCII hash string.
+ * |HASH_CTX| must be defined as the name of the context structure, which must
+ * have at least the following members:
*
- * <appro@fy.chalmers.se>
+ * typedef struct <name>_state_st {
+ * uint32_t h[<chaining length> / sizeof(uint32_t)];
+ * 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).
+ *
+ * |HASH_UPDATE| must be defined as the name of the "Update" function to
+ * generate.
+ *
+ * |HASH_TRANSFORM| must be defined as the the name of the "Transform"
+ * function to generate.
+ *
+ * |HASH_FINAL| must be defined as the name of "Final" function to generate.
+ *
+ * |HASH_BLOCK_DATA_ORDER| must be defined as the name of the "Block" function.
+ * That function must be implemented manually. It must be capable of operating
+ * on *unaligned* input data in its original (data) byte order. It must have
+ * this signature:
+ *
+ * void HASH_BLOCK_DATA_ORDER(uint32_t *state, const uint8_t *data,
+ * size_t num);
+ *
+ * It must update the hash state |state| with |num| blocks of data from |data|,
+ * where each block is |HASH_CBLOCK| bytes; i.e. |data| points to a array of
+ * |HASH_CBLOCK * num| bytes. |state| points to the |h| member of a |HASH_CTX|,
+ * and so will have |<chaining length> / sizeof(uint32_t)| elements.
+ *
+ * |HASH_MAKE_STRING(c, s)| must be defined as a block statement that converts
+ * the hash state |c->h| into the output byte order, storing the result in |s|.
*/
#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
@@ -110,9 +116,6 @@ extern "C" {
#ifndef HASH_CBLOCK
#error "HASH_CBLOCK must be defined!"
#endif
-#ifndef HASH_LONG
-#error "HASH_LONG must be defined!"
-#endif
#ifndef HASH_CTX
#error "HASH_CTX must be defined!"
#endif
@@ -131,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;
- HASH_LONG l;
- size_t n;
-
- if (len==0) return 1;
-
- l=(c->Nl+(((HASH_LONG)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+=(HASH_LONG)(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,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,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,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,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,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/CMakeLists.txt b/src/crypto/dsa/CMakeLists.txt
index 1bb8b63..de36565 100644
--- a/src/crypto/dsa/CMakeLists.txt
+++ b/src/crypto/dsa/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
dsa
@@ -6,7 +6,6 @@ add_library(
OBJECT
dsa.c
- dsa_impl.c
dsa_asn1.c
)
@@ -19,3 +18,4 @@ add_executable(
)
target_link_libraries(dsa_test crypto)
+add_dependencies(all_tests dsa_test)
diff --git a/src/crypto/dsa/dsa.c b/src/crypto/dsa/dsa.c
index 65444b1..ebe55e8 100644
--- a/src/crypto/dsa/dsa.c
+++ b/src/crypto/dsa/dsa.c
@@ -62,58 +62,43 @@
#include <string.h>
#include <openssl/asn1.h>
+#include <openssl/bn.h>
#include <openssl/dh.h>
+#include <openssl/digest.h>
#include <openssl/engine.h>
#include <openssl/err.h>
#include <openssl/ex_data.h>
#include <openssl/mem.h>
+#include <openssl/rand.h>
+#include <openssl/sha.h>
#include <openssl/thread.h>
#include "internal.h"
#include "../internal.h"
-extern const DSA_METHOD DSA_default_method;
+#define OPENSSL_DSA_MAX_MODULUS_BITS 10000
-static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
+/* Primality test according to FIPS PUB 186[-1], Appendix 2.1: 50 rounds of
+ * Rabin-Miller */
+#define DSS_prime_checks 50
-DSA *DSA_new(void) { return DSA_new_method(NULL); }
+static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
-DSA *DSA_new_method(const ENGINE *engine) {
+DSA *DSA_new(void) {
DSA *dsa = (DSA *)OPENSSL_malloc(sizeof(DSA));
if (dsa == NULL) {
- OPENSSL_PUT_ERROR(DSA, DSA_new_method, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(DSA, ERR_R_MALLOC_FAILURE);
return NULL;
}
memset(dsa, 0, sizeof(DSA));
- if (engine) {
- dsa->meth = ENGINE_get_DSA_method(engine);
- }
-
- if (dsa->meth == NULL) {
- dsa->meth = (DSA_METHOD*) &DSA_default_method;
- }
- METHOD_ref(dsa->meth);
-
dsa->write_params = 1;
dsa->references = 1;
CRYPTO_MUTEX_init(&dsa->method_mont_p_lock);
-
- if (!CRYPTO_new_ex_data(&g_ex_data_class, dsa, &dsa->ex_data)) {
- METHOD_unref(dsa->meth);
- OPENSSL_free(dsa);
- return NULL;
- }
-
- if (dsa->meth->init && !dsa->meth->init(dsa)) {
- CRYPTO_free_ex_data(&g_ex_data_class, dsa, &dsa->ex_data);
- METHOD_unref(dsa->meth);
- OPENSSL_free(dsa);
- return NULL;
- }
+ CRYPTO_new_ex_data(&dsa->ex_data);
return dsa;
}
@@ -127,11 +112,6 @@ void DSA_free(DSA *dsa) {
return;
}
- if (dsa->meth->finish) {
- dsa->meth->finish(dsa);
- }
- METHOD_unref(dsa->meth);
-
CRYPTO_free_ex_data(&g_ex_data_class, dsa, &dsa->ex_data);
BN_clear_free(dsa->p);
@@ -141,6 +121,7 @@ void DSA_free(DSA *dsa) {
BN_clear_free(dsa->priv_key);
BN_clear_free(dsa->kinv);
BN_clear_free(dsa->r);
+ BN_MONT_CTX_free(dsa->method_mont_p);
CRYPTO_MUTEX_cleanup(&dsa->method_mont_p_lock);
OPENSSL_free(dsa);
}
@@ -153,19 +134,319 @@ int DSA_up_ref(DSA *dsa) {
int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in,
size_t seed_len, int *out_counter,
unsigned long *out_h, BN_GENCB *cb) {
- if (dsa->meth->generate_parameters) {
- return dsa->meth->generate_parameters(dsa, bits, seed_in, seed_len,
- out_counter, out_h, cb);
+ int ok = 0;
+ unsigned char seed[SHA256_DIGEST_LENGTH];
+ unsigned char md[SHA256_DIGEST_LENGTH];
+ unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH];
+ BIGNUM *r0, *W, *X, *c, *test;
+ BIGNUM *g = NULL, *q = NULL, *p = NULL;
+ BN_MONT_CTX *mont = NULL;
+ int k, n = 0, m = 0;
+ unsigned i;
+ int counter = 0;
+ int r = 0;
+ BN_CTX *ctx = NULL;
+ unsigned int h = 2;
+ unsigned qsize;
+ const EVP_MD *evpmd;
+
+ evpmd = (bits >= 2048) ? EVP_sha256() : EVP_sha1();
+ qsize = EVP_MD_size(evpmd);
+
+ if (bits < 512) {
+ bits = 512;
+ }
+
+ bits = (bits + 63) / 64 * 64;
+
+ if (seed_in != NULL) {
+ if (seed_len < (size_t)qsize) {
+ return 0;
+ }
+ if (seed_len > (size_t)qsize) {
+ /* Only consume as much seed as is expected. */
+ seed_len = qsize;
+ }
+ memcpy(seed, seed_in, seed_len);
+ }
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL) {
+ goto err;
+ }
+ BN_CTX_start(ctx);
+
+ mont = BN_MONT_CTX_new();
+ if (mont == NULL) {
+ goto err;
+ }
+
+ r0 = BN_CTX_get(ctx);
+ g = BN_CTX_get(ctx);
+ W = BN_CTX_get(ctx);
+ q = BN_CTX_get(ctx);
+ X = BN_CTX_get(ctx);
+ c = BN_CTX_get(ctx);
+ p = BN_CTX_get(ctx);
+ test = BN_CTX_get(ctx);
+
+ if (test == NULL || !BN_lshift(test, BN_value_one(), bits - 1)) {
+ goto err;
+ }
+
+ for (;;) {
+ /* Find q. */
+ for (;;) {
+ /* step 1 */
+ if (!BN_GENCB_call(cb, 0, m++)) {
+ goto err;
+ }
+
+ int use_random_seed = (seed_in == NULL);
+ if (use_random_seed) {
+ if (!RAND_bytes(seed, qsize)) {
+ goto err;
+ }
+ } else {
+ /* If we come back through, use random seed next time. */
+ seed_in = NULL;
+ }
+ memcpy(buf, seed, qsize);
+ memcpy(buf2, seed, qsize);
+ /* precompute "SEED + 1" for step 7: */
+ for (i = qsize - 1; i < qsize; i--) {
+ buf[i]++;
+ if (buf[i] != 0) {
+ break;
+ }
+ }
+
+ /* step 2 */
+ if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL) ||
+ !EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL)) {
+ goto err;
+ }
+ for (i = 0; i < qsize; i++) {
+ md[i] ^= buf2[i];
+ }
+
+ /* step 3 */
+ md[0] |= 0x80;
+ md[qsize - 1] |= 0x01;
+ if (!BN_bin2bn(md, qsize, q)) {
+ goto err;
+ }
+
+ /* step 4 */
+ r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, use_random_seed, cb);
+ if (r > 0) {
+ break;
+ }
+ if (r != 0) {
+ goto err;
+ }
+
+ /* do a callback call */
+ /* step 5 */
+ }
+
+ if (!BN_GENCB_call(cb, 2, 0) || !BN_GENCB_call(cb, 3, 0)) {
+ goto err;
+ }
+
+ /* step 6 */
+ counter = 0;
+ /* "offset = 2" */
+
+ n = (bits - 1) / 160;
+
+ for (;;) {
+ if ((counter != 0) && !BN_GENCB_call(cb, 0, counter)) {
+ goto err;
+ }
+
+ /* step 7 */
+ BN_zero(W);
+ /* now 'buf' contains "SEED + offset - 1" */
+ for (k = 0; k <= n; k++) {
+ /* obtain "SEED + offset + k" by incrementing: */
+ for (i = qsize - 1; i < qsize; i--) {
+ buf[i]++;
+ if (buf[i] != 0) {
+ break;
+ }
+ }
+
+ if (!EVP_Digest(buf, qsize, md, NULL, evpmd, NULL)) {
+ goto err;
+ }
+
+ /* step 8 */
+ if (!BN_bin2bn(md, qsize, r0) ||
+ !BN_lshift(r0, r0, (qsize << 3) * k) ||
+ !BN_add(W, W, r0)) {
+ goto err;
+ }
+ }
+
+ /* more of step 8 */
+ if (!BN_mask_bits(W, bits - 1) ||
+ !BN_copy(X, W) ||
+ !BN_add(X, X, test)) {
+ goto err;
+ }
+
+ /* step 9 */
+ if (!BN_lshift1(r0, q) ||
+ !BN_mod(c, X, r0, ctx) ||
+ !BN_sub(r0, c, BN_value_one()) ||
+ !BN_sub(p, X, r0)) {
+ goto err;
+ }
+
+ /* step 10 */
+ if (BN_cmp(p, test) >= 0) {
+ /* step 11 */
+ r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb);
+ if (r > 0) {
+ goto end; /* found it */
+ }
+ if (r != 0) {
+ goto err;
+ }
+ }
+
+ /* step 13 */
+ counter++;
+ /* "offset = offset + n + 1" */
+
+ /* step 14 */
+ if (counter >= 4096) {
+ break;
+ }
+ }
+ }
+end:
+ if (!BN_GENCB_call(cb, 2, 1)) {
+ goto err;
+ }
+
+ /* We now need to generate g */
+ /* Set r0=(p-1)/q */
+ if (!BN_sub(test, p, BN_value_one()) ||
+ !BN_div(r0, NULL, test, q, ctx)) {
+ goto err;
+ }
+
+ if (!BN_set_word(test, h) ||
+ !BN_MONT_CTX_set(mont, p, ctx)) {
+ goto err;
+ }
+
+ for (;;) {
+ /* g=test^r0%p */
+ if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont)) {
+ goto err;
+ }
+ if (!BN_is_one(g)) {
+ break;
+ }
+ if (!BN_add(test, test, BN_value_one())) {
+ goto err;
+ }
+ h++;
+ }
+
+ if (!BN_GENCB_call(cb, 3, 1)) {
+ goto err;
}
- return DSA_default_method.generate_parameters(dsa, bits, seed_in, seed_len,
- out_counter, out_h, cb);
+
+ ok = 1;
+
+err:
+ if (ok) {
+ BN_free(dsa->p);
+ BN_free(dsa->q);
+ BN_free(dsa->g);
+ dsa->p = BN_dup(p);
+ dsa->q = BN_dup(q);
+ dsa->g = BN_dup(g);
+ if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) {
+ ok = 0;
+ goto err;
+ }
+ if (out_counter != NULL) {
+ *out_counter = counter;
+ }
+ if (out_h != NULL) {
+ *out_h = h;
+ }
+ }
+
+ if (ctx) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+
+ BN_MONT_CTX_free(mont);
+
+ return ok;
}
int DSA_generate_key(DSA *dsa) {
- if (dsa->meth->keygen) {
- return dsa->meth->keygen(dsa);
+ int ok = 0;
+ BN_CTX *ctx = NULL;
+ BIGNUM *pub_key = NULL, *priv_key = NULL;
+ BIGNUM prk;
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL) {
+ goto err;
}
- return DSA_default_method.keygen(dsa);
+
+ priv_key = dsa->priv_key;
+ if (priv_key == NULL) {
+ priv_key = BN_new();
+ if (priv_key == NULL) {
+ goto err;
+ }
+ }
+
+ do {
+ if (!BN_rand_range(priv_key, dsa->q)) {
+ goto err;
+ }
+ } while (BN_is_zero(priv_key));
+
+ pub_key = dsa->pub_key;
+ if (pub_key == NULL) {
+ pub_key = BN_new();
+ if (pub_key == NULL) {
+ goto err;
+ }
+ }
+
+ BN_init(&prk);
+ BN_with_flags(&prk, priv_key, BN_FLG_CONSTTIME);
+
+ if (!BN_mod_exp(pub_key, dsa->g, &prk, dsa->p, ctx)) {
+ goto err;
+ }
+
+ dsa->priv_key = priv_key;
+ dsa->pub_key = pub_key;
+ ok = 1;
+
+err:
+ if (dsa->pub_key == NULL) {
+ BN_free(pub_key);
+ }
+ if (dsa->priv_key == NULL) {
+ BN_free(priv_key);
+ }
+ BN_CTX_free(ctx);
+
+ return ok;
}
DSA_SIG *DSA_SIG_new(void) {
@@ -190,10 +471,99 @@ void DSA_SIG_free(DSA_SIG *sig) {
}
DSA_SIG *DSA_do_sign(const uint8_t *digest, size_t digest_len, DSA *dsa) {
- if (dsa->meth->sign) {
- return dsa->meth->sign(digest, digest_len, dsa);
+ BIGNUM *kinv = NULL, *r = NULL, *s = NULL;
+ BIGNUM m;
+ BIGNUM xr;
+ BN_CTX *ctx = NULL;
+ int reason = ERR_R_BN_LIB;
+ DSA_SIG *ret = NULL;
+ int noredo = 0;
+
+ BN_init(&m);
+ BN_init(&xr);
+
+ if (!dsa->p || !dsa->q || !dsa->g) {
+ reason = DSA_R_MISSING_PARAMETERS;
+ goto err;
+ }
+
+ s = BN_new();
+ if (s == NULL) {
+ goto err;
+ }
+ ctx = BN_CTX_new();
+ if (ctx == NULL) {
+ goto err;
}
- return DSA_default_method.sign(digest, digest_len, dsa);
+
+redo:
+ if (dsa->kinv == NULL || dsa->r == NULL) {
+ if (!DSA_sign_setup(dsa, ctx, &kinv, &r)) {
+ goto err;
+ }
+ } else {
+ kinv = dsa->kinv;
+ dsa->kinv = NULL;
+ r = dsa->r;
+ dsa->r = NULL;
+ noredo = 1;
+ }
+
+ if (digest_len > BN_num_bytes(dsa->q)) {
+ /* if the digest length is greater than the size of q use the
+ * BN_num_bits(dsa->q) leftmost bits of the digest, see
+ * fips 186-3, 4.2 */
+ digest_len = BN_num_bytes(dsa->q);
+ }
+
+ if (BN_bin2bn(digest, digest_len, &m) == NULL) {
+ goto err;
+ }
+
+ /* Compute s = inv(k) (m + xr) mod q */
+ if (!BN_mod_mul(&xr, dsa->priv_key, r, dsa->q, ctx)) {
+ goto err; /* s = xr */
+ }
+ if (!BN_add(s, &xr, &m)) {
+ goto err; /* s = m + xr */
+ }
+ if (BN_cmp(s, dsa->q) > 0) {
+ if (!BN_sub(s, s, dsa->q)) {
+ goto err;
+ }
+ }
+ if (!BN_mod_mul(s, s, kinv, dsa->q, ctx)) {
+ 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)) {
+ if (noredo) {
+ reason = DSA_R_NEED_NEW_SETUP_VALUES;
+ goto err;
+ }
+ goto redo;
+ }
+ ret = DSA_SIG_new();
+ if (ret == NULL) {
+ goto err;
+ }
+ ret->r = r;
+ ret->s = s;
+
+err:
+ if (ret == NULL) {
+ OPENSSL_PUT_ERROR(DSA, reason);
+ BN_free(r);
+ BN_free(s);
+ }
+ BN_CTX_free(ctx);
+ BN_clear_free(&m);
+ BN_clear_free(&xr);
+ BN_clear_free(kinv);
+
+ return ret;
}
int DSA_do_verify(const uint8_t *digest, size_t digest_len, DSA_SIG *sig,
@@ -207,11 +577,112 @@ int DSA_do_verify(const uint8_t *digest, size_t digest_len, DSA_SIG *sig,
int DSA_do_check_signature(int *out_valid, const uint8_t *digest,
size_t digest_len, DSA_SIG *sig, const DSA *dsa) {
- if (dsa->meth->verify) {
- return dsa->meth->verify(out_valid, digest, digest_len, sig, dsa);
+ BN_CTX *ctx;
+ BIGNUM u1, u2, t1;
+ BN_MONT_CTX *mont = NULL;
+ int ret = 0;
+ unsigned i;
+
+ *out_valid = 0;
+
+ if (!dsa->p || !dsa->q || !dsa->g) {
+ OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS);
+ return 0;
+ }
+
+ i = BN_num_bits(dsa->q);
+ /* fips 186-3 allows only different sizes for q */
+ if (i != 160 && i != 224 && i != 256) {
+ OPENSSL_PUT_ERROR(DSA, DSA_R_BAD_Q_VALUE);
+ return 0;
+ }
+
+ if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) {
+ OPENSSL_PUT_ERROR(DSA, DSA_R_MODULUS_TOO_LARGE);
+ return 0;
}
- return DSA_default_method.verify(out_valid, digest, digest_len, sig, dsa);
+ BN_init(&u1);
+ BN_init(&u2);
+ BN_init(&t1);
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL) {
+ goto err;
+ }
+
+ if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
+ BN_ucmp(sig->r, dsa->q) >= 0) {
+ ret = 1;
+ goto err;
+ }
+ if (BN_is_zero(sig->s) || BN_is_negative(sig->s) ||
+ BN_ucmp(sig->s, dsa->q) >= 0) {
+ ret = 1;
+ goto err;
+ }
+
+ /* Calculate W = inv(S) mod Q
+ * save W in u2 */
+ if (BN_mod_inverse(&u2, sig->s, dsa->q, ctx) == NULL) {
+ goto err;
+ }
+
+ /* save M in u1 */
+ if (digest_len > (i >> 3)) {
+ /* if the digest length is greater than the size of q use the
+ * BN_num_bits(dsa->q) leftmost bits of the digest, see
+ * fips 186-3, 4.2 */
+ digest_len = (i >> 3);
+ }
+
+ if (BN_bin2bn(digest, digest_len, &u1) == NULL) {
+ goto err;
+ }
+
+ /* u1 = M * w mod q */
+ if (!BN_mod_mul(&u1, &u1, &u2, dsa->q, ctx)) {
+ goto err;
+ }
+
+ /* u2 = r * w mod q */
+ if (!BN_mod_mul(&u2, sig->r, &u2, dsa->q, ctx)) {
+ goto err;
+ }
+
+ mont = BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
+ (CRYPTO_MUTEX *)&dsa->method_mont_p_lock,
+ dsa->p, ctx);
+ if (!mont) {
+ goto err;
+ }
+
+ if (!BN_mod_exp2_mont(&t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, ctx,
+ mont)) {
+ goto err;
+ }
+
+ /* BN_copy(&u1,&t1); */
+ /* let u1 = u1 mod q */
+ if (!BN_mod(&u1, &t1, dsa->q, ctx)) {
+ goto err;
+ }
+
+ /* V is now in u1. If the signature is correct, it will be
+ * equal to R. */
+ *out_valid = BN_ucmp(&u1, sig->r) == 0;
+ ret = 1;
+
+err:
+ if (ret != 1) {
+ OPENSSL_PUT_ERROR(DSA, ERR_R_BN_LIB);
+ }
+ BN_CTX_free(ctx);
+ BN_free(&u1);
+ BN_free(&u2);
+ BN_free(&t1);
+
+ return ret;
}
int DSA_sign(int type, const uint8_t *digest, size_t digest_len,
@@ -290,20 +761,109 @@ int DSA_size(const DSA *dsa) {
return ret;
}
-int DSA_sign_setup(const DSA *dsa, BN_CTX *ctx, BIGNUM **out_kinv,
+int DSA_sign_setup(const DSA *dsa, BN_CTX *ctx_in, BIGNUM **out_kinv,
BIGNUM **out_r) {
- if (dsa->meth->sign_setup) {
- return dsa->meth->sign_setup(dsa, ctx, out_kinv, out_r, NULL, 0);
+ BN_CTX *ctx;
+ BIGNUM k, kq, *K, *kinv = NULL, *r = NULL;
+ int ret = 0;
+
+ if (!dsa->p || !dsa->q || !dsa->g) {
+ OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS);
+ return 0;
+ }
+
+ BN_init(&k);
+ BN_init(&kq);
+
+ ctx = ctx_in;
+ if (ctx == NULL) {
+ ctx = BN_CTX_new();
+ if (ctx == NULL) {
+ goto err;
+ }
+ }
+
+ r = BN_new();
+ if (r == NULL) {
+ goto err;
+ }
+
+ /* Get random k */
+ do {
+ if (!BN_rand_range(&k, dsa->q)) {
+ goto err;
+ }
+ } while (BN_is_zero(&k));
+
+ BN_set_flags(&k, BN_FLG_CONSTTIME);
+
+ if (BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
+ (CRYPTO_MUTEX *)&dsa->method_mont_p_lock, dsa->p,
+ ctx) == NULL) {
+ goto err;
+ }
+
+ /* Compute r = (g^k mod p) mod q */
+ if (!BN_copy(&kq, &k)) {
+ goto err;
+ }
+
+ /* We do not want timing information to leak the length of k,
+ * so we compute g^k using an equivalent exponent of fixed length.
+ *
+ * (This is a kludge that we need because the BN_mod_exp_mont()
+ * does not let us specify the desired timing behaviour.) */
+
+ if (!BN_add(&kq, &kq, dsa->q)) {
+ goto err;
+ }
+ if (BN_num_bits(&kq) <= BN_num_bits(dsa->q) && !BN_add(&kq, &kq, dsa->q)) {
+ goto err;
}
- return DSA_default_method.sign_setup(dsa, ctx, out_kinv, out_r, NULL, 0);
+ K = &kq;
+
+ if (!BN_mod_exp_mont(r, dsa->g, K, dsa->p, ctx, dsa->method_mont_p)) {
+ goto err;
+ }
+ if (!BN_mod(r, r, dsa->q, ctx)) {
+ goto err;
+ }
+
+ /* Compute part of 's = inv(k) (m + xr) mod q' */
+ kinv = BN_mod_inverse(NULL, &k, dsa->q, ctx);
+ if (kinv == NULL) {
+ goto err;
+ }
+
+ BN_clear_free(*out_kinv);
+ *out_kinv = kinv;
+ kinv = NULL;
+ BN_clear_free(*out_r);
+ *out_r = r;
+ ret = 1;
+
+err:
+ if (!ret) {
+ OPENSSL_PUT_ERROR(DSA, ERR_R_BN_LIB);
+ if (r != NULL) {
+ BN_clear_free(r);
+ }
+ }
+
+ if (ctx_in == NULL) {
+ BN_CTX_free(ctx);
+ }
+ BN_clear_free(&k);
+ BN_clear_free(&kq);
+ 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/dsa/dsa_asn1.c b/src/crypto/dsa/dsa_asn1.c
index 933fba7..b6b3fa4 100644
--- a/src/crypto/dsa/dsa_asn1.c
+++ b/src/crypto/dsa/dsa_asn1.c
@@ -73,7 +73,7 @@ static int dsa_sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
DSA_SIG *sig;
sig = OPENSSL_malloc(sizeof(DSA_SIG));
if (!sig) {
- OPENSSL_PUT_ERROR(DSA, dsa_sig_cb, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(DSA, ERR_R_MALLOC_FAILURE);
return 0;
}
diff --git a/src/crypto/dsa/dsa_impl.c b/src/crypto/dsa/dsa_impl.c
deleted file mode 100644
index 2ab8ba8..0000000
--- a/src/crypto/dsa/dsa_impl.c
+++ /dev/null
@@ -1,750 +0,0 @@
-/* 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.]
- *
- * The DSS routines are based on patches supplied by
- * Steven Schoch <schoch@sheba.arc.nasa.gov>. */
-
-#include <openssl/dsa.h>
-
-#include <string.h>
-
-#include <openssl/bn.h>
-#include <openssl/digest.h>
-#include <openssl/err.h>
-#include <openssl/rand.h>
-#include <openssl/sha.h>
-#include <openssl/thread.h>
-
-#include "internal.h"
-
-#define OPENSSL_DSA_MAX_MODULUS_BITS 10000
-
-/* Primality test according to FIPS PUB 186[-1], Appendix 2.1: 50 rounds of
- * Rabin-Miller */
-#define DSS_prime_checks 50
-
-static int sign_setup(const DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
- BIGNUM **rp, const uint8_t *digest, size_t digest_len) {
- BN_CTX *ctx;
- BIGNUM k, kq, *K, *kinv = NULL, *r = NULL;
- int ret = 0;
-
- if (!dsa->p || !dsa->q || !dsa->g) {
- OPENSSL_PUT_ERROR(DSA, sign_setup, DSA_R_MISSING_PARAMETERS);
- return 0;
- }
-
- BN_init(&k);
- BN_init(&kq);
-
- ctx = ctx_in;
- if (ctx == NULL) {
- ctx = BN_CTX_new();
- if (ctx == NULL) {
- goto err;
- }
- }
-
- r = BN_new();
- if (r == NULL) {
- goto err;
- }
-
- /* Get random k */
- do {
- /* If possible, we'll include the private key and message digest in the k
- * generation. The |digest| argument is only empty if |DSA_sign_setup| is
- * being used. */
- int ok;
-
- if (digest_len > 0) {
- ok = BN_generate_dsa_nonce(&k, dsa->q, dsa->priv_key, digest, digest_len,
- ctx);
- } else {
- ok = BN_rand_range(&k, dsa->q);
- }
- if (!ok) {
- goto err;
- }
- } while (BN_is_zero(&k));
-
- BN_set_flags(&k, BN_FLG_CONSTTIME);
-
- if (BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
- (CRYPTO_MUTEX *)&dsa->method_mont_p_lock, dsa->p,
- ctx) == NULL) {
- goto err;
- }
-
- /* Compute r = (g^k mod p) mod q */
- if (!BN_copy(&kq, &k)) {
- goto err;
- }
-
- /* We do not want timing information to leak the length of k,
- * so we compute g^k using an equivalent exponent of fixed length.
- *
- * (This is a kludge that we need because the BN_mod_exp_mont()
- * does not let us specify the desired timing behaviour.) */
-
- if (!BN_add(&kq, &kq, dsa->q)) {
- goto err;
- }
- if (BN_num_bits(&kq) <= BN_num_bits(dsa->q) && !BN_add(&kq, &kq, dsa->q)) {
- goto err;
- }
-
- K = &kq;
-
- if (!BN_mod_exp_mont(r, dsa->g, K, dsa->p, ctx, dsa->method_mont_p)) {
- goto err;
- }
- if (!BN_mod(r, r, dsa->q, ctx)) {
- goto err;
- }
-
- /* Compute part of 's = inv(k) (m + xr) mod q' */
- kinv = BN_mod_inverse(NULL, &k, dsa->q, ctx);
- if (kinv == NULL) {
- goto err;
- }
-
- BN_clear_free(*kinvp);
- *kinvp = kinv;
- kinv = NULL;
- BN_clear_free(*rp);
- *rp = r;
- ret = 1;
-
-err:
- if (!ret) {
- OPENSSL_PUT_ERROR(DSA, sign_setup, ERR_R_BN_LIB);
- if (r != NULL) {
- BN_clear_free(r);
- }
- }
-
- if (ctx_in == NULL) {
- BN_CTX_free(ctx);
- }
- BN_clear_free(&k);
- BN_clear_free(&kq);
- return ret;
-}
-
-static DSA_SIG *sign(const uint8_t *digest, size_t digest_len, DSA *dsa) {
- BIGNUM *kinv = NULL, *r = NULL, *s = NULL;
- BIGNUM m;
- BIGNUM xr;
- BN_CTX *ctx = NULL;
- int reason = ERR_R_BN_LIB;
- DSA_SIG *ret = NULL;
- int noredo = 0;
-
- BN_init(&m);
- BN_init(&xr);
-
- if (!dsa->p || !dsa->q || !dsa->g) {
- reason = DSA_R_MISSING_PARAMETERS;
- goto err;
- }
-
- s = BN_new();
- if (s == NULL) {
- goto err;
- }
- ctx = BN_CTX_new();
- if (ctx == NULL) {
- goto err;
- }
-
-redo:
- if (dsa->kinv == NULL || dsa->r == NULL) {
- if (!DSA_sign_setup(dsa, ctx, &kinv, &r)) {
- goto err;
- }
- } else {
- kinv = dsa->kinv;
- dsa->kinv = NULL;
- r = dsa->r;
- dsa->r = NULL;
- noredo = 1;
- }
-
- if (digest_len > BN_num_bytes(dsa->q)) {
- /* if the digest length is greater than the size of q use the
- * BN_num_bits(dsa->q) leftmost bits of the digest, see
- * fips 186-3, 4.2 */
- digest_len = BN_num_bytes(dsa->q);
- }
-
- if (BN_bin2bn(digest, digest_len, &m) == NULL) {
- goto err;
- }
-
- /* Compute s = inv(k) (m + xr) mod q */
- if (!BN_mod_mul(&xr, dsa->priv_key, r, dsa->q, ctx)) {
- goto err; /* s = xr */
- }
- if (!BN_add(s, &xr, &m)) {
- goto err; /* s = m + xr */
- }
- if (BN_cmp(s, dsa->q) > 0) {
- if (!BN_sub(s, s, dsa->q)) {
- goto err;
- }
- }
- if (!BN_mod_mul(s, s, kinv, dsa->q, ctx)) {
- 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)) {
- if (noredo) {
- reason = DSA_R_NEED_NEW_SETUP_VALUES;
- goto err;
- }
- goto redo;
- }
- ret->r = r;
- ret->s = s;
-
-err:
- if (!ret) {
- OPENSSL_PUT_ERROR(DSA, sign, reason);
- BN_free(r);
- BN_free(s);
- }
- BN_CTX_free(ctx);
- BN_clear_free(&m);
- BN_clear_free(&xr);
- BN_clear_free(kinv);
-
- return ret;
-}
-
-static int verify(int *out_valid, const uint8_t *dgst, size_t digest_len,
- DSA_SIG *sig, const DSA *dsa) {
- BN_CTX *ctx;
- BIGNUM u1, u2, t1;
- BN_MONT_CTX *mont = NULL;
- int ret = 0;
- unsigned i;
-
- *out_valid = 0;
-
- if (!dsa->p || !dsa->q || !dsa->g) {
- OPENSSL_PUT_ERROR(DSA, verify, DSA_R_MISSING_PARAMETERS);
- return 0;
- }
-
- i = BN_num_bits(dsa->q);
- /* fips 186-3 allows only different sizes for q */
- if (i != 160 && i != 224 && i != 256) {
- OPENSSL_PUT_ERROR(DSA, verify, DSA_R_BAD_Q_VALUE);
- return 0;
- }
-
- if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) {
- OPENSSL_PUT_ERROR(DSA, verify, DSA_R_MODULUS_TOO_LARGE);
- return 0;
- }
-
- BN_init(&u1);
- BN_init(&u2);
- BN_init(&t1);
-
- ctx = BN_CTX_new();
- if (ctx == NULL) {
- goto err;
- }
-
- if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
- BN_ucmp(sig->r, dsa->q) >= 0) {
- ret = 1;
- goto err;
- }
- if (BN_is_zero(sig->s) || BN_is_negative(sig->s) ||
- BN_ucmp(sig->s, dsa->q) >= 0) {
- ret = 1;
- goto err;
- }
-
- /* Calculate W = inv(S) mod Q
- * save W in u2 */
- if (BN_mod_inverse(&u2, sig->s, dsa->q, ctx) == NULL) {
- goto err;
- }
-
- /* save M in u1 */
- if (digest_len > (i >> 3)) {
- /* if the digest length is greater than the size of q use the
- * BN_num_bits(dsa->q) leftmost bits of the digest, see
- * fips 186-3, 4.2 */
- digest_len = (i >> 3);
- }
-
- if (BN_bin2bn(dgst, digest_len, &u1) == NULL) {
- goto err;
- }
-
- /* u1 = M * w mod q */
- if (!BN_mod_mul(&u1, &u1, &u2, dsa->q, ctx)) {
- goto err;
- }
-
- /* u2 = r * w mod q */
- if (!BN_mod_mul(&u2, sig->r, &u2, dsa->q, ctx)) {
- goto err;
- }
-
- mont = BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
- (CRYPTO_MUTEX *)&dsa->method_mont_p_lock,
- dsa->p, ctx);
- if (!mont) {
- goto err;
- }
-
- if (!BN_mod_exp2_mont(&t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, ctx,
- mont)) {
- goto err;
- }
-
- /* BN_copy(&u1,&t1); */
- /* let u1 = u1 mod q */
- if (!BN_mod(&u1, &t1, dsa->q, ctx)) {
- goto err;
- }
-
- /* V is now in u1. If the signature is correct, it will be
- * equal to R. */
- *out_valid = BN_ucmp(&u1, sig->r) == 0;
- ret = 1;
-
-err:
- if (ret != 1) {
- OPENSSL_PUT_ERROR(DSA, verify, ERR_R_BN_LIB);
- }
- BN_CTX_free(ctx);
- BN_free(&u1);
- BN_free(&u2);
- BN_free(&t1);
-
- return ret;
-}
-
-static int keygen(DSA *dsa) {
- int ok = 0;
- BN_CTX *ctx = NULL;
- BIGNUM *pub_key = NULL, *priv_key = NULL;
- BIGNUM prk;
-
- ctx = BN_CTX_new();
- if (ctx == NULL) {
- goto err;
- }
-
- priv_key = dsa->priv_key;
- if (priv_key == NULL) {
- priv_key = BN_new();
- if (priv_key == NULL) {
- goto err;
- }
- }
-
- do {
- if (!BN_rand_range(priv_key, dsa->q)) {
- goto err;
- }
- } while (BN_is_zero(priv_key));
-
- pub_key = dsa->pub_key;
- if (pub_key == NULL) {
- pub_key = BN_new();
- if (pub_key == NULL) {
- goto err;
- }
- }
-
- BN_init(&prk);
- BN_with_flags(&prk, priv_key, BN_FLG_CONSTTIME);
-
- if (!BN_mod_exp(pub_key, dsa->g, &prk, dsa->p, ctx)) {
- goto err;
- }
-
- dsa->priv_key = priv_key;
- dsa->pub_key = pub_key;
- ok = 1;
-
-err:
- if (dsa->pub_key == NULL) {
- BN_free(pub_key);
- }
- if (dsa->priv_key == NULL) {
- BN_free(priv_key);
- }
- BN_CTX_free(ctx);
-
- return ok;
-}
-
-static int paramgen(DSA *ret, unsigned bits, const uint8_t *seed_in,
- size_t seed_len, int *counter_ret, unsigned long *h_ret,
- BN_GENCB *cb) {
- int ok = 0;
- unsigned char seed[SHA256_DIGEST_LENGTH];
- unsigned char md[SHA256_DIGEST_LENGTH];
- unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH];
- BIGNUM *r0, *W, *X, *c, *test;
- BIGNUM *g = NULL, *q = NULL, *p = NULL;
- BN_MONT_CTX *mont = NULL;
- int k, n = 0, m = 0;
- unsigned i;
- int counter = 0;
- int r = 0;
- BN_CTX *ctx = NULL;
- unsigned int h = 2;
- unsigned qbits, qsize;
- const EVP_MD *evpmd;
-
- if (bits >= 2048) {
- qbits = 256;
- evpmd = EVP_sha256();
- } else {
- qbits = 160;
- evpmd = EVP_sha1();
- }
- qsize = qbits / 8;
-
- if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH &&
- qsize != SHA256_DIGEST_LENGTH) {
- /* invalid q size */
- return 0;
- }
-
- if (bits < 512) {
- bits = 512;
- }
-
- bits = (bits + 63) / 64 * 64;
-
- /* NB: seed_len == 0 is special case: copy generated seed to
- * seed_in if it is not NULL. */
- if (seed_len && (seed_len < (size_t)qsize)) {
- seed_in = NULL; /* seed buffer too small -- ignore */
- }
- if (seed_len > (size_t)qsize) {
- seed_len = qsize; /* App. 2.2 of FIPS PUB 186 allows larger SEED,
- * but our internal buffers are restricted to 160 bits*/
- }
- if (seed_in != NULL) {
- memcpy(seed, seed_in, seed_len);
- }
-
- ctx = BN_CTX_new();
- if (ctx == NULL) {
- goto err;
- }
- BN_CTX_start(ctx);
-
- mont = BN_MONT_CTX_new();
- if (mont == NULL) {
- goto err;
- }
-
- r0 = BN_CTX_get(ctx);
- g = BN_CTX_get(ctx);
- W = BN_CTX_get(ctx);
- q = BN_CTX_get(ctx);
- X = BN_CTX_get(ctx);
- c = BN_CTX_get(ctx);
- p = BN_CTX_get(ctx);
- test = BN_CTX_get(ctx);
-
- if (test == NULL || !BN_lshift(test, BN_value_one(), bits - 1)) {
- goto err;
- }
-
- for (;;) {
- /* Find q. */
- for (;;) {
- int seed_is_random;
-
- /* step 1 */
- if (!BN_GENCB_call(cb, 0, m++)) {
- goto err;
- }
-
- if (!seed_len) {
- if (!RAND_bytes(seed, qsize)) {
- goto err;
- }
- seed_is_random = 1;
- } else {
- seed_is_random = 0;
- seed_len = 0; /* use random seed if 'seed_in' turns out to be bad*/
- }
- memcpy(buf, seed, qsize);
- memcpy(buf2, seed, qsize);
- /* precompute "SEED + 1" for step 7: */
- for (i = qsize - 1; i < qsize; i--) {
- buf[i]++;
- if (buf[i] != 0) {
- break;
- }
- }
-
- /* step 2 */
- if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL) ||
- !EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL)) {
- goto err;
- }
- for (i = 0; i < qsize; i++) {
- md[i] ^= buf2[i];
- }
-
- /* step 3 */
- md[0] |= 0x80;
- md[qsize - 1] |= 0x01;
- if (!BN_bin2bn(md, qsize, q)) {
- goto err;
- }
-
- /* step 4 */
- r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, seed_is_random, cb);
- if (r > 0) {
- break;
- }
- if (r != 0) {
- goto err;
- }
-
- /* do a callback call */
- /* step 5 */
- }
-
- if (!BN_GENCB_call(cb, 2, 0) || !BN_GENCB_call(cb, 3, 0)) {
- goto err;
- }
-
- /* step 6 */
- counter = 0;
- /* "offset = 2" */
-
- n = (bits - 1) / 160;
-
- for (;;) {
- if ((counter != 0) && !BN_GENCB_call(cb, 0, counter)) {
- goto err;
- }
-
- /* step 7 */
- BN_zero(W);
- /* now 'buf' contains "SEED + offset - 1" */
- for (k = 0; k <= n; k++) {
- /* obtain "SEED + offset + k" by incrementing: */
- for (i = qsize - 1; i < qsize; i--) {
- buf[i]++;
- if (buf[i] != 0) {
- break;
- }
- }
-
- if (!EVP_Digest(buf, qsize, md, NULL, evpmd, NULL)) {
- goto err;
- }
-
- /* step 8 */
- if (!BN_bin2bn(md, qsize, r0) ||
- !BN_lshift(r0, r0, (qsize << 3) * k) ||
- !BN_add(W, W, r0)) {
- goto err;
- }
- }
-
- /* more of step 8 */
- if (!BN_mask_bits(W, bits - 1) ||
- !BN_copy(X, W) ||
- !BN_add(X, X, test)) {
- goto err;
- }
-
- /* step 9 */
- if (!BN_lshift1(r0, q) ||
- !BN_mod(c, X, r0, ctx) ||
- !BN_sub(r0, c, BN_value_one()) ||
- !BN_sub(p, X, r0)) {
- goto err;
- }
-
- /* step 10 */
- if (BN_cmp(p, test) >= 0) {
- /* step 11 */
- r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb);
- if (r > 0) {
- goto end; /* found it */
- }
- if (r != 0) {
- goto err;
- }
- }
-
- /* step 13 */
- counter++;
- /* "offset = offset + n + 1" */
-
- /* step 14 */
- if (counter >= 4096) {
- break;
- }
- }
- }
-end:
- if (!BN_GENCB_call(cb, 2, 1)) {
- goto err;
- }
-
- /* We now need to generate g */
- /* Set r0=(p-1)/q */
- if (!BN_sub(test, p, BN_value_one()) ||
- !BN_div(r0, NULL, test, q, ctx)) {
- goto err;
- }
-
- if (!BN_set_word(test, h) ||
- !BN_MONT_CTX_set(mont, p, ctx)) {
- goto err;
- }
-
- for (;;) {
- /* g=test^r0%p */
- if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont)) {
- goto err;
- }
- if (!BN_is_one(g)) {
- break;
- }
- if (!BN_add(test, test, BN_value_one())) {
- goto err;
- }
- h++;
- }
-
- if (!BN_GENCB_call(cb, 3, 1)) {
- goto err;
- }
-
- ok = 1;
-
-err:
- if (ok) {
- BN_free(ret->p);
- BN_free(ret->q);
- BN_free(ret->g);
- ret->p = BN_dup(p);
- ret->q = BN_dup(q);
- ret->g = BN_dup(g);
- if (ret->p == NULL || ret->q == NULL || ret->g == NULL) {
- ok = 0;
- goto err;
- }
- if (counter_ret != NULL) {
- *counter_ret = counter;
- }
- if (h_ret != NULL) {
- *h_ret = h;
- }
- }
-
- if (ctx) {
- BN_CTX_end(ctx);
- BN_CTX_free(ctx);
- }
-
- BN_MONT_CTX_free(mont);
-
- return ok;
-}
-
-static int finish(DSA *dsa) {
- BN_MONT_CTX_free(dsa->method_mont_p);
- dsa->method_mont_p = NULL;
- return 1;
-}
-
-const struct dsa_method DSA_default_method = {
- {
- 0 /* references */,
- 1 /* is_static */,
- },
- NULL /* app_data */,
-
- NULL /* init */,
- finish /* finish */,
-
- sign,
- sign_setup,
- verify,
-
- paramgen,
- keygen,
-};
diff --git a/src/crypto/ec/CMakeLists.txt b/src/crypto/ec/CMakeLists.txt
index b5ebefa..4749484 100644
--- a/src/crypto/ec/CMakeLists.txt
+++ b/src/crypto/ec/CMakeLists.txt
@@ -1,4 +1,12 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
+
+if (${ARCH} STREQUAL "x86_64")
+ set(
+ EC_ARCH_SOURCES
+
+ p256-x86_64-asm.${ASM_EXT}
+ )
+endif()
add_library(
ec
@@ -10,12 +18,18 @@ add_library(
ec_key.c
ec_montgomery.c
oct.c
+ p224-64.c
p256-64.c
- util-64.c
+ p256-x86_64.c
simple.c
+ util-64.c
wnaf.c
+
+ ${EC_ARCH_SOURCES}
)
+perlasm(p256-x86_64-asm.${ASM_EXT} asm/p256-x86_64-asm.pl)
+
add_executable(
example_mul
@@ -34,3 +48,4 @@ add_executable(
target_link_libraries(example_mul crypto)
target_link_libraries(ec_test crypto)
+add_dependencies(all_tests example_mul ec_test)
diff --git a/src/crypto/ec/asm/p256-x86_64-asm.pl b/src/crypto/ec/asm/p256-x86_64-asm.pl
new file mode 100644
index 0000000..361a84b
--- /dev/null
+++ b/src/crypto/ec/asm/p256-x86_64-asm.pl
@@ -0,0 +1,2725 @@
+#!/usr/bin/env perl
+
+# Copyright (c) 2014, Intel Corporation.
+#
+# 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.
+
+# Developers and authors:
+# Shay Gueron (1, 2), and Vlad Krasnov (1)
+# (1) Intel Corporation, Israel Development Center
+# (2) University of Haifa
+
+# Reference:
+# S.Gueron and V.Krasnov, "Fast Prime Field Elliptic Curve Cryptography with
+# 256 Bit Primes"
+
+# Further optimization by <appro@openssl.org>:
+#
+# this/original
+# Opteron +12-49%
+# Bulldozer +14-45%
+# P4 +18-46%
+# Westmere +12-34%
+# Sandy Bridge +9-35%
+# Ivy Bridge +9-35%
+# Haswell +8-37%
+# Broadwell +18-58%
+# Atom +15-50%
+# VIA Nano +43-160%
+#
+# Ranges denote minimum and maximum improvement coefficients depending
+# on benchmark.
+
+$flavour = shift;
+$output = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+
+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
+die "can't locate x86_64-xlate.pl";
+
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
+
+# TODO: enable these after testing. $avx goes to two and $addx to one.
+$avx=0;
+$addx=0;
+
+$code.=<<___;
+.text
+.extern OPENSSL_ia32cap_P
+
+# The polynomial
+.align 64
+.Lpoly:
+.quad 0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001
+
+.LOne:
+.long 1,1,1,1,1,1,1,1
+.LTwo:
+.long 2,2,2,2,2,2,2,2
+.LThree:
+.long 3,3,3,3,3,3,3,3
+.LONE_mont:
+.quad 0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe
+___
+
+{
+################################################################################
+# void ecp_nistz256_mul_by_2(uint64_t res[4], uint64_t a[4]);
+
+my ($a0,$a1,$a2,$a3)=map("%r$_",(8..11));
+my ($t0,$t1,$t2,$t3,$t4)=("%rax","%rdx","%rcx","%r12","%r13");
+my ($r_ptr,$a_ptr,$b_ptr)=("%rdi","%rsi","%rdx");
+
+$code.=<<___;
+
+.type ecp_nistz256_mul_by_2,\@function,2
+.align 64
+ecp_nistz256_mul_by_2:
+ push %r12
+ push %r13
+
+ mov 8*0($a_ptr), $a0
+ 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
+ lea .Lpoly(%rip), $a_ptr
+ mov $a0, $t0
+ adc $a2, $a2
+ adc $a3, $a3
+ mov $a1, $t1
+ sbb $t4, $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_mul_by_2,.-ecp_nistz256_mul_by_2
+
+################################################################################
+# void ecp_nistz256_neg(uint64_t res[4], uint64_t a[4]);
+.globl ecp_nistz256_neg
+.type ecp_nistz256_neg,\@function,2
+.align 32
+ecp_nistz256_neg:
+ push %r12
+ push %r13
+
+ xor $a0, $a0
+ xor $a1, $a1
+ xor $a2, $a2
+ xor $a3, $a3
+ xor $t4, $t4
+
+ sub 8*0($a_ptr), $a0
+ sbb 8*1($a_ptr), $a1
+ sbb 8*2($a_ptr), $a2
+ mov $a0, $t0
+ sbb 8*3($a_ptr), $a3
+ lea .Lpoly(%rip), $a_ptr
+ 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_neg,.-ecp_nistz256_neg
+___
+}
+{
+my ($r_ptr,$a_ptr,$b_org,$b_ptr)=("%rdi","%rsi","%rdx","%rbx");
+my ($acc0,$acc1,$acc2,$acc3,$acc4,$acc5,$acc6,$acc7)=map("%r$_",(8..15));
+my ($t0,$t1,$t2,$t3,$t4)=("%rcx","%rbp","%rbx","%rdx","%rax");
+my ($poly1,$poly3)=($acc6,$acc7);
+
+$code.=<<___;
+################################################################################
+# void ecp_nistz256_mul_mont(
+# uint64_t res[4],
+# uint64_t a[4],
+# uint64_t b[4]);
+
+.globl ecp_nistz256_mul_mont
+.type ecp_nistz256_mul_mont,\@function,3
+.align 32
+ecp_nistz256_mul_mont:
+___
+$code.=<<___ if ($addx);
+ mov \$0x80100, %ecx
+ and OPENSSL_ia32cap_P+8(%rip), %ecx
+___
+$code.=<<___;
+.Lmul_mont:
+ push %rbp
+ push %rbx
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+___
+$code.=<<___ if ($addx);
+ cmp \$0x80100, %ecx
+ je .Lmul_montx
+___
+$code.=<<___;
+ mov $b_org, $b_ptr
+ mov 8*0($b_org), %rax
+ mov 8*0($a_ptr), $acc1
+ mov 8*1($a_ptr), $acc2
+ mov 8*2($a_ptr), $acc3
+ mov 8*3($a_ptr), $acc4
+
+ call __ecp_nistz256_mul_montq
+___
+$code.=<<___ if ($addx);
+ jmp .Lmul_mont_done
+
+.align 32
+.Lmul_montx:
+ mov $b_org, $b_ptr
+ mov 8*0($b_org), %rdx
+ mov 8*0($a_ptr), $acc1
+ mov 8*1($a_ptr), $acc2
+ mov 8*2($a_ptr), $acc3
+ mov 8*3($a_ptr), $acc4
+ lea -128($a_ptr), $a_ptr # control u-op density
+
+ call __ecp_nistz256_mul_montx
+___
+$code.=<<___;
+.Lmul_mont_done:
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbx
+ pop %rbp
+ ret
+.size ecp_nistz256_mul_mont,.-ecp_nistz256_mul_mont
+
+.type __ecp_nistz256_mul_montq,\@abi-omnipotent
+.align 32
+__ecp_nistz256_mul_montq:
+ ########################################################################
+ # Multiply a by b[0]
+ mov %rax, $t1
+ mulq $acc1
+ mov .Lpoly+8*1(%rip),$poly1
+ mov %rax, $acc0
+ mov $t1, %rax
+ mov %rdx, $acc1
+
+ mulq $acc2
+ mov .Lpoly+8*3(%rip),$poly3
+ add %rax, $acc1
+ mov $t1, %rax
+ adc \$0, %rdx
+ mov %rdx, $acc2
+
+ mulq $acc3
+ add %rax, $acc2
+ mov $t1, %rax
+ adc \$0, %rdx
+ mov %rdx, $acc3
+
+ mulq $acc4
+ add %rax, $acc3
+ mov $acc0, %rax
+ adc \$0, %rdx
+ xor $acc5, $acc5
+ mov %rdx, $acc4
+
+ ########################################################################
+ # First reduction step
+ # Basically now we want to multiply acc[0] by p256,
+ # and add the result to the acc.
+ # Due to the special form of p256 we do some optimizations
+ #
+ # acc[0] x p256[0..1] = acc[0] x 2^96 - acc[0]
+ # then we add acc[0] and get acc[0] x 2^96
+
+ mov $acc0, $t1
+ shl \$32, $acc0
+ mulq $poly3
+ shr \$32, $t1
+ add $acc0, $acc1 # +=acc[0]<<96
+ adc $t1, $acc2
+ adc %rax, $acc3
+ mov 8*1($b_ptr), %rax
+ adc %rdx, $acc4
+ adc \$0, $acc5
+ xor $acc0, $acc0
+
+ ########################################################################
+ # Multiply by b[1]
+ mov %rax, $t1
+ mulq 8*0($a_ptr)
+ add %rax, $acc1
+ mov $t1, %rax
+ adc \$0, %rdx
+ mov %rdx, $t0
+
+ mulq 8*1($a_ptr)
+ add $t0, $acc2
+ adc \$0, %rdx
+ add %rax, $acc2
+ mov $t1, %rax
+ adc \$0, %rdx
+ mov %rdx, $t0
+
+ mulq 8*2($a_ptr)
+ add $t0, $acc3
+ adc \$0, %rdx
+ add %rax, $acc3
+ mov $t1, %rax
+ adc \$0, %rdx
+ mov %rdx, $t0
+
+ mulq 8*3($a_ptr)
+ add $t0, $acc4
+ adc \$0, %rdx
+ add %rax, $acc4
+ mov $acc1, %rax
+ adc %rdx, $acc5
+ adc \$0, $acc0
+
+ ########################################################################
+ # Second reduction step
+ mov $acc1, $t1
+ shl \$32, $acc1
+ mulq $poly3
+ shr \$32, $t1
+ add $acc1, $acc2
+ adc $t1, $acc3
+ adc %rax, $acc4
+ mov 8*2($b_ptr), %rax
+ adc %rdx, $acc5
+ adc \$0, $acc0
+ xor $acc1, $acc1
+
+ ########################################################################
+ # Multiply by b[2]
+ mov %rax, $t1
+ mulq 8*0($a_ptr)
+ add %rax, $acc2
+ mov $t1, %rax
+ adc \$0, %rdx
+ mov %rdx, $t0
+
+ mulq 8*1($a_ptr)
+ add $t0, $acc3
+ adc \$0, %rdx
+ add %rax, $acc3
+ mov $t1, %rax
+ adc \$0, %rdx
+ mov %rdx, $t0
+
+ mulq 8*2($a_ptr)
+ add $t0, $acc4
+ adc \$0, %rdx
+ add %rax, $acc4
+ mov $t1, %rax
+ adc \$0, %rdx
+ mov %rdx, $t0
+
+ mulq 8*3($a_ptr)
+ add $t0, $acc5
+ adc \$0, %rdx
+ add %rax, $acc5
+ mov $acc2, %rax
+ adc %rdx, $acc0
+ adc \$0, $acc1
+
+ ########################################################################
+ # Third reduction step
+ mov $acc2, $t1
+ shl \$32, $acc2
+ mulq $poly3
+ shr \$32, $t1
+ add $acc2, $acc3
+ adc $t1, $acc4
+ adc %rax, $acc5
+ mov 8*3($b_ptr), %rax
+ adc %rdx, $acc0
+ adc \$0, $acc1
+ xor $acc2, $acc2
+
+ ########################################################################
+ # Multiply by b[3]
+ mov %rax, $t1
+ mulq 8*0($a_ptr)
+ add %rax, $acc3
+ mov $t1, %rax
+ adc \$0, %rdx
+ mov %rdx, $t0
+
+ mulq 8*1($a_ptr)
+ add $t0, $acc4
+ adc \$0, %rdx
+ add %rax, $acc4
+ mov $t1, %rax
+ adc \$0, %rdx
+ mov %rdx, $t0
+
+ mulq 8*2($a_ptr)
+ add $t0, $acc5
+ adc \$0, %rdx
+ add %rax, $acc5
+ mov $t1, %rax
+ adc \$0, %rdx
+ mov %rdx, $t0
+
+ mulq 8*3($a_ptr)
+ add $t0, $acc0
+ adc \$0, %rdx
+ add %rax, $acc0
+ mov $acc3, %rax
+ adc %rdx, $acc1
+ adc \$0, $acc2
+
+ ########################################################################
+ # Final reduction step
+ mov $acc3, $t1
+ shl \$32, $acc3
+ mulq $poly3
+ shr \$32, $t1
+ add $acc3, $acc4
+ adc $t1, $acc5
+ mov $acc4, $t0
+ adc %rax, $acc0
+ adc %rdx, $acc1
+ mov $acc5, $t1
+ adc \$0, $acc2
+
+ ########################################################################
+ # Branch-less conditional subtraction of P
+ sub \$-1, $acc4 # .Lpoly[0]
+ mov $acc0, $t2
+ sbb $poly1, $acc5 # .Lpoly[1]
+ sbb \$0, $acc0 # .Lpoly[2]
+ mov $acc1, $t3
+ sbb $poly3, $acc1 # .Lpoly[3]
+ sbb \$0, $acc2
+
+ cmovc $t0, $acc4
+ cmovc $t1, $acc5
+ mov $acc4, 8*0($r_ptr)
+ cmovc $t2, $acc0
+ mov $acc5, 8*1($r_ptr)
+ cmovc $t3, $acc1
+ mov $acc0, 8*2($r_ptr)
+ mov $acc1, 8*3($r_ptr)
+
+ ret
+.size __ecp_nistz256_mul_montq,.-__ecp_nistz256_mul_montq
+
+################################################################################
+# void ecp_nistz256_sqr_mont(
+# uint64_t res[4],
+# uint64_t a[4]);
+
+# we optimize the square according to S.Gueron and V.Krasnov,
+# "Speeding up Big-Number Squaring"
+.globl ecp_nistz256_sqr_mont
+.type ecp_nistz256_sqr_mont,\@function,2
+.align 32
+ecp_nistz256_sqr_mont:
+___
+$code.=<<___ if ($addx);
+ mov \$0x80100, %ecx
+ and OPENSSL_ia32cap_P+8(%rip), %ecx
+___
+$code.=<<___;
+ push %rbp
+ push %rbx
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+___
+$code.=<<___ if ($addx);
+ cmp \$0x80100, %ecx
+ je .Lsqr_montx
+___
+$code.=<<___;
+ mov 8*0($a_ptr), %rax
+ mov 8*1($a_ptr), $acc6
+ mov 8*2($a_ptr), $acc7
+ mov 8*3($a_ptr), $acc0
+
+ call __ecp_nistz256_sqr_montq
+___
+$code.=<<___ if ($addx);
+ jmp .Lsqr_mont_done
+
+.align 32
+.Lsqr_montx:
+ mov 8*0($a_ptr), %rdx
+ mov 8*1($a_ptr), $acc6
+ mov 8*2($a_ptr), $acc7
+ mov 8*3($a_ptr), $acc0
+ lea -128($a_ptr), $a_ptr # control u-op density
+
+ call __ecp_nistz256_sqr_montx
+___
+$code.=<<___;
+.Lsqr_mont_done:
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbx
+ pop %rbp
+ ret
+.size ecp_nistz256_sqr_mont,.-ecp_nistz256_sqr_mont
+
+.type __ecp_nistz256_sqr_montq,\@abi-omnipotent
+.align 32
+__ecp_nistz256_sqr_montq:
+ mov %rax, $acc5
+ mulq $acc6 # a[1]*a[0]
+ mov %rax, $acc1
+ mov $acc7, %rax
+ mov %rdx, $acc2
+
+ mulq $acc5 # a[0]*a[2]
+ add %rax, $acc2
+ mov $acc0, %rax
+ adc \$0, %rdx
+ mov %rdx, $acc3
+
+ mulq $acc5 # a[0]*a[3]
+ add %rax, $acc3
+ mov $acc7, %rax
+ adc \$0, %rdx
+ mov %rdx, $acc4
+
+ #################################
+ mulq $acc6 # a[1]*a[2]
+ add %rax, $acc3
+ mov $acc0, %rax
+ adc \$0, %rdx
+ mov %rdx, $t1
+
+ mulq $acc6 # a[1]*a[3]
+ add %rax, $acc4
+ mov $acc0, %rax
+ adc \$0, %rdx
+ add $t1, $acc4
+ mov %rdx, $acc5
+ adc \$0, $acc5
+
+ #################################
+ mulq $acc7 # a[2]*a[3]
+ xor $acc7, $acc7
+ add %rax, $acc5
+ mov 8*0($a_ptr), %rax
+ mov %rdx, $acc6
+ adc \$0, $acc6
+
+ add $acc1, $acc1 # acc1:6<<1
+ adc $acc2, $acc2
+ adc $acc3, $acc3
+ adc $acc4, $acc4
+ adc $acc5, $acc5
+ adc $acc6, $acc6
+ adc \$0, $acc7
+
+ mulq %rax
+ mov %rax, $acc0
+ mov 8*1($a_ptr), %rax
+ mov %rdx, $t0
+
+ mulq %rax
+ add $t0, $acc1
+ adc %rax, $acc2
+ mov 8*2($a_ptr), %rax
+ adc \$0, %rdx
+ mov %rdx, $t0
+
+ mulq %rax
+ add $t0, $acc3
+ adc %rax, $acc4
+ mov 8*3($a_ptr), %rax
+ adc \$0, %rdx
+ mov %rdx, $t0
+
+ mulq %rax
+ add $t0, $acc5
+ adc %rax, $acc6
+ mov $acc0, %rax
+ adc %rdx, $acc7
+
+ mov .Lpoly+8*1(%rip), $a_ptr
+ mov .Lpoly+8*3(%rip), $t1
+
+ ##########################################
+ # Now the reduction
+ # First iteration
+ mov $acc0, $t0
+ shl \$32, $acc0
+ mulq $t1
+ shr \$32, $t0
+ add $acc0, $acc1 # +=acc[0]<<96
+ adc $t0, $acc2
+ adc %rax, $acc3
+ mov $acc1, %rax
+ adc \$0, %rdx
+
+ ##########################################
+ # Second iteration
+ mov $acc1, $t0
+ shl \$32, $acc1
+ mov %rdx, $acc0
+ mulq $t1
+ shr \$32, $t0
+ add $acc1, $acc2
+ adc $t0, $acc3
+ adc %rax, $acc0
+ mov $acc2, %rax
+ adc \$0, %rdx
+
+ ##########################################
+ # Third iteration
+ mov $acc2, $t0
+ shl \$32, $acc2
+ mov %rdx, $acc1
+ mulq $t1
+ shr \$32, $t0
+ add $acc2, $acc3
+ adc $t0, $acc0
+ adc %rax, $acc1
+ mov $acc3, %rax
+ adc \$0, %rdx
+
+ ###########################################
+ # Last iteration
+ mov $acc3, $t0
+ shl \$32, $acc3
+ mov %rdx, $acc2
+ mulq $t1
+ shr \$32, $t0
+ add $acc3, $acc0
+ adc $t0, $acc1
+ adc %rax, $acc2
+ adc \$0, %rdx
+ xor $acc3, $acc3
+
+ ############################################
+ # Add the rest of the acc
+ add $acc0, $acc4
+ adc $acc1, $acc5
+ mov $acc4, $acc0
+ adc $acc2, $acc6
+ adc %rdx, $acc7
+ mov $acc5, $acc1
+ adc \$0, $acc3
+
+ sub \$-1, $acc4 # .Lpoly[0]
+ mov $acc6, $acc2
+ sbb $a_ptr, $acc5 # .Lpoly[1]
+ sbb \$0, $acc6 # .Lpoly[2]
+ mov $acc7, $t0
+ sbb $t1, $acc7 # .Lpoly[3]
+ sbb \$0, $acc3
+
+ cmovc $acc0, $acc4
+ cmovc $acc1, $acc5
+ mov $acc4, 8*0($r_ptr)
+ cmovc $acc2, $acc6
+ mov $acc5, 8*1($r_ptr)
+ cmovc $t0, $acc7
+ mov $acc6, 8*2($r_ptr)
+ mov $acc7, 8*3($r_ptr)
+
+ ret
+.size __ecp_nistz256_sqr_montq,.-__ecp_nistz256_sqr_montq
+___
+
+if ($addx) {
+$code.=<<___;
+.type __ecp_nistz256_mul_montx,\@abi-omnipotent
+.align 32
+__ecp_nistz256_mul_montx:
+ ########################################################################
+ # Multiply by b[0]
+ mulx $acc1, $acc0, $acc1
+ mulx $acc2, $t0, $acc2
+ mov \$32, $poly1
+ xor $acc5, $acc5 # cf=0
+ mulx $acc3, $t1, $acc3
+ mov .Lpoly+8*3(%rip), $poly3
+ adc $t0, $acc1
+ mulx $acc4, $t0, $acc4
+ mov $acc0, %rdx
+ adc $t1, $acc2
+ shlx $poly1,$acc0,$t1
+ adc $t0, $acc3
+ shrx $poly1,$acc0,$t0
+ adc \$0, $acc4
+
+ ########################################################################
+ # First reduction step
+ add $t1, $acc1
+ adc $t0, $acc2
+
+ mulx $poly3, $t0, $t1
+ mov 8*1($b_ptr), %rdx
+ adc $t0, $acc3
+ adc $t1, $acc4
+ adc \$0, $acc5
+ xor $acc0, $acc0 # $acc0=0,cf=0,of=0
+
+ ########################################################################
+ # Multiply by b[1]
+ mulx 8*0+128($a_ptr), $t0, $t1
+ adcx $t0, $acc1
+ adox $t1, $acc2
+
+ mulx 8*1+128($a_ptr), $t0, $t1
+ adcx $t0, $acc2
+ adox $t1, $acc3
+
+ mulx 8*2+128($a_ptr), $t0, $t1
+ adcx $t0, $acc3
+ adox $t1, $acc4
+
+ mulx 8*3+128($a_ptr), $t0, $t1
+ mov $acc1, %rdx
+ adcx $t0, $acc4
+ shlx $poly1, $acc1, $t0
+ adox $t1, $acc5
+ shrx $poly1, $acc1, $t1
+
+ adcx $acc0, $acc5
+ adox $acc0, $acc0
+ adc \$0, $acc0
+
+ ########################################################################
+ # Second reduction step
+ add $t0, $acc2
+ adc $t1, $acc3
+
+ mulx $poly3, $t0, $t1
+ mov 8*2($b_ptr), %rdx
+ adc $t0, $acc4
+ adc $t1, $acc5
+ adc \$0, $acc0
+ xor $acc1 ,$acc1 # $acc1=0,cf=0,of=0
+
+ ########################################################################
+ # Multiply by b[2]
+ mulx 8*0+128($a_ptr), $t0, $t1
+ adcx $t0, $acc2
+ adox $t1, $acc3
+
+ mulx 8*1+128($a_ptr), $t0, $t1
+ adcx $t0, $acc3
+ adox $t1, $acc4
+
+ mulx 8*2+128($a_ptr), $t0, $t1
+ adcx $t0, $acc4
+ adox $t1, $acc5
+
+ mulx 8*3+128($a_ptr), $t0, $t1
+ mov $acc2, %rdx
+ adcx $t0, $acc5
+ shlx $poly1, $acc2, $t0
+ adox $t1, $acc0
+ shrx $poly1, $acc2, $t1
+
+ adcx $acc1, $acc0
+ adox $acc1, $acc1
+ adc \$0, $acc1
+
+ ########################################################################
+ # Third reduction step
+ add $t0, $acc3
+ adc $t1, $acc4
+
+ mulx $poly3, $t0, $t1
+ mov 8*3($b_ptr), %rdx
+ adc $t0, $acc5
+ adc $t1, $acc0
+ adc \$0, $acc1
+ xor $acc2, $acc2 # $acc2=0,cf=0,of=0
+
+ ########################################################################
+ # Multiply by b[3]
+ mulx 8*0+128($a_ptr), $t0, $t1
+ adcx $t0, $acc3
+ adox $t1, $acc4
+
+ mulx 8*1+128($a_ptr), $t0, $t1
+ adcx $t0, $acc4
+ adox $t1, $acc5
+
+ mulx 8*2+128($a_ptr), $t0, $t1
+ adcx $t0, $acc5
+ adox $t1, $acc0
+
+ mulx 8*3+128($a_ptr), $t0, $t1
+ mov $acc3, %rdx
+ adcx $t0, $acc0
+ shlx $poly1, $acc3, $t0
+ adox $t1, $acc1
+ shrx $poly1, $acc3, $t1
+
+ adcx $acc2, $acc1
+ adox $acc2, $acc2
+ adc \$0, $acc2
+
+ ########################################################################
+ # Fourth reduction step
+ add $t0, $acc4
+ adc $t1, $acc5
+
+ mulx $poly3, $t0, $t1
+ mov $acc4, $t2
+ mov .Lpoly+8*1(%rip), $poly1
+ adc $t0, $acc0
+ mov $acc5, $t3
+ adc $t1, $acc1
+ adc \$0, $acc2
+
+ ########################################################################
+ # Branch-less conditional subtraction of P
+ xor %eax, %eax
+ mov $acc0, $t0
+ sbb \$-1, $acc4 # .Lpoly[0]
+ sbb $poly1, $acc5 # .Lpoly[1]
+ sbb \$0, $acc0 # .Lpoly[2]
+ mov $acc1, $t1
+ sbb $poly3, $acc1 # .Lpoly[3]
+ sbb \$0, $acc2
+
+ cmovc $t2, $acc4
+ cmovc $t3, $acc5
+ mov $acc4, 8*0($r_ptr)
+ cmovc $t0, $acc0
+ mov $acc5, 8*1($r_ptr)
+ cmovc $t1, $acc1
+ mov $acc0, 8*2($r_ptr)
+ mov $acc1, 8*3($r_ptr)
+
+ ret
+.size __ecp_nistz256_mul_montx,.-__ecp_nistz256_mul_montx
+
+.type __ecp_nistz256_sqr_montx,\@abi-omnipotent
+.align 32
+__ecp_nistz256_sqr_montx:
+ mulx $acc6, $acc1, $acc2 # a[0]*a[1]
+ mulx $acc7, $t0, $acc3 # a[0]*a[2]
+ xor %eax, %eax
+ adc $t0, $acc2
+ mulx $acc0, $t1, $acc4 # a[0]*a[3]
+ mov $acc6, %rdx
+ adc $t1, $acc3
+ adc \$0, $acc4
+ xor $acc5, $acc5 # $acc5=0,cf=0,of=0
+
+ #################################
+ mulx $acc7, $t0, $t1 # a[1]*a[2]
+ adcx $t0, $acc3
+ adox $t1, $acc4
+
+ mulx $acc0, $t0, $t1 # a[1]*a[3]
+ mov $acc7, %rdx
+ adcx $t0, $acc4
+ adox $t1, $acc5
+ adc \$0, $acc5
+
+ #################################
+ mulx $acc0, $t0, $acc6 # a[2]*a[3]
+ mov 8*0+128($a_ptr), %rdx
+ xor $acc7, $acc7 # $acc7=0,cf=0,of=0
+ adcx $acc1, $acc1 # acc1:6<<1
+ adox $t0, $acc5
+ adcx $acc2, $acc2
+ adox $acc7, $acc6 # of=0
+
+ mulx %rdx, $acc0, $t1
+ mov 8*1+128($a_ptr), %rdx
+ adcx $acc3, $acc3
+ adox $t1, $acc1
+ adcx $acc4, $acc4
+ mulx %rdx, $t0, $t4
+ mov 8*2+128($a_ptr), %rdx
+ adcx $acc5, $acc5
+ adox $t0, $acc2
+ adcx $acc6, $acc6
+ .byte 0x67
+ mulx %rdx, $t0, $t1
+ mov 8*3+128($a_ptr), %rdx
+ adox $t4, $acc3
+ adcx $acc7, $acc7
+ adox $t0, $acc4
+ mov \$32, $a_ptr
+ adox $t1, $acc5
+ .byte 0x67,0x67
+ mulx %rdx, $t0, $t4
+ mov $acc0, %rdx
+ adox $t0, $acc6
+ shlx $a_ptr, $acc0, $t0
+ adox $t4, $acc7
+ shrx $a_ptr, $acc0, $t4
+ mov .Lpoly+8*3(%rip), $t1
+
+ # reduction step 1
+ add $t0, $acc1
+ adc $t4, $acc2
+
+ mulx $t1, $t0, $acc0
+ mov $acc1, %rdx
+ adc $t0, $acc3
+ shlx $a_ptr, $acc1, $t0
+ adc \$0, $acc0
+ shrx $a_ptr, $acc1, $t4
+
+ # reduction step 2
+ add $t0, $acc2
+ adc $t4, $acc3
+
+ mulx $t1, $t0, $acc1
+ mov $acc2, %rdx
+ adc $t0, $acc0
+ shlx $a_ptr, $acc2, $t0
+ adc \$0, $acc1
+ shrx $a_ptr, $acc2, $t4
+
+ # reduction step 3
+ add $t0, $acc3
+ adc $t4, $acc0
+
+ mulx $t1, $t0, $acc2
+ mov $acc3, %rdx
+ adc $t0, $acc1
+ shlx $a_ptr, $acc3, $t0
+ adc \$0, $acc2
+ shrx $a_ptr, $acc3, $t4
+
+ # reduction step 4
+ add $t0, $acc0
+ adc $t4, $acc1
+
+ mulx $t1, $t0, $acc3
+ adc $t0, $acc2
+ adc \$0, $acc3
+
+ xor $t3, $t3 # cf=0
+ adc $acc0, $acc4 # accumulate upper half
+ mov .Lpoly+8*1(%rip), $a_ptr
+ adc $acc1, $acc5
+ mov $acc4, $acc0
+ adc $acc2, $acc6
+ adc $acc3, $acc7
+ mov $acc5, $acc1
+ adc \$0, $t3
+
+ xor %eax, %eax # cf=0
+ sbb \$-1, $acc4 # .Lpoly[0]
+ mov $acc6, $acc2
+ sbb $a_ptr, $acc5 # .Lpoly[1]
+ sbb \$0, $acc6 # .Lpoly[2]
+ mov $acc7, $acc3
+ sbb $t1, $acc7 # .Lpoly[3]
+ sbb \$0, $t3
+
+ cmovc $acc0, $acc4
+ cmovc $acc1, $acc5
+ mov $acc4, 8*0($r_ptr)
+ cmovc $acc2, $acc6
+ mov $acc5, 8*1($r_ptr)
+ cmovc $acc3, $acc7
+ mov $acc6, 8*2($r_ptr)
+ mov $acc7, 8*3($r_ptr)
+
+ ret
+.size __ecp_nistz256_sqr_montx,.-__ecp_nistz256_sqr_montx
+___
+}
+}
+{
+my ($r_ptr,$in_ptr)=("%rdi","%rsi");
+my ($acc0,$acc1,$acc2,$acc3)=map("%r$_",(8..11));
+my ($t0,$t1,$t2)=("%rcx","%r12","%r13");
+
+$code.=<<___;
+################################################################################
+# void ecp_nistz256_from_mont(
+# uint64_t res[4],
+# uint64_t in[4]);
+# This one performs Montgomery multiplication by 1, so we only need the reduction
+
+.globl ecp_nistz256_from_mont
+.type ecp_nistz256_from_mont,\@function,2
+.align 32
+ecp_nistz256_from_mont:
+ push %r12
+ push %r13
+
+ mov 8*0($in_ptr), %rax
+ mov .Lpoly+8*3(%rip), $t2
+ mov 8*1($in_ptr), $acc1
+ mov 8*2($in_ptr), $acc2
+ mov 8*3($in_ptr), $acc3
+ mov %rax, $acc0
+ mov .Lpoly+8*1(%rip), $t1
+
+ #########################################
+ # First iteration
+ mov %rax, $t0
+ shl \$32, $acc0
+ mulq $t2
+ shr \$32, $t0
+ add $acc0, $acc1
+ adc $t0, $acc2
+ adc %rax, $acc3
+ mov $acc1, %rax
+ adc \$0, %rdx
+
+ #########################################
+ # Second iteration
+ mov $acc1, $t0
+ shl \$32, $acc1
+ mov %rdx, $acc0
+ mulq $t2
+ shr \$32, $t0
+ add $acc1, $acc2
+ adc $t0, $acc3
+ adc %rax, $acc0
+ mov $acc2, %rax
+ adc \$0, %rdx
+
+ ##########################################
+ # Third iteration
+ mov $acc2, $t0
+ shl \$32, $acc2
+ mov %rdx, $acc1
+ mulq $t2
+ shr \$32, $t0
+ add $acc2, $acc3
+ adc $t0, $acc0
+ adc %rax, $acc1
+ mov $acc3, %rax
+ adc \$0, %rdx
+
+ ###########################################
+ # Last iteration
+ mov $acc3, $t0
+ shl \$32, $acc3
+ mov %rdx, $acc2
+ mulq $t2
+ shr \$32, $t0
+ add $acc3, $acc0
+ adc $t0, $acc1
+ mov $acc0, $t0
+ adc %rax, $acc2
+ mov $acc1, $in_ptr
+ adc \$0, %rdx
+
+ sub \$-1, $acc0
+ mov $acc2, %rax
+ sbb $t1, $acc1
+ sbb \$0, $acc2
+ mov %rdx, $acc3
+ sbb $t2, %rdx
+ sbb $t2, $t2
+
+ cmovnz $t0, $acc0
+ cmovnz $in_ptr, $acc1
+ mov $acc0, 8*0($r_ptr)
+ cmovnz %rax, $acc2
+ mov $acc1, 8*1($r_ptr)
+ cmovz %rdx, $acc3
+ mov $acc2, 8*2($r_ptr)
+ mov $acc3, 8*3($r_ptr)
+
+ pop %r13
+ pop %r12
+ ret
+.size ecp_nistz256_from_mont,.-ecp_nistz256_from_mont
+___
+}
+{
+my ($val,$in_t,$index)=$win64?("%rcx","%rdx","%r8d"):("%rdi","%rsi","%edx");
+my ($ONE,$INDEX,$Ra,$Rb,$Rc,$Rd,$Re,$Rf)=map("%xmm$_",(0..7));
+my ($M0,$T0a,$T0b,$T0c,$T0d,$T0e,$T0f,$TMP0)=map("%xmm$_",(8..15));
+my ($M1,$T2a,$T2b,$TMP2,$M2,$T2a,$T2b,$TMP2)=map("%xmm$_",(8..15));
+
+$code.=<<___;
+################################################################################
+# void ecp_nistz256_select_w5(uint64_t *val, uint64_t *in_t, int index);
+.globl ecp_nistz256_select_w5
+.type ecp_nistz256_select_w5,\@abi-omnipotent
+.align 32
+ecp_nistz256_select_w5:
+___
+$code.=<<___ if ($avx>1);
+ mov OPENSSL_ia32cap_P+8(%rip), %eax
+ test \$`1<<5`, %eax
+ jnz .Lavx2_select_w5
+___
+$code.=<<___ if ($win64);
+ lea -0x88(%rsp), %rax
+.LSEH_begin_ecp_nistz256_select_w5:
+ .byte 0x48,0x8d,0x60,0xe0 #lea -0x20(%rax), %rsp
+ .byte 0x0f,0x29,0x70,0xe0 #movaps %xmm6, -0x20(%rax)
+ .byte 0x0f,0x29,0x78,0xf0 #movaps %xmm7, -0x10(%rax)
+ .byte 0x44,0x0f,0x29,0x00 #movaps %xmm8, 0(%rax)
+ .byte 0x44,0x0f,0x29,0x48,0x10 #movaps %xmm9, 0x10(%rax)
+ .byte 0x44,0x0f,0x29,0x50,0x20 #movaps %xmm10, 0x20(%rax)
+ .byte 0x44,0x0f,0x29,0x58,0x30 #movaps %xmm11, 0x30(%rax)
+ .byte 0x44,0x0f,0x29,0x60,0x40 #movaps %xmm12, 0x40(%rax)
+ .byte 0x44,0x0f,0x29,0x68,0x50 #movaps %xmm13, 0x50(%rax)
+ .byte 0x44,0x0f,0x29,0x70,0x60 #movaps %xmm14, 0x60(%rax)
+ .byte 0x44,0x0f,0x29,0x78,0x70 #movaps %xmm15, 0x70(%rax)
+___
+$code.=<<___;
+ movdqa .LOne(%rip), $ONE
+ movd $index, $INDEX
+
+ pxor $Ra, $Ra
+ pxor $Rb, $Rb
+ pxor $Rc, $Rc
+ pxor $Rd, $Rd
+ pxor $Re, $Re
+ pxor $Rf, $Rf
+
+ movdqa $ONE, $M0
+ pshufd \$0, $INDEX, $INDEX
+
+ mov \$16, %rax
+.Lselect_loop_sse_w5:
+
+ movdqa $M0, $TMP0
+ paddd $ONE, $M0
+ pcmpeqd $INDEX, $TMP0
+
+ movdqa 16*0($in_t), $T0a
+ movdqa 16*1($in_t), $T0b
+ movdqa 16*2($in_t), $T0c
+ movdqa 16*3($in_t), $T0d
+ movdqa 16*4($in_t), $T0e
+ movdqa 16*5($in_t), $T0f
+ lea 16*6($in_t), $in_t
+
+ pand $TMP0, $T0a
+ pand $TMP0, $T0b
+ por $T0a, $Ra
+ pand $TMP0, $T0c
+ por $T0b, $Rb
+ pand $TMP0, $T0d
+ por $T0c, $Rc
+ pand $TMP0, $T0e
+ por $T0d, $Rd
+ pand $TMP0, $T0f
+ por $T0e, $Re
+ por $T0f, $Rf
+
+ dec %rax
+ jnz .Lselect_loop_sse_w5
+
+ movdqu $Ra, 16*0($val)
+ movdqu $Rb, 16*1($val)
+ movdqu $Rc, 16*2($val)
+ movdqu $Rd, 16*3($val)
+ movdqu $Re, 16*4($val)
+ movdqu $Rf, 16*5($val)
+___
+$code.=<<___ if ($win64);
+ movaps (%rsp), %xmm6
+ movaps 0x10(%rsp), %xmm7
+ movaps 0x20(%rsp), %xmm8
+ movaps 0x30(%rsp), %xmm9
+ movaps 0x40(%rsp), %xmm10
+ movaps 0x50(%rsp), %xmm11
+ movaps 0x60(%rsp), %xmm12
+ movaps 0x70(%rsp), %xmm13
+ movaps 0x80(%rsp), %xmm14
+ movaps 0x90(%rsp), %xmm15
+ lea 0xa8(%rsp), %rsp
+.LSEH_end_ecp_nistz256_select_w5:
+___
+$code.=<<___;
+ ret
+.size ecp_nistz256_select_w5,.-ecp_nistz256_select_w5
+
+################################################################################
+# void ecp_nistz256_select_w7(uint64_t *val, uint64_t *in_t, int index);
+.globl ecp_nistz256_select_w7
+.type ecp_nistz256_select_w7,\@abi-omnipotent
+.align 32
+ecp_nistz256_select_w7:
+___
+$code.=<<___ if ($avx>1);
+ mov OPENSSL_ia32cap_P+8(%rip), %eax
+ test \$`1<<5`, %eax
+ jnz .Lavx2_select_w7
+___
+$code.=<<___ if ($win64);
+ lea -0x88(%rsp), %rax
+.LSEH_begin_ecp_nistz256_select_w7:
+ .byte 0x48,0x8d,0x60,0xe0 #lea -0x20(%rax), %rsp
+ .byte 0x0f,0x29,0x70,0xe0 #movaps %xmm6, -0x20(%rax)
+ .byte 0x0f,0x29,0x78,0xf0 #movaps %xmm7, -0x10(%rax)
+ .byte 0x44,0x0f,0x29,0x00 #movaps %xmm8, 0(%rax)
+ .byte 0x44,0x0f,0x29,0x48,0x10 #movaps %xmm9, 0x10(%rax)
+ .byte 0x44,0x0f,0x29,0x50,0x20 #movaps %xmm10, 0x20(%rax)
+ .byte 0x44,0x0f,0x29,0x58,0x30 #movaps %xmm11, 0x30(%rax)
+ .byte 0x44,0x0f,0x29,0x60,0x40 #movaps %xmm12, 0x40(%rax)
+ .byte 0x44,0x0f,0x29,0x68,0x50 #movaps %xmm13, 0x50(%rax)
+ .byte 0x44,0x0f,0x29,0x70,0x60 #movaps %xmm14, 0x60(%rax)
+ .byte 0x44,0x0f,0x29,0x78,0x70 #movaps %xmm15, 0x70(%rax)
+___
+$code.=<<___;
+ movdqa .LOne(%rip), $M0
+ movd $index, $INDEX
+
+ pxor $Ra, $Ra
+ pxor $Rb, $Rb
+ pxor $Rc, $Rc
+ pxor $Rd, $Rd
+
+ movdqa $M0, $ONE
+ pshufd \$0, $INDEX, $INDEX
+ mov \$64, %rax
+
+.Lselect_loop_sse_w7:
+ movdqa $M0, $TMP0
+ paddd $ONE, $M0
+ movdqa 16*0($in_t), $T0a
+ movdqa 16*1($in_t), $T0b
+ pcmpeqd $INDEX, $TMP0
+ movdqa 16*2($in_t), $T0c
+ movdqa 16*3($in_t), $T0d
+ lea 16*4($in_t), $in_t
+
+ pand $TMP0, $T0a
+ pand $TMP0, $T0b
+ por $T0a, $Ra
+ pand $TMP0, $T0c
+ por $T0b, $Rb
+ pand $TMP0, $T0d
+ por $T0c, $Rc
+ prefetcht0 255($in_t)
+ por $T0d, $Rd
+
+ dec %rax
+ jnz .Lselect_loop_sse_w7
+
+ movdqu $Ra, 16*0($val)
+ movdqu $Rb, 16*1($val)
+ movdqu $Rc, 16*2($val)
+ movdqu $Rd, 16*3($val)
+___
+$code.=<<___ if ($win64);
+ movaps (%rsp), %xmm6
+ movaps 0x10(%rsp), %xmm7
+ movaps 0x20(%rsp), %xmm8
+ movaps 0x30(%rsp), %xmm9
+ movaps 0x40(%rsp), %xmm10
+ movaps 0x50(%rsp), %xmm11
+ movaps 0x60(%rsp), %xmm12
+ movaps 0x70(%rsp), %xmm13
+ movaps 0x80(%rsp), %xmm14
+ movaps 0x90(%rsp), %xmm15
+ lea 0xa8(%rsp), %rsp
+.LSEH_end_ecp_nistz256_select_w7:
+___
+$code.=<<___;
+ ret
+.size ecp_nistz256_select_w7,.-ecp_nistz256_select_w7
+___
+}
+if ($avx>1) {
+my ($val,$in_t,$index)=$win64?("%rcx","%rdx","%r8d"):("%rdi","%rsi","%edx");
+my ($TWO,$INDEX,$Ra,$Rb,$Rc)=map("%ymm$_",(0..4));
+my ($M0,$T0a,$T0b,$T0c,$TMP0)=map("%ymm$_",(5..9));
+my ($M1,$T1a,$T1b,$T1c,$TMP1)=map("%ymm$_",(10..14));
+
+$code.=<<___;
+################################################################################
+# void ecp_nistz256_avx2_select_w5(uint64_t *val, uint64_t *in_t, int index);
+.type ecp_nistz256_avx2_select_w5,\@abi-omnipotent
+.align 32
+ecp_nistz256_avx2_select_w5:
+.Lavx2_select_w5:
+ vzeroupper
+___
+$code.=<<___ if ($win64);
+ lea -0x88(%rsp), %rax
+.LSEH_begin_ecp_nistz256_avx2_select_w5:
+ .byte 0x48,0x8d,0x60,0xe0 #lea -0x20(%rax), %rsp
+ .byte 0xc5,0xf8,0x29,0x70,0xe0 #vmovaps %xmm6, -0x20(%rax)
+ .byte 0xc5,0xf8,0x29,0x78,0xf0 #vmovaps %xmm7, -0x10(%rax)
+ .byte 0xc5,0x78,0x29,0x40,0x00 #vmovaps %xmm8, 8(%rax)
+ .byte 0xc5,0x78,0x29,0x48,0x10 #vmovaps %xmm9, 0x10(%rax)
+ .byte 0xc5,0x78,0x29,0x50,0x20 #vmovaps %xmm10, 0x20(%rax)
+ .byte 0xc5,0x78,0x29,0x58,0x30 #vmovaps %xmm11, 0x30(%rax)
+ .byte 0xc5,0x78,0x29,0x60,0x40 #vmovaps %xmm12, 0x40(%rax)
+ .byte 0xc5,0x78,0x29,0x68,0x50 #vmovaps %xmm13, 0x50(%rax)
+ .byte 0xc5,0x78,0x29,0x70,0x60 #vmovaps %xmm14, 0x60(%rax)
+ .byte 0xc5,0x78,0x29,0x78,0x70 #vmovaps %xmm15, 0x70(%rax)
+___
+$code.=<<___;
+ vmovdqa .LTwo(%rip), $TWO
+
+ vpxor $Ra, $Ra, $Ra
+ vpxor $Rb, $Rb, $Rb
+ vpxor $Rc, $Rc, $Rc
+
+ vmovdqa .LOne(%rip), $M0
+ vmovdqa .LTwo(%rip), $M1
+
+ vmovd $index, %xmm1
+ vpermd $INDEX, $Ra, $INDEX
+
+ mov \$8, %rax
+.Lselect_loop_avx2_w5:
+
+ vmovdqa 32*0($in_t), $T0a
+ vmovdqa 32*1($in_t), $T0b
+ vmovdqa 32*2($in_t), $T0c
+
+ vmovdqa 32*3($in_t), $T1a
+ vmovdqa 32*4($in_t), $T1b
+ vmovdqa 32*5($in_t), $T1c
+
+ vpcmpeqd $INDEX, $M0, $TMP0
+ vpcmpeqd $INDEX, $M1, $TMP1
+
+ vpaddd $TWO, $M0, $M0
+ vpaddd $TWO, $M1, $M1
+ lea 32*6($in_t), $in_t
+
+ vpand $TMP0, $T0a, $T0a
+ vpand $TMP0, $T0b, $T0b
+ vpand $TMP0, $T0c, $T0c
+ vpand $TMP1, $T1a, $T1a
+ vpand $TMP1, $T1b, $T1b
+ vpand $TMP1, $T1c, $T1c
+
+ vpxor $T0a, $Ra, $Ra
+ vpxor $T0b, $Rb, $Rb
+ vpxor $T0c, $Rc, $Rc
+ vpxor $T1a, $Ra, $Ra
+ vpxor $T1b, $Rb, $Rb
+ vpxor $T1c, $Rc, $Rc
+
+ dec %rax
+ jnz .Lselect_loop_avx2_w5
+
+ vmovdqu $Ra, 32*0($val)
+ vmovdqu $Rb, 32*1($val)
+ vmovdqu $Rc, 32*2($val)
+ vzeroupper
+___
+$code.=<<___ if ($win64);
+ movaps (%rsp), %xmm6
+ movaps 0x10(%rsp), %xmm7
+ movaps 0x20(%rsp), %xmm8
+ movaps 0x30(%rsp), %xmm9
+ movaps 0x40(%rsp), %xmm10
+ movaps 0x50(%rsp), %xmm11
+ movaps 0x60(%rsp), %xmm12
+ movaps 0x70(%rsp), %xmm13
+ movaps 0x80(%rsp), %xmm14
+ movaps 0x90(%rsp), %xmm15
+ lea 0xa8(%rsp), %rsp
+.LSEH_end_ecp_nistz256_avx2_select_w5:
+___
+$code.=<<___;
+ ret
+.size ecp_nistz256_avx2_select_w5,.-ecp_nistz256_avx2_select_w5
+___
+}
+if ($avx>1) {
+my ($val,$in_t,$index)=$win64?("%rcx","%rdx","%r8d"):("%rdi","%rsi","%edx");
+my ($THREE,$INDEX,$Ra,$Rb)=map("%ymm$_",(0..3));
+my ($M0,$T0a,$T0b,$TMP0)=map("%ymm$_",(4..7));
+my ($M1,$T1a,$T1b,$TMP1)=map("%ymm$_",(8..11));
+my ($M2,$T2a,$T2b,$TMP2)=map("%ymm$_",(12..15));
+
+$code.=<<___;
+
+################################################################################
+# void ecp_nistz256_avx2_select_w7(uint64_t *val, uint64_t *in_t, int index);
+.globl ecp_nistz256_avx2_select_w7
+.type ecp_nistz256_avx2_select_w7,\@abi-omnipotent
+.align 32
+ecp_nistz256_avx2_select_w7:
+.Lavx2_select_w7:
+ vzeroupper
+___
+$code.=<<___ if ($win64);
+ lea -0x88(%rsp), %rax
+.LSEH_begin_ecp_nistz256_avx2_select_w7:
+ .byte 0x48,0x8d,0x60,0xe0 #lea -0x20(%rax), %rsp
+ .byte 0xc5,0xf8,0x29,0x70,0xe0 #vmovaps %xmm6, -0x20(%rax)
+ .byte 0xc5,0xf8,0x29,0x78,0xf0 #vmovaps %xmm7, -0x10(%rax)
+ .byte 0xc5,0x78,0x29,0x40,0x00 #vmovaps %xmm8, 8(%rax)
+ .byte 0xc5,0x78,0x29,0x48,0x10 #vmovaps %xmm9, 0x10(%rax)
+ .byte 0xc5,0x78,0x29,0x50,0x20 #vmovaps %xmm10, 0x20(%rax)
+ .byte 0xc5,0x78,0x29,0x58,0x30 #vmovaps %xmm11, 0x30(%rax)
+ .byte 0xc5,0x78,0x29,0x60,0x40 #vmovaps %xmm12, 0x40(%rax)
+ .byte 0xc5,0x78,0x29,0x68,0x50 #vmovaps %xmm13, 0x50(%rax)
+ .byte 0xc5,0x78,0x29,0x70,0x60 #vmovaps %xmm14, 0x60(%rax)
+ .byte 0xc5,0x78,0x29,0x78,0x70 #vmovaps %xmm15, 0x70(%rax)
+___
+$code.=<<___;
+ vmovdqa .LThree(%rip), $THREE
+
+ vpxor $Ra, $Ra, $Ra
+ vpxor $Rb, $Rb, $Rb
+
+ vmovdqa .LOne(%rip), $M0
+ vmovdqa .LTwo(%rip), $M1
+ vmovdqa .LThree(%rip), $M2
+
+ vmovd $index, %xmm1
+ vpermd $INDEX, $Ra, $INDEX
+ # Skip index = 0, because it is implicitly the point at infinity
+
+ mov \$21, %rax
+.Lselect_loop_avx2_w7:
+
+ vmovdqa 32*0($in_t), $T0a
+ vmovdqa 32*1($in_t), $T0b
+
+ vmovdqa 32*2($in_t), $T1a
+ vmovdqa 32*3($in_t), $T1b
+
+ vmovdqa 32*4($in_t), $T2a
+ vmovdqa 32*5($in_t), $T2b
+
+ vpcmpeqd $INDEX, $M0, $TMP0
+ vpcmpeqd $INDEX, $M1, $TMP1
+ vpcmpeqd $INDEX, $M2, $TMP2
+
+ vpaddd $THREE, $M0, $M0
+ vpaddd $THREE, $M1, $M1
+ vpaddd $THREE, $M2, $M2
+ lea 32*6($in_t), $in_t
+
+ vpand $TMP0, $T0a, $T0a
+ vpand $TMP0, $T0b, $T0b
+ vpand $TMP1, $T1a, $T1a
+ vpand $TMP1, $T1b, $T1b
+ vpand $TMP2, $T2a, $T2a
+ vpand $TMP2, $T2b, $T2b
+
+ vpxor $T0a, $Ra, $Ra
+ vpxor $T0b, $Rb, $Rb
+ vpxor $T1a, $Ra, $Ra
+ vpxor $T1b, $Rb, $Rb
+ vpxor $T2a, $Ra, $Ra
+ vpxor $T2b, $Rb, $Rb
+
+ dec %rax
+ jnz .Lselect_loop_avx2_w7
+
+
+ vmovdqa 32*0($in_t), $T0a
+ vmovdqa 32*1($in_t), $T0b
+
+ vpcmpeqd $INDEX, $M0, $TMP0
+
+ vpand $TMP0, $T0a, $T0a
+ vpand $TMP0, $T0b, $T0b
+
+ vpxor $T0a, $Ra, $Ra
+ vpxor $T0b, $Rb, $Rb
+
+ vmovdqu $Ra, 32*0($val)
+ vmovdqu $Rb, 32*1($val)
+ vzeroupper
+___
+$code.=<<___ if ($win64);
+ movaps (%rsp), %xmm6
+ movaps 0x10(%rsp), %xmm7
+ movaps 0x20(%rsp), %xmm8
+ movaps 0x30(%rsp), %xmm9
+ movaps 0x40(%rsp), %xmm10
+ movaps 0x50(%rsp), %xmm11
+ movaps 0x60(%rsp), %xmm12
+ movaps 0x70(%rsp), %xmm13
+ movaps 0x80(%rsp), %xmm14
+ movaps 0x90(%rsp), %xmm15
+ lea 0xa8(%rsp), %rsp
+.LSEH_end_ecp_nistz256_avx2_select_w7:
+___
+$code.=<<___;
+ ret
+.size ecp_nistz256_avx2_select_w7,.-ecp_nistz256_avx2_select_w7
+___
+} else {
+$code.=<<___;
+.globl ecp_nistz256_avx2_select_w7
+.type ecp_nistz256_avx2_select_w7,\@function,3
+.align 32
+ecp_nistz256_avx2_select_w7:
+ .byte 0x0f,0x0b # ud2
+ ret
+.size ecp_nistz256_avx2_select_w7,.-ecp_nistz256_avx2_select_w7
+___
+}
+{{{
+########################################################################
+# This block implements higher level point_double, point_add and
+# point_add_affine. The key to performance in this case is to allow
+# out-of-order execution logic to overlap computations from next step
+# with tail processing from current step. By using tailored calling
+# sequence we minimize inter-step overhead to give processor better
+# shot at overlapping operations...
+#
+# You will notice that input data is copied to stack. Trouble is that
+# there are no registers to spare for holding original pointers and
+# reloading them, pointers, would create undesired dependencies on
+# effective addresses calculation paths. In other words it's too done
+# to favour out-of-order execution logic.
+# <appro@openssl.org>
+
+my ($r_ptr,$a_ptr,$b_org,$b_ptr)=("%rdi","%rsi","%rdx","%rbx");
+my ($acc0,$acc1,$acc2,$acc3,$acc4,$acc5,$acc6,$acc7)=map("%r$_",(8..15));
+my ($t0,$t1,$t2,$t3,$t4)=("%rax","%rbp","%rcx",$acc4,$acc4);
+my ($poly1,$poly3)=($acc6,$acc7);
+
+sub load_for_mul () {
+my ($a,$b,$src0) = @_;
+my $bias = $src0 eq "%rax" ? 0 : -128;
+
+" mov $b, $src0
+ lea $b, $b_ptr
+ mov 8*0+$a, $acc1
+ mov 8*1+$a, $acc2
+ lea $bias+$a, $a_ptr
+ mov 8*2+$a, $acc3
+ mov 8*3+$a, $acc4"
+}
+
+sub load_for_sqr () {
+my ($a,$src0) = @_;
+my $bias = $src0 eq "%rax" ? 0 : -128;
+
+" mov 8*0+$a, $src0
+ mov 8*1+$a, $acc6
+ lea $bias+$a, $a_ptr
+ mov 8*2+$a, $acc7
+ mov 8*3+$a, $acc0"
+}
+
+ {
+########################################################################
+# operate in 4-5-0-1 "name space" that matches multiplication output
+#
+my ($a0,$a1,$a2,$a3,$t3,$t4)=($acc4,$acc5,$acc0,$acc1,$acc2,$acc3);
+
+$code.=<<___;
+.type __ecp_nistz256_add_toq,\@abi-omnipotent
+.align 32
+__ecp_nistz256_add_toq:
+ 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
+ sbb $t4, $t4
+
+ sub \$-1, $a0
+ mov $a2, $t2
+ sbb $poly1, $a1
+ sbb \$0, $a2
+ mov $a3, $t3
+ sbb $poly3, $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)
+
+ ret
+.size __ecp_nistz256_add_toq,.-__ecp_nistz256_add_toq
+
+.type __ecp_nistz256_sub_fromq,\@abi-omnipotent
+.align 32
+__ecp_nistz256_sub_fromq:
+ 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 $t4, $t4
+
+ add \$-1, $a0
+ mov $a2, $t2
+ adc $poly1, $a1
+ adc \$0, $a2
+ mov $a3, $t3
+ adc $poly3, $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)
+
+ ret
+.size __ecp_nistz256_sub_fromq,.-__ecp_nistz256_sub_fromq
+
+.type __ecp_nistz256_subq,\@abi-omnipotent
+.align 32
+__ecp_nistz256_subq:
+ sub $a0, $t0
+ sbb $a1, $t1
+ mov $t0, $a0
+ sbb $a2, $t2
+ sbb $a3, $t3
+ mov $t1, $a1
+ sbb $t4, $t4
+
+ add \$-1, $t0
+ mov $t2, $a2
+ adc $poly1, $t1
+ adc \$0, $t2
+ mov $t3, $a3
+ adc $poly3, $t3
+ test $t4, $t4
+
+ cmovnz $t0, $a0
+ cmovnz $t1, $a1
+ cmovnz $t2, $a2
+ cmovnz $t3, $a3
+
+ ret
+.size __ecp_nistz256_subq,.-__ecp_nistz256_subq
+
+.type __ecp_nistz256_mul_by_2q,\@abi-omnipotent
+.align 32
+__ecp_nistz256_mul_by_2q:
+ add $a0, $a0 # a0:a3+a0:a3
+ adc $a1, $a1
+ mov $a0, $t0
+ adc $a2, $a2
+ adc $a3, $a3
+ mov $a1, $t1
+ sbb $t4, $t4
+
+ sub \$-1, $a0
+ mov $a2, $t2
+ sbb $poly1, $a1
+ sbb \$0, $a2
+ mov $a3, $t3
+ sbb $poly3, $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)
+
+ ret
+.size __ecp_nistz256_mul_by_2q,.-__ecp_nistz256_mul_by_2q
+___
+ }
+sub gen_double () {
+ my $x = shift;
+ my ($src0,$sfx,$bias);
+ my ($S,$M,$Zsqr,$in_x,$tmp0)=map(32*$_,(0..4));
+
+ if ($x ne "x") {
+ $src0 = "%rax";
+ $sfx = "";
+ $bias = 0;
+
+$code.=<<___;
+.globl ecp_nistz256_point_double
+.type ecp_nistz256_point_double,\@function,2
+.align 32
+ecp_nistz256_point_double:
+___
+$code.=<<___ if ($addx);
+ mov \$0x80100, %ecx
+ and OPENSSL_ia32cap_P+8(%rip), %ecx
+ cmp \$0x80100, %ecx
+ je .Lpoint_doublex
+___
+ } else {
+ $src0 = "%rdx";
+ $sfx = "x";
+ $bias = 128;
+
+$code.=<<___;
+.type ecp_nistz256_point_doublex,\@function,2
+.align 32
+ecp_nistz256_point_doublex:
+.Lpoint_doublex:
+___
+ }
+$code.=<<___;
+ push %rbp
+ push %rbx
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ sub \$32*5+8, %rsp
+
+ movdqu 0x00($a_ptr), %xmm0 # copy *(P256_POINT *)$a_ptr.x
+ mov $a_ptr, $b_ptr # backup copy
+ movdqu 0x10($a_ptr), %xmm1
+ mov 0x20+8*0($a_ptr), $acc4 # load in_y in "5-4-0-1" order
+ mov 0x20+8*1($a_ptr), $acc5
+ mov 0x20+8*2($a_ptr), $acc0
+ mov 0x20+8*3($a_ptr), $acc1
+ mov .Lpoly+8*1(%rip), $poly1
+ mov .Lpoly+8*3(%rip), $poly3
+ movdqa %xmm0, $in_x(%rsp)
+ movdqa %xmm1, $in_x+0x10(%rsp)
+ lea 0x20($r_ptr), $acc2
+ lea 0x40($r_ptr), $acc3
+ movq $r_ptr, %xmm0
+ movq $acc2, %xmm1
+ movq $acc3, %xmm2
+
+ lea $S(%rsp), $r_ptr
+ call __ecp_nistz256_mul_by_2$x # p256_mul_by_2(S, in_y);
+
+ mov 0x40+8*0($a_ptr), $src0
+ mov 0x40+8*1($a_ptr), $acc6
+ mov 0x40+8*2($a_ptr), $acc7
+ mov 0x40+8*3($a_ptr), $acc0
+ lea 0x40-$bias($a_ptr), $a_ptr
+ lea $Zsqr(%rsp), $r_ptr
+ call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(Zsqr, in_z);
+
+ `&load_for_sqr("$S(%rsp)", "$src0")`
+ lea $S(%rsp), $r_ptr
+ call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(S, S);
+
+ mov 0x20($b_ptr), $src0 # $b_ptr is still valid
+ mov 0x40+8*0($b_ptr), $acc1
+ mov 0x40+8*1($b_ptr), $acc2
+ mov 0x40+8*2($b_ptr), $acc3
+ mov 0x40+8*3($b_ptr), $acc4
+ lea 0x40-$bias($b_ptr), $a_ptr
+ lea 0x20($b_ptr), $b_ptr
+ movq %xmm2, $r_ptr
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(res_z, in_z, in_y);
+ call __ecp_nistz256_mul_by_2$x # p256_mul_by_2(res_z, res_z);
+
+ mov $in_x+8*0(%rsp), $acc4 # "5-4-0-1" order
+ mov $in_x+8*1(%rsp), $acc5
+ lea $Zsqr(%rsp), $b_ptr
+ mov $in_x+8*2(%rsp), $acc0
+ mov $in_x+8*3(%rsp), $acc1
+ lea $M(%rsp), $r_ptr
+ call __ecp_nistz256_add_to$x # p256_add(M, in_x, Zsqr);
+
+ mov $in_x+8*0(%rsp), $acc4 # "5-4-0-1" order
+ mov $in_x+8*1(%rsp), $acc5
+ lea $Zsqr(%rsp), $b_ptr
+ mov $in_x+8*2(%rsp), $acc0
+ mov $in_x+8*3(%rsp), $acc1
+ lea $Zsqr(%rsp), $r_ptr
+ call __ecp_nistz256_sub_from$x # p256_sub(Zsqr, in_x, Zsqr);
+
+ `&load_for_sqr("$S(%rsp)", "$src0")`
+ movq %xmm1, $r_ptr
+ call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(res_y, S);
+___
+{
+######## ecp_nistz256_div_by_2(res_y, res_y); ##########################
+# operate in 4-5-6-7 "name space" that matches squaring output
+#
+my ($poly1,$poly3)=($a_ptr,$t1);
+my ($a0,$a1,$a2,$a3,$t3,$t4,$t1)=($acc4,$acc5,$acc6,$acc7,$acc0,$acc1,$acc2);
+
+$code.=<<___;
+ xor $t4, $t4
+ mov $a0, $t0
+ add \$-1, $a0
+ mov $a1, $t1
+ adc $poly1, $a1
+ mov $a2, $t2
+ adc \$0, $a2
+ mov $a3, $t3
+ adc $poly3, $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
+ mov $a0, 8*0($r_ptr)
+ shr \$1, $a3
+ mov $a1, 8*1($r_ptr)
+ shl \$63, $t4
+ or $t2, $a2
+ or $t4, $a3
+ mov $a2, 8*2($r_ptr)
+ mov $a3, 8*3($r_ptr)
+___
+}
+$code.=<<___;
+ `&load_for_mul("$M(%rsp)", "$Zsqr(%rsp)", "$src0")`
+ lea $M(%rsp), $r_ptr
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(M, M, Zsqr);
+
+ lea $tmp0(%rsp), $r_ptr
+ call __ecp_nistz256_mul_by_2$x
+
+ lea $M(%rsp), $b_ptr
+ lea $M(%rsp), $r_ptr
+ call __ecp_nistz256_add_to$x # p256_mul_by_3(M, M);
+
+ `&load_for_mul("$S(%rsp)", "$in_x(%rsp)", "$src0")`
+ lea $S(%rsp), $r_ptr
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(S, S, in_x);
+
+ lea $tmp0(%rsp), $r_ptr
+ call __ecp_nistz256_mul_by_2$x # p256_mul_by_2(tmp0, S);
+
+ `&load_for_sqr("$M(%rsp)", "$src0")`
+ movq %xmm0, $r_ptr
+ call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(res_x, M);
+
+ lea $tmp0(%rsp), $b_ptr
+ mov $acc6, $acc0 # harmonize sqr output and sub input
+ mov $acc7, $acc1
+ mov $a_ptr, $poly1
+ mov $t1, $poly3
+ call __ecp_nistz256_sub_from$x # p256_sub(res_x, res_x, tmp0);
+
+ mov $S+8*0(%rsp), $t0
+ mov $S+8*1(%rsp), $t1
+ mov $S+8*2(%rsp), $t2
+ mov $S+8*3(%rsp), $acc2 # "4-5-0-1" order
+ lea $S(%rsp), $r_ptr
+ call __ecp_nistz256_sub$x # p256_sub(S, S, res_x);
+
+ mov $M(%rsp), $src0
+ lea $M(%rsp), $b_ptr
+ mov $acc4, $acc6 # harmonize sub output and mul input
+ xor %ecx, %ecx
+ mov $acc4, $S+8*0(%rsp) # have to save:-(
+ mov $acc5, $acc2
+ mov $acc5, $S+8*1(%rsp)
+ cmovz $acc0, $acc3
+ mov $acc0, $S+8*2(%rsp)
+ lea $S-$bias(%rsp), $a_ptr
+ cmovz $acc1, $acc4
+ mov $acc1, $S+8*3(%rsp)
+ mov $acc6, $acc1
+ lea $S(%rsp), $r_ptr
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(S, S, M);
+
+ movq %xmm1, $b_ptr
+ movq %xmm1, $r_ptr
+ call __ecp_nistz256_sub_from$x # p256_sub(res_y, S, res_y);
+
+ add \$32*5+8, %rsp
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbx
+ pop %rbp
+ ret
+.size ecp_nistz256_point_double$sfx,.-ecp_nistz256_point_double$sfx
+___
+}
+&gen_double("q");
+
+sub gen_add () {
+ my $x = shift;
+ my ($src0,$sfx,$bias);
+ my ($H,$Hsqr,$R,$Rsqr,$Hcub,
+ $U1,$U2,$S1,$S2,
+ $res_x,$res_y,$res_z,
+ $in1_x,$in1_y,$in1_z,
+ $in2_x,$in2_y,$in2_z)=map(32*$_,(0..17));
+ my ($Z1sqr, $Z2sqr) = ($Hsqr, $Rsqr);
+
+ if ($x ne "x") {
+ $src0 = "%rax";
+ $sfx = "";
+ $bias = 0;
+
+$code.=<<___;
+.globl ecp_nistz256_point_add
+.type ecp_nistz256_point_add,\@function,3
+.align 32
+ecp_nistz256_point_add:
+___
+$code.=<<___ if ($addx);
+ mov \$0x80100, %ecx
+ and OPENSSL_ia32cap_P+8(%rip), %ecx
+ cmp \$0x80100, %ecx
+ je .Lpoint_addx
+___
+ } else {
+ $src0 = "%rdx";
+ $sfx = "x";
+ $bias = 128;
+
+$code.=<<___;
+.type ecp_nistz256_point_addx,\@function,3
+.align 32
+ecp_nistz256_point_addx:
+.Lpoint_addx:
+___
+ }
+$code.=<<___;
+ push %rbp
+ push %rbx
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ sub \$32*18+8, %rsp
+
+ movdqu 0x00($a_ptr), %xmm0 # copy *(P256_POINT *)$a_ptr
+ movdqu 0x10($a_ptr), %xmm1
+ movdqu 0x20($a_ptr), %xmm2
+ movdqu 0x30($a_ptr), %xmm3
+ movdqu 0x40($a_ptr), %xmm4
+ movdqu 0x50($a_ptr), %xmm5
+ mov $a_ptr, $b_ptr # reassign
+ mov $b_org, $a_ptr # reassign
+ movdqa %xmm0, $in1_x(%rsp)
+ movdqa %xmm1, $in1_x+0x10(%rsp)
+ por %xmm0, %xmm1
+ movdqa %xmm2, $in1_y(%rsp)
+ movdqa %xmm3, $in1_y+0x10(%rsp)
+ por %xmm2, %xmm3
+ movdqa %xmm4, $in1_z(%rsp)
+ movdqa %xmm5, $in1_z+0x10(%rsp)
+ por %xmm1, %xmm3
+
+ movdqu 0x00($a_ptr), %xmm0 # copy *(P256_POINT *)$b_ptr
+ pshufd \$0xb1, %xmm3, %xmm5
+ movdqu 0x10($a_ptr), %xmm1
+ movdqu 0x20($a_ptr), %xmm2
+ por %xmm3, %xmm5
+ movdqu 0x30($a_ptr), %xmm3
+ mov 0x40+8*0($a_ptr), $src0 # load original in2_z
+ mov 0x40+8*1($a_ptr), $acc6
+ mov 0x40+8*2($a_ptr), $acc7
+ mov 0x40+8*3($a_ptr), $acc0
+ movdqa %xmm0, $in2_x(%rsp)
+ pshufd \$0x1e, %xmm5, %xmm4
+ movdqa %xmm1, $in2_x+0x10(%rsp)
+ por %xmm0, %xmm1
+ movq $r_ptr, %xmm0 # save $r_ptr
+ movdqa %xmm2, $in2_y(%rsp)
+ movdqa %xmm3, $in2_y+0x10(%rsp)
+ por %xmm2, %xmm3
+ por %xmm4, %xmm5
+ pxor %xmm4, %xmm4
+ por %xmm1, %xmm3
+
+ lea 0x40-$bias($a_ptr), $a_ptr # $a_ptr is still valid
+ mov $src0, $in2_z+8*0(%rsp) # make in2_z copy
+ mov $acc6, $in2_z+8*1(%rsp)
+ mov $acc7, $in2_z+8*2(%rsp)
+ mov $acc0, $in2_z+8*3(%rsp)
+ lea $Z2sqr(%rsp), $r_ptr # Z2^2
+ call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(Z2sqr, in2_z);
+
+ pcmpeqd %xmm4, %xmm5
+ pshufd \$0xb1, %xmm3, %xmm4
+ por %xmm3, %xmm4
+ pshufd \$0, %xmm5, %xmm5 # in1infty
+ pshufd \$0x1e, %xmm4, %xmm3
+ por %xmm3, %xmm4
+ pxor %xmm3, %xmm3
+ pcmpeqd %xmm3, %xmm4
+ pshufd \$0, %xmm4, %xmm4 # in2infty
+ mov 0x40+8*0($b_ptr), $src0 # load original in1_z
+ mov 0x40+8*1($b_ptr), $acc6
+ mov 0x40+8*2($b_ptr), $acc7
+ mov 0x40+8*3($b_ptr), $acc0
+
+ lea 0x40-$bias($b_ptr), $a_ptr
+ lea $Z1sqr(%rsp), $r_ptr # Z1^2
+ call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(Z1sqr, in1_z);
+
+ `&load_for_mul("$Z2sqr(%rsp)", "$in2_z(%rsp)", "$src0")`
+ lea $S1(%rsp), $r_ptr # S1 = Z2^3
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(S1, Z2sqr, in2_z);
+
+ `&load_for_mul("$Z1sqr(%rsp)", "$in1_z(%rsp)", "$src0")`
+ lea $S2(%rsp), $r_ptr # S2 = Z1^3
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(S2, Z1sqr, in1_z);
+
+ `&load_for_mul("$S1(%rsp)", "$in1_y(%rsp)", "$src0")`
+ lea $S1(%rsp), $r_ptr # S1 = Y1*Z2^3
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(S1, S1, in1_y);
+
+ `&load_for_mul("$S2(%rsp)", "$in2_y(%rsp)", "$src0")`
+ lea $S2(%rsp), $r_ptr # S2 = Y2*Z1^3
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(S2, S2, in2_y);
+
+ lea $S1(%rsp), $b_ptr
+ lea $R(%rsp), $r_ptr # R = S2 - S1
+ call __ecp_nistz256_sub_from$x # p256_sub(R, S2, S1);
+
+ or $acc5, $acc4 # see if result is zero
+ movdqa %xmm4, %xmm2
+ or $acc0, $acc4
+ or $acc1, $acc4
+ por %xmm5, %xmm2 # in1infty || in2infty
+ movq $acc4, %xmm3
+
+ `&load_for_mul("$Z2sqr(%rsp)", "$in1_x(%rsp)", "$src0")`
+ lea $U1(%rsp), $r_ptr # U1 = X1*Z2^2
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(U1, in1_x, Z2sqr);
+
+ `&load_for_mul("$Z1sqr(%rsp)", "$in2_x(%rsp)", "$src0")`
+ lea $U2(%rsp), $r_ptr # U2 = X2*Z1^2
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(U2, in2_x, Z1sqr);
+
+ lea $U1(%rsp), $b_ptr
+ lea $H(%rsp), $r_ptr # H = U2 - U1
+ call __ecp_nistz256_sub_from$x # p256_sub(H, U2, U1);
+
+ or $acc5, $acc4 # see if result is zero
+ or $acc0, $acc4
+ or $acc1, $acc4
+
+ .byte 0x3e # predict taken
+ jnz .Ladd_proceed$x # is_equal(U1,U2)?
+ movq %xmm2, $acc0
+ movq %xmm3, $acc1
+ test $acc0, $acc0
+ jnz .Ladd_proceed$x # (in1infty || in2infty)?
+ test $acc1, $acc1
+ jz .Ladd_proceed$x # is_equal(S1,S2)?
+
+ movq %xmm0, $r_ptr # restore $r_ptr
+ pxor %xmm0, %xmm0
+ movdqu %xmm0, 0x00($r_ptr)
+ movdqu %xmm0, 0x10($r_ptr)
+ movdqu %xmm0, 0x20($r_ptr)
+ movdqu %xmm0, 0x30($r_ptr)
+ movdqu %xmm0, 0x40($r_ptr)
+ movdqu %xmm0, 0x50($r_ptr)
+ jmp .Ladd_done$x
+
+.align 32
+.Ladd_proceed$x:
+ `&load_for_sqr("$R(%rsp)", "$src0")`
+ lea $Rsqr(%rsp), $r_ptr # R^2
+ call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(Rsqr, R);
+
+ `&load_for_mul("$H(%rsp)", "$in1_z(%rsp)", "$src0")`
+ lea $res_z(%rsp), $r_ptr # Z3 = H*Z1*Z2
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(res_z, H, in1_z);
+
+ `&load_for_sqr("$H(%rsp)", "$src0")`
+ lea $Hsqr(%rsp), $r_ptr # H^2
+ call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(Hsqr, H);
+
+ `&load_for_mul("$res_z(%rsp)", "$in2_z(%rsp)", "$src0")`
+ lea $res_z(%rsp), $r_ptr # Z3 = H*Z1*Z2
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(res_z, res_z, in2_z);
+
+ `&load_for_mul("$Hsqr(%rsp)", "$H(%rsp)", "$src0")`
+ lea $Hcub(%rsp), $r_ptr # H^3
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(Hcub, Hsqr, H);
+
+ `&load_for_mul("$Hsqr(%rsp)", "$U1(%rsp)", "$src0")`
+ lea $U2(%rsp), $r_ptr # U1*H^2
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(U2, U1, Hsqr);
+___
+{
+#######################################################################
+# operate in 4-5-0-1 "name space" that matches multiplication output
+#
+my ($acc0,$acc1,$acc2,$acc3,$t3,$t4)=($acc4,$acc5,$acc0,$acc1,$acc2,$acc3);
+my ($poly1, $poly3)=($acc6,$acc7);
+
+$code.=<<___;
+ #lea $U2(%rsp), $a_ptr
+ #lea $Hsqr(%rsp), $r_ptr # 2*U1*H^2
+ #call __ecp_nistz256_mul_by_2 # ecp_nistz256_mul_by_2(Hsqr, U2);
+
+ add $acc0, $acc0 # a0:a3+a0:a3
+ lea $Rsqr(%rsp), $a_ptr
+ adc $acc1, $acc1
+ mov $acc0, $t0
+ adc $acc2, $acc2
+ adc $acc3, $acc3
+ mov $acc1, $t1
+ sbb $t4, $t4
+
+ sub \$-1, $acc0
+ mov $acc2, $t2
+ sbb $poly1, $acc1
+ sbb \$0, $acc2
+ mov $acc3, $t3
+ sbb $poly3, $acc3
+ test $t4, $t4
+
+ cmovz $t0, $acc0
+ mov 8*0($a_ptr), $t0
+ cmovz $t1, $acc1
+ mov 8*1($a_ptr), $t1
+ cmovz $t2, $acc2
+ mov 8*2($a_ptr), $t2
+ cmovz $t3, $acc3
+ mov 8*3($a_ptr), $t3
+
+ call __ecp_nistz256_sub$x # p256_sub(res_x, Rsqr, Hsqr);
+
+ lea $Hcub(%rsp), $b_ptr
+ lea $res_x(%rsp), $r_ptr
+ call __ecp_nistz256_sub_from$x # p256_sub(res_x, res_x, Hcub);
+
+ mov $U2+8*0(%rsp), $t0
+ mov $U2+8*1(%rsp), $t1
+ mov $U2+8*2(%rsp), $t2
+ mov $U2+8*3(%rsp), $t3
+ lea $res_y(%rsp), $r_ptr
+
+ call __ecp_nistz256_sub$x # p256_sub(res_y, U2, res_x);
+
+ mov $acc0, 8*0($r_ptr) # save the result, as
+ mov $acc1, 8*1($r_ptr) # __ecp_nistz256_sub doesn't
+ mov $acc2, 8*2($r_ptr)
+ mov $acc3, 8*3($r_ptr)
+___
+}
+$code.=<<___;
+ `&load_for_mul("$S1(%rsp)", "$Hcub(%rsp)", "$src0")`
+ lea $S2(%rsp), $r_ptr
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(S2, S1, Hcub);
+
+ `&load_for_mul("$R(%rsp)", "$res_y(%rsp)", "$src0")`
+ lea $res_y(%rsp), $r_ptr
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(res_y, R, res_y);
+
+ lea $S2(%rsp), $b_ptr
+ lea $res_y(%rsp), $r_ptr
+ call __ecp_nistz256_sub_from$x # p256_sub(res_y, res_y, S2);
+
+ movq %xmm0, $r_ptr # restore $r_ptr
+
+ movdqa %xmm5, %xmm0 # copy_conditional(res_z, in2_z, in1infty);
+ movdqa %xmm5, %xmm1
+ pandn $res_z(%rsp), %xmm0
+ movdqa %xmm5, %xmm2
+ pandn $res_z+0x10(%rsp), %xmm1
+ movdqa %xmm5, %xmm3
+ pand $in2_z(%rsp), %xmm2
+ pand $in2_z+0x10(%rsp), %xmm3
+ por %xmm0, %xmm2
+ por %xmm1, %xmm3
+
+ movdqa %xmm4, %xmm0 # copy_conditional(res_z, in1_z, in2infty);
+ movdqa %xmm4, %xmm1
+ pandn %xmm2, %xmm0
+ movdqa %xmm4, %xmm2
+ pandn %xmm3, %xmm1
+ movdqa %xmm4, %xmm3
+ pand $in1_z(%rsp), %xmm2
+ pand $in1_z+0x10(%rsp), %xmm3
+ por %xmm0, %xmm2
+ por %xmm1, %xmm3
+ movdqu %xmm2, 0x40($r_ptr)
+ movdqu %xmm3, 0x50($r_ptr)
+
+ movdqa %xmm5, %xmm0 # copy_conditional(res_x, in2_x, in1infty);
+ movdqa %xmm5, %xmm1
+ pandn $res_x(%rsp), %xmm0
+ movdqa %xmm5, %xmm2
+ pandn $res_x+0x10(%rsp), %xmm1
+ movdqa %xmm5, %xmm3
+ pand $in2_x(%rsp), %xmm2
+ pand $in2_x+0x10(%rsp), %xmm3
+ por %xmm0, %xmm2
+ por %xmm1, %xmm3
+
+ movdqa %xmm4, %xmm0 # copy_conditional(res_x, in1_x, in2infty);
+ movdqa %xmm4, %xmm1
+ pandn %xmm2, %xmm0
+ movdqa %xmm4, %xmm2
+ pandn %xmm3, %xmm1
+ movdqa %xmm4, %xmm3
+ pand $in1_x(%rsp), %xmm2
+ pand $in1_x+0x10(%rsp), %xmm3
+ por %xmm0, %xmm2
+ por %xmm1, %xmm3
+ movdqu %xmm2, 0x00($r_ptr)
+ movdqu %xmm3, 0x10($r_ptr)
+
+ movdqa %xmm5, %xmm0 # copy_conditional(res_y, in2_y, in1infty);
+ movdqa %xmm5, %xmm1
+ pandn $res_y(%rsp), %xmm0
+ movdqa %xmm5, %xmm2
+ pandn $res_y+0x10(%rsp), %xmm1
+ movdqa %xmm5, %xmm3
+ pand $in2_y(%rsp), %xmm2
+ pand $in2_y+0x10(%rsp), %xmm3
+ por %xmm0, %xmm2
+ por %xmm1, %xmm3
+
+ movdqa %xmm4, %xmm0 # copy_conditional(res_y, in1_y, in2infty);
+ movdqa %xmm4, %xmm1
+ pandn %xmm2, %xmm0
+ movdqa %xmm4, %xmm2
+ pandn %xmm3, %xmm1
+ movdqa %xmm4, %xmm3
+ pand $in1_y(%rsp), %xmm2
+ pand $in1_y+0x10(%rsp), %xmm3
+ por %xmm0, %xmm2
+ por %xmm1, %xmm3
+ movdqu %xmm2, 0x20($r_ptr)
+ movdqu %xmm3, 0x30($r_ptr)
+
+.Ladd_done$x:
+ add \$32*18+8, %rsp
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbx
+ pop %rbp
+ ret
+.size ecp_nistz256_point_add$sfx,.-ecp_nistz256_point_add$sfx
+___
+}
+&gen_add("q");
+
+sub gen_add_affine () {
+ my $x = shift;
+ my ($src0,$sfx,$bias);
+ my ($U2,$S2,$H,$R,$Hsqr,$Hcub,$Rsqr,
+ $res_x,$res_y,$res_z,
+ $in1_x,$in1_y,$in1_z,
+ $in2_x,$in2_y)=map(32*$_,(0..14));
+ my $Z1sqr = $S2;
+
+ if ($x ne "x") {
+ $src0 = "%rax";
+ $sfx = "";
+ $bias = 0;
+
+$code.=<<___;
+.globl ecp_nistz256_point_add_affine
+.type ecp_nistz256_point_add_affine,\@function,3
+.align 32
+ecp_nistz256_point_add_affine:
+___
+$code.=<<___ if ($addx);
+ mov \$0x80100, %ecx
+ and OPENSSL_ia32cap_P+8(%rip), %ecx
+ cmp \$0x80100, %ecx
+ je .Lpoint_add_affinex
+___
+ } else {
+ $src0 = "%rdx";
+ $sfx = "x";
+ $bias = 128;
+
+$code.=<<___;
+.type ecp_nistz256_point_add_affinex,\@function,3
+.align 32
+ecp_nistz256_point_add_affinex:
+.Lpoint_add_affinex:
+___
+ }
+$code.=<<___;
+ push %rbp
+ push %rbx
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ sub \$32*15+8, %rsp
+
+ movdqu 0x00($a_ptr), %xmm0 # copy *(P256_POINT *)$a_ptr
+ mov $b_org, $b_ptr # reassign
+ movdqu 0x10($a_ptr), %xmm1
+ movdqu 0x20($a_ptr), %xmm2
+ movdqu 0x30($a_ptr), %xmm3
+ movdqu 0x40($a_ptr), %xmm4
+ movdqu 0x50($a_ptr), %xmm5
+ mov 0x40+8*0($a_ptr), $src0 # load original in1_z
+ mov 0x40+8*1($a_ptr), $acc6
+ mov 0x40+8*2($a_ptr), $acc7
+ mov 0x40+8*3($a_ptr), $acc0
+ movdqa %xmm0, $in1_x(%rsp)
+ movdqa %xmm1, $in1_x+0x10(%rsp)
+ por %xmm0, %xmm1
+ movdqa %xmm2, $in1_y(%rsp)
+ movdqa %xmm3, $in1_y+0x10(%rsp)
+ por %xmm2, %xmm3
+ movdqa %xmm4, $in1_z(%rsp)
+ movdqa %xmm5, $in1_z+0x10(%rsp)
+ por %xmm1, %xmm3
+
+ movdqu 0x00($b_ptr), %xmm0 # copy *(P256_POINT_AFFINE *)$b_ptr
+ pshufd \$0xb1, %xmm3, %xmm5
+ movdqu 0x10($b_ptr), %xmm1
+ movdqu 0x20($b_ptr), %xmm2
+ por %xmm3, %xmm5
+ movdqu 0x30($b_ptr), %xmm3
+ movdqa %xmm0, $in2_x(%rsp)
+ pshufd \$0x1e, %xmm5, %xmm4
+ movdqa %xmm1, $in2_x+0x10(%rsp)
+ por %xmm0, %xmm1
+ movq $r_ptr, %xmm0 # save $r_ptr
+ movdqa %xmm2, $in2_y(%rsp)
+ movdqa %xmm3, $in2_y+0x10(%rsp)
+ por %xmm2, %xmm3
+ por %xmm4, %xmm5
+ pxor %xmm4, %xmm4
+ por %xmm1, %xmm3
+
+ lea 0x40-$bias($a_ptr), $a_ptr # $a_ptr is still valid
+ lea $Z1sqr(%rsp), $r_ptr # Z1^2
+ call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(Z1sqr, in1_z);
+
+ pcmpeqd %xmm4, %xmm5
+ pshufd \$0xb1, %xmm3, %xmm4
+ mov 0x00($b_ptr), $src0 # $b_ptr is still valid
+ #lea 0x00($b_ptr), $b_ptr
+ mov $acc4, $acc1 # harmonize sqr output and mul input
+ por %xmm3, %xmm4
+ pshufd \$0, %xmm5, %xmm5 # in1infty
+ pshufd \$0x1e, %xmm4, %xmm3
+ mov $acc5, $acc2
+ por %xmm3, %xmm4
+ pxor %xmm3, %xmm3
+ mov $acc6, $acc3
+ pcmpeqd %xmm3, %xmm4
+ pshufd \$0, %xmm4, %xmm4 # in2infty
+
+ lea $Z1sqr-$bias(%rsp), $a_ptr
+ mov $acc7, $acc4
+ lea $U2(%rsp), $r_ptr # U2 = X2*Z1^2
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(U2, Z1sqr, in2_x);
+
+ lea $in1_x(%rsp), $b_ptr
+ lea $H(%rsp), $r_ptr # H = U2 - U1
+ call __ecp_nistz256_sub_from$x # p256_sub(H, U2, in1_x);
+
+ `&load_for_mul("$Z1sqr(%rsp)", "$in1_z(%rsp)", "$src0")`
+ lea $S2(%rsp), $r_ptr # S2 = Z1^3
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(S2, Z1sqr, in1_z);
+
+ `&load_for_mul("$H(%rsp)", "$in1_z(%rsp)", "$src0")`
+ lea $res_z(%rsp), $r_ptr # Z3 = H*Z1*Z2
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(res_z, H, in1_z);
+
+ `&load_for_mul("$S2(%rsp)", "$in2_y(%rsp)", "$src0")`
+ lea $S2(%rsp), $r_ptr # S2 = Y2*Z1^3
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(S2, S2, in2_y);
+
+ lea $in1_y(%rsp), $b_ptr
+ lea $R(%rsp), $r_ptr # R = S2 - S1
+ call __ecp_nistz256_sub_from$x # p256_sub(R, S2, in1_y);
+
+ `&load_for_sqr("$H(%rsp)", "$src0")`
+ lea $Hsqr(%rsp), $r_ptr # H^2
+ call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(Hsqr, H);
+
+ `&load_for_sqr("$R(%rsp)", "$src0")`
+ lea $Rsqr(%rsp), $r_ptr # R^2
+ call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(Rsqr, R);
+
+ `&load_for_mul("$H(%rsp)", "$Hsqr(%rsp)", "$src0")`
+ lea $Hcub(%rsp), $r_ptr # H^3
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(Hcub, Hsqr, H);
+
+ `&load_for_mul("$Hsqr(%rsp)", "$in1_x(%rsp)", "$src0")`
+ lea $U2(%rsp), $r_ptr # U1*H^2
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(U2, in1_x, Hsqr);
+___
+{
+#######################################################################
+# operate in 4-5-0-1 "name space" that matches multiplication output
+#
+my ($acc0,$acc1,$acc2,$acc3,$t3,$t4)=($acc4,$acc5,$acc0,$acc1,$acc2,$acc3);
+my ($poly1, $poly3)=($acc6,$acc7);
+
+$code.=<<___;
+ #lea $U2(%rsp), $a_ptr
+ #lea $Hsqr(%rsp), $r_ptr # 2*U1*H^2
+ #call __ecp_nistz256_mul_by_2 # ecp_nistz256_mul_by_2(Hsqr, U2);
+
+ add $acc0, $acc0 # a0:a3+a0:a3
+ lea $Rsqr(%rsp), $a_ptr
+ adc $acc1, $acc1
+ mov $acc0, $t0
+ adc $acc2, $acc2
+ adc $acc3, $acc3
+ mov $acc1, $t1
+ sbb $t4, $t4
+
+ sub \$-1, $acc0
+ mov $acc2, $t2
+ sbb $poly1, $acc1
+ sbb \$0, $acc2
+ mov $acc3, $t3
+ sbb $poly3, $acc3
+ test $t4, $t4
+
+ cmovz $t0, $acc0
+ mov 8*0($a_ptr), $t0
+ cmovz $t1, $acc1
+ mov 8*1($a_ptr), $t1
+ cmovz $t2, $acc2
+ mov 8*2($a_ptr), $t2
+ cmovz $t3, $acc3
+ mov 8*3($a_ptr), $t3
+
+ call __ecp_nistz256_sub$x # p256_sub(res_x, Rsqr, Hsqr);
+
+ lea $Hcub(%rsp), $b_ptr
+ lea $res_x(%rsp), $r_ptr
+ call __ecp_nistz256_sub_from$x # p256_sub(res_x, res_x, Hcub);
+
+ mov $U2+8*0(%rsp), $t0
+ mov $U2+8*1(%rsp), $t1
+ mov $U2+8*2(%rsp), $t2
+ mov $U2+8*3(%rsp), $t3
+ lea $H(%rsp), $r_ptr
+
+ call __ecp_nistz256_sub$x # p256_sub(H, U2, res_x);
+
+ mov $acc0, 8*0($r_ptr) # save the result, as
+ mov $acc1, 8*1($r_ptr) # __ecp_nistz256_sub doesn't
+ mov $acc2, 8*2($r_ptr)
+ mov $acc3, 8*3($r_ptr)
+___
+}
+$code.=<<___;
+ `&load_for_mul("$Hcub(%rsp)", "$in1_y(%rsp)", "$src0")`
+ lea $S2(%rsp), $r_ptr
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(S2, Hcub, in1_y);
+
+ `&load_for_mul("$H(%rsp)", "$R(%rsp)", "$src0")`
+ lea $H(%rsp), $r_ptr
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(H, H, R);
+
+ lea $S2(%rsp), $b_ptr
+ lea $res_y(%rsp), $r_ptr
+ call __ecp_nistz256_sub_from$x # p256_sub(res_y, H, S2);
+
+ movq %xmm0, $r_ptr # restore $r_ptr
+
+ movdqa %xmm5, %xmm0 # copy_conditional(res_z, ONE, in1infty);
+ movdqa %xmm5, %xmm1
+ pandn $res_z(%rsp), %xmm0
+ movdqa %xmm5, %xmm2
+ pandn $res_z+0x10(%rsp), %xmm1
+ movdqa %xmm5, %xmm3
+ pand .LONE_mont(%rip), %xmm2
+ pand .LONE_mont+0x10(%rip), %xmm3
+ por %xmm0, %xmm2
+ por %xmm1, %xmm3
+
+ movdqa %xmm4, %xmm0 # copy_conditional(res_z, in1_z, in2infty);
+ movdqa %xmm4, %xmm1
+ pandn %xmm2, %xmm0
+ movdqa %xmm4, %xmm2
+ pandn %xmm3, %xmm1
+ movdqa %xmm4, %xmm3
+ pand $in1_z(%rsp), %xmm2
+ pand $in1_z+0x10(%rsp), %xmm3
+ por %xmm0, %xmm2
+ por %xmm1, %xmm3
+ movdqu %xmm2, 0x40($r_ptr)
+ movdqu %xmm3, 0x50($r_ptr)
+
+ movdqa %xmm5, %xmm0 # copy_conditional(res_x, in2_x, in1infty);
+ movdqa %xmm5, %xmm1
+ pandn $res_x(%rsp), %xmm0
+ movdqa %xmm5, %xmm2
+ pandn $res_x+0x10(%rsp), %xmm1
+ movdqa %xmm5, %xmm3
+ pand $in2_x(%rsp), %xmm2
+ pand $in2_x+0x10(%rsp), %xmm3
+ por %xmm0, %xmm2
+ por %xmm1, %xmm3
+
+ movdqa %xmm4, %xmm0 # copy_conditional(res_x, in1_x, in2infty);
+ movdqa %xmm4, %xmm1
+ pandn %xmm2, %xmm0
+ movdqa %xmm4, %xmm2
+ pandn %xmm3, %xmm1
+ movdqa %xmm4, %xmm3
+ pand $in1_x(%rsp), %xmm2
+ pand $in1_x+0x10(%rsp), %xmm3
+ por %xmm0, %xmm2
+ por %xmm1, %xmm3
+ movdqu %xmm2, 0x00($r_ptr)
+ movdqu %xmm3, 0x10($r_ptr)
+
+ movdqa %xmm5, %xmm0 # copy_conditional(res_y, in2_y, in1infty);
+ movdqa %xmm5, %xmm1
+ pandn $res_y(%rsp), %xmm0
+ movdqa %xmm5, %xmm2
+ pandn $res_y+0x10(%rsp), %xmm1
+ movdqa %xmm5, %xmm3
+ pand $in2_y(%rsp), %xmm2
+ pand $in2_y+0x10(%rsp), %xmm3
+ por %xmm0, %xmm2
+ por %xmm1, %xmm3
+
+ movdqa %xmm4, %xmm0 # copy_conditional(res_y, in1_y, in2infty);
+ movdqa %xmm4, %xmm1
+ pandn %xmm2, %xmm0
+ movdqa %xmm4, %xmm2
+ pandn %xmm3, %xmm1
+ movdqa %xmm4, %xmm3
+ pand $in1_y(%rsp), %xmm2
+ pand $in1_y+0x10(%rsp), %xmm3
+ por %xmm0, %xmm2
+ por %xmm1, %xmm3
+ movdqu %xmm2, 0x20($r_ptr)
+ movdqu %xmm3, 0x30($r_ptr)
+
+ add \$32*15+8, %rsp
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbx
+ pop %rbp
+ ret
+.size ecp_nistz256_point_add_affine$sfx,.-ecp_nistz256_point_add_affine$sfx
+___
+}
+&gen_add_affine("q");
+
+########################################################################
+# AD*X magic
+#
+if ($addx) { {
+########################################################################
+# operate in 4-5-0-1 "name space" that matches multiplication output
+#
+my ($a0,$a1,$a2,$a3,$t3,$t4)=($acc4,$acc5,$acc0,$acc1,$acc2,$acc3);
+
+$code.=<<___;
+.type __ecp_nistz256_add_tox,\@abi-omnipotent
+.align 32
+__ecp_nistz256_add_tox:
+ xor $t4, $t4
+ adc 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
+
+ xor $t3, $t3
+ sbb \$-1, $a0
+ mov $a2, $t2
+ sbb $poly1, $a1
+ sbb \$0, $a2
+ mov $a3, $t3
+ sbb $poly3, $a3
+
+ bt \$0, $t4
+ cmovnc $t0, $a0
+ cmovnc $t1, $a1
+ mov $a0, 8*0($r_ptr)
+ cmovnc $t2, $a2
+ mov $a1, 8*1($r_ptr)
+ cmovnc $t3, $a3
+ mov $a2, 8*2($r_ptr)
+ mov $a3, 8*3($r_ptr)
+
+ ret
+.size __ecp_nistz256_add_tox,.-__ecp_nistz256_add_tox
+
+.type __ecp_nistz256_sub_fromx,\@abi-omnipotent
+.align 32
+__ecp_nistz256_sub_fromx:
+ xor $t4, $t4
+ sbb 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
+
+ xor $t3, $t3
+ adc \$-1, $a0
+ mov $a2, $t2
+ adc $poly1, $a1
+ adc \$0, $a2
+ mov $a3, $t3
+ adc $poly3, $a3
+
+ bt \$0, $t4
+ cmovnc $t0, $a0
+ cmovnc $t1, $a1
+ mov $a0, 8*0($r_ptr)
+ cmovnc $t2, $a2
+ mov $a1, 8*1($r_ptr)
+ cmovnc $t3, $a3
+ mov $a2, 8*2($r_ptr)
+ mov $a3, 8*3($r_ptr)
+
+ ret
+.size __ecp_nistz256_sub_fromx,.-__ecp_nistz256_sub_fromx
+
+.type __ecp_nistz256_subx,\@abi-omnipotent
+.align 32
+__ecp_nistz256_subx:
+ xor $t4, $t4
+ sbb $a0, $t0
+ sbb $a1, $t1
+ mov $t0, $a0
+ sbb $a2, $t2
+ sbb $a3, $t3
+ mov $t1, $a1
+ sbb \$0, $t4
+
+ xor $a3 ,$a3
+ adc \$-1, $t0
+ mov $t2, $a2
+ adc $poly1, $t1
+ adc \$0, $t2
+ mov $t3, $a3
+ adc $poly3, $t3
+
+ bt \$0, $t4
+ cmovc $t0, $a0
+ cmovc $t1, $a1
+ cmovc $t2, $a2
+ cmovc $t3, $a3
+
+ ret
+.size __ecp_nistz256_subx,.-__ecp_nistz256_subx
+
+.type __ecp_nistz256_mul_by_2x,\@abi-omnipotent
+.align 32
+__ecp_nistz256_mul_by_2x:
+ xor $t4, $t4
+ adc $a0, $a0 # a0:a3+a0:a3
+ adc $a1, $a1
+ mov $a0, $t0
+ adc $a2, $a2
+ adc $a3, $a3
+ mov $a1, $t1
+ adc \$0, $t4
+
+ xor $t3, $t3
+ sbb \$-1, $a0
+ mov $a2, $t2
+ sbb $poly1, $a1
+ sbb \$0, $a2
+ mov $a3, $t3
+ sbb $poly3, $a3
+
+ bt \$0, $t4
+ cmovnc $t0, $a0
+ cmovnc $t1, $a1
+ mov $a0, 8*0($r_ptr)
+ cmovnc $t2, $a2
+ mov $a1, 8*1($r_ptr)
+ cmovnc $t3, $a3
+ mov $a2, 8*2($r_ptr)
+ mov $a3, 8*3($r_ptr)
+
+ ret
+.size __ecp_nistz256_mul_by_2x,.-__ecp_nistz256_mul_by_2x
+___
+ }
+&gen_double("x");
+&gen_add("x");
+&gen_add_affine("x");
+}
+}}}
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/src/crypto/ec/ec.c b/src/crypto/ec/ec.c
index f38eba6..827cc57 100644
--- a/src/crypto/ec/ec.c
+++ b/src/crypto/ec/ec.c
@@ -67,6 +67,7 @@
#include <openssl/ec.h>
+#include <assert.h>
#include <string.h>
#include <openssl/bn.h>
@@ -75,6 +76,7 @@
#include <openssl/obj.h>
#include "internal.h"
+#include "../internal.h"
static const struct curve_data P224 = {
@@ -218,37 +220,120 @@ static const struct curve_data P521 = {
0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F,
0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09}};
+/* MSan appears to have a bug that causes code to be miscompiled in opt mode.
+ * While that is being looked at, don't run the uint128_t code under MSan. */
+#if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS) && \
+ !defined(MEMORY_SANITIZER)
+#define BORINGSSL_USE_INT128_CODE
+#endif
+
const struct built_in_curve OPENSSL_built_in_curves[] = {
- {NID_secp224r1, &P224, 0},
+ {NID_secp521r1, &P521, 0},
+ {NID_secp384r1, &P384, 0},
{
NID_X9_62_prime256v1, &P256,
-#if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS)
+#if defined(BORINGSSL_USE_INT128_CODE)
+#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
+ !defined(OPENSSL_SMALL)
+ EC_GFp_nistz256_method,
+#else
EC_GFp_nistp256_method,
+#endif
+#else
+ 0,
+#endif
+ },
+ {
+ NID_secp224r1, &P224,
+#if defined(BORINGSSL_USE_INT128_CODE) && !defined(OPENSSL_SMALL)
+ EC_GFp_nistp224_method,
#else
0,
#endif
},
- {NID_secp384r1, &P384, 0},
- {NID_secp521r1, &P521, 0},
{NID_undef, 0, 0},
};
+/* built_in_curve_scalar_field_monts contains Montgomery contexts for
+ * performing inversions in the scalar fields of each of the built-in
+ * curves. It's protected by |built_in_curve_scalar_field_monts_once|. */
+static const BN_MONT_CTX **built_in_curve_scalar_field_monts;
+
+static CRYPTO_once_t built_in_curve_scalar_field_monts_once;
+
+static void built_in_curve_scalar_field_monts_init(void) {
+ unsigned num_built_in_curves;
+ for (num_built_in_curves = 0;; num_built_in_curves++) {
+ if (OPENSSL_built_in_curves[num_built_in_curves].nid == NID_undef) {
+ break;
+ }
+ }
+
+ assert(0 < num_built_in_curves);
+
+ built_in_curve_scalar_field_monts =
+ OPENSSL_malloc(sizeof(BN_MONT_CTX *) * num_built_in_curves);
+ if (built_in_curve_scalar_field_monts == NULL) {
+ return;
+ }
+
+ BIGNUM *order = BN_new();
+ BN_CTX *bn_ctx = BN_CTX_new();
+ BN_MONT_CTX *mont_ctx = NULL;
+
+ if (bn_ctx == NULL ||
+ order == NULL) {
+ goto err;
+ }
+
+ unsigned i;
+ for (i = 0; i < num_built_in_curves; i++) {
+ const struct curve_data *curve = OPENSSL_built_in_curves[i].data;
+ const unsigned param_len = curve->param_len;
+ const uint8_t *params = curve->data;
+
+ mont_ctx = BN_MONT_CTX_new();
+ if (mont_ctx == NULL) {
+ goto err;
+ }
+
+ if (!BN_bin2bn(params + 5 * param_len, param_len, order) ||
+ !BN_MONT_CTX_set(mont_ctx, order, bn_ctx)) {
+ goto err;
+ }
+
+ built_in_curve_scalar_field_monts[i] = mont_ctx;
+ mont_ctx = NULL;
+ }
+
+ goto out;
+
+err:
+ BN_MONT_CTX_free(mont_ctx);
+ OPENSSL_free((BN_MONT_CTX**) built_in_curve_scalar_field_monts);
+ built_in_curve_scalar_field_monts = NULL;
+
+out:
+ BN_free(order);
+ BN_CTX_free(bn_ctx);
+}
+
EC_GROUP *ec_group_new(const EC_METHOD *meth) {
EC_GROUP *ret;
if (meth == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_group_new, EC_R_SLOT_FULL);
+ OPENSSL_PUT_ERROR(EC, EC_R_SLOT_FULL);
return NULL;
}
if (meth->group_init == 0) {
- OPENSSL_PUT_ERROR(EC, ec_group_new, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return NULL;
}
ret = OPENSSL_malloc(sizeof(EC_GROUP));
if (ret == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_group_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return NULL;
}
memset(ret, 0, sizeof(EC_GROUP));
@@ -276,8 +361,7 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
}
if (ret->meth->group_set_curve == 0) {
- OPENSSL_PUT_ERROR(EC, EC_GROUP_new_curve_GFp,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (!ret->meth->group_set_curve(ret, p, a, b, ctx)) {
@@ -325,30 +409,28 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
return 1;
}
-static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) {
+static EC_GROUP *ec_group_new_from_data(unsigned built_in_index) {
+ const struct built_in_curve *curve = &OPENSSL_built_in_curves[built_in_index];
EC_GROUP *group = NULL;
EC_POINT *P = NULL;
- BN_CTX *ctx = NULL;
- BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL, *order = NULL;
- int ok = 0;
- unsigned param_len;
+ BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
const EC_METHOD *meth;
- const struct curve_data *data;
- const uint8_t *params;
+ int ok = 0;
- if ((ctx = BN_CTX_new()) == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_MALLOC_FAILURE);
+ BN_CTX *ctx = BN_CTX_new();
+ if (ctx == NULL) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
- data = curve->data;
- param_len = data->param_len;
- params = data->data;
+ const struct curve_data *data = curve->data;
+ const unsigned param_len = data->param_len;
+ const uint8_t *params = data->data;
if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) ||
!(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) ||
!(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) {
- OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
@@ -356,45 +438,45 @@ static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) {
meth = curve->method();
if (((group = ec_group_new(meth)) == NULL) ||
(!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
- OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
} else {
if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
}
if ((P = EC_POINT_new(group)) == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) ||
!(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) {
- OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
- OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
- if (!(order = BN_bin2bn(params + 5 * param_len, param_len, NULL)) ||
- !BN_set_word(x, (BN_ULONG)data->cofactor)) {
- OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
+ if (!BN_bin2bn(params + 5 * param_len, param_len, &group->order) ||
+ !BN_set_word(&group->cofactor, (BN_ULONG)data->cofactor)) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
- group->generator = P;
- P = NULL;
- if (!BN_copy(&group->order, order) ||
- !BN_set_word(&group->cofactor, (BN_ULONG)data->cofactor)) {
- OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
- goto err;
+ CRYPTO_once(&built_in_curve_scalar_field_monts_once,
+ built_in_curve_scalar_field_monts_init);
+ if (built_in_curve_scalar_field_monts != NULL) {
+ group->mont_data = built_in_curve_scalar_field_monts[built_in_index];
}
+ group->generator = P;
+ P = NULL;
ok = 1;
err:
@@ -407,7 +489,6 @@ err:
BN_free(p);
BN_free(a);
BN_free(b);
- BN_free(order);
BN_free(x);
BN_free(y);
return group;
@@ -421,13 +502,13 @@ EC_GROUP *EC_GROUP_new_by_curve_name(int nid) {
for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) {
curve = &OPENSSL_built_in_curves[i];
if (curve->nid == nid) {
- ret = ec_group_new_from_data(curve);
+ ret = ec_group_new_from_data(i);
break;
}
}
if (ret == NULL) {
- OPENSSL_PUT_ERROR(EC, EC_GROUP_new_by_curve_name, EC_R_UNKNOWN_GROUP);
+ OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
return NULL;
}
@@ -444,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);
@@ -455,19 +534,18 @@ void EC_GROUP_free(EC_GROUP *group) {
int ec_group_copy(EC_GROUP *dest, const EC_GROUP *src) {
if (dest->meth->group_copy == 0) {
- OPENSSL_PUT_ERROR(EC, EC_GROUP_copy, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (dest->meth != src->meth) {
- OPENSSL_PUT_ERROR(EC, EC_GROUP_copy, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
if (dest == 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) {
if (dest->generator == NULL) {
@@ -480,11 +558,8 @@ int ec_group_copy(EC_GROUP *dest, const EC_GROUP *src) {
return 0;
}
} else {
- /* src->generator == NULL */
- if (dest->generator != NULL) {
- EC_POINT_clear_free(dest->generator);
- dest->generator = NULL;
- }
+ EC_POINT_clear_free(dest->generator);
+ dest->generator = NULL;
}
if (!BN_copy(&dest->order, &src->order) ||
@@ -497,6 +572,10 @@ int ec_group_copy(EC_GROUP *dest, const EC_GROUP *src) {
return dest->meth->group_copy(dest, src);
}
+const BN_MONT_CTX *ec_group_get_mont_data(const EC_GROUP *group) {
+ return group->mont_data;
+}
+
EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) {
EC_GROUP *t = NULL;
int ok = 0;
@@ -534,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,
@@ -553,72 +636,32 @@ int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a,
BIGNUM *out_b, BN_CTX *ctx) {
- if (group->meth->group_get_curve == 0) {
- OPENSSL_PUT_ERROR(EC, EC_GROUP_get_curve_GFp,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
- return group->meth->group_get_curve(group, out_p, out_a, out_b, ctx);
+ return ec_GFp_simple_group_get_curve(group, out_p, out_a, out_b, ctx);
}
int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; }
-int EC_GROUP_get_degree(const EC_GROUP *group) {
- if (group->meth->group_get_degree == 0) {
- OPENSSL_PUT_ERROR(EC, EC_GROUP_get_degree,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
- return group->meth->group_get_degree(group);
-}
-
-int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) {
- if (group->meth->mul == 0) {
- /* use default */
- return ec_wNAF_precompute_mult(group, ctx);
- }
-
- if (group->meth->precompute_mult != 0) {
- 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->meth->mul == 0) {
- /* use default */
- return ec_wNAF_have_precompute_mult(group);
- }
-
- if (group->meth->have_precompute_mult != 0) {
- return group->meth->have_precompute_mult(group);
- }
-
- return 0; /* cannot tell whether precomputation has been performed */
+unsigned EC_GROUP_get_degree(const EC_GROUP *group) {
+ return ec_GFp_simple_group_get_degree(group);
}
EC_POINT *EC_POINT_new(const EC_GROUP *group) {
EC_POINT *ret;
if (group == NULL) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_PASSED_NULL_PARAMETER);
- return NULL;
- }
- if (group->meth->point_init == 0) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
ret = OPENSSL_malloc(sizeof *ret);
if (ret == NULL) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return NULL;
}
ret->meth = group->meth;
- if (!ret->meth->point_init(ret)) {
+ if (!ec_GFp_simple_point_init(ret)) {
OPENSSL_free(ret);
return NULL;
}
@@ -631,9 +674,8 @@ void EC_POINT_free(EC_POINT *point) {
return;
}
- if (point->meth->point_finish != 0) {
- point->meth->point_finish(point);
- }
+ ec_GFp_simple_point_finish(point);
+
OPENSSL_free(point);
}
@@ -642,28 +684,21 @@ void EC_POINT_clear_free(EC_POINT *point) {
return;
}
- if (point->meth->point_clear_finish != 0) {
- point->meth->point_clear_finish(point);
- } else if (point->meth->point_finish != 0) {
- point->meth->point_finish(point);
- }
+ ec_GFp_simple_point_clear_finish(point);
+
OPENSSL_cleanse(point, sizeof *point);
OPENSSL_free(point);
}
int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) {
- if (dest->meth->point_copy == 0) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_copy, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
if (dest->meth != src->meth) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_copy, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
if (dest == src) {
return 1;
}
- return dest->meth->point_copy(dest, src);
+ return ec_GFp_simple_point_copy(dest, src);
}
EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
@@ -676,7 +711,7 @@ EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
t = EC_POINT_new(group);
if (t == NULL) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_dup, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return NULL;
}
r = EC_POINT_copy(t, a);
@@ -689,100 +724,69 @@ EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
}
int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) {
- if (group->meth->point_set_to_infinity == 0) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_set_to_infinity,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
if (group->meth != point->meth) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_set_to_infinity, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- return group->meth->point_set_to_infinity(group, point);
+ return ec_GFp_simple_point_set_to_infinity(group, point);
}
int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
- if (group->meth->is_at_infinity == 0) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_is_at_infinity,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
if (group->meth != point->meth) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_is_at_infinity, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- return group->meth->is_at_infinity(group, point);
+ return ec_GFp_simple_is_at_infinity(group, point);
}
int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
BN_CTX *ctx) {
- if (group->meth->is_on_curve == 0) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_is_on_curve,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
if (group->meth != point->meth) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_is_on_curve, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- return group->meth->is_on_curve(group, point, ctx);
+ return ec_GFp_simple_is_on_curve(group, point, ctx);
}
int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
BN_CTX *ctx) {
- if (group->meth->point_cmp == 0) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_cmp, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return -1;
- }
if ((group->meth != a->meth) || (a->meth != b->meth)) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_cmp, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return -1;
}
- return group->meth->point_cmp(group, a, b, ctx);
+ return ec_GFp_simple_cmp(group, a, b, ctx);
}
int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) {
- if (group->meth->make_affine == 0) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_make_affine,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
if (group->meth != point->meth) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_make_affine, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- return group->meth->make_affine(group, point, ctx);
+ return ec_GFp_simple_make_affine(group, point, ctx);
}
int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
BN_CTX *ctx) {
size_t i;
- if (group->meth->points_make_affine == 0) {
- OPENSSL_PUT_ERROR(EC, EC_POINTs_make_affine,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
for (i = 0; i < num; i++) {
if (group->meth != points[i]->meth) {
- OPENSSL_PUT_ERROR(EC, EC_POINTs_make_affine, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
}
- return group->meth->points_make_affine(group, num, points, ctx);
+ return ec_GFp_simple_points_make_affine(group, num, points, ctx);
}
int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
const EC_POINT *point, BIGNUM *x,
BIGNUM *y, BN_CTX *ctx) {
if (group->meth->point_get_affine_coordinates == 0) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_get_affine_coordinates_GFp,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (group->meth != point->meth) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_get_affine_coordinates_GFp,
- EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
@@ -791,100 +795,80 @@ int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
const BIGNUM *x, const BIGNUM *y,
BN_CTX *ctx) {
- if (group->meth->point_set_affine_coordinates == 0) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_set_affine_coordinates_GFp,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ if (group->meth != point->meth) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- if (group->meth != point->meth) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_set_affine_coordinates_GFp,
- EC_R_INCOMPATIBLE_OBJECTS);
+ if (!ec_GFp_simple_point_set_affine_coordinates(group, point, x, y, ctx)) {
+ return 0;
+ }
+
+ if (!EC_POINT_is_on_curve(group, point, ctx)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE);
return 0;
}
- return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
+
+ return 1;
}
int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
const EC_POINT *b, BN_CTX *ctx) {
- if (group->meth->add == 0) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_add, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
if ((group->meth != r->meth) || (r->meth != a->meth) ||
(a->meth != b->meth)) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_add, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- return group->meth->add(group, r, a, b, ctx);
+ return ec_GFp_simple_add(group, r, a, b, ctx);
}
int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
BN_CTX *ctx) {
- if (group->meth->dbl == 0) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_dbl, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
if ((group->meth != r->meth) || (r->meth != a->meth)) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_dbl, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- return group->meth->dbl(group, r, a, ctx);
+ return ec_GFp_simple_dbl(group, r, a, ctx);
}
int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) {
- if (group->meth->invert == 0) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_invert, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
if (group->meth != a->meth) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_invert, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- return group->meth->invert(group, a, ctx);
+ return ec_GFp_simple_invert(group, a, 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);
-}
+ 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;
+ }
-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->mul == 0) {
- /* use default. Warning, not constant-time. */
- return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
+ 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,
const BIGNUM *x, const BIGNUM *y,
const BIGNUM *z, BN_CTX *ctx) {
- if (group->meth->point_set_Jprojective_coordinates_GFp == 0) {
- OPENSSL_PUT_ERROR(EC, ec_point_set_Jprojective_coordinates_GFp,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
if (group->meth != point->meth) {
- OPENSSL_PUT_ERROR(EC, ec_point_set_Jprojective_coordinates_GFp,
- EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y,
- z, ctx);
+ return ec_GFp_simple_set_Jprojective_coordinates_GFp(group, point, x, y, z,
+ ctx);
}
void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) {}
diff --git a/src/crypto/ec/ec_asn1.c b/src/crypto/ec/ec_asn1.c
index ff3dca6..a085be5 100644
--- a/src/crypto/ec/ec_asn1.c
+++ b/src/crypto/ec/ec_asn1.c
@@ -168,7 +168,7 @@ ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group,
if (ret == NULL) {
ret = ECPKPARAMETERS_new();
if (ret == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_asn1_group2pkparameters, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return NULL;
}
} else {
@@ -196,7 +196,7 @@ EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params) {
int nid = NID_undef;
if (params == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_asn1_pkparameters2group, EC_R_MISSING_PARAMETERS);
+ OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS);
return NULL;
}
@@ -212,7 +212,7 @@ EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params) {
for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) {
curve = &OPENSSL_built_in_curves[i];
const unsigned param_len = curve->data->param_len;
- if (ecparams->order->length == param_len &&
+ if ((unsigned) ecparams->order->length == param_len &&
memcmp(ecparams->order->data, &curve->data->data[param_len * 5],
param_len) == 0) {
nid = curve->nid;
@@ -222,14 +222,13 @@ EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params) {
}
if (nid == NID_undef) {
- OPENSSL_PUT_ERROR(EC, ec_asn1_pkparameters2group, EC_R_NON_NAMED_CURVE);
+ OPENSSL_PUT_ERROR(EC, EC_R_NON_NAMED_CURVE);
return NULL;
}
ret = EC_GROUP_new_by_curve_name(nid);
if (ret == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_asn1_pkparameters2group,
- EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
+ OPENSSL_PUT_ERROR(EC, EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
return NULL;
}
@@ -240,17 +239,18 @@ static EC_GROUP *d2i_ECPKParameters(EC_GROUP **groupp, const uint8_t **inp,
long len) {
EC_GROUP *group = NULL;
ECPKPARAMETERS *params = NULL;
+ const uint8_t *in = *inp;
- params = d2i_ECPKPARAMETERS(NULL, inp, len);
+ params = d2i_ECPKPARAMETERS(NULL, &in, len);
if (params == NULL) {
- OPENSSL_PUT_ERROR(EC, d2i_ECPKParameters, EC_R_D2I_ECPKPARAMETERS_FAILURE);
+ OPENSSL_PUT_ERROR(EC, EC_R_D2I_ECPKPARAMETERS_FAILURE);
ECPKPARAMETERS_free(params);
return NULL;
}
group = ec_asn1_pkparameters2group(params);
if (group == NULL) {
- OPENSSL_PUT_ERROR(EC, d2i_ECPKParameters, EC_R_PKPARAMETERS2GROUP_FAILURE);
+ OPENSSL_PUT_ERROR(EC, EC_R_PKPARAMETERS2GROUP_FAILURE);
ECPKPARAMETERS_free(params);
return NULL;
}
@@ -261,6 +261,7 @@ static EC_GROUP *d2i_ECPKParameters(EC_GROUP **groupp, const uint8_t **inp,
}
ECPKPARAMETERS_free(params);
+ *inp = in;
return group;
}
@@ -268,12 +269,12 @@ static int i2d_ECPKParameters(const EC_GROUP *group, uint8_t **outp) {
int ret = 0;
ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(group, NULL);
if (tmp == NULL) {
- OPENSSL_PUT_ERROR(EC, i2d_ECPKParameters, EC_R_GROUP2PKPARAMETERS_FAILURE);
+ OPENSSL_PUT_ERROR(EC, EC_R_GROUP2PKPARAMETERS_FAILURE);
return 0;
}
ret = i2d_ECPKPARAMETERS(tmp, outp);
if (ret == 0) {
- OPENSSL_PUT_ERROR(EC, i2d_ECPKParameters, EC_R_I2D_ECPKPARAMETERS_FAILURE);
+ OPENSSL_PUT_ERROR(EC, EC_R_I2D_ECPKPARAMETERS_FAILURE);
ECPKPARAMETERS_free(tmp);
return 0;
}
@@ -281,21 +282,22 @@ static int i2d_ECPKParameters(const EC_GROUP *group, uint8_t **outp) {
return ret;
}
-EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const uint8_t **in, long len) {
+EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const uint8_t **inp, long len) {
int ok = 0;
EC_KEY *ret = NULL;
EC_PRIVATEKEY *priv_key = NULL;
- priv_key = d2i_EC_PRIVATEKEY(NULL, in, len);
+ const uint8_t *in = *inp;
+ priv_key = d2i_EC_PRIVATEKEY(NULL, &in, len);
if (priv_key == NULL) {
- OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
return NULL;
}
if (a == NULL || *a == NULL) {
ret = EC_KEY_new();
if (ret == NULL) {
- OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
} else {
@@ -308,7 +310,7 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const uint8_t **in, long len) {
}
if (ret->group == NULL) {
- OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
@@ -319,18 +321,23 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const uint8_t **in, long len) {
BN_bin2bn(M_ASN1_STRING_data(priv_key->privateKey),
M_ASN1_STRING_length(priv_key->privateKey), ret->priv_key);
if (ret->priv_key == NULL) {
- OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
} else {
- OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, EC_R_MISSING_PRIVATE_KEY);
+ OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PRIVATE_KEY);
+ 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) {
- OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
@@ -342,20 +349,20 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const uint8_t **in, long len) {
pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey);
/* The first byte (the point conversion form) must be present. */
if (pub_oct_len <= 0) {
- OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, EC_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL);
goto err;
}
/* Save the point conversion form. */
ret->conv_form = (point_conversion_form_t)(pub_oct[0] & ~0x01);
if (!EC_POINT_oct2point(ret->group, ret->pub_key, pub_oct, pub_oct_len,
NULL)) {
- OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
} else {
if (!EC_POINT_mul(ret->group, ret->pub_key, ret->priv_key, NULL, NULL,
NULL)) {
- OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
/* Remember the original private-key-only encoding. */
@@ -365,6 +372,7 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const uint8_t **in, long len) {
if (a) {
*a = ret;
}
+ *inp = in;
ok = 1;
err:
@@ -387,13 +395,13 @@ int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) {
EC_PRIVATEKEY *priv_key = NULL;
if (key == NULL || key->group == NULL || key->priv_key == NULL) {
- OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
goto err;
}
priv_key = EC_PRIVATEKEY_new();
if (priv_key == NULL) {
- OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -402,17 +410,17 @@ int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) {
buf_len = BN_num_bytes(&key->group->order);
buffer = OPENSSL_malloc(buf_len);
if (buffer == NULL) {
- OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!BN_bn2bin_padded(buffer, buf_len, key->priv_key)) {
- OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) {
- OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_ASN1_LIB);
goto err;
}
@@ -420,7 +428,7 @@ int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) {
if (!(key->enc_flag & EC_PKEY_NO_PARAMETERS)) {
if ((priv_key->parameters = ec_asn1_group2pkparameters(
key->group, priv_key->parameters)) == NULL) {
- OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
}
@@ -429,7 +437,7 @@ int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) {
if (!(key->enc_flag & EC_PKEY_NO_PUBKEY) && key->pub_key != NULL) {
priv_key->publicKey = M_ASN1_BIT_STRING_new();
if (priv_key->publicKey == NULL) {
- OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -439,7 +447,7 @@ int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) {
if (tmp_len > buf_len) {
uint8_t *tmp_buffer = OPENSSL_realloc(buffer, tmp_len);
if (!tmp_buffer) {
- OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
buffer = tmp_buffer;
@@ -448,21 +456,21 @@ int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) {
if (!EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, buffer,
buf_len, NULL)) {
- OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer, buf_len)) {
- OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_ASN1_LIB);
goto err;
}
}
ret = i2d_EC_PRIVATEKEY(priv_key, outp);
if (ret == 0) {
- OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
ok = 1;
@@ -475,7 +483,7 @@ err:
int i2d_ECParameters(const EC_KEY *key, uint8_t **outp) {
if (key == NULL) {
- OPENSSL_PUT_ERROR(EC, i2d_ECParameters, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
return i2d_ECPKParameters(key->group, outp);
@@ -485,14 +493,14 @@ EC_KEY *d2i_ECParameters(EC_KEY **key, const uint8_t **inp, long len) {
EC_KEY *ret;
if (inp == NULL || *inp == NULL) {
- OPENSSL_PUT_ERROR(EC, d2i_ECParameters, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
if (key == NULL || *key == NULL) {
ret = EC_KEY_new();
if (ret == NULL) {
- OPENSSL_PUT_ERROR(EC, d2i_ECParameters, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return NULL;
}
} else {
@@ -500,7 +508,7 @@ EC_KEY *d2i_ECParameters(EC_KEY **key, const uint8_t **inp, long len) {
}
if (!d2i_ECPKParameters(&ret->group, inp, len)) {
- OPENSSL_PUT_ERROR(EC, d2i_ECParameters, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
if (key == NULL || *key == NULL) {
EC_KEY_free(ret);
}
@@ -517,17 +525,17 @@ EC_KEY *o2i_ECPublicKey(EC_KEY **keyp, const uint8_t **inp, long len) {
EC_KEY *ret = NULL;
if (keyp == NULL || *keyp == NULL || (*keyp)->group == NULL) {
- OPENSSL_PUT_ERROR(EC, o2i_ECPublicKey, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
ret = *keyp;
if (ret->pub_key == NULL &&
(ret->pub_key = EC_POINT_new(ret->group)) == NULL) {
- OPENSSL_PUT_ERROR(EC, o2i_ECPublicKey, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return 0;
}
if (!EC_POINT_oct2point(ret->group, ret->pub_key, *inp, len, NULL)) {
- OPENSSL_PUT_ERROR(EC, o2i_ECPublicKey, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
return 0;
}
/* save the point conversion form */
@@ -541,7 +549,7 @@ int i2o_ECPublicKey(const EC_KEY *key, uint8_t **outp) {
int new_buffer = 0;
if (key == NULL) {
- OPENSSL_PUT_ERROR(EC, i2o_ECPublicKey, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
@@ -556,14 +564,14 @@ int i2o_ECPublicKey(const EC_KEY *key, uint8_t **outp) {
if (*outp == NULL) {
*outp = OPENSSL_malloc(buf_len);
if (*outp == NULL) {
- OPENSSL_PUT_ERROR(EC, i2o_ECPublicKey, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return 0;
}
new_buffer = 1;
}
if (!EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, *outp,
buf_len, NULL)) {
- OPENSSL_PUT_ERROR(EC, i2o_ECPublicKey, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
if (new_buffer) {
OPENSSL_free(*outp);
*outp = NULL;
diff --git a/src/crypto/ec/ec_key.c b/src/crypto/ec/ec_key.c
index e5cbfed..d3bf4c6 100644
--- a/src/crypto/ec/ec_key.c
+++ b/src/crypto/ec/ec_key.c
@@ -87,7 +87,7 @@ EC_KEY *EC_KEY_new(void) { return EC_KEY_new_method(NULL); }
EC_KEY *EC_KEY_new_method(const ENGINE *engine) {
EC_KEY *ret = (EC_KEY *)OPENSSL_malloc(sizeof(EC_KEY));
if (ret == NULL) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_new_method, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -104,30 +104,24 @@ 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) {
EC_KEY *ret = EC_KEY_new();
if (ret == NULL) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_new_by_curve_name, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return NULL;
}
ret->group = EC_GROUP_new_by_curve_name(nid);
@@ -166,7 +160,7 @@ void EC_KEY_free(EC_KEY *r) {
EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) {
if (dest == NULL || src == NULL) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_copy, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
/* Copy the parameters. */
@@ -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,72 +294,57 @@ 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) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, EC_R_POINT_AT_INFINITY);
+ OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
goto err;
}
ctx = BN_CTX_new();
- point = EC_POINT_new(eckey->group);
- if (ctx == NULL ||
- point == NULL) {
+ if (ctx == NULL) {
goto err;
}
/* testing whether the pub_key is on the elliptic curve */
if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx)) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, EC_R_POINT_IS_NOT_ON_CURVE);
+ 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_KEY_check_key, EC_R_INVALID_GROUP_ORDER);
- goto err;
- }
- if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, ERR_R_EC_LIB);
- goto err;
- }
- if (!EC_POINT_is_at_infinity(eckey->group, point)) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, EC_R_WRONG_ORDER);
+ 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;
}
/* in case the priv_key is present :
* check if generator * priv_key == pub_key
*/
if (eckey->priv_key) {
- if (BN_cmp(eckey->priv_key, order) >= 0) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, EC_R_WRONG_ORDER);
+ /* 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)) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, ERR_R_EC_LIB);
+ 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;
}
if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, EC_R_INVALID_PRIVATE_KEY);
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_PRIVATE_KEY);
goto err;
}
}
@@ -371,8 +364,7 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
int ok = 0;
if (!key || !key->group || !x || !y) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_set_public_key_affine_coordinates,
- ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
ctx = BN_CTX_new();
@@ -394,8 +386,7 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
/* Check if retrieved coordinates match originals: if not values
* are out of range. */
if (BN_cmp(x, tx) || BN_cmp(y, ty)) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_set_public_key_affine_coordinates,
- EC_R_COORDINATES_OUT_OF_RANGE);
+ OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE);
goto err;
}
@@ -417,23 +408,14 @@ 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) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_generate_key, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
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) {
@@ -443,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;
@@ -462,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;
}
@@ -472,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 74dbc6c..1d4113d 100644
--- a/src/crypto/ec/ec_montgomery.c
+++ b/src/crypto/ec/ec_montgomery.c
@@ -74,49 +74,6 @@
#include "internal.h"
-const EC_METHOD *EC_GFp_mont_method(void) {
- static const EC_METHOD ret = {EC_FLAGS_DEFAULT_OCT,
- ec_GFp_mont_group_init,
- ec_GFp_mont_group_finish,
- ec_GFp_mont_group_clear_finish,
- ec_GFp_mont_group_copy,
- ec_GFp_mont_group_set_curve,
- ec_GFp_simple_group_get_curve,
- ec_GFp_simple_group_get_degree,
- ec_GFp_simple_group_check_discriminant,
- ec_GFp_simple_point_init,
- ec_GFp_simple_point_finish,
- ec_GFp_simple_point_clear_finish,
- ec_GFp_simple_point_copy,
- ec_GFp_simple_point_set_to_infinity,
- ec_GFp_simple_set_Jprojective_coordinates_GFp,
- ec_GFp_simple_get_Jprojective_coordinates_GFp,
- ec_GFp_simple_point_set_affine_coordinates,
- ec_GFp_simple_point_get_affine_coordinates,
- 0,
- 0,
- 0,
- ec_GFp_simple_add,
- ec_GFp_simple_dbl,
- ec_GFp_simple_invert,
- ec_GFp_simple_is_at_infinity,
- ec_GFp_simple_is_on_curve,
- ec_GFp_simple_cmp,
- ec_GFp_simple_make_affine,
- ec_GFp_simple_points_make_affine,
- 0 /* mul */,
- 0 /* precompute_mult */,
- 0 /* have_precompute_mult */,
- ec_GFp_mont_field_mul,
- ec_GFp_mont_field_sqr,
- 0 /* field_div */,
- 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;
@@ -200,7 +157,7 @@ int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p,
goto err;
}
if (!BN_MONT_CTX_set(mont, p, ctx)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_mont_group_set_curve, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
one = BN_new();
@@ -232,7 +189,7 @@ err:
int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
const BIGNUM *b, BN_CTX *ctx) {
if (group->mont == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_mont_field_mul, EC_R_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(EC, EC_R_NOT_INITIALIZED);
return 0;
}
@@ -242,7 +199,7 @@ int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
BN_CTX *ctx) {
if (group->mont == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_mont_field_sqr, EC_R_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(EC, EC_R_NOT_INITIALIZED);
return 0;
}
@@ -252,7 +209,7 @@ int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
BN_CTX *ctx) {
if (group->mont == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_mont_field_encode, EC_R_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(EC, EC_R_NOT_INITIALIZED);
return 0;
}
@@ -262,7 +219,7 @@ int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
BN_CTX *ctx) {
if (group->mont == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_mont_field_decode, EC_R_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(EC, EC_R_NOT_INITIALIZED);
return 0;
}
@@ -272,7 +229,7 @@ int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r,
BN_CTX *ctx) {
if (group->one == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_mont_field_set_to_one, EC_R_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(EC, EC_R_NOT_INITIALIZED);
return 0;
}
@@ -281,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 5af42d5..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;
}
@@ -173,12 +172,84 @@ static bool TestZeroPadding() {
return true;
}
+bool TestSetAffine(const int nid) {
+ ScopedEC_KEY key(EC_KEY_new_by_curve_name(nid));
+ if (!key) {
+ return false;
+ }
+
+ const EC_GROUP *const group = EC_KEY_get0_group(key.get());
+
+ if (!EC_KEY_generate_key(key.get())) {
+ fprintf(stderr, "EC_KEY_generate_key failed with nid %d\n", nid);
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ if (!EC_POINT_is_on_curve(group, EC_KEY_get0_public_key(key.get()),
+ nullptr)) {
+ fprintf(stderr, "generated point is not on curve with nid %d", nid);
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ ScopedBIGNUM x(BN_new());
+ ScopedBIGNUM y(BN_new());
+ if (!EC_POINT_get_affine_coordinates_GFp(group,
+ EC_KEY_get0_public_key(key.get()),
+ x.get(), y.get(), nullptr)) {
+ fprintf(stderr, "EC_POINT_get_affine_coordinates_GFp failed with nid %d\n",
+ nid);
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ ScopedEC_POINT point(EC_POINT_new(group));
+ if (!point) {
+ return false;
+ }
+
+ if (!EC_POINT_set_affine_coordinates_GFp(group, point.get(), x.get(), y.get(),
+ nullptr)) {
+ fprintf(stderr, "EC_POINT_set_affine_coordinates_GFp failed with nid %d\n",
+ nid);
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ // Subtract one from |y| to make the point no longer on the curve.
+ if (!BN_sub(y.get(), y.get(), BN_value_one())) {
+ return false;
+ }
+
+ ScopedEC_POINT invalid_point(EC_POINT_new(group));
+ if (!invalid_point) {
+ return false;
+ }
+
+ if (EC_POINT_set_affine_coordinates_GFp(group, invalid_point.get(), x.get(),
+ y.get(), nullptr)) {
+ fprintf(stderr,
+ "EC_POINT_set_affine_coordinates_GFp succeeded with invalid "
+ "coordinates with nid %d\n",
+ nid);
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ return true;
+}
+
int main(void) {
CRYPTO_library_init();
ERR_load_crypto_strings();
if (!Testd2i_ECPrivateKey() ||
- !TestZeroPadding()) {
+ !TestZeroPadding() ||
+ !TestSetAffine(NID_secp224r1) ||
+ !TestSetAffine(NID_X9_62_prime256v1) ||
+ !TestSetAffine(NID_secp384r1) ||
+ !TestSetAffine(NID_secp521r1)) {
fprintf(stderr, "failed\n");
return 1;
}
diff --git a/src/crypto/ec/internal.h b/src/crypto/ec/internal.h
index 71062c1..bcc0e37 100644
--- a/src/crypto/ec/internal.h
+++ b/src/crypto/ec/internal.h
@@ -79,13 +79,7 @@ extern "C" {
#endif
-/* Use default functions for poin2oct, oct2point and compressed coordinates */
-#define EC_FLAGS_DEFAULT_OCT 0x1
-
struct ec_method_st {
- /* Various method flags */
- int flags;
-
/* used by EC_GROUP_new, EC_GROUP_free, EC_GROUP_clear_free, EC_GROUP_copy: */
int (*group_init)(EC_GROUP *);
void (*group_finish)(EC_GROUP *);
@@ -96,87 +90,36 @@ struct ec_method_st {
/* EC_GROUP_set_curve_GF2m, and EC_GROUP_get_curve_GF2m: */
int (*group_set_curve)(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
const BIGNUM *b, BN_CTX *);
- int (*group_get_curve)(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b,
- BN_CTX *);
-
- /* used by EC_GROUP_get_degree: */
- int (*group_get_degree)(const EC_GROUP *);
-
- /* used by EC_GROUP_check: */
- int (*group_check_discriminant)(const EC_GROUP *, BN_CTX *);
-
- /* used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free, EC_POINT_copy: */
- int (*point_init)(EC_POINT *);
- void (*point_finish)(EC_POINT *);
- void (*point_clear_finish)(EC_POINT *);
- int (*point_copy)(EC_POINT *, const EC_POINT *);
-
- /* used by EC_POINT_set_to_infinity,
- * EC_POINT_set_Jprojective_coordinates_GFp,
- * EC_POINT_get_Jprojective_coordinates_GFp,
- * EC_POINT_set_affine_coordinates_GFp, ..._GF2m,
- * EC_POINT_get_affine_coordinates_GFp, ..._GF2m,
- * EC_POINT_set_compressed_coordinates_GFp, ..._GF2m:
- */
- int (*point_set_to_infinity)(const EC_GROUP *, EC_POINT *);
- int (*point_set_Jprojective_coordinates_GFp)(const EC_GROUP *, EC_POINT *,
- const BIGNUM *x, const BIGNUM *y,
- const BIGNUM *z, BN_CTX *);
- int (*point_get_Jprojective_coordinates_GFp)(const EC_GROUP *,
- const EC_POINT *, BIGNUM *x,
- BIGNUM *y, BIGNUM *z, BN_CTX *);
- int (*point_set_affine_coordinates)(const EC_GROUP *, EC_POINT *,
- const BIGNUM *x, const BIGNUM *y,
- BN_CTX *);
+
+ /* used by EC_POINT_get_affine_coordinates_GFp: */
int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *,
BIGNUM *x, BIGNUM *y, BN_CTX *);
- int (*point_set_compressed_coordinates)(const EC_GROUP *, EC_POINT *,
- const BIGNUM *x, int y_bit, BN_CTX *);
-
- /* used by EC_POINT_point2oct, EC_POINT_oct2point: */
- size_t (*point2oct)(const EC_GROUP *, const EC_POINT *,
- point_conversion_form_t form, unsigned char *buf,
- size_t len, BN_CTX *);
- int (*oct2point)(const EC_GROUP *, EC_POINT *, const unsigned char *buf,
- size_t len, BN_CTX *);
-
- /* used by EC_POINT_add, EC_POINT_dbl, ECP_POINT_invert: */
- int (*add)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
- const EC_POINT *b, BN_CTX *);
- int (*dbl)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
- int (*invert)(const EC_GROUP *, EC_POINT *, BN_CTX *);
-
- /* used by EC_POINT_is_at_infinity, EC_POINT_is_on_curve, EC_POINT_cmp: */
- int (*is_at_infinity)(const EC_GROUP *, const EC_POINT *);
- int (*is_on_curve)(const EC_GROUP *, const EC_POINT *, BN_CTX *);
- int (*point_cmp)(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
- BN_CTX *);
-
- /* used by EC_POINT_make_affine, EC_POINTs_make_affine: */
- int (*make_affine)(const EC_GROUP *, EC_POINT *, BN_CTX *);
- int (*points_make_affine)(const EC_GROUP *, size_t num, EC_POINT * [],
- 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 *);
- int (*have_precompute_mult)(const EC_GROUP *group);
+ /* 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 */
- /* 'field_mul', 'field_sqr', and 'field_div' can be used by 'add' and 'dbl'
- * so that the same implementations of point operations can be used with
- * different optimized implementations of expensive field operations: */
+ /* 'field_mul' and 'field_sqr' can be used by 'add' and 'dbl' so that the
+ * same implementations of point operations can be used with different
+ * optimized implementations of expensive field operations: */
int (*field_mul)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
const BIGNUM *b, BN_CTX *);
int (*field_sqr)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
- int (*field_div)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
- const BIGNUM *b, BN_CTX *);
int (*field_encode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
BN_CTX *); /* e.g. to Montgomery */
@@ -187,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;
@@ -199,7 +138,7 @@ 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,
* even if they appear generic */
@@ -230,11 +169,13 @@ struct ec_point_st {
EC_GROUP *ec_group_new(const EC_METHOD *meth);
int ec_group_copy(EC_GROUP *dest, const EC_GROUP *src);
-int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
- size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
- BN_CTX *);
-int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *);
-int ec_wNAF_have_precompute_mult(const EC_GROUP *group);
+/* ec_group_get_mont_data returns a Montgomery context for operations in the
+ * scalar field of |group|. It may return NULL in the case that |group| is not
+ * 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 *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 *);
@@ -245,7 +186,7 @@ int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
const BIGNUM *b, BN_CTX *);
int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
BIGNUM *b, BN_CTX *);
-int ec_GFp_simple_group_get_degree(const EC_GROUP *);
+unsigned ec_GFp_simple_group_get_degree(const EC_GROUP *);
int ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
int ec_GFp_simple_point_init(EC_POINT *);
void ec_GFp_simple_point_finish(EC_POINT *);
@@ -319,8 +260,13 @@ void ec_GFp_nistp_points_make_affine_internal(
void ec_GFp_nistp_recode_scalar_bits(uint8_t *sign, uint8_t *digit, uint8_t in);
+const EC_METHOD *EC_GFp_nistp224_method(void);
const EC_METHOD *EC_GFp_nistp256_method(void);
+/* Returns GFp methods using montgomery multiplication, with x86-64
+ * optimized P256. See http://eprint.iacr.org/2013/816. */
+const EC_METHOD *EC_GFp_nistz256_method(void);
+
struct ec_key_st {
int version;
diff --git a/src/crypto/ec/oct.c b/src/crypto/ec/oct.c
index 816a42f..e39337d 100644
--- a/src/crypto/ec/oct.c
+++ b/src/crypto/ec/oct.c
@@ -85,23 +85,15 @@ static size_t ec_GFp_simple_point2oct(const EC_GROUP *group,
if ((form != POINT_CONVERSION_COMPRESSED) &&
(form != POINT_CONVERSION_UNCOMPRESSED)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, EC_R_INVALID_FORM);
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FORM);
goto err;
}
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_GFp_simple_point2oct, 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 =
@@ -110,14 +102,14 @@ static size_t ec_GFp_simple_point2oct(const EC_GROUP *group,
/* if 'buf' is NULL, just return required length */
if (buf != NULL) {
if (len < ret) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, EC_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL);
goto err;
}
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL) {
- return 0;
+ goto err;
}
}
@@ -142,21 +134,21 @@ static size_t ec_GFp_simple_point2oct(const EC_GROUP *group,
i = 1;
if (!BN_bn2bin_padded(buf + i, field_len, x)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
i += field_len;
if (form == POINT_CONVERSION_UNCOMPRESSED) {
if (!BN_bn2bin_padded(buf + i, field_len, y)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
i += field_len;
}
if (i != ret) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
}
@@ -187,37 +179,25 @@ static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
int ret = 0;
if (len == 0) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL);
return 0;
}
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_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
- return 0;
- }
- if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
+ 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_GFp_simple_oct2point, 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;
if (len != enc_len) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
return 0;
}
@@ -231,7 +211,7 @@ static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
BN_CTX_start(ctx);
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
- if (y == NULL) {
+ if (x == NULL || y == NULL) {
goto err;
}
@@ -239,7 +219,7 @@ static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
goto err;
}
if (BN_ucmp(x, &group->field) >= 0) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
goto err;
}
@@ -252,7 +232,7 @@ static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
goto err;
}
if (BN_ucmp(y, &group->field) >= 0) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
goto err;
}
@@ -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_GFp_simple_oct2point, EC_R_POINT_IS_NOT_ON_CURVE);
- goto err;
- }
-
ret = 1;
err:
@@ -277,41 +251,21 @@ err:
int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
const uint8_t *buf, size_t len, BN_CTX *ctx) {
- if (group->meth->oct2point == 0 &&
- !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_oct2point,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
if (group->meth != point->meth) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_oct2point, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
- return ec_GFp_simple_oct2point(group, point, buf, len, ctx);
- }
-
- return group->meth->oct2point(group, point, buf, len, ctx);
+ return ec_GFp_simple_oct2point(group, point, buf, len, ctx);
}
size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point,
point_conversion_form_t form, uint8_t *buf,
size_t len, BN_CTX *ctx) {
- if (group->meth->point2oct == 0 &&
- !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_point2oct,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
if (group->meth != point->meth) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_point2oct, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
- return ec_GFp_simple_point2oct(group, point, form, buf, len, ctx);
- }
-
- return group->meth->point2oct(group, point, form, buf, len, ctx);
+ return ec_GFp_simple_point2oct(group, point, form, buf, len, ctx);
}
int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
@@ -406,9 +360,9 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
if (ERR_GET_LIB(err) == ERR_LIB_BN &&
ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) {
ERR_clear_error();
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_set_compressed_coordinates, EC_R_INVALID_COMPRESSED_POINT);
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSED_POINT);
} else {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_set_compressed_coordinates, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
}
goto err;
}
@@ -423,12 +377,10 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
}
if (kron == 1) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_set_compressed_coordinates,
- EC_R_INVALID_COMPRESSION_BIT);
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSION_BIT);
} else {
/* BN_mod_sqrt() should have cought this error (not a square) */
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_set_compressed_coordinates,
- EC_R_INVALID_COMPRESSED_POINT);
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSED_POINT);
}
goto err;
}
@@ -437,8 +389,7 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
}
}
if (y_bit != BN_is_odd(y)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_set_compressed_coordinates,
- ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -457,21 +408,9 @@ err:
int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group,
EC_POINT *point, const BIGNUM *x,
int y_bit, BN_CTX *ctx) {
- if (group->meth->point_set_compressed_coordinates == 0 &&
- !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_set_compressed_coordinates_GFp,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
if (group->meth != point->meth) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_set_compressed_coordinates_GFp,
- EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
- return ec_GFp_simple_set_compressed_coordinates(group, point, x, y_bit,
- ctx);
- }
- return group->meth->point_set_compressed_coordinates(group, point, x, y_bit,
- ctx);
+ return ec_GFp_simple_set_compressed_coordinates(group, point, x, y_bit, ctx);
}
diff --git a/src/crypto/ec/p224-64.c b/src/crypto/ec/p224-64.c
new file mode 100644
index 0000000..e026fc4
--- /dev/null
+++ b/src/crypto/ec/p224-64.c
@@ -0,0 +1,1305 @@
+/* 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. */
+
+/* A 64-bit implementation of the NIST P-224 elliptic curve point multiplication
+ *
+ * Inspired by Daniel J. Bernstein's public domain nistp224 implementation
+ * and Adam Langley's public domain 64-bit C implementation of curve25519. */
+
+#include <openssl/base.h>
+
+#if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS) && \
+ !defined(OPENSSL_SMALL)
+
+#include <openssl/bn.h>
+#include <openssl/ec.h>
+#include <openssl/err.h>
+#include <openssl/mem.h>
+#include <openssl/obj.h>
+
+#include <string.h>
+
+#include "internal.h"
+
+
+typedef uint8_t u8;
+typedef uint64_t u64;
+typedef int64_t s64;
+
+/* Field elements are represented as a_0 + 2^56*a_1 + 2^112*a_2 + 2^168*a_3
+ * using 64-bit coefficients called 'limbs', and sometimes (for multiplication
+ * results) as b_0 + 2^56*b_1 + 2^112*b_2 + 2^168*b_3 + 2^224*b_4 + 2^280*b_5 +
+ * 2^336*b_6 using 128-bit coefficients called 'widelimbs'. A 4-limb
+ * representation is an 'felem'; a 7-widelimb representation is a 'widefelem'.
+ * Even within felems, bits of adjacent limbs overlap, and we don't always
+ * reduce the representations: we ensure that inputs to each felem
+ * multiplication satisfy a_i < 2^60, so outputs satisfy b_i < 4*2^60*2^60, and
+ * fit into a 128-bit word without overflow. The coefficients are then again
+ * partially reduced to obtain an felem satisfying a_i < 2^57. We only reduce
+ * to the unique minimal representation at the end of the computation. */
+
+typedef uint64_t limb;
+typedef __uint128_t widelimb;
+
+typedef limb felem[4];
+typedef widelimb widefelem[7];
+
+/* Field element represented as a byte arrary. 28*8 = 224 bits is also the
+ * group order size for the elliptic curve, and we also use this type for
+ * scalars for point multiplication. */
+typedef u8 felem_bytearray[28];
+
+static const felem_bytearray nistp224_curve_params[5] = {
+ {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+ {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE},
+ {0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, /* b */
+ 0x32, 0x56, 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B,
+ 0x39, 0x43, 0x23, 0x55, 0xFF, 0xB4},
+ {0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, /* x */
+ 0x90, 0xB9, 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32,
+ 0x80, 0xD6, 0x11, 0x5C, 0x1D, 0x21},
+ {0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, /* y */
+ 0xdf, 0xe6, 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5,
+ 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34}};
+
+/* Precomputed multiples of the standard generator
+ * Points are given in coordinates (X, Y, Z) where Z normally is 1
+ * (0 for the point at infinity).
+ * For each field element, slice a_0 is word 0, etc.
+ *
+ * The table has 2 * 16 elements, starting with the following:
+ * index | bits | point
+ * ------+---------+------------------------------
+ * 0 | 0 0 0 0 | 0G
+ * 1 | 0 0 0 1 | 1G
+ * 2 | 0 0 1 0 | 2^56G
+ * 3 | 0 0 1 1 | (2^56 + 1)G
+ * 4 | 0 1 0 0 | 2^112G
+ * 5 | 0 1 0 1 | (2^112 + 1)G
+ * 6 | 0 1 1 0 | (2^112 + 2^56)G
+ * 7 | 0 1 1 1 | (2^112 + 2^56 + 1)G
+ * 8 | 1 0 0 0 | 2^168G
+ * 9 | 1 0 0 1 | (2^168 + 1)G
+ * 10 | 1 0 1 0 | (2^168 + 2^56)G
+ * 11 | 1 0 1 1 | (2^168 + 2^56 + 1)G
+ * 12 | 1 1 0 0 | (2^168 + 2^112)G
+ * 13 | 1 1 0 1 | (2^168 + 2^112 + 1)G
+ * 14 | 1 1 1 0 | (2^168 + 2^112 + 2^56)G
+ * 15 | 1 1 1 1 | (2^168 + 2^112 + 2^56 + 1)G
+ * followed by a copy of this with each element multiplied by 2^28.
+ *
+ * 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 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},
+ {1, 0, 0, 0}},
+ {{0xfd9675666ebbe9, 0xbca7664d40ce5e, 0x2242df8d8a2a43, 0x1f49bbb0f99bc5},
+ {0x29e0b892dc9c43, 0xece8608436e662, 0xdc858f185310d0, 0x9812dd4eb8d321},
+ {1, 0, 0, 0}},
+ {{0x6d3e678d5d8eb8, 0x559eed1cb362f1, 0x16e9a3bbce8a3f, 0xeedcccd8c2a748},
+ {0xf19f90ed50266d, 0xabf2b4bf65f9df, 0x313865468fafec, 0x5cb379ba910a17},
+ {1, 0, 0, 0}},
+ {{0x0641966cab26e3, 0x91fb2991fab0a0, 0xefec27a4e13a0b, 0x0499aa8a5f8ebe},
+ {0x7510407766af5d, 0x84d929610d5450, 0x81d77aae82f706, 0x6916f6d4338c5b},
+ {1, 0, 0, 0}},
+ {{0xea95ac3b1f15c6, 0x086000905e82d4, 0xdd323ae4d1c8b1, 0x932b56be7685a3},
+ {0x9ef93dea25dbbf, 0x41665960f390f0, 0xfdec76dbe2a8a7, 0x523e80f019062a},
+ {1, 0, 0, 0}},
+ {{0x822fdd26732c73, 0xa01c83531b5d0f, 0x363f37347c1ba4, 0xc391b45c84725c},
+ {0xbbd5e1b2d6ad24, 0xddfbcde19dfaec, 0xc393da7e222a7f, 0x1efb7890ede244},
+ {1, 0, 0, 0}},
+ {{0x4c9e90ca217da1, 0xd11beca79159bb, 0xff8d33c2c98b7c, 0x2610b39409f849},
+ {0x44d1352ac64da0, 0xcdbb7b2c46b4fb, 0x966c079b753c89, 0xfe67e4e820b112},
+ {1, 0, 0, 0}},
+ {{0xe28cae2df5312d, 0xc71b61d16f5c6e, 0x79b7619a3e7c4c, 0x05c73240899b47},
+ {0x9f7f6382c73e3a, 0x18615165c56bda, 0x641fab2116fd56, 0x72855882b08394},
+ {1, 0, 0, 0}},
+ {{0x0469182f161c09, 0x74a98ca8d00fb5, 0xb89da93489a3e0, 0x41c98768fb0c1d},
+ {0xe5ea05fb32da81, 0x3dce9ffbca6855, 0x1cfe2d3fbf59e6, 0x0e5e03408738a7},
+ {1, 0, 0, 0}},
+ {{0xdab22b2333e87f, 0x4430137a5dd2f6, 0xe03ab9f738beb8, 0xcb0c5d0dc34f24},
+ {0x764a7df0c8fda5, 0x185ba5c3fa2044, 0x9281d688bcbe50, 0xc40331df893881},
+ {1, 0, 0, 0}},
+ {{0xb89530796f0f60, 0xade92bd26909a3, 0x1a0c83fb4884da, 0x1765bf22a5a984},
+ {0x772a9ee75db09e, 0x23bc6c67cec16f, 0x4c1edba8b14e2f, 0xe2a215d9611369},
+ {1, 0, 0, 0}},
+ {{0x571e509fb5efb3, 0xade88696410552, 0xc8ae85fada74fe, 0x6c7e4be83bbde3},
+ {0xff9f51160f4652, 0xb47ce2495a6539, 0xa2946c53b582f4, 0x286d2db3ee9a60},
+ {1, 0, 0, 0}},
+ {{0x40bbd5081a44af, 0x0995183b13926c, 0xbcefba6f47f6d0, 0x215619e9cc0057},
+ {0x8bc94d3b0df45e, 0xf11c54a3694f6f, 0x8631b93cdfe8b5, 0xe7e3f4b0982db9},
+ {1, 0, 0, 0}},
+ {{0xb17048ab3e1c7b, 0xac38f36ff8a1d8, 0x1c29819435d2c6, 0xc813132f4c07e9},
+ {0x2891425503b11f, 0x08781030579fea, 0xf5426ba5cc9674, 0x1e28ebf18562bc},
+ {1, 0, 0, 0}},
+ {{0x9f31997cc864eb, 0x06cd91d28b5e4c, 0xff17036691a973, 0xf1aef351497c58},
+ {0xdd1f2d600564ff, 0xdead073b1402db, 0x74a684435bd693, 0xeea7471f962558},
+ {1, 0, 0, 0}}},
+ {{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{0x9665266dddf554, 0x9613d78b60ef2d, 0xce27a34cdba417, 0xd35ab74d6afc31},
+ {0x85ccdd22deb15e, 0x2137e5783a6aab, 0xa141cffd8c93c6, 0x355a1830e90f2d},
+ {1, 0, 0, 0}},
+ {{0x1a494eadaade65, 0xd6da4da77fe53c, 0xe7992996abec86, 0x65c3553c6090e3},
+ {0xfa610b1fb09346, 0xf1c6540b8a4aaf, 0xc51a13ccd3cbab, 0x02995b1b18c28a},
+ {1, 0, 0, 0}},
+ {{0x7874568e7295ef, 0x86b419fbe38d04, 0xdc0690a7550d9a, 0xd3966a44beac33},
+ {0x2b7280ec29132f, 0xbeaa3b6a032df3, 0xdc7dd88ae41200, 0xd25e2513e3a100},
+ {1, 0, 0, 0}},
+ {{0x924857eb2efafd, 0xac2bce41223190, 0x8edaa1445553fc, 0x825800fd3562d5},
+ {0x8d79148ea96621, 0x23a01c3dd9ed8d, 0xaf8b219f9416b5, 0xd8db0cc277daea},
+ {1, 0, 0, 0}},
+ {{0x76a9c3b1a700f0, 0xe9acd29bc7e691, 0x69212d1a6b0327, 0x6322e97fe154be},
+ {0x469fc5465d62aa, 0x8d41ed18883b05, 0x1f8eae66c52b88, 0xe4fcbe9325be51},
+ {1, 0, 0, 0}},
+ {{0x825fdf583cac16, 0x020b857c7b023a, 0x683c17744b0165, 0x14ffd0a2daf2f1},
+ {0x323b36184218f9, 0x4944ec4e3b47d4, 0xc15b3080841acf, 0x0bced4b01a28bb},
+ {1, 0, 0, 0}},
+ {{0x92ac22230df5c4, 0x52f33b4063eda8, 0xcb3f19870c0c93, 0x40064f2ba65233},
+ {0xfe16f0924f8992, 0x012da25af5b517, 0x1a57bb24f723a6, 0x06f8bc76760def},
+ {1, 0, 0, 0}},
+ {{0x4a7084f7817cb9, 0xbcab0738ee9a78, 0x3ec11e11d9c326, 0xdc0fe90e0f1aae},
+ {0xcf639ea5f98390, 0x5c350aa22ffb74, 0x9afae98a4047b7, 0x956ec2d617fc45},
+ {1, 0, 0, 0}},
+ {{0x4306d648c1be6a, 0x9247cd8bc9a462, 0xf5595e377d2f2e, 0xbd1c3caff1a52e},
+ {0x045e14472409d0, 0x29f3e17078f773, 0x745a602b2d4f7d, 0x191837685cdfbb},
+ {1, 0, 0, 0}},
+ {{0x5b6ee254a8cb79, 0x4953433f5e7026, 0xe21faeb1d1def4, 0xc4c225785c09de},
+ {0x307ce7bba1e518, 0x31b125b1036db8, 0x47e91868839e8f, 0xc765866e33b9f3},
+ {1, 0, 0, 0}},
+ {{0x3bfece24f96906, 0x4794da641e5093, 0xde5df64f95db26, 0x297ecd89714b05},
+ {0x701bd3ebb2c3aa, 0x7073b4f53cb1d5, 0x13c5665658af16, 0x9895089d66fe58},
+ {1, 0, 0, 0}},
+ {{0x0fef05f78c4790, 0x2d773633b05d2e, 0x94229c3a951c94, 0xbbbd70df4911bb},
+ {0xb2c6963d2c1168, 0x105f47a72b0d73, 0x9fdf6111614080, 0x7b7e94b39e67b0},
+ {1, 0, 0, 0}},
+ {{0xad1a7d6efbe2b3, 0xf012482c0da69d, 0x6b3bdf12438345, 0x40d7558d7aa4d9},
+ {0x8a09fffb5c6d3d, 0x9a356e5d9ffd38, 0x5973f15f4f9b1c, 0xdcd5f59f63c3ea},
+ {1, 0, 0, 0}},
+ {{0xacf39f4c5ca7ab, 0x4c8071cc5fd737, 0xc64e3602cd1184, 0x0acd4644c9abba},
+ {0x6c011a36d8bf6e, 0xfecd87ba24e32a, 0x19f6f56574fad8, 0x050b204ced9405},
+ {1, 0, 0, 0}},
+ {{0xed4f1cae7d9a96, 0x5ceef7ad94c40a, 0x778e4a3bf3ef9b, 0x7405783dc3b55e},
+ {0x32477c61b6e8c6, 0xb46a97570f018b, 0x91176d0a7e95d1, 0x3df90fbc4c7d0e},
+ {1, 0, 0, 0}}}};
+
+/* Helper functions to convert field elements to/from internal representation */
+static void bin28_to_felem(felem out, const u8 in[28]) {
+ out[0] = *((const uint64_t *)(in)) & 0x00ffffffffffffff;
+ out[1] = (*((const uint64_t *)(in + 7))) & 0x00ffffffffffffff;
+ out[2] = (*((const uint64_t *)(in + 14))) & 0x00ffffffffffffff;
+ out[3] = (*((const uint64_t *)(in + 20))) >> 8;
+}
+
+static void felem_to_bin28(u8 out[28], const felem in) {
+ unsigned i;
+ for (i = 0; i < 7; ++i) {
+ out[i] = in[0] >> (8 * i);
+ out[i + 7] = in[1] >> (8 * i);
+ out[i + 14] = in[2] >> (8 * i);
+ out[i + 21] = in[3] >> (8 * i);
+ }
+}
+
+/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
+static void flip_endian(u8 *out, const u8 *in, unsigned len) {
+ unsigned i;
+ for (i = 0; i < len; ++i) {
+ out[i] = in[len - 1 - i];
+ }
+}
+
+/* From OpenSSL BIGNUM to internal representation */
+static int BN_to_felem(felem out, const BIGNUM *bn) {
+ /* BN_bn2bin eats leading zeroes */
+ felem_bytearray b_out;
+ memset(b_out, 0, sizeof(b_out));
+ unsigned num_bytes = BN_num_bytes(bn);
+ if (num_bytes > sizeof(b_out) ||
+ BN_is_negative(bn)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_BIGNUM_OUT_OF_RANGE);
+ return 0;
+ }
+
+ felem_bytearray b_in;
+ num_bytes = BN_bn2bin(bn, b_in);
+ flip_endian(b_out, b_in, num_bytes);
+ bin28_to_felem(out, b_out);
+ return 1;
+}
+
+/* From internal representation to OpenSSL BIGNUM */
+static BIGNUM *felem_to_BN(BIGNUM *out, const felem in) {
+ felem_bytearray b_in, b_out;
+ felem_to_bin28(b_in, in);
+ flip_endian(b_out, b_in, sizeof(b_out));
+ return BN_bin2bn(b_out, sizeof(b_out), out);
+}
+
+/* Field operations, using the internal representation of field elements.
+ * NB! These operations are specific to our point multiplication and cannot be
+ * expected to be correct in general - e.g., multiplication with a large scalar
+ * will cause an overflow. */
+
+static void felem_one(felem out) {
+ out[0] = 1;
+ out[1] = 0;
+ out[2] = 0;
+ out[3] = 0;
+}
+
+static void felem_assign(felem out, const felem in) {
+ out[0] = in[0];
+ out[1] = in[1];
+ out[2] = in[2];
+ out[3] = in[3];
+}
+
+/* Sum two field elements: out += in */
+static void felem_sum(felem out, const felem in) {
+ out[0] += in[0];
+ out[1] += in[1];
+ out[2] += in[2];
+ out[3] += in[3];
+}
+
+/* Get negative value: out = -in */
+/* Assumes in[i] < 2^57 */
+static void felem_neg(felem out, const felem in) {
+ static const limb two58p2 = (((limb)1) << 58) + (((limb)1) << 2);
+ static const limb two58m2 = (((limb)1) << 58) - (((limb)1) << 2);
+ static const limb two58m42m2 =
+ (((limb)1) << 58) - (((limb)1) << 42) - (((limb)1) << 2);
+
+ /* Set to 0 mod 2^224-2^96+1 to ensure out > in */
+ out[0] = two58p2 - in[0];
+ out[1] = two58m42m2 - in[1];
+ out[2] = two58m2 - in[2];
+ out[3] = two58m2 - in[3];
+}
+
+/* Subtract field elements: out -= in */
+/* Assumes in[i] < 2^57 */
+static void felem_diff(felem out, const felem in) {
+ static const limb two58p2 = (((limb)1) << 58) + (((limb)1) << 2);
+ static const limb two58m2 = (((limb)1) << 58) - (((limb)1) << 2);
+ static const limb two58m42m2 =
+ (((limb)1) << 58) - (((limb)1) << 42) - (((limb)1) << 2);
+
+ /* Add 0 mod 2^224-2^96+1 to ensure out > in */
+ out[0] += two58p2;
+ out[1] += two58m42m2;
+ out[2] += two58m2;
+ out[3] += two58m2;
+
+ out[0] -= in[0];
+ out[1] -= in[1];
+ out[2] -= in[2];
+ out[3] -= in[3];
+}
+
+/* Subtract in unreduced 128-bit mode: out -= in */
+/* Assumes in[i] < 2^119 */
+static void widefelem_diff(widefelem out, const widefelem in) {
+ static const widelimb two120 = ((widelimb)1) << 120;
+ static const widelimb two120m64 =
+ (((widelimb)1) << 120) - (((widelimb)1) << 64);
+ static const widelimb two120m104m64 =
+ (((widelimb)1) << 120) - (((widelimb)1) << 104) - (((widelimb)1) << 64);
+
+ /* Add 0 mod 2^224-2^96+1 to ensure out > in */
+ out[0] += two120;
+ out[1] += two120m64;
+ out[2] += two120m64;
+ out[3] += two120;
+ out[4] += two120m104m64;
+ out[5] += two120m64;
+ out[6] += two120m64;
+
+ out[0] -= in[0];
+ out[1] -= in[1];
+ out[2] -= in[2];
+ out[3] -= in[3];
+ out[4] -= in[4];
+ out[5] -= in[5];
+ out[6] -= in[6];
+}
+
+/* Subtract in mixed mode: out128 -= in64 */
+/* in[i] < 2^63 */
+static void felem_diff_128_64(widefelem out, const felem in) {
+ static const widelimb two64p8 = (((widelimb)1) << 64) + (((widelimb)1) << 8);
+ static const widelimb two64m8 = (((widelimb)1) << 64) - (((widelimb)1) << 8);
+ static const widelimb two64m48m8 =
+ (((widelimb)1) << 64) - (((widelimb)1) << 48) - (((widelimb)1) << 8);
+
+ /* Add 0 mod 2^224-2^96+1 to ensure out > in */
+ out[0] += two64p8;
+ out[1] += two64m48m8;
+ out[2] += two64m8;
+ out[3] += two64m8;
+
+ out[0] -= in[0];
+ out[1] -= in[1];
+ out[2] -= in[2];
+ out[3] -= in[3];
+}
+
+/* Multiply a field element by a scalar: out = out * scalar
+ * The scalars we actually use are small, so results fit without overflow */
+static void felem_scalar(felem out, const limb scalar) {
+ out[0] *= scalar;
+ out[1] *= scalar;
+ out[2] *= scalar;
+ out[3] *= scalar;
+}
+
+/* Multiply an unreduced field element by a scalar: out = out * scalar
+ * The scalars we actually use are small, so results fit without overflow */
+static void widefelem_scalar(widefelem out, const widelimb scalar) {
+ out[0] *= scalar;
+ out[1] *= scalar;
+ out[2] *= scalar;
+ out[3] *= scalar;
+ out[4] *= scalar;
+ out[5] *= scalar;
+ out[6] *= scalar;
+}
+
+/* Square a field element: out = in^2 */
+static void felem_square(widefelem out, const felem in) {
+ limb tmp0, tmp1, tmp2;
+ tmp0 = 2 * in[0];
+ tmp1 = 2 * in[1];
+ tmp2 = 2 * in[2];
+ out[0] = ((widelimb)in[0]) * in[0];
+ out[1] = ((widelimb)in[0]) * tmp1;
+ out[2] = ((widelimb)in[0]) * tmp2 + ((widelimb)in[1]) * in[1];
+ out[3] = ((widelimb)in[3]) * tmp0 + ((widelimb)in[1]) * tmp2;
+ out[4] = ((widelimb)in[3]) * tmp1 + ((widelimb)in[2]) * in[2];
+ out[5] = ((widelimb)in[3]) * tmp2;
+ out[6] = ((widelimb)in[3]) * in[3];
+}
+
+/* Multiply two field elements: out = in1 * in2 */
+static void felem_mul(widefelem out, const felem in1, const felem in2) {
+ out[0] = ((widelimb)in1[0]) * in2[0];
+ out[1] = ((widelimb)in1[0]) * in2[1] + ((widelimb)in1[1]) * in2[0];
+ out[2] = ((widelimb)in1[0]) * in2[2] + ((widelimb)in1[1]) * in2[1] +
+ ((widelimb)in1[2]) * in2[0];
+ out[3] = ((widelimb)in1[0]) * in2[3] + ((widelimb)in1[1]) * in2[2] +
+ ((widelimb)in1[2]) * in2[1] + ((widelimb)in1[3]) * in2[0];
+ out[4] = ((widelimb)in1[1]) * in2[3] + ((widelimb)in1[2]) * in2[2] +
+ ((widelimb)in1[3]) * in2[1];
+ out[5] = ((widelimb)in1[2]) * in2[3] + ((widelimb)in1[3]) * in2[2];
+ out[6] = ((widelimb)in1[3]) * in2[3];
+}
+
+/* Reduce seven 128-bit coefficients to four 64-bit coefficients.
+ * Requires in[i] < 2^126,
+ * ensures out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, out[3] <= 2^56 + 2^16 */
+static void felem_reduce(felem out, const widefelem in) {
+ static const widelimb two127p15 =
+ (((widelimb)1) << 127) + (((widelimb)1) << 15);
+ static const widelimb two127m71 =
+ (((widelimb)1) << 127) - (((widelimb)1) << 71);
+ static const widelimb two127m71m55 =
+ (((widelimb)1) << 127) - (((widelimb)1) << 71) - (((widelimb)1) << 55);
+ widelimb output[5];
+
+ /* Add 0 mod 2^224-2^96+1 to ensure all differences are positive */
+ output[0] = in[0] + two127p15;
+ output[1] = in[1] + two127m71m55;
+ output[2] = in[2] + two127m71;
+ output[3] = in[3];
+ output[4] = in[4];
+
+ /* Eliminate in[4], in[5], in[6] */
+ output[4] += in[6] >> 16;
+ output[3] += (in[6] & 0xffff) << 40;
+ output[2] -= in[6];
+
+ output[3] += in[5] >> 16;
+ output[2] += (in[5] & 0xffff) << 40;
+ output[1] -= in[5];
+
+ output[2] += output[4] >> 16;
+ output[1] += (output[4] & 0xffff) << 40;
+ output[0] -= output[4];
+
+ /* Carry 2 -> 3 -> 4 */
+ output[3] += output[2] >> 56;
+ output[2] &= 0x00ffffffffffffff;
+
+ output[4] = output[3] >> 56;
+ output[3] &= 0x00ffffffffffffff;
+
+ /* Now output[2] < 2^56, output[3] < 2^56, output[4] < 2^72 */
+
+ /* Eliminate output[4] */
+ output[2] += output[4] >> 16;
+ /* output[2] < 2^56 + 2^56 = 2^57 */
+ output[1] += (output[4] & 0xffff) << 40;
+ output[0] -= output[4];
+
+ /* Carry 0 -> 1 -> 2 -> 3 */
+ output[1] += output[0] >> 56;
+ out[0] = output[0] & 0x00ffffffffffffff;
+
+ output[2] += output[1] >> 56;
+ /* output[2] < 2^57 + 2^72 */
+ out[1] = output[1] & 0x00ffffffffffffff;
+ output[3] += output[2] >> 56;
+ /* output[3] <= 2^56 + 2^16 */
+ out[2] = output[2] & 0x00ffffffffffffff;
+
+ /* out[0] < 2^56, out[1] < 2^56, out[2] < 2^56,
+ * out[3] <= 2^56 + 2^16 (due to final carry),
+ * so out < 2*p */
+ out[3] = output[3];
+}
+
+static void felem_square_reduce(felem out, const felem in) {
+ widefelem tmp;
+ felem_square(tmp, in);
+ felem_reduce(out, tmp);
+}
+
+static void felem_mul_reduce(felem out, const felem in1, const felem in2) {
+ widefelem tmp;
+ felem_mul(tmp, in1, in2);
+ felem_reduce(out, tmp);
+}
+
+/* Reduce to unique minimal representation.
+ * Requires 0 <= in < 2*p (always call felem_reduce first) */
+static void felem_contract(felem out, const felem in) {
+ static const int64_t two56 = ((limb)1) << 56;
+ /* 0 <= in < 2*p, p = 2^224 - 2^96 + 1 */
+ /* if in > p , reduce in = in - 2^224 + 2^96 - 1 */
+ int64_t tmp[4], a;
+ tmp[0] = in[0];
+ tmp[1] = in[1];
+ tmp[2] = in[2];
+ tmp[3] = in[3];
+ /* Case 1: a = 1 iff in >= 2^224 */
+ a = (in[3] >> 56);
+ tmp[0] -= a;
+ tmp[1] += a << 40;
+ tmp[3] &= 0x00ffffffffffffff;
+ /* Case 2: a = 0 iff p <= in < 2^224, i.e., the high 128 bits are all 1 and
+ * the lower part is non-zero */
+ a = ((in[3] & in[2] & (in[1] | 0x000000ffffffffff)) + 1) |
+ (((int64_t)(in[0] + (in[1] & 0x000000ffffffffff)) - 1) >> 63);
+ a &= 0x00ffffffffffffff;
+ /* turn a into an all-one mask (if a = 0) or an all-zero mask */
+ a = (a - 1) >> 63;
+ /* subtract 2^224 - 2^96 + 1 if a is all-one */
+ tmp[3] &= a ^ 0xffffffffffffffff;
+ tmp[2] &= a ^ 0xffffffffffffffff;
+ tmp[1] &= (a ^ 0xffffffffffffffff) | 0x000000ffffffffff;
+ tmp[0] -= 1 & a;
+
+ /* eliminate negative coefficients: if tmp[0] is negative, tmp[1] must
+ * be non-zero, so we only need one step */
+ a = tmp[0] >> 63;
+ tmp[0] += two56 & a;
+ tmp[1] -= 1 & a;
+
+ /* carry 1 -> 2 -> 3 */
+ tmp[2] += tmp[1] >> 56;
+ tmp[1] &= 0x00ffffffffffffff;
+
+ tmp[3] += tmp[2] >> 56;
+ tmp[2] &= 0x00ffffffffffffff;
+
+ /* Now 0 <= out < p */
+ out[0] = tmp[0];
+ out[1] = tmp[1];
+ out[2] = tmp[2];
+ out[3] = tmp[3];
+}
+
+/* Zero-check: returns 1 if input is 0, and 0 otherwise. We know that field
+ * elements are reduced to in < 2^225, so we only need to check three cases: 0,
+ * 2^224 - 2^96 + 1, and 2^225 - 2^97 + 2 */
+static limb felem_is_zero(const felem in) {
+ limb zero = in[0] | in[1] | in[2] | in[3];
+ zero = (((int64_t)(zero)-1) >> 63) & 1;
+
+ limb two224m96p1 = (in[0] ^ 1) | (in[1] ^ 0x00ffff0000000000) |
+ (in[2] ^ 0x00ffffffffffffff) |
+ (in[3] ^ 0x00ffffffffffffff);
+ two224m96p1 = (((int64_t)(two224m96p1)-1) >> 63) & 1;
+ limb two225m97p2 = (in[0] ^ 2) | (in[1] ^ 0x00fffe0000000000) |
+ (in[2] ^ 0x00ffffffffffffff) |
+ (in[3] ^ 0x01ffffffffffffff);
+ two225m97p2 = (((int64_t)(two225m97p2)-1) >> 63) & 1;
+ return (zero | two224m96p1 | two225m97p2);
+}
+
+static limb felem_is_zero_int(const felem in) {
+ return (int)(felem_is_zero(in) & ((limb)1));
+}
+
+/* Invert a field element */
+/* Computation chain copied from djb's code */
+static void felem_inv(felem out, const felem in) {
+ felem ftmp, ftmp2, ftmp3, ftmp4;
+ widefelem tmp;
+ unsigned i;
+
+ felem_square(tmp, in);
+ felem_reduce(ftmp, tmp); /* 2 */
+ felem_mul(tmp, in, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^2 - 1 */
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^3 - 2 */
+ felem_mul(tmp, in, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^3 - 1 */
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp2, tmp); /* 2^4 - 2 */
+ felem_square(tmp, ftmp2);
+ felem_reduce(ftmp2, tmp); /* 2^5 - 4 */
+ felem_square(tmp, ftmp2);
+ felem_reduce(ftmp2, tmp); /* 2^6 - 8 */
+ felem_mul(tmp, ftmp2, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^6 - 1 */
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp2, tmp); /* 2^7 - 2 */
+ for (i = 0; i < 5; ++i) { /* 2^12 - 2^6 */
+ felem_square(tmp, ftmp2);
+ felem_reduce(ftmp2, tmp);
+ }
+ felem_mul(tmp, ftmp2, ftmp);
+ felem_reduce(ftmp2, tmp); /* 2^12 - 1 */
+ felem_square(tmp, ftmp2);
+ felem_reduce(ftmp3, tmp); /* 2^13 - 2 */
+ for (i = 0; i < 11; ++i) {/* 2^24 - 2^12 */
+ felem_square(tmp, ftmp3);
+ felem_reduce(ftmp3, tmp);
+ }
+ felem_mul(tmp, ftmp3, ftmp2);
+ felem_reduce(ftmp2, tmp); /* 2^24 - 1 */
+ felem_square(tmp, ftmp2);
+ felem_reduce(ftmp3, tmp); /* 2^25 - 2 */
+ for (i = 0; i < 23; ++i) {/* 2^48 - 2^24 */
+ felem_square(tmp, ftmp3);
+ felem_reduce(ftmp3, tmp);
+ }
+ felem_mul(tmp, ftmp3, ftmp2);
+ felem_reduce(ftmp3, tmp); /* 2^48 - 1 */
+ felem_square(tmp, ftmp3);
+ felem_reduce(ftmp4, tmp); /* 2^49 - 2 */
+ for (i = 0; i < 47; ++i) {/* 2^96 - 2^48 */
+ felem_square(tmp, ftmp4);
+ felem_reduce(ftmp4, tmp);
+ }
+ felem_mul(tmp, ftmp3, ftmp4);
+ felem_reduce(ftmp3, tmp); /* 2^96 - 1 */
+ felem_square(tmp, ftmp3);
+ felem_reduce(ftmp4, tmp); /* 2^97 - 2 */
+ for (i = 0; i < 23; ++i) {/* 2^120 - 2^24 */
+ felem_square(tmp, ftmp4);
+ felem_reduce(ftmp4, tmp);
+ }
+ felem_mul(tmp, ftmp2, ftmp4);
+ felem_reduce(ftmp2, tmp); /* 2^120 - 1 */
+ for (i = 0; i < 6; ++i) { /* 2^126 - 2^6 */
+ felem_square(tmp, ftmp2);
+ felem_reduce(ftmp2, tmp);
+ }
+ felem_mul(tmp, ftmp2, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^126 - 1 */
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^127 - 2 */
+ felem_mul(tmp, ftmp, in);
+ felem_reduce(ftmp, tmp); /* 2^127 - 1 */
+ for (i = 0; i < 97; ++i) {/* 2^224 - 2^97 */
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp);
+ }
+ felem_mul(tmp, ftmp, ftmp3);
+ felem_reduce(out, tmp); /* 2^224 - 2^96 - 1 */
+}
+
+/* Copy in constant time:
+ * if icopy == 1, copy in to out,
+ * if icopy == 0, copy out to itself. */
+static void copy_conditional(felem out, const felem in, limb icopy) {
+ unsigned i;
+ /* icopy is a (64-bit) 0 or 1, so copy is either all-zero or all-one */
+ const limb copy = -icopy;
+ for (i = 0; i < 4; ++i) {
+ const limb tmp = copy & (in[i] ^ out[i]);
+ out[i] ^= tmp;
+ }
+}
+
+/* ELLIPTIC CURVE POINT OPERATIONS
+ *
+ * Points are represented in Jacobian projective coordinates:
+ * (X, Y, Z) corresponds to the affine point (X/Z^2, Y/Z^3),
+ * or to the point at infinity if Z == 0. */
+
+/* Double an elliptic curve point:
+ * (X', Y', Z') = 2 * (X, Y, Z), where
+ * X' = (3 * (X - Z^2) * (X + Z^2))^2 - 8 * X * Y^2
+ * Y' = 3 * (X - Z^2) * (X + Z^2) * (4 * X * Y^2 - X') - 8 * Y^2
+ * Z' = (Y + Z)^2 - Y^2 - Z^2 = 2 * Y * Z
+ * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed,
+ * while x_out == y_in is not (maybe this works, but it's not tested). */
+static void point_double(felem x_out, felem y_out, felem z_out,
+ const felem x_in, const felem y_in, const felem z_in) {
+ widefelem tmp, tmp2;
+ felem delta, gamma, beta, alpha, ftmp, ftmp2;
+
+ felem_assign(ftmp, x_in);
+ felem_assign(ftmp2, x_in);
+
+ /* delta = z^2 */
+ felem_square(tmp, z_in);
+ felem_reduce(delta, tmp);
+
+ /* gamma = y^2 */
+ felem_square(tmp, y_in);
+ felem_reduce(gamma, tmp);
+
+ /* beta = x*gamma */
+ felem_mul(tmp, x_in, gamma);
+ felem_reduce(beta, tmp);
+
+ /* alpha = 3*(x-delta)*(x+delta) */
+ felem_diff(ftmp, delta);
+ /* ftmp[i] < 2^57 + 2^58 + 2 < 2^59 */
+ felem_sum(ftmp2, delta);
+ /* ftmp2[i] < 2^57 + 2^57 = 2^58 */
+ felem_scalar(ftmp2, 3);
+ /* ftmp2[i] < 3 * 2^58 < 2^60 */
+ felem_mul(tmp, ftmp, ftmp2);
+ /* tmp[i] < 2^60 * 2^59 * 4 = 2^121 */
+ felem_reduce(alpha, tmp);
+
+ /* x' = alpha^2 - 8*beta */
+ felem_square(tmp, alpha);
+ /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
+ felem_assign(ftmp, beta);
+ felem_scalar(ftmp, 8);
+ /* ftmp[i] < 8 * 2^57 = 2^60 */
+ felem_diff_128_64(tmp, ftmp);
+ /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
+ felem_reduce(x_out, tmp);
+
+ /* z' = (y + z)^2 - gamma - delta */
+ felem_sum(delta, gamma);
+ /* delta[i] < 2^57 + 2^57 = 2^58 */
+ felem_assign(ftmp, y_in);
+ felem_sum(ftmp, z_in);
+ /* ftmp[i] < 2^57 + 2^57 = 2^58 */
+ felem_square(tmp, ftmp);
+ /* tmp[i] < 4 * 2^58 * 2^58 = 2^118 */
+ felem_diff_128_64(tmp, delta);
+ /* tmp[i] < 2^118 + 2^64 + 8 < 2^119 */
+ felem_reduce(z_out, tmp);
+
+ /* y' = alpha*(4*beta - x') - 8*gamma^2 */
+ felem_scalar(beta, 4);
+ /* beta[i] < 4 * 2^57 = 2^59 */
+ felem_diff(beta, x_out);
+ /* beta[i] < 2^59 + 2^58 + 2 < 2^60 */
+ felem_mul(tmp, alpha, beta);
+ /* tmp[i] < 4 * 2^57 * 2^60 = 2^119 */
+ felem_square(tmp2, gamma);
+ /* tmp2[i] < 4 * 2^57 * 2^57 = 2^116 */
+ widefelem_scalar(tmp2, 8);
+ /* tmp2[i] < 8 * 2^116 = 2^119 */
+ widefelem_diff(tmp, tmp2);
+ /* tmp[i] < 2^119 + 2^120 < 2^121 */
+ felem_reduce(y_out, tmp);
+}
+
+/* Add two elliptic curve points:
+ * (X_1, Y_1, Z_1) + (X_2, Y_2, Z_2) = (X_3, Y_3, Z_3), where
+ * X_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1)^2 - (Z_1^2 * X_2 - Z_2^2 * X_1)^3 -
+ * 2 * Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^2
+ * Y_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1) * (Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 *
+ * X_1)^2 - X_3) -
+ * Z_2^3 * Y_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^3
+ * Z_3 = (Z_1^2 * X_2 - Z_2^2 * X_1) * (Z_1 * Z_2)
+ *
+ * This runs faster if 'mixed' is set, which requires Z_2 = 1 or Z_2 = 0. */
+
+/* This function is not entirely constant-time: it includes a branch for
+ * checking whether the two input points are equal, (while not equal to the
+ * point at infinity). This case never happens during single point
+ * multiplication, so there is no timing leak for ECDH or ECDSA signing. */
+static void point_add(felem x3, felem y3, felem z3, const felem x1,
+ const felem y1, const felem z1, const int mixed,
+ const felem x2, const felem y2, const felem z2) {
+ felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, x_out, y_out, z_out;
+ widefelem tmp, tmp2;
+ limb z1_is_zero, z2_is_zero, x_equal, y_equal;
+
+ if (!mixed) {
+ /* ftmp2 = z2^2 */
+ felem_square(tmp, z2);
+ felem_reduce(ftmp2, tmp);
+
+ /* ftmp4 = z2^3 */
+ felem_mul(tmp, ftmp2, z2);
+ felem_reduce(ftmp4, tmp);
+
+ /* ftmp4 = z2^3*y1 */
+ felem_mul(tmp2, ftmp4, y1);
+ felem_reduce(ftmp4, tmp2);
+
+ /* ftmp2 = z2^2*x1 */
+ felem_mul(tmp2, ftmp2, x1);
+ felem_reduce(ftmp2, tmp2);
+ } else {
+ /* We'll assume z2 = 1 (special case z2 = 0 is handled later) */
+
+ /* ftmp4 = z2^3*y1 */
+ felem_assign(ftmp4, y1);
+
+ /* ftmp2 = z2^2*x1 */
+ felem_assign(ftmp2, x1);
+ }
+
+ /* ftmp = z1^2 */
+ felem_square(tmp, z1);
+ felem_reduce(ftmp, tmp);
+
+ /* ftmp3 = z1^3 */
+ felem_mul(tmp, ftmp, z1);
+ felem_reduce(ftmp3, tmp);
+
+ /* tmp = z1^3*y2 */
+ felem_mul(tmp, ftmp3, y2);
+ /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
+
+ /* ftmp3 = z1^3*y2 - z2^3*y1 */
+ felem_diff_128_64(tmp, ftmp4);
+ /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
+ felem_reduce(ftmp3, tmp);
+
+ /* tmp = z1^2*x2 */
+ felem_mul(tmp, ftmp, x2);
+ /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
+
+ /* ftmp = z1^2*x2 - z2^2*x1 */
+ felem_diff_128_64(tmp, ftmp2);
+ /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
+ felem_reduce(ftmp, tmp);
+
+ /* the formulae are incorrect if the points are equal
+ * so we check for this and do doubling if this happens */
+ x_equal = felem_is_zero(ftmp);
+ y_equal = felem_is_zero(ftmp3);
+ z1_is_zero = felem_is_zero(z1);
+ z2_is_zero = felem_is_zero(z2);
+ /* In affine coordinates, (X_1, Y_1) == (X_2, Y_2) */
+ if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) {
+ point_double(x3, y3, z3, x1, y1, z1);
+ return;
+ }
+
+ /* ftmp5 = z1*z2 */
+ if (!mixed) {
+ felem_mul(tmp, z1, z2);
+ felem_reduce(ftmp5, tmp);
+ } else {
+ /* special case z2 = 0 is handled later */
+ felem_assign(ftmp5, z1);
+ }
+
+ /* z_out = (z1^2*x2 - z2^2*x1)*(z1*z2) */
+ felem_mul(tmp, ftmp, ftmp5);
+ felem_reduce(z_out, tmp);
+
+ /* ftmp = (z1^2*x2 - z2^2*x1)^2 */
+ felem_assign(ftmp5, ftmp);
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp);
+
+ /* ftmp5 = (z1^2*x2 - z2^2*x1)^3 */
+ felem_mul(tmp, ftmp, ftmp5);
+ felem_reduce(ftmp5, tmp);
+
+ /* ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */
+ felem_mul(tmp, ftmp2, ftmp);
+ felem_reduce(ftmp2, tmp);
+
+ /* tmp = z2^3*y1*(z1^2*x2 - z2^2*x1)^3 */
+ felem_mul(tmp, ftmp4, ftmp5);
+ /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
+
+ /* tmp2 = (z1^3*y2 - z2^3*y1)^2 */
+ felem_square(tmp2, ftmp3);
+ /* tmp2[i] < 4 * 2^57 * 2^57 < 2^116 */
+
+ /* tmp2 = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 */
+ felem_diff_128_64(tmp2, ftmp5);
+ /* tmp2[i] < 2^116 + 2^64 + 8 < 2^117 */
+
+ /* ftmp5 = 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */
+ felem_assign(ftmp5, ftmp2);
+ felem_scalar(ftmp5, 2);
+ /* ftmp5[i] < 2 * 2^57 = 2^58 */
+
+ /* x_out = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 -
+ 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */
+ felem_diff_128_64(tmp2, ftmp5);
+ /* tmp2[i] < 2^117 + 2^64 + 8 < 2^118 */
+ felem_reduce(x_out, tmp2);
+
+ /* ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out */
+ felem_diff(ftmp2, x_out);
+ /* ftmp2[i] < 2^57 + 2^58 + 2 < 2^59 */
+
+ /* tmp2 = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out) */
+ felem_mul(tmp2, ftmp3, ftmp2);
+ /* tmp2[i] < 4 * 2^57 * 2^59 = 2^118 */
+
+ /* y_out = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out) -
+ z2^3*y1*(z1^2*x2 - z2^2*x1)^3 */
+ widefelem_diff(tmp2, tmp);
+ /* tmp2[i] < 2^118 + 2^120 < 2^121 */
+ felem_reduce(y_out, tmp2);
+
+ /* the result (x_out, y_out, z_out) is incorrect if one of the inputs is
+ * the point at infinity, so we need to check for this separately */
+
+ /* if point 1 is at infinity, copy point 2 to output, and vice versa */
+ copy_conditional(x_out, x2, z1_is_zero);
+ copy_conditional(x_out, x1, z2_is_zero);
+ copy_conditional(y_out, y2, z1_is_zero);
+ copy_conditional(y_out, y1, z2_is_zero);
+ copy_conditional(z_out, z2, z1_is_zero);
+ copy_conditional(z_out, z1, z2_is_zero);
+ felem_assign(x3, x_out);
+ felem_assign(y3, y_out);
+ felem_assign(z3, z_out);
+}
+
+/* select_point selects the |idx|th point from a precomputation table and
+ * copies it to out. */
+static void select_point(const u64 idx, unsigned int size,
+ const felem pre_comp[/*size*/][3], felem out[3]) {
+ unsigned i, j;
+ limb *outlimbs = &out[0][0];
+ memset(outlimbs, 0, 3 * sizeof(felem));
+
+ for (i = 0; i < size; i++) {
+ const limb *inlimbs = &pre_comp[i][0][0];
+ u64 mask = i ^ idx;
+ mask |= mask >> 4;
+ mask |= mask >> 2;
+ mask |= mask >> 1;
+ mask &= 1;
+ mask--;
+ for (j = 0; j < 4 * 3; j++) {
+ outlimbs[j] |= inlimbs[j] & mask;
+ }
+ }
+}
+
+/* get_bit returns the |i|th bit in |in| */
+static char get_bit(const felem_bytearray in, unsigned i) {
+ if (i >= 224) {
+ return 0;
+ }
+ return (in[i >> 3] >> (i & 7)) & 1;
+}
+
+/* Interleaved point multiplication using precomputed point multiples:
+ * The small point multiples 0*P, 1*P, ..., 16*P are in pre_comp[],
+ * the scalars in scalars[]. If g_scalar is non-NULL, we also add this multiple
+ * of the generator, using certain (large) precomputed multiples in g_pre_comp.
+ * Output point (X, Y, Z) is stored in x_out, y_out, z_out */
+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]) {
+ int i, skip;
+ unsigned num;
+ unsigned gen_mul = (g_scalar != NULL);
+ felem nq[3], tmp[4];
+ u64 bits;
+ u8 sign, digit;
+
+ /* set nq to the point at infinity */
+ memset(nq, 0, 3 * sizeof(felem));
+
+ /* Loop over all scalars msb-to-lsb, interleaving additions
+ * of multiples of the generator (two in each of the last 28 rounds)
+ * and additions of other points multiples (every 5th round). */
+ skip = 1; /* save two point operations in the first round */
+ for (i = (num_points ? 220 : 27); i >= 0; --i) {
+ /* double */
+ if (!skip) {
+ point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
+ }
+
+ /* add multiples of the generator */
+ if (gen_mul && (i <= 27)) {
+ /* first, look 28 bits upwards */
+ bits = get_bit(g_scalar, i + 196) << 3;
+ bits |= get_bit(g_scalar, i + 140) << 2;
+ bits |= get_bit(g_scalar, i + 84) << 1;
+ bits |= get_bit(g_scalar, i + 28);
+ /* select the point to add, in constant time */
+ select_point(bits, 16, g_pre_comp[1], tmp);
+
+ if (!skip) {
+ point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */,
+ tmp[0], tmp[1], tmp[2]);
+ } else {
+ memcpy(nq, tmp, 3 * sizeof(felem));
+ skip = 0;
+ }
+
+ /* second, look at the current position */
+ bits = get_bit(g_scalar, i + 168) << 3;
+ bits |= get_bit(g_scalar, i + 112) << 2;
+ bits |= get_bit(g_scalar, i + 56) << 1;
+ bits |= get_bit(g_scalar, i);
+ /* select the point to add, in constant time */
+ select_point(bits, 16, g_pre_comp[0], tmp);
+ point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */, tmp[0],
+ tmp[1], tmp[2]);
+ }
+
+ /* do other additions every 5 doublings */
+ if (num_points && (i % 5 == 0)) {
+ /* loop over all scalars */
+ for (num = 0; num < num_points; ++num) {
+ bits = get_bit(scalars[num], i + 4) << 5;
+ bits |= get_bit(scalars[num], i + 3) << 4;
+ bits |= get_bit(scalars[num], i + 2) << 3;
+ bits |= get_bit(scalars[num], i + 1) << 2;
+ bits |= get_bit(scalars[num], i) << 1;
+ bits |= get_bit(scalars[num], i - 1);
+ ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
+
+ /* select the point to add or subtract */
+ select_point(digit, 17, pre_comp[num], tmp);
+ felem_neg(tmp[3], tmp[1]); /* (X, -Y, Z) is the negative point */
+ copy_conditional(tmp[1], tmp[3], sign);
+
+ if (!skip) {
+ point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], mixed, tmp[0],
+ tmp[1], tmp[2]);
+ } else {
+ memcpy(nq, tmp, 3 * sizeof(felem));
+ skip = 0;
+ }
+ }
+ }
+ }
+ felem_assign(x_out, nq[0]);
+ felem_assign(y_out, nq[1]);
+ felem_assign(z_out, nq[2]);
+}
+
+int ec_GFp_nistp224_group_init(EC_GROUP *group) {
+ int ret;
+ ret = ec_GFp_simple_group_init(group);
+ group->a_is_minus3 = 1;
+ return ret;
+}
+
+int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *b,
+ BN_CTX *ctx) {
+ int ret = 0;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *curve_p, *curve_a, *curve_b;
+
+ if (ctx == NULL) {
+ ctx = BN_CTX_new();
+ new_ctx = ctx;
+ if (ctx == NULL) {
+ return 0;
+ }
+ }
+ BN_CTX_start(ctx);
+ if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
+ ((curve_a = BN_CTX_get(ctx)) == NULL) ||
+ ((curve_b = BN_CTX_get(ctx)) == NULL)) {
+ goto err;
+ }
+ BN_bin2bn(nistp224_curve_params[0], sizeof(felem_bytearray), curve_p);
+ BN_bin2bn(nistp224_curve_params[1], sizeof(felem_bytearray), curve_a);
+ BN_bin2bn(nistp224_curve_params[2], sizeof(felem_bytearray), curve_b);
+ if (BN_cmp(curve_p, p) ||
+ BN_cmp(curve_a, a) ||
+ BN_cmp(curve_b, b)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_WRONG_CURVE_PARAMETERS);
+ goto err;
+ }
+ ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
+
+err:
+ BN_CTX_end(ctx);
+ BN_CTX_free(new_ctx);
+ return ret;
+}
+
+/* Takes the Jacobian coordinates (X, Y, Z) of a point and returns
+ * (X', Y') = (X/Z^2, Y/Z^3) */
+int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group,
+ const EC_POINT *point,
+ BIGNUM *x, BIGNUM *y,
+ BN_CTX *ctx) {
+ felem z1, z2, x_in, y_in, x_out, y_out;
+ widefelem tmp;
+
+ if (EC_POINT_is_at_infinity(group, point)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
+ return 0;
+ }
+
+ if (!BN_to_felem(x_in, &point->X) ||
+ !BN_to_felem(y_in, &point->Y) ||
+ !BN_to_felem(z1, &point->Z)) {
+ return 0;
+ }
+
+ felem_inv(z2, z1);
+ felem_square(tmp, z2);
+ felem_reduce(z1, tmp);
+ felem_mul(tmp, x_in, z1);
+ felem_reduce(x_in, tmp);
+ felem_contract(x_out, x_in);
+ if (x != NULL && !felem_to_BN(x, x_out)) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
+ return 0;
+ }
+
+ felem_mul(tmp, z1, z2);
+ felem_reduce(z1, tmp);
+ felem_mul(tmp, y_in, z1);
+ felem_reduce(y_in, tmp);
+ felem_contract(y_out, y_in);
+ if (y != NULL && !felem_to_BN(y, y_out)) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
+ return 0;
+ }
+
+ return 1;
+}
+
+static void make_points_affine(size_t num, felem points[/*num*/][3],
+ felem tmp_felems[/*num+1*/]) {
+ /* Runs in constant time, unless an input is the point at infinity
+ * (which normally shouldn't happen). */
+ ec_GFp_nistp_points_make_affine_internal(
+ num, points, sizeof(felem), tmp_felems, (void (*)(void *))felem_one,
+ (int (*)(const void *))felem_is_zero_int,
+ (void (*)(void *, const void *))felem_assign,
+ (void (*)(void *, const void *))felem_square_reduce,
+ (void (*)(void *, const void *, const void *))felem_mul_reduce,
+ (void (*)(void *, const void *))felem_inv,
+ (void (*)(void *, const void *))felem_contract);
+}
+
+int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
+ 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;
+ int mixed = 0;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *x, *y, *z, *tmp_scalar;
+ felem_bytearray g_secret;
+ felem_bytearray *secrets = NULL;
+ felem(*pre_comp)[17][3] = NULL;
+ felem *tmp_felems = NULL;
+ felem_bytearray tmp;
+ unsigned num_bytes;
+ size_t num_points = num;
+ felem x_in, y_in, z_in, x_out, y_out, z_out;
+ const EC_POINT *p = NULL;
+ const BIGNUM *p_scalar = NULL;
+
+ if (ctx == NULL) {
+ ctx = BN_CTX_new();
+ new_ctx = ctx;
+ if (ctx == NULL) {
+ return 0;
+ }
+ }
+
+ BN_CTX_start(ctx);
+ if ((x = BN_CTX_get(ctx)) == NULL ||
+ (y = BN_CTX_get(ctx)) == NULL ||
+ (z = BN_CTX_get(ctx)) == NULL ||
+ (tmp_scalar = BN_CTX_get(ctx)) == NULL) {
+ goto err;
+ }
+
+ if (num_points > 0) {
+ if (num_points >= 3) {
+ /* unless we precompute multiples for just one or two points,
+ * converting those into affine form is time well spent */
+ mixed = 1;
+ }
+ secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray));
+ pre_comp = OPENSSL_malloc(num_points * sizeof(felem[17][3]));
+ if (mixed) {
+ tmp_felems = OPENSSL_malloc((num_points * 17 + 1) * sizeof(felem));
+ }
+ if (secrets == NULL ||
+ pre_comp == NULL ||
+ (mixed && tmp_felems == NULL)) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /* we treat NULL scalars as 0, and NULL points as points at infinity,
+ * i.e., they contribute nothing to the linear combination */
+ memset(secrets, 0, num_points * sizeof(felem_bytearray));
+ memset(pre_comp, 0, num_points * 17 * 3 * sizeof(felem));
+ for (i = 0; i < num_points; ++i) {
+ if (i == num) {
+ /* the generator */
+ p = EC_GROUP_get0_generator(group);
+ p_scalar = g_scalar;
+ } else {
+ /* the i^th point */
+ p = points[i];
+ p_scalar = scalars[i];
+ }
+
+ if (p_scalar != NULL && p != NULL) {
+ /* 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 */
+ if (!BN_nnmod(tmp_scalar, p_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(p_scalar, tmp);
+ }
+
+ flip_endian(secrets[i], tmp, num_bytes);
+ /* precompute multiples */
+ if (!BN_to_felem(x_out, &p->X) ||
+ !BN_to_felem(y_out, &p->Y) ||
+ !BN_to_felem(z_out, &p->Z)) {
+ goto err;
+ }
+
+ felem_assign(pre_comp[i][1][0], x_out);
+ felem_assign(pre_comp[i][1][1], y_out);
+ felem_assign(pre_comp[i][1][2], z_out);
+
+ for (j = 2; j <= 16; ++j) {
+ if (j & 1) {
+ point_add(pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
+ pre_comp[i][1][0], pre_comp[i][1][1], pre_comp[i][1][2],
+ 0, pre_comp[i][j - 1][0], pre_comp[i][j - 1][1],
+ pre_comp[i][j - 1][2]);
+ } else {
+ point_double(pre_comp[i][j][0], pre_comp[i][j][1],
+ pre_comp[i][j][2], pre_comp[i][j / 2][0],
+ pre_comp[i][j / 2][1], pre_comp[i][j / 2][2]);
+ }
+ }
+ }
+ }
+
+ if (mixed) {
+ make_points_affine(num_points * 17, pre_comp[0], tmp_felems);
+ }
+ }
+
+ if (g_scalar != NULL) {
+ memset(g_secret, 0, sizeof(g_secret));
+ /* 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, 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(g_scalar, tmp);
+ }
+
+ flip_endian(g_secret, tmp, num_bytes);
+ }
+ 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);
+ felem_contract(y_in, y_out);
+ felem_contract(z_in, z_out);
+ if (!felem_to_BN(x, x_in) ||
+ !felem_to_BN(y, y_in) ||
+ !felem_to_BN(z, z_in)) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
+ goto err;
+ }
+ ret = ec_point_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
+
+err:
+ BN_CTX_end(ctx);
+ BN_CTX_free(new_ctx);
+ OPENSSL_free(secrets);
+ OPENSSL_free(pre_comp);
+ OPENSSL_free(tmp_felems);
+ return ret;
+}
+
+const EC_METHOD *EC_GFp_nistp224_method(void) {
+ static const EC_METHOD ret = {ec_GFp_nistp224_group_init,
+ ec_GFp_simple_group_finish,
+ ec_GFp_simple_group_clear_finish,
+ ec_GFp_simple_group_copy,
+ ec_GFp_nistp224_group_set_curve,
+ ec_GFp_nistp224_point_get_affine_coordinates,
+ ec_GFp_nistp224_points_mul,
+ 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 */};
+
+ return &ret;
+}
+
+#endif /* 64_BIT && !WINDOWS && !SMALL */
diff --git a/src/crypto/ec/p256-64.c b/src/crypto/ec/p256-64.c
index fdb942c..32852dd 100644
--- a/src/crypto/ec/p256-64.c
+++ b/src/crypto/ec/p256-64.c
@@ -125,7 +125,7 @@ static void flip_endian(u8 *out, const u8 *in, unsigned len) {
/* BN_to_felem converts an OpenSSL BIGNUM into an felem. */
static int BN_to_felem(felem out, const BIGNUM *bn) {
if (BN_is_negative(bn)) {
- OPENSSL_PUT_ERROR(EC, BN_to_felem, EC_R_BIGNUM_OUT_OF_RANGE);
+ OPENSSL_PUT_ERROR(EC, EC_R_BIGNUM_OUT_OF_RANGE);
return 0;
}
@@ -134,7 +134,7 @@ static int BN_to_felem(felem out, const BIGNUM *bn) {
memset(b_out, 0, sizeof(b_out));
unsigned num_bytes = BN_num_bytes(bn);
if (num_bytes > sizeof(b_out)) {
- OPENSSL_PUT_ERROR(EC, BN_to_felem, EC_R_BIGNUM_OUT_OF_RANGE);
+ OPENSSL_PUT_ERROR(EC, EC_R_BIGNUM_OUT_OF_RANGE);
return 0;
}
@@ -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
@@ -1638,8 +1632,7 @@ int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p,
if (BN_cmp(curve_p, p) ||
BN_cmp(curve_a, a) ||
BN_cmp(curve_b, b)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_nistp256_group_set_curve,
- EC_R_WRONG_CURVE_PARAMETERS);
+ OPENSSL_PUT_ERROR(EC, EC_R_WRONG_CURVE_PARAMETERS);
goto err;
}
ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
@@ -1661,8 +1654,7 @@ int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
longfelem tmp;
if (EC_POINT_is_at_infinity(group, point)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_nistp256_point_get_affine_coordinates,
- EC_R_POINT_AT_INFINITY);
+ OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
return 0;
}
if (!BN_to_felem(x_in, &point->X) ||
@@ -1677,8 +1669,7 @@ int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
felem_reduce(x_in, tmp);
felem_contract(x_out, x_in);
if (x != NULL && !smallfelem_to_BN(x, x_out)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_nistp256_point_get_affine_coordinates,
- ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
return 0;
}
felem_mul(tmp, z1, z2);
@@ -1687,8 +1678,7 @@ int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
felem_reduce(y_in, tmp);
felem_contract(y_out, y_in);
if (y != NULL && !smallfelem_to_BN(y, y_out)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_nistp256_point_get_affine_coordinates,
- ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
return 0;
}
return 1;
@@ -1711,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;
@@ -1728,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;
@@ -1752,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, ec_GFp_nistp256_points_mul, 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,
@@ -1787,14 +1750,14 @@ 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));
}
if (secrets == NULL || pre_comp == NULL ||
(mixed && tmp_smallfelems == NULL)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_nistp256_points_mul, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -1806,19 +1769,19 @@ 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. */
if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_nistp256_points_mul, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
num_bytes = BN_bn2bin(tmp_scalar, tmp);
@@ -1855,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)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_nistp256_points_mul, ERR_R_BN_LIB);
+ 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);
@@ -1889,14 +1845,13 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
if (!smallfelem_to_BN(x, x_in) ||
!smallfelem_to_BN(y, y_in) ||
!smallfelem_to_BN(z, z_in)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_nistp256_points_mul, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
ret = ec_point_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
err:
BN_CTX_end(ctx);
- EC_POINT_free(generator);
BN_CTX_free(new_ctx);
OPENSSL_free(secrets);
OPENSSL_free(pre_comp);
@@ -1906,26 +1861,14 @@ err:
const EC_METHOD *EC_GFp_nistp256_method(void) {
static const EC_METHOD ret = {
- EC_FLAGS_DEFAULT_OCT,
ec_GFp_nistp256_group_init,
ec_GFp_simple_group_finish,
ec_GFp_simple_group_clear_finish,
ec_GFp_simple_group_copy, ec_GFp_nistp256_group_set_curve,
- ec_GFp_simple_group_get_curve, ec_GFp_simple_group_get_degree,
- ec_GFp_simple_group_check_discriminant, ec_GFp_simple_point_init,
- ec_GFp_simple_point_finish, ec_GFp_simple_point_clear_finish,
- ec_GFp_simple_point_copy, ec_GFp_simple_point_set_to_infinity,
- ec_GFp_simple_set_Jprojective_coordinates_GFp,
- ec_GFp_simple_get_Jprojective_coordinates_GFp,
- ec_GFp_simple_point_set_affine_coordinates,
ec_GFp_nistp256_point_get_affine_coordinates,
- 0 /* point_set_compressed_coordinates */, 0 /* point2oct */,
- 0 /* oct2point */, ec_GFp_simple_add, ec_GFp_simple_dbl,
- ec_GFp_simple_invert, ec_GFp_simple_is_at_infinity,
- ec_GFp_simple_is_on_curve, ec_GFp_simple_cmp, ec_GFp_simple_make_affine,
- ec_GFp_simple_points_make_affine, ec_GFp_nistp256_points_mul,
- 0 /* precompute_mult */, 0 /* have_precompute_mult */,
- ec_GFp_simple_field_mul, ec_GFp_simple_field_sqr, 0 /* field_div */,
+ ec_GFp_nistp256_points_mul,
+ 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-table.h b/src/crypto/ec/p256-x86_64-table.h
new file mode 100644
index 0000000..5b3254c
--- /dev/null
+++ b/src/crypto/ec/p256-x86_64-table.h
@@ -0,0 +1,9548 @@
+/* Copyright (c) 2015, Intel 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 is the precomputed constant time access table for the code in
+ * p256-x86_64.c, for the default generator. The table consists of 37
+ * subtables, each subtable contains 64 affine points. The affine points are
+ * encoded as eight uint64's, four for the x coordinate and four for the y.
+ * Both values are in little-endian order. There are 37 tables because a
+ * signed, 6-bit wNAF form of the scalar is used and ceil(256/(6 + 1)) = 37.
+ * Within each table there are 64 values because the 6-bit wNAF value can take
+ * 64 values, ignoring the sign bit, which is implemented by performing a
+ * negation of the affine point when required. We would like to align it to 2MB
+ * in order to increase the chances of using a large page but that appears to
+ * lead to invalid ELF files being produced. */
+
+#if defined(__GNUC__)
+__attribute((aligned(4096)))
+#elif defined(_MSC_VER)
+__declspec(align(4096))
+#endif
+static const BN_ULONG
+ ecp_nistz256_precomputed[37][64 * sizeof(P256_POINT_AFFINE) /
+ sizeof(BN_ULONG)] = {
+ {TOBN(0x79e730d4, 0x18a9143c), TOBN(0x75ba95fc, 0x5fedb601),
+ TOBN(0x79fb732b, 0x77622510), TOBN(0x18905f76, 0xa53755c6),
+ TOBN(0xddf25357, 0xce95560a), TOBN(0x8b4ab8e4, 0xba19e45c),
+ TOBN(0xd2e88688, 0xdd21f325), TOBN(0x8571ff18, 0x25885d85),
+ TOBN(0x850046d4, 0x10ddd64d), TOBN(0xaa6ae3c1, 0xa433827d),
+ TOBN(0x73220503, 0x8d1490d9), TOBN(0xf6bb32e4, 0x3dcf3a3b),
+ TOBN(0x2f3648d3, 0x61bee1a5), TOBN(0x152cd7cb, 0xeb236ff8),
+ TOBN(0x19a8fb0e, 0x92042dbe), TOBN(0x78c57751, 0x0a5b8a3b),
+ TOBN(0xffac3f90, 0x4eebc127), TOBN(0xb027f84a, 0x087d81fb),
+ TOBN(0x66ad77dd, 0x87cbbc98), TOBN(0x26936a3f, 0xb6ff747e),
+ TOBN(0xb04c5c1f, 0xc983a7eb), TOBN(0x583e47ad, 0x0861fe1a),
+ TOBN(0x78820831, 0x1a2ee98e), TOBN(0xd5f06a29, 0xe587cc07),
+ TOBN(0x74b0b50d, 0x46918dcc), TOBN(0x4650a6ed, 0xc623c173),
+ TOBN(0x0cdaacac, 0xe8100af2), TOBN(0x577362f5, 0x41b0176b),
+ TOBN(0x2d96f24c, 0xe4cbaba6), TOBN(0x17628471, 0xfad6f447),
+ TOBN(0x6b6c36de, 0xe5ddd22e), TOBN(0x84b14c39, 0x4c5ab863),
+ TOBN(0xbe1b8aae, 0xc45c61f5), TOBN(0x90ec649a, 0x94b9537d),
+ TOBN(0x941cb5aa, 0xd076c20c), TOBN(0xc9079605, 0x890523c8),
+ TOBN(0xeb309b4a, 0xe7ba4f10), TOBN(0x73c568ef, 0xe5eb882b),
+ TOBN(0x3540a987, 0x7e7a1f68), TOBN(0x73a076bb, 0x2dd1e916),
+ TOBN(0x40394737, 0x3e77664a), TOBN(0x55ae744f, 0x346cee3e),
+ TOBN(0xd50a961a, 0x5b17a3ad), TOBN(0x13074b59, 0x54213673),
+ TOBN(0x93d36220, 0xd377e44b), TOBN(0x299c2b53, 0xadff14b5),
+ TOBN(0xf424d44c, 0xef639f11), TOBN(0xa4c9916d, 0x4a07f75f),
+ TOBN(0x0746354e, 0xa0173b4f), TOBN(0x2bd20213, 0xd23c00f7),
+ TOBN(0xf43eaab5, 0x0c23bb08), TOBN(0x13ba5119, 0xc3123e03),
+ TOBN(0x2847d030, 0x3f5b9d4d), TOBN(0x6742f2f2, 0x5da67bdd),
+ TOBN(0xef933bdc, 0x77c94195), TOBN(0xeaedd915, 0x6e240867),
+ TOBN(0x27f14cd1, 0x9499a78f), TOBN(0x462ab5c5, 0x6f9b3455),
+ TOBN(0x8f90f02a, 0xf02cfc6b), TOBN(0xb763891e, 0xb265230d),
+ TOBN(0xf59da3a9, 0x532d4977), TOBN(0x21e3327d, 0xcf9eba15),
+ TOBN(0x123c7b84, 0xbe60bbf0), TOBN(0x56ec12f2, 0x7706df76),
+ TOBN(0x75c96e8f, 0x264e20e8), TOBN(0xabe6bfed, 0x59a7a841),
+ TOBN(0x2cc09c04, 0x44c8eb00), TOBN(0xe05b3080, 0xf0c4e16b),
+ TOBN(0x1eb7777a, 0xa45f3314), TOBN(0x56af7bed, 0xce5d45e3),
+ TOBN(0x2b6e019a, 0x88b12f1a), TOBN(0x086659cd, 0xfd835f9b),
+ TOBN(0x2c18dbd1, 0x9dc21ec8), TOBN(0x98f9868a, 0x0fcf8139),
+ TOBN(0x737d2cd6, 0x48250b49), TOBN(0xcc61c947, 0x24b3428f),
+ TOBN(0x0c2b4078, 0x80dd9e76), TOBN(0xc43a8991, 0x383fbe08),
+ TOBN(0x5f7d2d65, 0x779be5d2), TOBN(0x78719a54, 0xeb3b4ab5),
+ TOBN(0xea7d260a, 0x6245e404), TOBN(0x9de40795, 0x6e7fdfe0),
+ TOBN(0x1ff3a415, 0x8dac1ab5), TOBN(0x3e7090f1, 0x649c9073),
+ TOBN(0x1a768561, 0x2b944e88), TOBN(0x250f939e, 0xe57f61c8),
+ TOBN(0x0c0daa89, 0x1ead643d), TOBN(0x68930023, 0xe125b88e),
+ TOBN(0x04b71aa7, 0xd2697768), TOBN(0xabdedef5, 0xca345a33),
+ TOBN(0x2409d29d, 0xee37385e), TOBN(0x4ee1df77, 0xcb83e156),
+ TOBN(0x0cac12d9, 0x1cbb5b43), TOBN(0x170ed2f6, 0xca895637),
+ TOBN(0x28228cfa, 0x8ade6d66), TOBN(0x7ff57c95, 0x53238aca),
+ TOBN(0xccc42563, 0x4b2ed709), TOBN(0x0e356769, 0x856fd30d),
+ TOBN(0xbcbcd43f, 0x559e9811), TOBN(0x738477ac, 0x5395b759),
+ TOBN(0x35752b90, 0xc00ee17f), TOBN(0x68748390, 0x742ed2e3),
+ TOBN(0x7cd06422, 0xbd1f5bc1), TOBN(0xfbc08769, 0xc9e7b797),
+ TOBN(0xa242a35b, 0xb0cf664a), TOBN(0x126e48f7, 0x7f9707e3),
+ TOBN(0x1717bf54, 0xc6832660), TOBN(0xfaae7332, 0xfd12c72e),
+ TOBN(0x27b52db7, 0x995d586b), TOBN(0xbe29569e, 0x832237c2),
+ TOBN(0xe8e4193e, 0x2a65e7db), TOBN(0x152706dc, 0x2eaa1bbb),
+ TOBN(0x72bcd8b7, 0xbc60055b), TOBN(0x03cc23ee, 0x56e27e4b),
+ TOBN(0xee337424, 0xe4819370), TOBN(0xe2aa0e43, 0x0ad3da09),
+ TOBN(0x40b8524f, 0x6383c45d), TOBN(0xd7663554, 0x42a41b25),
+ TOBN(0x64efa6de, 0x778a4797), TOBN(0x2042170a, 0x7079adf4),
+ TOBN(0x808b0b65, 0x0bc6fb80), TOBN(0x5882e075, 0x3ffe2e6b),
+ TOBN(0xd5ef2f7c, 0x2c83f549), TOBN(0x54d63c80, 0x9103b723),
+ TOBN(0xf2f11bd6, 0x52a23f9b), TOBN(0x3670c319, 0x4b0b6587),
+ TOBN(0x55c4623b, 0xb1580e9e), TOBN(0x64edf7b2, 0x01efe220),
+ TOBN(0x97091dcb, 0xd53c5c9d), TOBN(0xf17624b6, 0xac0a177b),
+ TOBN(0xb0f13975, 0x2cfe2dff), TOBN(0xc1a35c0a, 0x6c7a574e),
+ TOBN(0x227d3146, 0x93e79987), TOBN(0x0575bf30, 0xe89cb80e),
+ TOBN(0x2f4e247f, 0x0d1883bb), TOBN(0xebd51226, 0x3274c3d0),
+ TOBN(0x5f3e51c8, 0x56ada97a), TOBN(0x4afc964d, 0x8f8b403e),
+ TOBN(0xa6f247ab, 0x412e2979), TOBN(0x675abd1b, 0x6f80ebda),
+ TOBN(0x66a2bd72, 0x5e485a1d), TOBN(0x4b2a5caf, 0x8f4f0b3c),
+ TOBN(0x2626927f, 0x1b847bba), TOBN(0x6c6fc7d9, 0x0502394d),
+ TOBN(0xfea912ba, 0xa5659ae8), TOBN(0x68363aba, 0x25e1a16e),
+ TOBN(0xb8842277, 0x752c41ac), TOBN(0xfe545c28, 0x2897c3fc),
+ TOBN(0x2d36e9e7, 0xdc4c696b), TOBN(0x5806244a, 0xfba977c5),
+ TOBN(0x85665e9b, 0xe39508c1), TOBN(0xf720ee25, 0x6d12597b),
+ TOBN(0x8a979129, 0xd2337a31), TOBN(0x5916868f, 0x0f862bdc),
+ TOBN(0x048099d9, 0x5dd283ba), TOBN(0xe2d1eeb6, 0xfe5bfb4e),
+ TOBN(0x82ef1c41, 0x7884005d), TOBN(0xa2d4ec17, 0xffffcbae),
+ TOBN(0x9161c53f, 0x8aa95e66), TOBN(0x5ee104e1, 0xc5fee0d0),
+ TOBN(0x562e4cec, 0xc135b208), TOBN(0x74e1b265, 0x4783f47d),
+ TOBN(0x6d2a506c, 0x5a3f3b30), TOBN(0xecead9f4, 0xc16762fc),
+ TOBN(0xf29dd4b2, 0xe286e5b9), TOBN(0x1b0fadc0, 0x83bb3c61),
+ TOBN(0x7a75023e, 0x7fac29a4), TOBN(0xc086d5f1, 0xc9477fa3),
+ TOBN(0x0fc61135, 0x2f6f3076), TOBN(0xc99ffa23, 0xe3912a9a),
+ TOBN(0x6a0b0685, 0xd2f8ba3d), TOBN(0xfdc777e8, 0xe93358a4),
+ TOBN(0x94a787bb, 0x35415f04), TOBN(0x640c2d6a, 0x4d23fea4),
+ TOBN(0x9de917da, 0x153a35b5), TOBN(0x793e8d07, 0x5d5cd074),
+ TOBN(0xf4f87653, 0x2de45068), TOBN(0x37c7a7e8, 0x9e2e1f6e),
+ TOBN(0xd0825fa2, 0xa3584069), TOBN(0xaf2cea7c, 0x1727bf42),
+ TOBN(0x0360a4fb, 0x9e4785a9), TOBN(0xe5fda49c, 0x27299f4a),
+ TOBN(0x48068e13, 0x71ac2f71), TOBN(0x83d0687b, 0x9077666f),
+ TOBN(0x6d3883b2, 0x15d02819), TOBN(0x6d0d7550, 0x40dd9a35),
+ TOBN(0x61d7cbf9, 0x1d2b469f), TOBN(0xf97b232f, 0x2efc3115),
+ TOBN(0xa551d750, 0xb24bcbc7), TOBN(0x11ea4949, 0x88a1e356),
+ TOBN(0x7669f031, 0x93cb7501), TOBN(0x595dc55e, 0xca737b8a),
+ TOBN(0xa4a319ac, 0xd837879f), TOBN(0x6fc1b49e, 0xed6b67b0),
+ TOBN(0xe3959933, 0x32f1f3af), TOBN(0x966742eb, 0x65432a2e),
+ TOBN(0x4b8dc9fe, 0xb4966228), TOBN(0x96cc6312, 0x43f43950),
+ TOBN(0x12068859, 0xc9b731ee), TOBN(0x7b948dc3, 0x56f79968),
+ TOBN(0x61e4ad32, 0xed1f8008), TOBN(0xe6c9267a, 0xd8b17538),
+ TOBN(0x1ac7c5eb, 0x857ff6fb), TOBN(0x994baaa8, 0x55f2fb10),
+ TOBN(0x84cf14e1, 0x1d248018), TOBN(0x5a39898b, 0x628ac508),
+ TOBN(0x14fde97b, 0x5fa944f5), TOBN(0xed178030, 0xd12e5ac7),
+ TOBN(0x042c2af4, 0x97e2feb4), TOBN(0xd36a42d7, 0xaebf7313),
+ TOBN(0x49d2c9eb, 0x084ffdd7), TOBN(0x9f8aa54b, 0x2ef7c76a),
+ TOBN(0x9200b7ba, 0x09895e70), TOBN(0x3bd0c66f, 0xddb7fb58),
+ TOBN(0x2d97d108, 0x78eb4cbb), TOBN(0x2d431068, 0xd84bde31),
+ TOBN(0x4b523eb7, 0x172ccd1f), TOBN(0x7323cb28, 0x30a6a892),
+ TOBN(0x97082ec0, 0xcfe153eb), TOBN(0xe97f6b6a, 0xf2aadb97),
+ TOBN(0x1d3d393e, 0xd1a83da1), TOBN(0xa6a7f9c7, 0x804b2a68),
+ TOBN(0x4a688b48, 0x2d0cb71e), TOBN(0xa9b4cc5f, 0x40585278),
+ TOBN(0x5e5db46a, 0xcb66e132), TOBN(0xf1be963a, 0x0d925880),
+ TOBN(0x944a7027, 0x0317b9e2), TOBN(0xe266f959, 0x48603d48),
+ TOBN(0x98db6673, 0x5c208899), TOBN(0x90472447, 0xa2fb18a3),
+ TOBN(0x8a966939, 0x777c619f), TOBN(0x3798142a, 0x2a3be21b),
+ TOBN(0xb4241cb1, 0x3298b343), TOBN(0xa3a14e49, 0xb44f65a1),
+ TOBN(0xc5f4d6cd, 0x3ac77acd), TOBN(0xd0288cb5, 0x52b6fc3c),
+ TOBN(0xd5cc8c2f, 0x1c040abc), TOBN(0xb675511e, 0x06bf9b4a),
+ TOBN(0xd667da37, 0x9b3aa441), TOBN(0x460d45ce, 0x51601f72),
+ TOBN(0xe2f73c69, 0x6755ff89), TOBN(0xdd3cf7e7, 0x473017e6),
+ TOBN(0x8ef5689d, 0x3cf7600d), TOBN(0x948dc4f8, 0xb1fc87b4),
+ TOBN(0xd9e9fe81, 0x4ea53299), TOBN(0x2d921ca2, 0x98eb6028),
+ TOBN(0xfaecedfd, 0x0c9803fc), TOBN(0xf38ae891, 0x4d7b4745),
+ TOBN(0xd8c5fccf, 0xc5e3a3d8), TOBN(0xbefd904c, 0x4079dfbf),
+ TOBN(0xbc6d6a58, 0xfead0197), TOBN(0x39227077, 0x695532a4),
+ TOBN(0x09e23e6d, 0xdbef42f5), TOBN(0x7e449b64, 0x480a9908),
+ TOBN(0x7b969c1a, 0xad9a2e40), TOBN(0x6231d792, 0x9591c2a4),
+ TOBN(0x87151456, 0x0f664534), TOBN(0x85ceae7c, 0x4b68f103),
+ TOBN(0xac09c4ae, 0x65578ab9), TOBN(0x33ec6868, 0xf044b10c),
+ TOBN(0x6ac4832b, 0x3a8ec1f1), TOBN(0x5509d128, 0x5847d5ef),
+ TOBN(0xf909604f, 0x763f1574), TOBN(0xb16c4303, 0xc32f63c4),
+ TOBN(0xb6ab2014, 0x7ca23cd3), TOBN(0xcaa7a5c6, 0xa391849d),
+ TOBN(0x5b0673a3, 0x75678d94), TOBN(0xc982ddd4, 0xdd303e64),
+ TOBN(0xfd7b000b, 0x5db6f971), TOBN(0xbba2cb1f, 0x6f876f92),
+ TOBN(0xc77332a3, 0x3c569426), TOBN(0xa159100c, 0x570d74f8),
+ TOBN(0xfd16847f, 0xdec67ef5), TOBN(0x742ee464, 0x233e76b7),
+ TOBN(0x0b8e4134, 0xefc2b4c8), TOBN(0xca640b86, 0x42a3e521),
+ TOBN(0x653a0190, 0x8ceb6aa9), TOBN(0x313c300c, 0x547852d5),
+ TOBN(0x24e4ab12, 0x6b237af7), TOBN(0x2ba90162, 0x8bb47af8),
+ TOBN(0x3d5e58d6, 0xa8219bb7), TOBN(0xc691d0bd, 0x1b06c57f),
+ TOBN(0x0ae4cb10, 0xd257576e), TOBN(0x3569656c, 0xd54a3dc3),
+ TOBN(0xe5ebaebd, 0x94cda03a), TOBN(0x934e82d3, 0x162bfe13),
+ TOBN(0x450ac0ba, 0xe251a0c6), TOBN(0x480b9e11, 0xdd6da526),
+ TOBN(0x00467bc5, 0x8cce08b5), TOBN(0xb636458c, 0x7f178d55),
+ TOBN(0xc5748bae, 0xa677d806), TOBN(0x2763a387, 0xdfa394eb),
+ TOBN(0xa12b448a, 0x7d3cebb6), TOBN(0xe7adda3e, 0x6f20d850),
+ TOBN(0xf63ebce5, 0x1558462c), TOBN(0x58b36143, 0x620088a8),
+ TOBN(0x8a2cc3ca, 0x4d63c0ee), TOBN(0x51233117, 0x0fe948ce),
+ TOBN(0x7463fd85, 0x222ef33b), TOBN(0xadf0c7dc, 0x7c603d6c),
+ TOBN(0x0ec32d3b, 0xfe7765e5), TOBN(0xccaab359, 0xbf380409),
+ TOBN(0xbdaa84d6, 0x8e59319c), TOBN(0xd9a4c280, 0x9c80c34d),
+ TOBN(0xa9d89488, 0xa059c142), TOBN(0x6f5ae714, 0xff0b9346),
+ TOBN(0x068f237d, 0x16fb3664), TOBN(0x5853e4c4, 0x363186ac),
+ TOBN(0xe2d87d23, 0x63c52f98), TOBN(0x2ec4a766, 0x81828876),
+ TOBN(0x47b864fa, 0xe14e7b1c), TOBN(0x0c0bc0e5, 0x69192408),
+ TOBN(0xe4d7681d, 0xb82e9f3e), TOBN(0x83200f0b, 0xdf25e13c),
+ TOBN(0x8909984c, 0x66f27280), TOBN(0x462d7b00, 0x75f73227),
+ TOBN(0xd90ba188, 0xf2651798), TOBN(0x74c6e18c, 0x36ab1c34),
+ TOBN(0xab256ea3, 0x5ef54359), TOBN(0x03466612, 0xd1aa702f),
+ TOBN(0x624d6049, 0x2ed22e91), TOBN(0x6fdfe0b5, 0x6f072822),
+ TOBN(0xeeca1115, 0x39ce2271), TOBN(0x98100a4f, 0xdb01614f),
+ TOBN(0xb6b0daa2, 0xa35c628f), TOBN(0xb6f94d2e, 0xc87e9a47),
+ TOBN(0xc6773259, 0x1d57d9ce), TOBN(0xf70bfeec, 0x03884a7b),
+ TOBN(0x5fb35ccf, 0xed2bad01), TOBN(0xa155cbe3, 0x1da6a5c7),
+ TOBN(0xc2e2594c, 0x30a92f8f), TOBN(0x649c89ce, 0x5bfafe43),
+ TOBN(0xd158667d, 0xe9ff257a), TOBN(0x9b359611, 0xf32c50ae),
+ TOBN(0x4b00b20b, 0x906014cf), TOBN(0xf3a8cfe3, 0x89bc7d3d),
+ TOBN(0x4ff23ffd, 0x248a7d06), TOBN(0x80c5bfb4, 0x878873fa),
+ TOBN(0xb7d9ad90, 0x05745981), TOBN(0x179c85db, 0x3db01994),
+ TOBN(0xba41b062, 0x61a6966c), TOBN(0x4d82d052, 0xeadce5a8),
+ TOBN(0x9e91cd3b, 0xa5e6a318), TOBN(0x47795f4f, 0x95b2dda0),
+ TOBN(0xecfd7c1f, 0xd55a897c), TOBN(0x009194ab, 0xb29110fb),
+ TOBN(0x5f0e2046, 0xe381d3b0), TOBN(0x5f3425f6, 0xa98dd291),
+ TOBN(0xbfa06687, 0x730d50da), TOBN(0x0423446c, 0x4b083b7f),
+ TOBN(0x397a247d, 0xd69d3417), TOBN(0xeb629f90, 0x387ba42a),
+ TOBN(0x1ee426cc, 0xd5cd79bf), TOBN(0x0032940b, 0x946c6e18),
+ TOBN(0x1b1e8ae0, 0x57477f58), TOBN(0xe94f7d34, 0x6d823278),
+ TOBN(0xc747cb96, 0x782ba21a), TOBN(0xc5254469, 0xf72b33a5),
+ TOBN(0x772ef6de, 0xc7f80c81), TOBN(0xd73acbfe, 0x2cd9e6b5),
+ TOBN(0x4075b5b1, 0x49ee90d9), TOBN(0x785c339a, 0xa06e9eba),
+ TOBN(0xa1030d5b, 0xabf825e0), TOBN(0xcec684c3, 0xa42931dc),
+ TOBN(0x42ab62c9, 0xc1586e63), TOBN(0x45431d66, 0x5ab43f2b),
+ TOBN(0x57c8b2c0, 0x55f7835d), TOBN(0x033da338, 0xc1b7f865),
+ TOBN(0x283c7513, 0xcaa76097), TOBN(0x0a624fa9, 0x36c83906),
+ TOBN(0x6b20afec, 0x715af2c7), TOBN(0x4b969974, 0xeba78bfd),
+ TOBN(0x220755cc, 0xd921d60e), TOBN(0x9b944e10, 0x7baeca13),
+ TOBN(0x04819d51, 0x5ded93d4), TOBN(0x9bbff86e, 0x6dddfd27),
+ TOBN(0x6b344130, 0x77adc612), TOBN(0xa7496529, 0xbbd803a0),
+ TOBN(0x1a1baaa7, 0x6d8805bd), TOBN(0xc8403902, 0x470343ad),
+ TOBN(0x39f59f66, 0x175adff1), TOBN(0x0b26d7fb, 0xb7d8c5b7),
+ TOBN(0xa875f5ce, 0x529d75e3), TOBN(0x85efc7e9, 0x41325cc2),
+ TOBN(0x21950b42, 0x1ff6acd3), TOBN(0xffe70484, 0x53dc6909),
+ TOBN(0xff4cd0b2, 0x28766127), TOBN(0xabdbe608, 0x4fb7db2b),
+ TOBN(0x837c9228, 0x5e1109e8), TOBN(0x26147d27, 0xf4645b5a),
+ TOBN(0x4d78f592, 0xf7818ed8), TOBN(0xd394077e, 0xf247fa36),
+ TOBN(0x0fb9c2d0, 0x488c171a), TOBN(0xa78bfbaa, 0x13685278),
+ TOBN(0xedfbe268, 0xd5b1fa6a), TOBN(0x0dceb8db, 0x2b7eaba7),
+ TOBN(0xbf9e8089, 0x9ae2b710), TOBN(0xefde7ae6, 0xa4449c96),
+ TOBN(0x43b7716b, 0xcc143a46), TOBN(0xd7d34194, 0xc3628c13),
+ TOBN(0x508cec1c, 0x3b3f64c9), TOBN(0xe20bc0ba, 0x1e5edf3f),
+ TOBN(0xda1deb85, 0x2f4318d4), TOBN(0xd20ebe0d, 0x5c3fa443),
+ TOBN(0x370b4ea7, 0x73241ea3), TOBN(0x61f1511c, 0x5e1a5f65),
+ TOBN(0x99a5e23d, 0x82681c62), TOBN(0xd731e383, 0xa2f54c2d),
+ TOBN(0x2692f36e, 0x83445904), TOBN(0x2e0ec469, 0xaf45f9c0),
+ TOBN(0x905a3201, 0xc67528b7), TOBN(0x88f77f34, 0xd0e5e542),
+ TOBN(0xf67a8d29, 0x5864687c), TOBN(0x23b92eae, 0x22df3562),
+ TOBN(0x5c27014b, 0x9bbec39e), TOBN(0x7ef2f226, 0x9c0f0f8d),
+ TOBN(0x97359638, 0x546c4d8d), TOBN(0x5f9c3fc4, 0x92f24679),
+ TOBN(0x912e8bed, 0xa8c8acd9), TOBN(0xec3a318d, 0x306634b0),
+ TOBN(0x80167f41, 0xc31cb264), TOBN(0x3db82f6f, 0x522113f2),
+ TOBN(0xb155bcd2, 0xdcafe197), TOBN(0xfba1da59, 0x43465283),
+ TOBN(0xa0425b8e, 0xb212cf53), TOBN(0x4f2e512e, 0xf8557c5f),
+ TOBN(0xc1286ff9, 0x25c4d56c), TOBN(0xbb8a0fea, 0xee26c851),
+ TOBN(0xc28f70d2, 0xe7d6107e), TOBN(0x7ee0c444, 0xe76265aa),
+ TOBN(0x3df277a4, 0x1d1936b1), TOBN(0x1a556e3f, 0xea9595eb),
+ TOBN(0x258bbbf9, 0xe7305683), TOBN(0x31eea5bf, 0x07ef5be6),
+ TOBN(0x0deb0e4a, 0x46c814c1), TOBN(0x5cee8449, 0xa7b730dd),
+ TOBN(0xeab495c5, 0xa0182bde), TOBN(0xee759f87, 0x9e27a6b4),
+ TOBN(0xc2cf6a68, 0x80e518ca), TOBN(0x25e8013f, 0xf14cf3f4),
+ TOBN(0x8fc44140, 0x7e8d7a14), TOBN(0xbb1ff3ca, 0x9556f36a),
+ TOBN(0x6a844385, 0x14600044), TOBN(0xba3f0c4a, 0x7451ae63),
+ TOBN(0xdfcac25b, 0x1f9af32a), TOBN(0x01e0db86, 0xb1f2214b),
+ TOBN(0x4e9a5bc2, 0xa4b596ac), TOBN(0x83927681, 0x026c2c08),
+ TOBN(0x3ec832e7, 0x7acaca28), TOBN(0x1bfeea57, 0xc7385b29),
+ TOBN(0x068212e3, 0xfd1eaf38), TOBN(0xc1329830, 0x6acf8ccc),
+ TOBN(0xb909f2db, 0x2aac9e59), TOBN(0x5748060d, 0xb661782a),
+ TOBN(0xc5ab2632, 0xc79b7a01), TOBN(0xda44c6c6, 0x00017626),
+ TOBN(0xf26c00e8, 0xa7ea82f0), TOBN(0x99cac80d, 0xe4299aaf),
+ TOBN(0xd66fe3b6, 0x7ed78be1), TOBN(0x305f725f, 0x648d02cd),
+ TOBN(0x33ed1bc4, 0x623fb21b), TOBN(0xfa70533e, 0x7a6319ad),
+ TOBN(0x17ab562d, 0xbe5ffb3e), TOBN(0x06374994, 0x56674741),
+ TOBN(0x69d44ed6, 0x5c46aa8e), TOBN(0x2100d5d3, 0xa8d063d1),
+ TOBN(0xcb9727ea, 0xa2d17c36), TOBN(0x4c2bab1b, 0x8add53b7),
+ TOBN(0xa084e90c, 0x15426704), TOBN(0x778afcd3, 0xa837ebea),
+ TOBN(0x6651f701, 0x7ce477f8), TOBN(0xa0624998, 0x46fb7a8b),
+ TOBN(0xdc1e6828, 0xed8a6e19), TOBN(0x33fc2336, 0x4189d9c7),
+ TOBN(0x026f8fe2, 0x671c39bc), TOBN(0xd40c4ccd, 0xbc6f9915),
+ TOBN(0xafa135bb, 0xf80e75ca), TOBN(0x12c651a0, 0x22adff2c),
+ TOBN(0xc40a04bd, 0x4f51ad96), TOBN(0x04820109, 0xbbe4e832),
+ TOBN(0x3667eb1a, 0x7f4c04cc), TOBN(0x59556621, 0xa9404f84),
+ TOBN(0x71cdf653, 0x7eceb50a), TOBN(0x994a44a6, 0x9b8335fa),
+ TOBN(0xd7faf819, 0xdbeb9b69), TOBN(0x473c5680, 0xeed4350d),
+ TOBN(0xb6658466, 0xda44bba2), TOBN(0x0d1bc780, 0x872bdbf3),
+ TOBN(0xe535f175, 0xa1962f91), TOBN(0x6ed7e061, 0xed58f5a7),
+ TOBN(0x177aa4c0, 0x2089a233), TOBN(0x0dbcb03a, 0xe539b413),
+ TOBN(0xe3dc424e, 0xbb32e38e), TOBN(0x6472e5ef, 0x6806701e),
+ TOBN(0xdd47ff98, 0x814be9ee), TOBN(0x6b60cfff, 0x35ace009),
+ TOBN(0xb8d3d931, 0x9ff91fe5), TOBN(0x039c4800, 0xf0518eed),
+ TOBN(0x95c37632, 0x9182cb26), TOBN(0x0763a434, 0x82fc568d),
+ TOBN(0x707c04d5, 0x383e76ba), TOBN(0xac98b930, 0x824e8197),
+ TOBN(0x92bf7c8f, 0x91230de0), TOBN(0x90876a01, 0x40959b70),
+ TOBN(0xdb6d96f3, 0x05968b80), TOBN(0x380a0913, 0x089f73b9),
+ TOBN(0x7da70b83, 0xc2c61e01), TOBN(0x95fb8394, 0x569b38c7),
+ TOBN(0x9a3c6512, 0x80edfe2f), TOBN(0x8f726bb9, 0x8faeaf82),
+ TOBN(0x8010a4a0, 0x78424bf8), TOBN(0x29672044, 0x0e844970)},
+ {TOBN(0x63c5cb81, 0x7a2ad62a), TOBN(0x7ef2b6b9, 0xac62ff54),
+ TOBN(0x3749bba4, 0xb3ad9db5), TOBN(0xad311f2c, 0x46d5a617),
+ TOBN(0xb77a8087, 0xc2ff3b6d), TOBN(0xb46feaf3, 0x367834ff),
+ TOBN(0xf8aa266d, 0x75d6b138), TOBN(0xfa38d320, 0xec008188),
+ TOBN(0x486d8ffa, 0x696946fc), TOBN(0x50fbc6d8, 0xb9cba56d),
+ TOBN(0x7e3d423e, 0x90f35a15), TOBN(0x7c3da195, 0xc0dd962c),
+ TOBN(0xe673fdb0, 0x3cfd5d8b), TOBN(0x0704b7c2, 0x889dfca5),
+ TOBN(0xf6ce581f, 0xf52305aa), TOBN(0x399d49eb, 0x914d5e53),
+ TOBN(0x380a496d, 0x6ec293cd), TOBN(0x733dbda7, 0x8e7051f5),
+ TOBN(0x037e388d, 0xb849140a), TOBN(0xee4b32b0, 0x5946dbf6),
+ TOBN(0xb1c4fda9, 0xcae368d1), TOBN(0x5001a7b0, 0xfdb0b2f3),
+ TOBN(0x6df59374, 0x2e3ac46e), TOBN(0x4af675f2, 0x39b3e656),
+ TOBN(0x44e38110, 0x39949296), TOBN(0x5b63827b, 0x361db1b5),
+ TOBN(0x3e5323ed, 0x206eaff5), TOBN(0x942370d2, 0xc21f4290),
+ TOBN(0xf2caaf2e, 0xe0d985a1), TOBN(0x192cc64b, 0x7239846d),
+ TOBN(0x7c0b8f47, 0xae6312f8), TOBN(0x7dc61f91, 0x96620108),
+ TOBN(0xb830fb5b, 0xc2da7de9), TOBN(0xd0e643df, 0x0ff8d3be),
+ TOBN(0x31ee77ba, 0x188a9641), TOBN(0x4e8aa3aa, 0xbcf6d502),
+ TOBN(0xf9fb6532, 0x9a49110f), TOBN(0xd18317f6, 0x2dd6b220),
+ TOBN(0x7e3ced41, 0x52c3ea5a), TOBN(0x0d296a14, 0x7d579c4a),
+ TOBN(0x35d6a53e, 0xed4c3717), TOBN(0x9f8240cf, 0x3d0ed2a3),
+ TOBN(0x8c0d4d05, 0xe5543aa5), TOBN(0x45d5bbfb, 0xdd33b4b4),
+ TOBN(0xfa04cc73, 0x137fd28e), TOBN(0x862ac6ef, 0xc73b3ffd),
+ TOBN(0x403ff9f5, 0x31f51ef2), TOBN(0x34d5e0fc, 0xbc73f5a2),
+ TOBN(0xf2526820, 0x08913f4f), TOBN(0xea20ed61, 0xeac93d95),
+ TOBN(0x51ed38b4, 0x6ca6b26c), TOBN(0x8662dcbc, 0xea4327b0),
+ TOBN(0x6daf295c, 0x725d2aaa), TOBN(0xbad2752f, 0x8e52dcda),
+ TOBN(0x2210e721, 0x0b17dacc), TOBN(0xa37f7912, 0xd51e8232),
+ TOBN(0x4f7081e1, 0x44cc3add), TOBN(0xd5ffa1d6, 0x87be82cf),
+ TOBN(0x89890b6c, 0x0edd6472), TOBN(0xada26e1a, 0x3ed17863),
+ TOBN(0x276f2715, 0x63483caa), TOBN(0xe6924cd9, 0x2f6077fd),
+ TOBN(0x05a7fe98, 0x0a466e3c), TOBN(0xf1c794b0, 0xb1902d1f),
+ TOBN(0xe5213688, 0x82a8042c), TOBN(0xd931cfaf, 0xcd278298),
+ TOBN(0x069a0ae0, 0xf597a740), TOBN(0x0adbb3f3, 0xeb59107c),
+ TOBN(0x983e951e, 0x5eaa8eb8), TOBN(0xe663a8b5, 0x11b48e78),
+ TOBN(0x1631cc0d, 0x8a03f2c5), TOBN(0x7577c11e, 0x11e271e2),
+ TOBN(0x33b2385c, 0x08369a90), TOBN(0x2990c59b, 0x190eb4f8),
+ TOBN(0x819a6145, 0xc68eac80), TOBN(0x7a786d62, 0x2ec4a014),
+ TOBN(0x33faadbe, 0x20ac3a8d), TOBN(0x31a21781, 0x5aba2d30),
+ TOBN(0x209d2742, 0xdba4f565), TOBN(0xdb2ce9e3, 0x55aa0fbb),
+ TOBN(0x8cef334b, 0x168984df), TOBN(0xe81dce17, 0x33879638),
+ TOBN(0xf6e6949c, 0x263720f0), TOBN(0x5c56feaf, 0xf593cbec),
+ TOBN(0x8bff5601, 0xfde58c84), TOBN(0x74e24117, 0x2eccb314),
+ TOBN(0xbcf01b61, 0x4c9a8a78), TOBN(0xa233e35e, 0x544c9868),
+ TOBN(0xb3156bf3, 0x8bd7aff1), TOBN(0x1b5ee4cb, 0x1d81b146),
+ TOBN(0x7ba1ac41, 0xd628a915), TOBN(0x8f3a8f9c, 0xfd89699e),
+ TOBN(0x7329b9c9, 0xa0748be7), TOBN(0x1d391c95, 0xa92e621f),
+ TOBN(0xe51e6b21, 0x4d10a837), TOBN(0xd255f53a, 0x4947b435),
+ TOBN(0x07669e04, 0xf1788ee3), TOBN(0xc14f27af, 0xa86938a2),
+ TOBN(0x8b47a334, 0xe93a01c0), TOBN(0xff627438, 0xd9366808),
+ TOBN(0x7a0985d8, 0xca2a5965), TOBN(0x3d9a5542, 0xd6e9b9b3),
+ TOBN(0xc23eb80b, 0x4cf972e8), TOBN(0x5c1c33bb, 0x4fdf72fd),
+ TOBN(0x0c4a58d4, 0x74a86108), TOBN(0xf8048a8f, 0xee4c5d90),
+ TOBN(0xe3c7c924, 0xe86d4c80), TOBN(0x28c889de, 0x056a1e60),
+ TOBN(0x57e2662e, 0xb214a040), TOBN(0xe8c48e98, 0x37e10347),
+ TOBN(0x87742862, 0x80ac748a), TOBN(0xf1c24022, 0x186b06f2),
+ TOBN(0xac2dd4c3, 0x5f74040a), TOBN(0x409aeb71, 0xfceac957),
+ TOBN(0x4fbad782, 0x55c4ec23), TOBN(0xb359ed61, 0x8a7b76ec),
+ TOBN(0x12744926, 0xed6f4a60), TOBN(0xe21e8d7f, 0x4b912de3),
+ TOBN(0xe2575a59, 0xfc705a59), TOBN(0x72f1d4de, 0xed2dbc0e),
+ TOBN(0x3d2b24b9, 0xeb7926b8), TOBN(0xbff88cb3, 0xcdbe5509),
+ TOBN(0xd0f399af, 0xe4dd640b), TOBN(0x3c5fe130, 0x2f76ed45),
+ TOBN(0x6f3562f4, 0x3764fb3d), TOBN(0x7b5af318, 0x3151b62d),
+ TOBN(0xd5bd0bc7, 0xd79ce5f3), TOBN(0xfdaf6b20, 0xec66890f),
+ TOBN(0x735c67ec, 0x6063540c), TOBN(0x50b259c2, 0xe5f9cb8f),
+ TOBN(0xb8734f9a, 0x3f99c6ab), TOBN(0xf8cc13d5, 0xa3a7bc85),
+ TOBN(0x80c1b305, 0xc5217659), TOBN(0xfe5364d4, 0x4ec12a54),
+ TOBN(0xbd87045e, 0x681345fe), TOBN(0x7f8efeb1, 0x582f897f),
+ TOBN(0xe8cbf1e5, 0xd5923359), TOBN(0xdb0cea9d, 0x539b9fb0),
+ TOBN(0x0c5b34cf, 0x49859b98), TOBN(0x5e583c56, 0xa4403cc6),
+ TOBN(0x11fc1a2d, 0xd48185b7), TOBN(0xc93fbc7e, 0x6e521787),
+ TOBN(0x47e7a058, 0x05105b8b), TOBN(0x7b4d4d58, 0xdb8260c8),
+ TOBN(0xe33930b0, 0x46eb842a), TOBN(0x8e844a9a, 0x7bdae56d),
+ TOBN(0x34ef3a9e, 0x13f7fdfc), TOBN(0xb3768f82, 0x636ca176),
+ TOBN(0x2821f4e0, 0x4e09e61c), TOBN(0x414dc3a1, 0xa0c7cddc),
+ TOBN(0xd5379437, 0x54945fcd), TOBN(0x151b6eef, 0xb3555ff1),
+ TOBN(0xb31bd613, 0x6339c083), TOBN(0x39ff8155, 0xdfb64701),
+ TOBN(0x7c3388d2, 0xe29604ab), TOBN(0x1e19084b, 0xa6b10442),
+ TOBN(0x17cf54c0, 0xeccd47ef), TOBN(0x89693385, 0x4a5dfb30),
+ TOBN(0x69d023fb, 0x47daf9f6), TOBN(0x9222840b, 0x7d91d959),
+ TOBN(0x439108f5, 0x803bac62), TOBN(0x0b7dd91d, 0x379bd45f),
+ TOBN(0xd651e827, 0xca63c581), TOBN(0x5c5d75f6, 0x509c104f),
+ TOBN(0x7d5fc738, 0x1f2dc308), TOBN(0x20faa7bf, 0xd98454be),
+ TOBN(0x95374bee, 0xa517b031), TOBN(0xf036b9b1, 0x642692ac),
+ TOBN(0xc5106109, 0x39842194), TOBN(0xb7e2353e, 0x49d05295),
+ TOBN(0xfc8c1d5c, 0xefb42ee0), TOBN(0xe04884eb, 0x08ce811c),
+ TOBN(0xf1f75d81, 0x7419f40e), TOBN(0x5b0ac162, 0xa995c241),
+ TOBN(0x120921bb, 0xc4c55646), TOBN(0x713520c2, 0x8d33cf97),
+ TOBN(0xb4a65a5c, 0xe98c5100), TOBN(0x6cec871d, 0x2ddd0f5a),
+ TOBN(0x251f0b7f, 0x9ba2e78b), TOBN(0x224a8434, 0xce3a2a5f),
+ TOBN(0x26827f61, 0x25f5c46f), TOBN(0x6a22bedc, 0x48545ec0),
+ TOBN(0x25ae5fa0, 0xb1bb5cdc), TOBN(0xd693682f, 0xfcb9b98f),
+ TOBN(0x32027fe8, 0x91e5d7d3), TOBN(0xf14b7d17, 0x73a07678),
+ TOBN(0xf88497b3, 0xc0dfdd61), TOBN(0xf7c2eec0, 0x2a8c4f48),
+ TOBN(0xaa5573f4, 0x3756e621), TOBN(0xc013a240, 0x1825b948),
+ TOBN(0x1c03b345, 0x63878572), TOBN(0xa0472bea, 0x653a4184),
+ TOBN(0xf4222e27, 0x0ac69a80), TOBN(0x34096d25, 0xf51e54f6),
+ TOBN(0x00a648cb, 0x8fffa591), TOBN(0x4e87acdc, 0x69b6527f),
+ TOBN(0x0575e037, 0xe285ccb4), TOBN(0x188089e4, 0x50ddcf52),
+ TOBN(0xaa96c9a8, 0x870ff719), TOBN(0x74a56cd8, 0x1fc7e369),
+ TOBN(0x41d04ee2, 0x1726931a), TOBN(0x0bbbb2c8, 0x3660ecfd),
+ TOBN(0xa6ef6de5, 0x24818e18), TOBN(0xe421cc51, 0xe7d57887),
+ TOBN(0xf127d208, 0xbea87be6), TOBN(0x16a475d3, 0xb1cdd682),
+ TOBN(0x9db1b684, 0x439b63f7), TOBN(0x5359b3db, 0xf0f113b6),
+ TOBN(0xdfccf1de, 0x8bf06e31), TOBN(0x1fdf8f44, 0xdd383901),
+ TOBN(0x10775cad, 0x5017e7d2), TOBN(0xdfc3a597, 0x58d11eef),
+ TOBN(0x6ec9c8a0, 0xb1ecff10), TOBN(0xee6ed6cc, 0x28400549),
+ TOBN(0xb5ad7bae, 0x1b4f8d73), TOBN(0x61b4f11d, 0xe00aaab9),
+ TOBN(0x7b32d69b, 0xd4eff2d7), TOBN(0x88ae6771, 0x4288b60f),
+ TOBN(0x159461b4, 0x37a1e723), TOBN(0x1f3d4789, 0x570aae8c),
+ TOBN(0x869118c0, 0x7f9871da), TOBN(0x35fbda78, 0xf635e278),
+ TOBN(0x738f3641, 0xe1541dac), TOBN(0x6794b13a, 0xc0dae45f),
+ TOBN(0x065064ac, 0x09cc0917), TOBN(0x27c53729, 0xc68540fd),
+ TOBN(0x0d2d4c8e, 0xef227671), TOBN(0xd23a9f80, 0xa1785a04),
+ TOBN(0x98c59528, 0x52650359), TOBN(0xfa09ad01, 0x74a1acad),
+ TOBN(0x082d5a29, 0x0b55bf5c), TOBN(0xa40f1c67, 0x419b8084),
+ TOBN(0x3a5c752e, 0xdcc18770), TOBN(0x4baf1f2f, 0x8825c3a5),
+ TOBN(0xebd63f74, 0x21b153ed), TOBN(0xa2383e47, 0xb2f64723),
+ TOBN(0xe7bf620a, 0x2646d19a), TOBN(0x56cb44ec, 0x03c83ffd),
+ TOBN(0xaf7267c9, 0x4f6be9f1), TOBN(0x8b2dfd7b, 0xc06bb5e9),
+ TOBN(0xb87072f2, 0xa672c5c7), TOBN(0xeacb11c8, 0x0d53c5e2),
+ TOBN(0x22dac29d, 0xff435932), TOBN(0x37bdb99d, 0x4408693c),
+ TOBN(0xf6e62fb6, 0x2899c20f), TOBN(0x3535d512, 0x447ece24),
+ TOBN(0xfbdc6b88, 0xff577ce3), TOBN(0x726693bd, 0x190575f2),
+ TOBN(0x6772b0e5, 0xab4b35a2), TOBN(0x1d8b6001, 0xf5eeaacf),
+ TOBN(0x728f7ce4, 0x795b9580), TOBN(0x4a20ed2a, 0x41fb81da),
+ TOBN(0x9f685cd4, 0x4fec01e6), TOBN(0x3ed7ddcc, 0xa7ff50ad),
+ TOBN(0x460fd264, 0x0c2d97fd), TOBN(0x3a241426, 0xeb82f4f9),
+ TOBN(0x17d1df2c, 0x6a8ea820), TOBN(0xb2b50d3b, 0xf22cc254),
+ TOBN(0x03856cba, 0xb7291426), TOBN(0x87fd26ae, 0x04f5ee39),
+ TOBN(0x9cb696cc, 0x02bee4ba), TOBN(0x53121804, 0x06820fd6),
+ TOBN(0xa5dfc269, 0x0212e985), TOBN(0x666f7ffa, 0x160f9a09),
+ TOBN(0xc503cd33, 0xbccd9617), TOBN(0x365dede4, 0xba7730a3),
+ TOBN(0x798c6355, 0x5ddb0786), TOBN(0xa6c3200e, 0xfc9cd3bc),
+ TOBN(0x060ffb2c, 0xe5e35efd), TOBN(0x99a4e25b, 0x5555a1c1),
+ TOBN(0x11d95375, 0xf70b3751), TOBN(0x0a57354a, 0x160e1bf6),
+ TOBN(0xecb3ae4b, 0xf8e4b065), TOBN(0x07a834c4, 0x2e53022b),
+ TOBN(0x1cd300b3, 0x8692ed96), TOBN(0x16a6f792, 0x61ee14ec),
+ TOBN(0x8f1063c6, 0x6a8649ed), TOBN(0xfbcdfcfe, 0x869f3e14),
+ TOBN(0x2cfb97c1, 0x00a7b3ec), TOBN(0xcea49b3c, 0x7130c2f1),
+ TOBN(0x462d044f, 0xe9d96488), TOBN(0x4b53d52e, 0x8182a0c1),
+ TOBN(0x84b6ddd3, 0x0391e9e9), TOBN(0x80ab7b48, 0xb1741a09),
+ TOBN(0xec0e15d4, 0x27d3317f), TOBN(0x8dfc1ddb, 0x1a64671e),
+ TOBN(0x93cc5d5f, 0xd49c5b92), TOBN(0xc995d53d, 0x3674a331),
+ TOBN(0x302e41ec, 0x090090ae), TOBN(0x2278a0cc, 0xedb06830),
+ TOBN(0x1d025932, 0xfbc99690), TOBN(0x0c32fbd2, 0xb80d68da),
+ TOBN(0xd79146da, 0xf341a6c1), TOBN(0xae0ba139, 0x1bef68a0),
+ TOBN(0xc6b8a563, 0x8d774b3a), TOBN(0x1cf307bd, 0x880ba4d7),
+ TOBN(0xc033bdc7, 0x19803511), TOBN(0xa9f97b3b, 0x8888c3be),
+ TOBN(0x3d68aebc, 0x85c6d05e), TOBN(0xc3b88a9d, 0x193919eb),
+ TOBN(0x2d300748, 0xc48b0ee3), TOBN(0x7506bc7c, 0x07a746c1),
+ TOBN(0xfc48437c, 0x6e6d57f3), TOBN(0x5bd71587, 0xcfeaa91a),
+ TOBN(0xa4ed0408, 0xc1bc5225), TOBN(0xd0b946db, 0x2719226d),
+ TOBN(0x109ecd62, 0x758d2d43), TOBN(0x75c8485a, 0x2751759b),
+ TOBN(0xb0b75f49, 0x9ce4177a), TOBN(0x4fa61a1e, 0x79c10c3d),
+ TOBN(0xc062d300, 0xa167fcd7), TOBN(0x4df3874c, 0x750f0fa8),
+ TOBN(0x29ae2cf9, 0x83dfedc9), TOBN(0xf8437134, 0x8d87631a),
+ TOBN(0xaf571711, 0x7429c8d2), TOBN(0x18d15867, 0x146d9272),
+ TOBN(0x83053ecf, 0x69769bb7), TOBN(0xc55eb856, 0xc479ab82),
+ TOBN(0x5ef7791c, 0x21b0f4b2), TOBN(0xaa5956ba, 0x3d491525),
+ TOBN(0x407a96c2, 0x9fe20eba), TOBN(0xf27168bb, 0xe52a5ad3),
+ TOBN(0x43b60ab3, 0xbf1d9d89), TOBN(0xe45c51ef, 0x710e727a),
+ TOBN(0xdfca5276, 0x099b4221), TOBN(0x8dc6407c, 0x2557a159),
+ TOBN(0x0ead8335, 0x91035895), TOBN(0x0a9db957, 0x9c55dc32),
+ TOBN(0xe40736d3, 0xdf61bc76), TOBN(0x13a619c0, 0x3f778cdb),
+ TOBN(0x6dd921a4, 0xc56ea28f), TOBN(0x76a52433, 0x2fa647b4),
+ TOBN(0x23591891, 0xac5bdc5d), TOBN(0xff4a1a72, 0xbac7dc01),
+ TOBN(0x9905e261, 0x62df8453), TOBN(0x3ac045df, 0xe63b265f),
+ TOBN(0x8a3f341b, 0xad53dba7), TOBN(0x8ec269cc, 0x837b625a),
+ TOBN(0xd71a2782, 0x3ae31189), TOBN(0x8fb4f9a3, 0x55e96120),
+ TOBN(0x804af823, 0xff9875cf), TOBN(0x23224f57, 0x5d442a9b),
+ TOBN(0x1c4d3b9e, 0xecc62679), TOBN(0x91da22fb, 0xa0e7ddb1),
+ TOBN(0xa370324d, 0x6c04a661), TOBN(0x9710d3b6, 0x5e376d17),
+ TOBN(0xed8c98f0, 0x3044e357), TOBN(0xc364ebbe, 0x6422701c),
+ TOBN(0x347f5d51, 0x7733d61c), TOBN(0xd55644b9, 0xcea826c3),
+ TOBN(0x80c6e0ad, 0x55a25548), TOBN(0x0aa7641d, 0x844220a7),
+ TOBN(0x1438ec81, 0x31810660), TOBN(0x9dfa6507, 0xde4b4043),
+ TOBN(0x10b515d8, 0xcc3e0273), TOBN(0x1b6066dd, 0x28d8cfb2),
+ TOBN(0xd3b04591, 0x9c9efebd), TOBN(0x425d4bdf, 0xa21c1ff4),
+ TOBN(0x5fe5af19, 0xd57607d3), TOBN(0xbbf773f7, 0x54481084),
+ TOBN(0x8435bd69, 0x94b03ed1), TOBN(0xd9ad1de3, 0x634cc546),
+ TOBN(0x2cf423fc, 0x00e420ca), TOBN(0xeed26d80, 0xa03096dd),
+ TOBN(0xd7f60be7, 0xa4db09d2), TOBN(0xf47f569d, 0x960622f7),
+ TOBN(0xe5925fd7, 0x7296c729), TOBN(0xeff2db26, 0x26ca2715),
+ TOBN(0xa6fcd014, 0xb913e759), TOBN(0x53da4786, 0x8ff4de93),
+ TOBN(0x14616d79, 0xc32068e1), TOBN(0xb187d664, 0xccdf352e),
+ TOBN(0xf7afb650, 0x1dc90b59), TOBN(0x8170e943, 0x7daa1b26),
+ TOBN(0xc8e3bdd8, 0x700c0a84), TOBN(0x6e8d345f, 0x6482bdfa),
+ TOBN(0x84cfbfa1, 0xc5c5ea50), TOBN(0xd3baf14c, 0x67960681),
+ TOBN(0x26398403, 0x0dd50942), TOBN(0xe4b7839c, 0x4716a663),
+ TOBN(0xd5f1f794, 0xe7de6dc0), TOBN(0x5cd0f4d4, 0x622aa7ce),
+ TOBN(0x5295f3f1, 0x59acfeec), TOBN(0x8d933552, 0x953e0607),
+ TOBN(0xc7db8ec5, 0x776c5722), TOBN(0xdc467e62, 0x2b5f290c),
+ TOBN(0xd4297e70, 0x4ff425a9), TOBN(0x4be924c1, 0x0cf7bb72),
+ TOBN(0x0d5dc5ae, 0xa1892131), TOBN(0x8bf8a8e3, 0xa705c992),
+ TOBN(0x73a0b064, 0x7a305ac5), TOBN(0x00c9ca4e, 0x9a8c77a8),
+ TOBN(0x5dfee80f, 0x83774bdd), TOBN(0x63131602, 0x85734485),
+ TOBN(0xa1b524ae, 0x914a69a9), TOBN(0xebc2ffaf, 0xd4e300d7),
+ TOBN(0x52c93db7, 0x7cfa46a5), TOBN(0x71e6161f, 0x21653b50),
+ TOBN(0x3574fc57, 0xa4bc580a), TOBN(0xc09015dd, 0xe1bc1253),
+ TOBN(0x4b7b47b2, 0xd174d7aa), TOBN(0x4072d8e8, 0xf3a15d04),
+ TOBN(0xeeb7d47f, 0xd6fa07ed), TOBN(0x6f2b9ff9, 0xedbdafb1),
+ TOBN(0x18c51615, 0x3760fe8a), TOBN(0x7a96e6bf, 0xf06c6c13),
+ TOBN(0x4d7a0410, 0x0ea2d071), TOBN(0xa1914e9b, 0x0be2a5ce),
+ TOBN(0x5726e357, 0xd8a3c5cf), TOBN(0x1197ecc3, 0x2abb2b13),
+ TOBN(0x6c0d7f7f, 0x31ae88dd), TOBN(0x15b20d1a, 0xfdbb3efe),
+ TOBN(0xcd06aa26, 0x70584039), TOBN(0x2277c969, 0xa7dc9747),
+ TOBN(0xbca69587, 0x7855d815), TOBN(0x899ea238, 0x5188b32a),
+ TOBN(0x37d9228b, 0x760c1c9d), TOBN(0xc7efbb11, 0x9b5c18da),
+ TOBN(0x7f0d1bc8, 0x19f6dbc5), TOBN(0x4875384b, 0x07e6905b),
+ TOBN(0xc7c50baa, 0x3ba8cd86), TOBN(0xb0ce40fb, 0xc2905de0),
+ TOBN(0x70840673, 0x7a231952), TOBN(0xa912a262, 0xcf43de26),
+ TOBN(0x9c38ddcc, 0xeb5b76c1), TOBN(0x746f5285, 0x26fc0ab4),
+ TOBN(0x52a63a50, 0xd62c269f), TOBN(0x60049c55, 0x99458621),
+ TOBN(0xe7f48f82, 0x3c2f7c9e), TOBN(0x6bd99043, 0x917d5cf3),
+ TOBN(0xeb1317a8, 0x8701f469), TOBN(0xbd3fe2ed, 0x9a449fe0),
+ TOBN(0x421e79ca, 0x12ef3d36), TOBN(0x9ee3c36c, 0x3e7ea5de),
+ TOBN(0xe48198b5, 0xcdff36f7), TOBN(0xaff4f967, 0xc6b82228),
+ TOBN(0x15e19dd0, 0xc47adb7e), TOBN(0x45699b23, 0x032e7dfa),
+ TOBN(0x40680c8b, 0x1fae026a), TOBN(0x5a347a48, 0x550dbf4d),
+ TOBN(0xe652533b, 0x3cef0d7d), TOBN(0xd94f7b18, 0x2bbb4381),
+ TOBN(0x838752be, 0x0e80f500), TOBN(0x8e6e2488, 0x9e9c9bfb),
+ TOBN(0xc9751697, 0x16caca6a), TOBN(0x866c49d8, 0x38531ad9),
+ TOBN(0xc917e239, 0x7151ade1), TOBN(0x2d016ec1, 0x6037c407),
+ TOBN(0xa407ccc9, 0x00eac3f9), TOBN(0x835f6280, 0xe2ed4748),
+ TOBN(0xcc54c347, 0x1cc98e0d), TOBN(0x0e969937, 0xdcb572eb),
+ TOBN(0x1b16c8e8, 0x8f30c9cb), TOBN(0xa606ae75, 0x373c4661),
+ TOBN(0x47aa689b, 0x35502cab), TOBN(0xf89014ae, 0x4d9bb64f),
+ TOBN(0x202f6a9c, 0x31c71f7b), TOBN(0x01f95aa3, 0x296ffe5c),
+ TOBN(0x5fc06014, 0x53cec3a3), TOBN(0xeb991237, 0x5f498a45),
+ TOBN(0xae9a935e, 0x5d91ba87), TOBN(0xc6ac6281, 0x0b564a19),
+ TOBN(0x8a8fe81c, 0x3bd44e69), TOBN(0x7c8b467f, 0x9dd11d45),
+ TOBN(0xf772251f, 0xea5b8e69), TOBN(0xaeecb3bd, 0xc5b75fbc),
+ TOBN(0x1aca3331, 0x887ff0e5), TOBN(0xbe5d49ff, 0x19f0a131),
+ TOBN(0x582c13aa, 0xe5c8646f), TOBN(0xdbaa12e8, 0x20e19980),
+ TOBN(0x8f40f31a, 0xf7abbd94), TOBN(0x1f13f5a8, 0x1dfc7663),
+ TOBN(0x5d81f1ee, 0xaceb4fc0), TOBN(0x36256002, 0x5e6f0f42),
+ TOBN(0x4b67d6d7, 0x751370c8), TOBN(0x2608b698, 0x03e80589),
+ TOBN(0xcfc0d2fc, 0x05268301), TOBN(0xa6943d39, 0x40309212),
+ TOBN(0x192a90c2, 0x1fd0e1c2), TOBN(0xb209f113, 0x37f1dc76),
+ TOBN(0xefcc5e06, 0x97bf1298), TOBN(0xcbdb6730, 0x219d639e),
+ TOBN(0xd009c116, 0xb81e8c6f), TOBN(0xa3ffdde3, 0x1a7ce2e5),
+ TOBN(0xc53fbaaa, 0xa914d3ba), TOBN(0x836d500f, 0x88df85ee),
+ TOBN(0xd98dc71b, 0x66ee0751), TOBN(0x5a3d7005, 0x714516fd),
+ TOBN(0x21d3634d, 0x39eedbba), TOBN(0x35cd2e68, 0x0455a46d),
+ TOBN(0xc8cafe65, 0xf9d7eb0c), TOBN(0xbda3ce9e, 0x00cefb3e),
+ TOBN(0xddc17a60, 0x2c9cf7a4), TOBN(0x01572ee4, 0x7bcb8773),
+ TOBN(0xa92b2b01, 0x8c7548df), TOBN(0x732fd309, 0xa84600e3),
+ TOBN(0xe22109c7, 0x16543a40), TOBN(0x9acafd36, 0xfede3c6c),
+ TOBN(0xfb206852, 0x6824e614), TOBN(0x2a4544a9, 0xda25dca0),
+ TOBN(0x25985262, 0x91d60b06), TOBN(0x281b7be9, 0x28753545),
+ TOBN(0xec667b1a, 0x90f13b27), TOBN(0x33a83aff, 0x940e2eb4),
+ TOBN(0x80009862, 0xd5d721d5), TOBN(0x0c3357a3, 0x5bd3a182),
+ TOBN(0x27f3a83b, 0x7aa2cda4), TOBN(0xb58ae74e, 0xf6f83085),
+ TOBN(0x2a911a81, 0x2e6dad6b), TOBN(0xde286051, 0xf43d6c5b),
+ TOBN(0x4bdccc41, 0xf996c4d8), TOBN(0xe7312ec0, 0x0ae1e24e)},
+ {TOBN(0xf8d112e7, 0x6e6485b3), TOBN(0x4d3e24db, 0x771c52f8),
+ TOBN(0x48e3ee41, 0x684a2f6d), TOBN(0x7161957d, 0x21d95551),
+ TOBN(0x19631283, 0xcdb12a6c), TOBN(0xbf3fa882, 0x2e50e164),
+ TOBN(0xf6254b63, 0x3166cc73), TOBN(0x3aefa7ae, 0xaee8cc38),
+ TOBN(0x79b0fe62, 0x3b36f9fd), TOBN(0x26543b23, 0xfde19fc0),
+ TOBN(0x136e64a0, 0x958482ef), TOBN(0x23f63771, 0x9b095825),
+ TOBN(0x14cfd596, 0xb6a1142e), TOBN(0x5ea6aac6, 0x335aac0b),
+ TOBN(0x86a0e8bd, 0xf3081dd5), TOBN(0x5fb89d79, 0x003dc12a),
+ TOBN(0xf615c33a, 0xf72e34d4), TOBN(0x0bd9ea40, 0x110eec35),
+ TOBN(0x1c12bc5b, 0xc1dea34e), TOBN(0x686584c9, 0x49ae4699),
+ TOBN(0x13ad95d3, 0x8c97b942), TOBN(0x4609561a, 0x4e5c7562),
+ TOBN(0x9e94a4ae, 0xf2737f89), TOBN(0xf57594c6, 0x371c78b6),
+ TOBN(0x0f0165fc, 0xe3779ee3), TOBN(0xe00e7f9d, 0xbd495d9e),
+ TOBN(0x1fa4efa2, 0x20284e7a), TOBN(0x4564bade, 0x47ac6219),
+ TOBN(0x90e6312a, 0xc4708e8e), TOBN(0x4f5725fb, 0xa71e9adf),
+ TOBN(0xe95f55ae, 0x3d684b9f), TOBN(0x47f7ccb1, 0x1e94b415),
+ TOBN(0x7322851b, 0x8d946581), TOBN(0xf0d13133, 0xbdf4a012),
+ TOBN(0xa3510f69, 0x6584dae0), TOBN(0x03a7c171, 0x3c9f6c6d),
+ TOBN(0x5be97f38, 0xe475381a), TOBN(0xca1ba422, 0x85823334),
+ TOBN(0xf83cc5c7, 0x0be17dda), TOBN(0x158b1494, 0x0b918c0f),
+ TOBN(0xda3a77e5, 0x522e6b69), TOBN(0x69c908c3, 0xbbcd6c18),
+ TOBN(0x1f1b9e48, 0xd924fd56), TOBN(0x37c64e36, 0xaa4bb3f7),
+ TOBN(0x5a4fdbdf, 0xee478d7d), TOBN(0xba75c8bc, 0x0193f7a0),
+ TOBN(0x84bc1e84, 0x56cd16df), TOBN(0x1fb08f08, 0x46fad151),
+ TOBN(0x8a7cabf9, 0x842e9f30), TOBN(0xa331d4bf, 0x5eab83af),
+ TOBN(0xd272cfba, 0x017f2a6a), TOBN(0x27560abc, 0x83aba0e3),
+ TOBN(0x94b83387, 0x0e3a6b75), TOBN(0x25c6aea2, 0x6b9f50f5),
+ TOBN(0x803d691d, 0xb5fdf6d0), TOBN(0x03b77509, 0xe6333514),
+ TOBN(0x36178903, 0x61a341c1), TOBN(0x3604dc60, 0x0cfd6142),
+ TOBN(0x022295eb, 0x8533316c), TOBN(0x3dbde4ac, 0x44af2922),
+ TOBN(0x898afc5d, 0x1c7eef69), TOBN(0x58896805, 0xd14f4fa1),
+ TOBN(0x05002160, 0x203c21ca), TOBN(0x6f0d1f30, 0x40ef730b),
+ TOBN(0x8e8c44d4, 0x196224f8), TOBN(0x75a4ab95, 0x374d079d),
+ TOBN(0x79085ecc, 0x7d48f123), TOBN(0x56f04d31, 0x1bf65ad8),
+ TOBN(0xe220bf1c, 0xbda602b2), TOBN(0x73ee1742, 0xf9612c69),
+ TOBN(0x76008fc8, 0x084fd06b), TOBN(0x4000ef9f, 0xf11380d1),
+ TOBN(0x48201b4b, 0x12cfe297), TOBN(0x3eee129c, 0x292f74e5),
+ TOBN(0xe1fe114e, 0xc9e874e8), TOBN(0x899b055c, 0x92c5fc41),
+ TOBN(0x4e477a64, 0x3a39c8cf), TOBN(0x82f09efe, 0x78963cc9),
+ TOBN(0x6fd3fd8f, 0xd333f863), TOBN(0x85132b2a, 0xdc949c63),
+ TOBN(0x7e06a3ab, 0x516eb17b), TOBN(0x73bec06f, 0xd2c7372b),
+ TOBN(0xe4f74f55, 0xba896da6), TOBN(0xbb4afef8, 0x8e9eb40f),
+ TOBN(0x2d75bec8, 0xe61d66b0), TOBN(0x02bda4b4, 0xef29300b),
+ TOBN(0x8bbaa8de, 0x026baa5a), TOBN(0xff54befd, 0xa07f4440),
+ TOBN(0xbd9b8b1d, 0xbe7a2af3), TOBN(0xec51caa9, 0x4fb74a72),
+ TOBN(0xb9937a4b, 0x63879697), TOBN(0x7c9a9d20, 0xec2687d5),
+ TOBN(0x1773e44f, 0x6ef5f014), TOBN(0x8abcf412, 0xe90c6900),
+ TOBN(0x387bd022, 0x8142161e), TOBN(0x50393755, 0xfcb6ff2a),
+ TOBN(0x9813fd56, 0xed6def63), TOBN(0x53cf6482, 0x7d53106c),
+ TOBN(0x991a35bd, 0x431f7ac1), TOBN(0xf1e274dd, 0x63e65faf),
+ TOBN(0xf63ffa3c, 0x44cc7880), TOBN(0x411a426b, 0x7c256981),
+ TOBN(0xb698b9fd, 0x93a420e0), TOBN(0x89fdddc0, 0xae53f8fe),
+ TOBN(0x766e0722, 0x32398baa), TOBN(0x205fee42, 0x5cfca031),
+ TOBN(0xa49f5341, 0x7a029cf2), TOBN(0xa88c68b8, 0x4023890d),
+ TOBN(0xbc275041, 0x7337aaa8), TOBN(0x9ed364ad, 0x0eb384f4),
+ TOBN(0xe0816f85, 0x29aba92f), TOBN(0x2e9e1941, 0x04e38a88),
+ TOBN(0x57eef44a, 0x3dafd2d5), TOBN(0x35d1fae5, 0x97ed98d8),
+ TOBN(0x50628c09, 0x2307f9b1), TOBN(0x09d84aae, 0xd6cba5c6),
+ TOBN(0x67071bc7, 0x88aaa691), TOBN(0x2dea57a9, 0xafe6cb03),
+ TOBN(0xdfe11bb4, 0x3d78ac01), TOBN(0x7286418c, 0x7fd7aa51),
+ TOBN(0xfabf7709, 0x77f7195a), TOBN(0x8ec86167, 0xadeb838f),
+ TOBN(0xea1285a8, 0xbb4f012d), TOBN(0xd6883503, 0x9a3eab3f),
+ TOBN(0xee5d24f8, 0x309004c2), TOBN(0xa96e4b76, 0x13ffe95e),
+ TOBN(0x0cdffe12, 0xbd223ea4), TOBN(0x8f5c2ee5, 0xb6739a53),
+ TOBN(0x5cb4aaa5, 0xdd968198), TOBN(0xfa131c52, 0x72413a6c),
+ TOBN(0x53d46a90, 0x9536d903), TOBN(0xb270f0d3, 0x48606d8e),
+ TOBN(0x518c7564, 0xa053a3bc), TOBN(0x088254b7, 0x1a86caef),
+ TOBN(0xb3ba8cb4, 0x0ab5efd0), TOBN(0x5c59900e, 0x4605945d),
+ TOBN(0xecace1dd, 0xa1887395), TOBN(0x40960f36, 0x932a65de),
+ TOBN(0x9611ff5c, 0x3aa95529), TOBN(0xc58215b0, 0x7c1e5a36),
+ TOBN(0xd48c9b58, 0xf0e1a524), TOBN(0xb406856b, 0xf590dfb8),
+ TOBN(0xc7605e04, 0x9cd95662), TOBN(0x0dd036ee, 0xa33ecf82),
+ TOBN(0xa50171ac, 0xc33156b3), TOBN(0xf09d24ea, 0x4a80172e),
+ TOBN(0x4e1f72c6, 0x76dc8eef), TOBN(0xe60caadc, 0x5e3d44ee),
+ TOBN(0x006ef8a6, 0x979b1d8f), TOBN(0x60908a1c, 0x97788d26),
+ TOBN(0x6e08f95b, 0x266feec0), TOBN(0x618427c2, 0x22e8c94e),
+ TOBN(0x3d613339, 0x59145a65), TOBN(0xcd9bc368, 0xfa406337),
+ TOBN(0x82d11be3, 0x2d8a52a0), TOBN(0xf6877b27, 0x97a1c590),
+ TOBN(0x837a819b, 0xf5cbdb25), TOBN(0x2a4fd1d8, 0xde090249),
+ TOBN(0x622a7de7, 0x74990e5f), TOBN(0x840fa5a0, 0x7945511b),
+ TOBN(0x30b974be, 0x6558842d), TOBN(0x70df8c64, 0x17f3d0a6),
+ TOBN(0x7c803520, 0x7542e46d), TOBN(0x7251fe7f, 0xe4ecc823),
+ TOBN(0xe59134cb, 0x5e9aac9a), TOBN(0x11bb0934, 0xf0045d71),
+ TOBN(0x53e5d9b5, 0xdbcb1d4e), TOBN(0x8d97a905, 0x92defc91),
+ TOBN(0xfe289327, 0x7946d3f9), TOBN(0xe132bd24, 0x07472273),
+ TOBN(0xeeeb510c, 0x1eb6ae86), TOBN(0x777708c5, 0xf0595067),
+ TOBN(0x18e2c8cd, 0x1297029e), TOBN(0x2c61095c, 0xbbf9305e),
+ TOBN(0xe466c258, 0x6b85d6d9), TOBN(0x8ac06c36, 0xda1ea530),
+ TOBN(0xa365dc39, 0xa1304668), TOBN(0xe4a9c885, 0x07f89606),
+ TOBN(0x65a4898f, 0xacc7228d), TOBN(0x3e2347ff, 0x84ca8303),
+ TOBN(0xa5f6fb77, 0xea7d23a3), TOBN(0x2fac257d, 0x672a71cd),
+ TOBN(0x6908bef8, 0x7e6a44d3), TOBN(0x8ff87566, 0x891d3d7a),
+ TOBN(0xe58e90b3, 0x6b0cf82e), TOBN(0x6438d246, 0x2615b5e7),
+ TOBN(0x07b1f8fc, 0x669c145a), TOBN(0xb0d8b2da, 0x36f1e1cb),
+ TOBN(0x54d5dadb, 0xd9184c4d), TOBN(0x3dbb18d5, 0xf93d9976),
+ TOBN(0x0a3e0f56, 0xd1147d47), TOBN(0x2afa8c8d, 0xa0a48609),
+ TOBN(0x275353e8, 0xbc36742c), TOBN(0x898f427e, 0xeea0ed90),
+ TOBN(0x26f4947e, 0x3e477b00), TOBN(0x8ad8848a, 0x308741e3),
+ TOBN(0x6c703c38, 0xd74a2a46), TOBN(0x5e3e05a9, 0x9ba17ba2),
+ TOBN(0xc1fa6f66, 0x4ab9a9e4), TOBN(0x474a2d9a, 0x3841d6ec),
+ TOBN(0x871239ad, 0x653ae326), TOBN(0x14bcf72a, 0xa74cbb43),
+ TOBN(0x8737650e, 0x20d4c083), TOBN(0x3df86536, 0x110ed4af),
+ TOBN(0xd2d86fe7, 0xb53ca555), TOBN(0x688cb00d, 0xabd5d538),
+ TOBN(0xcf81bda3, 0x1ad38468), TOBN(0x7ccfe3cc, 0xf01167b6),
+ TOBN(0xcf4f47e0, 0x6c4c1fe6), TOBN(0x557e1f1a, 0x298bbb79),
+ TOBN(0xf93b974f, 0x30d45a14), TOBN(0x174a1d2d, 0x0baf97c4),
+ TOBN(0x7a003b30, 0xc51fbf53), TOBN(0xd8940991, 0xee68b225),
+ TOBN(0x5b0aa7b7, 0x1c0f4173), TOBN(0x975797c9, 0xa20a7153),
+ TOBN(0x26e08c07, 0xe3533d77), TOBN(0xd7222e6a, 0x2e341c99),
+ TOBN(0x9d60ec3d, 0x8d2dc4ed), TOBN(0xbdfe0d8f, 0x7c476cf8),
+ TOBN(0x1fe59ab6, 0x1d056605), TOBN(0xa9ea9df6, 0x86a8551f),
+ TOBN(0x8489941e, 0x47fb8d8c), TOBN(0xfeb874eb, 0x4a7f1b10),
+ TOBN(0xfe5fea86, 0x7ee0d98f), TOBN(0x201ad34b, 0xdbf61864),
+ TOBN(0x45d8fe47, 0x37c031d4), TOBN(0xd5f49fae, 0x795f0822),
+ TOBN(0xdb0fb291, 0xc7f4a40c), TOBN(0x2e69d9c1, 0x730ddd92),
+ TOBN(0x754e1054, 0x49d76987), TOBN(0x8a24911d, 0x7662db87),
+ TOBN(0x61fc1810, 0x60a71676), TOBN(0xe852d1a8, 0xf66a8ad1),
+ TOBN(0x172bbd65, 0x6417231e), TOBN(0x0d6de7bd, 0x3babb11f),
+ TOBN(0x6fde6f88, 0xc8e347f8), TOBN(0x1c587547, 0x9bd99cc3),
+ TOBN(0x78e54ed0, 0x34076950), TOBN(0x97f0f334, 0x796e83ba),
+ TOBN(0xe4dbe1ce, 0x4924867a), TOBN(0xbd5f51b0, 0x60b84917),
+ TOBN(0x37530040, 0x3cb09a79), TOBN(0xdb3fe0f8, 0xff1743d8),
+ TOBN(0xed7894d8, 0x556fa9db), TOBN(0xfa262169, 0x23412fbf),
+ TOBN(0x563be0db, 0xba7b9291), TOBN(0x6ca8b8c0, 0x0c9fb234),
+ TOBN(0xed406aa9, 0xbd763802), TOBN(0xc21486a0, 0x65303da1),
+ TOBN(0x61ae291e, 0xc7e62ec4), TOBN(0x622a0492, 0xdf99333e),
+ TOBN(0x7fd80c9d, 0xbb7a8ee0), TOBN(0xdc2ed3bc, 0x6c01aedb),
+ TOBN(0x35c35a12, 0x08be74ec), TOBN(0xd540cb1a, 0x469f671f),
+ TOBN(0xd16ced4e, 0xcf84f6c7), TOBN(0x8561fb9c, 0x2d090f43),
+ TOBN(0x7e693d79, 0x6f239db4), TOBN(0xa736f928, 0x77bd0d94),
+ TOBN(0x07b4d929, 0x2c1950ee), TOBN(0xda177543, 0x56dc11b3),
+ TOBN(0xa5dfbbaa, 0x7a6a878e), TOBN(0x1c70cb29, 0x4decb08a),
+ TOBN(0xfba28c8b, 0x6f0f7c50), TOBN(0xa8eba2b8, 0x854dcc6d),
+ TOBN(0x5ff8e89a, 0x36b78642), TOBN(0x070c1c8e, 0xf6873adf),
+ TOBN(0xbbd3c371, 0x6484d2e4), TOBN(0xfb78318f, 0x0d414129),
+ TOBN(0x2621a39c, 0x6ad93b0b), TOBN(0x979d74c2, 0xa9e917f7),
+ TOBN(0xfc195647, 0x61fb0428), TOBN(0x4d78954a, 0xbee624d4),
+ TOBN(0xb94896e0, 0xb8ae86fd), TOBN(0x6667ac0c, 0xc91c8b13),
+ TOBN(0x9f180512, 0x43bcf832), TOBN(0xfbadf8b7, 0xa0010137),
+ TOBN(0xc69b4089, 0xb3ba8aa7), TOBN(0xfac4bacd, 0xe687ce85),
+ TOBN(0x9164088d, 0x977eab40), TOBN(0x51f4c5b6, 0x2760b390),
+ TOBN(0xd238238f, 0x340dd553), TOBN(0x358566c3, 0xdb1d31c9),
+ TOBN(0x3a5ad69e, 0x5068f5ff), TOBN(0xf31435fc, 0xdaff6b06),
+ TOBN(0xae549a5b, 0xd6debff0), TOBN(0x59e5f0b7, 0x75e01331),
+ TOBN(0x5d492fb8, 0x98559acf), TOBN(0x96018c2e, 0x4db79b50),
+ TOBN(0x55f4a48f, 0x609f66aa), TOBN(0x1943b3af, 0x4900a14f),
+ TOBN(0xc22496df, 0x15a40d39), TOBN(0xb2a44684, 0x4c20f7c5),
+ TOBN(0x76a35afa, 0x3b98404c), TOBN(0xbec75725, 0xff5d1b77),
+ TOBN(0xb67aa163, 0xbea06444), TOBN(0x27e95bb2, 0xf724b6f2),
+ TOBN(0x3c20e3e9, 0xd238c8ab), TOBN(0x1213754e, 0xddd6ae17),
+ TOBN(0x8c431020, 0x716e0f74), TOBN(0x6679c82e, 0xffc095c2),
+ TOBN(0x2eb3adf4, 0xd0ac2932), TOBN(0x2cc970d3, 0x01bb7a76),
+ TOBN(0x70c71f2f, 0x740f0e66), TOBN(0x545c616b, 0x2b6b23cc),
+ TOBN(0x4528cfcb, 0xb40a8bd7), TOBN(0xff839633, 0x2ab27722),
+ TOBN(0x049127d9, 0x025ac99a), TOBN(0xd314d4a0, 0x2b63e33b),
+ TOBN(0xc8c310e7, 0x28d84519), TOBN(0x0fcb8983, 0xb3bc84ba),
+ TOBN(0x2cc52261, 0x38634818), TOBN(0x501814f4, 0xb44c2e0b),
+ TOBN(0xf7e181aa, 0x54dfdba3), TOBN(0xcfd58ff0, 0xe759718c),
+ TOBN(0xf90cdb14, 0xd3b507a8), TOBN(0x57bd478e, 0xc50bdad8),
+ TOBN(0x29c197e2, 0x50e5f9aa), TOBN(0x4db6eef8, 0xe40bc855),
+ TOBN(0x2cc8f21a, 0xd1fc0654), TOBN(0xc71cc963, 0x81269d73),
+ TOBN(0xecfbb204, 0x077f49f9), TOBN(0xdde92571, 0xca56b793),
+ TOBN(0x9abed6a3, 0xf97ad8f7), TOBN(0xe6c19d3f, 0x924de3bd),
+ TOBN(0x8dce92f4, 0xa140a800), TOBN(0x85f44d1e, 0x1337af07),
+ TOBN(0x5953c08b, 0x09d64c52), TOBN(0xa1b5e49f, 0xf5df9749),
+ TOBN(0x336a8fb8, 0x52735f7d), TOBN(0xb332b6db, 0x9add676b),
+ TOBN(0x558b88a0, 0xb4511aa4), TOBN(0x09788752, 0xdbd5cc55),
+ TOBN(0x16b43b9c, 0xd8cd52bd), TOBN(0x7f0bc5a0, 0xc2a2696b),
+ TOBN(0x146e12d4, 0xc11f61ef), TOBN(0x9ce10754, 0x3a83e79e),
+ TOBN(0x08ec73d9, 0x6cbfca15), TOBN(0x09ff29ad, 0x5b49653f),
+ TOBN(0xe31b72bd, 0xe7da946e), TOBN(0xebf9eb3b, 0xee80a4f2),
+ TOBN(0xd1aabd08, 0x17598ce4), TOBN(0x18b5fef4, 0x53f37e80),
+ TOBN(0xd5d5cdd3, 0x5958cd79), TOBN(0x3580a1b5, 0x1d373114),
+ TOBN(0xa36e4c91, 0xfa935726), TOBN(0xa38c534d, 0xef20d760),
+ TOBN(0x7088e40a, 0x2ff5845b), TOBN(0xe5bb40bd, 0xbd78177f),
+ TOBN(0x4f06a7a8, 0x857f9920), TOBN(0xe3cc3e50, 0xe968f05d),
+ TOBN(0x1d68b7fe, 0xe5682d26), TOBN(0x5206f76f, 0xaec7f87c),
+ TOBN(0x41110530, 0x041951ab), TOBN(0x58ec52c1, 0xd4b5a71a),
+ TOBN(0xf3488f99, 0x0f75cf9a), TOBN(0xf411951f, 0xba82d0d5),
+ TOBN(0x27ee75be, 0x618895ab), TOBN(0xeae060d4, 0x6d8aab14),
+ TOBN(0x9ae1df73, 0x7fb54dc2), TOBN(0x1f3e391b, 0x25963649),
+ TOBN(0x242ec32a, 0xfe055081), TOBN(0x5bd450ef, 0x8491c9bd),
+ TOBN(0x367efc67, 0x981eb389), TOBN(0xed7e1928, 0x3a0550d5),
+ TOBN(0x362e776b, 0xab3ce75c), TOBN(0xe890e308, 0x1f24c523),
+ TOBN(0xb961b682, 0xfeccef76), TOBN(0x8b8e11f5, 0x8bba6d92),
+ TOBN(0x8f2ccc4c, 0x2b2375c4), TOBN(0x0d7f7a52, 0xe2f86cfa),
+ TOBN(0xfd94d30a, 0x9efe5633), TOBN(0x2d8d246b, 0x5451f934),
+ TOBN(0x2234c6e3, 0x244e6a00), TOBN(0xde2b5b0d, 0xddec8c50),
+ TOBN(0x2ce53c5a, 0xbf776f5b), TOBN(0x6f724071, 0x60357b05),
+ TOBN(0xb2593717, 0x71bf3f7a), TOBN(0x87d2501c, 0x440c4a9f),
+ TOBN(0x440552e1, 0x87b05340), TOBN(0xb7bf7cc8, 0x21624c32),
+ TOBN(0x4155a6ce, 0x22facddb), TOBN(0x5a4228cb, 0x889837ef),
+ TOBN(0xef87d6d6, 0xfd4fd671), TOBN(0xa233687e, 0xc2daa10e),
+ TOBN(0x75622244, 0x03c0eb96), TOBN(0x7632d184, 0x8bf19be6),
+ TOBN(0x05d0f8e9, 0x40735ff4), TOBN(0x3a3e6e13, 0xc00931f1),
+ TOBN(0x31ccde6a, 0xdafe3f18), TOBN(0xf381366a, 0xcfe51207),
+ TOBN(0x24c222a9, 0x60167d92), TOBN(0x62f9d6f8, 0x7529f18c),
+ TOBN(0x412397c0, 0x0353b114), TOBN(0x334d89dc, 0xef808043),
+ TOBN(0xd9ec63ba, 0x2a4383ce), TOBN(0xcec8e937, 0x5cf92ba0),
+ TOBN(0xfb8b4288, 0xc8be74c0), TOBN(0x67d6912f, 0x105d4391),
+ TOBN(0x7b996c46, 0x1b913149), TOBN(0x36aae2ef, 0x3a4e02da),
+ TOBN(0xb68aa003, 0x972de594), TOBN(0x284ec70d, 0x4ec6d545),
+ TOBN(0xf3d2b2d0, 0x61391d54), TOBN(0x69c5d5d6, 0xfe114e92),
+ TOBN(0xbe0f00b5, 0xb4482dff), TOBN(0xe1596fa5, 0xf5bf33c5),
+ TOBN(0x10595b56, 0x96a71cba), TOBN(0x944938b2, 0xfdcadeb7),
+ TOBN(0xa282da4c, 0xfccd8471), TOBN(0x98ec05f3, 0x0d37bfe1),
+ TOBN(0xe171ce1b, 0x0698304a), TOBN(0x2d691444, 0x21bdf79b),
+ TOBN(0xd0cd3b74, 0x1b21dec1), TOBN(0x712ecd8b, 0x16a15f71),
+ TOBN(0x8d4c00a7, 0x00fd56e1), TOBN(0x02ec9692, 0xf9527c18),
+ TOBN(0x21c44937, 0x4a3e42e1), TOBN(0x9176fbab, 0x1392ae0a),
+ TOBN(0x8726f1ba, 0x44b7b618), TOBN(0xb4d7aae9, 0xf1de491c),
+ TOBN(0xf91df7b9, 0x07b582c0), TOBN(0x7e116c30, 0xef60aa3a),
+ TOBN(0x99270f81, 0x466265d7), TOBN(0xb15b6fe2, 0x4df7adf0),
+ TOBN(0xfe33b2d3, 0xf9738f7f), TOBN(0x48553ab9, 0xd6d70f95),
+ TOBN(0x2cc72ac8, 0xc21e94db), TOBN(0x795ac38d, 0xbdc0bbee),
+ TOBN(0x0a1be449, 0x2e40478f), TOBN(0x81bd3394, 0x052bde55),
+ TOBN(0x63c8dbe9, 0x56b3c4f2), TOBN(0x017a99cf, 0x904177cc),
+ TOBN(0x947bbddb, 0x4d010fc1), TOBN(0xacf9b00b, 0xbb2c9b21),
+ TOBN(0x2970bc8d, 0x47173611), TOBN(0x1a4cbe08, 0xac7d756f),
+ TOBN(0x06d9f4aa, 0x67d541a2), TOBN(0xa3e8b689, 0x59c2cf44),
+ TOBN(0xaad066da, 0x4d88f1dd), TOBN(0xc604f165, 0x7ad35dea),
+ TOBN(0x7edc0720, 0x4478ca67), TOBN(0xa10dfae0, 0xba02ce06),
+ TOBN(0xeceb1c76, 0xaf36f4e4), TOBN(0x994b2292, 0xaf3f8f48),
+ TOBN(0xbf9ed77b, 0x77c8a68c), TOBN(0x74f544ea, 0x51744c9d),
+ TOBN(0x82d05bb9, 0x8113a757), TOBN(0x4ef2d2b4, 0x8a9885e4),
+ TOBN(0x1e332be5, 0x1aa7865f), TOBN(0x22b76b18, 0x290d1a52),
+ TOBN(0x308a2310, 0x44351683), TOBN(0x9d861896, 0xa3f22840),
+ TOBN(0x5959ddcd, 0x841ed947), TOBN(0x0def0c94, 0x154b73bf),
+ TOBN(0xf0105417, 0x4c7c15e0), TOBN(0x539bfb02, 0x3a277c32),
+ TOBN(0xe699268e, 0xf9dccf5f), TOBN(0x9f5796a5, 0x0247a3bd),
+ TOBN(0x8b839de8, 0x4f157269), TOBN(0xc825c1e5, 0x7a30196b),
+ TOBN(0x6ef0aabc, 0xdc8a5a91), TOBN(0xf4a8ce6c, 0x498b7fe6),
+ TOBN(0x1cce35a7, 0x70cbac78), TOBN(0x83488e9b, 0xf6b23958),
+ TOBN(0x0341a070, 0xd76cb011), TOBN(0xda6c9d06, 0xae1b2658),
+ TOBN(0xb701fb30, 0xdd648c52), TOBN(0x994ca02c, 0x52fb9fd1),
+ TOBN(0x06933117, 0x6f563086), TOBN(0x3d2b8100, 0x17856bab),
+ TOBN(0xe89f48c8, 0x5963a46e), TOBN(0x658ab875, 0xa99e61c7),
+ TOBN(0x6e296f87, 0x4b8517b4), TOBN(0x36c4fcdc, 0xfc1bc656),
+ TOBN(0xde5227a1, 0xa3906def), TOBN(0x9fe95f57, 0x62418945),
+ TOBN(0x20c91e81, 0xfdd96cde), TOBN(0x5adbe47e, 0xda4480de),
+ TOBN(0xa009370f, 0x396de2b6), TOBN(0x98583d4b, 0xf0ecc7bd),
+ TOBN(0xf44f6b57, 0xe51d0672), TOBN(0x03d6b078, 0x556b1984),
+ TOBN(0x27dbdd93, 0xb0b64912), TOBN(0x9b3a3434, 0x15687b09),
+ TOBN(0x0dba6461, 0x51ec20a9), TOBN(0xec93db7f, 0xff28187c),
+ TOBN(0x00ff8c24, 0x66e48bdd), TOBN(0x2514f2f9, 0x11ccd78e),
+ TOBN(0xeba11f4f, 0xe1250603), TOBN(0x8a22cd41, 0x243fa156),
+ TOBN(0xa4e58df4, 0xb283e4c6), TOBN(0x78c29859, 0x8b39783f),
+ TOBN(0x5235aee2, 0xa5259809), TOBN(0xc16284b5, 0x0e0227dd),
+ TOBN(0xa5f57916, 0x1338830d), TOBN(0x6d4b8a6b, 0xd2123fca),
+ TOBN(0x236ea68a, 0xf9c546f8), TOBN(0xc1d36873, 0xfa608d36),
+ TOBN(0xcd76e495, 0x8d436d13), TOBN(0xd4d9c221, 0x8fb080af),
+ TOBN(0x665c1728, 0xe8ad3fb5), TOBN(0xcf1ebe4d, 0xb3d572e0),
+ TOBN(0xa7a8746a, 0x584c5e20), TOBN(0x267e4ea1, 0xb9dc7035),
+ TOBN(0x593a15cf, 0xb9548c9b), TOBN(0x5e6e2135, 0x4bd012f3),
+ TOBN(0xdf31cc6a, 0x8c8f936e), TOBN(0x8af84d04, 0xb5c241dc),
+ TOBN(0x63990a6f, 0x345efb86), TOBN(0x6fef4e61, 0xb9b962cb)},
+ {TOBN(0xf6368f09, 0x25722608), TOBN(0x131260db, 0x131cf5c6),
+ TOBN(0x40eb353b, 0xfab4f7ac), TOBN(0x85c78880, 0x37eee829),
+ TOBN(0x4c1581ff, 0xc3bdf24e), TOBN(0x5bff75cb, 0xf5c3c5a8),
+ TOBN(0x35e8c83f, 0xa14e6f40), TOBN(0xb81d1c0f, 0x0295e0ca),
+ TOBN(0xfcde7cc8, 0xf43a730f), TOBN(0xe89b6f3c, 0x33ab590e),
+ TOBN(0xc823f529, 0xad03240b), TOBN(0x82b79afe, 0x98bea5db),
+ TOBN(0x568f2856, 0x962fe5de), TOBN(0x0c590adb, 0x60c591f3),
+ TOBN(0x1fc74a14, 0x4a28a858), TOBN(0x3b662498, 0xb3203f4c),
+ TOBN(0x91e3cf0d, 0x6c39765a), TOBN(0xa2db3acd, 0xac3cca0b),
+ TOBN(0x288f2f08, 0xcb953b50), TOBN(0x2414582c, 0xcf43cf1a),
+ TOBN(0x8dec8bbc, 0x60eee9a8), TOBN(0x54c79f02, 0x729aa042),
+ TOBN(0xd81cd5ec, 0x6532f5d5), TOBN(0xa672303a, 0xcf82e15f),
+ TOBN(0x376aafa8, 0x719c0563), TOBN(0xcd8ad2dc, 0xbc5fc79f),
+ TOBN(0x303fdb9f, 0xcb750cd3), TOBN(0x14ff052f, 0x4418b08e),
+ TOBN(0xf75084cf, 0x3e2d6520), TOBN(0x7ebdf0f8, 0x144ed509),
+ TOBN(0xf43bf0f2, 0xd3f25b98), TOBN(0x86ad71cf, 0xa354d837),
+ TOBN(0xb827fe92, 0x26f43572), TOBN(0xdfd3ab5b, 0x5d824758),
+ TOBN(0x315dd23a, 0x539094c1), TOBN(0x85c0e37a, 0x66623d68),
+ TOBN(0x575c7972, 0x7be19ae0), TOBN(0x616a3396, 0xdf0d36b5),
+ TOBN(0xa1ebb3c8, 0x26b1ff7e), TOBN(0x635b9485, 0x140ad453),
+ TOBN(0x92bf3cda, 0xda430c0b), TOBN(0x4702850e, 0x3a96dac6),
+ TOBN(0xc91cf0a5, 0x15ac326a), TOBN(0x95de4f49, 0xab8c25e4),
+ TOBN(0xb01bad09, 0xe265c17c), TOBN(0x24e45464, 0x087b3881),
+ TOBN(0xd43e583c, 0xe1fac5ca), TOBN(0xe17cb318, 0x6ead97a6),
+ TOBN(0x6cc39243, 0x74dcec46), TOBN(0x33cfc02d, 0x54c2b73f),
+ TOBN(0x82917844, 0xf26cd99c), TOBN(0x8819dd95, 0xd1773f89),
+ TOBN(0x09572aa6, 0x0871f427), TOBN(0x8e0cf365, 0xf6f01c34),
+ TOBN(0x7fa52988, 0xbff1f5af), TOBN(0x4eb357ea, 0xe75e8e50),
+ TOBN(0xd9d0c8c4, 0x868af75d), TOBN(0xd7325cff, 0x45c8c7ea),
+ TOBN(0xab471996, 0xcc81ecb0), TOBN(0xff5d55f3, 0x611824ed),
+ TOBN(0xbe314541, 0x1977a0ee), TOBN(0x5085c4c5, 0x722038c6),
+ TOBN(0x2d5335bf, 0xf94bb495), TOBN(0x894ad8a6, 0xc8e2a082),
+ TOBN(0x5c3e2341, 0xada35438), TOBN(0xf4a9fc89, 0x049b8c4e),
+ TOBN(0xbeeb355a, 0x9f17cf34), TOBN(0x3f311e0e, 0x6c91fe10),
+ TOBN(0xc2d20038, 0x92ab9891), TOBN(0x257bdcc1, 0x3e8ce9a9),
+ TOBN(0x1b2d9789, 0x88c53bee), TOBN(0x927ce89a, 0xcdba143a),
+ TOBN(0xb0a32cca, 0x523db280), TOBN(0x5c889f8a, 0x50d43783),
+ TOBN(0x503e04b3, 0x4897d16f), TOBN(0x8cdb6e78, 0x08f5f2e8),
+ TOBN(0x6ab91cf0, 0x179c8e74), TOBN(0xd8874e52, 0x48211d60),
+ TOBN(0xf948d4d5, 0xea851200), TOBN(0x4076d41e, 0xe6f9840a),
+ TOBN(0xc20e263c, 0x47b517ea), TOBN(0x79a448fd, 0x30685e5e),
+ TOBN(0xe55f6f78, 0xf90631a0), TOBN(0x88a790b1, 0xa79e6346),
+ TOBN(0x62160c7d, 0x80969fe8), TOBN(0x54f92fd4, 0x41491bb9),
+ TOBN(0xa6645c23, 0x5c957526), TOBN(0xf44cc5ae, 0xbea3ce7b),
+ TOBN(0xf7628327, 0x8b1e68b7), TOBN(0xc731ad7a, 0x303f29d3),
+ TOBN(0xfe5a9ca9, 0x57d03ecb), TOBN(0x96c0d50c, 0x41bc97a7),
+ TOBN(0xc4669fe7, 0x9b4f7f24), TOBN(0xfdd781d8, 0x3d9967ef),
+ TOBN(0x7892c7c3, 0x5d2c208d), TOBN(0x8bf64f7c, 0xae545cb3),
+ TOBN(0xc01f862c, 0x467be912), TOBN(0xf4c85ee9, 0xc73d30cc),
+ TOBN(0x1fa6f4be, 0x6ab83ec7), TOBN(0xa07a3c1c, 0x4e3e3cf9),
+ TOBN(0x87f8ef45, 0x0c00beb3), TOBN(0x30e2c2b3, 0x000d4c3e),
+ TOBN(0x1aa00b94, 0xfe08bf5b), TOBN(0x32c133aa, 0x9224ef52),
+ TOBN(0x38df16bb, 0x32e5685d), TOBN(0x68a9e069, 0x58e6f544),
+ TOBN(0x495aaff7, 0xcdc5ebc6), TOBN(0xf894a645, 0x378b135f),
+ TOBN(0xf316350a, 0x09e27ecf), TOBN(0xeced201e, 0x58f7179d),
+ TOBN(0x2eec273c, 0xe97861ba), TOBN(0x47ec2cae, 0xd693be2e),
+ TOBN(0xfa4c97c4, 0xf68367ce), TOBN(0xe4f47d0b, 0xbe5a5755),
+ TOBN(0x17de815d, 0xb298a979), TOBN(0xd7eca659, 0xc177dc7d),
+ TOBN(0x20fdbb71, 0x49ded0a3), TOBN(0x4cb2aad4, 0xfb34d3c5),
+ TOBN(0x2cf31d28, 0x60858a33), TOBN(0x3b6873ef, 0xa24aa40f),
+ TOBN(0x540234b2, 0x2c11bb37), TOBN(0x2d0366dd, 0xed4c74a3),
+ TOBN(0xf9a968da, 0xeec5f25d), TOBN(0x36601068, 0x67b63142),
+ TOBN(0x07cd6d2c, 0x68d7b6d4), TOBN(0xa8f74f09, 0x0c842942),
+ TOBN(0xe2751404, 0x7768b1ee), TOBN(0x4b5f7e89, 0xfe62aee4),
+ TOBN(0xc6a77177, 0x89070d26), TOBN(0xa1f28e4e, 0xdd1c8bc7),
+ TOBN(0xea5f4f06, 0x469e1f17), TOBN(0x78fc242a, 0xfbdb78e0),
+ TOBN(0xc9c7c592, 0x8b0588f1), TOBN(0xb6b7a0fd, 0x1535921e),
+ TOBN(0xcc5bdb91, 0xbde5ae35), TOBN(0xb42c485e, 0x12ff1864),
+ TOBN(0xa1113e13, 0xdbab98aa), TOBN(0xde9d469b, 0xa17b1024),
+ TOBN(0x23f48b37, 0xc0462d3a), TOBN(0x3752e537, 0x7c5c078d),
+ TOBN(0xe3a86add, 0x15544eb9), TOBN(0xf013aea7, 0x80fba279),
+ TOBN(0x8b5bb76c, 0xf22001b5), TOBN(0xe617ba14, 0xf02891ab),
+ TOBN(0xd39182a6, 0x936219d3), TOBN(0x5ce1f194, 0xae51cb19),
+ TOBN(0xc78f8598, 0xbf07a74c), TOBN(0x6d7158f2, 0x22cbf1bc),
+ TOBN(0x3b846b21, 0xe300ce18), TOBN(0x35fba630, 0x2d11275d),
+ TOBN(0x5fe25c36, 0xa0239b9b), TOBN(0xd8beb35d, 0xdf05d940),
+ TOBN(0x4db02bb0, 0x1f7e320d), TOBN(0x0641c364, 0x6da320ea),
+ TOBN(0x6d95fa5d, 0x821389a3), TOBN(0x92699748, 0x8fcd8e3d),
+ TOBN(0x316fef17, 0xceb6c143), TOBN(0x67fcb841, 0xd933762b),
+ TOBN(0xbb837e35, 0x118b17f8), TOBN(0x4b92552f, 0x9fd24821),
+ TOBN(0xae6bc70e, 0x46aca793), TOBN(0x1cf0b0e4, 0xe579311b),
+ TOBN(0x8dc631be, 0x5802f716), TOBN(0x099bdc6f, 0xbddbee4d),
+ TOBN(0xcc352bb2, 0x0caf8b05), TOBN(0xf74d505a, 0x72d63df2),
+ TOBN(0xb9876d4b, 0x91c4f408), TOBN(0x1ce18473, 0x9e229b2d),
+ TOBN(0x49507597, 0x83abdb4a), TOBN(0x850fbcb6, 0xdee84b18),
+ TOBN(0x6325236e, 0x609e67dc), TOBN(0x04d831d9, 0x9336c6d8),
+ TOBN(0x8deaae3b, 0xfa12d45d), TOBN(0xe425f8ce, 0x4746e246),
+ TOBN(0x8004c175, 0x24f5f31e), TOBN(0xaca16d8f, 0xad62c3b7),
+ TOBN(0x0dc15a6a, 0x9152f934), TOBN(0xf1235e5d, 0xed0e12c1),
+ TOBN(0xc33c06ec, 0xda477dac), TOBN(0x76be8732, 0xb2ea0006),
+ TOBN(0xcf3f7831, 0x0c0cd313), TOBN(0x3c524553, 0xa614260d),
+ TOBN(0x31a756f8, 0xcab22d15), TOBN(0x03ee10d1, 0x77827a20),
+ TOBN(0xd1e059b2, 0x1994ef20), TOBN(0x2a653b69, 0x638ae318),
+ TOBN(0x70d5eb58, 0x2f699010), TOBN(0x279739f7, 0x09f5f84a),
+ TOBN(0x5da4663c, 0x8b799336), TOBN(0xfdfdf14d, 0x203c37eb),
+ TOBN(0x32d8a9dc, 0xa1dbfb2d), TOBN(0xab40cff0, 0x77d48f9b),
+ TOBN(0xc018b383, 0xd20b42d5), TOBN(0xf9a810ef, 0x9f78845f),
+ TOBN(0x40af3753, 0xbdba9df0), TOBN(0xb90bdcfc, 0x131dfdf9),
+ TOBN(0x18720591, 0xf01ab782), TOBN(0xc823f211, 0x6af12a88),
+ TOBN(0xa51b80f3, 0x0dc14401), TOBN(0xde248f77, 0xfb2dfbe3),
+ TOBN(0xef5a44e5, 0x0cafe751), TOBN(0x73997c9c, 0xd4dcd221),
+ TOBN(0x32fd86d1, 0xde854024), TOBN(0xd5b53adc, 0xa09b84bb),
+ TOBN(0x008d7a11, 0xdcedd8d1), TOBN(0x406bd1c8, 0x74b32c84),
+ TOBN(0x5d4472ff, 0x05dde8b1), TOBN(0x2e25f2cd, 0xfce2b32f),
+ TOBN(0xbec0dd5e, 0x29dfc254), TOBN(0x4455fcf6, 0x2b98b267),
+ TOBN(0x0b4d43a5, 0xc72df2ad), TOBN(0xea70e6be, 0x48a75397),
+ TOBN(0x2aad6169, 0x5820f3bf), TOBN(0xf410d2dd, 0x9e37f68f),
+ TOBN(0x70fb7dba, 0x7be5ac83), TOBN(0x636bb645, 0x36ec3eec),
+ TOBN(0x27104ea3, 0x9754e21c), TOBN(0xbc87a3e6, 0x8d63c373),
+ TOBN(0x483351d7, 0x4109db9a), TOBN(0x0fa724e3, 0x60134da7),
+ TOBN(0x9ff44c29, 0xb0720b16), TOBN(0x2dd0cf13, 0x06aceead),
+ TOBN(0x5942758c, 0xe26929a6), TOBN(0x96c5db92, 0xb766a92b),
+ TOBN(0xcec7d4c0, 0x5f18395e), TOBN(0xd3f22744, 0x1f80d032),
+ TOBN(0x7a68b37a, 0xcb86075b), TOBN(0x074764dd, 0xafef92db),
+ TOBN(0xded1e950, 0x7bc7f389), TOBN(0xc580c850, 0xb9756460),
+ TOBN(0xaeeec2a4, 0x7da48157), TOBN(0x3f0b4e7f, 0x82c587b3),
+ TOBN(0x231c6de8, 0xa9f19c53), TOBN(0x5717bd73, 0x6974e34e),
+ TOBN(0xd9e1d216, 0xf1508fa9), TOBN(0x9f112361, 0xdadaa124),
+ TOBN(0x80145e31, 0x823b7348), TOBN(0x4dd8f0d5, 0xac634069),
+ TOBN(0xe3d82fc7, 0x2297c258), TOBN(0x276fcfee, 0x9cee7431),
+ TOBN(0x8eb61b5e, 0x2bc0aea9), TOBN(0x4f668fd5, 0xde329431),
+ TOBN(0x03a32ab1, 0x38e4b87e), TOBN(0xe1374517, 0x73d0ef0b),
+ TOBN(0x1a46f7e6, 0x853ac983), TOBN(0xc3bdf42e, 0x68e78a57),
+ TOBN(0xacf20785, 0x2ea96dd1), TOBN(0xa10649b9, 0xf1638460),
+ TOBN(0xf2369f0b, 0x879fbbed), TOBN(0x0ff0ae86, 0xda9d1869),
+ TOBN(0x5251d759, 0x56766f45), TOBN(0x4984d8c0, 0x2be8d0fc),
+ TOBN(0x7ecc95a6, 0xd21008f0), TOBN(0x29bd54a0, 0x3a1a1c49),
+ TOBN(0xab9828c5, 0xd26c50f3), TOBN(0x32c0087c, 0x51d0d251),
+ TOBN(0x9bac3ce6, 0x0c1cdb26), TOBN(0xcd94d947, 0x557ca205),
+ TOBN(0x1b1bd598, 0x9db1fdcd), TOBN(0x0eda0108, 0xa3d8b149),
+ TOBN(0x95066610, 0x56152fcc), TOBN(0xc2f037e6, 0xe7192b33),
+ TOBN(0xdeffb41a, 0xc92e05a4), TOBN(0x1105f6c2, 0xc2f6c62e),
+ TOBN(0x68e73500, 0x8733913c), TOBN(0xcce86163, 0x3f3adc40),
+ TOBN(0xf407a942, 0x38a278e9), TOBN(0xd13c1b9d, 0x2ab21292),
+ TOBN(0x93ed7ec7, 0x1c74cf5c), TOBN(0x8887dc48, 0xf1a4c1b4),
+ TOBN(0x3830ff30, 0x4b3a11f1), TOBN(0x358c5a3c, 0x58937cb6),
+ TOBN(0x027dc404, 0x89022829), TOBN(0x40e93977, 0x3b798f79),
+ TOBN(0x90ad3337, 0x38be6ead), TOBN(0x9c23f6bc, 0xf34c0a5d),
+ TOBN(0xd1711a35, 0xfbffd8bb), TOBN(0x60fcfb49, 0x1949d3dd),
+ TOBN(0x09c8ef4b, 0x7825d93a), TOBN(0x24233cff, 0xa0a8c968),
+ TOBN(0x67ade46c, 0xe6d982af), TOBN(0xebb6bf3e, 0xe7544d7c),
+ TOBN(0xd6b9ba76, 0x3d8bd087), TOBN(0x46fe382d, 0x4dc61280),
+ TOBN(0xbd39a7e8, 0xb5bdbd75), TOBN(0xab381331, 0xb8f228fe),
+ TOBN(0x0709a77c, 0xce1c4300), TOBN(0x6a247e56, 0xf337ceac),
+ TOBN(0x8f34f21b, 0x636288be), TOBN(0x9dfdca74, 0xc8a7c305),
+ TOBN(0x6decfd1b, 0xea919e04), TOBN(0xcdf2688d, 0x8e1991f8),
+ TOBN(0xe607df44, 0xd0f8a67e), TOBN(0xd985df4b, 0x0b58d010),
+ TOBN(0x57f834c5, 0x0c24f8f4), TOBN(0xe976ef56, 0xa0bf01ae),
+ TOBN(0x536395ac, 0xa1c32373), TOBN(0x351027aa, 0x734c0a13),
+ TOBN(0xd2f1b5d6, 0x5e6bd5bc), TOBN(0x2b539e24, 0x223debed),
+ TOBN(0xd4994cec, 0x0eaa1d71), TOBN(0x2a83381d, 0x661dcf65),
+ TOBN(0x5f1aed2f, 0x7b54c740), TOBN(0x0bea3fa5, 0xd6dda5ee),
+ TOBN(0x9d4fb684, 0x36cc6134), TOBN(0x8eb9bbf3, 0xc0a443dd),
+ TOBN(0xfc500e2e, 0x383b7d2a), TOBN(0x7aad621c, 0x5b775257),
+ TOBN(0x69284d74, 0x0a8f7cc0), TOBN(0xe820c2ce, 0x07562d65),
+ TOBN(0xbf9531b9, 0x499758ee), TOBN(0x73e95ca5, 0x6ee0cc2d),
+ TOBN(0xf61790ab, 0xfbaf50a5), TOBN(0xdf55e76b, 0x684e0750),
+ TOBN(0xec516da7, 0xf176b005), TOBN(0x575553bb, 0x7a2dddc7),
+ TOBN(0x37c87ca3, 0x553afa73), TOBN(0x315f3ffc, 0x4d55c251),
+ TOBN(0xe846442a, 0xaf3e5d35), TOBN(0x61b91149, 0x6495ff28),
+ TOBN(0x23cc95d3, 0xfa326dc3), TOBN(0x1df4da1f, 0x18fc2cea),
+ TOBN(0x24bf9adc, 0xd0a37d59), TOBN(0xb6710053, 0x320d6e1e),
+ TOBN(0x96f9667e, 0x618344d1), TOBN(0xcc7ce042, 0xa06445af),
+ TOBN(0xa02d8514, 0xd68dbc3a), TOBN(0x4ea109e4, 0x280b5a5b),
+ TOBN(0x5741a7ac, 0xb40961bf), TOBN(0x4ada5937, 0x6aa56bfa),
+ TOBN(0x7feb9145, 0x02b765d1), TOBN(0x561e97be, 0xe6ad1582),
+ TOBN(0xbbc4a5b6, 0xda3982f5), TOBN(0x0c2659ed, 0xb546f468),
+ TOBN(0xb8e7e6aa, 0x59612d20), TOBN(0xd83dfe20, 0xac19e8e0),
+ TOBN(0x8530c45f, 0xb835398c), TOBN(0x6106a8bf, 0xb38a41c2),
+ TOBN(0x21e8f9a6, 0x35f5dcdb), TOBN(0x39707137, 0xcae498ed),
+ TOBN(0x70c23834, 0xd8249f00), TOBN(0x9f14b58f, 0xab2537a0),
+ TOBN(0xd043c365, 0x5f61c0c2), TOBN(0xdc5926d6, 0x09a194a7),
+ TOBN(0xddec0339, 0x8e77738a), TOBN(0xd07a63ef, 0xfba46426),
+ TOBN(0x2e58e79c, 0xee7f6e86), TOBN(0xe59b0459, 0xff32d241),
+ TOBN(0xc5ec84e5, 0x20fa0338), TOBN(0x97939ac8, 0xeaff5ace),
+ TOBN(0x0310a4e3, 0xb4a38313), TOBN(0x9115fba2, 0x8f9d9885),
+ TOBN(0x8dd710c2, 0x5fadf8c3), TOBN(0x66be38a2, 0xce19c0e2),
+ TOBN(0xd42a279c, 0x4cfe5022), TOBN(0x597bb530, 0x0e24e1b8),
+ TOBN(0x3cde86b7, 0xc153ca7f), TOBN(0xa8d30fb3, 0x707d63bd),
+ TOBN(0xac905f92, 0xbd60d21e), TOBN(0x98e7ffb6, 0x7b9a54ab),
+ TOBN(0xd7147df8, 0xe9726a30), TOBN(0xb5e216ff, 0xafce3533),
+ TOBN(0xb550b799, 0x2ff1ec40), TOBN(0x6b613b87, 0xa1e953fd),
+ TOBN(0x87b88dba, 0x792d5610), TOBN(0x2ee1270a, 0xa190fbe1),
+ TOBN(0x02f4e2dc, 0x2ef581da), TOBN(0x016530e4, 0xeff82a95),
+ TOBN(0xcbb93dfd, 0x8fd6ee89), TOBN(0x16d3d986, 0x46848fff),
+ TOBN(0x600eff24, 0x1da47adf), TOBN(0x1b9754a0, 0x0ad47a71),
+ TOBN(0x8f9266df, 0x70c33b98), TOBN(0xaadc87ae, 0xdf34186e),
+ TOBN(0x0d2ce8e1, 0x4ad24132), TOBN(0x8a47cbfc, 0x19946eba),
+ TOBN(0x47feeb66, 0x62b5f3af), TOBN(0xcefab561, 0x0abb3734),
+ TOBN(0x449de60e, 0x19f35cb1), TOBN(0x39f8db14, 0x157f0eb9),
+ TOBN(0xffaecc5b, 0x3c61bfd6), TOBN(0xa5a4d41d, 0x41216703),
+ TOBN(0x7f8fabed, 0x224e1cc2), TOBN(0x0d5a8186, 0x871ad953),
+ TOBN(0xf10774f7, 0xd22da9a9), TOBN(0x45b8a678, 0xcc8a9b0d),
+ TOBN(0xd9c2e722, 0xbdc32cff), TOBN(0xbf71b5f5, 0x337202a5),
+ TOBN(0x95c57f2f, 0x69fc4db9), TOBN(0xb6dad34c, 0x765d01e1),
+ TOBN(0x7e0bd13f, 0xcb904635), TOBN(0x61751253, 0x763a588c),
+ TOBN(0xd85c2997, 0x81af2c2d), TOBN(0xc0f7d9c4, 0x81b9d7da),
+ TOBN(0x838a34ae, 0x08533e8d), TOBN(0x15c4cb08, 0x311d8311),
+ TOBN(0x97f83285, 0x8e121e14), TOBN(0xeea7dc1e, 0x85000a5f),
+ TOBN(0x0c6059b6, 0x5d256274), TOBN(0xec9beace, 0xb95075c0),
+ TOBN(0x173daad7, 0x1df97828), TOBN(0xbf851cb5, 0xa8937877),
+ TOBN(0xb083c594, 0x01646f3c), TOBN(0x3bad30cf, 0x50c6d352),
+ TOBN(0xfeb2b202, 0x496bbcea), TOBN(0x3cf9fd4f, 0x18a1e8ba),
+ TOBN(0xd26de7ff, 0x1c066029), TOBN(0x39c81e9e, 0x4e9ed4f8),
+ TOBN(0xd8be0cb9, 0x7b390d35), TOBN(0x01df2bbd, 0x964aab27),
+ TOBN(0x3e8c1a65, 0xc3ef64f8), TOBN(0x567291d1, 0x716ed1dd),
+ TOBN(0x95499c6c, 0x5f5406d3), TOBN(0x71fdda39, 0x5ba8e23f),
+ TOBN(0xcfeb320e, 0xd5096ece), TOBN(0xbe7ba92b, 0xca66dd16),
+ TOBN(0x4608d36b, 0xc6fb5a7d), TOBN(0xe3eea15a, 0x6d2dd0e0),
+ TOBN(0x75b0a3eb, 0x8f97a36a), TOBN(0xf59814cc, 0x1c83de1e),
+ TOBN(0x56c9c5b0, 0x1c33c23f), TOBN(0xa96c1da4, 0x6faa4136),
+ TOBN(0x46bf2074, 0xde316551), TOBN(0x3b866e7b, 0x1f756c8f),
+ TOBN(0x727727d8, 0x1495ed6b), TOBN(0xb2394243, 0xb682dce7),
+ TOBN(0x8ab8454e, 0x758610f3), TOBN(0xc243ce84, 0x857d72a4),
+ TOBN(0x7b320d71, 0xdbbf370f), TOBN(0xff9afa37, 0x78e0f7ca),
+ TOBN(0x0119d1e0, 0xea7b523f), TOBN(0xb997f8cb, 0x058c7d42),
+ TOBN(0x285bcd2a, 0x37bbb184), TOBN(0x51dcec49, 0xa45d1fa6),
+ TOBN(0x6ade3b64, 0xe29634cb), TOBN(0x080c94a7, 0x26b86ef1),
+ TOBN(0xba583db1, 0x2283fbe3), TOBN(0x902bddc8, 0x5a9315ed),
+ TOBN(0x07c1ccb3, 0x86964bec), TOBN(0x78f4eacf, 0xb6258301),
+ TOBN(0x4bdf3a49, 0x56f90823), TOBN(0xba0f5080, 0x741d777b),
+ TOBN(0x091d71c3, 0xf38bf760), TOBN(0x9633d50f, 0x9b625b02),
+ TOBN(0x03ecb743, 0xb8c9de61), TOBN(0xb4751254, 0x5de74720),
+ TOBN(0x9f9defc9, 0x74ce1cb2), TOBN(0x774a4f6a, 0x00bd32ef),
+ TOBN(0xaca385f7, 0x73848f22), TOBN(0x53dad716, 0xf3f8558e),
+ TOBN(0xab7b34b0, 0x93c471f9), TOBN(0xf530e069, 0x19644bc7),
+ TOBN(0x3d9fb1ff, 0xdd59d31a), TOBN(0x4382e0df, 0x08daa795),
+ TOBN(0x165c6f4b, 0xd5cc88d7), TOBN(0xeaa392d5, 0x4a18c900),
+ TOBN(0x94203c67, 0x648024ee), TOBN(0x188763f2, 0x8c2fabcd),
+ TOBN(0xa80f87ac, 0xbbaec835), TOBN(0x632c96e0, 0xf29d8d54),
+ TOBN(0x29b0a60e, 0x4c00a95e), TOBN(0x2ef17f40, 0xe011e9fa),
+ TOBN(0xf6c0e1d1, 0x15b77223), TOBN(0xaaec2c62, 0x14b04e32),
+ TOBN(0xd35688d8, 0x3d84e58c), TOBN(0x2af5094c, 0x958571db),
+ TOBN(0x4fff7e19, 0x760682a6), TOBN(0x4cb27077, 0xe39a407c),
+ TOBN(0x0f59c547, 0x4ff0e321), TOBN(0x169f34a6, 0x1b34c8ff),
+ TOBN(0x2bff1096, 0x52bc1ba7), TOBN(0xa25423b7, 0x83583544),
+ TOBN(0x5d55d5d5, 0x0ac8b782), TOBN(0xff6622ec, 0x2db3c892),
+ TOBN(0x48fce741, 0x6b8bb642), TOBN(0x31d6998c, 0x69d7e3dc),
+ TOBN(0xdbaf8004, 0xcadcaed0), TOBN(0x801b0142, 0xd81d053c),
+ TOBN(0x94b189fc, 0x59630ec6), TOBN(0x120e9934, 0xaf762c8e),
+ TOBN(0x53a29aa4, 0xfdc6a404), TOBN(0x19d8e01e, 0xa1909948),
+ TOBN(0x3cfcabf1, 0xd7e89681), TOBN(0x3321a50d, 0x4e132d37),
+ TOBN(0xd0496863, 0xe9a86111), TOBN(0x8c0cde61, 0x06a3bc65),
+ TOBN(0xaf866c49, 0xfc9f8eef), TOBN(0x2066350e, 0xff7f5141),
+ TOBN(0x4f8a4689, 0xe56ddfbd), TOBN(0xea1b0c07, 0xfe32983a),
+ TOBN(0x2b317462, 0x873cb8cb), TOBN(0x658deddc, 0x2d93229f),
+ TOBN(0x65efaf4d, 0x0f64ef58), TOBN(0xfe43287d, 0x730cc7a8),
+ TOBN(0xaebc0c72, 0x3d047d70), TOBN(0x92efa539, 0xd92d26c9),
+ TOBN(0x06e78457, 0x94b56526), TOBN(0x415cb80f, 0x0961002d),
+ TOBN(0x89e5c565, 0x76dcb10f), TOBN(0x8bbb6982, 0xff9259fe),
+ TOBN(0x4fe8795b, 0x9abc2668), TOBN(0xb5d4f534, 0x1e678fb1),
+ TOBN(0x6601f3be, 0x7b7da2b9), TOBN(0x98da59e2, 0xa13d6805),
+ TOBN(0x190d8ea6, 0x01799a52), TOBN(0xa20cec41, 0xb86d2952),
+ TOBN(0x3062ffb2, 0x7fff2a7c), TOBN(0x741b32e5, 0x79f19d37),
+ TOBN(0xf80d8181, 0x4eb57d47), TOBN(0x7a2d0ed4, 0x16aef06b),
+ TOBN(0x09735fb0, 0x1cecb588), TOBN(0x1641caaa, 0xc6061f5b)},
+ {TOBN(0x7f99824f, 0x20151427), TOBN(0x206828b6, 0x92430206),
+ TOBN(0xaa9097d7, 0xe1112357), TOBN(0xacf9a2f2, 0x09e414ec),
+ TOBN(0xdbdac9da, 0x27915356), TOBN(0x7e0734b7, 0x001efee3),
+ TOBN(0x54fab5bb, 0xd2b288e2), TOBN(0x4c630fc4, 0xf62dd09c),
+ TOBN(0x8537107a, 0x1ac2703b), TOBN(0xb49258d8, 0x6bc857b5),
+ TOBN(0x57df14de, 0xbcdaccd1), TOBN(0x24ab68d7, 0xc4ae8529),
+ TOBN(0x7ed8b5d4, 0x734e59d0), TOBN(0x5f8740c8, 0xc495cc80),
+ TOBN(0x84aedd5a, 0x291db9b3), TOBN(0x80b360f8, 0x4fb995be),
+ TOBN(0xae915f5d, 0x5fa067d1), TOBN(0x4134b57f, 0x9668960c),
+ TOBN(0xbd3656d6, 0xa48edaac), TOBN(0xdac1e3e4, 0xfc1d7436),
+ TOBN(0x674ff869, 0xd81fbb26), TOBN(0x449ed3ec, 0xb26c33d4),
+ TOBN(0x85138705, 0xd94203e8), TOBN(0xccde538b, 0xbeeb6f4a),
+ TOBN(0x55d5c68d, 0xa61a76fa), TOBN(0x598b441d, 0xca1554dc),
+ TOBN(0xd39923b9, 0x773b279c), TOBN(0x33331d3c, 0x36bf9efc),
+ TOBN(0x2d4c848e, 0x298de399), TOBN(0xcfdb8e77, 0xa1a27f56),
+ TOBN(0x94c855ea, 0x57b8ab70), TOBN(0xdcdb9dae, 0x6f7879ba),
+ TOBN(0x7bdff8c2, 0x019f2a59), TOBN(0xb3ce5bb3, 0xcb4fbc74),
+ TOBN(0xea907f68, 0x8a9173dd), TOBN(0x6cd3d0d3, 0x95a75439),
+ TOBN(0x92ecc4d6, 0xefed021c), TOBN(0x09a9f9b0, 0x6a77339a),
+ TOBN(0x87ca6b15, 0x7188c64a), TOBN(0x10c29968, 0x44899158),
+ TOBN(0x5859a229, 0xed6e82ef), TOBN(0x16f338e3, 0x65ebaf4e),
+ TOBN(0x0cd31387, 0x5ead67ae), TOBN(0x1c73d228, 0x54ef0bb4),
+ TOBN(0x4cb55131, 0x74a5c8c7), TOBN(0x01cd2970, 0x7f69ad6a),
+ TOBN(0xa04d00dd, 0xe966f87e), TOBN(0xd96fe447, 0x0b7b0321),
+ TOBN(0x342ac06e, 0x88fbd381), TOBN(0x02cd4a84, 0x5c35a493),
+ TOBN(0xe8fa89de, 0x54f1bbcd), TOBN(0x341d6367, 0x2575ed4c),
+ TOBN(0xebe357fb, 0xd238202b), TOBN(0x600b4d1a, 0xa984ead9),
+ TOBN(0xc35c9f44, 0x52436ea0), TOBN(0x96fe0a39, 0xa370751b),
+ TOBN(0x4c4f0736, 0x7f636a38), TOBN(0x9f943fb7, 0x0e76d5cb),
+ TOBN(0xb03510ba, 0xa8b68b8b), TOBN(0xc246780a, 0x9ed07a1f),
+ TOBN(0x3c051415, 0x6d549fc2), TOBN(0xc2953f31, 0x607781ca),
+ TOBN(0x955e2c69, 0xd8d95413), TOBN(0xb300fadc, 0x7bd282e3),
+ TOBN(0x81fe7b50, 0x87e9189f), TOBN(0xdb17375c, 0xf42dda27),
+ TOBN(0x22f7d896, 0xcf0a5904), TOBN(0xa0e57c5a, 0xebe348e6),
+ TOBN(0xa61011d3, 0xf40e3c80), TOBN(0xb1189321, 0x8db705c5),
+ TOBN(0x4ed9309e, 0x50fedec3), TOBN(0xdcf14a10, 0x4d6d5c1d),
+ TOBN(0x056c265b, 0x55691342), TOBN(0xe8e08504, 0x91049dc7),
+ TOBN(0x131329f5, 0xc9bae20a), TOBN(0x96c8b3e8, 0xd9dccdb4),
+ TOBN(0x8c5ff838, 0xfb4ee6b4), TOBN(0xfc5a9aeb, 0x41e8ccf0),
+ TOBN(0x7417b764, 0xfae050c6), TOBN(0x0953c3d7, 0x00452080),
+ TOBN(0x21372682, 0x38dfe7e8), TOBN(0xea417e15, 0x2bb79d4b),
+ TOBN(0x59641f1c, 0x76e7cf2d), TOBN(0x271e3059, 0xea0bcfcc),
+ TOBN(0x624c7dfd, 0x7253ecbd), TOBN(0x2f552e25, 0x4fca6186),
+ TOBN(0xcbf84ecd, 0x4d866e9c), TOBN(0x73967709, 0xf68d4610),
+ TOBN(0xa14b1163, 0xc27901b4), TOBN(0xfd9236e0, 0x899b8bf3),
+ TOBN(0x42b091ec, 0xcbc6da0a), TOBN(0xbb1dac6f, 0x5ad1d297),
+ TOBN(0x80e61d53, 0xa91cf76e), TOBN(0x4110a412, 0xd31f1ee7),
+ TOBN(0x2d87c3ba, 0x13efcf77), TOBN(0x1f374bb4, 0xdf450d76),
+ TOBN(0x5e78e2f2, 0x0d188dab), TOBN(0xe3968ed0, 0xf4b885ef),
+ TOBN(0x46c0568e, 0x7314570f), TOBN(0x31616338, 0x01170521),
+ TOBN(0x18e1e7e2, 0x4f0c8afe), TOBN(0x4caa75ff, 0xdeea78da),
+ TOBN(0x82db67f2, 0x7c5d8a51), TOBN(0x36a44d86, 0x6f505370),
+ TOBN(0xd72c5bda, 0x0333974f), TOBN(0x5db516ae, 0x27a70146),
+ TOBN(0x34705281, 0x210ef921), TOBN(0xbff17a8f, 0x0c9c38e5),
+ TOBN(0x78f4814e, 0x12476da1), TOBN(0xc1e16613, 0x33c16980),
+ TOBN(0x9e5b386f, 0x424d4bca), TOBN(0x4c274e87, 0xc85740de),
+ TOBN(0xb6a9b88d, 0x6c2f5226), TOBN(0x14d1b944, 0x550d7ca8),
+ TOBN(0x580c85fc, 0x1fc41709), TOBN(0xc1da368b, 0x54c6d519),
+ TOBN(0x2b0785ce, 0xd5113cf7), TOBN(0x0670f633, 0x5a34708f),
+ TOBN(0x46e23767, 0x15cc3f88), TOBN(0x1b480cfa, 0x50c72c8f),
+ TOBN(0x20288602, 0x4147519a), TOBN(0xd0981eac, 0x26b372f0),
+ TOBN(0xa9d4a7ca, 0xa785ebc8), TOBN(0xd953c50d, 0xdbdf58e9),
+ TOBN(0x9d6361cc, 0xfd590f8f), TOBN(0x72e9626b, 0x44e6c917),
+ TOBN(0x7fd96110, 0x22eb64cf), TOBN(0x863ebb7e, 0x9eb288f3),
+ TOBN(0x6e6ab761, 0x6aca8ee7), TOBN(0x97d10b39, 0xd7b40358),
+ TOBN(0x1687d377, 0x1e5feb0d), TOBN(0xc83e50e4, 0x8265a27a),
+ TOBN(0x8f75a9fe, 0xc954b313), TOBN(0xcc2e8f47, 0x310d1f61),
+ TOBN(0xf5ba81c5, 0x6557d0e0), TOBN(0x25f9680c, 0x3eaf6207),
+ TOBN(0xf95c6609, 0x4354080b), TOBN(0x5225bfa5, 0x7bf2fe1c),
+ TOBN(0xc5c004e2, 0x5c7d98fa), TOBN(0x3561bf1c, 0x019aaf60),
+ TOBN(0x5e6f9f17, 0xba151474), TOBN(0xdec2f934, 0xb04f6eca),
+ TOBN(0x64e368a1, 0x269acb1e), TOBN(0x1332d9e4, 0x0cdda493),
+ TOBN(0x60d6cf69, 0xdf23de05), TOBN(0x66d17da2, 0x009339a0),
+ TOBN(0x9fcac985, 0x0a693923), TOBN(0xbcf057fc, 0xed7c6a6d),
+ TOBN(0xc3c5c8c5, 0xf0b5662c), TOBN(0x25318dd8, 0xdcba4f24),
+ TOBN(0x60e8cb75, 0x082b69ff), TOBN(0x7c23b3ee, 0x1e728c01),
+ TOBN(0x15e10a0a, 0x097e4403), TOBN(0xcb3d0a86, 0x19854665),
+ TOBN(0x88d8e211, 0xd67d4826), TOBN(0xb39af66e, 0x0b9d2839),
+ TOBN(0xa5f94588, 0xbd475ca8), TOBN(0xe06b7966, 0xc077b80b),
+ TOBN(0xfedb1485, 0xda27c26c), TOBN(0xd290d33a, 0xfe0fd5e0),
+ TOBN(0xa40bcc47, 0xf34fb0fa), TOBN(0xb4760cc8, 0x1fb1ab09),
+ TOBN(0x8fca0993, 0xa273bfe3), TOBN(0x13e4fe07, 0xf70b213c),
+ TOBN(0x3bcdb992, 0xfdb05163), TOBN(0x8c484b11, 0x0c2b19b6),
+ TOBN(0x1acb815f, 0xaaf2e3e2), TOBN(0xc6905935, 0xb89ff1b4),
+ TOBN(0xb2ad6f9d, 0x586e74e1), TOBN(0x488883ad, 0x67b80484),
+ TOBN(0x758aa2c7, 0x369c3ddb), TOBN(0x8ab74e69, 0x9f9afd31),
+ TOBN(0x10fc2d28, 0x5e21beb1), TOBN(0x3484518a, 0x318c42f9),
+ TOBN(0x377427dc, 0x53cf40c3), TOBN(0x9de0781a, 0x391bc1d9),
+ TOBN(0x8faee858, 0x693807e1), TOBN(0xa3865327, 0x4e81ccc7),
+ TOBN(0x02c30ff2, 0x6f835b84), TOBN(0xb604437b, 0x0d3d38d4),
+ TOBN(0xb3fc8a98, 0x5ca1823d), TOBN(0xb82f7ec9, 0x03be0324),
+ TOBN(0xee36d761, 0xcf684a33), TOBN(0x5a01df0e, 0x9f29bf7d),
+ TOBN(0x686202f3, 0x1306583d), TOBN(0x05b10da0, 0x437c622e),
+ TOBN(0xbf9aaa0f, 0x076a7bc8), TOBN(0x25e94efb, 0x8f8f4e43),
+ TOBN(0x8a35c9b7, 0xfa3dc26d), TOBN(0xe0e5fb93, 0x96ff03c5),
+ TOBN(0xa77e3843, 0xebc394ce), TOBN(0xcede6595, 0x8361de60),
+ TOBN(0xd27c22f6, 0xa1993545), TOBN(0xab01cc36, 0x24d671ba),
+ TOBN(0x63fa2877, 0xa169c28e), TOBN(0x925ef904, 0x2eb08376),
+ TOBN(0x3b2fa3cf, 0x53aa0b32), TOBN(0xb27beb5b, 0x71c49d7a),
+ TOBN(0xb60e1834, 0xd105e27f), TOBN(0xd6089788, 0x4f68570d),
+ TOBN(0x23094ce0, 0xd6fbc2ac), TOBN(0x738037a1, 0x815ff551),
+ TOBN(0xda73b1bb, 0x6bef119c), TOBN(0xdcf6c430, 0xeef506ba),
+ TOBN(0x00e4fe7b, 0xe3ef104a), TOBN(0xebdd9a2c, 0x0a065628),
+ TOBN(0x853a81c3, 0x8792043e), TOBN(0x22ad6ece, 0xb3b59108),
+ TOBN(0x9fb813c0, 0x39cd297d), TOBN(0x8ec7e16e, 0x05bda5d9),
+ TOBN(0x2834797c, 0x0d104b96), TOBN(0xcc11a2e7, 0x7c511510),
+ TOBN(0x96ca5a53, 0x96ee6380), TOBN(0x054c8655, 0xcea38742),
+ TOBN(0xb5946852, 0xd54dfa7d), TOBN(0x97c422e7, 0x1f4ab207),
+ TOBN(0xbf907509, 0x0c22b540), TOBN(0x2cde42aa, 0xb7c267d4),
+ TOBN(0xba18f9ed, 0x5ab0d693), TOBN(0x3ba62aa6, 0x6e4660d9),
+ TOBN(0xb24bf97b, 0xab9ea96a), TOBN(0x5d039642, 0xe3b60e32),
+ TOBN(0x4e6a4506, 0x7c4d9bd5), TOBN(0x666c5b9e, 0x7ed4a6a4),
+ TOBN(0xfa3fdcd9, 0x8edbd7cc), TOBN(0x4660bb87, 0xc6ccd753),
+ TOBN(0x9ae90820, 0x21e6b64f), TOBN(0x8a56a713, 0xb36bfb3f),
+ TOBN(0xabfce096, 0x5726d47f), TOBN(0x9eed01b2, 0x0b1a9a7f),
+ TOBN(0x30e9cad4, 0x4eb74a37), TOBN(0x7b2524cc, 0x53e9666d),
+ TOBN(0x6a29683b, 0x8f4b002f), TOBN(0xc2200d7a, 0x41f4fc20),
+ TOBN(0xcf3af47a, 0x3a338acc), TOBN(0x6539a4fb, 0xe7128975),
+ TOBN(0xcec31c14, 0xc33c7fcf), TOBN(0x7eb6799b, 0xc7be322b),
+ TOBN(0x119ef4e9, 0x6646f623), TOBN(0x7b7a26a5, 0x54d7299b),
+ TOBN(0xcb37f08d, 0x403f46f2), TOBN(0x94b8fc43, 0x1a0ec0c7),
+ TOBN(0xbb8514e3, 0xc332142f), TOBN(0xf3ed2c33, 0xe80d2a7a),
+ TOBN(0x8d2080af, 0xb639126c), TOBN(0xf7b6be60, 0xe3553ade),
+ TOBN(0x3950aa9f, 0x1c7e2b09), TOBN(0x847ff958, 0x6410f02b),
+ TOBN(0x877b7cf5, 0x678a31b0), TOBN(0xd50301ae, 0x3998b620),
+ TOBN(0x734257c5, 0xc00fb396), TOBN(0xf9fb18a0, 0x04e672a6),
+ TOBN(0xff8bd8eb, 0xe8758851), TOBN(0x1e64e4c6, 0x5d99ba44),
+ TOBN(0x4b8eaedf, 0x7dfd93b7), TOBN(0xba2f2a98, 0x04e76b8c),
+ TOBN(0x7d790cba, 0xe8053433), TOBN(0xc8e725a0, 0x3d2c9585),
+ TOBN(0x58c5c476, 0xcdd8f5ed), TOBN(0xd106b952, 0xefa9fe1d),
+ TOBN(0x3c5c775b, 0x0eff13a9), TOBN(0x242442ba, 0xe057b930),
+ TOBN(0xe9f458d4, 0xc9b70cbd), TOBN(0x69b71448, 0xa3cdb89a),
+ TOBN(0x41ee46f6, 0x0e2ed742), TOBN(0x573f1045, 0x40067493),
+ TOBN(0xb1e154ff, 0x9d54c304), TOBN(0x2ad0436a, 0x8d3a7502),
+ TOBN(0xee4aaa2d, 0x431a8121), TOBN(0xcd38b3ab, 0x886f11ed),
+ TOBN(0x57d49ea6, 0x034a0eb7), TOBN(0xd2b773bd, 0xf7e85e58),
+ TOBN(0x4a559ac4, 0x9b5c1f14), TOBN(0xc444be1a, 0x3e54df2b),
+ TOBN(0x13aad704, 0xeda41891), TOBN(0xcd927bec, 0x5eb5c788),
+ TOBN(0xeb3c8516, 0xe48c8a34), TOBN(0x1b7ac812, 0x4b546669),
+ TOBN(0x1815f896, 0x594df8ec), TOBN(0x87c6a79c, 0x79227865),
+ TOBN(0xae02a2f0, 0x9b56ddbd), TOBN(0x1339b5ac, 0x8a2f1cf3),
+ TOBN(0xf2b569c7, 0x839dff0d), TOBN(0xb0b9e864, 0xfee9a43d),
+ TOBN(0x4ff8ca41, 0x77bb064e), TOBN(0x145a2812, 0xfd249f63),
+ TOBN(0x3ab7beac, 0xf86f689a), TOBN(0x9bafec27, 0x01d35f5e),
+ TOBN(0x28054c65, 0x4265aa91), TOBN(0xa4b18304, 0x035efe42),
+ TOBN(0x6887b0e6, 0x9639dec7), TOBN(0xf4b8f6ad, 0x3d52aea5),
+ TOBN(0xfb9293cc, 0x971a8a13), TOBN(0x3f159e5d, 0x4c934d07),
+ TOBN(0x2c50e9b1, 0x09acbc29), TOBN(0x08eb65e6, 0x7154d129),
+ TOBN(0x4feff589, 0x30b75c3e), TOBN(0x0bb82fe2, 0x94491c93),
+ TOBN(0xd8ac377a, 0x89af62bb), TOBN(0xd7b51490, 0x9685e49f),
+ TOBN(0xabca9a7b, 0x04497f19), TOBN(0x1b35ed0a, 0x1a7ad13f),
+ TOBN(0x6b601e21, 0x3ec86ed6), TOBN(0xda91fcb9, 0xce0c76f1),
+ TOBN(0x9e28507b, 0xd7ab27e1), TOBN(0x7c19a555, 0x63945b7b),
+ TOBN(0x6b43f0a1, 0xaafc9827), TOBN(0x443b4fbd, 0x3aa55b91),
+ TOBN(0x962b2e65, 0x6962c88f), TOBN(0x139da8d4, 0xce0db0ca),
+ TOBN(0xb93f05dd, 0x1b8d6c4f), TOBN(0x779cdff7, 0x180b9824),
+ TOBN(0xbba23fdd, 0xae57c7b7), TOBN(0x345342f2, 0x1b932522),
+ TOBN(0xfd9c80fe, 0x556d4aa3), TOBN(0xa03907ba, 0x6525bb61),
+ TOBN(0x38b010e1, 0xff218933), TOBN(0xc066b654, 0xaa52117b),
+ TOBN(0x8e141920, 0x94f2e6ea), TOBN(0x66a27dca, 0x0d32f2b2),
+ TOBN(0x69c7f993, 0x048b3717), TOBN(0xbf5a989a, 0xb178ae1c),
+ TOBN(0x49fa9058, 0x564f1d6b), TOBN(0x27ec6e15, 0xd31fde4e),
+ TOBN(0x4cce0373, 0x7276e7fc), TOBN(0x64086d79, 0x89d6bf02),
+ TOBN(0x5a72f046, 0x4ccdd979), TOBN(0x909c3566, 0x47775631),
+ TOBN(0x1c07bc6b, 0x75dd7125), TOBN(0xb4c6bc97, 0x87a0428d),
+ TOBN(0x507ece52, 0xfdeb6b9d), TOBN(0xfca56512, 0xb2c95432),
+ TOBN(0x15d97181, 0xd0e8bd06), TOBN(0x384dd317, 0xc6bb46ea),
+ TOBN(0x5441ea20, 0x3952b624), TOBN(0xbcf70dee, 0x4e7dc2fb),
+ TOBN(0x372b016e, 0x6628e8c3), TOBN(0x07a0d667, 0xb60a7522),
+ TOBN(0xcf05751b, 0x0a344ee2), TOBN(0x0ec09a48, 0x118bdeec),
+ TOBN(0x6e4b3d4e, 0xd83dce46), TOBN(0x43a6316d, 0x99d2fc6e),
+ TOBN(0xa99d8989, 0x56cf044c), TOBN(0x7c7f4454, 0xae3e5fb7),
+ TOBN(0xb2e6b121, 0xfbabbe92), TOBN(0x281850fb, 0xe1330076),
+ TOBN(0x093581ec, 0x97890015), TOBN(0x69b1dded, 0x75ff77f5),
+ TOBN(0x7cf0b18f, 0xab105105), TOBN(0x953ced31, 0xa89ccfef),
+ TOBN(0x3151f85f, 0xeb914009), TOBN(0x3c9f1b87, 0x88ed48ad),
+ TOBN(0xc9aba1a1, 0x4a7eadcb), TOBN(0x928e7501, 0x522e71cf),
+ TOBN(0xeaede727, 0x3a2e4f83), TOBN(0x467e10d1, 0x1ce3bbd3),
+ TOBN(0xf3442ac3, 0xb955dcf0), TOBN(0xba96307d, 0xd3d5e527),
+ TOBN(0xf763a10e, 0xfd77f474), TOBN(0x5d744bd0, 0x6a6e1ff0),
+ TOBN(0xd287282a, 0xa777899e), TOBN(0xe20eda8f, 0xd03f3cde),
+ TOBN(0x6a7e75bb, 0x50b07d31), TOBN(0x0b7e2a94, 0x6f379de4),
+ TOBN(0x31cb64ad, 0x19f593cf), TOBN(0x7b1a9e4f, 0x1e76ef1d),
+ TOBN(0xe18c9c9d, 0xb62d609c), TOBN(0x439bad6d, 0xe779a650),
+ TOBN(0x219d9066, 0xe032f144), TOBN(0x1db632b8, 0xe8b2ec6a),
+ TOBN(0xff0d0fd4, 0xfda12f78), TOBN(0x56fb4c2d, 0x2a25d265),
+ TOBN(0x5f4e2ee1, 0x255a03f1), TOBN(0x61cd6af2, 0xe96af176),
+ TOBN(0xe0317ba8, 0xd068bc97), TOBN(0x927d6bab, 0x264b988e),
+ TOBN(0xa18f07e0, 0xe90fb21e), TOBN(0x00fd2b80, 0xbba7fca1),
+ TOBN(0x20387f27, 0x95cd67b5), TOBN(0x5b89a4e7, 0xd39707f7),
+ TOBN(0x8f83ad3f, 0x894407ce), TOBN(0xa0025b94, 0x6c226132),
+ TOBN(0xc79563c7, 0xf906c13b), TOBN(0x5f548f31, 0x4e7bb025),
+ TOBN(0x2b4c6b8f, 0xeac6d113), TOBN(0xa67e3f9c, 0x0e813c76),
+ TOBN(0x3982717c, 0x3fe1f4b9), TOBN(0x58865819, 0x26d8050e),
+ TOBN(0x99f3640c, 0xf7f06f20), TOBN(0xdc610216, 0x2a66ebc2),
+ TOBN(0x52f2c175, 0x767a1e08), TOBN(0x05660e1a, 0x5999871b),
+ TOBN(0x6b0f1762, 0x6d3c4693), TOBN(0xf0e7d627, 0x37ed7bea),
+ TOBN(0xc51758c7, 0xb75b226d), TOBN(0x40a88628, 0x1f91613b),
+ TOBN(0x889dbaa7, 0xbbb38ce0), TOBN(0xe0404b65, 0xbddcad81),
+ TOBN(0xfebccd3a, 0x8bc9671f), TOBN(0xfbf9a357, 0xee1f5375),
+ TOBN(0x5dc169b0, 0x28f33398), TOBN(0xb07ec11d, 0x72e90f65),
+ TOBN(0xae7f3b4a, 0xfaab1eb1), TOBN(0xd970195e, 0x5f17538a),
+ TOBN(0x52b05cbe, 0x0181e640), TOBN(0xf5debd62, 0x2643313d),
+ TOBN(0x76148154, 0x5df31f82), TOBN(0x23e03b33, 0x3a9e13c5),
+ TOBN(0xff758949, 0x4fde0c1f), TOBN(0xbf8a1abe, 0xe5b6ec20),
+ TOBN(0x702278fb, 0x87e1db6c), TOBN(0xc447ad7a, 0x35ed658f),
+ TOBN(0x48d4aa38, 0x03d0ccf2), TOBN(0x80acb338, 0x819a7c03),
+ TOBN(0x9bc7c89e, 0x6e17cecc), TOBN(0x46736b8b, 0x03be1d82),
+ TOBN(0xd65d7b60, 0xc0432f96), TOBN(0xddebe7a3, 0xdeb5442f),
+ TOBN(0x79a25307, 0x7dff69a2), TOBN(0x37a56d94, 0x02cf3122),
+ TOBN(0x8bab8aed, 0xf2350d0a), TOBN(0x13c3f276, 0x037b0d9a),
+ TOBN(0xc664957c, 0x44c65cae), TOBN(0x88b44089, 0xc2e71a88),
+ TOBN(0xdb88e5a3, 0x5cb02664), TOBN(0x5d4c0bf1, 0x8686c72e),
+ TOBN(0xea3d9b62, 0xa682d53e), TOBN(0x9b605ef4, 0x0b2ad431),
+ TOBN(0x71bac202, 0xc69645d0), TOBN(0xa115f03a, 0x6a1b66e7),
+ TOBN(0xfe2c563a, 0x158f4dc4), TOBN(0xf715b3a0, 0x4d12a78c),
+ TOBN(0x8f7f0a48, 0xd413213a), TOBN(0x2035806d, 0xc04becdb),
+ TOBN(0xecd34a99, 0x5d8587f5), TOBN(0x4d8c3079, 0x9f6d3a71),
+ TOBN(0x1b2a2a67, 0x8d95a8f6), TOBN(0xc58c9d7d, 0xf2110d0d),
+ TOBN(0xdeee81d5, 0xcf8fba3f), TOBN(0xa42be3c0, 0x0c7cdf68),
+ TOBN(0x2126f742, 0xd43b5eaa), TOBN(0x054a0766, 0xdfa59b85),
+ TOBN(0x9d0d5e36, 0x126bfd45), TOBN(0xa1f8fbd7, 0x384f8a8f),
+ TOBN(0x317680f5, 0xd563fccc), TOBN(0x48ca5055, 0xf280a928),
+ TOBN(0xe00b81b2, 0x27b578cf), TOBN(0x10aad918, 0x2994a514),
+ TOBN(0xd9e07b62, 0xb7bdc953), TOBN(0x9f0f6ff2, 0x5bc086dd),
+ TOBN(0x09d1ccff, 0x655eee77), TOBN(0x45475f79, 0x5bef7df1),
+ TOBN(0x3faa28fa, 0x86f702cc), TOBN(0x92e60905, 0x0f021f07),
+ TOBN(0xe9e62968, 0x7f8fa8c6), TOBN(0xbd71419a, 0xf036ea2c),
+ TOBN(0x171ee1cc, 0x6028da9a), TOBN(0x5352fe1a, 0xc251f573),
+ TOBN(0xf8ff236e, 0x3fa997f4), TOBN(0xd831b6c9, 0xa5749d5f),
+ TOBN(0x7c872e1d, 0xe350e2c2), TOBN(0xc56240d9, 0x1e0ce403),
+ TOBN(0xf9deb077, 0x6974f5cb), TOBN(0x7d50ba87, 0x961c3728),
+ TOBN(0xd6f89426, 0x5a3a2518), TOBN(0xcf817799, 0xc6303d43),
+ TOBN(0x510a0471, 0x619e5696), TOBN(0xab049ff6, 0x3a5e307b),
+ TOBN(0xe4cdf9b0, 0xfeb13ec7), TOBN(0xd5e97117, 0x9d8ff90c),
+ TOBN(0xf6f64d06, 0x9afa96af), TOBN(0x00d0bf5e, 0x9d2012a2),
+ TOBN(0xe63f301f, 0x358bcdc0), TOBN(0x07689e99, 0x0a9d47f8),
+ TOBN(0x1f689e2f, 0x4f43d43a), TOBN(0x4d542a16, 0x90920904),
+ TOBN(0xaea293d5, 0x9ca0a707), TOBN(0xd061fe45, 0x8ac68065),
+ TOBN(0x1033bf1b, 0x0090008c), TOBN(0x29749558, 0xc08a6db6),
+ TOBN(0x74b5fc59, 0xc1d5d034), TOBN(0xf712e9f6, 0x67e215e0),
+ TOBN(0xfd520cbd, 0x860200e6), TOBN(0x0229acb4, 0x3ea22588),
+ TOBN(0x9cd1e14c, 0xfff0c82e), TOBN(0x87684b62, 0x59c69e73),
+ TOBN(0xda85e61c, 0x96ccb989), TOBN(0x2d5dbb02, 0xa3d06493),
+ TOBN(0xf22ad33a, 0xe86b173c), TOBN(0xe8e41ea5, 0xa79ff0e3),
+ TOBN(0x01d2d725, 0xdd0d0c10), TOBN(0x31f39088, 0x032d28f9),
+ TOBN(0x7b3f71e1, 0x7829839e), TOBN(0x0cf691b4, 0x4502ae58),
+ TOBN(0xef658dbd, 0xbefc6115), TOBN(0xa5cd6ee5, 0xb3ab5314),
+ TOBN(0x206c8d7b, 0x5f1d2347), TOBN(0x794645ba, 0x4cc2253a),
+ TOBN(0xd517d8ff, 0x58389e08), TOBN(0x4fa20dee, 0x9f847288),
+ TOBN(0xeba072d8, 0xd797770a), TOBN(0x7360c91d, 0xbf429e26),
+ TOBN(0x7200a3b3, 0x80af8279), TOBN(0x6a1c9150, 0x82dadce3),
+ TOBN(0x0ee6d3a7, 0xc35d8794), TOBN(0x042e6558, 0x0356bae5),
+ TOBN(0x9f59698d, 0x643322fd), TOBN(0x9379ae15, 0x50a61967),
+ TOBN(0x64b9ae62, 0xfcc9981e), TOBN(0xaed3d631, 0x6d2934c6),
+ TOBN(0x2454b302, 0x5e4e65eb), TOBN(0xab09f647, 0xf9950428)},
+ {TOBN(0xb2083a12, 0x22248acc), TOBN(0x1f6ec0ef, 0x3264e366),
+ TOBN(0x5659b704, 0x5afdee28), TOBN(0x7a823a40, 0xe6430bb5),
+ TOBN(0x24592a04, 0xe1900a79), TOBN(0xcde09d4a, 0xc9ee6576),
+ TOBN(0x52b6463f, 0x4b5ea54a), TOBN(0x1efe9ed3, 0xd3ca65a7),
+ TOBN(0xe27a6dbe, 0x305406dd), TOBN(0x8eb7dc7f, 0xdd5d1957),
+ TOBN(0xf54a6876, 0x387d4d8f), TOBN(0x9c479409, 0xc7762de4),
+ TOBN(0xbe4d5b5d, 0x99b30778), TOBN(0x25380c56, 0x6e793682),
+ TOBN(0x602d37f3, 0xdac740e3), TOBN(0x140deabe, 0x1566e4ae),
+ TOBN(0x4481d067, 0xafd32acf), TOBN(0xd8f0fcca, 0xe1f71ccf),
+ TOBN(0xd208dd0c, 0xb596f2da), TOBN(0xd049d730, 0x9aad93f9),
+ TOBN(0xc79f263d, 0x42ab580e), TOBN(0x09411bb1, 0x23f707b4),
+ TOBN(0x8cfde1ff, 0x835e0eda), TOBN(0x72707490, 0x90f03402),
+ TOBN(0xeaee6126, 0xc49a861e), TOBN(0x024f3b65, 0xe14f0d06),
+ TOBN(0x51a3f1e8, 0xc69bfc17), TOBN(0xc3c3a8e9, 0xa7686381),
+ TOBN(0x3400752c, 0xb103d4c8), TOBN(0x02bc4613, 0x9218b36b),
+ TOBN(0xc67f75eb, 0x7651504a), TOBN(0xd6848b56, 0xd02aebfa),
+ TOBN(0xbd9802e6, 0xc30fa92b), TOBN(0x5a70d96d, 0x9a552784),
+ TOBN(0x9085c4ea, 0x3f83169b), TOBN(0xfa9423bb, 0x06908228),
+ TOBN(0x2ffebe12, 0xfe97a5b9), TOBN(0x85da6049, 0x71b99118),
+ TOBN(0x9cbc2f7f, 0x63178846), TOBN(0xfd96bc70, 0x9153218e),
+ TOBN(0x958381db, 0x1782269b), TOBN(0xae34bf79, 0x2597e550),
+ TOBN(0xbb5c6064, 0x5f385153), TOBN(0x6f0e96af, 0xe3088048),
+ TOBN(0xbf6a0215, 0x77884456), TOBN(0xb3b5688c, 0x69310ea7),
+ TOBN(0x17c94295, 0x04fad2de), TOBN(0xe020f0e5, 0x17896d4d),
+ TOBN(0x730ba0ab, 0x0976505f), TOBN(0x567f6813, 0x095e2ec5),
+ TOBN(0x47062010, 0x6331ab71), TOBN(0x72cfa977, 0x41d22b9f),
+ TOBN(0x33e55ead, 0x8a2373da), TOBN(0xa8d0d5f4, 0x7ba45a68),
+ TOBN(0xba1d8f9c, 0x03029d15), TOBN(0x8f34f1cc, 0xfc55b9f3),
+ TOBN(0xcca4428d, 0xbbe5a1a9), TOBN(0x8187fd5f, 0x3126bd67),
+ TOBN(0x0036973a, 0x48105826), TOBN(0xa39b6663, 0xb8bd61a0),
+ TOBN(0x6d42deef, 0x2d65a808), TOBN(0x4969044f, 0x94636b19),
+ TOBN(0xf611ee47, 0xdd5d564c), TOBN(0x7b2f3a49, 0xd2873077),
+ TOBN(0x94157d45, 0x300eb294), TOBN(0x2b2a656e, 0x169c1494),
+ TOBN(0xc000dd76, 0xd3a47aa9), TOBN(0xa2864e4f, 0xa6243ea4),
+ TOBN(0x82716c47, 0xdb89842e), TOBN(0x12dfd7d7, 0x61479fb7),
+ TOBN(0x3b9a2c56, 0xe0b2f6dc), TOBN(0x46be862a, 0xd7f85d67),
+ TOBN(0x03b0d8dd, 0x0f82b214), TOBN(0x460c34f9, 0xf103cbc6),
+ TOBN(0xf32e5c03, 0x18d79e19), TOBN(0x8b8888ba, 0xa84117f8),
+ TOBN(0x8f3c37dc, 0xc0722677), TOBN(0x10d21be9, 0x1c1c0f27),
+ TOBN(0xd47c8468, 0xe0f7a0c6), TOBN(0x9bf02213, 0xadecc0e0),
+ TOBN(0x0baa7d12, 0x42b48b99), TOBN(0x1bcb665d, 0x48424096),
+ TOBN(0x8b847cd6, 0xebfb5cfb), TOBN(0x87c2ae56, 0x9ad4d10d),
+ TOBN(0xf1cbb122, 0x0de36726), TOBN(0xe7043c68, 0x3fdfbd21),
+ TOBN(0x4bd0826a, 0x4e79d460), TOBN(0x11f5e598, 0x4bd1a2cb),
+ TOBN(0x97554160, 0xb7fe7b6e), TOBN(0x7d16189a, 0x400a3fb2),
+ TOBN(0xd73e9bea, 0xe328ca1e), TOBN(0x0dd04b97, 0xe793d8cc),
+ TOBN(0xa9c83c9b, 0x506db8cc), TOBN(0x5cd47aae, 0xcf38814c),
+ TOBN(0x26fc430d, 0xb64b45e6), TOBN(0x079b5499, 0xd818ea84),
+ TOBN(0xebb01102, 0xc1c24a3b), TOBN(0xca24e568, 0x1c161c1a),
+ TOBN(0x103eea69, 0x36f00a4a), TOBN(0x9ad76ee8, 0x76176c7b),
+ TOBN(0x97451fc2, 0x538e0ff7), TOBN(0x94f89809, 0x6604b3b0),
+ TOBN(0x6311436e, 0x3249cfd7), TOBN(0x27b4a7bd, 0x41224f69),
+ TOBN(0x03b5d21a, 0xe0ac2941), TOBN(0x279b0254, 0xc2d31937),
+ TOBN(0x3307c052, 0xcac992d0), TOBN(0x6aa7cb92, 0xefa8b1f3),
+ TOBN(0x5a182580, 0x0d37c7a5), TOBN(0x13380c37, 0x342d5422),
+ TOBN(0x92ac2d66, 0xd5d2ef92), TOBN(0x035a70c9, 0x030c63c6),
+ TOBN(0xc16025dd, 0x4ce4f152), TOBN(0x1f419a71, 0xf9df7c06),
+ TOBN(0x6d5b2214, 0x91e4bb14), TOBN(0xfc43c6cc, 0x839fb4ce),
+ TOBN(0x49f06591, 0x925d6b2d), TOBN(0x4b37d9d3, 0x62186598),
+ TOBN(0x8c54a971, 0xd01b1629), TOBN(0xe1a9c29f, 0x51d50e05),
+ TOBN(0x5109b785, 0x71ba1861), TOBN(0x48b22d5c, 0xd0c8f93d),
+ TOBN(0xe8fa84a7, 0x8633bb93), TOBN(0x53fba6ba, 0x5aebbd08),
+ TOBN(0x7ff27df3, 0xe5eea7d8), TOBN(0x521c8796, 0x68ca7158),
+ TOBN(0xb9d5133b, 0xce6f1a05), TOBN(0x2d50cd53, 0xfd0ebee4),
+ TOBN(0xc82115d6, 0xc5a3ef16), TOBN(0x993eff9d, 0xba079221),
+ TOBN(0xe4da2c5e, 0x4b5da81c), TOBN(0x9a89dbdb, 0x8033fd85),
+ TOBN(0x60819ebf, 0x2b892891), TOBN(0x53902b21, 0x5d14a4d5),
+ TOBN(0x6ac35051, 0xd7fda421), TOBN(0xcc6ab885, 0x61c83284),
+ TOBN(0x14eba133, 0xf74cff17), TOBN(0x240aaa03, 0xecb813f2),
+ TOBN(0xcfbb6540, 0x6f665bee), TOBN(0x084b1fe4, 0xa425ad73),
+ TOBN(0x009d5d16, 0xd081f6a6), TOBN(0x35304fe8, 0xeef82c90),
+ TOBN(0xf20346d5, 0xaa9eaa22), TOBN(0x0ada9f07, 0xac1c91e3),
+ TOBN(0xa6e21678, 0x968a6144), TOBN(0x54c1f77c, 0x07b31a1e),
+ TOBN(0xd6bb787e, 0x5781fbe1), TOBN(0x61bd2ee0, 0xe31f1c4a),
+ TOBN(0xf25aa1e9, 0x781105fc), TOBN(0x9cf2971f, 0x7b2f8e80),
+ TOBN(0x26d15412, 0xcdff919b), TOBN(0x01db4ebe, 0x34bc896e),
+ TOBN(0x7d9b3e23, 0xb40df1cf), TOBN(0x59337373, 0x94e971b4),
+ TOBN(0xbf57bd14, 0x669cf921), TOBN(0x865daedf, 0x0c1a1064),
+ TOBN(0x3eb70bd3, 0x83279125), TOBN(0xbc3d5b9f, 0x34ecdaab),
+ TOBN(0x91e3ed7e, 0x5f755caf), TOBN(0x49699f54, 0xd41e6f02),
+ TOBN(0x185770e1, 0xd4a7a15b), TOBN(0x08f3587a, 0xeaac87e7),
+ TOBN(0x352018db, 0x473133ea), TOBN(0x674ce719, 0x04fd30fc),
+ TOBN(0x7b8d9835, 0x088b3e0e), TOBN(0x7a0356a9, 0x5d0d47a1),
+ TOBN(0x9d9e7659, 0x6474a3c4), TOBN(0x61ea48a7, 0xff66966c),
+ TOBN(0x30417758, 0x0f3e4834), TOBN(0xfdbb21c2, 0x17a9afcb),
+ TOBN(0x756fa17f, 0x2f9a67b3), TOBN(0x2a6b2421, 0xa245c1a8),
+ TOBN(0x64be2794, 0x4af02291), TOBN(0xade465c6, 0x2a5804fe),
+ TOBN(0x8dffbd39, 0xa6f08fd7), TOBN(0xc4efa84c, 0xaa14403b),
+ TOBN(0xa1b91b2a, 0x442b0f5c), TOBN(0xb748e317, 0xcf997736),
+ TOBN(0x8d1b62bf, 0xcee90e16), TOBN(0x907ae271, 0x0b2078c0),
+ TOBN(0xdf31534b, 0x0c9bcddd), TOBN(0x043fb054, 0x39adce83),
+ TOBN(0x99031043, 0xd826846a), TOBN(0x61a9c0d6, 0xb144f393),
+ TOBN(0xdab48046, 0x47718427), TOBN(0xdf17ff9b, 0x6e830f8b),
+ TOBN(0x408d7ee8, 0xe49a1347), TOBN(0x6ac71e23, 0x91c1d4ae),
+ TOBN(0xc8cbb9fd, 0x1defd73c), TOBN(0x19840657, 0xbbbbfec5),
+ TOBN(0x39db1cb5, 0x9e7ef8ea), TOBN(0x78aa8296, 0x64105f30),
+ TOBN(0xa3d9b7f0, 0xa3738c29), TOBN(0x0a2f235a, 0xbc3250a3),
+ TOBN(0x55e506f6, 0x445e4caf), TOBN(0x0974f73d, 0x33475f7a),
+ TOBN(0xd37dbba3, 0x5ba2f5a8), TOBN(0x542c6e63, 0x6af40066),
+ TOBN(0x26d99b53, 0xc5d73e2c), TOBN(0x06060d7d, 0x6c3ca33e),
+ TOBN(0xcdbef1c2, 0x065fef4a), TOBN(0x77e60f7d, 0xfd5b92e3),
+ TOBN(0xd7c549f0, 0x26708350), TOBN(0x201b3ad0, 0x34f121bf),
+ TOBN(0x5fcac2a1, 0x0334fc14), TOBN(0x8a9a9e09, 0x344552f6),
+ TOBN(0x7dd8a1d3, 0x97653082), TOBN(0x5fc0738f, 0x79d4f289),
+ TOBN(0x787d244d, 0x17d2d8c3), TOBN(0xeffc6345, 0x70830684),
+ TOBN(0x5ddb96dd, 0xe4f73ae5), TOBN(0x8efb14b1, 0x172549a5),
+ TOBN(0x6eb73eee, 0x2245ae7a), TOBN(0xbca4061e, 0xea11f13e),
+ TOBN(0xb577421d, 0x30b01f5d), TOBN(0xaa688b24, 0x782e152c),
+ TOBN(0x67608e71, 0xbd3502ba), TOBN(0x4ef41f24, 0xb4de75a0),
+ TOBN(0xb08dde5e, 0xfd6125e5), TOBN(0xde484825, 0xa409543f),
+ TOBN(0x1f198d98, 0x65cc2295), TOBN(0x428a3771, 0x6e0edfa2),
+ TOBN(0x4f9697a2, 0xadf35fc7), TOBN(0x01a43c79, 0xf7cac3c7),
+ TOBN(0xb05d7059, 0x0fd3659a), TOBN(0x8927f30c, 0xbb7f2d9a),
+ TOBN(0x4023d1ac, 0x8cf984d3), TOBN(0x32125ed3, 0x02897a45),
+ TOBN(0xfb572dad, 0x3d414205), TOBN(0x73000ef2, 0xe3fa82a9),
+ TOBN(0x4c0868e9, 0xf10a5581), TOBN(0x5b61fc67, 0x6b0b3ca5),
+ TOBN(0xc1258d5b, 0x7cae440c), TOBN(0x21c08b41, 0x402b7531),
+ TOBN(0xf61a8955, 0xde932321), TOBN(0x3568faf8, 0x2d1408af),
+ TOBN(0x71b15e99, 0x9ecf965b), TOBN(0xf14ed248, 0xe917276f),
+ TOBN(0xc6f4caa1, 0x820cf9e2), TOBN(0x681b20b2, 0x18d83c7e),
+ TOBN(0x6cde738d, 0xc6c01120), TOBN(0x71db0813, 0xae70e0db),
+ TOBN(0x95fc0644, 0x74afe18c), TOBN(0x34619053, 0x129e2be7),
+ TOBN(0x80615cea, 0xdb2a3b15), TOBN(0x0a49a19e, 0xdb4c7073),
+ TOBN(0x0e1b84c8, 0x8fd2d367), TOBN(0xd74bf462, 0x033fb8aa),
+ TOBN(0x889f6d65, 0x533ef217), TOBN(0x7158c7e4, 0xc3ca2e87),
+ TOBN(0xfb670dfb, 0xdc2b4167), TOBN(0x75910a01, 0x844c257f),
+ TOBN(0xf336bf07, 0xcf88577d), TOBN(0x22245250, 0xe45e2ace),
+ TOBN(0x2ed92e8d, 0x7ca23d85), TOBN(0x29f8be4c, 0x2b812f58),
+ TOBN(0xdd9ebaa7, 0x076fe12b), TOBN(0x3f2400cb, 0xae1537f9),
+ TOBN(0x1aa93528, 0x17bdfb46), TOBN(0xc0f98430, 0x67883b41),
+ TOBN(0x5590ede1, 0x0170911d), TOBN(0x7562f5bb, 0x34d4b17f),
+ TOBN(0xe1fa1df2, 0x1826b8d2), TOBN(0xb40b796a, 0x6bd80d59),
+ TOBN(0xd65bf197, 0x3467ba92), TOBN(0x8c9b46db, 0xf70954b0),
+ TOBN(0x97c8a0f3, 0x0e78f15d), TOBN(0xa8f3a69a, 0x85a4c961),
+ TOBN(0x4242660f, 0x61e4ce9b), TOBN(0xbf06aab3, 0x6ea6790c),
+ TOBN(0xc6706f8e, 0xec986416), TOBN(0x9e56dec1, 0x9a9fc225),
+ TOBN(0x527c46f4, 0x9a9898d9), TOBN(0xd799e77b, 0x5633cdef),
+ TOBN(0x24eacc16, 0x7d9e4297), TOBN(0xabb61cea, 0x6b1cb734),
+ TOBN(0xbee2e8a7, 0xf778443c), TOBN(0x3bb42bf1, 0x29de2fe6),
+ TOBN(0xcbed86a1, 0x3003bb6f), TOBN(0xd3918e6c, 0xd781cdf6),
+ TOBN(0x4bee3271, 0x9a5103f1), TOBN(0x5243efc6, 0xf50eac06),
+ TOBN(0xb8e122cb, 0x6adcc119), TOBN(0x1b7faa84, 0xc0b80a08),
+ TOBN(0x32c3d1bd, 0x6dfcd08c), TOBN(0x129dec4e, 0x0be427de),
+ TOBN(0x98ab679c, 0x1d263c83), TOBN(0xafc83cb7, 0xcef64eff),
+ TOBN(0x85eb6088, 0x2fa6be76), TOBN(0x892585fb, 0x1328cbfe),
+ TOBN(0xc154d3ed, 0xcf618dda), TOBN(0xc44f601b, 0x3abaf26e),
+ TOBN(0x7bf57d0b, 0x2be1fdfd), TOBN(0xa833bd2d, 0x21137fee),
+ TOBN(0x9353af36, 0x2db591a8), TOBN(0xc76f26dc, 0x5562a056),
+ TOBN(0x1d87e47d, 0x3fdf5a51), TOBN(0x7afb5f93, 0x55c9cab0),
+ TOBN(0x91bbf58f, 0x89e0586e), TOBN(0x7c72c018, 0x0d843709),
+ TOBN(0xa9a5aafb, 0x99b5c3dc), TOBN(0xa48a0f1d, 0x3844aeb0),
+ TOBN(0x7178b7dd, 0xb667e482), TOBN(0x453985e9, 0x6e23a59a),
+ TOBN(0x4a54c860, 0x01b25dd8), TOBN(0x0dd37f48, 0xfb897c8a),
+ TOBN(0x5f8aa610, 0x0ea90cd9), TOBN(0xc8892c68, 0x16d5830d),
+ TOBN(0xeb4befc0, 0xef514ca5), TOBN(0x478eb679, 0xe72c9ee6),
+ TOBN(0x9bca20da, 0xdbc40d5f), TOBN(0xf015de21, 0xdde4f64a),
+ TOBN(0xaa6a4de0, 0xeaf4b8a5), TOBN(0x68cfd9ca, 0x4bc60e32),
+ TOBN(0x668a4b01, 0x7fd15e70), TOBN(0xd9f0694a, 0xf27dc09d),
+ TOBN(0xf6c3cad5, 0xba708bcd), TOBN(0x5cd2ba69, 0x5bb95c2a),
+ TOBN(0xaa28c1d3, 0x33c0a58f), TOBN(0x23e274e3, 0xabc77870),
+ TOBN(0x44c3692d, 0xdfd20a4a), TOBN(0x091c5fd3, 0x81a66653),
+ TOBN(0x6c0bb691, 0x09a0757d), TOBN(0x9072e8b9, 0x667343ea),
+ TOBN(0x31d40eb0, 0x80848bec), TOBN(0x95bd480a, 0x79fd36cc),
+ TOBN(0x01a77c61, 0x65ed43f5), TOBN(0xafccd127, 0x2e0d40bf),
+ TOBN(0xeccfc82d, 0x1cc1884b), TOBN(0xc85ac201, 0x5d4753b4),
+ TOBN(0xc7a6caac, 0x658e099f), TOBN(0xcf46369e, 0x04b27390),
+ TOBN(0xe2e7d049, 0x506467ea), TOBN(0x481b63a2, 0x37cdeccc),
+ TOBN(0x4029abd8, 0xed80143a), TOBN(0x28bfe3c7, 0xbcb00b88),
+ TOBN(0x3bec1009, 0x0643d84a), TOBN(0x885f3668, 0xabd11041),
+ TOBN(0xdb02432c, 0xf83a34d6), TOBN(0x32f7b360, 0x719ceebe),
+ TOBN(0xf06c7837, 0xdad1fe7a), TOBN(0x60a157a9, 0x5441a0b0),
+ TOBN(0x704970e9, 0xe2d47550), TOBN(0xcd2bd553, 0x271b9020),
+ TOBN(0xff57f82f, 0x33e24a0b), TOBN(0x9cbee23f, 0xf2565079),
+ TOBN(0x16353427, 0xeb5f5825), TOBN(0x276feec4, 0xe948d662),
+ TOBN(0xd1b62bc6, 0xda10032b), TOBN(0x718351dd, 0xf0e72a53),
+ TOBN(0x93452076, 0x2420e7ba), TOBN(0x96368fff, 0x3a00118d),
+ TOBN(0x00ce2d26, 0x150a49e4), TOBN(0x0c28b636, 0x3f04706b),
+ TOBN(0xbad65a46, 0x58b196d0), TOBN(0x6c8455fc, 0xec9f8b7c),
+ TOBN(0xe90c895f, 0x2d71867e), TOBN(0x5c0be31b, 0xedf9f38c),
+ TOBN(0x2a37a15e, 0xd8f6ec04), TOBN(0x239639e7, 0x8cd85251),
+ TOBN(0xd8975315, 0x9c7c4c6b), TOBN(0x603aa3c0, 0xd7409af7),
+ TOBN(0xb8d53d0c, 0x007132fb), TOBN(0x68d12af7, 0xa6849238),
+ TOBN(0xbe0607e7, 0xbf5d9279), TOBN(0x9aa50055, 0xaada74ce),
+ TOBN(0xe81079cb, 0xba7e8ccb), TOBN(0x610c71d1, 0xa5f4ff5e),
+ TOBN(0x9e2ee1a7, 0x5aa07093), TOBN(0xca84004b, 0xa75da47c),
+ TOBN(0x074d3951, 0x3de75401), TOBN(0xf938f756, 0xbb311592),
+ TOBN(0x96197618, 0x00a43421), TOBN(0x39a25362, 0x07bc78c8),
+ TOBN(0x278f710a, 0x0a171276), TOBN(0xb28446ea, 0x8d1a8f08),
+ TOBN(0x184781bf, 0xe3b6a661), TOBN(0x7751cb1d, 0xe6d279f7),
+ TOBN(0xf8ff95d6, 0xc59eb662), TOBN(0x186d90b7, 0x58d3dea7),
+ TOBN(0x0e4bb6c1, 0xdfb4f754), TOBN(0x5c5cf56b, 0x2b2801dc),
+ TOBN(0xc561e452, 0x1f54564d), TOBN(0xb4fb8c60, 0xf0dd7f13),
+ TOBN(0xf8849630, 0x33ff98c7), TOBN(0x9619fffa, 0xcf17769c),
+ TOBN(0xf8090bf6, 0x1bfdd80a), TOBN(0x14d9a149, 0x422cfe63),
+ TOBN(0xb354c360, 0x6f6df9ea), TOBN(0xdbcf770d, 0x218f17ea),
+ TOBN(0x207db7c8, 0x79eb3480), TOBN(0x213dbda8, 0x559b6a26),
+ TOBN(0xac4c200b, 0x29fc81b3), TOBN(0xebc3e09f, 0x171d87c1),
+ TOBN(0x91799530, 0x1481aa9e), TOBN(0x051b92e1, 0x92e114fa),
+ TOBN(0xdf8f92e9, 0xecb5537f), TOBN(0x44b1b2cc, 0x290c7483),
+ TOBN(0xa711455a, 0x2adeb016), TOBN(0x964b6856, 0x81a10c2c),
+ TOBN(0x4f159d99, 0xcec03623), TOBN(0x05532225, 0xef3271ea),
+ TOBN(0xb231bea3, 0xc5ee4849), TOBN(0x57a54f50, 0x7094f103),
+ TOBN(0x3e2d421d, 0x9598b352), TOBN(0xe865a49c, 0x67412ab4),
+ TOBN(0xd2998a25, 0x1cc3a912), TOBN(0x5d092808, 0x0c74d65d),
+ TOBN(0x73f45908, 0x4088567a), TOBN(0xeb6b280e, 0x1f214a61),
+ TOBN(0x8c9adc34, 0xcaf0c13d), TOBN(0x39d12938, 0xf561fb80),
+ TOBN(0xb2dc3a5e, 0xbc6edfb4), TOBN(0x7485b1b1, 0xfe4d210e),
+ TOBN(0x062e0400, 0xe186ae72), TOBN(0x91e32d5c, 0x6eeb3b88),
+ TOBN(0x6df574d7, 0x4be59224), TOBN(0xebc88ccc, 0x716d55f3),
+ TOBN(0x26c2e6d0, 0xcad6ed33), TOBN(0xc6e21e7d, 0x0d3e8b10),
+ TOBN(0x2cc5840e, 0x5bcc36bb), TOBN(0x9292445e, 0x7da74f69),
+ TOBN(0x8be8d321, 0x4e5193a8), TOBN(0x3ec23629, 0x8df06413),
+ TOBN(0xc7e9ae85, 0xb134defa), TOBN(0x6073b1d0, 0x1bb2d475),
+ TOBN(0xb9ad615e, 0x2863c00d), TOBN(0x9e29493d, 0x525f4ac4),
+ TOBN(0xc32b1dea, 0x4e9acf4f), TOBN(0x3e1f01c8, 0xa50db88d),
+ TOBN(0xb05d70ea, 0x04da916c), TOBN(0x714b0d0a, 0xd865803e),
+ TOBN(0x4bd493fc, 0x9920cb5e), TOBN(0x5b44b1f7, 0x92c7a3ac),
+ TOBN(0xa2a77293, 0xbcec9235), TOBN(0x5ee06e87, 0xcd378553),
+ TOBN(0xceff8173, 0xda621607), TOBN(0x2bb03e4c, 0x99f5d290),
+ TOBN(0x2945106a, 0xa6f734ac), TOBN(0xb5056604, 0xd25c4732),
+ TOBN(0x5945920c, 0xe079afee), TOBN(0x686e17a0, 0x6789831f),
+ TOBN(0x5966bee8, 0xb74a5ae5), TOBN(0x38a673a2, 0x1e258d46),
+ TOBN(0xbd1cc1f2, 0x83141c95), TOBN(0x3b2ecf4f, 0x0e96e486),
+ TOBN(0xcd3aa896, 0x74e5fc78), TOBN(0x415ec10c, 0x2482fa7a),
+ TOBN(0x15234419, 0x80503380), TOBN(0x513d917a, 0xd314b392),
+ TOBN(0xb0b52f4e, 0x63caecae), TOBN(0x07bf22ad, 0x2dc7780b),
+ TOBN(0xe761e8a1, 0xe4306839), TOBN(0x1b3be962, 0x5dd7feaa),
+ TOBN(0x4fe728de, 0x74c778f1), TOBN(0xf1fa0bda, 0x5e0070f6),
+ TOBN(0x85205a31, 0x6ec3f510), TOBN(0x2c7e4a14, 0xd2980475),
+ TOBN(0xde3c19c0, 0x6f30ebfd), TOBN(0xdb1c1f38, 0xd4b7e644),
+ TOBN(0xfe291a75, 0x5dce364a), TOBN(0xb7b22a3c, 0x058f5be3),
+ TOBN(0x2cd2c302, 0x37fea38c), TOBN(0x2930967a, 0x2e17be17),
+ TOBN(0x87f009de, 0x0c061c65), TOBN(0xcb014aac, 0xedc6ed44),
+ TOBN(0x49bd1cb4, 0x3bafb1eb), TOBN(0x81bd8b5c, 0x282d3688),
+ TOBN(0x1cdab87e, 0xf01a17af), TOBN(0x21f37ac4, 0xe710063b),
+ TOBN(0x5a6c5676, 0x42fc8193), TOBN(0xf4753e70, 0x56a6015c),
+ TOBN(0x020f795e, 0xa15b0a44), TOBN(0x8f37c8d7, 0x8958a958),
+ TOBN(0x63b7e89b, 0xa4b675b5), TOBN(0xb4fb0c0c, 0x0fc31aea),
+ TOBN(0xed95e639, 0xa7ff1f2e), TOBN(0x9880f5a3, 0x619614fb),
+ TOBN(0xdeb6ff02, 0x947151ab), TOBN(0x5bc5118c, 0xa868dcdb),
+ TOBN(0xd8da2055, 0x4c20cea5), TOBN(0xcac2776e, 0x14c4d69a),
+ TOBN(0xcccb22c1, 0x622d599b), TOBN(0xa4ddb653, 0x68a9bb50),
+ TOBN(0x2c4ff151, 0x1b4941b4), TOBN(0xe1ff19b4, 0x6efba588),
+ TOBN(0x35034363, 0xc48345e0), TOBN(0x45542e3d, 0x1e29dfc4),
+ TOBN(0xf197cb91, 0x349f7aed), TOBN(0x3b2b5a00, 0x8fca8420),
+ TOBN(0x7c175ee8, 0x23aaf6d8), TOBN(0x54dcf421, 0x35af32b6),
+ TOBN(0x0ba14307, 0x27d6561e), TOBN(0x879d5ee4, 0xd175b1e2),
+ TOBN(0xc7c43673, 0x99807db5), TOBN(0x77a54455, 0x9cd55bcd),
+ TOBN(0xe6c2ff13, 0x0105c072), TOBN(0x18f7a99f, 0x8dda7da4),
+ TOBN(0x4c301820, 0x0e2d35c1), TOBN(0x06a53ca0, 0xd9cc6c82),
+ TOBN(0xaa21cc1e, 0xf1aa1d9e), TOBN(0x32414334, 0x4a75b1e8),
+ TOBN(0x2a6d1328, 0x0ebe9fdc), TOBN(0x16bd173f, 0x98a4755a),
+ TOBN(0xfbb9b245, 0x2133ffd9), TOBN(0x39a8b2f1, 0x830f1a20),
+ TOBN(0x484bc97d, 0xd5a1f52a), TOBN(0xd6aebf56, 0xa40eddf8),
+ TOBN(0x32257acb, 0x76ccdac6), TOBN(0xaf4d36ec, 0x1586ff27),
+ TOBN(0x8eaa8863, 0xf8de7dd1), TOBN(0x0045d5cf, 0x88647c16)},
+ {TOBN(0xa6f3d574, 0xc005979d), TOBN(0xc2072b42, 0x6a40e350),
+ TOBN(0xfca5c156, 0x8de2ecf9), TOBN(0xa8c8bf5b, 0xa515344e),
+ TOBN(0x97aee555, 0x114df14a), TOBN(0xd4374a4d, 0xfdc5ec6b),
+ TOBN(0x754cc28f, 0x2ca85418), TOBN(0x71cb9e27, 0xd3c41f78),
+ TOBN(0x89105079, 0x03605c39), TOBN(0xf0843d9e, 0xa142c96c),
+ TOBN(0xf3744934, 0x16923684), TOBN(0x732caa2f, 0xfa0a2893),
+ TOBN(0xb2e8c270, 0x61160170), TOBN(0xc32788cc, 0x437fbaa3),
+ TOBN(0x39cd818e, 0xa6eda3ac), TOBN(0xe2e94239, 0x9e2b2e07),
+ TOBN(0x6967d39b, 0x0260e52a), TOBN(0xd42585cc, 0x90653325),
+ TOBN(0x0d9bd605, 0x21ca7954), TOBN(0x4fa20877, 0x81ed57b3),
+ TOBN(0x60c1eff8, 0xe34a0bbe), TOBN(0x56b0040c, 0x84f6ef64),
+ TOBN(0x28be2b24, 0xb1af8483), TOBN(0xb2278163, 0xf5531614),
+ TOBN(0x8df27545, 0x5922ac1c), TOBN(0xa7b3ef5c, 0xa52b3f63),
+ TOBN(0x8e77b214, 0x71de57c4), TOBN(0x31682c10, 0x834c008b),
+ TOBN(0xc76824f0, 0x4bd55d31), TOBN(0xb6d1c086, 0x17b61c71),
+ TOBN(0x31db0903, 0xc2a5089d), TOBN(0x9c092172, 0x184e5d3f),
+ TOBN(0xdd7ced5b, 0xc00cc638), TOBN(0x1a2015eb, 0x61278fc2),
+ TOBN(0x2e8e5288, 0x6a37f8d6), TOBN(0xc457786f, 0xe79933ad),
+ TOBN(0xb3fe4cce, 0x2c51211a), TOBN(0xad9b10b2, 0x24c20498),
+ TOBN(0x90d87a4f, 0xd28db5e5), TOBN(0x698cd105, 0x3aca2fc3),
+ TOBN(0x4f112d07, 0xe91b536d), TOBN(0xceb982f2, 0x9eba09d6),
+ TOBN(0x3c157b2c, 0x197c396f), TOBN(0xe23c2d41, 0x7b66eb24),
+ TOBN(0x480c57d9, 0x3f330d37), TOBN(0xb3a4c8a1, 0x79108deb),
+ TOBN(0x702388de, 0xcb199ce5), TOBN(0x0b019211, 0xb944a8d4),
+ TOBN(0x24f2a692, 0x840bb336), TOBN(0x7c353bdc, 0xa669fa7b),
+ TOBN(0xda20d6fc, 0xdec9c300), TOBN(0x625fbe2f, 0xa13a4f17),
+ TOBN(0xa2b1b61a, 0xdbc17328), TOBN(0x008965bf, 0xa9515621),
+ TOBN(0x49690939, 0xc620ff46), TOBN(0x182dd27d, 0x8717e91c),
+ TOBN(0x5ace5035, 0xea6c3997), TOBN(0x54259aaa, 0xc2610bef),
+ TOBN(0xef18bb3f, 0x3c80dd39), TOBN(0x6910b95b, 0x5fc3fa39),
+ TOBN(0xfce2f510, 0x43e09aee), TOBN(0xced56c9f, 0xa7675665),
+ TOBN(0x10e265ac, 0xd872db61), TOBN(0x6982812e, 0xae9fce69),
+ TOBN(0x29be11c6, 0xce800998), TOBN(0x72bb1752, 0xb90360d9),
+ TOBN(0x2c193197, 0x5a4ad590), TOBN(0x2ba2f548, 0x9fc1dbc0),
+ TOBN(0x7fe4eebb, 0xe490ebe0), TOBN(0x12a0a4cd, 0x7fae11c0),
+ TOBN(0x7197cf81, 0xe903ba37), TOBN(0xcf7d4aa8, 0xde1c6dd8),
+ TOBN(0x92af6bf4, 0x3fd5684c), TOBN(0x2b26eecf, 0x80360aa1),
+ TOBN(0xbd960f30, 0x00546a82), TOBN(0x407b3c43, 0xf59ad8fe),
+ TOBN(0x86cae5fe, 0x249c82ba), TOBN(0x9e0faec7, 0x2463744c),
+ TOBN(0x87f551e8, 0x94916272), TOBN(0x033f9344, 0x6ceb0615),
+ TOBN(0x1e5eb0d1, 0x8be82e84), TOBN(0x89967f0e, 0x7a582fef),
+ TOBN(0xbcf687d5, 0xa6e921fa), TOBN(0xdfee4cf3, 0xd37a09ba),
+ TOBN(0x94f06965, 0xb493c465), TOBN(0x638b9a1c, 0x7635c030),
+ TOBN(0x76667864, 0x66f05e9f), TOBN(0xccaf6808, 0xc04da725),
+ TOBN(0xca2eb690, 0x768fccfc), TOBN(0xf402d37d, 0xb835b362),
+ TOBN(0x0efac0d0, 0xe2fdfcce), TOBN(0xefc9cdef, 0xb638d990),
+ TOBN(0x2af12b72, 0xd1669a8b), TOBN(0x33c536bc, 0x5774ccbd),
+ TOBN(0x30b21909, 0xfb34870e), TOBN(0xc38fa2f7, 0x7df25aca),
+ TOBN(0x74c5f02b, 0xbf81f3f5), TOBN(0x0525a5ae, 0xaf7e4581),
+ TOBN(0x88d2aaba, 0x433c54ae), TOBN(0xed9775db, 0x806a56c5),
+ TOBN(0xd320738a, 0xc0edb37d), TOBN(0x25fdb6ee, 0x66cc1f51),
+ TOBN(0xac661d17, 0x10600d76), TOBN(0x931ec1f3, 0xbdd1ed76),
+ TOBN(0x65c11d62, 0x19ee43f1), TOBN(0x5cd57c3e, 0x60829d97),
+ TOBN(0xd26c91a3, 0x984be6e8), TOBN(0xf08d9309, 0x8b0c53bd),
+ TOBN(0x94bc9e5b, 0xc016e4ea), TOBN(0xd3916839, 0x11d43d2b),
+ TOBN(0x886c5ad7, 0x73701155), TOBN(0xe0377626, 0x20b00715),
+ TOBN(0x7f01c9ec, 0xaa80ba59), TOBN(0x3083411a, 0x68538e51),
+ TOBN(0x970370f1, 0xe88128af), TOBN(0x625cc3db, 0x91dec14b),
+ TOBN(0xfef9666c, 0x01ac3107), TOBN(0xb2a8d577, 0xd5057ac3),
+ TOBN(0xb0f26299, 0x92be5df7), TOBN(0xf579c8e5, 0x00353924),
+ TOBN(0xb8fa3d93, 0x1341ed7a), TOBN(0x4223272c, 0xa7b59d49),
+ TOBN(0x3dcb1947, 0x83b8c4a4), TOBN(0x4e413c01, 0xed1302e4),
+ TOBN(0x6d999127, 0xe17e44ce), TOBN(0xee86bf75, 0x33b3adfb),
+ TOBN(0xf6902fe6, 0x25aa96ca), TOBN(0xb73540e4, 0xe5aae47d),
+ TOBN(0x32801d7b, 0x1b4a158c), TOBN(0xe571c99e, 0x27e2a369),
+ TOBN(0x40cb76c0, 0x10d9f197), TOBN(0xc308c289, 0x3167c0ae),
+ TOBN(0xa6ef9dd3, 0xeb7958f2), TOBN(0xa7226dfc, 0x300879b1),
+ TOBN(0x6cd0b362, 0x7edf0636), TOBN(0x4efbce6c, 0x7bc37eed),
+ TOBN(0x75f92a05, 0x8d699021), TOBN(0x586d4c79, 0x772566e3),
+ TOBN(0x378ca5f1, 0x761ad23a), TOBN(0x650d86fc, 0x1465a8ac),
+ TOBN(0x7a4ed457, 0x842ba251), TOBN(0x6b65e3e6, 0x42234933),
+ TOBN(0xaf1543b7, 0x31aad657), TOBN(0xa4cefe98, 0xcbfec369),
+ TOBN(0xb587da90, 0x9f47befb), TOBN(0x6562e9fb, 0x41312d13),
+ TOBN(0xa691ea59, 0xeff1cefe), TOBN(0xcc30477a, 0x05fc4cf6),
+ TOBN(0xa1632461, 0x0b0ffd3d), TOBN(0xa1f16f3b, 0x5b355956),
+ TOBN(0x5b148d53, 0x4224ec24), TOBN(0xdc834e7b, 0xf977012a),
+ TOBN(0x7bfc5e75, 0xb2c69dbc), TOBN(0x3aa77a29, 0x03c3da6c),
+ TOBN(0xde0df03c, 0xca910271), TOBN(0xcbd5ca4a, 0x7806dc55),
+ TOBN(0xe1ca5807, 0x6db476cb), TOBN(0xfde15d62, 0x5f37a31e),
+ TOBN(0xf49af520, 0xf41af416), TOBN(0x96c5c5b1, 0x7d342db5),
+ TOBN(0x155c43b7, 0xeb4ceb9b), TOBN(0x2e993010, 0x4e77371a),
+ TOBN(0x1d2987da, 0x675d43af), TOBN(0xef2bc1c0, 0x8599fd72),
+ TOBN(0x96894b7b, 0x9342f6b2), TOBN(0x201eadf2, 0x7c8e71f0),
+ TOBN(0xf3479d9f, 0x4a1f3efc), TOBN(0xe0f8a742, 0x702a9704),
+ TOBN(0xeafd44b6, 0xb3eba40c), TOBN(0xf9739f29, 0xc1c1e0d0),
+ TOBN(0x0091471a, 0x619d505e), TOBN(0xc15f9c96, 0x9d7c263e),
+ TOBN(0x5be47285, 0x83afbe33), TOBN(0xa3b6d6af, 0x04f1e092),
+ TOBN(0xe76526b9, 0x751a9d11), TOBN(0x2ec5b26d, 0x9a4ae4d2),
+ TOBN(0xeb66f4d9, 0x02f6fb8d), TOBN(0x4063c561, 0x96912164),
+ TOBN(0xeb7050c1, 0x80ef3000), TOBN(0x288d1c33, 0xeaa5b3f0),
+ TOBN(0xe87c68d6, 0x07806fd8), TOBN(0xb2f7f9d5, 0x4bbbf50f),
+ TOBN(0x25972f3a, 0xac8d6627), TOBN(0xf8547774, 0x10e8c13b),
+ TOBN(0xcc50ef6c, 0x872b4a60), TOBN(0xab2a34a4, 0x4613521b),
+ TOBN(0x39c5c190, 0x983e15d1), TOBN(0x61dde5df, 0x59905512),
+ TOBN(0xe417f621, 0x9f2275f3), TOBN(0x0750c8b6, 0x451d894b),
+ TOBN(0x75b04ab9, 0x78b0bdaa), TOBN(0x3bfd9fd4, 0x458589bd),
+ TOBN(0xf1013e30, 0xee9120b6), TOBN(0x2b51af93, 0x23a4743e),
+ TOBN(0xea96ffae, 0x48d14d9e), TOBN(0x71dc0dbe, 0x698a1d32),
+ TOBN(0x914962d2, 0x0180cca4), TOBN(0x1ae60677, 0xc3568963),
+ TOBN(0x8cf227b1, 0x437bc444), TOBN(0xc650c83b, 0xc9962c7a),
+ TOBN(0x23c2c7dd, 0xfe7ccfc4), TOBN(0xf925c89d, 0x1b929d48),
+ TOBN(0x4460f74b, 0x06783c33), TOBN(0xac2c8d49, 0xa590475a),
+ TOBN(0xfb40b407, 0xb807bba0), TOBN(0x9d1e362d, 0x69ff8f3a),
+ TOBN(0xa33e9681, 0xcbef64a4), TOBN(0x67ece5fa, 0x332fb4b2),
+ TOBN(0x6900a99b, 0x739f10e3), TOBN(0xc3341ca9, 0xff525925),
+ TOBN(0xee18a626, 0xa9e2d041), TOBN(0xa5a83685, 0x29580ddd),
+ TOBN(0xf3470c81, 0x9d7de3cd), TOBN(0xedf02586, 0x2062cf9c),
+ TOBN(0xf43522fa, 0xc010edb0), TOBN(0x30314135, 0x13a4b1ae),
+ TOBN(0xc792e02a, 0xdb22b94b), TOBN(0x993d8ae9, 0xa1eaa45b),
+ TOBN(0x8aad6cd3, 0xcd1e1c63), TOBN(0x89529ca7, 0xc5ce688a),
+ TOBN(0x2ccee3aa, 0xe572a253), TOBN(0xe02b6438, 0x02a21efb),
+ TOBN(0xa7091b6e, 0xc9430358), TOBN(0x06d1b1fa, 0x9d7db504),
+ TOBN(0x58846d32, 0xc4744733), TOBN(0x40517c71, 0x379f9e34),
+ TOBN(0x2f65655f, 0x130ef6ca), TOBN(0x526e4488, 0xf1f3503f),
+ TOBN(0x8467bd17, 0x7ee4a976), TOBN(0x1d9dc913, 0x921363d1),
+ TOBN(0xd8d24c33, 0xb069e041), TOBN(0x5eb5da0a, 0x2cdf7f51),
+ TOBN(0x1c0f3cb1, 0x197b994f), TOBN(0x3c95a6c5, 0x2843eae9),
+ TOBN(0x7766ffc9, 0xa6097ea5), TOBN(0x7bea4093, 0xd723b867),
+ TOBN(0xb48e1f73, 0x4db378f9), TOBN(0x70025b00, 0xe37b77ac),
+ TOBN(0x943dc8e7, 0xaf24ad46), TOBN(0xb98a15ac, 0x16d00a85),
+ TOBN(0x3adc38ba, 0x2743b004), TOBN(0xb1c7f4f7, 0x334415ee),
+ TOBN(0xea43df8f, 0x1e62d05a), TOBN(0x32618905, 0x9d76a3b6),
+ TOBN(0x2fbd0bb5, 0xa23a0f46), TOBN(0x5bc971db, 0x6a01918c),
+ TOBN(0x7801d94a, 0xb4743f94), TOBN(0xb94df65e, 0x676ae22b),
+ TOBN(0xaafcbfab, 0xaf95894c), TOBN(0x7b9bdc07, 0x276b2241),
+ TOBN(0xeaf98362, 0x5bdda48b), TOBN(0x5977faf2, 0xa3fcb4df),
+ TOBN(0xbed042ef, 0x052c4b5b), TOBN(0x9fe87f71, 0x067591f0),
+ TOBN(0xc89c73ca, 0x22f24ec7), TOBN(0x7d37fa9e, 0xe64a9f1b),
+ TOBN(0x2710841a, 0x15562627), TOBN(0x2c01a613, 0xc243b034),
+ TOBN(0x1d135c56, 0x2bc68609), TOBN(0xc2ca1715, 0x8b03f1f6),
+ TOBN(0xc9966c2d, 0x3eb81d82), TOBN(0xc02abf4a, 0x8f6df13e),
+ TOBN(0x77b34bd7, 0x8f72b43b), TOBN(0xaff6218f, 0x360c82b0),
+ TOBN(0x0aa5726c, 0x8d55b9d2), TOBN(0xdc0adbe9, 0x99e9bffb),
+ TOBN(0x9097549c, 0xefb9e72a), TOBN(0x16755712, 0x9dfb3111),
+ TOBN(0xdd8bf984, 0xf26847f9), TOBN(0xbcb8e387, 0xdfb30cb7),
+ TOBN(0xc1fd32a7, 0x5171ef9c), TOBN(0x977f3fc7, 0x389b363f),
+ TOBN(0x116eaf2b, 0xf4babda0), TOBN(0xfeab68bd, 0xf7113c8e),
+ TOBN(0xd1e3f064, 0xb7def526), TOBN(0x1ac30885, 0xe0b3fa02),
+ TOBN(0x1c5a6e7b, 0x40142d9d), TOBN(0x839b5603, 0x30921c0b),
+ TOBN(0x48f301fa, 0x36a116a3), TOBN(0x380e1107, 0xcfd9ee6d),
+ TOBN(0x7945ead8, 0x58854be1), TOBN(0x4111c12e, 0xcbd4d49d),
+ TOBN(0xece3b1ec, 0x3a29c2ef), TOBN(0x6356d404, 0x8d3616f5),
+ TOBN(0x9f0d6a8f, 0x594d320e), TOBN(0x0989316d, 0xf651ccd2),
+ TOBN(0x6c32117a, 0x0f8fdde4), TOBN(0x9abe5cc5, 0xa26a9bbc),
+ TOBN(0xcff560fb, 0x9723f671), TOBN(0x21b2a12d, 0x7f3d593c),
+ TOBN(0xe4cb18da, 0x24ba0696), TOBN(0x186e2220, 0xc3543384),
+ TOBN(0x722f64e0, 0x88312c29), TOBN(0x94282a99, 0x17dc7752),
+ TOBN(0x62467bbf, 0x5a85ee89), TOBN(0xf435c650, 0xf10076a0),
+ TOBN(0xc9ff1539, 0x43b3a50b), TOBN(0x7132130c, 0x1a53efbc),
+ TOBN(0x31bfe063, 0xf7b0c5b7), TOBN(0xb0179a7d, 0x4ea994cc),
+ TOBN(0x12d064b3, 0xc85f455b), TOBN(0x47259328, 0x8f6e0062),
+ TOBN(0xf64e590b, 0xb875d6d9), TOBN(0x22dd6225, 0xad92bcc7),
+ TOBN(0xb658038e, 0xb9c3bd6d), TOBN(0x00cdb0d6, 0xfbba27c8),
+ TOBN(0x0c681337, 0x1062c45d), TOBN(0xd8515b8c, 0x2d33407d),
+ TOBN(0xcb8f699e, 0x8cbb5ecf), TOBN(0x8c4347f8, 0xc608d7d8),
+ TOBN(0x2c11850a, 0xbb3e00db), TOBN(0x20a8dafd, 0xecb49d19),
+ TOBN(0xbd781480, 0x45ee2f40), TOBN(0x75e354af, 0x416b60cf),
+ TOBN(0xde0b58a1, 0x8d49a8c4), TOBN(0xe40e94e2, 0xfa359536),
+ TOBN(0xbd4fa59f, 0x62accd76), TOBN(0x05cf466a, 0x8c762837),
+ TOBN(0xb5abda99, 0x448c277b), TOBN(0x5a9e01bf, 0x48b13740),
+ TOBN(0x9d457798, 0x326aad8d), TOBN(0xbdef4954, 0xc396f7e7),
+ TOBN(0x6fb274a2, 0xc253e292), TOBN(0x2800bf0a, 0x1cfe53e7),
+ TOBN(0x22426d31, 0x44438fd4), TOBN(0xef233923, 0x5e259f9a),
+ TOBN(0x4188503c, 0x03f66264), TOBN(0x9e5e7f13, 0x7f9fdfab),
+ TOBN(0x565eb76c, 0x5fcc1aba), TOBN(0xea632548, 0x59b5bff8),
+ TOBN(0x5587c087, 0xaab6d3fa), TOBN(0x92b639ea, 0x6ce39c1b),
+ TOBN(0x0706e782, 0x953b135c), TOBN(0x7308912e, 0x425268ef),
+ TOBN(0x599e92c7, 0x090e7469), TOBN(0x83b90f52, 0x9bc35e75),
+ TOBN(0x4750b3d0, 0x244975b3), TOBN(0xf3a44358, 0x11965d72),
+ TOBN(0x179c6774, 0x9c8dc751), TOBN(0xff18cdfe, 0xd23d9ff0),
+ TOBN(0xc4013833, 0x2028e247), TOBN(0x96e280e2, 0xf3bfbc79),
+ TOBN(0xf60417bd, 0xd0880a84), TOBN(0x263c9f3d, 0x2a568151),
+ TOBN(0x36be15b3, 0x2d2ce811), TOBN(0x846dc0c2, 0xf8291d21),
+ TOBN(0x5cfa0ecb, 0x789fcfdb), TOBN(0x45a0beed, 0xd7535b9a),
+ TOBN(0xec8e9f07, 0x96d69af1), TOBN(0x31a7c5b8, 0x599ab6dc),
+ TOBN(0xd36d45ef, 0xf9e2e09f), TOBN(0x3cf49ef1, 0xdcee954b),
+ TOBN(0x6be34cf3, 0x086cff9b), TOBN(0x88dbd491, 0x39a3360f),
+ TOBN(0x1e96b8cc, 0x0dbfbd1d), TOBN(0xc1e5f7bf, 0xcb7e2552),
+ TOBN(0x0547b214, 0x28819d98), TOBN(0xc770dd9c, 0x7aea9dcb),
+ TOBN(0xaef0d4c7, 0x041d68c8), TOBN(0xcc2b9818, 0x13cb9ba8),
+ TOBN(0x7fc7bc76, 0xfe86c607), TOBN(0x6b7b9337, 0x502a9a95),
+ TOBN(0x1948dc27, 0xd14dab63), TOBN(0x249dd198, 0xdae047be),
+ TOBN(0xe8356584, 0xa981a202), TOBN(0x3531dd18, 0x3a893387),
+ TOBN(0x1be11f90, 0xc85c7209), TOBN(0x93d2fe1e, 0xe2a52b5a),
+ TOBN(0x8225bfe2, 0xec6d6b97), TOBN(0x9cf6d6f4, 0xbd0aa5de),
+ TOBN(0x911459cb, 0x54779f5f), TOBN(0x5649cddb, 0x86aeb1f3),
+ TOBN(0x32133579, 0x3f26ce5a), TOBN(0xc289a102, 0x550f431e),
+ TOBN(0x559dcfda, 0x73b84c6f), TOBN(0x84973819, 0xee3ac4d7),
+ TOBN(0xb51e55e6, 0xf2606a82), TOBN(0xe25f7061, 0x90f2fb57),
+ TOBN(0xacef6c2a, 0xb1a4e37c), TOBN(0x864e359d, 0x5dcf2706),
+ TOBN(0x479e6b18, 0x7ce57316), TOBN(0x2cab2500, 0x3a96b23d),
+ TOBN(0xed489862, 0x8ef16df7), TOBN(0x2056538c, 0xef3758b5),
+ TOBN(0xa7df865e, 0xf15d3101), TOBN(0x80c5533a, 0x61b553d7),
+ TOBN(0x366e1997, 0x4ed14294), TOBN(0x6620741f, 0xb3c0bcd6),
+ TOBN(0x21d1d9c4, 0xedc45418), TOBN(0x005b859e, 0xc1cc4a9d),
+ TOBN(0xdf01f630, 0xa1c462f0), TOBN(0x15d06cf3, 0xf26820c7),
+ TOBN(0x9f7f24ee, 0x3484be47), TOBN(0x2ff33e96, 0x4a0c902f),
+ TOBN(0x00bdf457, 0x5a0bc453), TOBN(0x2378dfaf, 0x1aa238db),
+ TOBN(0x272420ec, 0x856720f2), TOBN(0x2ad9d95b, 0x96797291),
+ TOBN(0xd1242cc6, 0x768a1558), TOBN(0x2e287f8b, 0x5cc86aa8),
+ TOBN(0x796873d0, 0x990cecaa), TOBN(0xade55f81, 0x675d4080),
+ TOBN(0x2645eea3, 0x21f0cd84), TOBN(0x7a1efa0f, 0xb4e17d02),
+ TOBN(0xf6858420, 0x037cc061), TOBN(0x682e05f0, 0xd5d43e12),
+ TOBN(0x59c36994, 0x27218710), TOBN(0x85cbba4d, 0x3f7cd2fc),
+ TOBN(0x726f9729, 0x7a3cd22a), TOBN(0x9f8cd5dc, 0x4a628397),
+ TOBN(0x17b93ab9, 0xc23165ed), TOBN(0xff5f5dbf, 0x122823d4),
+ TOBN(0xc1e4e4b5, 0x654a446d), TOBN(0xd1a9496f, 0x677257ba),
+ TOBN(0x6387ba94, 0xde766a56), TOBN(0x23608bc8, 0x521ec74a),
+ TOBN(0x16a522d7, 0x6688c4d4), TOBN(0x9d6b4282, 0x07373abd),
+ TOBN(0xa62f07ac, 0xb42efaa3), TOBN(0xf73e00f7, 0xe3b90180),
+ TOBN(0x36175fec, 0x49421c3e), TOBN(0xc4e44f9b, 0x3dcf2678),
+ TOBN(0x76df436b, 0x7220f09f), TOBN(0x172755fb, 0x3aa8b6cf),
+ TOBN(0xbab89d57, 0x446139cc), TOBN(0x0a0a6e02, 0x5fe0208f),
+ TOBN(0xcdbb63e2, 0x11e5d399), TOBN(0x33ecaa12, 0xa8977f0b),
+ TOBN(0x59598b21, 0xf7c42664), TOBN(0xb3e91b32, 0xab65d08a),
+ TOBN(0x035822ee, 0xf4502526), TOBN(0x1dcf0176, 0x720a82a9),
+ TOBN(0x50f8598f, 0x3d589e02), TOBN(0xdf0478ff, 0xb1d63d2c),
+ TOBN(0x8b8068bd, 0x1571cd07), TOBN(0x30c3aa4f, 0xd79670cd),
+ TOBN(0x25e8fd4b, 0x941ade7f), TOBN(0x3d1debdc, 0x32790011),
+ TOBN(0x65b6dcbd, 0x3a3f9ff0), TOBN(0x282736a4, 0x793de69c),
+ TOBN(0xef69a0c3, 0xd41d3bd3), TOBN(0xb533b8c9, 0x07a26bde),
+ TOBN(0xe2801d97, 0xdb2edf9f), TOBN(0xdc4a8269, 0xe1877af0),
+ TOBN(0x6c1c5851, 0x3d590dbe), TOBN(0x84632f6b, 0xee4e9357),
+ TOBN(0xd36d36b7, 0x79b33374), TOBN(0xb46833e3, 0x9bbca2e6),
+ TOBN(0x37893913, 0xf7fc0586), TOBN(0x385315f7, 0x66bf4719),
+ TOBN(0x72c56293, 0xb31855dc), TOBN(0xd1416d4e, 0x849061fe),
+ TOBN(0xbeb3ab78, 0x51047213), TOBN(0x447f6e61, 0xf040c996),
+ TOBN(0xd06d310d, 0x638b1d0c), TOBN(0xe28a413f, 0xbad1522e),
+ TOBN(0x685a76cb, 0x82003f86), TOBN(0x610d07f7, 0x0bcdbca3),
+ TOBN(0x6ff66021, 0x9ca4c455), TOBN(0x7df39b87, 0xcea10eec),
+ TOBN(0xb9255f96, 0xe22db218), TOBN(0x8cc6d9eb, 0x08a34c44),
+ TOBN(0xcd4ffb86, 0x859f9276), TOBN(0x8fa15eb2, 0x50d07335),
+ TOBN(0xdf553845, 0xcf2c24b5), TOBN(0x89f66a9f, 0x52f9c3ba),
+ TOBN(0x8f22b5b9, 0xe4a7ceb3), TOBN(0xaffef809, 0x0e134686),
+ TOBN(0x3e53e1c6, 0x8eb8fac2), TOBN(0x93c1e4eb, 0x28aec98e),
+ TOBN(0xb6b91ec5, 0x32a43bcb), TOBN(0x2dbfa947, 0xb2d74a51),
+ TOBN(0xe065d190, 0xca84bad7), TOBN(0xfb13919f, 0xad58e65c),
+ TOBN(0x3c41718b, 0xf1cb6e31), TOBN(0x688969f0, 0x06d05c3f),
+ TOBN(0xd4f94ce7, 0x21264d45), TOBN(0xfdfb65e9, 0x7367532b),
+ TOBN(0x5b1be8b1, 0x0945a39d), TOBN(0x229f789c, 0x2b8baf3b),
+ TOBN(0xd8f41f3e, 0x6f49f15d), TOBN(0x678ce828, 0x907f0792),
+ TOBN(0xc69ace82, 0xfca6e867), TOBN(0x106451ae, 0xd01dcc89),
+ TOBN(0x1bb4f7f0, 0x19fc32d2), TOBN(0x64633dfc, 0xb00c52d2),
+ TOBN(0x8f13549a, 0xad9ea445), TOBN(0x99a3bf50, 0xfb323705),
+ TOBN(0x0c9625a2, 0x534d4dbc), TOBN(0x45b8f1d1, 0xc2a2fea3),
+ TOBN(0x76ec21a1, 0xa530fc1a), TOBN(0x4bac9c2a, 0x9e5bd734),
+ TOBN(0x5996d76a, 0x7b4e3587), TOBN(0x0045cdee, 0x1182d9e3),
+ TOBN(0x1aee24b9, 0x1207f13d), TOBN(0x66452e97, 0x97345a41),
+ TOBN(0x16e5b054, 0x9f950cd0), TOBN(0x9cc72fb1, 0xd7fdd075),
+ TOBN(0x6edd61e7, 0x66249663), TOBN(0xde4caa4d, 0xf043cccb),
+ TOBN(0x11b1f57a, 0x55c7ac17), TOBN(0x779cbd44, 0x1a85e24d),
+ TOBN(0x78030f86, 0xe46081e7), TOBN(0xfd4a6032, 0x8e20f643),
+ TOBN(0xcc7a6488, 0x0a750c0f), TOBN(0x39bacfe3, 0x4e548e83),
+ TOBN(0x3d418c76, 0x0c110f05), TOBN(0x3e4daa4c, 0xb1f11588),
+ TOBN(0x2733e7b5, 0x5ffc69ff), TOBN(0x46f147bc, 0x92053127),
+ TOBN(0x885b2434, 0xd722df94), TOBN(0x6a444f65, 0xe6fc6b7c)},
+ {TOBN(0x7a1a465a, 0xc3f16ea8), TOBN(0x115a461d, 0xb2f1d11c),
+ TOBN(0x4767dd95, 0x6c68a172), TOBN(0x3392f2eb, 0xd13a4698),
+ TOBN(0xc7a99ccd, 0xe526cdc7), TOBN(0x8e537fdc, 0x22292b81),
+ TOBN(0x76d8cf69, 0xa6d39198), TOBN(0xffc5ff43, 0x2446852d),
+ TOBN(0x97b14f7e, 0xa90567e6), TOBN(0x513257b7, 0xb6ae5cb7),
+ TOBN(0x85454a3c, 0x9f10903d), TOBN(0xd8d2c9ad, 0x69bc3724),
+ TOBN(0x38da9324, 0x6b29cb44), TOBN(0xb540a21d, 0x77c8cbac),
+ TOBN(0x9bbfe435, 0x01918e42), TOBN(0xfffa707a, 0x56c3614e),
+ TOBN(0x0ce4e3f1, 0xd4e353b7), TOBN(0x062d8a14, 0xef46b0a0),
+ TOBN(0x6408d5ab, 0x574b73fd), TOBN(0xbc41d1c9, 0xd3273ffd),
+ TOBN(0x3538e1e7, 0x6be77800), TOBN(0x71fe8b37, 0xc5655031),
+ TOBN(0x1cd91621, 0x6b9b331a), TOBN(0xad825d0b, 0xbb388f73),
+ TOBN(0x56c2e05b, 0x1cb76219), TOBN(0x0ec0bf91, 0x71567e7e),
+ TOBN(0xe7076f86, 0x61c4c910), TOBN(0xd67b085b, 0xbabc04d9),
+ TOBN(0x9fb90459, 0x5e93a96a), TOBN(0x7526c1ea, 0xfbdc249a),
+ TOBN(0x0d44d367, 0xecdd0bb7), TOBN(0x95399917, 0x9dc0d695),
+ TOBN(0x61360ee9, 0x9e240d18), TOBN(0x057cdcac, 0xb4b94466),
+ TOBN(0xe7667cd1, 0x2fe5325c), TOBN(0x1fa297b5, 0x21974e3b),
+ TOBN(0xfa4081e7, 0xdb083d76), TOBN(0x31993be6, 0xf206bd15),
+ TOBN(0x8949269b, 0x14c19f8c), TOBN(0x21468d72, 0xa9d92357),
+ TOBN(0x2ccbc583, 0xa4c506ec), TOBN(0x957ed188, 0xd1acfe97),
+ TOBN(0x8baed833, 0x12f1aea2), TOBN(0xef2a6cb4, 0x8325362d),
+ TOBN(0x130dde42, 0x8e195c43), TOBN(0xc842025a, 0x0e6050c6),
+ TOBN(0x2da972a7, 0x08686a5d), TOBN(0xb52999a1, 0xe508b4a8),
+ TOBN(0xd9f090b9, 0x10a5a8bd), TOBN(0xca91d249, 0x096864da),
+ TOBN(0x8e6a93be, 0x3f67dbc1), TOBN(0xacae6fba, 0xf5f4764c),
+ TOBN(0x1563c6e0, 0xd21411a0), TOBN(0x28fa787f, 0xda0a4ad8),
+ TOBN(0xd524491c, 0x908c8030), TOBN(0x1257ba0e, 0x4c795f07),
+ TOBN(0x83f49167, 0xceca9754), TOBN(0x426d2cf6, 0x4b7939a0),
+ TOBN(0x2555e355, 0x723fd0bf), TOBN(0xa96e6d06, 0xc4f144e2),
+ TOBN(0x4768a8dd, 0x87880e61), TOBN(0x15543815, 0xe508e4d5),
+ TOBN(0x09d7e772, 0xb1b65e15), TOBN(0x63439dd6, 0xac302fa0),
+ TOBN(0xb93f802f, 0xc14e35c2), TOBN(0x71735b7c, 0x4341333c),
+ TOBN(0x03a25104, 0x16d4f362), TOBN(0x3f4d069b, 0xbf433c8e),
+ TOBN(0x0d83ae01, 0xf78f5a7c), TOBN(0x50a8ffbe, 0x7c4eed07),
+ TOBN(0xc74f8906, 0x76e10f83), TOBN(0x7d080966, 0x9ddaf8e1),
+ TOBN(0xb11df8e1, 0x698e04cc), TOBN(0x877be203, 0x169005c8),
+ TOBN(0x32749e8c, 0x4f3c6179), TOBN(0x2dbc9d0a, 0x7853fc05),
+ TOBN(0x187d4f93, 0x9454d937), TOBN(0xe682ce9d, 0xb4800e1b),
+ TOBN(0xa9129ad8, 0x165e68e8), TOBN(0x0fe29735, 0xbe7f785b),
+ TOBN(0x5303f40c, 0x5b9e02b7), TOBN(0xa37c9692, 0x35ee04e8),
+ TOBN(0x5f46cc20, 0x34d6632b), TOBN(0x55ef72b2, 0x96ac545b),
+ TOBN(0xabec5c1f, 0x7b91b062), TOBN(0x0a79e1c7, 0xbb33e821),
+ TOBN(0xbb04b428, 0x3a9f4117), TOBN(0x0de1f28f, 0xfd2a475a),
+ TOBN(0x31019ccf, 0x3a4434b4), TOBN(0xa3458111, 0x1a7954dc),
+ TOBN(0xa9dac80d, 0xe34972a7), TOBN(0xb043d054, 0x74f6b8dd),
+ TOBN(0x021c319e, 0x11137b1a), TOBN(0x00a754ce, 0xed5cc03f),
+ TOBN(0x0aa2c794, 0xcbea5ad4), TOBN(0x093e67f4, 0x70c015b6),
+ TOBN(0x72cdfee9, 0xc97e3f6b), TOBN(0xc10bcab4, 0xb6da7461),
+ TOBN(0x3b02d2fc, 0xb59806b9), TOBN(0x85185e89, 0xa1de6f47),
+ TOBN(0x39e6931f, 0x0eb6c4d4), TOBN(0x4d4440bd, 0xd4fa5b04),
+ TOBN(0x5418786e, 0x34be7eb8), TOBN(0x6380e521, 0x9d7259bc),
+ TOBN(0x20ac0351, 0xd598d710), TOBN(0x272c4166, 0xcb3a4da4),
+ TOBN(0xdb82fe1a, 0xca71de1f), TOBN(0x746e79f2, 0xd8f54b0f),
+ TOBN(0x6e7fc736, 0x4b573e9b), TOBN(0x75d03f46, 0xfd4b5040),
+ TOBN(0x5c1cc36d, 0x0b98d87b), TOBN(0x513ba3f1, 0x1f472da1),
+ TOBN(0x79d0af26, 0xabb177dd), TOBN(0xf82ab568, 0x7891d564),
+ TOBN(0x2b6768a9, 0x72232173), TOBN(0xefbb3bb0, 0x8c1f6619),
+ TOBN(0xb29c11db, 0xa6d18358), TOBN(0x519e2797, 0xb0916d3a),
+ TOBN(0xd4dc18f0, 0x9188e290), TOBN(0x648e86e3, 0x98b0ca7f),
+ TOBN(0x859d3145, 0x983c38b5), TOBN(0xb14f176c, 0x637abc8b),
+ TOBN(0x2793fb9d, 0xcaff7be6), TOBN(0xebe5a55f, 0x35a66a5a),
+ TOBN(0x7cec1dcd, 0x9f87dc59), TOBN(0x7c595cd3, 0xfbdbf560),
+ TOBN(0x5b543b22, 0x26eb3257), TOBN(0x69080646, 0xc4c935fd),
+ TOBN(0x7f2e4403, 0x81e9ede3), TOBN(0x243c3894, 0xcaf6df0a),
+ TOBN(0x7c605bb1, 0x1c073b11), TOBN(0xcd06a541, 0xba6a4a62),
+ TOBN(0x29168949, 0x49d4e2e5), TOBN(0x33649d07, 0x4af66880),
+ TOBN(0xbfc0c885, 0xe9a85035), TOBN(0xb4e52113, 0xfc410f4b),
+ TOBN(0xdca3b706, 0x78a6513b), TOBN(0x92ea4a2a, 0x9edb1943),
+ TOBN(0x02642216, 0xdb6e2dd8), TOBN(0x9b45d0b4, 0x9fd57894),
+ TOBN(0x114e70db, 0xc69d11ae), TOBN(0x1477dd19, 0x4c57595f),
+ TOBN(0xbc2208b4, 0xec77c272), TOBN(0x95c5b4d7, 0xdb68f59c),
+ TOBN(0xb8c4fc63, 0x42e532b7), TOBN(0x386ba422, 0x9ae35290),
+ TOBN(0xfb5dda42, 0xd201ecbc), TOBN(0x2353dc8b, 0xa0e38fd6),
+ TOBN(0x9a0b85ea, 0x68f7e978), TOBN(0x96ec5682, 0x2ad6d11f),
+ TOBN(0x5e279d6c, 0xe5f6886d), TOBN(0xd3fe03cd, 0x3cb1914d),
+ TOBN(0xfe541fa4, 0x7ea67c77), TOBN(0x952bd2af, 0xe3ea810c),
+ TOBN(0x791fef56, 0x8d01d374), TOBN(0xa3a1c621, 0x0f11336e),
+ TOBN(0x5ad0d5a9, 0xc7ec6d79), TOBN(0xff7038af, 0x3225c342),
+ TOBN(0x003c6689, 0xbc69601b), TOBN(0x25059bc7, 0x45e8747d),
+ TOBN(0xfa4965b2, 0xf2086fbf), TOBN(0xf6840ea6, 0x86916078),
+ TOBN(0xd7ac7620, 0x70081d6c), TOBN(0xe600da31, 0xb5328645),
+ TOBN(0x01916f63, 0x529b8a80), TOBN(0xe80e4858, 0x2d7d6f3e),
+ TOBN(0x29eb0fe8, 0xd664ca7c), TOBN(0xf017637b, 0xe7b43b0c),
+ TOBN(0x9a75c806, 0x76cb2566), TOBN(0x8f76acb1, 0xb24892d9),
+ TOBN(0x7ae7b9cc, 0x1f08fe45), TOBN(0x19ef7329, 0x6a4907d8),
+ TOBN(0x2db4ab71, 0x5f228bf0), TOBN(0xf3cdea39, 0x817032d7),
+ TOBN(0x0b1f482e, 0xdcabe3c0), TOBN(0x3baf76b4, 0xbb86325c),
+ TOBN(0xd49065e0, 0x10089465), TOBN(0x3bab5d29, 0x8e77c596),
+ TOBN(0x7636c3a6, 0x193dbd95), TOBN(0xdef5d294, 0xb246e499),
+ TOBN(0xb22c58b9, 0x286b2475), TOBN(0xa0b93939, 0xcd80862b),
+ TOBN(0x3002c83a, 0xf0992388), TOBN(0x6de01f9b, 0xeacbe14c),
+ TOBN(0x6aac688e, 0xadd70482), TOBN(0x708de92a, 0x7b4a4e8a),
+ TOBN(0x75b6dd73, 0x758a6eef), TOBN(0xea4bf352, 0x725b3c43),
+ TOBN(0x10041f2c, 0x87912868), TOBN(0xb1b1be95, 0xef09297a),
+ TOBN(0x19ae23c5, 0xa9f3860a), TOBN(0xc4f0f839, 0x515dcf4b),
+ TOBN(0x3c7ecca3, 0x97f6306a), TOBN(0x744c44ae, 0x68a3a4b0),
+ TOBN(0x69cd13a0, 0xb3a1d8a2), TOBN(0x7cad0a1e, 0x5256b578),
+ TOBN(0xea653fcd, 0x33791d9e), TOBN(0x9cc2a05d, 0x74b2e05f),
+ TOBN(0x73b391dc, 0xfd7affa2), TOBN(0xddb7091e, 0xb6b05442),
+ TOBN(0xc71e27bf, 0x8538a5c6), TOBN(0x195c63dd, 0x89abff17),
+ TOBN(0xfd315285, 0x1b71e3da), TOBN(0x9cbdfda7, 0xfa680fa0),
+ TOBN(0x9db876ca, 0x849d7eab), TOBN(0xebe2764b, 0x3c273271),
+ TOBN(0x663357e3, 0xf208dcea), TOBN(0x8c5bd833, 0x565b1b70),
+ TOBN(0xccc3b4f5, 0x9837fc0d), TOBN(0x9b641ba8, 0xa79cf00f),
+ TOBN(0x7428243d, 0xdfdf3990), TOBN(0x83a594c4, 0x020786b1),
+ TOBN(0xb712451a, 0x526c4502), TOBN(0x9d39438e, 0x6adb3f93),
+ TOBN(0xfdb261e3, 0xe9ff0ccd), TOBN(0x80344e3c, 0xe07af4c3),
+ TOBN(0x75900d7c, 0x2fa4f126), TOBN(0x08a3b865, 0x5c99a232),
+ TOBN(0x2478b6bf, 0xdb25e0c3), TOBN(0x482cc2c2, 0x71db2edf),
+ TOBN(0x37df7e64, 0x5f321bb8), TOBN(0x8a93821b, 0x9a8005b4),
+ TOBN(0x3fa2f10c, 0xcc8c1958), TOBN(0x0d332218, 0x2c269d0a),
+ TOBN(0x20ab8119, 0xe246b0e6), TOBN(0xb39781e4, 0xd349fd17),
+ TOBN(0xd293231e, 0xb31aa100), TOBN(0x4b779c97, 0xbb032168),
+ TOBN(0x4b3f19e1, 0xc8470500), TOBN(0x45b7efe9, 0x0c4c869d),
+ TOBN(0xdb84f38a, 0xa1a6bbcc), TOBN(0x3b59cb15, 0xb2fddbc1),
+ TOBN(0xba5514df, 0x3fd165e8), TOBN(0x499fd6a9, 0x061f8811),
+ TOBN(0x72cd1fe0, 0xbfef9f00), TOBN(0x120a4bb9, 0x79ad7e8a),
+ TOBN(0xf2ffd095, 0x5f4a5ac5), TOBN(0xcfd174f1, 0x95a7a2f0),
+ TOBN(0xd42301ba, 0x9d17baf1), TOBN(0xd2fa487a, 0x77f22089),
+ TOBN(0x9cb09efe, 0xb1dc77e1), TOBN(0xe9566939, 0x21c99682),
+ TOBN(0x8c546901, 0x6c6067bb), TOBN(0xfd378574, 0x61c24456),
+ TOBN(0x2b6a6cbe, 0x81796b33), TOBN(0x62d550f6, 0x58e87f8b),
+ TOBN(0x1b763e1c, 0x7f1b01b4), TOBN(0x4b93cfea, 0x1b1b5e12),
+ TOBN(0xb9345238, 0x1d531696), TOBN(0x57201c00, 0x88cdde69),
+ TOBN(0xdde92251, 0x9a86afc7), TOBN(0xe3043895, 0xbd35cea8),
+ TOBN(0x7608c1e1, 0x8555970d), TOBN(0x8267dfa9, 0x2535935e),
+ TOBN(0xd4c60a57, 0x322ea38b), TOBN(0xe0bf7977, 0x804ef8b5),
+ TOBN(0x1a0dab28, 0xc06fece4), TOBN(0xd405991e, 0x94e7b49d),
+ TOBN(0xc542b6d2, 0x706dab28), TOBN(0xcb228da3, 0xa91618fb),
+ TOBN(0x224e4164, 0x107d1cea), TOBN(0xeb9fdab3, 0xd0f5d8f1),
+ TOBN(0xc02ba386, 0x0d6e41cd), TOBN(0x676a72c5, 0x9b1f7146),
+ TOBN(0xffd6dd98, 0x4d6cb00b), TOBN(0xcef9c5ca, 0xde2e8d7c),
+ TOBN(0xa1bbf5d7, 0x641c7936), TOBN(0x1b95b230, 0xee8f772e),
+ TOBN(0xf765a92e, 0xe8ac25b1), TOBN(0xceb04cfc, 0x3a18b7c6),
+ TOBN(0x27944cef, 0x0acc8966), TOBN(0xcbb3c957, 0x434c1004),
+ TOBN(0x9c9971a1, 0xa43ff93c), TOBN(0x5bc2db17, 0xa1e358a9),
+ TOBN(0x45b4862e, 0xa8d9bc82), TOBN(0x70ebfbfb, 0x2201e052),
+ TOBN(0xafdf64c7, 0x92871591), TOBN(0xea5bcae6, 0xb42d0219),
+ TOBN(0xde536c55, 0x2ad8f03c), TOBN(0xcd6c3f4d, 0xa76aa33c),
+ TOBN(0xbeb5f623, 0x0bca6de3), TOBN(0xdd20dd99, 0xb1e706fd),
+ TOBN(0x90b3ff9d, 0xac9059d4), TOBN(0x2d7b2902, 0x7ccccc4e),
+ TOBN(0x8a090a59, 0xce98840f), TOBN(0xa5d947e0, 0x8410680a),
+ TOBN(0x49ae346a, 0x923379a5), TOBN(0x7dbc84f9, 0xb28a3156),
+ TOBN(0xfd40d916, 0x54a1aff2), TOBN(0xabf318ba, 0x3a78fb9b),
+ TOBN(0x50152ed8, 0x3029f95e), TOBN(0x9fc1dd77, 0xc58ad7fa),
+ TOBN(0x5fa57915, 0x13595c17), TOBN(0xb9504668, 0x8f62b3a9),
+ TOBN(0x907b5b24, 0xff3055b0), TOBN(0x2e995e35, 0x9a84f125),
+ TOBN(0x87dacf69, 0x7e9bbcfb), TOBN(0x95d0c1d6, 0xe86d96e3),
+ TOBN(0x65726e3c, 0x2d95a75c), TOBN(0x2c3c9001, 0xacd27f21),
+ TOBN(0x1deab561, 0x6c973f57), TOBN(0x108b7e2c, 0xa5221643),
+ TOBN(0x5fee9859, 0xc4ef79d4), TOBN(0xbd62b88a, 0x40d4b8c6),
+ TOBN(0xb4dd29c4, 0x197c75d6), TOBN(0x266a6df2, 0xb7076feb),
+ TOBN(0x9512d0ea, 0x4bf2df11), TOBN(0x1320c24f, 0x6b0cc9ec),
+ TOBN(0x6bb1e0e1, 0x01a59596), TOBN(0x8317c5bb, 0xeff9aaac),
+ TOBN(0x65bb405e, 0x385aa6c9), TOBN(0x613439c1, 0x8f07988f),
+ TOBN(0xd730049f, 0x16a66e91), TOBN(0xe97f2820, 0xfa1b0e0d),
+ TOBN(0x4131e003, 0x304c28ea), TOBN(0x820ab732, 0x526bac62),
+ TOBN(0xb2ac9ef9, 0x28714423), TOBN(0x54ecfffa, 0xadb10cb2),
+ TOBN(0x8781476e, 0xf886a4cc), TOBN(0x4b2c87b5, 0xdb2f8d49),
+ TOBN(0xe857cd20, 0x0a44295d), TOBN(0x707d7d21, 0x58c6b044),
+ TOBN(0xae8521f9, 0xf596757c), TOBN(0x87448f03, 0x67b2b714),
+ TOBN(0x13a9bc45, 0x5ebcd58d), TOBN(0x79bcced9, 0x9122d3c1),
+ TOBN(0x3c644247, 0x9e076642), TOBN(0x0cf22778, 0x2df4767d),
+ TOBN(0x5e61aee4, 0x71d444b6), TOBN(0x211236bf, 0xc5084a1d),
+ TOBN(0x7e15bc9a, 0x4fd3eaf6), TOBN(0x68df2c34, 0xab622bf5),
+ TOBN(0x9e674f0f, 0x59bf4f36), TOBN(0xf883669b, 0xd7f34d73),
+ TOBN(0xc48ac1b8, 0x31497b1d), TOBN(0x323b925d, 0x5106703b),
+ TOBN(0x22156f42, 0x74082008), TOBN(0xeffc521a, 0xc8482bcb),
+ TOBN(0x5c6831bf, 0x12173479), TOBN(0xcaa2528f, 0xc4739490),
+ TOBN(0x84d2102a, 0x8f1b3c4d), TOBN(0xcf64dfc1, 0x2d9bec0d),
+ TOBN(0x433febad, 0x78a546ef), TOBN(0x1f621ec3, 0x7b73cef1),
+ TOBN(0x6aecd627, 0x37338615), TOBN(0x162082ab, 0x01d8edf6),
+ TOBN(0x833a8119, 0x19e86b66), TOBN(0x6023a251, 0xd299b5db),
+ TOBN(0xf5bb0c3a, 0xbbf04b89), TOBN(0x6735eb69, 0xae749a44),
+ TOBN(0xd0e058c5, 0x4713de3b), TOBN(0xfdf2593e, 0x2c3d4ccd),
+ TOBN(0x1b8f414e, 0xfdd23667), TOBN(0xdd52aaca, 0xfa2015ee),
+ TOBN(0x3e31b517, 0xbd9625ff), TOBN(0x5ec9322d, 0x8db5918c),
+ TOBN(0xbc73ac85, 0xa96f5294), TOBN(0x82aa5bf3, 0x61a0666a),
+ TOBN(0x49755810, 0xbf08ac42), TOBN(0xd21cdfd5, 0x891cedfc),
+ TOBN(0x918cb57b, 0x67f8be10), TOBN(0x365d1a7c, 0x56ffa726),
+ TOBN(0x2435c504, 0x6532de93), TOBN(0xc0fc5e10, 0x2674cd02),
+ TOBN(0x6e51fcf8, 0x9cbbb142), TOBN(0x1d436e5a, 0xafc50692),
+ TOBN(0x766bffff, 0x3fbcae22), TOBN(0x3148c2fd, 0xfd55d3b8),
+ TOBN(0x52c7fdc9, 0x233222fa), TOBN(0x89ff1092, 0xe419fb6b),
+ TOBN(0x3cd6db99, 0x25254977), TOBN(0x2e85a161, 0x1cf12ca7),
+ TOBN(0xadd2547c, 0xdc810bc9), TOBN(0xea3f458f, 0x9d257c22),
+ TOBN(0x642c1fbe, 0x27d6b19b), TOBN(0xed07e6b5, 0x140481a6),
+ TOBN(0x6ada1d42, 0x86d2e0f8), TOBN(0xe5920122, 0x0e8a9fd5),
+ TOBN(0x02c936af, 0x708c1b49), TOBN(0x60f30fee, 0x2b4bfaff),
+ TOBN(0x6637ad06, 0x858e6a61), TOBN(0xce4c7767, 0x3fd374d0),
+ TOBN(0x39d54b2d, 0x7188defb), TOBN(0xa8c9d250, 0xf56a6b66),
+ TOBN(0x58fc0f5e, 0xb24fe1dc), TOBN(0x9eaf9dee, 0x6b73f24c),
+ TOBN(0xa90d588b, 0x33650705), TOBN(0xde5b62c5, 0xaf2ec729),
+ TOBN(0x5c72cfae, 0xd3c2b36e), TOBN(0x868c19d5, 0x034435da),
+ TOBN(0x88605f93, 0xe17ee145), TOBN(0xaa60c4ee, 0x77a5d5b1),
+ TOBN(0xbcf5bfd2, 0x3b60c472), TOBN(0xaf4ef13c, 0xeb1d3049),
+ TOBN(0x373f44fc, 0xe13895c9), TOBN(0xf29b382f, 0x0cbc9822),
+ TOBN(0x1bfcb853, 0x73efaef6), TOBN(0xcf56ac9c, 0xa8c96f40),
+ TOBN(0xd7adf109, 0x7a191e24), TOBN(0x98035f44, 0xbf8a8dc2),
+ TOBN(0xf40a71b9, 0x1e750c84), TOBN(0xc57f7b0c, 0x5dc6c469),
+ TOBN(0x49a0e79c, 0x6fbc19c1), TOBN(0x6b0f5889, 0xa48ebdb8),
+ TOBN(0x5d3fd084, 0xa07c4e9f), TOBN(0xc3830111, 0xab27de14),
+ TOBN(0x0e4929fe, 0x33e08dcc), TOBN(0xf4a5ad24, 0x40bb73a3),
+ TOBN(0xde86c2bf, 0x490f97ca), TOBN(0x288f09c6, 0x67a1ce18),
+ TOBN(0x364bb886, 0x1844478d), TOBN(0x7840fa42, 0xceedb040),
+ TOBN(0x1269fdd2, 0x5a631b37), TOBN(0x94761f1e, 0xa47c8b7d),
+ TOBN(0xfc0c2e17, 0x481c6266), TOBN(0x85e16ea2, 0x3daa5fa7),
+ TOBN(0xccd86033, 0x92491048), TOBN(0x0c2f6963, 0xf4d402d7),
+ TOBN(0x6336f7df, 0xdf6a865c), TOBN(0x0a2a463c, 0xb5c02a87),
+ TOBN(0xb0e29be7, 0xbf2f12ee), TOBN(0xf0a22002, 0x66bad988),
+ TOBN(0x27f87e03, 0x9123c1d7), TOBN(0x21669c55, 0x328a8c98),
+ TOBN(0x186b9803, 0x92f14529), TOBN(0xd3d056cc, 0x63954df3),
+ TOBN(0x2f03fd58, 0x175a46f6), TOBN(0x63e34ebe, 0x11558558),
+ TOBN(0xe13fedee, 0x5b80cfa5), TOBN(0xe872a120, 0xd401dbd1),
+ TOBN(0x52657616, 0xe8a9d667), TOBN(0xbc8da4b6, 0xe08d6693),
+ TOBN(0x370fb9bb, 0x1b703e75), TOBN(0x6773b186, 0xd4338363),
+ TOBN(0x18dad378, 0xecef7bff), TOBN(0xaac787ed, 0x995677da),
+ TOBN(0x4801ea8b, 0x0437164b), TOBN(0xf430ad20, 0x73fe795e),
+ TOBN(0xb164154d, 0x8ee5eb73), TOBN(0x0884ecd8, 0x108f7c0e),
+ TOBN(0x0e6ec096, 0x5f520698), TOBN(0x640631fe, 0x44f7b8d9),
+ TOBN(0x92fd34fc, 0xa35a68b9), TOBN(0x9c5a4b66, 0x4d40cf4e),
+ TOBN(0x949454bf, 0x80b6783d), TOBN(0x80e701fe, 0x3a320a10),
+ TOBN(0x8d1a564a, 0x1a0a39b2), TOBN(0x1436d53d, 0x320587db),
+ TOBN(0xf5096e6d, 0x6556c362), TOBN(0xbc23a3c0, 0xe2455d7e),
+ TOBN(0x3a7aee54, 0x807230f9), TOBN(0x9ba1cfa6, 0x22ae82fd),
+ TOBN(0x833a057a, 0x99c5d706), TOBN(0x8be85f4b, 0x842315c9),
+ TOBN(0xd083179a, 0x66a72f12), TOBN(0x2fc77d5d, 0xcdcc73cd),
+ TOBN(0x22b88a80, 0x5616ee30), TOBN(0xfb09548f, 0xe7ab1083),
+ TOBN(0x8ad6ab0d, 0x511270cd), TOBN(0x61f6c57a, 0x6924d9ab),
+ TOBN(0xa0f7bf72, 0x90aecb08), TOBN(0x849f87c9, 0x0df784a4),
+ TOBN(0x27c79c15, 0xcfaf1d03), TOBN(0xbbf9f675, 0xc463face),
+ TOBN(0x91502c65, 0x765ba543), TOBN(0x18ce3cac, 0x42ea60dd),
+ TOBN(0xe5cee6ac, 0x6e43ecb3), TOBN(0x63e4e910, 0x68f2aeeb),
+ TOBN(0x26234fa3, 0xc85932ee), TOBN(0x96883e8b, 0x4c90c44d),
+ TOBN(0x29b9e738, 0xa18a50f6), TOBN(0xbfc62b2a, 0x3f0420df),
+ TOBN(0xd22a7d90, 0x6d3e1fa9), TOBN(0x17115618, 0xfe05b8a3),
+ TOBN(0x2a0c9926, 0xbb2b9c01), TOBN(0xc739fcc6, 0xe07e76a2),
+ TOBN(0x540e9157, 0x165e439a), TOBN(0x06353a62, 0x6a9063d8),
+ TOBN(0x84d95594, 0x61e927a3), TOBN(0x013b9b26, 0xe2e0be7f),
+ TOBN(0x4feaec3b, 0x973497f1), TOBN(0x15c0f94e, 0x093ebc2d),
+ TOBN(0x6af5f227, 0x33af0583), TOBN(0x0c2af206, 0xc61f3340),
+ TOBN(0xd25dbdf1, 0x4457397c), TOBN(0x2e8ed017, 0xcabcbae0),
+ TOBN(0xe3010938, 0xc2815306), TOBN(0xbaa99337, 0xe8c6cd68),
+ TOBN(0x08513182, 0x3b0ec7de), TOBN(0x1e1b822b, 0x58df05df),
+ TOBN(0x5c14842f, 0xa5c3b683), TOBN(0x98fe977e, 0x3eba34ce),
+ TOBN(0xfd2316c2, 0x0d5e8873), TOBN(0xe48d839a, 0xbd0d427d),
+ TOBN(0x495b2218, 0x623fc961), TOBN(0x24ee56e7, 0xb46fba5e),
+ TOBN(0x9184a55b, 0x91e4de58), TOBN(0xa7488ca5, 0xdfdea288),
+ TOBN(0xa723862e, 0xa8dcc943), TOBN(0x92d762b2, 0x849dc0fc),
+ TOBN(0x3c444a12, 0x091ff4a9), TOBN(0x581113fa, 0x0cada274),
+ TOBN(0xb9de0a45, 0x30d8eae2), TOBN(0x5e0fcd85, 0xdf6b41ea),
+ TOBN(0x6233ea68, 0xc094dbb5), TOBN(0xb77d062e, 0xd968d410),
+ TOBN(0x3e719bbc, 0x58b3002d), TOBN(0x68e7dd3d, 0x3dc49d58),
+ TOBN(0x8d825740, 0x013a5e58), TOBN(0x21311747, 0x3c9e3c1b),
+ TOBN(0x0cb0a2a7, 0x7c99b6ab), TOBN(0x5c48a3b3, 0xc2f888f2)},
+ {TOBN(0xc7913e91, 0x991724f3), TOBN(0x5eda799c, 0x39cbd686),
+ TOBN(0xddb595c7, 0x63d4fc1e), TOBN(0x6b63b80b, 0xac4fed54),
+ TOBN(0x6ea0fc69, 0x7e5fb516), TOBN(0x737708ba, 0xd0f1c964),
+ TOBN(0x9628745f, 0x11a92ca5), TOBN(0x61f37958, 0x9a86967a),
+ TOBN(0x9af39b2c, 0xaa665072), TOBN(0x78322fa4, 0xefd324ef),
+ TOBN(0x3d153394, 0xc327bd31), TOBN(0x81d5f271, 0x3129dab0),
+ TOBN(0xc72e0c42, 0xf48027f5), TOBN(0xaa40cdbc, 0x8536e717),
+ TOBN(0xf45a657a, 0x2d369d0f), TOBN(0xb03bbfc4, 0xea7f74e6),
+ TOBN(0x46a8c418, 0x0d738ded), TOBN(0x6f1a5bb0, 0xe0de5729),
+ TOBN(0xf10230b9, 0x8ba81675), TOBN(0x32c6f30c, 0x112b33d4),
+ TOBN(0x7559129d, 0xd8fffb62), TOBN(0x6a281b47, 0xb459bf05),
+ TOBN(0x77c1bd3a, 0xfa3b6776), TOBN(0x0709b380, 0x7829973a),
+ TOBN(0x8c26b232, 0xa3326505), TOBN(0x38d69272, 0xee1d41bf),
+ TOBN(0x0459453e, 0xffe32afa), TOBN(0xce8143ad, 0x7cb3ea87),
+ TOBN(0x932ec1fa, 0x7e6ab666), TOBN(0x6cd2d230, 0x22286264),
+ TOBN(0x459a46fe, 0x6736f8ed), TOBN(0x50bf0d00, 0x9eca85bb),
+ TOBN(0x0b825852, 0x877a21ec), TOBN(0x300414a7, 0x0f537a94),
+ TOBN(0x3f1cba40, 0x21a9a6a2), TOBN(0x50824eee, 0x76943c00),
+ TOBN(0xa0dbfcec, 0xf83cba5d), TOBN(0xf9538148, 0x93b4f3c0),
+ TOBN(0x61744162, 0x48f24dd7), TOBN(0x5322d64d, 0xe4fb09dd),
+ TOBN(0x57447384, 0x3d9325f3), TOBN(0xa9bef2d0, 0xf371cb84),
+ TOBN(0x77d2188b, 0xa61e36c5), TOBN(0xbbd6a7d7, 0xc602df72),
+ TOBN(0xba3aa902, 0x8f61bc0b), TOBN(0xf49085ed, 0x6ed0b6a1),
+ TOBN(0x8bc625d6, 0xae6e8298), TOBN(0x832b0b1d, 0xa2e9c01d),
+ TOBN(0xa337c447, 0xf1f0ced1), TOBN(0x800cc793, 0x9492dd2b),
+ TOBN(0x4b93151d, 0xbea08efa), TOBN(0x820cf3f8, 0xde0a741e),
+ TOBN(0xff1982dc, 0x1c0f7d13), TOBN(0xef921960, 0x84dde6ca),
+ TOBN(0x1ad7d972, 0x45f96ee3), TOBN(0x319c8dbe, 0x29dea0c7),
+ TOBN(0xd3ea3871, 0x7b82b99b), TOBN(0x75922d4d, 0x470eb624),
+ TOBN(0x8f66ec54, 0x3b95d466), TOBN(0x66e673cc, 0xbee1e346),
+ TOBN(0x6afe67c4, 0xb5f2b89a), TOBN(0x3de9c1e6, 0x290e5cd3),
+ TOBN(0x8c278bb6, 0x310a2ada), TOBN(0x420fa384, 0x0bdb323b),
+ TOBN(0x0ae1d63b, 0x0eb919b0), TOBN(0xd74ee51d, 0xa74b9620),
+ TOBN(0x395458d0, 0xa674290c), TOBN(0x324c930f, 0x4620a510),
+ TOBN(0x2d1f4d19, 0xfbac27d4), TOBN(0x4086e8ca, 0x9bedeeac),
+ TOBN(0x0cdd211b, 0x9b679ab8), TOBN(0x5970167d, 0x7090fec4),
+ TOBN(0x3420f2c9, 0xfaf1fc63), TOBN(0x616d333a, 0x328c8bb4),
+ TOBN(0x7d65364c, 0x57f1fe4a), TOBN(0x9343e877, 0x55e5c73a),
+ TOBN(0x5795176b, 0xe970e78c), TOBN(0xa36ccebf, 0x60533627),
+ TOBN(0xfc7c7380, 0x09cdfc1b), TOBN(0xb39a2afe, 0xb3fec326),
+ TOBN(0xb7ff1ba1, 0x6224408a), TOBN(0xcc856e92, 0x247cfc5e),
+ TOBN(0x01f102e7, 0xc18bc493), TOBN(0x4613ab74, 0x2091c727),
+ TOBN(0xaa25e89c, 0xc420bf2b), TOBN(0x00a53176, 0x90337ec2),
+ TOBN(0xd2be9f43, 0x7d025fc7), TOBN(0x3316fb85, 0x6e6fe3dc),
+ TOBN(0x27520af5, 0x9ac50814), TOBN(0xfdf95e78, 0x9a8e4223),
+ TOBN(0xb7e7df2a, 0x56bec5a0), TOBN(0xf7022f7d, 0xdf159e5d),
+ TOBN(0x93eeeab1, 0xcac1fe8f), TOBN(0x8040188c, 0x37451168),
+ TOBN(0x7ee8aa8a, 0xd967dce6), TOBN(0xfa0e79e7, 0x3abc9299),
+ TOBN(0x67332cfc, 0x2064cfd1), TOBN(0x339c31de, 0xb0651934),
+ TOBN(0x719b28d5, 0x2a3bcbea), TOBN(0xee74c82b, 0x9d6ae5c6),
+ TOBN(0x0927d05e, 0xbaf28ee6), TOBN(0x82cecf2c, 0x9d719028),
+ TOBN(0x0b0d353e, 0xddb30289), TOBN(0xfe4bb977, 0xfddb2e29),
+ TOBN(0xbb5bb990, 0x640bfd9e), TOBN(0xd226e277, 0x82f62108),
+ TOBN(0x4bf00985, 0x02ffdd56), TOBN(0x7756758a, 0x2ca1b1b5),
+ TOBN(0xc32b62a3, 0x5285fe91), TOBN(0xedbc546a, 0x8c9cd140),
+ TOBN(0x1e47a013, 0xaf5cb008), TOBN(0xbca7e720, 0x073ce8f2),
+ TOBN(0xe10b2ab8, 0x17a91cae), TOBN(0xb89aab65, 0x08e27f63),
+ TOBN(0x7b3074a7, 0xdba3ddf9), TOBN(0x1c20ce09, 0x330c2972),
+ TOBN(0x6b9917b4, 0x5fcf7e33), TOBN(0xe6793743, 0x945ceb42),
+ TOBN(0x18fc2215, 0x5c633d19), TOBN(0xad1adb3c, 0xc7485474),
+ TOBN(0x646f9679, 0x6424c49b), TOBN(0xf888dfe8, 0x67c241c9),
+ TOBN(0xe12d4b93, 0x24f68b49), TOBN(0x9a6b62d8, 0xa571df20),
+ TOBN(0x81b4b26d, 0x179483cb), TOBN(0x666f9632, 0x9511fae2),
+ TOBN(0xd281b3e4, 0xd53aa51f), TOBN(0x7f96a765, 0x7f3dbd16),
+ TOBN(0xa7f8b5bf, 0x074a30ce), TOBN(0xd7f52107, 0x005a32e6),
+ TOBN(0x6f9e0907, 0x50237ed4), TOBN(0x2f21da47, 0x8096fa2b),
+ TOBN(0xf3e19cb4, 0xeec863a0), TOBN(0xd18f77fd, 0x9527620a),
+ TOBN(0x9505c81c, 0x407c1cf8), TOBN(0x9998db4e, 0x1b6ec284),
+ TOBN(0x7e3389e5, 0xc247d44d), TOBN(0x12507141, 0x3f4f3d80),
+ TOBN(0xd4ba0110, 0x4a78a6c7), TOBN(0x312874a0, 0x767720be),
+ TOBN(0xded059a6, 0x75944370), TOBN(0xd6123d90, 0x3b2c0bdd),
+ TOBN(0xa56b717b, 0x51c108e3), TOBN(0x9bb7940e, 0x070623e9),
+ TOBN(0x794e2d59, 0x84ac066c), TOBN(0xf5954a92, 0xe68c69a0),
+ TOBN(0x28c52458, 0x4fd99dcc), TOBN(0x60e639fc, 0xb1012517),
+ TOBN(0xc2e60125, 0x7de79248), TOBN(0xe9ef6404, 0xf12fc6d7),
+ TOBN(0x4c4f2808, 0x2a3b5d32), TOBN(0x865ad32e, 0xc768eb8a),
+ TOBN(0xac02331b, 0x13fb70b6), TOBN(0x037b44c1, 0x95599b27),
+ TOBN(0x1a860fc4, 0x60bd082c), TOBN(0xa2e25745, 0xc980cd01),
+ TOBN(0xee3387a8, 0x1da0263e), TOBN(0x931bfb95, 0x2d10f3d6),
+ TOBN(0x5b687270, 0xa1f24a32), TOBN(0xf140e65d, 0xca494b86),
+ TOBN(0x4f4ddf91, 0xb2f1ac7a), TOBN(0xf99eaabb, 0x760fee27),
+ TOBN(0x57f4008a, 0x49c228e5), TOBN(0x090be440, 0x1cf713bb),
+ TOBN(0xac91fbe4, 0x5004f022), TOBN(0xd838c2c2, 0x569e1af6),
+ TOBN(0xd6c7d20b, 0x0f1daaa5), TOBN(0xaa063ac1, 0x1bbb02c0),
+ TOBN(0x0938a422, 0x59558a78), TOBN(0x5343c669, 0x8435da2f),
+ TOBN(0x96f67b18, 0x034410dc), TOBN(0x7cc1e424, 0x84510804),
+ TOBN(0x86a1543f, 0x16dfbb7d), TOBN(0x921fa942, 0x5b5bd592),
+ TOBN(0x9dcccb6e, 0xb33dd03c), TOBN(0x8581ddd9, 0xb843f51e),
+ TOBN(0x54935fcb, 0x81d73c9e), TOBN(0x6d07e979, 0x0a5e97ab),
+ TOBN(0x4dc7b30a, 0xcf3a6bab), TOBN(0x147ab1f3, 0x170bee11),
+ TOBN(0x0aaf8e3d, 0x9fafdee4), TOBN(0xfab3dbcb, 0x538a8b95),
+ TOBN(0x405df4b3, 0x6ef13871), TOBN(0xf1f4e9cb, 0x088d5a49),
+ TOBN(0x9bcd24d3, 0x66b33f1d), TOBN(0x3b97b820, 0x5ce445c0),
+ TOBN(0xe2926549, 0xba93ff61), TOBN(0xd9c341ce, 0x4dafe616),
+ TOBN(0xfb30a76e, 0x16efb6f3), TOBN(0xdf24b8ca, 0x605b953c),
+ TOBN(0x8bd52afe, 0xc2fffb9f), TOBN(0xbbac5ff7, 0xe19d0b96),
+ TOBN(0x43c01b87, 0x459afccd), TOBN(0x6bd45143, 0xb7432652),
+ TOBN(0x84734530, 0x55b5d78e), TOBN(0x81088fdb, 0x1554ba7d),
+ TOBN(0xada0a52c, 0x1e269375), TOBN(0xf9f037c4, 0x2dc5ec10),
+ TOBN(0xc0660607, 0x94bfbc11), TOBN(0xc0a630bb, 0xc9c40d2f),
+ TOBN(0x5efc797e, 0xab64c31e), TOBN(0xffdb1dab, 0x74507144),
+ TOBN(0xf6124287, 0x1ca6790c), TOBN(0xe9609d81, 0xe69bf1bf),
+ TOBN(0xdb898595, 0x00d24fc9), TOBN(0x9c750333, 0xe51fb417),
+ TOBN(0x51830a91, 0xfef7bbde), TOBN(0x0ce67dc8, 0x945f585c),
+ TOBN(0x9a730ed4, 0x4763eb50), TOBN(0x24a0e221, 0xc1ab0d66),
+ TOBN(0x643b6393, 0x648748f3), TOBN(0x1982daa1, 0x6d3c6291),
+ TOBN(0x6f00a9f7, 0x8bbc5549), TOBN(0x7a1783e1, 0x7f36384e),
+ TOBN(0xe8346323, 0xde977f50), TOBN(0x91ab688d, 0xb245502a),
+ TOBN(0x331ab6b5, 0x6d0bdd66), TOBN(0x0a6ef32e, 0x64b71229),
+ TOBN(0x1028150e, 0xfe7c352f), TOBN(0x27e04350, 0xce7b39d3),
+ TOBN(0x2a3c8acd, 0xc1070c82), TOBN(0xfb2034d3, 0x80c9feef),
+ TOBN(0x2d729621, 0x709f3729), TOBN(0x8df290bf, 0x62cb4549),
+ TOBN(0x02f99f33, 0xfc2e4326), TOBN(0x3b30076d, 0x5eddf032),
+ TOBN(0xbb21f8cf, 0x0c652fb5), TOBN(0x314fb49e, 0xed91cf7b),
+ TOBN(0xa013eca5, 0x2f700750), TOBN(0x2b9e3c23, 0x712a4575),
+ TOBN(0xe5355557, 0xaf30fbb0), TOBN(0x1ada3516, 0x7c77e771),
+ TOBN(0x45f6ecb2, 0x7b135670), TOBN(0xe85d19df, 0x7cfc202e),
+ TOBN(0x0f1b50c7, 0x58d1be9f), TOBN(0x5ebf2c0a, 0xead2e344),
+ TOBN(0x1531fe4e, 0xabc199c9), TOBN(0xc7032592, 0x56bab0ae),
+ TOBN(0x16ab2e48, 0x6c1fec54), TOBN(0x0f87fda8, 0x04280188),
+ TOBN(0xdc9f46fc, 0x609e4a74), TOBN(0x2a44a143, 0xba667f91),
+ TOBN(0xbc3d8b95, 0xb4d83436), TOBN(0xa01e4bd0, 0xc7bd2958),
+ TOBN(0x7b182932, 0x73483c90), TOBN(0xa79c6aa1, 0xa7c7b598),
+ TOBN(0xbf3983c6, 0xeaaac07e), TOBN(0x8f18181e, 0x96e0d4e6),
+ TOBN(0x8553d37c, 0x051af62b), TOBN(0xe9a998eb, 0x0bf94496),
+ TOBN(0xe0844f9f, 0xb0d59aa1), TOBN(0x983fd558, 0xe6afb813),
+ TOBN(0x9670c0ca, 0x65d69804), TOBN(0x732b22de, 0x6ea5ff2d),
+ TOBN(0xd7640ba9, 0x5fd8623b), TOBN(0x9f619163, 0xa6351782),
+ TOBN(0x0bfc27ee, 0xacee5043), TOBN(0xae419e73, 0x2eb10f02),
+ TOBN(0x19c028d1, 0x8943fb05), TOBN(0x71f01cf7, 0xff13aa2a),
+ TOBN(0x7790737e, 0x8887a132), TOBN(0x67513309, 0x66318410),
+ TOBN(0x9819e8a3, 0x7ddb795e), TOBN(0xfecb8ef5, 0xdad100b2),
+ TOBN(0x59f74a22, 0x3021926a), TOBN(0xb7c28a49, 0x6f9b4c1c),
+ TOBN(0xed1a733f, 0x912ad0ab), TOBN(0x42a910af, 0x01a5659c),
+ TOBN(0x3842c6e0, 0x7bd68cab), TOBN(0x2b57fa38, 0x76d70ac8),
+ TOBN(0x8a6707a8, 0x3c53aaeb), TOBN(0x62c1c510, 0x65b4db18),
+ TOBN(0x8de2c1fb, 0xb2d09dc7), TOBN(0xc3dfed12, 0x266bd23b),
+ TOBN(0x927d039b, 0xd5b27db6), TOBN(0x2fb2f0f1, 0x103243da),
+ TOBN(0xf855a07b, 0x80be7399), TOBN(0xed9327ce, 0x1f9f27a8),
+ TOBN(0xa0bd99c7, 0x729bdef7), TOBN(0x2b67125e, 0x28250d88),
+ TOBN(0x784b26e8, 0x8670ced7), TOBN(0xe3dfe41f, 0xc31bd3b4),
+ TOBN(0x9e353a06, 0xbcc85cbc), TOBN(0x302e2909, 0x60178a9d),
+ TOBN(0x860abf11, 0xa6eac16e), TOBN(0x76447000, 0xaa2b3aac),
+ TOBN(0x46ff9d19, 0x850afdab), TOBN(0x35bdd6a5, 0xfdb2d4c1),
+ TOBN(0xe82594b0, 0x7e5c9ce9), TOBN(0x0f379e53, 0x20af346e),
+ TOBN(0x608b31e3, 0xbc65ad4a), TOBN(0x710c6b12, 0x267c4826),
+ TOBN(0x51c966f9, 0x71954cf1), TOBN(0xb1cec793, 0x0d0aa215),
+ TOBN(0x1f155989, 0x86bd23a8), TOBN(0xae2ff99c, 0xf9452e86),
+ TOBN(0xd8dd953c, 0x340ceaa2), TOBN(0x26355275, 0x2e2e9333),
+ TOBN(0x15d4e5f9, 0x8586f06d), TOBN(0xd6bf94a8, 0xf7cab546),
+ TOBN(0x33c59a0a, 0xb76a9af0), TOBN(0x52740ab3, 0xba095af7),
+ TOBN(0xc444de8a, 0x24389ca0), TOBN(0xcc6f9863, 0x706da0cb),
+ TOBN(0xb5a741a7, 0x6b2515cf), TOBN(0x71c41601, 0x9585c749),
+ TOBN(0x78350d4f, 0xe683de97), TOBN(0x31d61524, 0x63d0b5f5),
+ TOBN(0x7a0cc5e1, 0xfbce090b), TOBN(0xaac927ed, 0xfbcb2a5b),
+ TOBN(0xe920de49, 0x20d84c35), TOBN(0x8c06a0b6, 0x22b4de26),
+ TOBN(0xd34dd58b, 0xafe7ddf3), TOBN(0x55851fed, 0xc1e6e55b),
+ TOBN(0xd1395616, 0x960696e7), TOBN(0x940304b2, 0x5f22705f),
+ TOBN(0x6f43f861, 0xb0a2a860), TOBN(0xcf121282, 0x0e7cc981),
+ TOBN(0x12186212, 0x0ab64a96), TOBN(0x09215b9a, 0xb789383c),
+ TOBN(0x311eb305, 0x37387c09), TOBN(0xc5832fce, 0xf03ee760),
+ TOBN(0x30358f58, 0x32f7ea19), TOBN(0xe01d3c34, 0x91d53551),
+ TOBN(0x1ca5ee41, 0xda48ea80), TOBN(0x34e71e8e, 0xcf4fa4c1),
+ TOBN(0x312abd25, 0x7af1e1c7), TOBN(0xe3afcdeb, 0x2153f4a5),
+ TOBN(0x9d5c84d7, 0x00235e9a), TOBN(0x0308d3f4, 0x8c4c836f),
+ TOBN(0xc0a66b04, 0x89332de5), TOBN(0x610dd399, 0x89e566ef),
+ TOBN(0xf8eea460, 0xd1ac1635), TOBN(0x84cbb3fb, 0x20a2c0df),
+ TOBN(0x40afb488, 0xe74a48c5), TOBN(0x29738198, 0xd326b150),
+ TOBN(0x2a17747f, 0xa6d74081), TOBN(0x60ea4c05, 0x55a26214),
+ TOBN(0x53514bb4, 0x1f88c5fe), TOBN(0xedd64567, 0x7e83426c),
+ TOBN(0xd5d6cbec, 0x96460b25), TOBN(0xa12fd0ce, 0x68dc115e),
+ TOBN(0xc5bc3ed2, 0x697840ea), TOBN(0x969876a8, 0xa6331e31),
+ TOBN(0x60c36217, 0x472ff580), TOBN(0xf4229705, 0x4ad41393),
+ TOBN(0x4bd99ef0, 0xa03b8b92), TOBN(0x501c7317, 0xc144f4f6),
+ TOBN(0x159009b3, 0x18464945), TOBN(0x6d5e594c, 0x74c5c6be),
+ TOBN(0x2d587011, 0x321a3660), TOBN(0xd1e184b1, 0x3898d022),
+ TOBN(0x5ba04752, 0x4c6a7e04), TOBN(0x47fa1e2b, 0x45550b65),
+ TOBN(0x9419daf0, 0x48c0a9a5), TOBN(0x66362953, 0x7c243236),
+ TOBN(0xcd0744b1, 0x5cb12a88), TOBN(0x561b6f9a, 0x2b646188),
+ TOBN(0x599415a5, 0x66c2c0c0), TOBN(0xbe3f0859, 0x0f83f09a),
+ TOBN(0x9141c5be, 0xb92041b8), TOBN(0x01ae38c7, 0x26477d0d),
+ TOBN(0xca8b71f3, 0xd12c7a94), TOBN(0xfab5b31f, 0x765c70db),
+ TOBN(0x76ae7492, 0x487443e9), TOBN(0x8595a310, 0x990d1349),
+ TOBN(0xf8dbeda8, 0x7d460a37), TOBN(0x7f7ad082, 0x1e45a38f),
+ TOBN(0xed1d4db6, 0x1059705a), TOBN(0xa3dd492a, 0xe6b9c697),
+ TOBN(0x4b92ee3a, 0x6eb38bd5), TOBN(0xbab2609d, 0x67cc0bb7),
+ TOBN(0x7fc4fe89, 0x6e70ee82), TOBN(0xeff2c56e, 0x13e6b7e3),
+ TOBN(0x9b18959e, 0x34d26fca), TOBN(0x2517ab66, 0x889d6b45),
+ TOBN(0xf167b4e0, 0xbdefdd4f), TOBN(0x69958465, 0xf366e401),
+ TOBN(0x5aa368ab, 0xa73bbec0), TOBN(0x12148709, 0x7b240c21),
+ TOBN(0x378c3233, 0x18969006), TOBN(0xcb4d73ce, 0xe1fe53d1),
+ TOBN(0x5f50a80e, 0x130c4361), TOBN(0xd67f5951, 0x7ef5212b),
+ TOBN(0xf145e21e, 0x9e70c72e), TOBN(0xb2e52e29, 0x5566d2fb),
+ TOBN(0x44eaba4a, 0x032397f5), TOBN(0x5e56937b, 0x7e31a7de),
+ TOBN(0x68dcf517, 0x456c61e1), TOBN(0xbc2e954a, 0xa8b0a388),
+ TOBN(0xe3552fa7, 0x60a8b755), TOBN(0x03442dae, 0x73ad0cde),
+ TOBN(0x37ffe747, 0xceb26210), TOBN(0x983545e8, 0x787baef9),
+ TOBN(0x8b8c8535, 0x86a3de31), TOBN(0xc621dbcb, 0xfacd46db),
+ TOBN(0x82e442e9, 0x59266fbb), TOBN(0xa3514c37, 0x339d471c),
+ TOBN(0x3a11b771, 0x62cdad96), TOBN(0xf0cb3b3c, 0xecf9bdf0),
+ TOBN(0x3fcbdbce, 0x478e2135), TOBN(0x7547b5cf, 0xbda35342),
+ TOBN(0xa97e81f1, 0x8a677af6), TOBN(0xc8c2bf83, 0x28817987),
+ TOBN(0xdf07eaaf, 0x45580985), TOBN(0xc68d1f05, 0xc93b45cb),
+ TOBN(0x106aa2fe, 0xc77b4cac), TOBN(0x4c1d8afc, 0x04a7ae86),
+ TOBN(0xdb41c3fd, 0x9eb45ab2), TOBN(0x5b234b5b, 0xd4b22e74),
+ TOBN(0xda253dec, 0xf215958a), TOBN(0x67e0606e, 0xa04edfa0),
+ TOBN(0xabbbf070, 0xef751b11), TOBN(0xf352f175, 0xf6f06dce),
+ TOBN(0xdfc4b6af, 0x6839f6b4), TOBN(0x53ddf9a8, 0x9959848e),
+ TOBN(0xda49c379, 0xc21520b0), TOBN(0x90864ff0, 0xdbd5d1b6),
+ TOBN(0x2f055d23, 0x5f49c7f7), TOBN(0xe51e4e6a, 0xa796b2d8),
+ TOBN(0xc361a67f, 0x5c9dc340), TOBN(0x5ad53c37, 0xbca7c620),
+ TOBN(0xda1d6588, 0x32c756d0), TOBN(0xad60d911, 0x8bb67e13),
+ TOBN(0xd6c47bdf, 0x0eeec8c6), TOBN(0x4a27fec1, 0x078a1821),
+ TOBN(0x081f7415, 0xc3099524), TOBN(0x8effdf0b, 0x82cd8060),
+ TOBN(0xdb70ec1c, 0x65842df8), TOBN(0x8821b358, 0xd319a901),
+ TOBN(0x72ee56ee, 0xde42b529), TOBN(0x5bb39592, 0x236e4286),
+ TOBN(0xd1183316, 0xfd6f7140), TOBN(0xf9fadb5b, 0xbd8e81f7),
+ TOBN(0x701d5e0c, 0x5a02d962), TOBN(0xfdee4dbf, 0x1b601324),
+ TOBN(0xbed17407, 0x35d7620e), TOBN(0x04e3c2c3, 0xf48c0012),
+ TOBN(0x9ee29da7, 0x3455449a), TOBN(0x562cdef4, 0x91a836c4),
+ TOBN(0x8f682a5f, 0x47701097), TOBN(0x617125d8, 0xff88d0c2),
+ TOBN(0x948fda24, 0x57bb86dd), TOBN(0x348abb8f, 0x289f7286),
+ TOBN(0xeb10eab5, 0x99d94bbd), TOBN(0xd51ba28e, 0x4684d160),
+ TOBN(0xabe0e51c, 0x30c8f41a), TOBN(0x66588b45, 0x13254f4a),
+ TOBN(0x147ebf01, 0xfad097a5), TOBN(0x49883ea8, 0x610e815d),
+ TOBN(0xe44d60ba, 0x8a11de56), TOBN(0xa970de6e, 0x827a7a6d),
+ TOBN(0x2be41424, 0x5e17fc19), TOBN(0xd833c657, 0x01214057),
+ TOBN(0x1375813b, 0x363e723f), TOBN(0x6820bb88, 0xe6a52e9b),
+ TOBN(0x7e7f6970, 0xd875d56a), TOBN(0xd6a0a9ac, 0x51fbf6bf),
+ TOBN(0x54ba8790, 0xa3083c12), TOBN(0xebaeb23d, 0x6ae7eb64),
+ TOBN(0xa8685c3a, 0xb99a907a), TOBN(0xf1e74550, 0x026bf40b),
+ TOBN(0x7b73a027, 0xc802cd9e), TOBN(0x9a8a927c, 0x4fef4635),
+ TOBN(0xe1b6f60c, 0x08191224), TOBN(0xc4126ebb, 0xde4ec091),
+ TOBN(0xe1dff4dc, 0x4ae38d84), TOBN(0xde3f57db, 0x4f2ef985),
+ TOBN(0x34964337, 0xd446a1dd), TOBN(0x7bf217a0, 0x859e77f6),
+ TOBN(0x8ff10527, 0x8e1d13f5), TOBN(0xa304ef03, 0x74eeae27),
+ TOBN(0xfc6f5e47, 0xd19dfa5a), TOBN(0xdb007de3, 0x7fad982b),
+ TOBN(0x28205ad1, 0x613715f5), TOBN(0x251e6729, 0x7889529e),
+ TOBN(0x72705184, 0x1ae98e78), TOBN(0xf818537d, 0x271cac32),
+ TOBN(0xc8a15b7e, 0xb7f410f5), TOBN(0xc474356f, 0x81f62393),
+ TOBN(0x92dbdc5a, 0xc242316b), TOBN(0xabe060ac, 0xdbf4aff5),
+ TOBN(0x6e8c38fe, 0x909a8ec6), TOBN(0x43e514e5, 0x6116cb94),
+ TOBN(0x2078fa38, 0x07d784f9), TOBN(0x1161a880, 0xf4b5b357),
+ TOBN(0x5283ce79, 0x13adea3d), TOBN(0x0756c3e6, 0xcc6a910b),
+ TOBN(0x60bcfe01, 0xaaa79697), TOBN(0x04a73b29, 0x56391db1),
+ TOBN(0xdd8dad47, 0x189b45a0), TOBN(0xbfac0dd0, 0x48d5b8d9),
+ TOBN(0x34ab3af5, 0x7d3d2ec2), TOBN(0x6fa2fc2d, 0x207bd3af),
+ TOBN(0x9ff40092, 0x66550ded), TOBN(0x719b3e87, 0x1fd5b913),
+ TOBN(0xa573a496, 0x6d17fbc7), TOBN(0x0cd1a70a, 0x73d2b24e),
+ TOBN(0x34e2c5ca, 0xb2676937), TOBN(0xe7050b06, 0xbf669f21),
+ TOBN(0xfbe948b6, 0x1ede9046), TOBN(0xa0530051, 0x97662659),
+ TOBN(0x58cbd4ed, 0xf10124c5), TOBN(0xde2646e4, 0xdd6c06c8),
+ TOBN(0x332f8108, 0x8cad38c0), TOBN(0x471b7e90, 0x6bd68ae2),
+ TOBN(0x56ac3fb2, 0x0d8e27a3), TOBN(0xb54660db, 0x136b4b0d),
+ TOBN(0x123a1e11, 0xa6fd8de4), TOBN(0x44dbffea, 0xa37799ef),
+ TOBN(0x4540b977, 0xce6ac17c), TOBN(0x495173a8, 0xaf60acef)},
+ {TOBN(0x9ebb284d, 0x391c2a82), TOBN(0xbcdd4863, 0x158308e8),
+ TOBN(0x006f16ec, 0x83f1edca), TOBN(0xa13e2c37, 0x695dc6c8),
+ TOBN(0x2ab756f0, 0x4a057a87), TOBN(0xa8765500, 0xa6b48f98),
+ TOBN(0x4252face, 0x68651c44), TOBN(0xa52b540b, 0xe1765e02),
+ TOBN(0x4f922fc5, 0x16a0d2bb), TOBN(0x0d5cc16c, 0x1a623499),
+ TOBN(0x9241cf3a, 0x57c62c8b), TOBN(0x2f5e6961, 0xfd1b667f),
+ TOBN(0x5c15c70b, 0xf5a01797), TOBN(0x3d20b44d, 0x60956192),
+ TOBN(0x04911b37, 0x071fdb52), TOBN(0xf648f916, 0x8d6f0f7b),
+ TOBN(0x6dc1acaf, 0xe60b7cf7), TOBN(0x25860a50, 0x84a9d869),
+ TOBN(0x56fc6f09, 0xe7ba8ac4), TOBN(0x828c5bd0, 0x6148d29e),
+ TOBN(0xac6b435e, 0xdc55ae5f), TOBN(0xa527f56c, 0xc0117411),
+ TOBN(0x94d5045e, 0xfd24342c), TOBN(0x2c4c0a35, 0x70b67c0d),
+ TOBN(0x027cc8b8, 0xfac61d9a), TOBN(0x7d25e062, 0xe3c6fe8a),
+ TOBN(0xe08805bf, 0xe5bff503), TOBN(0x13271e6c, 0x6ff632f7),
+ TOBN(0x55dca6c0, 0x232f76a5), TOBN(0x8957c32d, 0x701ef426),
+ TOBN(0xee728bcb, 0xa10a5178), TOBN(0x5ea60411, 0xb62c5173),
+ TOBN(0xfc4e964e, 0xd0b8892b), TOBN(0x9ea17683, 0x9301bb74),
+ TOBN(0x6265c5ae, 0xfcc48626), TOBN(0xe60cf82e, 0xbb3e9102),
+ TOBN(0x57adf797, 0xd4df5531), TOBN(0x235b59a1, 0x8deeefe2),
+ TOBN(0x60adcf58, 0x3f306eb1), TOBN(0x105c2753, 0x3d09492d),
+ TOBN(0x4090914b, 0xb5def996), TOBN(0x1cb69c83, 0x233dd1e7),
+ TOBN(0xc1e9c1d3, 0x9b3d5e76), TOBN(0x1f3338ed, 0xfccf6012),
+ TOBN(0xb1e95d0d, 0x2f5378a8), TOBN(0xacf4c2c7, 0x2f00cd21),
+ TOBN(0x6e984240, 0xeb5fe290), TOBN(0xd66c038d, 0x248088ae),
+ TOBN(0x804d264a, 0xf94d70cf), TOBN(0xbdb802ef, 0x7314bf7e),
+ TOBN(0x8fb54de2, 0x4333ed02), TOBN(0x740461e0, 0x285635d9),
+ TOBN(0x4113b2c8, 0x365e9383), TOBN(0xea762c83, 0x3fdef652),
+ TOBN(0x4eec6e2e, 0x47b956c1), TOBN(0xa3d814be, 0x65620fa4),
+ TOBN(0x9ad5462b, 0xb4d8bc50), TOBN(0x181c0b16, 0xa9195770),
+ TOBN(0xebd4fe1c, 0x78412a68), TOBN(0xae0341bc, 0xc0dff48c),
+ TOBN(0xb6bc45cf, 0x7003e866), TOBN(0xf11a6dea, 0x8a24a41b),
+ TOBN(0x5407151a, 0xd04c24c2), TOBN(0x62c9d27d, 0xda5b7b68),
+ TOBN(0x2e964235, 0x88cceff6), TOBN(0x8594c54f, 0x8b07ed69),
+ TOBN(0x1578e73c, 0xc84d0d0d), TOBN(0x7b4e1055, 0xff532868),
+ TOBN(0xa348c0d5, 0xb5ec995a), TOBN(0xbf4b9d55, 0x14289a54),
+ TOBN(0x9ba155a6, 0x58fbd777), TOBN(0x186ed7a8, 0x1a84491d),
+ TOBN(0xd4992b30, 0x614c0900), TOBN(0xda98d121, 0xbd00c24b),
+ TOBN(0x7f534dc8, 0x7ec4bfa1), TOBN(0x4a5ff674, 0x37dc34bc),
+ TOBN(0x68c196b8, 0x1d7ea1d7), TOBN(0x38cf2893, 0x80a6d208),
+ TOBN(0xfd56cd09, 0xe3cbbd6e), TOBN(0xec72e27e, 0x4205a5b6),
+ TOBN(0x15ea68f5, 0xa44f77f7), TOBN(0x7aa5f9fd, 0xb43c52bc),
+ TOBN(0x86ff676f, 0x94f0e609), TOBN(0xa4cde963, 0x2e2d432b),
+ TOBN(0x8cafa0c0, 0xeee470af), TOBN(0x84137d0e, 0x8a3f5ec8),
+ TOBN(0xebb40411, 0xfaa31231), TOBN(0xa239c13f, 0x6f7f7ccf),
+ TOBN(0x32865719, 0xa8afd30b), TOBN(0x86798328, 0x8a826dce),
+ TOBN(0xdf04e891, 0xc4a8fbe0), TOBN(0xbb6b6e1b, 0xebf56ad3),
+ TOBN(0x0a695b11, 0x471f1ff0), TOBN(0xd76c3389, 0xbe15baf0),
+ TOBN(0x018edb95, 0xbe96c43e), TOBN(0xf2beaaf4, 0x90794158),
+ TOBN(0x152db09e, 0xc3076a27), TOBN(0x5e82908e, 0xe416545d),
+ TOBN(0xa2c41272, 0x356d6f2e), TOBN(0xdc9c9642, 0x31fd74e1),
+ TOBN(0x66ceb88d, 0x519bf615), TOBN(0xe29ecd76, 0x05a2274e),
+ TOBN(0x3a0473c4, 0xbf5e2fa0), TOBN(0x6b6eb671, 0x64284e67),
+ TOBN(0xe8b97932, 0xb88756dd), TOBN(0xed4e8652, 0xf17e3e61),
+ TOBN(0xc2dd1499, 0x3ee1c4a4), TOBN(0xc0aaee17, 0x597f8c0e),
+ TOBN(0x15c4edb9, 0x6c168af3), TOBN(0x6563c7bf, 0xb39ae875),
+ TOBN(0xadfadb6f, 0x20adb436), TOBN(0xad55e8c9, 0x9a042ac0),
+ TOBN(0x975a1ed8, 0xb76da1f5), TOBN(0x10dfa466, 0xa58acb94),
+ TOBN(0x8dd7f7e3, 0xac060282), TOBN(0x6813e66a, 0x572a051e),
+ TOBN(0xb4ccae1e, 0x350cb901), TOBN(0xb653d656, 0x50cb7822),
+ TOBN(0x42484710, 0xdfab3b87), TOBN(0xcd7ee537, 0x9b670fd0),
+ TOBN(0x0a50b12e, 0x523b8bf6), TOBN(0x8009eb5b, 0x8f910c1b),
+ TOBN(0xf535af82, 0x4a167588), TOBN(0x0f835f9c, 0xfb2a2abd),
+ TOBN(0xf59b2931, 0x2afceb62), TOBN(0xc797df2a, 0x169d383f),
+ TOBN(0xeb3f5fb0, 0x66ac02b0), TOBN(0x029d4c6f, 0xdaa2d0ca),
+ TOBN(0xd4059bc1, 0xafab4bc5), TOBN(0x833f5c6f, 0x56783247),
+ TOBN(0xb5346630, 0x8d2d3605), TOBN(0x83387891, 0xd34d8433),
+ TOBN(0xd973b30f, 0xadd9419a), TOBN(0xbcca1099, 0xafe3fce8),
+ TOBN(0x08178315, 0x0809aac6), TOBN(0x01b7f21a, 0x540f0f11),
+ TOBN(0x65c29219, 0x909523c8), TOBN(0xa62f648f, 0xa3a1c741),
+ TOBN(0x88598d4f, 0x60c9e55a), TOBN(0xbce9141b, 0x0e4f347a),
+ TOBN(0x9af97d84, 0x35f9b988), TOBN(0x0210da62, 0x320475b6),
+ TOBN(0x3c076e22, 0x9191476c), TOBN(0x7520dbd9, 0x44fc7834),
+ TOBN(0x6a6b2cfe, 0xc1ab1bbd), TOBN(0xef8a65be, 0xdc650938),
+ TOBN(0x72855540, 0x805d7bc4), TOBN(0xda389396, 0xed11fdfd),
+ TOBN(0xa9d5bd36, 0x74660876), TOBN(0x11d67c54, 0xb45dff35),
+ TOBN(0x6af7d148, 0xa4f5da94), TOBN(0xbb8d4c3f, 0xc0bbeb31),
+ TOBN(0x87a7ebd1, 0xe0a1b12a), TOBN(0x1e4ef88d, 0x770ba95f),
+ TOBN(0x8c33345c, 0xdc2ae9cb), TOBN(0xcecf1276, 0x01cc8403),
+ TOBN(0x687c012e, 0x1b39b80f), TOBN(0xfd90d0ad, 0x35c33ba4),
+ TOBN(0xa3ef5a67, 0x5c9661c2), TOBN(0x368fc88e, 0xe017429e),
+ TOBN(0xd30c6761, 0x196a2fa2), TOBN(0x931b9817, 0xbd5b312e),
+ TOBN(0xba01000c, 0x72f54a31), TOBN(0xa203d2c8, 0x66eaa541),
+ TOBN(0xf2abdee0, 0x98939db3), TOBN(0xe37d6c2c, 0x3e606c02),
+ TOBN(0xf2921574, 0x521ff643), TOBN(0x2781b3c4, 0xd7e2fca3),
+ TOBN(0x664300b0, 0x7850ec06), TOBN(0xac5a38b9, 0x7d3a10cf),
+ TOBN(0x9233188d, 0xe34ab39d), TOBN(0xe77057e4, 0x5072cbb9),
+ TOBN(0xbcf0c042, 0xb59e78df), TOBN(0x4cfc91e8, 0x1d97de52),
+ TOBN(0x4661a26c, 0x3ee0ca4a), TOBN(0x5620a4c1, 0xfb8507bc),
+ TOBN(0x4b44d4aa, 0x049f842c), TOBN(0xceabc5d5, 0x1540e82b),
+ TOBN(0x306710fd, 0x15c6f156), TOBN(0xbe5ae52b, 0x63db1d72),
+ TOBN(0x06f1e7e6, 0x334957f1), TOBN(0x57e388f0, 0x31144a70),
+ TOBN(0xfb69bb2f, 0xdf96447b), TOBN(0x0f78ebd3, 0x73e38a12),
+ TOBN(0xb8222605, 0x2b7ce542), TOBN(0xe6d4ce99, 0x7472bde1),
+ TOBN(0x53e16ebe, 0x09d2f4da), TOBN(0x180ff42e, 0x53b92b2e),
+ TOBN(0xc59bcc02, 0x2c34a1c6), TOBN(0x3803d6f9, 0x422c46c2),
+ TOBN(0x18aff74f, 0x5c14a8a2), TOBN(0x55aebf80, 0x10a08b28),
+ TOBN(0x66097d58, 0x7135593f), TOBN(0x32e6eff7, 0x2be570cd),
+ TOBN(0x584e6a10, 0x2a8c860d), TOBN(0xcd185890, 0xa2eb4163),
+ TOBN(0x7ceae99d, 0x6d97e134), TOBN(0xd42c6b70, 0xdd8447ce),
+ TOBN(0x59ddbb4a, 0xb8c50273), TOBN(0x03c612df, 0x3cf34e1e),
+ TOBN(0x84b9ca15, 0x04b6c5a0), TOBN(0x35216f39, 0x18f0e3a3),
+ TOBN(0x3ec2d2bc, 0xbd986c00), TOBN(0x8bf546d9, 0xd19228fe),
+ TOBN(0xd1c655a4, 0x4cd623c3), TOBN(0x366ce718, 0x502b8e5a),
+ TOBN(0x2cfc84b4, 0xeea0bfe7), TOBN(0xe01d5cee, 0xcf443e8e),
+ TOBN(0x8ec045d9, 0x036520f8), TOBN(0xdfb3c3d1, 0x92d40e98),
+ TOBN(0x0bac4cce, 0xcc559a04), TOBN(0x35eccae5, 0x240ea6b1),
+ TOBN(0x180b32db, 0xf8a5a0ac), TOBN(0x547972a5, 0xeb699700),
+ TOBN(0xa3765801, 0xca26bca0), TOBN(0x57e09d0e, 0xa647f25a),
+ TOBN(0xb956970e, 0x2fdd23cc), TOBN(0xb80288bc, 0x5682e971),
+ TOBN(0xe6e6d91e, 0x9ae86ebc), TOBN(0x0564c83f, 0x8c9f1939),
+ TOBN(0x551932a2, 0x39560368), TOBN(0xe893752b, 0x049c28e2),
+ TOBN(0x0b03cee5, 0xa6a158c3), TOBN(0xe12d656b, 0x04964263),
+ TOBN(0x4b47554e, 0x63e3bc1d), TOBN(0xc719b6a2, 0x45044ff7),
+ TOBN(0x4f24d30a, 0xe48daa07), TOBN(0xa3f37556, 0xc8c1edc3),
+ TOBN(0x9a47bf76, 0x0700d360), TOBN(0xbb1a1824, 0x822ae4e2),
+ TOBN(0x22e275a3, 0x89f1fb4c), TOBN(0x72b1aa23, 0x9968c5f5),
+ TOBN(0xa75feaca, 0xbe063f64), TOBN(0x9b392f43, 0xbce47a09),
+ TOBN(0xd4241509, 0x1ad07aca), TOBN(0x4b0c591b, 0x8d26cd0f),
+ TOBN(0x2d42ddfd, 0x92f1169a), TOBN(0x63aeb1ac, 0x4cbf2392),
+ TOBN(0x1de9e877, 0x0691a2af), TOBN(0xebe79af7, 0xd98021da),
+ TOBN(0xcfdf2a4e, 0x40e50acf), TOBN(0xf0a98ad7, 0xaf01d665),
+ TOBN(0xefb640bf, 0x1831be1f), TOBN(0x6fe8bd2f, 0x80e9ada0),
+ TOBN(0x94c103a1, 0x6cafbc91), TOBN(0x170f8759, 0x8308e08c),
+ TOBN(0x5de2d2ab, 0x9780ff4f), TOBN(0x666466bc, 0x45b201f2),
+ TOBN(0x58af2010, 0xf5b343bc), TOBN(0x0f2e400a, 0xf2f142fe),
+ TOBN(0x3483bfde, 0xa85f4bdf), TOBN(0xf0b1d093, 0x03bfeaa9),
+ TOBN(0x2ea01b95, 0xc7081603), TOBN(0xe943e4c9, 0x3dba1097),
+ TOBN(0x47be92ad, 0xb438f3a6), TOBN(0x00bb7742, 0xe5bf6636),
+ TOBN(0x136b7083, 0x824297b4), TOBN(0x9d0e5580, 0x5584455f),
+ TOBN(0xab48cedc, 0xf1c7d69e), TOBN(0x53a9e481, 0x2a256e76),
+ TOBN(0x0402b0e0, 0x65eb2413), TOBN(0xdadbbb84, 0x8fc407a7),
+ TOBN(0xa65cd5a4, 0x8d7f5492), TOBN(0x21d44293, 0x74bae294),
+ TOBN(0x66917ce6, 0x3b5f1cc4), TOBN(0x37ae52ea, 0xce872e62),
+ TOBN(0xbb087b72, 0x2905f244), TOBN(0x12077086, 0x1e6af74f),
+ TOBN(0x4b644e49, 0x1058edea), TOBN(0x827510e3, 0xb638ca1d),
+ TOBN(0x8cf2b704, 0x6038591c), TOBN(0xffc8b47a, 0xfe635063),
+ TOBN(0x3ae220e6, 0x1b4d5e63), TOBN(0xbd864742, 0x9d961b4b),
+ TOBN(0x610c107e, 0x9bd16bed), TOBN(0x4270352a, 0x1127147b),
+ TOBN(0x7d17ffe6, 0x64cfc50e), TOBN(0x50dee01a, 0x1e36cb42),
+ TOBN(0x068a7622, 0x35dc5f9a), TOBN(0x9a08d536, 0xdf53f62c),
+ TOBN(0x4ed71457, 0x6be5f7de), TOBN(0xd93006f8, 0xc2263c9e),
+ TOBN(0xe073694c, 0xcacacb36), TOBN(0x2ff7a5b4, 0x3ae118ab),
+ TOBN(0x3cce53f1, 0xcd871236), TOBN(0xf156a39d, 0xc2aa6d52),
+ TOBN(0x9cc5f271, 0xb198d76d), TOBN(0xbc615b6f, 0x81383d39),
+ TOBN(0xa54538e8, 0xde3eee6b), TOBN(0x58c77538, 0xab910d91),
+ TOBN(0x31e5bdbc, 0x58d278bd), TOBN(0x3cde4adf, 0xb963acae),
+ TOBN(0xb1881fd2, 0x5302169c), TOBN(0x8ca60fa0, 0xa989ed8b),
+ TOBN(0xa1999458, 0xff96a0ee), TOBN(0xc1141f03, 0xac6c283d),
+ TOBN(0x7677408d, 0x6dfafed3), TOBN(0x33a01653, 0x39661588),
+ TOBN(0x3c9c15ec, 0x0b726fa0), TOBN(0x090cfd93, 0x6c9b56da),
+ TOBN(0xe34f4bae, 0xa3c40af5), TOBN(0x3469eadb, 0xd21129f1),
+ TOBN(0xcc51674a, 0x1e207ce8), TOBN(0x1e293b24, 0xc83b1ef9),
+ TOBN(0x17173d13, 0x1e6c0bb4), TOBN(0x19004695, 0x90776d35),
+ TOBN(0xe7980e34, 0x6de6f922), TOBN(0x873554cb, 0xf4dd9a22),
+ TOBN(0x0316c627, 0xcbf18a51), TOBN(0x4d93651b, 0x3032c081),
+ TOBN(0x207f2771, 0x3946834d), TOBN(0x2c08d7b4, 0x30cdbf80),
+ TOBN(0x137a4fb4, 0x86df2a61), TOBN(0xa1ed9c07, 0xecf7b4a2),
+ TOBN(0xb2e460e2, 0x7bd042ff), TOBN(0xb7f5e2fa, 0x5f62f5ec),
+ TOBN(0x7aa6ec6b, 0xcc2423b7), TOBN(0x75ce0a7f, 0xba63eea7),
+ TOBN(0x67a45fb1, 0xf250a6e1), TOBN(0x93bc919c, 0xe53cdc9f),
+ TOBN(0x9271f56f, 0x871942df), TOBN(0x2372ff6f, 0x7859ad66),
+ TOBN(0x5f4c2b96, 0x33cb1a78), TOBN(0xe3e29101, 0x5838aa83),
+ TOBN(0xa7ed1611, 0xe4e8110c), TOBN(0x2a2d70d5, 0x330198ce),
+ TOBN(0xbdf132e8, 0x6720efe0), TOBN(0xe61a8962, 0x66a471bf),
+ TOBN(0x796d3a85, 0x825808bd), TOBN(0x51dc3cb7, 0x3fd6e902),
+ TOBN(0x643c768a, 0x916219d1), TOBN(0x36cd7685, 0xa2ad7d32),
+ TOBN(0xe3db9d05, 0xb22922a4), TOBN(0x6494c87e, 0xdba29660),
+ TOBN(0xf0ac91df, 0xbcd2ebc7), TOBN(0x4deb57a0, 0x45107f8d),
+ TOBN(0x42271f59, 0xc3d12a73), TOBN(0x5f71687c, 0xa5c2c51d),
+ TOBN(0xcb1f50c6, 0x05797bcb), TOBN(0x29ed0ed9, 0xd6d34eb0),
+ TOBN(0xe5fe5b47, 0x4683c2eb), TOBN(0x4956eeb5, 0x97447c46),
+ TOBN(0x5b163a43, 0x71207167), TOBN(0x93fa2fed, 0x0248c5ef),
+ TOBN(0x67930af2, 0x31f63950), TOBN(0xa77797c1, 0x14caa2c9),
+ TOBN(0x526e80ee, 0x27ac7e62), TOBN(0xe1e6e626, 0x58b28aec),
+ TOBN(0x636178b0, 0xb3c9fef0), TOBN(0xaf7752e0, 0x6d5f90be),
+ TOBN(0x94ecaf18, 0xeece51cf), TOBN(0x2864d0ed, 0xca806e1f),
+ TOBN(0x6de2e383, 0x97c69134), TOBN(0x5a42c316, 0xeb291293),
+ TOBN(0xc7779219, 0x6a60bae0), TOBN(0xa24de346, 0x6b7599d1),
+ TOBN(0x49d374aa, 0xb75d4941), TOBN(0x98900586, 0x2d501ff0),
+ TOBN(0x9f16d40e, 0xeb7974cf), TOBN(0x1033860b, 0xcdd8c115),
+ TOBN(0xb6c69ac8, 0x2094cec3), TOBN(0x9976fb88, 0x403b770c),
+ TOBN(0x1dea026c, 0x4859590d), TOBN(0xb6acbb46, 0x8562d1fd),
+ TOBN(0x7cd6c461, 0x44569d85), TOBN(0xc3190a36, 0x97f0891d),
+ TOBN(0xc6f53195, 0x48d5a17d), TOBN(0x7d919966, 0xd749abc8),
+ TOBN(0x65104837, 0xdd1c8a20), TOBN(0x7e5410c8, 0x2f683419),
+ TOBN(0x958c3ca8, 0xbe94022e), TOBN(0x605c3197, 0x6145dac2),
+ TOBN(0x3fc07501, 0x01683d54), TOBN(0x1d7127c5, 0x595b1234),
+ TOBN(0x10b8f87c, 0x9481277f), TOBN(0x677db2a8, 0xe65a1adb),
+ TOBN(0xec2fccaa, 0xddce3345), TOBN(0x2a6811b7, 0x012a4350),
+ TOBN(0x96760ff1, 0xac598bdc), TOBN(0x054d652a, 0xd1bf4128),
+ TOBN(0x0a1151d4, 0x92a21005), TOBN(0xad7f3971, 0x33110fdf),
+ TOBN(0x8c95928c, 0x1960100f), TOBN(0x6c91c825, 0x7bf03362),
+ TOBN(0xc8c8b2a2, 0xce309f06), TOBN(0xfdb27b59, 0xca27204b),
+ TOBN(0xd223eaa5, 0x0848e32e), TOBN(0xb93e4b2e, 0xe7bfaf1e),
+ TOBN(0xc5308ae6, 0x44aa3ded), TOBN(0x317a666a, 0xc015d573),
+ TOBN(0xc888ce23, 0x1a979707), TOBN(0xf141c1e6, 0x0d5c4958),
+ TOBN(0xb53b7de5, 0x61906373), TOBN(0x858dbade, 0xeb999595),
+ TOBN(0x8cbb47b2, 0xa59e5c36), TOBN(0x660318b3, 0xdcf4e842),
+ TOBN(0xbd161ccd, 0x12ba4b7a), TOBN(0xf399daab, 0xf8c8282a),
+ TOBN(0x1587633a, 0xeeb2130d), TOBN(0xa465311a, 0xda38dd7d),
+ TOBN(0x5f75eec8, 0x64d3779b), TOBN(0x3c5d0476, 0xad64c171),
+ TOBN(0x87410371, 0x2a914428), TOBN(0x8096a891, 0x90e2fc29),
+ TOBN(0xd3d2ae9d, 0x23b3ebc2), TOBN(0x90bdd6db, 0xa580cfd6),
+ TOBN(0x52dbb7f3, 0xc5b01f6c), TOBN(0xe68eded4, 0xe102a2dc),
+ TOBN(0x17785b77, 0x99eb6df0), TOBN(0x26c3cc51, 0x7386b779),
+ TOBN(0x345ed988, 0x6417a48e), TOBN(0xe990b4e4, 0x07d6ef31),
+ TOBN(0x0f456b7e, 0x2586abba), TOBN(0x239ca6a5, 0x59c96e9a),
+ TOBN(0xe327459c, 0xe2eb4206), TOBN(0x3a4c3313, 0xa002b90a),
+ TOBN(0x2a114806, 0xf6a3f6fb), TOBN(0xad5cad2f, 0x85c251dd),
+ TOBN(0x92c1f613, 0xf5a784d3), TOBN(0xec7bfacf, 0x349766d5),
+ TOBN(0x04b3cd33, 0x3e23cb3b), TOBN(0x3979fe84, 0xc5a64b2d),
+ TOBN(0x192e2720, 0x7e589106), TOBN(0xa60c43d1, 0xa15b527f),
+ TOBN(0x2dae9082, 0xbe7cf3a6), TOBN(0xcc86ba92, 0xbc967274),
+ TOBN(0xf28a2ce8, 0xaea0a8a9), TOBN(0x404ca6d9, 0x6ee988b3),
+ TOBN(0xfd7e9c5d, 0x005921b8), TOBN(0xf56297f1, 0x44e79bf9),
+ TOBN(0xa163b460, 0x0d75ddc2), TOBN(0x30b23616, 0xa1f2be87),
+ TOBN(0x4b070d21, 0xbfe50e2b), TOBN(0x7ef8cfd0, 0xe1bfede1),
+ TOBN(0xadba0011, 0x2aac4ae0), TOBN(0x2a3e7d01, 0xb9ebd033),
+ TOBN(0x995277ec, 0xe38d9d1c), TOBN(0xb500249e, 0x9c5d2de3),
+ TOBN(0x8912b820, 0xf13ca8c9), TOBN(0xc8798114, 0x877793af),
+ TOBN(0x19e6125d, 0xec3f1dec), TOBN(0x07b1f040, 0x911178da),
+ TOBN(0xd93ededa, 0x904a6738), TOBN(0x55187a5a, 0x0bebedcd),
+ TOBN(0xf7d04722, 0xeb329d41), TOBN(0xf449099e, 0xf170b391),
+ TOBN(0xfd317a69, 0xca99f828), TOBN(0x50c3db2b, 0x34a4976d),
+ TOBN(0xe9ba7784, 0x3757b392), TOBN(0x326caefd, 0xaa3ca05a),
+ TOBN(0x78e5293b, 0xf1e593d4), TOBN(0x7842a937, 0x0d98fd13),
+ TOBN(0xe694bf96, 0x5f96b10d), TOBN(0x373a9df6, 0x06a8cd05),
+ TOBN(0x997d1e51, 0xe8f0c7fc), TOBN(0x1d019790, 0x63fd972e),
+ TOBN(0x0064d858, 0x5499fb32), TOBN(0x7b67bad9, 0x77a8aeb7),
+ TOBN(0x1d3eb977, 0x2d08eec5), TOBN(0x5fc047a6, 0xcbabae1d),
+ TOBN(0x0577d159, 0xe54a64bb), TOBN(0x8862201b, 0xc43497e4),
+ TOBN(0xad6b4e28, 0x2ce0608d), TOBN(0x8b687b7d, 0x0b167aac),
+ TOBN(0x6ed4d367, 0x8b2ecfa9), TOBN(0x24dfe62d, 0xa90c3c38),
+ TOBN(0xa1862e10, 0x3fe5c42b), TOBN(0x1ca73dca, 0xd5732a9f),
+ TOBN(0x35f038b7, 0x76bb87ad), TOBN(0x674976ab, 0xf242b81f),
+ TOBN(0x4f2bde7e, 0xb0fd90cd), TOBN(0x6efc172e, 0xa7fdf092),
+ TOBN(0x3806b69b, 0x92222f1f), TOBN(0x5a2459ca, 0x6cf7ae70),
+ TOBN(0x6789f69c, 0xa85217ee), TOBN(0x5f232b5e, 0xe3dc85ac),
+ TOBN(0x660e3ec5, 0x48e9e516), TOBN(0x124b4e47, 0x3197eb31),
+ TOBN(0x10a0cb13, 0xaafcca23), TOBN(0x7bd63ba4, 0x8213224f),
+ TOBN(0xaffad7cc, 0x290a7f4f), TOBN(0x6b409c9e, 0x0286b461),
+ TOBN(0x58ab809f, 0xffa407af), TOBN(0xc3122eed, 0xc68ac073),
+ TOBN(0x17bf9e50, 0x4ef24d7e), TOBN(0x5d929794, 0x3e2a5811),
+ TOBN(0x519bc867, 0x02902e01), TOBN(0x76bba5da, 0x39c8a851),
+ TOBN(0xe9f9669c, 0xda94951e), TOBN(0x4b6af58d, 0x66b8d418),
+ TOBN(0xfa321074, 0x17d426a4), TOBN(0xc78e66a9, 0x9dde6027),
+ TOBN(0x0516c083, 0x4a53b964), TOBN(0xfc659d38, 0xff602330),
+ TOBN(0x0ab55e5c, 0x58c5c897), TOBN(0x985099b2, 0x838bc5df),
+ TOBN(0x061d9efc, 0xc52fc238), TOBN(0x712b2728, 0x6ac1da3f),
+ TOBN(0xfb658149, 0x9283fe08), TOBN(0x4954ac94, 0xb8aaa2f7),
+ TOBN(0x85c0ada4, 0x7fb2e74f), TOBN(0xee8ba98e, 0xb89926b0),
+ TOBN(0xe4f9d37d, 0x23d1af5b), TOBN(0x14ccdbf9, 0xba9b015e),
+ TOBN(0xb674481b, 0x7bfe7178), TOBN(0x4e1debae, 0x65405868),
+ TOBN(0x061b2821, 0xc48c867d), TOBN(0x69c15b35, 0x513b30ea),
+ TOBN(0x3b4a1666, 0x36871088), TOBN(0xe5e29f5d, 0x1220b1ff),
+ TOBN(0x4b82bb35, 0x233d9f4d), TOBN(0x4e076333, 0x18cdc675)},
+ {TOBN(0x0d53f5c7, 0xa3e6fced), TOBN(0xe8cbbdd5, 0xf45fbdeb),
+ TOBN(0xf85c01df, 0x13339a70), TOBN(0x0ff71880, 0x142ceb81),
+ TOBN(0x4c4e8774, 0xbd70437a), TOBN(0x5fb32891, 0xba0bda6a),
+ TOBN(0x1cdbebd2, 0xf18bd26e), TOBN(0x2f9526f1, 0x03a9d522),
+ TOBN(0x40ce3051, 0x92c4d684), TOBN(0x8b04d725, 0x7612efcd),
+ TOBN(0xb9dcda36, 0x6f9cae20), TOBN(0x0edc4d24, 0xf058856c),
+ TOBN(0x64f2e6bf, 0x85427900), TOBN(0x3de81295, 0xdc09dfea),
+ TOBN(0xd41b4487, 0x379bf26c), TOBN(0x50b62c6d, 0x6df135a9),
+ TOBN(0xd4f8e3b4, 0xc72dfe67), TOBN(0xc416b0f6, 0x90e19fdf),
+ TOBN(0x18b9098d, 0x4c13bd35), TOBN(0xac11118a, 0x15b8cb9e),
+ TOBN(0xf598a318, 0xf0062841), TOBN(0xbfe0602f, 0x89f356f4),
+ TOBN(0x7ae3637e, 0x30177a0c), TOBN(0x34097747, 0x61136537),
+ TOBN(0x0db2fb5e, 0xd005832a), TOBN(0x5f5efd3b, 0x91042e4f),
+ TOBN(0x8c4ffdc6, 0xed70f8ca), TOBN(0xe4645d0b, 0xb52da9cc),
+ TOBN(0x9596f58b, 0xc9001d1f), TOBN(0x52c8f0bc, 0x4e117205),
+ TOBN(0xfd4aa0d2, 0xe398a084), TOBN(0x815bfe3a, 0x104f49de),
+ TOBN(0x97e5443f, 0x23885e5f), TOBN(0xf72f8f99, 0xe8433aab),
+ TOBN(0xbd00b154, 0xe4d4e604), TOBN(0xd0b35e6a, 0xe5e173ff),
+ TOBN(0x57b2a048, 0x9164722d), TOBN(0x3e3c665b, 0x88761ec8),
+ TOBN(0x6bdd1397, 0x3da83832), TOBN(0x3c8b1a1e, 0x73dafe3b),
+ TOBN(0x4497ace6, 0x54317cac), TOBN(0xbe600ab9, 0x521771b3),
+ TOBN(0xb42e409e, 0xb0dfe8b8), TOBN(0x386a67d7, 0x3942310f),
+ TOBN(0x25548d8d, 0x4431cc28), TOBN(0xa7cff142, 0x985dc524),
+ TOBN(0x4d60f5a1, 0x93c4be32), TOBN(0x83ebd5c8, 0xd071c6e1),
+ TOBN(0xba3a80a7, 0xb1fd2b0b), TOBN(0x9b3ad396, 0x5bec33e8),
+ TOBN(0xb3868d61, 0x79743fb3), TOBN(0xcfd169fc, 0xfdb462fa),
+ TOBN(0xd3b499d7, 0x9ce0a6af), TOBN(0x55dc1cf1, 0xe42d3ff8),
+ TOBN(0x04fb9e6c, 0xc6c3e1b2), TOBN(0x47e6961d, 0x6f69a474),
+ TOBN(0x54eb3acc, 0xe548b37b), TOBN(0xb38e7542, 0x84d40549),
+ TOBN(0x8c3daa51, 0x7b341b4f), TOBN(0x2f6928ec, 0x690bf7fa),
+ TOBN(0x0496b323, 0x86ce6c41), TOBN(0x01be1c55, 0x10adadcd),
+ TOBN(0xc04e67e7, 0x4bb5faf9), TOBN(0x3cbaf678, 0xe15c9985),
+ TOBN(0x8cd12145, 0x50ca4247), TOBN(0xba1aa47a, 0xe7dd30aa),
+ TOBN(0x2f81ddf1, 0xe58fee24), TOBN(0x03452936, 0xeec9b0e8),
+ TOBN(0x8bdc3b81, 0x243aea96), TOBN(0x9a2919af, 0x15c3d0e5),
+ TOBN(0x9ea640ec, 0x10948361), TOBN(0x5ac86d5b, 0x6e0bcccf),
+ TOBN(0xf892d918, 0xc36cf440), TOBN(0xaed3e837, 0xc939719c),
+ TOBN(0xb07b08d2, 0xc0218b64), TOBN(0x6f1bcbba, 0xce9790dd),
+ TOBN(0x4a84d6ed, 0x60919b8e), TOBN(0xd8900791, 0x8ac1f9eb),
+ TOBN(0xf84941aa, 0x0dd5daef), TOBN(0xb22fe40a, 0x67fd62c5),
+ TOBN(0x97e15ba2, 0x157f2db3), TOBN(0xbda2fc8f, 0x8e28ca9c),
+ TOBN(0x5d050da4, 0x37b9f454), TOBN(0x3d57eb57, 0x2379d72e),
+ TOBN(0xe9b5eba2, 0xfb5ee997), TOBN(0x01648ca2, 0xe11538ca),
+ TOBN(0x32bb76f6, 0xf6327974), TOBN(0x338f14b8, 0xff3f4bb7),
+ TOBN(0x524d226a, 0xd7ab9a2d), TOBN(0x9c00090d, 0x7dfae958),
+ TOBN(0x0ba5f539, 0x8751d8c2), TOBN(0x8afcbcdd, 0x3ab8262d),
+ TOBN(0x57392729, 0xe99d043b), TOBN(0xef51263b, 0xaebc943a),
+ TOBN(0x9feace93, 0x20862935), TOBN(0x639efc03, 0xb06c817b),
+ TOBN(0x1fe054b3, 0x66b4be7a), TOBN(0x3f25a9de, 0x84a37a1e),
+ TOBN(0xf39ef1ad, 0x78d75cd9), TOBN(0xd7b58f49, 0x5062c1b5),
+ TOBN(0x6f74f9a9, 0xff563436), TOBN(0xf718ff29, 0xe8af51e7),
+ TOBN(0x5234d313, 0x15e97fec), TOBN(0xb6a8e2b1, 0x292f1c0a),
+ TOBN(0xa7f53aa8, 0x327720c1), TOBN(0x956ca322, 0xba092cc8),
+ TOBN(0x8f03d64a, 0x28746c4d), TOBN(0x51fe1782, 0x66d0d392),
+ TOBN(0xd19b34db, 0x3c832c80), TOBN(0x60dccc5c, 0x6da2e3b4),
+ TOBN(0x245dd62e, 0x0a104ccc), TOBN(0xa7ab1de1, 0x620b21fd),
+ TOBN(0xb293ae0b, 0x3893d123), TOBN(0xf7b75783, 0xb15ee71c),
+ TOBN(0x5aa3c614, 0x42a9468b), TOBN(0xd686123c, 0xdb15d744),
+ TOBN(0x8c616891, 0xa7ab4116), TOBN(0x6fcd72c8, 0xa4e6a459),
+ TOBN(0xac219110, 0x77e5fad7), TOBN(0xfb6a20e7, 0x704fa46b),
+ TOBN(0xe839be7d, 0x341d81dc), TOBN(0xcddb6889, 0x32148379),
+ TOBN(0xda6211a1, 0xf7026ead), TOBN(0xf3b2575f, 0xf4d1cc5e),
+ TOBN(0x40cfc8f6, 0xa7a73ae6), TOBN(0x83879a5e, 0x61d5b483),
+ TOBN(0xc5acb1ed, 0x41a50ebc), TOBN(0x59a60cc8, 0x3c07d8fa),
+ TOBN(0x1b73bdce, 0xb1876262), TOBN(0x2b0d79f0, 0x12af4ee9),
+ TOBN(0x8bcf3b0b, 0xd46e1d07), TOBN(0x17d6af9d, 0xe45d152f),
+ TOBN(0x73520461, 0x6d736451), TOBN(0x43cbbd97, 0x56b0bf5a),
+ TOBN(0xb0833a5b, 0xd5999b9d), TOBN(0x702614f0, 0xeb72e398),
+ TOBN(0x0aadf01a, 0x59c3e9f8), TOBN(0x40200e77, 0xce6b3d16),
+ TOBN(0xda22bdd3, 0xdeddafad), TOBN(0x76dedaf4, 0x310d72e1),
+ TOBN(0x49ef807c, 0x4bc2e88f), TOBN(0x6ba81291, 0x146dd5a5),
+ TOBN(0xa1a4077a, 0x7d8d59e9), TOBN(0x87b6a2e7, 0x802db349),
+ TOBN(0xd5679997, 0x1b4e598e), TOBN(0xf499ef1f, 0x06fe4b1d),
+ TOBN(0x3978d3ae, 0xfcb267c5), TOBN(0xb582b557, 0x235786d0),
+ TOBN(0x32b3b2ca, 0x1715cb07), TOBN(0x4c3de6a2, 0x8480241d),
+ TOBN(0x63b5ffed, 0xcb571ecd), TOBN(0xeaf53900, 0xed2fe9a9),
+ TOBN(0xdec98d4a, 0xc3b81990), TOBN(0x1cb83722, 0x9e0cc8fe),
+ TOBN(0xfe0b0491, 0xd2b427b9), TOBN(0x0f2386ac, 0xe983a66c),
+ TOBN(0x930c4d1e, 0xb3291213), TOBN(0xa2f82b2e, 0x59a62ae4),
+ TOBN(0x77233853, 0xf93e89e3), TOBN(0x7f8063ac, 0x11777c7f),
+ TOBN(0xff0eb567, 0x59ad2877), TOBN(0x6f454642, 0x9865c754),
+ TOBN(0xe6fe701a, 0x236e9a84), TOBN(0xc586ef16, 0x06e40fc3),
+ TOBN(0x3f62b6e0, 0x24bafad9), TOBN(0xc8b42bd2, 0x64da906a),
+ TOBN(0xc98e1eb4, 0xda3276a0), TOBN(0x30d0e5fc, 0x06cbf852),
+ TOBN(0x1b6b2ae1, 0xe8b4dfd4), TOBN(0xd754d5c7, 0x8301cbac),
+ TOBN(0x66097629, 0x112a39ac), TOBN(0xf86b5999, 0x93ba4ab9),
+ TOBN(0x26c9dea7, 0x99f9d581), TOBN(0x0473b1a8, 0xc2fafeaa),
+ TOBN(0x1469af55, 0x3b2505a5), TOBN(0x227d16d7, 0xd6a43323),
+ TOBN(0x3316f73c, 0xad3d97f9), TOBN(0x52bf3bb5, 0x1f137455),
+ TOBN(0x953eafeb, 0x09954e7c), TOBN(0xa721dfed, 0xdd732411),
+ TOBN(0xb4929821, 0x141d4579), TOBN(0x3411321c, 0xaa3bd435),
+ TOBN(0xafb355aa, 0x17fa6015), TOBN(0xb4e7ef4a, 0x18e42f0e),
+ TOBN(0x604ac97c, 0x59371000), TOBN(0xe1c48c70, 0x7f759c18),
+ TOBN(0x3f62ecc5, 0xa5db6b65), TOBN(0x0a78b173, 0x38a21495),
+ TOBN(0x6be1819d, 0xbcc8ad94), TOBN(0x70dc04f6, 0xd89c3400),
+ TOBN(0x462557b4, 0xa6b4840a), TOBN(0x544c6ade, 0x60bd21c0),
+ TOBN(0x6a00f24e, 0x907a544b), TOBN(0xa7520dcb, 0x313da210),
+ TOBN(0xfe939b75, 0x11e4994b), TOBN(0x918b6ba6, 0xbc275d70),
+ TOBN(0xd3e5e0fc, 0x644be892), TOBN(0x707a9816, 0xfdaf6c42),
+ TOBN(0x60145567, 0xf15c13fe), TOBN(0x4818ebaa, 0xe130a54a),
+ TOBN(0x28aad3ad, 0x58d2f767), TOBN(0xdc5267fd, 0xd7e7c773),
+ TOBN(0x4919cc88, 0xc3afcc98), TOBN(0xaa2e6ab0, 0x2db8cd4b),
+ TOBN(0xd46fec04, 0xd0c63eaa), TOBN(0xa1cb92c5, 0x19ffa832),
+ TOBN(0x678dd178, 0xe43a631f), TOBN(0xfb5ae1cd, 0x3dc788b3),
+ TOBN(0x68b4fb90, 0x6e77de04), TOBN(0x7992bcf0, 0xf06dbb97),
+ TOBN(0x896e6a13, 0xc417c01d), TOBN(0x8d96332c, 0xb956be01),
+ TOBN(0x902fc93a, 0x413aa2b9), TOBN(0x99a4d915, 0xfc98c8a5),
+ TOBN(0x52c29407, 0x565f1137), TOBN(0x4072690f, 0x21e4f281),
+ TOBN(0x36e607cf, 0x02ff6072), TOBN(0xa47d2ca9, 0x8ad98cdc),
+ TOBN(0xbf471d1e, 0xf5f56609), TOBN(0xbcf86623, 0xf264ada0),
+ TOBN(0xb70c0687, 0xaa9e5cb6), TOBN(0xc98124f2, 0x17401c6c),
+ TOBN(0x8189635f, 0xd4a61435), TOBN(0xd28fb8af, 0xa9d98ea6),
+ TOBN(0xb9a67c2a, 0x40c251f8), TOBN(0x88cd5d87, 0xa2da44be),
+ TOBN(0x437deb96, 0xe09b5423), TOBN(0x150467db, 0x64287dc1),
+ TOBN(0xe161debb, 0xcdabb839), TOBN(0xa79e9742, 0xf1839a3e),
+ TOBN(0xbb8dd3c2, 0x652d202b), TOBN(0x7b3e67f7, 0xe9f97d96),
+ TOBN(0x5aa5d78f, 0xb1cb6ac9), TOBN(0xffa13e8e, 0xca1d0d45),
+ TOBN(0x369295dd, 0x2ba5bf95), TOBN(0xd68bd1f8, 0x39aff05e),
+ TOBN(0xaf0d86f9, 0x26d783f2), TOBN(0x543a59b3, 0xfc3aafc1),
+ TOBN(0x3fcf81d2, 0x7b7da97c), TOBN(0xc990a056, 0xd25dee46),
+ TOBN(0x3e6775b8, 0x519cce2c), TOBN(0xfc9af71f, 0xae13d863),
+ TOBN(0x774a4a6f, 0x47c1605c), TOBN(0x46ba4245, 0x2fd205e8),
+ TOBN(0xa06feea4, 0xd3fd524d), TOBN(0x1e724641, 0x6de1acc2),
+ TOBN(0xf53816f1, 0x334e2b42), TOBN(0x49e5918e, 0x922f0024),
+ TOBN(0x439530b6, 0x65c7322d), TOBN(0xcf12cc01, 0xb3c1b3fb),
+ TOBN(0xc70b0186, 0x0172f685), TOBN(0xb915ee22, 0x1b58391d),
+ TOBN(0x9afdf03b, 0xa317db24), TOBN(0x87dec659, 0x17b8ffc4),
+ TOBN(0x7f46597b, 0xe4d3d050), TOBN(0x80a1c1ed, 0x006500e7),
+ TOBN(0x84902a96, 0x78bf030e), TOBN(0xfb5e9c9a, 0x50560148),
+ TOBN(0x6dae0a92, 0x63362426), TOBN(0xdcaeecf4, 0xa9e30c40),
+ TOBN(0xc0d887bb, 0x518d0c6b), TOBN(0x99181152, 0xcb985b9d),
+ TOBN(0xad186898, 0xef7bc381), TOBN(0x18168ffb, 0x9ee46201),
+ TOBN(0x9a04cdaa, 0x2502753c), TOBN(0xbb279e26, 0x51407c41),
+ TOBN(0xeacb03aa, 0xf23564e5), TOBN(0x18336582, 0x71e61016),
+ TOBN(0x8684b8c4, 0xeb809877), TOBN(0xb336e18d, 0xea0e672e),
+ TOBN(0xefb601f0, 0x34ee5867), TOBN(0x2733edbe, 0x1341cfd1),
+ TOBN(0xb15e809a, 0x26025c3c), TOBN(0xe6e981a6, 0x9350df88),
+ TOBN(0x92376237, 0x8502fd8e), TOBN(0x4791f216, 0x0c12be9b),
+ TOBN(0xb7256789, 0x25f02425), TOBN(0xec863194, 0x7a974443),
+ TOBN(0x7c0ce882, 0xfb41cc52), TOBN(0xc266ff7e, 0xf25c07f2),
+ TOBN(0x3d4da8c3, 0x017025f3), TOBN(0xefcf628c, 0xfb9579b4),
+ TOBN(0x5c4d0016, 0x1f3716ec), TOBN(0x9c27ebc4, 0x6801116e),
+ TOBN(0x5eba0ea1, 0x1da1767e), TOBN(0xfe151452, 0x47004c57),
+ TOBN(0x3ace6df6, 0x8c2373b7), TOBN(0x75c3dffe, 0x5dbc37ac),
+ TOBN(0x3dc32a73, 0xddc925fc), TOBN(0xb679c841, 0x2f65ee0b),
+ TOBN(0x715a3295, 0x451cbfeb), TOBN(0xd9889768, 0xf76e9a29),
+ TOBN(0xec20ce7f, 0xb28ad247), TOBN(0xe99146c4, 0x00894d79),
+ TOBN(0x71457d7c, 0x9f5e3ea7), TOBN(0x097b2662, 0x38030031),
+ TOBN(0xdb7f6ae6, 0xcf9f82a8), TOBN(0x319decb9, 0x438f473a),
+ TOBN(0xa63ab386, 0x283856c3), TOBN(0x13e3172f, 0xb06a361b),
+ TOBN(0x2959f8dc, 0x7d5a006c), TOBN(0x2dbc27c6, 0x75fba752),
+ TOBN(0xc1227ab2, 0x87c22c9e), TOBN(0x06f61f75, 0x71a268b2),
+ TOBN(0x1b6bb971, 0x04779ce2), TOBN(0xaca83812, 0x0aadcb1d),
+ TOBN(0x297ae0bc, 0xaeaab2d5), TOBN(0xa5c14ee7, 0x5bfb9f13),
+ TOBN(0xaa00c583, 0xf17a62c7), TOBN(0x39eb962c, 0x173759f6),
+ TOBN(0x1eeba1d4, 0x86c9a88f), TOBN(0x0ab6c37a, 0xdf016c5e),
+ TOBN(0xa2a147db, 0xa28a0749), TOBN(0x246c20d6, 0xee519165),
+ TOBN(0x5068d1b1, 0xd3810715), TOBN(0xb1e7018c, 0x748160b9),
+ TOBN(0x03f5b1fa, 0xf380ff62), TOBN(0xef7fb1dd, 0xf3cb2c1e),
+ TOBN(0xeab539a8, 0xfc91a7da), TOBN(0x83ddb707, 0xf3f9b561),
+ TOBN(0xc550e211, 0xfe7df7a4), TOBN(0xa7cd07f2, 0x063f6f40),
+ TOBN(0xb0de3635, 0x2976879c), TOBN(0xb5f83f85, 0xe55741da),
+ TOBN(0x4ea9d25e, 0xf3d8ac3d), TOBN(0x6fe2066f, 0x62819f02),
+ TOBN(0x4ab2b9c2, 0xcef4a564), TOBN(0x1e155d96, 0x5ffa2de3),
+ TOBN(0x0eb0a19b, 0xc3a72d00), TOBN(0x4037665b, 0x8513c31b),
+ TOBN(0x2fb2b6bf, 0x04c64637), TOBN(0x45c34d6e, 0x08cdc639),
+ TOBN(0x56f1e10f, 0xf01fd796), TOBN(0x4dfb8101, 0xfe3667b8),
+ TOBN(0xe0eda253, 0x9021d0c0), TOBN(0x7a94e9ff, 0x8a06c6ab),
+ TOBN(0x2d3bb0d9, 0xbb9aa882), TOBN(0xea20e4e5, 0xec05fd10),
+ TOBN(0xed7eeb5f, 0x1a1ca64e), TOBN(0x2fa6b43c, 0xc6327cbd),
+ TOBN(0xb577e3cf, 0x3aa91121), TOBN(0x8c6bd5ea, 0x3a34079b),
+ TOBN(0xd7e5ba39, 0x60e02fc0), TOBN(0xf16dd2c3, 0x90141bf8),
+ TOBN(0xb57276d9, 0x80101b98), TOBN(0x760883fd, 0xb82f0f66),
+ TOBN(0x89d7de75, 0x4bc3eff3), TOBN(0x03b60643, 0x5dc2ab40),
+ TOBN(0xcd6e53df, 0xe05beeac), TOBN(0xf2f1e862, 0xbc3325cd),
+ TOBN(0xdd0f7921, 0x774f03c3), TOBN(0x97ca7221, 0x4552cc1b),
+ TOBN(0x5a0d6afe, 0x1cd19f72), TOBN(0xa20915dc, 0xf183fbeb),
+ TOBN(0x9fda4b40, 0x832c403c), TOBN(0x32738edd, 0xbe425442),
+ TOBN(0x469a1df6, 0xb5eccf1a), TOBN(0x4b5aff42, 0x28bbe1f0),
+ TOBN(0x31359d7f, 0x570dfc93), TOBN(0xa18be235, 0xf0088628),
+ TOBN(0xa5b30fba, 0xb00ed3a9), TOBN(0x34c61374, 0x73cdf8be),
+ TOBN(0x2c5c5f46, 0xabc56797), TOBN(0x5cecf93d, 0xb82a8ae2),
+ TOBN(0x7d3dbe41, 0xa968fbf0), TOBN(0xd23d4583, 0x1a5c7f3d),
+ TOBN(0xf28f69a0, 0xc087a9c7), TOBN(0xc2d75471, 0x474471ca),
+ TOBN(0x36ec9f4a, 0x4eb732ec), TOBN(0x6c943bbd, 0xb1ca6bed),
+ TOBN(0xd64535e1, 0xf2457892), TOBN(0x8b84a8ea, 0xf7e2ac06),
+ TOBN(0xe0936cd3, 0x2499dd5f), TOBN(0x12053d7e, 0x0ed04e57),
+ TOBN(0x4bdd0076, 0xe4305d9d), TOBN(0x34a527b9, 0x1f67f0a2),
+ TOBN(0xe79a4af0, 0x9cec46ea), TOBN(0xb15347a1, 0x658b9bc7),
+ TOBN(0x6bd2796f, 0x35af2f75), TOBN(0xac957990, 0x4051c435),
+ TOBN(0x2669dda3, 0xc33a655d), TOBN(0x5d503c2e, 0x88514aa3),
+ TOBN(0xdfa11337, 0x3753dd41), TOBN(0x3f054673, 0x0b754f78),
+ TOBN(0xbf185677, 0x496125bd), TOBN(0xfb0023c8, 0x3775006c),
+ TOBN(0xfa0f072f, 0x3a037899), TOBN(0x4222b6eb, 0x0e4aea57),
+ TOBN(0x3dde5e76, 0x7866d25a), TOBN(0xb6eb04f8, 0x4837aa6f),
+ TOBN(0x5315591a, 0x2cf1cdb8), TOBN(0x6dfb4f41, 0x2d4e683c),
+ TOBN(0x7e923ea4, 0x48ee1f3a), TOBN(0x9604d9f7, 0x05a2afd5),
+ TOBN(0xbe1d4a33, 0x40ea4948), TOBN(0x5b45f1f4, 0xb44cbd2f),
+ TOBN(0x5faf8376, 0x4acc757e), TOBN(0xa7cf9ab8, 0x63d68ff7),
+ TOBN(0x8ad62f69, 0xdf0e404b), TOBN(0xd65f33c2, 0x12bdafdf),
+ TOBN(0xc365de15, 0xa377b14e), TOBN(0x6bf5463b, 0x8e39f60c),
+ TOBN(0x62030d2d, 0x2ce68148), TOBN(0xd95867ef, 0xe6f843a8),
+ TOBN(0xd39a0244, 0xef5ab017), TOBN(0x0bd2d8c1, 0x4ab55d12),
+ TOBN(0xc9503db3, 0x41639169), TOBN(0x2d4e25b0, 0xf7660c8a),
+ TOBN(0x760cb3b5, 0xe224c5d7), TOBN(0xfa3baf8c, 0x68616919),
+ TOBN(0x9fbca113, 0x8d142552), TOBN(0x1ab18bf1, 0x7669ebf5),
+ TOBN(0x55e6f53e, 0x9bdf25dd), TOBN(0x04cc0bf3, 0xcb6cd154),
+ TOBN(0x595bef49, 0x95e89080), TOBN(0xfe9459a8, 0x104a9ac1),
+ TOBN(0xad2d89ca, 0xcce9bb32), TOBN(0xddea65e1, 0xf7de8285),
+ TOBN(0x62ed8c35, 0xb351bd4b), TOBN(0x4150ff36, 0x0c0e19a7),
+ TOBN(0x86e3c801, 0x345f4e47), TOBN(0x3bf21f71, 0x203a266c),
+ TOBN(0x7ae110d4, 0x855b1f13), TOBN(0x5d6aaf6a, 0x07262517),
+ TOBN(0x1e0f12e1, 0x813d28f1), TOBN(0x6000e11d, 0x7ad7a523),
+ TOBN(0xc7d8deef, 0xc744a17b), TOBN(0x1e990b48, 0x14c05a00),
+ TOBN(0x68fddaee, 0x93e976d5), TOBN(0x696241d1, 0x46610d63),
+ TOBN(0xb204e7c3, 0x893dda88), TOBN(0x8bccfa65, 0x6a3a6946),
+ TOBN(0xb59425b4, 0xc5cd1411), TOBN(0x701b4042, 0xff3658b1),
+ TOBN(0xe3e56bca, 0x4784cf93), TOBN(0x27de5f15, 0x8fe68d60),
+ TOBN(0x4ab9cfce, 0xf8d53f19), TOBN(0xddb10311, 0xa40a730d),
+ TOBN(0x6fa73cd1, 0x4eee0a8a), TOBN(0xfd548748, 0x5249719d),
+ TOBN(0x49d66316, 0xa8123ef0), TOBN(0x73c32db4, 0xe7f95438),
+ TOBN(0x2e2ed209, 0x0d9e7854), TOBN(0xf98a9329, 0x9d9f0507),
+ TOBN(0xc5d33cf6, 0x0c6aa20a), TOBN(0x9a32ba14, 0x75279bb2),
+ TOBN(0x7e3202cb, 0x774a7307), TOBN(0x64ed4bc4, 0xe8c42dbd),
+ TOBN(0xc20f1a06, 0xd4caed0d), TOBN(0xb8021407, 0x171d22b3),
+ TOBN(0xd426ca04, 0xd13268d7), TOBN(0x92377007, 0x25f4d126),
+ TOBN(0x4204cbc3, 0x71f21a85), TOBN(0x18461b7a, 0xf82369ba),
+ TOBN(0xc0c07d31, 0x3fc858f9), TOBN(0x5deb5a50, 0xe2bab569),
+ TOBN(0xd5959d46, 0xd5eea89e), TOBN(0xfdff8424, 0x08437f4b),
+ TOBN(0xf21071e4, 0x3cfe254f), TOBN(0x72417696, 0x95468321),
+ TOBN(0x5d8288b9, 0x102cae3e), TOBN(0x2d143e3d, 0xf1965dff),
+ TOBN(0x00c9a376, 0xa078d847), TOBN(0x6fc0da31, 0x26028731),
+ TOBN(0xa2baeadf, 0xe45083a2), TOBN(0x66bc7218, 0x5e5b4bcd),
+ TOBN(0x2c826442, 0xd04b8e7f), TOBN(0xc19f5451, 0x6c4b586b),
+ TOBN(0x60182c49, 0x5b7eeed5), TOBN(0xd9954ecd, 0x7aa9dfa1),
+ TOBN(0xa403a8ec, 0xc73884ad), TOBN(0x7fb17de2, 0x9bb39041),
+ TOBN(0x694b64c5, 0xabb020e8), TOBN(0x3d18c184, 0x19c4eec7),
+ TOBN(0x9c4673ef, 0x1c4793e5), TOBN(0xc7b8aeb5, 0x056092e6),
+ TOBN(0x3aa1ca43, 0xf0f8c16b), TOBN(0x224ed5ec, 0xd679b2f6),
+ TOBN(0x0d56eeaf, 0x55a205c9), TOBN(0xbfe115ba, 0x4b8e028b),
+ TOBN(0x97e60849, 0x3927f4fe), TOBN(0xf91fbf94, 0x759aa7c5),
+ TOBN(0x985af769, 0x6be90a51), TOBN(0xc1277b78, 0x78ccb823),
+ TOBN(0x395b656e, 0xe7a75952), TOBN(0x00df7de0, 0x928da5f5),
+ TOBN(0x09c23175, 0x4ca4454f), TOBN(0x4ec971f4, 0x7aa2d3c1),
+ TOBN(0x45c3c507, 0xe75d9ccc), TOBN(0x63b7be8a, 0x3dc90306),
+ TOBN(0x37e09c66, 0x5db44bdc), TOBN(0x50d60da1, 0x6841c6a2),
+ TOBN(0x6f9b65ee, 0x08df1b12), TOBN(0x38734879, 0x7ff089df),
+ TOBN(0x9c331a66, 0x3fe8013d), TOBN(0x017f5de9, 0x5f42fcc8),
+ TOBN(0x43077866, 0xe8e57567), TOBN(0xc9f781ce, 0xf9fcdb18),
+ TOBN(0x38131dda, 0x9b12e174), TOBN(0x25d84aa3, 0x8a03752a),
+ TOBN(0x45e09e09, 0x4d0c0ce2), TOBN(0x1564008b, 0x92bebba5),
+ TOBN(0xf7e8ad31, 0xa87284c7), TOBN(0xb7c4b46c, 0x97e7bbaa),
+ TOBN(0x3e22a7b3, 0x97acf4ec), TOBN(0x0426c400, 0x5ea8b640),
+ TOBN(0x5e3295a6, 0x4e969285), TOBN(0x22aabc59, 0xa6a45670),
+ TOBN(0xb929714c, 0x5f5942bc), TOBN(0x9a6168bd, 0xfa3182ed),
+ TOBN(0x2216a665, 0x104152ba), TOBN(0x46908d03, 0xb6926368)},
+ {
+ TOBN(0xa9f5d874, 0x5a1251fb), TOBN(0x967747a8, 0xc72725c7),
+ TOBN(0x195c33e5, 0x31ffe89e), TOBN(0x609d210f, 0xe964935e),
+ TOBN(0xcafd6ca8, 0x2fe12227), TOBN(0xaf9b5b96, 0x0426469d),
+ TOBN(0x2e9ee04c, 0x5693183c), TOBN(0x1084a333, 0xc8146fef),
+ TOBN(0x96649933, 0xaed1d1f7), TOBN(0x566eaff3, 0x50563090),
+ TOBN(0x345057f0, 0xad2e39cf), TOBN(0x148ff65b, 0x1f832124),
+ TOBN(0x042e89d4, 0xcf94cf0d), TOBN(0x319bec84, 0x520c58b3),
+ TOBN(0x2a267626, 0x5361aa0d), TOBN(0xc86fa302, 0x8fbc87ad),
+ TOBN(0xfc83d2ab, 0x5c8b06d5), TOBN(0xb1a785a2, 0xfe4eac46),
+ TOBN(0xb99315bc, 0x846f7779), TOBN(0xcf31d816, 0xef9ea505),
+ TOBN(0x2391fe6a, 0x15d7dc85), TOBN(0x2f132b04, 0xb4016b33),
+ TOBN(0x29547fe3, 0x181cb4c7), TOBN(0xdb66d8a6, 0x650155a1),
+ TOBN(0x6b66d7e1, 0xadc1696f), TOBN(0x98ebe593, 0x0acd72d0),
+ TOBN(0x65f24550, 0xcc1b7435), TOBN(0xce231393, 0xb4b9a5ec),
+ TOBN(0x234a22d4, 0xdb067df9), TOBN(0x98dda095, 0xcaff9b00),
+ TOBN(0x1bbc75a0, 0x6100c9c1), TOBN(0x1560a9c8, 0x939cf695),
+ TOBN(0xcf006d3e, 0x99e0925f), TOBN(0x2dd74a96, 0x6322375a),
+ TOBN(0xc58b446a, 0xb56af5ba), TOBN(0x50292683, 0xe0b9b4f1),
+ TOBN(0xe2c34cb4, 0x1aeaffa3), TOBN(0x8b17203f, 0x9b9587c1),
+ TOBN(0x6d559207, 0xead1350c), TOBN(0x2b66a215, 0xfb7f9604),
+ TOBN(0x0850325e, 0xfe51bf74), TOBN(0x9c4f579e, 0x5e460094),
+ TOBN(0x5c87b92a, 0x76da2f25), TOBN(0x889de4e0, 0x6febef33),
+ TOBN(0x6900ec06, 0x646083ce), TOBN(0xbe2a0335, 0xbfe12773),
+ TOBN(0xadd1da35, 0xc5344110), TOBN(0x757568b7, 0xb802cd20),
+ TOBN(0x75559779, 0x00f7e6c8), TOBN(0x38e8b94f, 0x0facd2f0),
+ TOBN(0xfea1f3af, 0x03fde375), TOBN(0x5e11a1d8, 0x75881dfc),
+ TOBN(0xb3a6b02e, 0xc1e2f2ef), TOBN(0x193d2bbb, 0xc605a6c5),
+ TOBN(0x325ffeee, 0x339a0b2d), TOBN(0x27b6a724, 0x9e0c8846),
+ TOBN(0xe4050f1c, 0xf1c367ca), TOBN(0x9bc85a9b, 0xc90fbc7d),
+ TOBN(0xa373c4a2, 0xe1a11032), TOBN(0xb64232b7, 0xad0393a9),
+ TOBN(0xf5577eb0, 0x167dad29), TOBN(0x1604f301, 0x94b78ab2),
+ TOBN(0x0baa94af, 0xe829348b), TOBN(0x77fbd8dd, 0x41654342),
+ TOBN(0xdab50ea5, 0xb964e39a), TOBN(0xd4c29e3c, 0xd0d3c76e),
+ TOBN(0x80dae67c, 0x56d11964), TOBN(0x7307a8bf, 0xe5ffcc2f),
+ TOBN(0x65bbc1aa, 0x91708c3b), TOBN(0xa151e62c, 0x28bf0eeb),
+ TOBN(0x6cb53381, 0x6fa34db7), TOBN(0x5139e05c, 0xa29403a8),
+ TOBN(0x6ff651b4, 0x94a7cd2e), TOBN(0x5671ffd1, 0x0699336c),
+ TOBN(0x6f5fd2cc, 0x979a896a), TOBN(0x11e893a8, 0xd8148cef),
+ TOBN(0x988906a1, 0x65cf7b10), TOBN(0x81b67178, 0xc50d8485),
+ TOBN(0x7c0deb35, 0x8a35b3de), TOBN(0x423ac855, 0xc1d29799),
+ TOBN(0xaf580d87, 0xdac50b74), TOBN(0x28b2b89f, 0x5869734c),
+ TOBN(0x99a3b936, 0x874e28fb), TOBN(0xbb2c9190, 0x25f3f73a),
+ TOBN(0x199f6918, 0x84a9d5b7), TOBN(0x7ebe2325, 0x7e770374),
+ TOBN(0xf442e107, 0x0738efe2), TOBN(0xcf9f3f56, 0xcf9082d2),
+ TOBN(0x719f69e1, 0x09618708), TOBN(0xcc9e8364, 0xc183f9b1),
+ TOBN(0xec203a95, 0x366a21af), TOBN(0x6aec5d6d, 0x068b141f),
+ TOBN(0xee2df78a, 0x994f04e9), TOBN(0xb39ccae8, 0x271245b0),
+ TOBN(0xb875a4a9, 0x97e43f4f), TOBN(0x507dfe11, 0xdb2cea98),
+ TOBN(0x4fbf81cb, 0x489b03e9), TOBN(0xdb86ec5b, 0x6ec414fa),
+ TOBN(0xfad444f9, 0xf51b3ae5), TOBN(0xca7d33d6, 0x1914e3fe),
+ TOBN(0xa9c32f5c, 0x0ae6c4d0), TOBN(0xa9ca1d1e, 0x73969568),
+ TOBN(0x98043c31, 0x1aa7467e), TOBN(0xe832e75c, 0xe21b5ac6),
+ TOBN(0x314b7aea, 0x5232123d), TOBN(0x08307c8c, 0x65ae86db),
+ TOBN(0x06e7165c, 0xaa4668ed), TOBN(0xb170458b, 0xb4d3ec39),
+ TOBN(0x4d2e3ec6, 0xc19bb986), TOBN(0xc5f34846, 0xae0304ed),
+ TOBN(0x917695a0, 0x6c9f9722), TOBN(0x6c7f7317, 0x4cab1c0a),
+ TOBN(0x6295940e, 0x9d6d2e8b), TOBN(0xd318b8c1, 0x549f7c97),
+ TOBN(0x22453204, 0x97713885), TOBN(0x468d834b, 0xa8a440fe),
+ TOBN(0xd81fe5b2, 0xbfba796e), TOBN(0x152364db, 0x6d71f116),
+ TOBN(0xbb8c7c59, 0xb5b66e53), TOBN(0x0b12c61b, 0x2641a192),
+ TOBN(0x31f14802, 0xfcf0a7fd), TOBN(0x42fd0789, 0x5488b01e),
+ TOBN(0x71d78d6d, 0x9952b498), TOBN(0x8eb572d9, 0x07ac5201),
+ TOBN(0xe0a2a44c, 0x4d194a88), TOBN(0xd2b63fd9, 0xba017e66),
+ TOBN(0x78efc6c8, 0xf888aefc), TOBN(0xb76f6bda, 0x4a881a11),
+ TOBN(0x187f314b, 0xb46c2397), TOBN(0x004cf566, 0x5ded2819),
+ TOBN(0xa9ea5704, 0x38764d34), TOBN(0xbba45217, 0x78084709),
+ TOBN(0x06474571, 0x1171121e), TOBN(0xad7b7eb1, 0xe7c9b671),
+ TOBN(0xdacfbc40, 0x730f7507), TOBN(0x178cd8c6, 0xc7ad7bd1),
+ TOBN(0xbf0be101, 0xb2a67238), TOBN(0x3556d367, 0xaf9c14f2),
+ TOBN(0x104b7831, 0xa5662075), TOBN(0x58ca59bb, 0x79d9e60a),
+ TOBN(0x4bc45392, 0xa569a73b), TOBN(0x517a52e8, 0x5698f6c9),
+ TOBN(0x85643da5, 0xaeadd755), TOBN(0x1aed0cd5, 0x2a581b84),
+ TOBN(0xb9b4ff84, 0x80af1372), TOBN(0x244c3113, 0xf1ba5d1f),
+ TOBN(0x2a5dacbe, 0xf5f98d31), TOBN(0x2c3323e8, 0x4375bc2a),
+ TOBN(0x17a3ab4a, 0x5594b1dd), TOBN(0xa1928bfb, 0xceb4797e),
+ TOBN(0xe83af245, 0xe4886a19), TOBN(0x8979d546, 0x72b5a74a),
+ TOBN(0xa0f726bc, 0x19f9e967), TOBN(0xd9d03152, 0xe8fbbf4e),
+ TOBN(0xcfd6f51d, 0xb7707d40), TOBN(0x633084d9, 0x63f6e6e0),
+ TOBN(0xedcd9cdc, 0x55667eaf), TOBN(0x73b7f92b, 0x2e44d56f),
+ TOBN(0xfb2e39b6, 0x4e962b14), TOBN(0x7d408f6e, 0xf671fcbf),
+ TOBN(0xcc634ddc, 0x164a89bb), TOBN(0x74a42bb2, 0x3ef3bd05),
+ TOBN(0x1280dbb2, 0x428decbb), TOBN(0x6103f6bb, 0x402c8596),
+ TOBN(0xfa2bf581, 0x355a5752), TOBN(0x562f96a8, 0x00946674),
+ TOBN(0x4e4ca16d, 0x6da0223b), TOBN(0xfe47819f, 0x28d3aa25),
+ TOBN(0x9eea3075, 0xf8dfcf8a), TOBN(0xa284f0aa, 0x95669825),
+ TOBN(0xb3fca250, 0x867d3fd8), TOBN(0x20757b5f, 0x269d691e),
+ TOBN(0xf2c24020, 0x93b8a5de), TOBN(0xd3f93359, 0xebc06da6),
+ TOBN(0x1178293e, 0xb2739c33), TOBN(0xd2a3e770, 0xbcd686e5),
+ TOBN(0xa76f49f4, 0xcd941534), TOBN(0x0d37406b, 0xe3c71c0e),
+ TOBN(0x172d9397, 0x3b97f7e3), TOBN(0xec17e239, 0xbd7fd0de),
+ TOBN(0xe3290551, 0x6f496ba2), TOBN(0x6a693172, 0x36ad50e7),
+ TOBN(0xc4e539a2, 0x83e7eff5), TOBN(0x752737e7, 0x18e1b4cf),
+ TOBN(0xa2f7932c, 0x68af43ee), TOBN(0x5502468e, 0x703d00bd),
+ TOBN(0xe5dc978f, 0x2fb061f5), TOBN(0xc9a1904a, 0x28c815ad),
+ TOBN(0xd3af538d, 0x470c56a4), TOBN(0x159abc5f, 0x193d8ced),
+ TOBN(0x2a37245f, 0x20108ef3), TOBN(0xfa17081e, 0x223f7178),
+ TOBN(0x27b0fb2b, 0x10c8c0f5), TOBN(0x2102c3ea, 0x40650547),
+ TOBN(0x594564df, 0x8ac3bfa7), TOBN(0x98102033, 0x509dad96),
+ TOBN(0x6989643f, 0xf1d18a13), TOBN(0x35eebd91, 0xd7fc5af0),
+ TOBN(0x078d096a, 0xfaeaafd8), TOBN(0xb7a89341, 0xdef3de98),
+ TOBN(0x2a206e8d, 0xecf2a73a), TOBN(0x066a6397, 0x8e551994),
+ TOBN(0x3a6a088a, 0xb98d53a2), TOBN(0x0ce7c67c, 0x2d1124aa),
+ TOBN(0x48cec671, 0x759a113c), TOBN(0xe3b373d3, 0x4f6f67fa),
+ TOBN(0x5455d479, 0xfd36727b), TOBN(0xe5a428ee, 0xa13c0d81),
+ TOBN(0xb853dbc8, 0x1c86682b), TOBN(0xb78d2727, 0xb8d02b2a),
+ TOBN(0xaaf69bed, 0x8ebc329a), TOBN(0xdb6b40b3, 0x293b2148),
+ TOBN(0xe42ea77d, 0xb8c4961f), TOBN(0xb1a12f7c, 0x20e5e0ab),
+ TOBN(0xa0ec5274, 0x79e8b05e), TOBN(0x68027391, 0xfab60a80),
+ TOBN(0x6bfeea5f, 0x16b1bd5e), TOBN(0xf957e420, 0x4de30ad3),
+ TOBN(0xcbaf664e, 0x6a353b9e), TOBN(0x5c873312, 0x26d14feb),
+ TOBN(0x4e87f98c, 0xb65f57cb), TOBN(0xdb60a621, 0x5e0cdd41),
+ TOBN(0x67c16865, 0xa6881440), TOBN(0x1093ef1a, 0x46ab52aa),
+ TOBN(0xc095afb5, 0x3f4ece64), TOBN(0x6a6bb02e, 0x7604551a),
+ TOBN(0x55d44b4e, 0x0b26b8cd), TOBN(0xe5f9a999, 0xf971268a),
+ TOBN(0xc08ec425, 0x11a7de84), TOBN(0x83568095, 0xfda469dd),
+ TOBN(0x737bfba1, 0x6c6c90a2), TOBN(0x1cb9c4a0, 0xbe229831),
+ TOBN(0x93bccbba, 0xbb2eec64), TOBN(0xa0c23b64, 0xda03adbe),
+ TOBN(0x5f7aa00a, 0xe0e86ac4), TOBN(0x470b941e, 0xfc1401e6),
+ TOBN(0x5ad8d679, 0x9df43574), TOBN(0x4ccfb8a9, 0x0f65d810),
+ TOBN(0x1bce80e3, 0xaa7fbd81), TOBN(0x273291ad, 0x9508d20a),
+ TOBN(0xf5c4b46b, 0x42a92806), TOBN(0x810684ec, 0xa86ab44a),
+ TOBN(0x4591640b, 0xca0bc9f8), TOBN(0xb5efcdfc, 0x5c4b6054),
+ TOBN(0x16fc8907, 0x6e9edd12), TOBN(0xe29d0b50, 0xd4d792f9),
+ TOBN(0xa45fd01c, 0x9b03116d), TOBN(0x85035235, 0xc81765a4),
+ TOBN(0x1fe2a9b2, 0xb4b4b67c), TOBN(0xc1d10df0, 0xe8020604),
+ TOBN(0x9d64abfc, 0xbc8058d8), TOBN(0x8943b9b2, 0x712a0fbb),
+ TOBN(0x90eed914, 0x3b3def04), TOBN(0x85ab3aa2, 0x4ce775ff),
+ TOBN(0x605fd4ca, 0x7bbc9040), TOBN(0x8b34a564, 0xe2c75dfb),
+ TOBN(0x41ffc94a, 0x10358560), TOBN(0x2d8a5072, 0x9e5c28aa),
+ TOBN(0xe915a0fc, 0x4cc7eb15), TOBN(0xe9efab05, 0x8f6d0f5d),
+ TOBN(0xdbab47a9, 0xd19e9b91), TOBN(0x8cfed745, 0x0276154c),
+ TOBN(0x154357ae, 0x2cfede0d), TOBN(0x520630df, 0x19f5a4ef),
+ TOBN(0x25759f7c, 0xe382360f), TOBN(0xb6db05c9, 0x88bf5857),
+ TOBN(0x2917d61d, 0x6c58d46c), TOBN(0x14f8e491, 0xfd20cb7a),
+ TOBN(0xb68a727a, 0x11c20340), TOBN(0x0386f86f, 0xaf7ccbb6),
+ TOBN(0x5c8bc6cc, 0xfee09a20), TOBN(0x7d76ff4a, 0xbb7eea35),
+ TOBN(0xa7bdebe7, 0xdb15be7a), TOBN(0x67a08054, 0xd89f0302),
+ TOBN(0x56bf0ea9, 0xc1193364), TOBN(0xc8244467, 0x62837ebe),
+ TOBN(0x32bd8e8b, 0x20d841b8), TOBN(0x127a0548, 0xdbb8a54f),
+ TOBN(0x83dd4ca6, 0x63b20236), TOBN(0x87714718, 0x203491fa),
+ TOBN(0x4dabcaaa, 0xaa8a5288), TOBN(0x91cc0c8a, 0xaf23a1c9),
+ TOBN(0x34c72c6a, 0x3f220e0c), TOBN(0xbcc20bdf, 0x1232144a),
+ TOBN(0x6e2f42da, 0xa20ede1b), TOBN(0xc441f00c, 0x74a00515),
+ TOBN(0xbf46a5b6, 0x734b8c4b), TOBN(0x57409503, 0x7b56c9a4),
+ TOBN(0x9f735261, 0xe4585d45), TOBN(0x9231faed, 0x6734e642),
+ TOBN(0x1158a176, 0xbe70ee6c), TOBN(0x35f1068d, 0x7c3501bf),
+ TOBN(0x6beef900, 0xa2d26115), TOBN(0x649406f2, 0xef0afee3),
+ TOBN(0x3f43a60a, 0xbc2420a1), TOBN(0x509002a7, 0xd5aee4ac),
+ TOBN(0xb46836a5, 0x3ff3571b), TOBN(0x24f98b78, 0x837927c1),
+ TOBN(0x6254256a, 0x4533c716), TOBN(0xf27abb0b, 0xd07ee196),
+ TOBN(0xd7cf64fc, 0x5c6d5bfd), TOBN(0x6915c751, 0xf0cd7a77),
+ TOBN(0xd9f59012, 0x8798f534), TOBN(0x772b0da8, 0xf81d8b5f),
+ TOBN(0x1244260c, 0x2e03fa69), TOBN(0x36cf0e3a, 0x3be1a374),
+ TOBN(0x6e7c1633, 0xef06b960), TOBN(0xa71a4c55, 0x671f90f6),
+ TOBN(0x7a941251, 0x33c673db), TOBN(0xc0bea510, 0x73e8c131),
+ TOBN(0x61a8a699, 0xd4f6c734), TOBN(0x25e78c88, 0x341ed001),
+ TOBN(0x5c18acf8, 0x8e2f7d90), TOBN(0xfdbf33d7, 0x77be32cd),
+ TOBN(0x0a085cd7, 0xd2eb5ee9), TOBN(0x2d702cfb, 0xb3201115),
+ TOBN(0xb6e0ebdb, 0x85c88ce8), TOBN(0x23a3ce3c, 0x1e01d617),
+ TOBN(0x3041618e, 0x567333ac), TOBN(0x9dd0fd8f, 0x157edb6b),
+ TOBN(0x27f74702, 0xb57872b8), TOBN(0x2ef26b4f, 0x657d5fe1),
+ TOBN(0x95426f0a, 0x57cf3d40), TOBN(0x847e2ad1, 0x65a6067a),
+ TOBN(0xd474d9a0, 0x09996a74), TOBN(0x16a56acd, 0x2a26115c),
+ TOBN(0x02a615c3, 0xd16f4d43), TOBN(0xcc3fc965, 0xaadb85b7),
+ TOBN(0x386bda73, 0xce07d1b0), TOBN(0xd82910c2, 0x58ad4178),
+ TOBN(0x124f82cf, 0xcd2617f4), TOBN(0xcc2f5e8d, 0xef691770),
+ TOBN(0x82702550, 0xb8c30ccc), TOBN(0x7b856aea, 0x1a8e575a),
+ TOBN(0xbb822fef, 0xb1ab9459), TOBN(0x085928bc, 0xec24e38e),
+ TOBN(0x5d0402ec, 0xba8f4b4d), TOBN(0xc07cd4ba, 0x00b4d58b),
+ TOBN(0x5d8dffd5, 0x29227e7a), TOBN(0x61d44d0c, 0x31bf386f),
+ TOBN(0xe486dc2b, 0x135e6f4d), TOBN(0x680962eb, 0xe79410ef),
+ TOBN(0xa61bd343, 0xf10088b5), TOBN(0x6aa76076, 0xe2e28686),
+ TOBN(0x80463d11, 0x8fb98871), TOBN(0xcb26f5c3, 0xbbc76aff),
+ TOBN(0xd4ab8edd, 0xfbe03614), TOBN(0xc8eb579b, 0xc0cf2dee),
+ TOBN(0xcc004c15, 0xc93bae41), TOBN(0x46fbae5d, 0x3aeca3b2),
+ TOBN(0x671235cf, 0x0f1e9ab1), TOBN(0xadfba934, 0x9ec285c1),
+ TOBN(0x88ded013, 0xf216c980), TOBN(0xc8ac4fb8, 0xf79e0bc1),
+ TOBN(0xa29b89c6, 0xfb97a237), TOBN(0xb697b780, 0x9922d8e7),
+ TOBN(0x3142c639, 0xddb945b5), TOBN(0x447b06c7, 0xe094c3a9),
+ TOBN(0xcdcb3642, 0x72266c90), TOBN(0x633aad08, 0xa9385046),
+ TOBN(0xa36c936b, 0xb57c6477), TOBN(0x871f8b64, 0xe94dbcc6),
+ TOBN(0x28d0fb62, 0xa591a67b), TOBN(0x9d40e081, 0xc1d926f5),
+ TOBN(0x3111eaf6, 0xf2d84b5a), TOBN(0x228993f9, 0xa565b644),
+ TOBN(0x0ccbf592, 0x2c83188b), TOBN(0xf87b30ab, 0x3df3e197),
+ TOBN(0xb8658b31, 0x7642bca8), TOBN(0x1a032d7f, 0x52800f17),
+ TOBN(0x051dcae5, 0x79bf9445), TOBN(0xeba6b8ee, 0x54a2e253),
+ TOBN(0x5c8b9cad, 0xd4485692), TOBN(0x84bda40e, 0x8986e9be),
+ TOBN(0xd16d16a4, 0x2f0db448), TOBN(0x8ec80050, 0xa14d4188),
+ TOBN(0xb2b26107, 0x98fa7aaa), TOBN(0x41209ee4, 0xf073aa4e),
+ TOBN(0xf1570359, 0xf2d6b19b), TOBN(0xcbe6868c, 0xfc577caf),
+ TOBN(0x186c4bdc, 0x32c04dd3), TOBN(0xa6c35fae, 0xcfeee397),
+ TOBN(0xb4a1b312, 0xf086c0cf), TOBN(0xe0a5ccc6, 0xd9461fe2),
+ TOBN(0xc32278aa, 0x1536189f), TOBN(0x1126c55f, 0xba6df571),
+ TOBN(0x0f71a602, 0xb194560e), TOBN(0x8b2d7405, 0x324bd6e1),
+ TOBN(0x8481939e, 0x3738be71), TOBN(0xb5090b1a, 0x1a4d97a9),
+ TOBN(0x116c65a3, 0xf05ba915), TOBN(0x21863ad3, 0xaae448aa),
+ TOBN(0xd24e2679, 0xa7aae5d3), TOBN(0x7076013d, 0x0de5c1c4),
+ TOBN(0x2d50f8ba, 0xbb05b629), TOBN(0x73c1abe2, 0x6e66efbb),
+ TOBN(0xefd4b422, 0xf2488af7), TOBN(0xe4105d02, 0x663ba575),
+ TOBN(0x7eb60a8b, 0x53a69457), TOBN(0x62210008, 0xc945973b),
+ TOBN(0xfb255478, 0x77a50ec6), TOBN(0xbf0392f7, 0x0a37a72c),
+ TOBN(0xa0a7a19c, 0x4be18e7a), TOBN(0x90d8ea16, 0x25b1e0af),
+ TOBN(0x7582a293, 0xef953f57), TOBN(0x90a64d05, 0xbdc5465a),
+ TOBN(0xca79c497, 0xe2510717), TOBN(0x560dbb7c, 0x18cb641f),
+ TOBN(0x1d8e3286, 0x4b66abfb), TOBN(0xd26f52e5, 0x59030900),
+ TOBN(0x1ee3f643, 0x5584941a), TOBN(0x6d3b3730, 0x569f5958),
+ TOBN(0x9ff2a62f, 0x4789dba5), TOBN(0x91fcb815, 0x72b5c9b7),
+ TOBN(0xf446cb7d, 0x6c8f9a0e), TOBN(0x48f625c1, 0x39b7ecb5),
+ TOBN(0xbabae801, 0x1c6219b8), TOBN(0xe7a562d9, 0x28ac2f23),
+ TOBN(0xe1b48732, 0x26e20588), TOBN(0x06ee1cad, 0x775af051),
+ TOBN(0xda29ae43, 0xfaff79f7), TOBN(0xc141a412, 0x652ee9e0),
+ TOBN(0x1e127f6f, 0x195f4bd0), TOBN(0x29c6ab4f, 0x072f34f8),
+ TOBN(0x7b7c1477, 0x30448112), TOBN(0x82b51af1, 0xe4a38656),
+ TOBN(0x2bf2028a, 0x2f315010), TOBN(0xc9a4a01f, 0x6ea88cd4),
+ TOBN(0xf63e95d8, 0x257e5818), TOBN(0xdd8efa10, 0xb4519b16),
+ TOBN(0xed8973e0, 0x0da910bf), TOBN(0xed49d077, 0x5c0fe4a9),
+ TOBN(0xac3aac5e, 0xb7caee1e), TOBN(0x1033898d, 0xa7f4da57),
+ TOBN(0x42145c0e, 0x5c6669b9), TOBN(0x42daa688, 0xc1aa2aa0),
+ TOBN(0x629cc15c, 0x1a1d885a), TOBN(0x25572ec0, 0xf4b76817),
+ TOBN(0x8312e435, 0x9c8f8f28), TOBN(0x8107f8cd, 0x81965490),
+ TOBN(0x516ff3a3, 0x6fa6110c), TOBN(0x74fb1eb1, 0xfb93561f),
+ TOBN(0x6c0c9047, 0x8457522b), TOBN(0xcfd32104, 0x6bb8bdc6),
+ TOBN(0x2d6884a2, 0xcc80ad57), TOBN(0x7c27fc35, 0x86a9b637),
+ TOBN(0x3461baed, 0xadf4e8cd), TOBN(0x1d56251a, 0x617242f0),
+ TOBN(0x0b80d209, 0xc955bef4), TOBN(0xdf02cad2, 0x06adb047),
+ TOBN(0xf0d7cb91, 0x5ec74fee), TOBN(0xd2503375, 0x1111ba44),
+ TOBN(0x9671755e, 0xdf53cb36), TOBN(0x54dcb612, 0x3368551b),
+ TOBN(0x66d69aac, 0xc8a025a4), TOBN(0x6be946c6, 0xe77ef445),
+ TOBN(0x719946d1, 0xa995e094), TOBN(0x65e848f6, 0xe51e04d8),
+ TOBN(0xe62f3300, 0x6a1e3113), TOBN(0x1541c7c1, 0x501de503),
+ TOBN(0x4daac9fa, 0xf4acfade), TOBN(0x0e585897, 0x44cd0b71),
+ TOBN(0x544fd869, 0x0a51cd77), TOBN(0x60fc20ed, 0x0031016d),
+ TOBN(0x58b404ec, 0xa4276867), TOBN(0x46f6c3cc, 0x34f34993),
+ TOBN(0x477ca007, 0xc636e5bd), TOBN(0x8018f5e5, 0x7c458b47),
+ TOBN(0xa1202270, 0xe47b668f), TOBN(0xcef48ccd, 0xee14f203),
+ TOBN(0x23f98bae, 0x62ff9b4d), TOBN(0x55acc035, 0xc589eddd),
+ TOBN(0x3fe712af, 0x64db4444), TOBN(0x19e9d634, 0xbecdd480),
+ TOBN(0xe08bc047, 0xa930978a), TOBN(0x2dbf24ec, 0xa1280733),
+ TOBN(0x3c0ae38c, 0x2cd706b2), TOBN(0x5b012a5b, 0x359017b9),
+ TOBN(0x3943c38c, 0x72e0f5ae), TOBN(0x786167ea, 0x57176fa3),
+ TOBN(0xe5f9897d, 0x594881dc), TOBN(0x6b5efad8, 0xcfb820c1),
+ TOBN(0xb2179093, 0xd55018de), TOBN(0x39ad7d32, 0x0bac56ce),
+ TOBN(0xb55122e0, 0x2cfc0e81), TOBN(0x117c4661, 0xf6d89daa),
+ TOBN(0x362d01e1, 0xcb64fa09), TOBN(0x6a309b4e, 0x3e9c4ddd),
+ TOBN(0xfa979fb7, 0xabea49b1), TOBN(0xb4b1d27d, 0x10e2c6c5),
+ TOBN(0xbd61c2c4, 0x23afde7a), TOBN(0xeb6614f8, 0x9786d358),
+ TOBN(0x4a5d816b, 0x7f6f7459), TOBN(0xe431a44f, 0x09360e7b),
+ TOBN(0x8c27a032, 0xc309914c), TOBN(0xcea5d68a, 0xcaede3d8),
+ TOBN(0x3668f665, 0x3a0a3f95), TOBN(0x89369416, 0x7ceba27b),
+ TOBN(0x89981fad, 0xe4728fe9), TOBN(0x7102c8a0, 0x8a093562),
+ TOBN(0xbb80310e, 0x235d21c8), TOBN(0x505e55d1, 0xbefb7f7b),
+ TOBN(0xa0a90811, 0x12958a67), TOBN(0xd67e106a, 0x4d851fef),
+ TOBN(0xb84011a9, 0x431dd80e), TOBN(0xeb7c7cca, 0x73306cd9),
+ TOBN(0x20fadd29, 0xd1b3b730), TOBN(0x83858b5b, 0xfe37b3d3),
+ TOBN(0xbf4cd193, 0xb6251d5c), TOBN(0x1cca1fd3, 0x1352d952),
+ TOBN(0xc66157a4, 0x90fbc051), TOBN(0x7990a638, 0x89b98636),
+ },
+ {TOBN(0xe5aa692a, 0x87dec0e1), TOBN(0x010ded8d, 0xf7b39d00),
+ TOBN(0x7b1b80c8, 0x54cfa0b5), TOBN(0x66beb876, 0xa0f8ea28),
+ TOBN(0x50d7f531, 0x3476cd0e), TOBN(0xa63d0e65, 0xb08d3949),
+ TOBN(0x1a09eea9, 0x53479fc6), TOBN(0x82ae9891, 0xf499e742),
+ TOBN(0xab58b910, 0x5ca7d866), TOBN(0x582967e2, 0x3adb3b34),
+ TOBN(0x89ae4447, 0xcceac0bc), TOBN(0x919c667c, 0x7bf56af5),
+ TOBN(0x9aec17b1, 0x60f5dcd7), TOBN(0xec697b9f, 0xddcaadbc),
+ TOBN(0x0b98f341, 0x463467f5), TOBN(0xb187f1f7, 0xa967132f),
+ TOBN(0x90fe7a1d, 0x214aeb18), TOBN(0x1506af3c, 0x741432f7),
+ TOBN(0xbb5565f9, 0xe591a0c4), TOBN(0x10d41a77, 0xb44f1bc3),
+ TOBN(0xa09d65e4, 0xa84bde96), TOBN(0x42f060d8, 0xf20a6a1c),
+ TOBN(0x652a3bfd, 0xf27f9ce7), TOBN(0xb6bdb65c, 0x3b3d739f),
+ TOBN(0xeb5ddcb6, 0xec7fae9f), TOBN(0x995f2714, 0xefb66e5a),
+ TOBN(0xdee95d8e, 0x69445d52), TOBN(0x1b6c2d46, 0x09e27620),
+ TOBN(0x32621c31, 0x8129d716), TOBN(0xb03909f1, 0x0958c1aa),
+ TOBN(0x8c468ef9, 0x1af4af63), TOBN(0x162c429f, 0xfba5cdf6),
+ TOBN(0x2f682343, 0x753b9371), TOBN(0x29cab45a, 0x5f1f9cd7),
+ TOBN(0x571623ab, 0xb245db96), TOBN(0xc507db09, 0x3fd79999),
+ TOBN(0x4e2ef652, 0xaf036c32), TOBN(0x86f0cc78, 0x05018e5c),
+ TOBN(0xc10a73d4, 0xab8be350), TOBN(0x6519b397, 0x7e826327),
+ TOBN(0xe8cb5eef, 0x9c053df7), TOBN(0x8de25b37, 0xb300ea6f),
+ TOBN(0xdb03fa92, 0xc849cffb), TOBN(0x242e43a7, 0xe84169bb),
+ TOBN(0xe4fa51f4, 0xdd6f958e), TOBN(0x6925a77f, 0xf4445a8d),
+ TOBN(0xe6e72a50, 0xe90d8949), TOBN(0xc66648e3, 0x2b1f6390),
+ TOBN(0xb2ab1957, 0x173e460c), TOBN(0x1bbbce75, 0x30704590),
+ TOBN(0xc0a90dbd, 0xdb1c7162), TOBN(0x505e399e, 0x15cdd65d),
+ TOBN(0x68434dcb, 0x57797ab7), TOBN(0x60ad35ba, 0x6a2ca8e8),
+ TOBN(0x4bfdb1e0, 0xde3336c1), TOBN(0xbbef99eb, 0xd8b39015),
+ TOBN(0x6c3b96f3, 0x1711ebec), TOBN(0x2da40f1f, 0xce98fdc4),
+ TOBN(0xb99774d3, 0x57b4411f), TOBN(0x87c8bdf4, 0x15b65bb6),
+ TOBN(0xda3a89e3, 0xc2eef12d), TOBN(0xde95bb9b, 0x3c7471f3),
+ TOBN(0x600f225b, 0xd812c594), TOBN(0x54907c5d, 0x2b75a56b),
+ TOBN(0xa93cc5f0, 0x8db60e35), TOBN(0x743e3cd6, 0xfa833319),
+ TOBN(0x7dad5c41, 0xf81683c9), TOBN(0x70c1e7d9, 0x9c34107e),
+ TOBN(0x0edc4a39, 0xa6be0907), TOBN(0x36d47035, 0x86d0b7d3),
+ TOBN(0x8c76da03, 0x272bfa60), TOBN(0x0b4a07ea, 0x0f08a414),
+ TOBN(0x699e4d29, 0x45c1dd53), TOBN(0xcadc5898, 0x231debb5),
+ TOBN(0xdf49fcc7, 0xa77f00e0), TOBN(0x93057bbf, 0xa73e5a0e),
+ TOBN(0x2f8b7ecd, 0x027a4cd1), TOBN(0x114734b3, 0xc614011a),
+ TOBN(0xe7a01db7, 0x67677c68), TOBN(0x89d9be5e, 0x7e273f4f),
+ TOBN(0xd225cb2e, 0x089808ef), TOBN(0xf1f7a27d, 0xd59e4107),
+ TOBN(0x53afc761, 0x8211b9c9), TOBN(0x0361bc67, 0xe6819159),
+ TOBN(0x2a865d0b, 0x7f071426), TOBN(0x6a3c1810, 0xe7072567),
+ TOBN(0x3e3bca1e, 0x0d6bcabd), TOBN(0xa1b02bc1, 0x408591bc),
+ TOBN(0xe0deee59, 0x31fba239), TOBN(0xf47424d3, 0x98bd91d1),
+ TOBN(0x0f8886f4, 0x071a3c1d), TOBN(0x3f7d41e8, 0xa819233b),
+ TOBN(0x708623c2, 0xcf6eb998), TOBN(0x86bb49af, 0x609a287f),
+ TOBN(0x942bb249, 0x63c90762), TOBN(0x0ef6eea5, 0x55a9654b),
+ TOBN(0x5f6d2d72, 0x36f5defe), TOBN(0xfa9922dc, 0x56f99176),
+ TOBN(0x6c8c5ece, 0xf78ce0c7), TOBN(0x7b44589d, 0xbe09b55e),
+ TOBN(0xe11b3bca, 0x9ea83770), TOBN(0xd7fa2c7f, 0x2ab71547),
+ TOBN(0x2a3dd6fa, 0x2a1ddcc0), TOBN(0x09acb430, 0x5a7b7707),
+ TOBN(0x4add4a2e, 0x649d4e57), TOBN(0xcd53a2b0, 0x1917526e),
+ TOBN(0xc5262330, 0x20b44ac4), TOBN(0x4028746a, 0xbaa2c31d),
+ TOBN(0x51318390, 0x64291d4c), TOBN(0xbf48f151, 0xee5ad909),
+ TOBN(0xcce57f59, 0x7b185681), TOBN(0x7c3ac1b0, 0x4854d442),
+ TOBN(0x65587dc3, 0xc093c171), TOBN(0xae7acb24, 0x24f42b65),
+ TOBN(0x5a338adb, 0x955996cb), TOBN(0xc8e65675, 0x6051f91b),
+ TOBN(0x66711fba, 0x28b8d0b1), TOBN(0x15d74137, 0xb6c10a90),
+ TOBN(0x70cdd7eb, 0x3a232a80), TOBN(0xc9e2f07f, 0x6191ed24),
+ TOBN(0xa80d1db6, 0xf79588c0), TOBN(0xfa52fc69, 0xb55768cc),
+ TOBN(0x0b4df1ae, 0x7f54438a), TOBN(0x0cadd1a7, 0xf9b46a4f),
+ TOBN(0xb40ea6b3, 0x1803dd6f), TOBN(0x488e4fa5, 0x55eaae35),
+ TOBN(0x9f047d55, 0x382e4e16), TOBN(0xc9b5b7e0, 0x2f6e0c98),
+ TOBN(0x6b1bd2d3, 0x95762649), TOBN(0xa9604ee7, 0xc7aea3f6),
+ TOBN(0x3646ff27, 0x6dc6f896), TOBN(0x9bf0e7f5, 0x2860bad1),
+ TOBN(0x2d92c821, 0x7cb44b92), TOBN(0xa2f5ce63, 0xaea9c182),
+ TOBN(0xd0a2afb1, 0x9154a5fd), TOBN(0x482e474c, 0x95801da6),
+ TOBN(0xc19972d0, 0xb611c24b), TOBN(0x1d468e65, 0x60a8f351),
+ TOBN(0xeb758069, 0x7bcf6421), TOBN(0xec9dd0ee, 0x88fbc491),
+ TOBN(0x5b59d2bf, 0x956c2e32), TOBN(0x73dc6864, 0xdcddf94e),
+ TOBN(0xfd5e2321, 0xbcee7665), TOBN(0xa7b4f8ef, 0x5e9a06c4),
+ TOBN(0xfba918dd, 0x7280f855), TOBN(0xbbaac260, 0x8baec688),
+ TOBN(0xa3b3f00f, 0x33400f42), TOBN(0x3d2dba29, 0x66f2e6e4),
+ TOBN(0xb6f71a94, 0x98509375), TOBN(0x8f33031f, 0xcea423cc),
+ TOBN(0x009b8dd0, 0x4807e6fb), TOBN(0x5163cfe5, 0x5cdb954c),
+ TOBN(0x03cc8f17, 0xcf41c6e8), TOBN(0xf1f03c2a, 0x037b925c),
+ TOBN(0xc39c19cc, 0x66d2427c), TOBN(0x823d24ba, 0x7b6c18e4),
+ TOBN(0x32ef9013, 0x901f0b4f), TOBN(0x684360f1, 0xf8941c2e),
+ TOBN(0x0ebaff52, 0x2c28092e), TOBN(0x7891e4e3, 0x256c932f),
+ TOBN(0x51264319, 0xac445e3d), TOBN(0x553432e7, 0x8ea74381),
+ TOBN(0xe6eeaa69, 0x67e9c50a), TOBN(0x27ced284, 0x62e628c7),
+ TOBN(0x3f96d375, 0x7a4afa57), TOBN(0xde0a14c3, 0xe484c150),
+ TOBN(0x364a24eb, 0x38bd9923), TOBN(0x1df18da0, 0xe5177422),
+ TOBN(0x174e8f82, 0xd8d38a9b), TOBN(0x2e97c600, 0xe7de1391),
+ TOBN(0xc5709850, 0xa1c175dd), TOBN(0x969041a0, 0x32ae5035),
+ TOBN(0xcbfd533b, 0x76a2086b), TOBN(0xd6bba71b, 0xd7c2e8fe),
+ TOBN(0xb2d58ee6, 0x099dfb67), TOBN(0x3a8b342d, 0x064a85d9),
+ TOBN(0x3bc07649, 0x522f9be3), TOBN(0x690c075b, 0xdf1f49a8),
+ TOBN(0x80e1aee8, 0x3854ec42), TOBN(0x2a7dbf44, 0x17689dc7),
+ TOBN(0xc004fc0e, 0x3faf4078), TOBN(0xb2f02e9e, 0xdf11862c),
+ TOBN(0xf10a5e0f, 0xa0a1b7b3), TOBN(0x30aca623, 0x8936ec80),
+ TOBN(0xf83cbf05, 0x02f40d9a), TOBN(0x4681c468, 0x2c318a4d),
+ TOBN(0x98575618, 0x0e9c2674), TOBN(0xbe79d046, 0x1847092e),
+ TOBN(0xaf1e480a, 0x78bd01e0), TOBN(0x6dd359e4, 0x72a51db9),
+ TOBN(0x62ce3821, 0xe3afbab6), TOBN(0xc5cee5b6, 0x17733199),
+ TOBN(0xe08b30d4, 0x6ffd9fbb), TOBN(0x6e5bc699, 0x36c610b7),
+ TOBN(0xf343cff2, 0x9ce262cf), TOBN(0xca2e4e35, 0x68b914c1),
+ TOBN(0x011d64c0, 0x16de36c5), TOBN(0xe0b10fdd, 0x42e2b829),
+ TOBN(0x78942981, 0x6685aaf8), TOBN(0xe7511708, 0x230ede97),
+ TOBN(0x671ed8fc, 0x3b922bf8), TOBN(0xe4d8c0a0, 0x4c29b133),
+ TOBN(0x87eb1239, 0x3b6e99c4), TOBN(0xaff3974c, 0x8793beba),
+ TOBN(0x03749405, 0x2c18df9b), TOBN(0xc5c3a293, 0x91007139),
+ TOBN(0x6a77234f, 0xe37a0b95), TOBN(0x02c29a21, 0xb661c96b),
+ TOBN(0xc3aaf1d6, 0x141ecf61), TOBN(0x9195509e, 0x3bb22f53),
+ TOBN(0x29597404, 0x22d51357), TOBN(0x1b083822, 0x537bed60),
+ TOBN(0xcd7d6e35, 0xe07289f0), TOBN(0x1f94c48c, 0x6dd86eff),
+ TOBN(0xc8bb1f82, 0xeb0f9cfa), TOBN(0x9ee0b7e6, 0x1b2eb97d),
+ TOBN(0x5a52fe2e, 0x34d74e31), TOBN(0xa352c310, 0x3bf79ab6),
+ TOBN(0x97ff6c5a, 0xabfeeb8f), TOBN(0xbfbe8fef, 0xf5c97305),
+ TOBN(0xd6081ce6, 0xa7904608), TOBN(0x1f812f3a, 0xc4fca249),
+ TOBN(0x9b24bc9a, 0xb9e5e200), TOBN(0x91022c67, 0x38012ee8),
+ TOBN(0xe83d9c5d, 0x30a713a1), TOBN(0x4876e3f0, 0x84ef0f93),
+ TOBN(0xc9777029, 0xc1fbf928), TOBN(0xef7a6bb3, 0xbce7d2a4),
+ TOBN(0xb8067228, 0xdfa2a659), TOBN(0xd5cd3398, 0xd877a48f),
+ TOBN(0xbea4fd8f, 0x025d0f3f), TOBN(0xd67d2e35, 0x2eae7c2b),
+ TOBN(0x184de7d7, 0xcc5f4394), TOBN(0xb5551b5c, 0x4536e142),
+ TOBN(0x2e89b212, 0xd34aa60a), TOBN(0x14a96fea, 0xf50051d5),
+ TOBN(0x4e21ef74, 0x0d12bb0b), TOBN(0xc522f020, 0x60b9677e),
+ TOBN(0x8b12e467, 0x2df7731d), TOBN(0x39f80382, 0x7b326d31),
+ TOBN(0xdfb8630c, 0x39024a94), TOBN(0xaacb96a8, 0x97319452),
+ TOBN(0xd68a3961, 0xeda3867c), TOBN(0x0c58e2b0, 0x77c4ffca),
+ TOBN(0x3d545d63, 0x4da919fa), TOBN(0xef79b69a, 0xf15e2289),
+ TOBN(0x54bc3d3d, 0x808bab10), TOBN(0xc8ab3007, 0x45f82c37),
+ TOBN(0xc12738b6, 0x7c4a658a), TOBN(0xb3c47639, 0x40e72182),
+ TOBN(0x3b77be46, 0x8798e44f), TOBN(0xdc047df2, 0x17a7f85f),
+ TOBN(0x2439d4c5, 0x5e59d92d), TOBN(0xcedca475, 0xe8e64d8d),
+ TOBN(0xa724cd0d, 0x87ca9b16), TOBN(0x35e4fd59, 0xa5540dfe),
+ TOBN(0xf8c1ff18, 0xe4bcf6b1), TOBN(0x856d6285, 0x295018fa),
+ TOBN(0x433f665c, 0x3263c949), TOBN(0xa6a76dd6, 0xa1f21409),
+ TOBN(0x17d32334, 0xcc7b4f79), TOBN(0xa1d03122, 0x06720e4a),
+ TOBN(0xadb6661d, 0x81d9bed5), TOBN(0xf0d6fb02, 0x11db15d1),
+ TOBN(0x7fd11ad5, 0x1fb747d2), TOBN(0xab50f959, 0x3033762b),
+ TOBN(0x2a7e711b, 0xfbefaf5a), TOBN(0xc7393278, 0x3fef2bbf),
+ TOBN(0xe29fa244, 0x0df6f9be), TOBN(0x9092757b, 0x71efd215),
+ TOBN(0xee60e311, 0x4f3d6fd9), TOBN(0x338542d4, 0x0acfb78b),
+ TOBN(0x44a23f08, 0x38961a0f), TOBN(0x1426eade, 0x986987ca),
+ TOBN(0x36e6ee2e, 0x4a863cc6), TOBN(0x48059420, 0x628b8b79),
+ TOBN(0x30303ad8, 0x7396e1de), TOBN(0x5c8bdc48, 0x38c5aad1),
+ TOBN(0x3e40e11f, 0x5c8f5066), TOBN(0xabd6e768, 0x8d246bbd),
+ TOBN(0x68aa40bb, 0x23330a01), TOBN(0xd23f5ee4, 0xc34eafa0),
+ TOBN(0x3bbee315, 0x5de02c21), TOBN(0x18dd4397, 0xd1d8dd06),
+ TOBN(0x3ba1939a, 0x122d7b44), TOBN(0xe6d3b40a, 0xa33870d6),
+ TOBN(0x8e620f70, 0x1c4fe3f8), TOBN(0xf6bba1a5, 0xd3a50cbf),
+ TOBN(0x4a78bde5, 0xcfc0aee0), TOBN(0x847edc46, 0xc08c50bd),
+ TOBN(0xbaa2439c, 0xad63c9b2), TOBN(0xceb4a728, 0x10fc2acb),
+ TOBN(0xa419e40e, 0x26da033d), TOBN(0x6cc3889d, 0x03e02683),
+ TOBN(0x1cd28559, 0xfdccf725), TOBN(0x0fd7e0f1, 0x8d13d208),
+ TOBN(0x01b9733b, 0x1f0df9d4), TOBN(0x8cc2c5f3, 0xa2b5e4f3),
+ TOBN(0x43053bfa, 0x3a304fd4), TOBN(0x8e87665c, 0x0a9f1aa7),
+ TOBN(0x087f29ec, 0xd73dc965), TOBN(0x15ace455, 0x3e9023db),
+ TOBN(0x2370e309, 0x2bce28b4), TOBN(0xf9723442, 0xb6b1e84a),
+ TOBN(0xbeee662e, 0xb72d9f26), TOBN(0xb19396de, 0xf0e47109),
+ TOBN(0x85b1fa73, 0xe13289d0), TOBN(0x436cf77e, 0x54e58e32),
+ TOBN(0x0ec833b3, 0xe990ef77), TOBN(0x7373e3ed, 0x1b11fc25),
+ TOBN(0xbe0eda87, 0x0fc332ce), TOBN(0xced04970, 0x8d7ea856),
+ TOBN(0xf85ff785, 0x7e977ca0), TOBN(0xb66ee8da, 0xdfdd5d2b),
+ TOBN(0xf5e37950, 0x905af461), TOBN(0x587b9090, 0x966d487c),
+ TOBN(0x6a198a1b, 0x32ba0127), TOBN(0xa7720e07, 0x141615ac),
+ TOBN(0xa23f3499, 0x996ef2f2), TOBN(0xef5f64b4, 0x470bcb3d),
+ TOBN(0xa526a962, 0x92b8c559), TOBN(0x0c14aac0, 0x69740a0f),
+ TOBN(0x0d41a9e3, 0xa6bdc0a5), TOBN(0x97d52106, 0x9c48aef4),
+ TOBN(0xcf16bd30, 0x3e7c253b), TOBN(0xcc834b1a, 0x47fdedc1),
+ TOBN(0x7362c6e5, 0x373aab2e), TOBN(0x264ed85e, 0xc5f590ff),
+ TOBN(0x7a46d9c0, 0x66d41870), TOBN(0xa50c20b1, 0x4787ba09),
+ TOBN(0x185e7e51, 0xe3d44635), TOBN(0xb3b3e080, 0x31e2d8dc),
+ TOBN(0xbed1e558, 0xa179e9d9), TOBN(0x2daa3f79, 0x74a76781),
+ TOBN(0x4372baf2, 0x3a40864f), TOBN(0x46900c54, 0x4fe75cb5),
+ TOBN(0xb95f171e, 0xf76765d0), TOBN(0x4ad726d2, 0x95c87502),
+ TOBN(0x2ec769da, 0x4d7c99bd), TOBN(0x5e2ddd19, 0xc36cdfa8),
+ TOBN(0xc22117fc, 0xa93e6dea), TOBN(0xe8a2583b, 0x93771123),
+ TOBN(0xbe2f6089, 0xfa08a3a2), TOBN(0x4809d5ed, 0x8f0e1112),
+ TOBN(0x3b414aa3, 0xda7a095e), TOBN(0x9049acf1, 0x26f5aadd),
+ TOBN(0x78d46a4d, 0x6be8b84a), TOBN(0xd66b1963, 0xb732b9b3),
+ TOBN(0x5c2ac2a0, 0xde6e9555), TOBN(0xcf52d098, 0xb5bd8770),
+ TOBN(0x15a15fa6, 0x0fd28921), TOBN(0x56ccb81e, 0x8b27536d),
+ TOBN(0x0f0d8ab8, 0x9f4ccbb8), TOBN(0xed5f44d2, 0xdb221729),
+ TOBN(0x43141988, 0x00bed10c), TOBN(0xc94348a4, 0x1d735b8b),
+ TOBN(0x79f3e9c4, 0x29ef8479), TOBN(0x4c13a4e3, 0x614c693f),
+ TOBN(0x32c9af56, 0x8e143a14), TOBN(0xbc517799, 0xe29ac5c4),
+ TOBN(0x05e17992, 0x2774856f), TOBN(0x6e52fb05, 0x6c1bf55f),
+ TOBN(0xaeda4225, 0xe4f19e16), TOBN(0x70f4728a, 0xaf5ccb26),
+ TOBN(0x5d2118d1, 0xb2947f22), TOBN(0xc827ea16, 0x281d6fb9),
+ TOBN(0x8412328d, 0x8cf0eabd), TOBN(0x45ee9fb2, 0x03ef9dcf),
+ TOBN(0x8e700421, 0xbb937d63), TOBN(0xdf8ff2d5, 0xcc4b37a6),
+ TOBN(0xa4c0d5b2, 0x5ced7b68), TOBN(0x6537c1ef, 0xc7308f59),
+ TOBN(0x25ce6a26, 0x3b37f8e8), TOBN(0x170e9a9b, 0xdeebc6ce),
+ TOBN(0xdd037952, 0x8728d72c), TOBN(0x445b0e55, 0x850154bc),
+ TOBN(0x4b7d0e06, 0x83a7337b), TOBN(0x1e3416d4, 0xffecf249),
+ TOBN(0x24840eff, 0x66a2b71f), TOBN(0xd0d9a50a, 0xb37cc26d),
+ TOBN(0xe2198150, 0x6fe28ef7), TOBN(0x3cc5ef16, 0x23324c7f),
+ TOBN(0x220f3455, 0x769b5263), TOBN(0xe2ade2f1, 0xa10bf475),
+ TOBN(0x28cd20fa, 0x458d3671), TOBN(0x1549722c, 0x2dc4847b),
+ TOBN(0x6dd01e55, 0x591941e3), TOBN(0x0e6fbcea, 0x27128ccb),
+ TOBN(0xae1a1e6b, 0x3bef0262), TOBN(0xfa8c472c, 0x8f54e103),
+ TOBN(0x7539c0a8, 0x72c052ec), TOBN(0xd7b27369, 0x5a3490e9),
+ TOBN(0x143fe1f1, 0x71684349), TOBN(0x36b4722e, 0x32e19b97),
+ TOBN(0xdc059227, 0x90980aff), TOBN(0x175c9c88, 0x9e13d674),
+ TOBN(0xa7de5b22, 0x6e6bfdb1), TOBN(0x5ea5b7b2, 0xbedb4b46),
+ TOBN(0xd5570191, 0xd34a6e44), TOBN(0xfcf60d2e, 0xa24ff7e6),
+ TOBN(0x614a392d, 0x677819e1), TOBN(0x7be74c7e, 0xaa5a29e8),
+ TOBN(0xab50fece, 0x63c85f3f), TOBN(0xaca2e2a9, 0x46cab337),
+ TOBN(0x7f700388, 0x122a6fe3), TOBN(0xdb69f703, 0x882a04a8),
+ TOBN(0x9a77935d, 0xcf7aed57), TOBN(0xdf16207c, 0x8d91c86f),
+ TOBN(0x2fca49ab, 0x63ed9998), TOBN(0xa3125c44, 0xa77ddf96),
+ TOBN(0x05dd8a86, 0x24344072), TOBN(0xa023dda2, 0xfec3fb56),
+ TOBN(0x421b41fc, 0x0c743032), TOBN(0x4f2120c1, 0x5e438639),
+ TOBN(0xfb7cae51, 0xc83c1b07), TOBN(0xb2370caa, 0xcac2171a),
+ TOBN(0x2eb2d962, 0x6cc820fb), TOBN(0x59feee5c, 0xb85a44bf),
+ TOBN(0x94620fca, 0x5b6598f0), TOBN(0x6b922cae, 0x7e314051),
+ TOBN(0xff8745ad, 0x106bed4e), TOBN(0x546e71f5, 0xdfa1e9ab),
+ TOBN(0x935c1e48, 0x1ec29487), TOBN(0x9509216c, 0x4d936530),
+ TOBN(0xc7ca3067, 0x85c9a2db), TOBN(0xd6ae5152, 0x6be8606f),
+ TOBN(0x09dbcae6, 0xe14c651d), TOBN(0xc9536e23, 0x9bc32f96),
+ TOBN(0xa90535a9, 0x34521b03), TOBN(0xf39c526c, 0x878756ff),
+ TOBN(0x383172ec, 0x8aedf03c), TOBN(0x20a8075e, 0xefe0c034),
+ TOBN(0xf22f9c62, 0x64026422), TOBN(0x8dd10780, 0x24b9d076),
+ TOBN(0x944c742a, 0x3bef2950), TOBN(0x55b9502e, 0x88a2b00b),
+ TOBN(0xa59e14b4, 0x86a09817), TOBN(0xa39dd3ac, 0x47bb4071),
+ TOBN(0x55137f66, 0x3be0592f), TOBN(0x07fcafd4, 0xc9e63f5b),
+ TOBN(0x963652ee, 0x346eb226), TOBN(0x7dfab085, 0xec2facb7),
+ TOBN(0x273bf2b8, 0x691add26), TOBN(0x30d74540, 0xf2b46c44),
+ TOBN(0x05e8e73e, 0xf2c2d065), TOBN(0xff9b8a00, 0xd42eeac9),
+ TOBN(0x2fcbd205, 0x97209d22), TOBN(0xeb740ffa, 0xde14ea2c),
+ TOBN(0xc71ff913, 0xa8aef518), TOBN(0x7bfc74bb, 0xfff4cfa2),
+ TOBN(0x1716680c, 0xb6b36048), TOBN(0x121b2cce, 0x9ef79af1),
+ TOBN(0xbff3c836, 0xa01eb3d3), TOBN(0x50eb1c6a, 0x5f79077b),
+ TOBN(0xa48c32d6, 0xa004bbcf), TOBN(0x47a59316, 0x7d64f61d),
+ TOBN(0x6068147f, 0x93102016), TOBN(0x12c5f654, 0x94d12576),
+ TOBN(0xefb071a7, 0xc9bc6b91), TOBN(0x7c2da0c5, 0x6e23ea95),
+ TOBN(0xf4fd45b6, 0xd4a1dd5d), TOBN(0x3e7ad9b6, 0x9122b13c),
+ TOBN(0x342ca118, 0xe6f57a48), TOBN(0x1c2e94a7, 0x06f8288f),
+ TOBN(0x99e68f07, 0x5a97d231), TOBN(0x7c80de97, 0x4d838758),
+ TOBN(0xbce0f5d0, 0x05872727), TOBN(0xbe5d95c2, 0x19c4d016),
+ TOBN(0x921d5cb1, 0x9c2492ee), TOBN(0x42192dc1, 0x404d6fb3),
+ TOBN(0x4c84dcd1, 0x32f988d3), TOBN(0xde26d61f, 0xa17b8e85),
+ TOBN(0xc466dcb6, 0x137c7408), TOBN(0x9a38d7b6, 0x36a266da),
+ TOBN(0x7ef5cb06, 0x83bebf1b), TOBN(0xe5cdcbbf, 0x0fd014e3),
+ TOBN(0x30aa376d, 0xf65965a0), TOBN(0x60fe88c2, 0xebb3e95e),
+ TOBN(0x33fd0b61, 0x66ee6f20), TOBN(0x8827dcdb, 0x3f41f0a0),
+ TOBN(0xbf8a9d24, 0x0c56c690), TOBN(0x40265dad, 0xddb7641d),
+ TOBN(0x522b05bf, 0x3a6b662b), TOBN(0x466d1dfe, 0xb1478c9b),
+ TOBN(0xaa616962, 0x1484469b), TOBN(0x0db60549, 0x02df8f9f),
+ TOBN(0xc37bca02, 0x3cb8bf51), TOBN(0x5effe346, 0x21371ce8),
+ TOBN(0xe8f65264, 0xff112c32), TOBN(0x8a9c736d, 0x7b971fb2),
+ TOBN(0xa4f19470, 0x7b75080d), TOBN(0xfc3f2c5a, 0x8839c59b),
+ TOBN(0x1d6c777e, 0x5aeb49c2), TOBN(0xf3db034d, 0xda1addfe),
+ TOBN(0xd76fee5a, 0x5535affc), TOBN(0x0853ac70, 0xb92251fd),
+ TOBN(0x37e3d594, 0x8b2a29d5), TOBN(0x28f1f457, 0x4de00ddb),
+ TOBN(0x8083c1b5, 0xf42c328b), TOBN(0xd8ef1d8f, 0xe493c73b),
+ TOBN(0x96fb6260, 0x41dc61bd), TOBN(0xf74e8a9d, 0x27ee2f8a),
+ TOBN(0x7c605a80, 0x2c946a5d), TOBN(0xeed48d65, 0x3839ccfd),
+ TOBN(0x9894344f, 0x3a29467a), TOBN(0xde81e949, 0xc51eba6d),
+ TOBN(0xdaea066b, 0xa5e5c2f2), TOBN(0x3fc8a614, 0x08c8c7b3),
+ TOBN(0x7adff88f, 0x06d0de9f), TOBN(0xbbc11cf5, 0x3b75ce0a),
+ TOBN(0x9fbb7acc, 0xfbbc87d5), TOBN(0xa1458e26, 0x7badfde2)},
+ {
+ TOBN(0x1cb43668, 0xe039c256), TOBN(0x5f26fb8b, 0x7c17fd5d),
+ TOBN(0xeee426af, 0x79aa062b), TOBN(0x072002d0, 0xd78fbf04),
+ TOBN(0x4c9ca237, 0xe84fb7e3), TOBN(0xb401d8a1, 0x0c82133d),
+ TOBN(0xaaa52592, 0x6d7e4181), TOBN(0xe9430833, 0x73dbb152),
+ TOBN(0xf92dda31, 0xbe24319a), TOBN(0x03f7d28b, 0xe095a8e7),
+ TOBN(0xa52fe840, 0x98782185), TOBN(0x276ddafe, 0x29c24dbc),
+ TOBN(0x80cd5496, 0x1d7a64eb), TOBN(0xe4360889, 0x7f1dbe42),
+ TOBN(0x2f81a877, 0x8438d2d5), TOBN(0x7e4d52a8, 0x85169036),
+ TOBN(0x19e3d5b1, 0x1d59715d), TOBN(0xc7eaa762, 0xd788983e),
+ TOBN(0xe5a730b0, 0xabf1f248), TOBN(0xfbab8084, 0xfae3fd83),
+ TOBN(0x65e50d21, 0x53765b2f), TOBN(0xbdd4e083, 0xfa127f3d),
+ TOBN(0x9cf3c074, 0x397b1b10), TOBN(0x59f8090c, 0xb1b59fd3),
+ TOBN(0x7b15fd9d, 0x615faa8f), TOBN(0x8fa1eb40, 0x968554ed),
+ TOBN(0x7bb4447e, 0x7aa44882), TOBN(0x2bb2d0d1, 0x029fff32),
+ TOBN(0x075e2a64, 0x6caa6d2f), TOBN(0x8eb879de, 0x22e7351b),
+ TOBN(0xbcd5624e, 0x9a506c62), TOBN(0x218eaef0, 0xa87e24dc),
+ TOBN(0x37e56847, 0x44ddfa35), TOBN(0x9ccfc5c5, 0xdab3f747),
+ TOBN(0x9ac1df3f, 0x1ee96cf4), TOBN(0x0c0571a1, 0x3b480b8f),
+ TOBN(0x2fbeb3d5, 0x4b3a7b3c), TOBN(0x35c03669, 0x5dcdbb99),
+ TOBN(0x52a0f5dc, 0xb2415b3a), TOBN(0xd57759b4, 0x4413ed9a),
+ TOBN(0x1fe647d8, 0x3d30a2c5), TOBN(0x0857f77e, 0xf78a81dc),
+ TOBN(0x11d5a334, 0x131a4a9b), TOBN(0xc0a94af9, 0x29d393f5),
+ TOBN(0xbc3a5c0b, 0xdaa6ec1a), TOBN(0xba9fe493, 0x88d2d7ed),
+ TOBN(0xbb4335b4, 0xbb614797), TOBN(0x991c4d68, 0x72f83533),
+ TOBN(0x53258c28, 0xd2f01cb3), TOBN(0x93d6eaa3, 0xd75db0b1),
+ TOBN(0x419a2b0d, 0xe87d0db4), TOBN(0xa1e48f03, 0xd8fe8493),
+ TOBN(0xf747faf6, 0xc508b23a), TOBN(0xf137571a, 0x35d53549),
+ TOBN(0x9f5e58e2, 0xfcf9b838), TOBN(0xc7186cee, 0xa7fd3cf5),
+ TOBN(0x77b868ce, 0xe978a1d3), TOBN(0xe3a68b33, 0x7ab92d04),
+ TOBN(0x51029794, 0x87a5b862), TOBN(0x5f0606c3, 0x3a61d41d),
+ TOBN(0x2814be27, 0x6f9326f1), TOBN(0x2f521c14, 0xc6fe3c2e),
+ TOBN(0x17464d7d, 0xacdf7351), TOBN(0x10f5f9d3, 0x777f7e44),
+ TOBN(0xce8e616b, 0x269fb37d), TOBN(0xaaf73804, 0x7de62de5),
+ TOBN(0xaba11175, 0x4fdd4153), TOBN(0x515759ba, 0x3770b49b),
+ TOBN(0x8b09ebf8, 0xaa423a61), TOBN(0x592245a1, 0xcd41fb92),
+ TOBN(0x1cba8ec1, 0x9b4c8936), TOBN(0xa87e91e3, 0xaf36710e),
+ TOBN(0x1fd84ce4, 0x3d34a2e3), TOBN(0xee3759ce, 0xb43b5d61),
+ TOBN(0x895bc78c, 0x619186c7), TOBN(0xf19c3809, 0xcbb9725a),
+ TOBN(0xc0be21aa, 0xde744b1f), TOBN(0xa7d222b0, 0x60f8056b),
+ TOBN(0x74be6157, 0xb23efe11), TOBN(0x6fab2b4f, 0x0cd68253),
+ TOBN(0xad33ea5f, 0x4bf1d725), TOBN(0x9c1d8ee2, 0x4f6c950f),
+ TOBN(0x544ee78a, 0xa377af06), TOBN(0x54f489bb, 0x94a113e1),
+ TOBN(0x8f11d634, 0x992fb7e8), TOBN(0x0169a7aa, 0xa2a44347),
+ TOBN(0x1d49d4af, 0x95020e00), TOBN(0x95945722, 0xe08e120b),
+ TOBN(0xb6e33878, 0xa4d32282), TOBN(0xe36e029d, 0x48020ae7),
+ TOBN(0xe05847fb, 0x37a9b750), TOBN(0xf876812c, 0xb29e3819),
+ TOBN(0x84ad138e, 0xd23a17f0), TOBN(0x6d7b4480, 0xf0b3950e),
+ TOBN(0xdfa8aef4, 0x2fd67ae0), TOBN(0x8d3eea24, 0x52333af6),
+ TOBN(0x0d052075, 0xb15d5acc), TOBN(0xc6d9c79f, 0xbd815bc4),
+ TOBN(0x8dcafd88, 0xdfa36cf2), TOBN(0x908ccbe2, 0x38aa9070),
+ TOBN(0x638722c4, 0xba35afce), TOBN(0x5a3da8b0, 0xfd6abf0b),
+ TOBN(0x2dce252c, 0xc9c335c1), TOBN(0x84e7f0de, 0x65aa799b),
+ TOBN(0x2101a522, 0xb99a72cb), TOBN(0x06de6e67, 0x87618016),
+ TOBN(0x5ff8c7cd, 0xe6f3653e), TOBN(0x0a821ab5, 0xc7a6754a),
+ TOBN(0x7e3fa52b, 0x7cb0b5a2), TOBN(0xa7fb121c, 0xc9048790),
+ TOBN(0x1a725020, 0x06ce053a), TOBN(0xb490a31f, 0x04e929b0),
+ TOBN(0xe17be47d, 0x62dd61ad), TOBN(0x781a961c, 0x6be01371),
+ TOBN(0x1063bfd3, 0xdae3cbba), TOBN(0x35647406, 0x7f73c9ba),
+ TOBN(0xf50e957b, 0x2736a129), TOBN(0xa6313702, 0xed13f256),
+ TOBN(0x9436ee65, 0x3a19fcc5), TOBN(0xcf2bdb29, 0xe7a4c8b6),
+ TOBN(0xb06b1244, 0xc5f95cd8), TOBN(0xda8c8af0, 0xf4ab95f4),
+ TOBN(0x1bae59c2, 0xb9e5836d), TOBN(0x07d51e7e, 0x3acffffc),
+ TOBN(0x01e15e6a, 0xc2ccbcda), TOBN(0x3bc1923f, 0x8528c3e0),
+ TOBN(0x43324577, 0xa49fead4), TOBN(0x61a1b884, 0x2aa7a711),
+ TOBN(0xf9a86e08, 0x700230ef), TOBN(0x0af585a1, 0xbd19adf8),
+ TOBN(0x7645f361, 0xf55ad8f2), TOBN(0x6e676223, 0x46c3614c),
+ TOBN(0x23cb257c, 0x4e774d3f), TOBN(0x82a38513, 0xac102d1b),
+ TOBN(0x9bcddd88, 0x7b126aa5), TOBN(0xe716998b, 0xeefd3ee4),
+ TOBN(0x4239d571, 0xfb167583), TOBN(0xdd011c78, 0xd16c8f8a),
+ TOBN(0x271c2895, 0x69a27519), TOBN(0x9ce0a3b7, 0xd2d64b6a),
+ TOBN(0x8c977289, 0xd5ec6738), TOBN(0xa3b49f9a, 0x8840ef6b),
+ TOBN(0x808c14c9, 0x9a453419), TOBN(0x5c00295b, 0x0cf0a2d5),
+ TOBN(0x524414fb, 0x1d4bcc76), TOBN(0xb07691d2, 0x459a88f1),
+ TOBN(0x77f43263, 0xf70d110f), TOBN(0x64ada5e0, 0xb7abf9f3),
+ TOBN(0xafd0f94e, 0x5b544cf5), TOBN(0xb4a13a15, 0xfd2713fe),
+ TOBN(0xb99b7d6e, 0x250c74f4), TOBN(0x097f2f73, 0x20324e45),
+ TOBN(0x994b37d8, 0xaffa8208), TOBN(0xc3c31b0b, 0xdc29aafc),
+ TOBN(0x3da74651, 0x7a3a607f), TOBN(0xd8e1b8c1, 0xfe6955d6),
+ TOBN(0x716e1815, 0xc8418682), TOBN(0x541d487f, 0x7dc91d97),
+ TOBN(0x48a04669, 0xc6996982), TOBN(0xf39cab15, 0x83a6502e),
+ TOBN(0x025801a0, 0xe68db055), TOBN(0xf3569758, 0xba3338d5),
+ TOBN(0xb0c8c0aa, 0xee2afa84), TOBN(0x4f6985d3, 0xfb6562d1),
+ TOBN(0x351f1f15, 0x132ed17a), TOBN(0x510ed0b4, 0xc04365fe),
+ TOBN(0xa3f98138, 0xe5b1f066), TOBN(0xbc9d95d6, 0x32df03dc),
+ TOBN(0xa83ccf6e, 0x19abd09e), TOBN(0x0b4097c1, 0x4ff17edb),
+ TOBN(0x58a5c478, 0xd64a06ce), TOBN(0x2ddcc3fd, 0x544a58fd),
+ TOBN(0xd449503d, 0x9e8153b8), TOBN(0x3324fd02, 0x7774179b),
+ TOBN(0xaf5d47c8, 0xdbd9120c), TOBN(0xeb860162, 0x34fa94db),
+ TOBN(0x5817bdd1, 0x972f07f4), TOBN(0xe5579e2e, 0xd27bbceb),
+ TOBN(0x86847a1f, 0x5f11e5a6), TOBN(0xb39ed255, 0x7c3cf048),
+ TOBN(0xe1076417, 0xa2f62e55), TOBN(0x6b9ab38f, 0x1bcf82a2),
+ TOBN(0x4bb7c319, 0x7aeb29f9), TOBN(0xf6d17da3, 0x17227a46),
+ TOBN(0xab53ddbd, 0x0f968c00), TOBN(0xa03da7ec, 0x000c880b),
+ TOBN(0x7b239624, 0x6a9ad24d), TOBN(0x612c0401, 0x01ec60d0),
+ TOBN(0x70d10493, 0x109f5df1), TOBN(0xfbda4030, 0x80af7550),
+ TOBN(0x30b93f95, 0xc6b9a9b3), TOBN(0x0c74ec71, 0x007d9418),
+ TOBN(0x94175564, 0x6edb951f), TOBN(0x5f4a9d78, 0x7f22c282),
+ TOBN(0xb7870895, 0xb38d1196), TOBN(0xbc593df3, 0xa228ce7c),
+ TOBN(0xc78c5bd4, 0x6af3641a), TOBN(0x7802200b, 0x3d9b3dcc),
+ TOBN(0x0dc73f32, 0x8be33304), TOBN(0x847ed87d, 0x61ffb79a),
+ TOBN(0xf85c974e, 0x6d671192), TOBN(0x1e14100a, 0xde16f60f),
+ TOBN(0x45cb0d5a, 0x95c38797), TOBN(0x18923bba, 0x9b022da4),
+ TOBN(0xef2be899, 0xbbe7e86e), TOBN(0x4a1510ee, 0x216067bf),
+ TOBN(0xd98c8154, 0x84d5ce3e), TOBN(0x1af777f0, 0xf92a2b90),
+ TOBN(0x9fbcb400, 0x4ef65724), TOBN(0x3e04a4c9, 0x3c0ca6fe),
+ TOBN(0xfb3e2cb5, 0x55002994), TOBN(0x1f3a93c5, 0x5363ecab),
+ TOBN(0x1fe00efe, 0x3923555b), TOBN(0x744bedd9, 0x1e1751ea),
+ TOBN(0x3fb2db59, 0x6ab69357), TOBN(0x8dbd7365, 0xf5e6618b),
+ TOBN(0x99d53099, 0xdf1ea40e), TOBN(0xb3f24a0b, 0x57d61e64),
+ TOBN(0xd088a198, 0x596eb812), TOBN(0x22c8361b, 0x5762940b),
+ TOBN(0x66f01f97, 0xf9c0d95c), TOBN(0x88461172, 0x8e43cdae),
+ TOBN(0x11599a7f, 0xb72b15c3), TOBN(0x135a7536, 0x420d95cc),
+ TOBN(0x2dcdf0f7, 0x5f7ae2f6), TOBN(0x15fc6e1d, 0xd7fa6da2),
+ TOBN(0x81ca829a, 0xd1d441b6), TOBN(0x84c10cf8, 0x04a106b6),
+ TOBN(0xa9b26c95, 0xa73fbbd0), TOBN(0x7f24e0cb, 0x4d8f6ee8),
+ TOBN(0x48b45937, 0x1e25a043), TOBN(0xf8a74fca, 0x036f3dfe),
+ TOBN(0x1ed46585, 0xc9f84296), TOBN(0x7fbaa8fb, 0x3bc278b0),
+ TOBN(0xa8e96cd4, 0x6c4fcbd0), TOBN(0x940a1202, 0x73b60a5f),
+ TOBN(0x34aae120, 0x55a4aec8), TOBN(0x550e9a74, 0xdbd742f0),
+ TOBN(0x794456d7, 0x228c68ab), TOBN(0x492f8868, 0xa4e25ec6),
+ TOBN(0x682915ad, 0xb2d8f398), TOBN(0xf13b51cc, 0x5b84c953),
+ TOBN(0xcda90ab8, 0x5bb917d6), TOBN(0x4b615560, 0x4ea3dee1),
+ TOBN(0x578b4e85, 0x0a52c1c8), TOBN(0xeab1a695, 0x20b75fc4),
+ TOBN(0x60c14f3c, 0xaa0bb3c6), TOBN(0x220f448a, 0xb8216094),
+ TOBN(0x4fe7ee31, 0xb0e63d34), TOBN(0xf4600572, 0xa9e54fab),
+ TOBN(0xc0493334, 0xd5e7b5a4), TOBN(0x8589fb92, 0x06d54831),
+ TOBN(0xaa70f5cc, 0x6583553a), TOBN(0x0879094a, 0xe25649e5),
+ TOBN(0xcc904507, 0x10044652), TOBN(0xebb0696d, 0x02541c4f),
+ TOBN(0x5a171fde, 0xb9718710), TOBN(0x38f1bed8, 0xf374a9f5),
+ TOBN(0xc8c582e1, 0xba39bdc1), TOBN(0xfc457b0a, 0x908cc0ce),
+ TOBN(0x9a187fd4, 0x883841e2), TOBN(0x8ec25b39, 0x38725381),
+ TOBN(0x2553ed05, 0x96f84395), TOBN(0x095c7661, 0x6f6c6897),
+ TOBN(0x917ac85c, 0x4bdc5610), TOBN(0xb2885fe4, 0x179eb301),
+ TOBN(0x5fc65547, 0x8b78bdcc), TOBN(0x4a9fc893, 0xe59e4699),
+ TOBN(0xbb7ff0cd, 0x3ce299af), TOBN(0x195be9b3, 0xadf38b20),
+ TOBN(0x6a929c87, 0xd38ddb8f), TOBN(0x55fcc99c, 0xb21a51b9),
+ TOBN(0x2b695b4c, 0x721a4593), TOBN(0xed1e9a15, 0x768eaac2),
+ TOBN(0xfb63d71c, 0x7489f914), TOBN(0xf98ba31c, 0x78118910),
+ TOBN(0x80291373, 0x9b128eb4), TOBN(0x7801214e, 0xd448af4a),
+ TOBN(0xdbd2e22b, 0x55418dd3), TOBN(0xeffb3c0d, 0xd3998242),
+ TOBN(0xdfa6077c, 0xc7bf3827), TOBN(0xf2165bcb, 0x47f8238f),
+ TOBN(0xfe37cf68, 0x8564d554), TOBN(0xe5f825c4, 0x0a81fb98),
+ TOBN(0x43cc4f67, 0xffed4d6f), TOBN(0xbc609578, 0xb50a34b0),
+ TOBN(0x8aa8fcf9, 0x5041faf1), TOBN(0x5659f053, 0x651773b6),
+ TOBN(0xe87582c3, 0x6044d63b), TOBN(0xa6089409, 0x0cdb0ca0),
+ TOBN(0x8c993e0f, 0xbfb2bcf6), TOBN(0xfc64a719, 0x45985cfc),
+ TOBN(0x15c4da80, 0x83dbedba), TOBN(0x804ae112, 0x2be67df7),
+ TOBN(0xda4c9658, 0xa23defde), TOBN(0x12002ddd, 0x5156e0d3),
+ TOBN(0xe68eae89, 0x5dd21b96), TOBN(0x8b99f28b, 0xcf44624d),
+ TOBN(0x0ae00808, 0x1ec8897a), TOBN(0xdd0a9303, 0x6712f76e),
+ TOBN(0x96237522, 0x4e233de4), TOBN(0x192445b1, 0x2b36a8a5),
+ TOBN(0xabf9ff74, 0x023993d9), TOBN(0x21f37bf4, 0x2aad4a8f),
+ TOBN(0x340a4349, 0xf8bd2bbd), TOBN(0x1d902cd9, 0x4868195d),
+ TOBN(0x3d27bbf1, 0xe5fdb6f1), TOBN(0x7a5ab088, 0x124f9f1c),
+ TOBN(0xc466ab06, 0xf7a09e03), TOBN(0x2f8a1977, 0x31f2c123),
+ TOBN(0xda355dc7, 0x041b6657), TOBN(0xcb840d12, 0x8ece2a7c),
+ TOBN(0xb600ad9f, 0x7db32675), TOBN(0x78fea133, 0x07a06f1b),
+ TOBN(0x5d032269, 0xb31f6094), TOBN(0x07753ef5, 0x83ec37aa),
+ TOBN(0x03485aed, 0x9c0bea78), TOBN(0x41bb3989, 0xbc3f4524),
+ TOBN(0x09403761, 0x697f726d), TOBN(0x6109beb3, 0xdf394820),
+ TOBN(0x804111ea, 0x3b6d1145), TOBN(0xb6271ea9, 0xa8582654),
+ TOBN(0x619615e6, 0x24e66562), TOBN(0xa2554945, 0xd7b6ad9c),
+ TOBN(0xd9c4985e, 0x99bfe35f), TOBN(0x9770ccc0, 0x7b51cdf6),
+ TOBN(0x7c327013, 0x92881832), TOBN(0x8777d45f, 0x286b26d1),
+ TOBN(0x9bbeda22, 0xd847999d), TOBN(0x03aa33b6, 0xc3525d32),
+ TOBN(0x4b7b96d4, 0x28a959a1), TOBN(0xbb3786e5, 0x31e5d234),
+ TOBN(0xaeb5d3ce, 0x6961f247), TOBN(0x20aa85af, 0x02f93d3f),
+ TOBN(0x9cd1ad3d, 0xd7a7ae4f), TOBN(0xbf6688f0, 0x781adaa8),
+ TOBN(0xb1b40e86, 0x7469cead), TOBN(0x1904c524, 0x309fca48),
+ TOBN(0x9b7312af, 0x4b54bbc7), TOBN(0xbe24bf8f, 0x593affa2),
+ TOBN(0xbe5e0790, 0xbd98764b), TOBN(0xa0f45f17, 0xa26e299e),
+ TOBN(0x4af0d2c2, 0x6b8fe4c7), TOBN(0xef170db1, 0x8ae8a3e6),
+ TOBN(0x0e8d61a0, 0x29e0ccc1), TOBN(0xcd53e87e, 0x60ad36ca),
+ TOBN(0x328c6623, 0xc8173822), TOBN(0x7ee1767d, 0xa496be55),
+ TOBN(0x89f13259, 0x648945af), TOBN(0x9e45a5fd, 0x25c8009c),
+ TOBN(0xaf2febd9, 0x1f61ab8c), TOBN(0x43f6bc86, 0x8a275385),
+ TOBN(0x87792348, 0xf2142e79), TOBN(0x17d89259, 0xc6e6238a),
+ TOBN(0x7536d2f6, 0x4a839d9b), TOBN(0x1f428fce, 0x76a1fbdc),
+ TOBN(0x1c109601, 0x0db06dfe), TOBN(0xbfc16bc1, 0x50a3a3cc),
+ TOBN(0xf9cbd9ec, 0x9b30f41b), TOBN(0x5b5da0d6, 0x00138cce),
+ TOBN(0xec1d0a48, 0x56ef96a7), TOBN(0xb47eb848, 0x982bf842),
+ TOBN(0x66deae32, 0xec3f700d), TOBN(0x4e43c42c, 0xaa1181e0),
+ TOBN(0xa1d72a31, 0xd1a4aa2a), TOBN(0x440d4668, 0xc004f3ce),
+ TOBN(0x0d6a2d3b, 0x45fe8a7a), TOBN(0x820e52e2, 0xfb128365),
+ TOBN(0x29ac5fcf, 0x25e51b09), TOBN(0x180cd2bf, 0x2023d159),
+ TOBN(0xa9892171, 0xa1ebf90e), TOBN(0xf97c4c87, 0x7c132181),
+ TOBN(0x9f1dc724, 0xc03dbb7e), TOBN(0xae043765, 0x018cbbe4),
+ TOBN(0xfb0b2a36, 0x0767d153), TOBN(0xa8e2f4d6, 0x249cbaeb),
+ TOBN(0x172a5247, 0xd95ea168), TOBN(0x1758fada, 0x2970764a),
+ TOBN(0xac803a51, 0x1d978169), TOBN(0x299cfe2e, 0xde77e01b),
+ TOBN(0x652a1e17, 0xb0a98927), TOBN(0x2e26e1d1, 0x20014495),
+ TOBN(0x7ae0af9f, 0x7175b56a), TOBN(0xc2e22a80, 0xd64b9f95),
+ TOBN(0x4d0ff9fb, 0xd90a060a), TOBN(0x496a27db, 0xbaf38085),
+ TOBN(0x32305401, 0xda776bcf), TOBN(0xb8cdcef6, 0x725f209e),
+ TOBN(0x61ba0f37, 0x436a0bba), TOBN(0x263fa108, 0x76860049),
+ TOBN(0x92beb98e, 0xda3542cf), TOBN(0xa2d4d14a, 0xd5849538),
+ TOBN(0x989b9d68, 0x12e9a1bc), TOBN(0x61d9075c, 0x5f6e3268),
+ TOBN(0x352c6aa9, 0x99ace638), TOBN(0xde4e4a55, 0x920f43ff),
+ TOBN(0xe5e4144a, 0xd673c017), TOBN(0x667417ae, 0x6f6e05ea),
+ TOBN(0x613416ae, 0xdcd1bd56), TOBN(0x5eb36201, 0x86693711),
+ TOBN(0x2d7bc504, 0x3a1aa914), TOBN(0x175a1299, 0x76dc5975),
+ TOBN(0xe900e0f2, 0x3fc8125c), TOBN(0x569ef68c, 0x11198875),
+ TOBN(0x9012db63, 0x63a113b4), TOBN(0xe3bd3f56, 0x98835766),
+ TOBN(0xa5c94a52, 0x76412dea), TOBN(0xad9e2a09, 0xaa735e5c),
+ TOBN(0x405a984c, 0x508b65e9), TOBN(0xbde4a1d1, 0x6df1a0d1),
+ TOBN(0x1a9433a1, 0xdfba80da), TOBN(0xe9192ff9, 0x9440ad2e),
+ TOBN(0x9f649696, 0x5099fe92), TOBN(0x25ddb65c, 0x0b27a54a),
+ TOBN(0x178279dd, 0xc590da61), TOBN(0x5479a999, 0xfbde681a),
+ TOBN(0xd0e84e05, 0x013fe162), TOBN(0xbe11dc92, 0x632d471b),
+ TOBN(0xdf0b0c45, 0xfc0e089f), TOBN(0x04fb15b0, 0x4c144025),
+ TOBN(0xa61d5fc2, 0x13c99927), TOBN(0xa033e9e0, 0x3de2eb35),
+ TOBN(0xf8185d5c, 0xb8dacbb4), TOBN(0x9a88e265, 0x8644549d),
+ TOBN(0xf717af62, 0x54671ff6), TOBN(0x4bd4241b, 0x5fa58603),
+ TOBN(0x06fba40b, 0xe67773c0), TOBN(0xc1d933d2, 0x6a2847e9),
+ TOBN(0xf4f5acf3, 0x689e2c70), TOBN(0x92aab0e7, 0x46bafd31),
+ TOBN(0x798d76aa, 0x3473f6e5), TOBN(0xcc6641db, 0x93141934),
+ TOBN(0xcae27757, 0xd31e535e), TOBN(0x04cc43b6, 0x87c2ee11),
+ TOBN(0x8d1f9675, 0x2e029ffa), TOBN(0xc2150672, 0xe4cc7a2c),
+ TOBN(0x3b03c1e0, 0x8d68b013), TOBN(0xa9d6816f, 0xedf298f3),
+ TOBN(0x1bfbb529, 0xa2804464), TOBN(0x95a52fae, 0x5db22125),
+ TOBN(0x55b32160, 0x0e1cb64e), TOBN(0x004828f6, 0x7e7fc9fe),
+ TOBN(0x13394b82, 0x1bb0fb93), TOBN(0xb6293a2d, 0x35f1a920),
+ TOBN(0xde35ef21, 0xd145d2d9), TOBN(0xbe6225b3, 0xbb8fa603),
+ TOBN(0x00fc8f6b, 0x32cf252d), TOBN(0xa28e52e6, 0x117cf8c2),
+ TOBN(0x9d1dc89b, 0x4c371e6d), TOBN(0xcebe0675, 0x36ef0f28),
+ TOBN(0x5de05d09, 0xa4292f81), TOBN(0xa8303593, 0x353e3083),
+ TOBN(0xa1715b0a, 0x7e37a9bb), TOBN(0x8c56f61e, 0x2b8faec3),
+ TOBN(0x52507431, 0x33c9b102), TOBN(0x0130cefc, 0xa44431f0),
+ TOBN(0x56039fa0, 0xbd865cfb), TOBN(0x4b03e578, 0xbc5f1dd7),
+ TOBN(0x40edf2e4, 0xbabe7224), TOBN(0xc752496d, 0x3a1988f6),
+ TOBN(0xd1572d3b, 0x564beb6b), TOBN(0x0db1d110, 0x39a1c608),
+ TOBN(0x568d1934, 0x16f60126), TOBN(0x05ae9668, 0xf354af33),
+ TOBN(0x19de6d37, 0xc92544f2), TOBN(0xcc084353, 0xa35837d5),
+ TOBN(0xcbb6869c, 0x1a514ece), TOBN(0xb633e728, 0x2e1d1066),
+ TOBN(0xf15dd69f, 0x936c581c), TOBN(0x96e7b8ce, 0x7439c4f9),
+ TOBN(0x5e676f48, 0x2e448a5b), TOBN(0xb2ca7d5b, 0xfd916bbb),
+ TOBN(0xd55a2541, 0xf5024025), TOBN(0x47bc5769, 0xe4c2d937),
+ TOBN(0x7d31b92a, 0x0362189f), TOBN(0x83f3086e, 0xef7816f9),
+ TOBN(0xf9f46d94, 0xb587579a), TOBN(0xec2d22d8, 0x30e76c5f),
+ TOBN(0x27d57461, 0xb000ffcf), TOBN(0xbb7e65f9, 0x364ffc2c),
+ TOBN(0x7c7c9477, 0x6652a220), TOBN(0x61618f89, 0xd696c981),
+ TOBN(0x5021701d, 0x89effff3), TOBN(0xf2c8ff8e, 0x7c314163),
+ TOBN(0x2da413ad, 0x8efb4d3e), TOBN(0x937b5adf, 0xce176d95),
+ TOBN(0x22867d34, 0x2a67d51c), TOBN(0x262b9b10, 0x18eb3ac9),
+ TOBN(0x4e314fe4, 0xc43ff28b), TOBN(0x76476627, 0x6a664e7a),
+ TOBN(0x3e90e40b, 0xb7a565c2), TOBN(0x8588993a, 0xc1acf831),
+ TOBN(0xd7b501d6, 0x8f938829), TOBN(0x996627ee, 0x3edd7d4c),
+ TOBN(0x37d44a62, 0x90cd34c7), TOBN(0xa8327499, 0xf3833e8d),
+ TOBN(0x2e18917d, 0x4bf50353), TOBN(0x85dd726b, 0x556765fb),
+ TOBN(0x54fe65d6, 0x93d5ab66), TOBN(0x3ddbaced, 0x915c25fe),
+ TOBN(0xa799d9a4, 0x12f22e85), TOBN(0xe2a24867, 0x6d06f6bc),
+ TOBN(0xf4f1ee56, 0x43ca1637), TOBN(0xfda2828b, 0x61ece30a),
+ TOBN(0x758c1a3e, 0xa2dee7a6), TOBN(0xdcde2f3c, 0x734b2284),
+ TOBN(0xaba445d2, 0x4eaba6ad), TOBN(0x35aaf668, 0x76cee0a7),
+ TOBN(0x7e0b04a9, 0xe5aa049a), TOBN(0xe74083ad, 0x91103e84),
+ TOBN(0xbeb183ce, 0x40afecc3), TOBN(0x6b89de9f, 0xea043f7a),
+ },
+ {TOBN(0x0e299d23, 0xfe67ba66), TOBN(0x91450760, 0x93cf2f34),
+ TOBN(0xf45b5ea9, 0x97fcf913), TOBN(0x5be00843, 0x8bd7ddda),
+ TOBN(0x358c3e05, 0xd53ff04d), TOBN(0xbf7ccdc3, 0x5de91ef7),
+ TOBN(0xad684dbf, 0xb69ec1a0), TOBN(0x367e7cf2, 0x801fd997),
+ TOBN(0x0ca1f3b7, 0xb0dc8595), TOBN(0x27de4608, 0x9f1d9f2e),
+ TOBN(0x1af3bf39, 0xbadd82a7), TOBN(0x79356a79, 0x65862448),
+ TOBN(0xc0602345, 0xf5f9a052), TOBN(0x1a8b0f89, 0x139a42f9),
+ TOBN(0xb53eee42, 0x844d40fc), TOBN(0x93b0bfe5, 0x4e5b6368),
+ TOBN(0x5434dd02, 0xc024789c), TOBN(0x90dca9ea, 0x41b57bfc),
+ TOBN(0x8aa898e2, 0x243398df), TOBN(0xf607c834, 0x894a94bb),
+ TOBN(0xbb07be97, 0xc2c99b76), TOBN(0x6576ba67, 0x18c29302),
+ TOBN(0x3d79efcc, 0xe703a88c), TOBN(0xf259ced7, 0xb6a0d106),
+ TOBN(0x0f893a5d, 0xc8de610b), TOBN(0xe8c515fb, 0x67e223ce),
+ TOBN(0x7774bfa6, 0x4ead6dc5), TOBN(0x89d20f95, 0x925c728f),
+ TOBN(0x7a1e0966, 0x098583ce), TOBN(0xa2eedb94, 0x93f2a7d7),
+ TOBN(0x1b282097, 0x4c304d4a), TOBN(0x0842e3da, 0xc077282d),
+ TOBN(0xe4d972a3, 0x3b9e2d7b), TOBN(0x7cc60b27, 0xc48218ff),
+ TOBN(0x8fc70838, 0x84149d91), TOBN(0x5c04346f, 0x2f461ecc),
+ TOBN(0xebe9fdf2, 0x614650a9), TOBN(0x5e35b537, 0xc1f666ac),
+ TOBN(0x645613d1, 0x88babc83), TOBN(0x88cace3a, 0xc5e1c93e),
+ TOBN(0x209ca375, 0x3de92e23), TOBN(0xccb03cc8, 0x5fbbb6e3),
+ TOBN(0xccb90f03, 0xd7b1487e), TOBN(0xfa9c2a38, 0xc710941f),
+ TOBN(0x756c3823, 0x6724ceed), TOBN(0x3a902258, 0x192d0323),
+ TOBN(0xb150e519, 0xea5e038e), TOBN(0xdcba2865, 0xc7427591),
+ TOBN(0xe549237f, 0x78890732), TOBN(0xc443bef9, 0x53fcb4d9),
+ TOBN(0x9884d8a6, 0xeb3480d6), TOBN(0x8a35b6a1, 0x3048b186),
+ TOBN(0xb4e44716, 0x65e9a90a), TOBN(0x45bf380d, 0x653006c0),
+ TOBN(0x8f3f820d, 0x4fe9ae3b), TOBN(0x244a35a0, 0x979a3b71),
+ TOBN(0xa1010e9d, 0x74cd06ff), TOBN(0x9c17c7df, 0xaca3eeac),
+ TOBN(0x74c86cd3, 0x8063aa2b), TOBN(0x8595c4b3, 0x734614ff),
+ TOBN(0xa3de00ca, 0x990f62cc), TOBN(0xd9bed213, 0xca0c3be5),
+ TOBN(0x7886078a, 0xdf8ce9f5), TOBN(0xddb27ce3, 0x5cd44444),
+ TOBN(0xed374a66, 0x58926ddd), TOBN(0x138b2d49, 0x908015b8),
+ TOBN(0x886c6579, 0xde1f7ab8), TOBN(0x888b9aa0, 0xc3020b7a),
+ TOBN(0xd3ec034e, 0x3a96e355), TOBN(0xba65b0b8, 0xf30fbe9a),
+ TOBN(0x064c8e50, 0xff21367a), TOBN(0x1f508ea4, 0x0b04b46e),
+ TOBN(0x98561a49, 0x747c866c), TOBN(0xbbb1e5fe, 0x0518a062),
+ TOBN(0x20ff4e8b, 0xecdc3608), TOBN(0x7f55cded, 0x20184027),
+ TOBN(0x8d73ec95, 0xf38c85f0), TOBN(0x5b589fdf, 0x8bc3b8c3),
+ TOBN(0xbe95dd98, 0x0f12b66f), TOBN(0xf5bd1a09, 0x0e338e01),
+ TOBN(0x65163ae5, 0x5e915918), TOBN(0x6158d6d9, 0x86f8a46b),
+ TOBN(0x8466b538, 0xeeebf99c), TOBN(0xca8761f6, 0xbca477ef),
+ TOBN(0xaf3449c2, 0x9ebbc601), TOBN(0xef3b0f41, 0xe0c3ae2f),
+ TOBN(0xaa6c577d, 0x5de63752), TOBN(0xe9166601, 0x64682a51),
+ TOBN(0x5a3097be, 0xfc15aa1e), TOBN(0x40d12548, 0xb54b0745),
+ TOBN(0x5bad4706, 0x519a5f12), TOBN(0xed03f717, 0xa439dee6),
+ TOBN(0x0794bb6c, 0x4a02c499), TOBN(0xf725083d, 0xcffe71d2),
+ TOBN(0x2cad7519, 0x0f3adcaf), TOBN(0x7f68ea1c, 0x43729310),
+ TOBN(0xe747c8c7, 0xb7ffd977), TOBN(0xec104c35, 0x80761a22),
+ TOBN(0x8395ebaf, 0x5a3ffb83), TOBN(0xfb3261f4, 0xe4b63db7),
+ TOBN(0x53544960, 0xd883e544), TOBN(0x13520d70, 0x8cc2eeb8),
+ TOBN(0x08f6337b, 0xd3d65f99), TOBN(0x83997db2, 0x781cf95b),
+ TOBN(0xce6ff106, 0x0dbd2c01), TOBN(0x4f8eea6b, 0x1f9ce934),
+ TOBN(0x546f7c4b, 0x0e993921), TOBN(0x6236a324, 0x5e753fc7),
+ TOBN(0x65a41f84, 0xa16022e9), TOBN(0x0c18d878, 0x43d1dbb2),
+ TOBN(0x73c55640, 0x2d4cef9c), TOBN(0xa0428108, 0x70444c74),
+ TOBN(0x68e4f15e, 0x9afdfb3c), TOBN(0x49a56143, 0x5bdfb6df),
+ TOBN(0xa9bc1bd4, 0x5f823d97), TOBN(0xbceb5970, 0xea111c2a),
+ TOBN(0x366b455f, 0xb269bbc4), TOBN(0x7cd85e1e, 0xe9bc5d62),
+ TOBN(0xc743c41c, 0x4f18b086), TOBN(0xa4b40990, 0x95294fb9),
+ TOBN(0x9c7c581d, 0x26ee8382), TOBN(0xcf17dcc5, 0x359d638e),
+ TOBN(0xee8273ab, 0xb728ae3d), TOBN(0x1d112926, 0xf821f047),
+ TOBN(0x11498477, 0x50491a74), TOBN(0x687fa761, 0xfde0dfb9),
+ TOBN(0x2c258022, 0x7ea435ab), TOBN(0x6b8bdb94, 0x91ce7e3f),
+ TOBN(0x4c5b5dc9, 0x3bf834aa), TOBN(0x04371819, 0x4f6c7e4b),
+ TOBN(0xc284e00a, 0x3736bcad), TOBN(0x0d881118, 0x21ae8f8d),
+ TOBN(0xf9cf0f82, 0xf48c8e33), TOBN(0xa11fd075, 0xa1bf40db),
+ TOBN(0xdceab0de, 0xdc2733e5), TOBN(0xc560a8b5, 0x8e986bd7),
+ TOBN(0x48dd1fe2, 0x3929d097), TOBN(0x3885b290, 0x92f188f1),
+ TOBN(0x0f2ae613, 0xda6fcdac), TOBN(0x9054303e, 0xb662a46c),
+ TOBN(0xb6871e44, 0x0738042a), TOBN(0x98e6a977, 0xbdaf6449),
+ TOBN(0xd8bc0650, 0xd1c9df1b), TOBN(0xef3d6451, 0x36e098f9),
+ TOBN(0x03fbae82, 0xb6d72d28), TOBN(0x77ca9db1, 0xf5d84080),
+ TOBN(0x8a112cff, 0xa58efc1c), TOBN(0x518d761c, 0xc564cb4a),
+ TOBN(0x69b5740e, 0xf0d1b5ce), TOBN(0x717039cc, 0xe9eb1785),
+ TOBN(0x3fe29f90, 0x22f53382), TOBN(0x8e54ba56, 0x6bc7c95c),
+ TOBN(0x9c806d8a, 0xf7f91d0f), TOBN(0x3b61b0f1, 0xa82a5728),
+ TOBN(0x4640032d, 0x94d76754), TOBN(0x273eb5de, 0x47d834c6),
+ TOBN(0x2988abf7, 0x7b4e4d53), TOBN(0xb7ce66bf, 0xde401777),
+ TOBN(0x9fba6b32, 0x715071b3), TOBN(0x82413c24, 0xad3a1a98),
+ TOBN(0x5b7fc8c4, 0xe0e8ad93), TOBN(0xb5679aee, 0x5fab868d),
+ TOBN(0xb1f9d2fa, 0x2b3946f3), TOBN(0x458897dc, 0x5685b50a),
+ TOBN(0x1e98c930, 0x89d0caf3), TOBN(0x39564c5f, 0x78642e92),
+ TOBN(0x1b77729a, 0x0dbdaf18), TOBN(0xf9170722, 0x579e82e6),
+ TOBN(0x680c0317, 0xe4515fa5), TOBN(0xf85cff84, 0xfb0c790f),
+ TOBN(0xc7a82aab, 0x6d2e0765), TOBN(0x7446bca9, 0x35c82b32),
+ TOBN(0x5de607aa, 0x6d63184f), TOBN(0x7c1a46a8, 0x262803a6),
+ TOBN(0xd218313d, 0xaebe8035), TOBN(0x92113ffd, 0xc73c51f8),
+ TOBN(0x4b38e083, 0x12e7e46c), TOBN(0x69d0a37a, 0x56126bd5),
+ TOBN(0xfb3f324b, 0x73c07e04), TOBN(0xa0c22f67, 0x8fda7267),
+ TOBN(0x8f2c0051, 0x4d2c7d8f), TOBN(0xbc45ced3, 0xcbe2cae5),
+ TOBN(0xe1c6cf07, 0xa8f0f277), TOBN(0xbc392312, 0x1eb99a98),
+ TOBN(0x75537b7e, 0x3cc8ac85), TOBN(0x8d725f57, 0xdd02753b),
+ TOBN(0xfd05ff64, 0xb737df2f), TOBN(0x55fe8712, 0xf6d2531d),
+ TOBN(0x57ce04a9, 0x6ab6b01c), TOBN(0x69a02a89, 0x7cd93724),
+ TOBN(0x4f82ac35, 0xcf86699b), TOBN(0x8242d3ad, 0x9cb4b232),
+ TOBN(0x713d0f65, 0xd62105e5), TOBN(0xbb222bfa, 0x2d29be61),
+ TOBN(0xf2f9a79e, 0x6cfbef09), TOBN(0xfc24d8d3, 0xd5d6782f),
+ TOBN(0x5db77085, 0xd4129967), TOBN(0xdb81c3cc, 0xdc3c2a43),
+ TOBN(0x9d655fc0, 0x05d8d9a3), TOBN(0x3f5d057a, 0x54298026),
+ TOBN(0x1157f56d, 0x88c54694), TOBN(0xb26baba5, 0x9b09573e),
+ TOBN(0x2cab03b0, 0x22adffd1), TOBN(0x60a412c8, 0xdd69f383),
+ TOBN(0xed76e98b, 0x54b25039), TOBN(0xd4ee67d3, 0x687e714d),
+ TOBN(0x87739648, 0x7b00b594), TOBN(0xce419775, 0xc9ef709b),
+ TOBN(0x40f76f85, 0x1c203a40), TOBN(0x30d352d6, 0xeafd8f91),
+ TOBN(0xaf196d3d, 0x95578dd2), TOBN(0xea4bb3d7, 0x77cc3f3d),
+ TOBN(0x42a5bd03, 0xb98e782b), TOBN(0xac958c40, 0x0624920d),
+ TOBN(0xb838134c, 0xfc56fcc8), TOBN(0x86ec4ccf, 0x89572e5e),
+ TOBN(0x69c43526, 0x9be47be0), TOBN(0x323b7dd8, 0xcb28fea1),
+ TOBN(0xfa5538ba, 0x3a6c67e5), TOBN(0xef921d70, 0x1d378e46),
+ TOBN(0xf92961fc, 0x3c4b880e), TOBN(0x3f6f914e, 0x98940a67),
+ TOBN(0xa990eb0a, 0xfef0ff39), TOBN(0xa6c2920f, 0xf0eeff9c),
+ TOBN(0xca804166, 0x51b8d9a3), TOBN(0x42531bc9, 0x0ffb0db1),
+ TOBN(0x72ce4718, 0xaa82e7ce), TOBN(0x6e199913, 0xdf574741),
+ TOBN(0xd5f1b13d, 0xd5d36946), TOBN(0x8255dc65, 0xf68f0194),
+ TOBN(0xdc9df4cd, 0x8710d230), TOBN(0x3453c20f, 0x138c1988),
+ TOBN(0x9af98dc0, 0x89a6ef01), TOBN(0x4dbcc3f0, 0x9857df85),
+ TOBN(0x34805601, 0x5c1ad924), TOBN(0x40448da5, 0xd0493046),
+ TOBN(0xf629926d, 0x4ee343e2), TOBN(0x6343f1bd, 0x90e8a301),
+ TOBN(0xefc93491, 0x40815b3f), TOBN(0xf882a423, 0xde8f66fb),
+ TOBN(0x3a12d5f4, 0xe7db9f57), TOBN(0x7dfba38a, 0x3c384c27),
+ TOBN(0x7a904bfd, 0x6fc660b1), TOBN(0xeb6c5db3, 0x2773b21c),
+ TOBN(0xc350ee66, 0x1cdfe049), TOBN(0x9baac0ce, 0x44540f29),
+ TOBN(0xbc57b6ab, 0xa5ec6aad), TOBN(0x167ce8c3, 0x0a7c1baa),
+ TOBN(0xb23a03a5, 0x53fb2b56), TOBN(0x6ce141e7, 0x4e057f78),
+ TOBN(0x796525c3, 0x89e490d9), TOBN(0x0bc95725, 0xa31a7e75),
+ TOBN(0x1ec56791, 0x1220fd06), TOBN(0x716e3a3c, 0x408b0bd6),
+ TOBN(0x31cd6bf7, 0xe8ebeba9), TOBN(0xa7326ca6, 0xbee6b670),
+ TOBN(0x3d9f851c, 0xcd090c43), TOBN(0x561e8f13, 0xf12c3988),
+ TOBN(0x50490b6a, 0x904b7be4), TOBN(0x61690ce1, 0x0410737b),
+ TOBN(0x299e9a37, 0x0f009052), TOBN(0x258758f0, 0xf026092e),
+ TOBN(0x9fa255f3, 0xfdfcdc0f), TOBN(0xdbc9fb1f, 0xc0e1bcd2),
+ TOBN(0x35f9dd6e, 0x24651840), TOBN(0xdca45a84, 0xa5c59abc),
+ TOBN(0x103d396f, 0xecca4938), TOBN(0x4532da0a, 0xb97b3f29),
+ TOBN(0xc4135ea5, 0x1999a6bf), TOBN(0x3aa9505a, 0x5e6bf2ee),
+ TOBN(0xf77cef06, 0x3f5be093), TOBN(0x97d1a0f8, 0xa943152e),
+ TOBN(0x2cb0ebba, 0x2e1c21dd), TOBN(0xf41b29fc, 0x2c6797c4),
+ TOBN(0xc6e17321, 0xb300101f), TOBN(0x4422b0e9, 0xd0d79a89),
+ TOBN(0x49e4901c, 0x92f1bfc4), TOBN(0x06ab1f8f, 0xe1e10ed9),
+ TOBN(0x84d35577, 0xdb2926b8), TOBN(0xca349d39, 0x356e8ec2),
+ TOBN(0x70b63d32, 0x343bf1a9), TOBN(0x8fd3bd28, 0x37d1a6b1),
+ TOBN(0x0454879c, 0x316865b4), TOBN(0xee959ff6, 0xc458efa2),
+ TOBN(0x0461dcf8, 0x9706dc3f), TOBN(0x737db0e2, 0x164e4b2e),
+ TOBN(0x09262680, 0x2f8843c8), TOBN(0x54498bbc, 0x7745e6f6),
+ TOBN(0x359473fa, 0xa29e24af), TOBN(0xfcc3c454, 0x70aa87a1),
+ TOBN(0xfd2c4bf5, 0x00573ace), TOBN(0xb65b514e, 0x28dd1965),
+ TOBN(0xe46ae7cf, 0x2193e393), TOBN(0x60e9a4e1, 0xf5444d97),
+ TOBN(0xe7594e96, 0x00ff38ed), TOBN(0x43d84d2f, 0x0a0e0f02),
+ TOBN(0x8b6db141, 0xee398a21), TOBN(0xb88a56ae, 0xe3bcc5be),
+ TOBN(0x0a1aa52f, 0x373460ea), TOBN(0x20da1a56, 0x160bb19b),
+ TOBN(0xfb54999d, 0x65bf0384), TOBN(0x71a14d24, 0x5d5a180e),
+ TOBN(0xbc44db7b, 0x21737b04), TOBN(0xd84fcb18, 0x01dd8e92),
+ TOBN(0x80de937b, 0xfa44b479), TOBN(0x53505499, 0x5c98fd4f),
+ TOBN(0x1edb12ab, 0x28f08727), TOBN(0x4c58b582, 0xa5f3ef53),
+ TOBN(0xbfb236d8, 0x8327f246), TOBN(0xc3a3bfaa, 0x4d7df320),
+ TOBN(0xecd96c59, 0xb96024f2), TOBN(0xfc293a53, 0x7f4e0433),
+ TOBN(0x5341352b, 0x5acf6e10), TOBN(0xc50343fd, 0xafe652c3),
+ TOBN(0x4af3792d, 0x18577a7f), TOBN(0xe1a4c617, 0xaf16823d),
+ TOBN(0x9b26d0cd, 0x33425d0a), TOBN(0x306399ed, 0x9b7bc47f),
+ TOBN(0x2a792f33, 0x706bb20b), TOBN(0x31219614, 0x98111055),
+ TOBN(0x864ec064, 0x87f5d28b), TOBN(0x11392d91, 0x962277fd),
+ TOBN(0xb5aa7942, 0xbb6aed5f), TOBN(0x080094dc, 0x47e799d9),
+ TOBN(0x4afa588c, 0x208ba19b), TOBN(0xd3e7570f, 0x8512f284),
+ TOBN(0xcbae64e6, 0x02f5799a), TOBN(0xdeebe7ef, 0x514b9492),
+ TOBN(0x30300f98, 0xe5c298ff), TOBN(0x17f561be, 0x3678361f),
+ TOBN(0xf52ff312, 0x98cb9a16), TOBN(0x6233c3bc, 0x5562d490),
+ TOBN(0x7bfa15a1, 0x92e3a2cb), TOBN(0x961bcfd1, 0xe6365119),
+ TOBN(0x3bdd29bf, 0x2c8c53b1), TOBN(0x739704df, 0x822844ba),
+ TOBN(0x7dacfb58, 0x7e7b754b), TOBN(0x23360791, 0xa806c9b9),
+ TOBN(0xe7eb88c9, 0x23504452), TOBN(0x2983e996, 0x852c1783),
+ TOBN(0xdd4ae529, 0x958d881d), TOBN(0x026bae03, 0x262c7b3c),
+ TOBN(0x3a6f9193, 0x960b52d1), TOBN(0xd0980f90, 0x92696cfb),
+ TOBN(0x4c1f428c, 0xd5f30851), TOBN(0x94dfed27, 0x2a4f6630),
+ TOBN(0x4df53772, 0xfc5d48a4), TOBN(0xdd2d5a2f, 0x933260ce),
+ TOBN(0x574115bd, 0xd44cc7a5), TOBN(0x4ba6b20d, 0xbd12533a),
+ TOBN(0x30e93cb8, 0x243057c9), TOBN(0x794c486a, 0x14de320e),
+ TOBN(0xe925d4ce, 0xf21496e4), TOBN(0xf951d198, 0xec696331),
+ TOBN(0x9810e2de, 0x3e8d812f), TOBN(0xd0a47259, 0x389294ab),
+ TOBN(0x513ba2b5, 0x0e3bab66), TOBN(0x462caff5, 0xabad306f),
+ TOBN(0xe2dc6d59, 0xaf04c49e), TOBN(0x1aeb8750, 0xe0b84b0b),
+ TOBN(0xc034f12f, 0x2f7d0ca2), TOBN(0x6d2e8128, 0xe06acf2f),
+ TOBN(0x801f4f83, 0x21facc2f), TOBN(0xa1170c03, 0xf40ef607),
+ TOBN(0xfe0a1d4f, 0x7805a99c), TOBN(0xbde56a36, 0xcc26aba5),
+ TOBN(0x5b1629d0, 0x35531f40), TOBN(0xac212c2b, 0x9afa6108),
+ TOBN(0x30a06bf3, 0x15697be5), TOBN(0x6f0545dc, 0x2c63c7c1),
+ TOBN(0x5d8cb842, 0x7ccdadaf), TOBN(0xd52e379b, 0xac7015bb),
+ TOBN(0xc4f56147, 0xf462c23e), TOBN(0xd44a4298, 0x46bc24b0),
+ TOBN(0xbc73d23a, 0xe2856d4f), TOBN(0x61cedd8c, 0x0832bcdf),
+ TOBN(0x60953556, 0x99f241d7), TOBN(0xee4adbd7, 0x001a349d),
+ TOBN(0x0b35bf6a, 0xaa89e491), TOBN(0x7f0076f4, 0x136f7546),
+ TOBN(0xd19a18ba, 0x9264da3d), TOBN(0x6eb2d2cd, 0x62a7a28b),
+ TOBN(0xcdba941f, 0x8761c971), TOBN(0x1550518b, 0xa3be4a5d),
+ TOBN(0xd0e8e2f0, 0x57d0b70c), TOBN(0xeea8612e, 0xcd133ba3),
+ TOBN(0x814670f0, 0x44416aec), TOBN(0x424db6c3, 0x30775061),
+ TOBN(0xd96039d1, 0x16213fd1), TOBN(0xc61e7fa5, 0x18a3478f),
+ TOBN(0xa805bdcc, 0xcb0c5021), TOBN(0xbdd6f3a8, 0x0cc616dd),
+ TOBN(0x06009667, 0x5d97f7e2), TOBN(0x31db0fc1, 0xaf0bf4b6),
+ TOBN(0x23680ed4, 0x5491627a), TOBN(0xb99a3c66, 0x7d741fb1),
+ TOBN(0xe9bb5f55, 0x36b1ff92), TOBN(0x29738577, 0x512b388d),
+ TOBN(0xdb8a2ce7, 0x50fcf263), TOBN(0x385346d4, 0x6c4f7b47),
+ TOBN(0xbe86c5ef, 0x31631f9e), TOBN(0xbf91da21, 0x03a57a29),
+ TOBN(0xc3b1f796, 0x7b23f821), TOBN(0x0f7d00d2, 0x770db354),
+ TOBN(0x8ffc6c3b, 0xd8fe79da), TOBN(0xcc5e8c40, 0xd525c996),
+ TOBN(0x4640991d, 0xcfff632a), TOBN(0x64d97e8c, 0x67112528),
+ TOBN(0xc232d973, 0x02f1cd1e), TOBN(0xce87eacb, 0x1dd212a4),
+ TOBN(0x6e4c8c73, 0xe69802f7), TOBN(0x12ef0290, 0x1fffddbd),
+ TOBN(0x941ec74e, 0x1bcea6e2), TOBN(0xd0b54024, 0x3cb92cbb),
+ TOBN(0x809fb9d4, 0x7e8f9d05), TOBN(0x3bf16159, 0xf2992aae),
+ TOBN(0xad40f279, 0xf8a7a838), TOBN(0x11aea631, 0x05615660),
+ TOBN(0xbf52e6f1, 0xa01f6fa1), TOBN(0xef046995, 0x3dc2aec9),
+ TOBN(0x785dbec9, 0xd8080711), TOBN(0xe1aec60a, 0x9fdedf76),
+ TOBN(0xece797b5, 0xfa21c126), TOBN(0xc66e898f, 0x05e52732),
+ TOBN(0x39bb69c4, 0x08811fdb), TOBN(0x8bfe1ef8, 0x2fc7f082),
+ TOBN(0xc8e7a393, 0x174f4138), TOBN(0xfba8ad1d, 0xd58d1f98),
+ TOBN(0xbc21d0ce, 0xbfd2fd5b), TOBN(0x0b839a82, 0x6ee60d61),
+ TOBN(0xaacf7658, 0xafd22253), TOBN(0xb526bed8, 0xaae396b3),
+ TOBN(0xccc1bbc2, 0x38564464), TOBN(0x9e3ff947, 0x8c45bc73),
+ TOBN(0xcde9bca3, 0x58188a78), TOBN(0x138b8ee0, 0xd73bf8f7),
+ TOBN(0x5c7e234c, 0x4123c489), TOBN(0x66e69368, 0xfa643297),
+ TOBN(0x0629eeee, 0x39a15fa3), TOBN(0x95fab881, 0xa9e2a927),
+ TOBN(0xb2497007, 0xeafbb1e1), TOBN(0xd75c9ce6, 0xe75b7a93),
+ TOBN(0x3558352d, 0xefb68d78), TOBN(0xa2f26699, 0x223f6396),
+ TOBN(0xeb911ecf, 0xe469b17a), TOBN(0x62545779, 0xe72d3ec2),
+ TOBN(0x8ea47de7, 0x82cb113f), TOBN(0xebe4b086, 0x4e1fa98d),
+ TOBN(0xec2d5ed7, 0x8cdfedb1), TOBN(0xa535c077, 0xfe211a74),
+ TOBN(0x9678109b, 0x11d244c5), TOBN(0xf17c8bfb, 0xbe299a76),
+ TOBN(0xb651412e, 0xfb11fbc4), TOBN(0xea0b5482, 0x94ab3f65),
+ TOBN(0xd8dffd95, 0x0cf78243), TOBN(0x2e719e57, 0xce0361d4),
+ TOBN(0x9007f085, 0x304ddc5b), TOBN(0x095e8c6d, 0x4daba2ea),
+ TOBN(0x5a33cdb4, 0x3f9d28a9), TOBN(0x85b95cd8, 0xe2283003),
+ TOBN(0xbcd6c819, 0xb9744733), TOBN(0x29c5f538, 0xfc7f5783),
+ TOBN(0x6c49b2fa, 0xd59038e4), TOBN(0x68349cc1, 0x3bbe1018),
+ TOBN(0xcc490c1d, 0x21830ee5), TOBN(0x36f9c4ee, 0xe9bfa297),
+ TOBN(0x58fd7294, 0x48de1a94), TOBN(0xaadb13a8, 0x4e8f2cdc),
+ TOBN(0x515eaaa0, 0x81313dba), TOBN(0xc76bb468, 0xc2152dd8),
+ TOBN(0x357f8d75, 0xa653dbf8), TOBN(0xe4d8c4d1, 0xb14ac143),
+ TOBN(0xbdb8e675, 0xb055cb40), TOBN(0x898f8e7b, 0x977b5167),
+ TOBN(0xecc65651, 0xb82fb863), TOBN(0x56544814, 0x6d88f01f),
+ TOBN(0xb0928e95, 0x263a75a9), TOBN(0xcfb6836f, 0x1a22fcda),
+ TOBN(0x651d14db, 0x3f3bd37c), TOBN(0x1d3837fb, 0xb6ad4664),
+ TOBN(0x7c5fb538, 0xff4f94ab), TOBN(0x7243c712, 0x6d7fb8f2),
+ TOBN(0xef13d60c, 0xa85c5287), TOBN(0x18cfb7c7, 0x4bb8dd1b),
+ TOBN(0x82f9bfe6, 0x72908219), TOBN(0x35c4592b, 0x9d5144ab),
+ TOBN(0x52734f37, 0x9cf4b42f), TOBN(0x6bac55e7, 0x8c60ddc4),
+ TOBN(0xb5cd811e, 0x94dea0f6), TOBN(0x259ecae4, 0xe18cc1a3),
+ TOBN(0x6a0e836e, 0x15e660f8), TOBN(0x6c639ea6, 0x0e02bff2),
+ TOBN(0x8721b8cb, 0x7e1026fd), TOBN(0x9e73b50b, 0x63261942),
+ TOBN(0xb8c70974, 0x77f01da3), TOBN(0x1839e6a6, 0x8268f57f),
+ TOBN(0x571b9415, 0x5150b805), TOBN(0x1892389e, 0xf92c7097),
+ TOBN(0x8d69c18e, 0x4a084b95), TOBN(0x7014c512, 0xbe5b495c),
+ TOBN(0x4780db36, 0x1b07523c), TOBN(0x2f6219ce, 0x2c1c64fa),
+ TOBN(0xc38b81b0, 0x602c105a), TOBN(0xab4f4f20, 0x5dc8e360),
+ TOBN(0x20d3c982, 0xcf7d62d2), TOBN(0x1f36e29d, 0x23ba8150),
+ TOBN(0x48ae0bf0, 0x92763f9e), TOBN(0x7a527e6b, 0x1d3a7007),
+ TOBN(0xb4a89097, 0x581a85e3), TOBN(0x1f1a520f, 0xdc158be5),
+ TOBN(0xf98db37d, 0x167d726e), TOBN(0x8802786e, 0x1113e862)},
+ {TOBN(0xefb2149e, 0x36f09ab0), TOBN(0x03f163ca, 0x4a10bb5b),
+ TOBN(0xd0297045, 0x06e20998), TOBN(0x56f0af00, 0x1b5a3bab),
+ TOBN(0x7af4cfec, 0x70880e0d), TOBN(0x7332a66f, 0xbe3d913f),
+ TOBN(0x32e6c84a, 0x7eceb4bd), TOBN(0xedc4a79a, 0x9c228f55),
+ TOBN(0xc37c7dd0, 0xc55c4496), TOBN(0xa6a96357, 0x25bbabd2),
+ TOBN(0x5b7e63f2, 0xadd7f363), TOBN(0x9dce3782, 0x2e73f1df),
+ TOBN(0xe1e5a16a, 0xb2b91f71), TOBN(0xe4489823, 0x5ba0163c),
+ TOBN(0xf2759c32, 0xf6e515ad), TOBN(0xa5e2f1f8, 0x8615eecf),
+ TOBN(0x74519be7, 0xabded551), TOBN(0x03d358b8, 0xc8b74410),
+ TOBN(0x4d00b10b, 0x0e10d9a9), TOBN(0x6392b0b1, 0x28da52b7),
+ TOBN(0x6744a298, 0x0b75c904), TOBN(0xc305b0ae, 0xa8f7f96c),
+ TOBN(0x042e421d, 0x182cf932), TOBN(0xf6fc5d50, 0x9e4636ca),
+ TOBN(0x795847c9, 0xd64cc78c), TOBN(0x6c50621b, 0x9b6cb27b),
+ TOBN(0x07099bf8, 0xdf8022ab), TOBN(0x48f862eb, 0xc04eda1d),
+ TOBN(0xd12732ed, 0xe1603c16), TOBN(0x19a80e0f, 0x5c9a9450),
+ TOBN(0xe2257f54, 0xb429b4fc), TOBN(0x66d3b2c6, 0x45460515),
+ TOBN(0x6ca4f87e, 0x822e37be), TOBN(0x73f237b4, 0x253bda4e),
+ TOBN(0xf747f3a2, 0x41190aeb), TOBN(0xf06fa36f, 0x804cf284),
+ TOBN(0x0a6bbb6e, 0xfc621c12), TOBN(0x5d624b64, 0x40b80ec6),
+ TOBN(0x4b072425, 0x7ba556f3), TOBN(0x7fa0c354, 0x3e2d20a8),
+ TOBN(0xe921fa31, 0xe3229d41), TOBN(0xa929c652, 0x94531bd4),
+ TOBN(0x84156027, 0xa6d38209), TOBN(0xf3d69f73, 0x6bdb97bd),
+ TOBN(0x8906d19a, 0x16833631), TOBN(0x68a34c2e, 0x03d51be3),
+ TOBN(0xcb59583b, 0x0e511cd8), TOBN(0x99ce6bfd, 0xfdc132a8),
+ TOBN(0x3facdaaa, 0xffcdb463), TOBN(0x658bbc1a, 0x34a38b08),
+ TOBN(0x12a801f8, 0xf1a9078d), TOBN(0x1567bcf9, 0x6ab855de),
+ TOBN(0xe08498e0, 0x3572359b), TOBN(0xcf0353e5, 0x8659e68b),
+ TOBN(0xbb86e9c8, 0x7d23807c), TOBN(0xbc08728d, 0x2198e8a2),
+ TOBN(0x8de2b7bc, 0x453cadd6), TOBN(0x203900a7, 0xbc0bc1f8),
+ TOBN(0xbcd86e47, 0xa6abd3af), TOBN(0x911cac12, 0x8502effb),
+ TOBN(0x2d550242, 0xec965469), TOBN(0x0e9f7692, 0x29e0017e),
+ TOBN(0x633f078f, 0x65979885), TOBN(0xfb87d449, 0x4cf751ef),
+ TOBN(0xe1790e4b, 0xfc25419a), TOBN(0x36467203, 0x4bff3cfd),
+ TOBN(0xc8db6386, 0x25b6e83f), TOBN(0x6cc69f23, 0x6cad6fd2),
+ TOBN(0x0219e45a, 0x6bc68bb9), TOBN(0xe43d79b6, 0x297f7334),
+ TOBN(0x7d445368, 0x465dc97c), TOBN(0x4b9eea32, 0x2a0b949a),
+ TOBN(0x1b96c6ba, 0x6102d021), TOBN(0xeaafac78, 0x2f4461ea),
+ TOBN(0xd4b85c41, 0xc49f19a8), TOBN(0x275c28e4, 0xcf538875),
+ TOBN(0x35451a9d, 0xdd2e54e0), TOBN(0x6991adb5, 0x0605618b),
+ TOBN(0x5b8b4bcd, 0x7b36cd24), TOBN(0x372a4f8c, 0x56f37216),
+ TOBN(0xc890bd73, 0xa6a5da60), TOBN(0x6f083da0, 0xdc4c9ff0),
+ TOBN(0xf4e14d94, 0xf0536e57), TOBN(0xf9ee1eda, 0xaaec8243),
+ TOBN(0x571241ec, 0x8bdcf8e7), TOBN(0xa5db8271, 0x0b041e26),
+ TOBN(0x9a0b9a99, 0xe3fff040), TOBN(0xcaaf21dd, 0x7c271202),
+ TOBN(0xb4e2b2e1, 0x4f0dd2e8), TOBN(0xe77e7c4f, 0x0a377ac7),
+ TOBN(0x69202c3f, 0x0d7a2198), TOBN(0xf759b7ff, 0x28200eb8),
+ TOBN(0xc87526ed, 0xdcfe314e), TOBN(0xeb84c524, 0x53d5cf99),
+ TOBN(0xb1b52ace, 0x515138b6), TOBN(0x5aa7ff8c, 0x23fca3f4),
+ TOBN(0xff0b13c3, 0xb9791a26), TOBN(0x960022da, 0xcdd58b16),
+ TOBN(0xdbd55c92, 0x57aad2de), TOBN(0x3baaaaa3, 0xf30fe619),
+ TOBN(0x9a4b2346, 0x0d881efd), TOBN(0x506416c0, 0x46325e2a),
+ TOBN(0x91381e76, 0x035c18d4), TOBN(0xb3bb68be, 0xf27817b0),
+ TOBN(0x15bfb8bf, 0x5116f937), TOBN(0x7c64a586, 0xc1268943),
+ TOBN(0x71e25cc3, 0x8419a2c8), TOBN(0x9fd6b0c4, 0x8335f463),
+ TOBN(0x4bf0ba3c, 0xe8ee0e0e), TOBN(0x6f6fba60, 0x298c21fa),
+ TOBN(0x57d57b39, 0xae66bee0), TOBN(0x292d5130, 0x22672544),
+ TOBN(0xf451105d, 0xbab093b3), TOBN(0x012f59b9, 0x02839986),
+ TOBN(0x8a915802, 0x3474a89c), TOBN(0x048c919c, 0x2de03e97),
+ TOBN(0xc476a2b5, 0x91071cd5), TOBN(0x791ed89a, 0x034970a5),
+ TOBN(0x89bd9042, 0xe1b7994b), TOBN(0x8eaf5179, 0xa1057ffd),
+ TOBN(0x6066e2a2, 0xd551ee10), TOBN(0x87a8f1d8, 0x727e09a6),
+ TOBN(0x00d08bab, 0x2c01148d), TOBN(0x6da8e4f1, 0x424f33fe),
+ TOBN(0x466d17f0, 0xcf9a4e71), TOBN(0xff502010, 0x3bf5cb19),
+ TOBN(0xdccf97d8, 0xd062ecc0), TOBN(0x80c0d9af, 0x81d80ac4),
+ TOBN(0xe87771d8, 0x033f2876), TOBN(0xb0186ec6, 0x7d5cc3db),
+ TOBN(0x58e8bb80, 0x3bc9bc1d), TOBN(0x4d1395cc, 0x6f6ef60e),
+ TOBN(0xa73c62d6, 0x186244a0), TOBN(0x918e5f23, 0x110a5b53),
+ TOBN(0xed4878ca, 0x741b7eab), TOBN(0x3038d71a, 0xdbe03e51),
+ TOBN(0x840204b7, 0xa93c3246), TOBN(0x21ab6069, 0xa0b9b4cd),
+ TOBN(0xf5fa6e2b, 0xb1d64218), TOBN(0x1de6ad0e, 0xf3d56191),
+ TOBN(0x570aaa88, 0xff1929c7), TOBN(0xc6df4c6b, 0x640e87b5),
+ TOBN(0xde8a74f2, 0xc65f0ccc), TOBN(0x8b972fd5, 0xe6f6cc01),
+ TOBN(0x3fff36b6, 0x0b846531), TOBN(0xba7e45e6, 0x10a5e475),
+ TOBN(0x84a1d10e, 0x4145b6c5), TOBN(0xf1f7f91a, 0x5e046d9d),
+ TOBN(0x0317a692, 0x44de90d7), TOBN(0x951a1d4a, 0xf199c15e),
+ TOBN(0x91f78046, 0xc9d73deb), TOBN(0x74c82828, 0xfab8224f),
+ TOBN(0xaa6778fc, 0xe7560b90), TOBN(0xb4073e61, 0xa7e824ce),
+ TOBN(0xff0d693c, 0xd642eba8), TOBN(0x7ce2e57a, 0x5dccef38),
+ TOBN(0x89c2c789, 0x1df1ad46), TOBN(0x83a06922, 0x098346fd),
+ TOBN(0x2d715d72, 0xda2fc177), TOBN(0x7b6dd71d, 0x85b6cf1d),
+ TOBN(0xc60a6d0a, 0x73fa9cb0), TOBN(0xedd3992e, 0x328bf5a9),
+ TOBN(0xc380ddd0, 0x832c8c82), TOBN(0xd182d410, 0xa2a0bf50),
+ TOBN(0x7d9d7438, 0xd9a528db), TOBN(0xe8b1a0e9, 0xcaf53994),
+ TOBN(0xddd6e5fe, 0x0e19987c), TOBN(0xacb8df03, 0x190b059d),
+ TOBN(0x53703a32, 0x8300129f), TOBN(0x1f637662, 0x68c43bfd),
+ TOBN(0xbcbd1913, 0x00e54051), TOBN(0x812fcc62, 0x7bf5a8c5),
+ TOBN(0x3f969d5f, 0x29fb85da), TOBN(0x72f4e00a, 0x694759e8),
+ TOBN(0x426b6e52, 0x790726b7), TOBN(0x617bbc87, 0x3bdbb209),
+ TOBN(0x511f8bb9, 0x97aee317), TOBN(0x812a4096, 0xe81536a8),
+ TOBN(0x137dfe59, 0x3ac09b9b), TOBN(0x0682238f, 0xba8c9a7a),
+ TOBN(0x7072ead6, 0xaeccb4bd), TOBN(0x6a34e9aa, 0x692ba633),
+ TOBN(0xc82eaec2, 0x6fff9d33), TOBN(0xfb753512, 0x1d4d2b62),
+ TOBN(0x1a0445ff, 0x1d7aadab), TOBN(0x65d38260, 0xd5f6a67c),
+ TOBN(0x6e62fb08, 0x91cfb26f), TOBN(0xef1e0fa5, 0x5c7d91d6),
+ TOBN(0x47e7c7ba, 0x33db72cd), TOBN(0x017cbc09, 0xfa7c74b2),
+ TOBN(0x3c931590, 0xf50a503c), TOBN(0xcac54f60, 0x616baa42),
+ TOBN(0x9b6cd380, 0xb2369f0f), TOBN(0x97d3a70d, 0x23c76151),
+ TOBN(0x5f9dd6fc, 0x9862a9c6), TOBN(0x044c4ab2, 0x12312f51),
+ TOBN(0x035ea0fd, 0x834a2ddc), TOBN(0x49e6b862, 0xcc7b826d),
+ TOBN(0xb03d6883, 0x62fce490), TOBN(0x62f2497a, 0xb37e36e9),
+ TOBN(0x04b005b6, 0xc6458293), TOBN(0x36bb5276, 0xe8d10af7),
+ TOBN(0xacf2dc13, 0x8ee617b8), TOBN(0x470d2d35, 0xb004b3d4),
+ TOBN(0x06790832, 0xfeeb1b77), TOBN(0x2bb75c39, 0x85657f9c),
+ TOBN(0xd70bd4ed, 0xc0f60004), TOBN(0xfe797ecc, 0x219b018b),
+ TOBN(0x9b5bec2a, 0x753aebcc), TOBN(0xdaf9f3dc, 0xc939eca5),
+ TOBN(0xd6bc6833, 0xd095ad09), TOBN(0x98abdd51, 0xdaa4d2fc),
+ TOBN(0xd9840a31, 0x8d168be5), TOBN(0xcf7c10e0, 0x2325a23c),
+ TOBN(0xa5c02aa0, 0x7e6ecfaf), TOBN(0x2462e7e6, 0xb5bfdf18),
+ TOBN(0xab2d8a8b, 0xa0cc3f12), TOBN(0x68dd485d, 0xbc672a29),
+ TOBN(0x72039752, 0x596f2cd3), TOBN(0x5d3eea67, 0xa0cf3d8d),
+ TOBN(0x810a1a81, 0xe6602671), TOBN(0x8f144a40, 0x14026c0c),
+ TOBN(0xbc753a6d, 0x76b50f85), TOBN(0xc4dc21e8, 0x645cd4a4),
+ TOBN(0xc5262dea, 0x521d0378), TOBN(0x802b8e0e, 0x05011c6f),
+ TOBN(0x1ba19cbb, 0x0b4c19ea), TOBN(0x21db64b5, 0xebf0aaec),
+ TOBN(0x1f394ee9, 0x70342f9d), TOBN(0x93a10aee, 0x1bc44a14),
+ TOBN(0xa7eed31b, 0x3efd0baa), TOBN(0x6e7c824e, 0x1d154e65),
+ TOBN(0xee23fa81, 0x9966e7ee), TOBN(0x64ec4aa8, 0x05b7920d),
+ TOBN(0x2d44462d, 0x2d90aad4), TOBN(0xf44dd195, 0xdf277ad5),
+ TOBN(0x8d6471f1, 0xbb46b6a1), TOBN(0x1e65d313, 0xfd885090),
+ TOBN(0x33a800f5, 0x13a977b4), TOBN(0xaca9d721, 0x0797e1ef),
+ TOBN(0x9a5a85a0, 0xfcff6a17), TOBN(0x9970a3f3, 0x1eca7cee),
+ TOBN(0xbb9f0d6b, 0xc9504be3), TOBN(0xe0c504be, 0xadd24ee2),
+ TOBN(0x7e09d956, 0x77fcc2f4), TOBN(0xef1a5227, 0x65bb5fc4),
+ TOBN(0x145d4fb1, 0x8b9286aa), TOBN(0x66fd0c5d, 0x6649028b),
+ TOBN(0x98857ceb, 0x1bf4581c), TOBN(0xe635e186, 0xaca7b166),
+ TOBN(0x278ddd22, 0x659722ac), TOBN(0xa0903c4c, 0x1db68007),
+ TOBN(0x366e4589, 0x48f21402), TOBN(0x31b49c14, 0xb96abda2),
+ TOBN(0x329c4b09, 0xe0403190), TOBN(0x97197ca3, 0xd29f43fe),
+ TOBN(0x8073dd1e, 0x274983d8), TOBN(0xda1a3bde, 0x55717c8f),
+ TOBN(0xfd3d4da2, 0x0361f9d1), TOBN(0x1332d081, 0x4c7de1ce),
+ TOBN(0x9b7ef7a3, 0xaa6d0e10), TOBN(0x17db2e73, 0xf54f1c4a),
+ TOBN(0xaf3dffae, 0x4cd35567), TOBN(0xaaa2f406, 0xe56f4e71),
+ TOBN(0x8966759e, 0x7ace3fc7), TOBN(0x9594eacf, 0x45a8d8c6),
+ TOBN(0x8de3bd8b, 0x91834e0e), TOBN(0xafe4ca53, 0x548c0421),
+ TOBN(0xfdd7e856, 0xe6ee81c6), TOBN(0x8f671beb, 0x6b891a3a),
+ TOBN(0xf7a58f2b, 0xfae63829), TOBN(0x9ab186fb, 0x9c11ac9f),
+ TOBN(0x8d6eb369, 0x10b5be76), TOBN(0x046b7739, 0xfb040bcd),
+ TOBN(0xccb4529f, 0xcb73de88), TOBN(0x1df0fefc, 0xcf26be03),
+ TOBN(0xad7757a6, 0xbcfcd027), TOBN(0xa8786c75, 0xbb3165ca),
+ TOBN(0xe9db1e34, 0x7e99a4d9), TOBN(0x99ee86df, 0xb06c504b),
+ TOBN(0x5b7c2ddd, 0xc15c9f0a), TOBN(0xdf87a734, 0x4295989e),
+ TOBN(0x59ece47c, 0x03d08fda), TOBN(0xb074d3dd, 0xad5fc702),
+ TOBN(0x20407903, 0x51a03776), TOBN(0x2bb1f77b, 0x2a608007),
+ TOBN(0x25c58f4f, 0xe1153185), TOBN(0xe6df62f6, 0x766e6447),
+ TOBN(0xefb3d1be, 0xed51275a), TOBN(0x5de47dc7, 0x2f0f483f),
+ TOBN(0x7932d98e, 0x97c2bedf), TOBN(0xd5c11927, 0x0219f8a1),
+ TOBN(0x9d751200, 0xa73a294e), TOBN(0x5f88434a, 0x9dc20172),
+ TOBN(0xd28d9fd3, 0xa26f506a), TOBN(0xa890cd31, 0x9d1dcd48),
+ TOBN(0x0aebaec1, 0x70f4d3b4), TOBN(0xfd1a1369, 0x0ffc8d00),
+ TOBN(0xb9d9c240, 0x57d57838), TOBN(0x45929d26, 0x68bac361),
+ TOBN(0x5a2cd060, 0x25b15ca6), TOBN(0x4b3c83e1, 0x6e474446),
+ TOBN(0x1aac7578, 0xee1e5134), TOBN(0xa418f5d6, 0xc91e2f41),
+ TOBN(0x6936fc8a, 0x213ed68b), TOBN(0x860ae7ed, 0x510a5224),
+ TOBN(0x63660335, 0xdef09b53), TOBN(0x641b2897, 0xcd79c98d),
+ TOBN(0x29bd38e1, 0x01110f35), TOBN(0x79c26f42, 0x648b1937),
+ TOBN(0x64dae519, 0x9d9164f4), TOBN(0xd85a2310, 0x0265c273),
+ TOBN(0x7173dd5d, 0x4b07e2b1), TOBN(0xd144c4cb, 0x8d9ea221),
+ TOBN(0xe8b04ea4, 0x1105ab14), TOBN(0x92dda542, 0xfe80d8f1),
+ TOBN(0xe9982fa8, 0xcf03dce6), TOBN(0x8b5ea965, 0x1a22cffc),
+ TOBN(0xf7f4ea7f, 0x3fad88c4), TOBN(0x62db773e, 0x6a5ba95c),
+ TOBN(0xd20f02fb, 0x93f24567), TOBN(0xfd46c69a, 0x315257ca),
+ TOBN(0x0ac74cc7, 0x8bcab987), TOBN(0x46f31c01, 0x5ceca2f5),
+ TOBN(0x40aedb59, 0x888b219e), TOBN(0xe50ecc37, 0xe1fccd02),
+ TOBN(0x1bcd9dad, 0x911f816c), TOBN(0x583cc1ec, 0x8db9b00c),
+ TOBN(0xf3cd2e66, 0xa483bf11), TOBN(0xfa08a6f5, 0xb1b2c169),
+ TOBN(0xf375e245, 0x4be9fa28), TOBN(0x99a7ffec, 0x5b6d011f),
+ TOBN(0x6a3ebddb, 0xc4ae62da), TOBN(0x6cea00ae, 0x374aef5d),
+ TOBN(0xab5fb98d, 0x9d4d05bc), TOBN(0x7cba1423, 0xd560f252),
+ TOBN(0x49b2cc21, 0x208490de), TOBN(0x1ca66ec3, 0xbcfb2879),
+ TOBN(0x7f1166b7, 0x1b6fb16f), TOBN(0xfff63e08, 0x65fe5db3),
+ TOBN(0xb8345abe, 0x8b2610be), TOBN(0xb732ed80, 0x39de3df4),
+ TOBN(0x0e24ed50, 0x211c32b4), TOBN(0xd10d8a69, 0x848ff27d),
+ TOBN(0xc1074398, 0xed4de248), TOBN(0xd7cedace, 0x10488927),
+ TOBN(0xa4aa6bf8, 0x85673e13), TOBN(0xb46bae91, 0x6daf30af),
+ TOBN(0x07088472, 0xfcef7ad8), TOBN(0x61151608, 0xd4b35e97),
+ TOBN(0xbcfe8f26, 0xdde29986), TOBN(0xeb84c4c7, 0xd5a34c79),
+ TOBN(0xc1eec55c, 0x164e1214), TOBN(0x891be86d, 0xa147bb03),
+ TOBN(0x9fab4d10, 0x0ba96835), TOBN(0xbf01e9b8, 0xa5c1ae9f),
+ TOBN(0x6b4de139, 0xb186ebc0), TOBN(0xd5c74c26, 0x85b91bca),
+ TOBN(0x5086a99c, 0xc2d93854), TOBN(0xeed62a7b, 0xa7a9dfbc),
+ TOBN(0x8778ed6f, 0x76b7618a), TOBN(0xbff750a5, 0x03b66062),
+ TOBN(0x4cb7be22, 0xb65186db), TOBN(0x369dfbf0, 0xcc3a6d13),
+ TOBN(0xc7dab26c, 0x7191a321), TOBN(0x9edac3f9, 0x40ed718e),
+ TOBN(0xbc142b36, 0xd0cfd183), TOBN(0xc8af82f6, 0x7c991693),
+ TOBN(0xb3d1e4d8, 0x97ce0b2a), TOBN(0xe6d7c87f, 0xc3a55cdf),
+ TOBN(0x35846b95, 0x68b81afe), TOBN(0x018d12af, 0xd3c239d8),
+ TOBN(0x2b2c6208, 0x01206e15), TOBN(0xe0e42453, 0xa3b882c6),
+ TOBN(0x854470a3, 0xa50162d5), TOBN(0x08157478, 0x7017a62a),
+ TOBN(0x18bd3fb4, 0x820357c7), TOBN(0x992039ae, 0x6f1458ad),
+ TOBN(0x9a1df3c5, 0x25b44aa1), TOBN(0x2d780357, 0xed3d5281),
+ TOBN(0x58cf7e4d, 0xc77ad4d4), TOBN(0xd49a7998, 0xf9df4fc4),
+ TOBN(0x4465a8b5, 0x1d71205e), TOBN(0xa0ee0ea6, 0x649254aa),
+ TOBN(0x4b5eeecf, 0xab7bd771), TOBN(0x6c873073, 0x35c262b9),
+ TOBN(0xdc5bd648, 0x3c9d61e7), TOBN(0x233d6d54, 0x321460d2),
+ TOBN(0xd20c5626, 0xfc195bcc), TOBN(0x25445958, 0x04d78b63),
+ TOBN(0xe03fcb3d, 0x17ec8ef3), TOBN(0x54b690d1, 0x46b8f781),
+ TOBN(0x82fa2c8a, 0x21230646), TOBN(0xf51aabb9, 0x084f418c),
+ TOBN(0xff4fbec1, 0x1a30ba43), TOBN(0x6a5acf73, 0x743c9df7),
+ TOBN(0x1da2b357, 0xd635b4d5), TOBN(0xc3de68dd, 0xecd5c1da),
+ TOBN(0xa689080b, 0xd61af0dd), TOBN(0xdea5938a, 0xd665bf99),
+ TOBN(0x0231d71a, 0xfe637294), TOBN(0x01968aa6, 0xa5a81cd8),
+ TOBN(0x11252d50, 0x048e63b5), TOBN(0xc446bc52, 0x6ca007e9),
+ TOBN(0xef8c50a6, 0x96d6134b), TOBN(0x9361fbf5, 0x9e09a05c),
+ TOBN(0xf17f85a6, 0xdca3291a), TOBN(0xb178d548, 0xff251a21),
+ TOBN(0x87f6374b, 0xa4df3915), TOBN(0x566ce1bf, 0x2fd5d608),
+ TOBN(0x425cba4d, 0x7de35102), TOBN(0x6b745f8f, 0x58c5d5e2),
+ TOBN(0x88402af6, 0x63122edf), TOBN(0x3190f9ed, 0x3b989a89),
+ TOBN(0x4ad3d387, 0xebba3156), TOBN(0xef385ad9, 0xc7c469a5),
+ TOBN(0xb08281de, 0x3f642c29), TOBN(0x20be0888, 0x910ffb88),
+ TOBN(0xf353dd4a, 0xd5292546), TOBN(0x3f1627de, 0x8377a262),
+ TOBN(0xa5faa013, 0xeefcd638), TOBN(0x8f3bf626, 0x74cc77c3),
+ TOBN(0x32618f65, 0xa348f55e), TOBN(0x5787c0dc, 0x9fefeb9e),
+ TOBN(0xf1673aa2, 0xd9a23e44), TOBN(0x88dfa993, 0x4e10690d),
+ TOBN(0x1ced1b36, 0x2bf91108), TOBN(0x9193ceca, 0x3af48649),
+ TOBN(0xfb34327d, 0x2d738fc5), TOBN(0x6697b037, 0x975fee6c),
+ TOBN(0x2f485da0, 0xc04079a5), TOBN(0x2cdf5735, 0x2feaa1ac),
+ TOBN(0x76944420, 0xbd55659e), TOBN(0x7973e32b, 0x4376090c),
+ TOBN(0x86bb4fe1, 0x163b591a), TOBN(0x10441aed, 0xc196f0ca),
+ TOBN(0x3b431f4a, 0x045ad915), TOBN(0x6c11b437, 0xa4afacb1),
+ TOBN(0x30b0c7db, 0x71fdbbd8), TOBN(0xb642931f, 0xeda65acd),
+ TOBN(0x4baae6e8, 0x9c92b235), TOBN(0xa73bbd0e, 0x6b3993a1),
+ TOBN(0xd06d60ec, 0x693dd031), TOBN(0x03cab91b, 0x7156881c),
+ TOBN(0xd615862f, 0x1db3574b), TOBN(0x485b0185, 0x64bb061a),
+ TOBN(0x27434988, 0xa0181e06), TOBN(0x2cd61ad4, 0xc1c0c757),
+ TOBN(0x3effed5a, 0x2ff9f403), TOBN(0x8dc98d8b, 0x62239029),
+ TOBN(0x2206021e, 0x1f17b70d), TOBN(0xafbec0ca, 0xbf510015),
+ TOBN(0x9fed7164, 0x80130dfa), TOBN(0x306dc2b5, 0x8a02dcf5),
+ TOBN(0x48f06620, 0xfeb10fc0), TOBN(0x78d1e1d5, 0x5a57cf51),
+ TOBN(0xadef8c5a, 0x192ef710), TOBN(0x88afbd4b, 0x3b7431f9),
+ TOBN(0x7e1f7407, 0x64250c9e), TOBN(0x6e31318d, 0xb58bec07),
+ TOBN(0xfd4fc4b8, 0x24f89b4e), TOBN(0x65a5dd88, 0x48c36a2a),
+ TOBN(0x4f1eccff, 0xf024baa7), TOBN(0x22a21cf2, 0xcba94650),
+ TOBN(0x95d29dee, 0x42a554f7), TOBN(0x828983a5, 0x002ec4ba),
+ TOBN(0x8112a1f7, 0x8badb73d), TOBN(0x79ea8897, 0xa27c1839),
+ TOBN(0x8969a5a7, 0xd065fd83), TOBN(0xf49af791, 0xb262a0bc),
+ TOBN(0xfcdea8b6, 0xaf2b5127), TOBN(0x10e913e1, 0x564c2dbc),
+ TOBN(0x51239d14, 0xbc21ef51), TOBN(0xe51c3ceb, 0x4ce57292),
+ TOBN(0x795ff068, 0x47bbcc3b), TOBN(0x86b46e1e, 0xbd7e11e6),
+ TOBN(0x0ea6ba23, 0x80041ef4), TOBN(0xd72fe505, 0x6262342e),
+ TOBN(0x8abc6dfd, 0x31d294d4), TOBN(0xbbe017a2, 0x1278c2c9),
+ TOBN(0xb1fcfa09, 0xb389328a), TOBN(0x322fbc62, 0xd01771b5),
+ TOBN(0x04c0d063, 0x60b045bf), TOBN(0xdb652edc, 0x10e52d01),
+ TOBN(0x50ef932c, 0x03ec6627), TOBN(0xde1b3b2d, 0xc1ee50e3),
+ TOBN(0x5ab7bdc5, 0xdc37a90d), TOBN(0xfea67213, 0x31e33a96),
+ TOBN(0x6482b5cb, 0x4f2999aa), TOBN(0x38476cc6, 0xb8cbf0dd),
+ TOBN(0x93ebfacb, 0x173405bb), TOBN(0x15cdafe7, 0xe52369ec),
+ TOBN(0xd42d5ba4, 0xd935b7db), TOBN(0x648b6004, 0x1c99a4cd),
+ TOBN(0x785101bd, 0xa3b5545b), TOBN(0x4bf2c38a, 0x9dd67faf),
+ TOBN(0xb1aadc63, 0x4442449c), TOBN(0xe0e9921a, 0x33ad4fb8),
+ TOBN(0x5c552313, 0xaa686d82), TOBN(0xdee635fa, 0x465d866c),
+ TOBN(0xbc3c224a, 0x18ee6e8a), TOBN(0xeed748a6, 0xed42e02f),
+ TOBN(0xe70f930a, 0xd474cd08), TOBN(0x774ea6ec, 0xfff24adf),
+ TOBN(0x03e2de1c, 0xf3480d4a), TOBN(0xf0d8edc7, 0xbc8acf1a),
+ TOBN(0xf23e3303, 0x68295a9c), TOBN(0xfadd5f68, 0xc546a97d),
+ TOBN(0x895597ad, 0x96f8acb1), TOBN(0xbddd49d5, 0x671bdae2),
+ TOBN(0x16fcd528, 0x21dd43f4), TOBN(0xa5a45412, 0x6619141a)},
+ {TOBN(0x8ce9b6bf, 0xc360e25a), TOBN(0xe6425195, 0x075a1a78),
+ TOBN(0x9dc756a8, 0x481732f4), TOBN(0x83c0440f, 0x5432b57a),
+ TOBN(0xc670b3f1, 0xd720281f), TOBN(0x2205910e, 0xd135e051),
+ TOBN(0xded14b0e, 0xdb052be7), TOBN(0x697b3d27, 0xc568ea39),
+ TOBN(0x2e599b9a, 0xfb3ff9ed), TOBN(0x28c2e0ab, 0x17f6515c),
+ TOBN(0x1cbee4fd, 0x474da449), TOBN(0x071279a4, 0x4f364452),
+ TOBN(0x97abff66, 0x01fbe855), TOBN(0x3ee394e8, 0x5fda51c4),
+ TOBN(0x190385f6, 0x67597c0b), TOBN(0x6e9fccc6, 0xa27ee34b),
+ TOBN(0x0b89de93, 0x14092ebb), TOBN(0xf17256bd, 0x428e240c),
+ TOBN(0xcf89a7f3, 0x93d2f064), TOBN(0x4f57841e, 0xe1ed3b14),
+ TOBN(0x4ee14405, 0xe708d855), TOBN(0x856aae72, 0x03f1c3d0),
+ TOBN(0xc8e5424f, 0xbdd7eed5), TOBN(0x3333e4ef, 0x73ab4270),
+ TOBN(0x3bc77ade, 0xdda492f8), TOBN(0xc11a3aea, 0x78297205),
+ TOBN(0x5e89a3e7, 0x34931b4c), TOBN(0x17512e2e, 0x9f5694bb),
+ TOBN(0x5dc349f3, 0x177bf8b6), TOBN(0x232ea4ba, 0x08c7ff3e),
+ TOBN(0x9c4f9d16, 0xf511145d), TOBN(0xccf109a3, 0x33b379c3),
+ TOBN(0xe75e7a88, 0xa1f25897), TOBN(0x7ac6961f, 0xa1b5d4d8),
+ TOBN(0xe3e10773, 0x08f3ed5c), TOBN(0x208a54ec, 0x0a892dfb),
+ TOBN(0xbe826e19, 0x78660710), TOBN(0x0cf70a97, 0x237df2c8),
+ TOBN(0x418a7340, 0xed704da5), TOBN(0xa3eeb9a9, 0x08ca33fd),
+ TOBN(0x49d96233, 0x169bca96), TOBN(0x04d286d4, 0x2da6aafb),
+ TOBN(0xc09606ec, 0xa0c2fa94), TOBN(0x8869d0d5, 0x23ff0fb3),
+ TOBN(0xa99937e5, 0xd0150d65), TOBN(0xa92e2503, 0x240c14c9),
+ TOBN(0x656bf945, 0x108e2d49), TOBN(0x152a733a, 0xa2f59e2b),
+ TOBN(0xb4323d58, 0x8434a920), TOBN(0xc0af8e93, 0x622103c5),
+ TOBN(0x667518ef, 0x938dbf9a), TOBN(0xa1843073, 0x83a9cdf2),
+ TOBN(0x350a94aa, 0x5447ab80), TOBN(0xe5e5a325, 0xc75a3d61),
+ TOBN(0x74ba507f, 0x68411a9e), TOBN(0x10581fc1, 0x594f70c5),
+ TOBN(0x60e28570, 0x80eb24a9), TOBN(0x7bedfb4d, 0x488e0cfd),
+ TOBN(0x721ebbd7, 0xc259cdb8), TOBN(0x0b0da855, 0xbc6390a9),
+ TOBN(0x2b4d04db, 0xde314c70), TOBN(0xcdbf1fbc, 0x6c32e846),
+ TOBN(0x33833eab, 0xb162fc9e), TOBN(0x9939b48b, 0xb0dd3ab7),
+ TOBN(0x5aaa98a7, 0xcb0c9c8c), TOBN(0x75105f30, 0x81c4375c),
+ TOBN(0xceee5057, 0x5ef1c90f), TOBN(0xb31e065f, 0xc23a17bf),
+ TOBN(0x5364d275, 0xd4b6d45a), TOBN(0xd363f3ad, 0x62ec8996),
+ TOBN(0xb5d21239, 0x4391c65b), TOBN(0x84564765, 0xebb41b47),
+ TOBN(0x20d18ecc, 0x37107c78), TOBN(0xacff3b6b, 0x570c2a66),
+ TOBN(0x22f975d9, 0x9bd0d845), TOBN(0xef0a0c46, 0xba178fa0),
+ TOBN(0x1a419651, 0x76b6028e), TOBN(0xc49ec674, 0x248612d4),
+ TOBN(0x5b6ac4f2, 0x7338af55), TOBN(0x06145e62, 0x7bee5a36),
+ TOBN(0x33e95d07, 0xe75746b5), TOBN(0x1c1e1f6d, 0xc40c78be),
+ TOBN(0x967833ef, 0x222ff8e2), TOBN(0x4bedcf6a, 0xb49180ad),
+ TOBN(0x6b37e9c1, 0x3d7a4c8a), TOBN(0x2748887c, 0x6ddfe760),
+ TOBN(0xf7055123, 0xaa3a5bbc), TOBN(0x954ff225, 0x7bbb8e74),
+ TOBN(0xc42b8ab1, 0x97c3dfb9), TOBN(0x55a549b0, 0xcf168154),
+ TOBN(0xad6748e7, 0xc1b50692), TOBN(0x2775780f, 0x6fc5cbcb),
+ TOBN(0x4eab80b8, 0xe1c9d7c8), TOBN(0x8c69dae1, 0x3fdbcd56),
+ TOBN(0x47e6b4fb, 0x9969eace), TOBN(0x002f1085, 0xa705cb5a),
+ TOBN(0x4e23ca44, 0x6d3fea55), TOBN(0xb4ae9c86, 0xf4810568),
+ TOBN(0x47bfb91b, 0x2a62f27d), TOBN(0x60deb4c9, 0xd9bac28c),
+ TOBN(0xa892d894, 0x7de6c34c), TOBN(0x4ee68259, 0x4494587d),
+ TOBN(0x914ee14e, 0x1a3f8a5b), TOBN(0xbb113eaa, 0x28700385),
+ TOBN(0x81ca03b9, 0x2115b4c9), TOBN(0x7c163d38, 0x8908cad1),
+ TOBN(0xc912a118, 0xaa18179a), TOBN(0xe09ed750, 0x886e3081),
+ TOBN(0xa676e3fa, 0x26f516ca), TOBN(0x753cacf7, 0x8e732f91),
+ TOBN(0x51592aea, 0x833da8b4), TOBN(0xc626f42f, 0x4cbea8aa),
+ TOBN(0xef9dc899, 0xa7b56eaf), TOBN(0x00c0e52c, 0x34ef7316),
+ TOBN(0x5b1e4e24, 0xfe818a86), TOBN(0x9d31e20d, 0xc538be47),
+ TOBN(0x22eb932d, 0x3ed68974), TOBN(0xe44bbc08, 0x7c4e87c4),
+ TOBN(0x4121086e, 0x0dde9aef), TOBN(0x8e6b9cff, 0x134f4345),
+ TOBN(0x96892c1f, 0x711b0eb9), TOBN(0xb905f2c8, 0x780ab954),
+ TOBN(0xace26309, 0xa20792db), TOBN(0xec8ac9b3, 0x0684e126),
+ TOBN(0x486ad8b6, 0xb40a2447), TOBN(0x60121fc1, 0x9fe3fb24),
+ TOBN(0x5626fccf, 0x1a8e3b3f), TOBN(0x4e568622, 0x6ad1f394),
+ TOBN(0xda7aae0d, 0x196aa5a1), TOBN(0xe0df8c77, 0x1041b5fb),
+ TOBN(0x451465d9, 0x26b318b7), TOBN(0xc29b6e55, 0x7ab136e9),
+ TOBN(0x2c2ab48b, 0x71148463), TOBN(0xb5738de3, 0x64454a76),
+ TOBN(0x54ccf9a0, 0x5a03abe4), TOBN(0x377c0296, 0x0427d58e),
+ TOBN(0x73f5f0b9, 0x2bb39c1f), TOBN(0x14373f2c, 0xe608d8c5),
+ TOBN(0xdcbfd314, 0x00fbb805), TOBN(0xdf18fb20, 0x83afdcfb),
+ TOBN(0x81a57f42, 0x42b3523f), TOBN(0xe958532d, 0x87f650fb),
+ TOBN(0xaa8dc8b6, 0x8b0a7d7c), TOBN(0x1b75dfb7, 0x150166be),
+ TOBN(0x90e4f7c9, 0x2d7d1413), TOBN(0x67e2d6b5, 0x9834f597),
+ TOBN(0x4fd4f4f9, 0xa808c3e8), TOBN(0xaf8237e0, 0xd5281ec1),
+ TOBN(0x25ab5fdc, 0x84687cee), TOBN(0xc5ded6b1, 0xa5b26c09),
+ TOBN(0x8e4a5aec, 0xc8ea7650), TOBN(0x23b73e5c, 0x14cc417f),
+ TOBN(0x2bfb4318, 0x3037bf52), TOBN(0xb61e6db5, 0x78c725d7),
+ TOBN(0x8efd4060, 0xbbb3e5d7), TOBN(0x2e014701, 0xdbac488e),
+ TOBN(0xac75cf9a, 0x360aa449), TOBN(0xb70cfd05, 0x79634d08),
+ TOBN(0xa591536d, 0xfffb15ef), TOBN(0xb2c37582, 0xd07c106c),
+ TOBN(0xb4293fdc, 0xf50225f9), TOBN(0xc52e175c, 0xb0e12b03),
+ TOBN(0xf649c3ba, 0xd0a8bf64), TOBN(0x745a8fef, 0xeb8ae3c6),
+ TOBN(0x30d7e5a3, 0x58321bc3), TOBN(0xb1732be7, 0x0bc4df48),
+ TOBN(0x1f217993, 0xe9ea5058), TOBN(0xf7a71cde, 0x3e4fd745),
+ TOBN(0x86cc533e, 0x894c5bbb), TOBN(0x6915c7d9, 0x69d83082),
+ TOBN(0xa6aa2d05, 0x5815c244), TOBN(0xaeeee592, 0x49b22ce5),
+ TOBN(0x89e39d13, 0x78135486), TOBN(0x3a275c1f, 0x16b76f2f),
+ TOBN(0xdb6bcc1b, 0xe036e8f5), TOBN(0x4df69b21, 0x5e4709f5),
+ TOBN(0xa188b250, 0x2d0f39aa), TOBN(0x622118bb, 0x15a85947),
+ TOBN(0x2ebf520f, 0xfde0f4fa), TOBN(0xa40e9f29, 0x4860e539),
+ TOBN(0x7b6a51eb, 0x22b57f0f), TOBN(0x849a33b9, 0x7e80644a),
+ TOBN(0x50e5d16f, 0x1cf095fe), TOBN(0xd754b54e, 0xec55f002),
+ TOBN(0x5cfbbb22, 0x236f4a98), TOBN(0x0b0c59e9, 0x066800bb),
+ TOBN(0x4ac69a8f, 0x5a9a7774), TOBN(0x2b33f804, 0xd6bec948),
+ TOBN(0xb3729295, 0x32e6c466), TOBN(0x68956d0f, 0x4e599c73),
+ TOBN(0xa47a249f, 0x155c31cc), TOBN(0x24d80f0d, 0xe1ce284e),
+ TOBN(0xcd821dfb, 0x988baf01), TOBN(0xe6331a7d, 0xdbb16647),
+ TOBN(0x1eb8ad33, 0x094cb960), TOBN(0x593cca38, 0xc91bbca5),
+ TOBN(0x384aac8d, 0x26567456), TOBN(0x40fa0309, 0xc04b6490),
+ TOBN(0x97834cd6, 0xdab6c8f6), TOBN(0x68a7318d, 0x3f91e55f),
+ TOBN(0xa00fd04e, 0xfc4d3157), TOBN(0xb56f8ab2, 0x2bf3bdea),
+ TOBN(0x014f5648, 0x4fa57172), TOBN(0x948c5860, 0x450abdb3),
+ TOBN(0x342b5df0, 0x0ebd4f08), TOBN(0x3e5168cd, 0x0e82938e),
+ TOBN(0x7aedc1ce, 0xb0df5dd0), TOBN(0x6bbbc6d9, 0xe5732516),
+ TOBN(0xc7bfd486, 0x605daaa6), TOBN(0x46fd72b7, 0xbb9a6c9e),
+ TOBN(0xe4847fb1, 0xa124fb89), TOBN(0x75959cbd, 0xa2d8ffbc),
+ TOBN(0x42579f65, 0xc8a588ee), TOBN(0x368c92e6, 0xb80b499d),
+ TOBN(0xea4ef6cd, 0x999a5df1), TOBN(0xaa73bb7f, 0x936fe604),
+ TOBN(0xf347a70d, 0x6457d188), TOBN(0x86eda86b, 0x8b7a388b),
+ TOBN(0xb7cdff06, 0x0ccd6013), TOBN(0xbeb1b6c7, 0xd0053fb2),
+ TOBN(0x0b022387, 0x99240a9f), TOBN(0x1bbb384f, 0x776189b2),
+ TOBN(0x8695e71e, 0x9066193a), TOBN(0x2eb50097, 0x06ffac7e),
+ TOBN(0x0654a9c0, 0x4a7d2caa), TOBN(0x6f3fb3d1, 0xa5aaa290),
+ TOBN(0x835db041, 0xff476e8f), TOBN(0x540b8b0b, 0xc42295e4),
+ TOBN(0xa5c73ac9, 0x05e214f5), TOBN(0x9a74075a, 0x56a0b638),
+ TOBN(0x2e4b1090, 0xce9e680b), TOBN(0x57a5b479, 0x6b8d9afa),
+ TOBN(0x0dca48e7, 0x26bfe65c), TOBN(0x097e391c, 0x7290c307),
+ TOBN(0x683c462e, 0x6669e72e), TOBN(0xf505be1e, 0x062559ac),
+ TOBN(0x5fbe3ea1, 0xe3a3035a), TOBN(0x6431ebf6, 0x9cd50da8),
+ TOBN(0xfd169d5c, 0x1f6407f2), TOBN(0x8d838a95, 0x60fce6b8),
+ TOBN(0x2a2bfa7f, 0x650006f0), TOBN(0xdfd7dad3, 0x50c0fbb2),
+ TOBN(0x92452495, 0xccf9ad96), TOBN(0x183bf494, 0xd95635f9),
+ TOBN(0x02d5df43, 0x4a7bd989), TOBN(0x505385cc, 0xa5431095),
+ TOBN(0xdd98e67d, 0xfd43f53e), TOBN(0xd61e1a6c, 0x500c34a9),
+ TOBN(0x5a4b46c6, 0x4a8a3d62), TOBN(0x8469c4d0, 0x247743d2),
+ TOBN(0x2bb3a13d, 0x88f7e433), TOBN(0x62b23a10, 0x01be5849),
+ TOBN(0xe83596b4, 0xa63d1a4c), TOBN(0x454e7fea, 0x7d183f3e),
+ TOBN(0x643fce61, 0x17afb01c), TOBN(0x4e65e5e6, 0x1c4c3638),
+ TOBN(0x41d85ea1, 0xef74c45b), TOBN(0x2cfbfa66, 0xae328506),
+ TOBN(0x98b078f5, 0x3ada7da9), TOBN(0xd985fe37, 0xec752fbb),
+ TOBN(0xeece68fe, 0x5a0148b4), TOBN(0x6f9a55c7, 0x2d78136d),
+ TOBN(0x232dccc4, 0xd2b729ce), TOBN(0xa27e0dfd, 0x90aafbc4),
+ TOBN(0x96474452, 0x12b4603e), TOBN(0xa876c551, 0x6b706d14),
+ TOBN(0xdf145fcf, 0x69a9d412), TOBN(0xe2ab75b7, 0x2d479c34),
+ TOBN(0x12df9a76, 0x1a23ff97), TOBN(0xc6138992, 0x5d359d10),
+ TOBN(0x6e51c7ae, 0xfa835f22), TOBN(0x69a79cb1, 0xc0fcc4d9),
+ TOBN(0xf57f350d, 0x594cc7e1), TOBN(0x3079ca63, 0x3350ab79),
+ TOBN(0x226fb614, 0x9aff594a), TOBN(0x35afec02, 0x6d59a62b),
+ TOBN(0x9bee46f4, 0x06ed2c6e), TOBN(0x58da1735, 0x7d939a57),
+ TOBN(0x44c50402, 0x8fd1797e), TOBN(0xd8853e7c, 0x5ccea6ca),
+ TOBN(0x4065508d, 0xa35fcd5f), TOBN(0x8965df8c, 0x495ccaeb),
+ TOBN(0x0f2da850, 0x12e1a962), TOBN(0xee471b94, 0xc1cf1cc4),
+ TOBN(0xcef19bc8, 0x0a08fb75), TOBN(0x704958f5, 0x81de3591),
+ TOBN(0x2867f8b2, 0x3aef4f88), TOBN(0x8d749384, 0xea9f9a5f),
+ TOBN(0x1b385537, 0x8c9049f4), TOBN(0x5be948f3, 0x7b92d8b6),
+ TOBN(0xd96f725d, 0xb6e2bd6b), TOBN(0x37a222bc, 0x958c454d),
+ TOBN(0xe7c61abb, 0x8809bf61), TOBN(0x46f07fbc, 0x1346f18d),
+ TOBN(0xfb567a7a, 0xe87c0d1c), TOBN(0x84a461c8, 0x7ef3d07a),
+ TOBN(0x0a5adce6, 0xd9278d98), TOBN(0x24d94813, 0x9dfc73e1),
+ TOBN(0x4f3528b6, 0x054321c3), TOBN(0x2e03fdde, 0x692ea706),
+ TOBN(0x10e60619, 0x47b533c0), TOBN(0x1a8bc73f, 0x2ca3c055),
+ TOBN(0xae58d4b2, 0x1bb62b8f), TOBN(0xb2045a73, 0x584a24e3),
+ TOBN(0x3ab3d5af, 0xbd76e195), TOBN(0x478dd1ad, 0x6938a810),
+ TOBN(0x6ffab393, 0x6ee3d5cb), TOBN(0xdfb693db, 0x22b361e4),
+ TOBN(0xf9694496, 0x51dbf1a7), TOBN(0xcab4b4ef, 0x08a2e762),
+ TOBN(0xe8c92f25, 0xd39bba9a), TOBN(0x850e61bc, 0xf1464d96),
+ TOBN(0xb7e830e3, 0xdc09508b), TOBN(0xfaf6d2cf, 0x74317655),
+ TOBN(0x72606ceb, 0xdf690355), TOBN(0x48bb92b3, 0xd0c3ded6),
+ TOBN(0x65b75484, 0x5c7cf892), TOBN(0xf6cd7ac9, 0xd5d5f01f),
+ TOBN(0xc2c30a59, 0x96401d69), TOBN(0x91268650, 0xed921878),
+ TOBN(0x380bf913, 0xb78c558f), TOBN(0x43c0baeb, 0xc8afdaa9),
+ TOBN(0x377f61d5, 0x54f169d3), TOBN(0xf8da07e3, 0xae5ff20b),
+ TOBN(0xb676c49d, 0xa8a90ea8), TOBN(0x81c1ff2b, 0x83a29b21),
+ TOBN(0x383297ac, 0x2ad8d276), TOBN(0x3001122f, 0xba89f982),
+ TOBN(0xe1d794be, 0x6718e448), TOBN(0x246c1482, 0x7c3e6e13),
+ TOBN(0x56646ef8, 0x5d26b5ef), TOBN(0x80f5091e, 0x88069cdd),
+ TOBN(0xc5992e2f, 0x724bdd38), TOBN(0x02e915b4, 0x8471e8c7),
+ TOBN(0x96ff320a, 0x0d0ff2a9), TOBN(0xbf886487, 0x4384d1a0),
+ TOBN(0xbbe1e6a6, 0xc93f72d6), TOBN(0xd5f75d12, 0xcad800ea),
+ TOBN(0xfa40a09f, 0xe7acf117), TOBN(0x32c8cdd5, 0x7581a355),
+ TOBN(0x74221992, 0x7023c499), TOBN(0xa8afe5d7, 0x38ec3901),
+ TOBN(0x5691afcb, 0xa90e83f0), TOBN(0x41bcaa03, 0x0b8f8eac),
+ TOBN(0xe38b5ff9, 0x8d2668d5), TOBN(0x0715281a, 0x7ad81965),
+ TOBN(0x1bc8fc7c, 0x03c6ce11), TOBN(0xcbbee6e2, 0x8b650436),
+ TOBN(0x06b00fe8, 0x0cdb9808), TOBN(0x17d6e066, 0xfe3ed315),
+ TOBN(0x2e9d38c6, 0x4d0b5018), TOBN(0xab8bfd56, 0x844dcaef),
+ TOBN(0x42894a59, 0x513aed8b), TOBN(0xf77f3b6d, 0x314bd07a),
+ TOBN(0xbbdecb8f, 0x8e42b582), TOBN(0xf10e2fa8, 0xd2390fe6),
+ TOBN(0xefb95022, 0x62a2f201), TOBN(0x4d59ea50, 0x50ee32b0),
+ TOBN(0xd87f7728, 0x6da789a8), TOBN(0xcf98a2cf, 0xf79492c4),
+ TOBN(0xf9577239, 0x720943c2), TOBN(0xba044cf5, 0x3990b9d0),
+ TOBN(0x5aa8e823, 0x95f2884a), TOBN(0x834de6ed, 0x0278a0af),
+ TOBN(0xc8e1ee9a, 0x5f25bd12), TOBN(0x9259ceaa, 0x6f7ab271),
+ TOBN(0x7e6d97a2, 0x77d00b76), TOBN(0x5c0c6eea, 0xa437832a),
+ TOBN(0x5232c20f, 0x5606b81d), TOBN(0xabd7b375, 0x0d991ee5),
+ TOBN(0x4d2bfe35, 0x8632d951), TOBN(0x78f85146, 0x98ed9364),
+ TOBN(0x951873f0, 0xf30c3282), TOBN(0x0da8ac80, 0xa789230b),
+ TOBN(0x3ac7789c, 0x5398967f), TOBN(0xa69b8f7f, 0xbdda0fb5),
+ TOBN(0xe5db7717, 0x6add8545), TOBN(0x1b71cb66, 0x72c49b66),
+ TOBN(0xd8560739, 0x68421d77), TOBN(0x03840fe8, 0x83e3afea),
+ TOBN(0xb391dad5, 0x1ec69977), TOBN(0xae243fb9, 0x307f6726),
+ TOBN(0xc88ac87b, 0xe8ca160c), TOBN(0x5174cced, 0x4ce355f4),
+ TOBN(0x98a35966, 0xe58ba37d), TOBN(0xfdcc8da2, 0x7817335d),
+ TOBN(0x5b752830, 0x83fbc7bf), TOBN(0x68e419d4, 0xd9c96984),
+ TOBN(0x409a39f4, 0x02a40380), TOBN(0x88940faf, 0x1fe977bc),
+ TOBN(0xc640a94b, 0x8f8edea6), TOBN(0x1e22cd17, 0xed11547d),
+ TOBN(0xe28568ce, 0x59ffc3e2), TOBN(0x60aa1b55, 0xc1dee4e7),
+ TOBN(0xc67497c8, 0x837cb363), TOBN(0x06fb438a, 0x105a2bf2),
+ TOBN(0x30357ec4, 0x500d8e20), TOBN(0x1ad9095d, 0x0670db10),
+ TOBN(0x7f589a05, 0xc73b7cfd), TOBN(0xf544607d, 0x880d6d28),
+ TOBN(0x17ba93b1, 0xa20ef103), TOBN(0xad859130, 0x6ba6577b),
+ TOBN(0x65c91cf6, 0x6fa214a0), TOBN(0xd7d49c6c, 0x27990da5),
+ TOBN(0xecd9ec8d, 0x20bb569d), TOBN(0xbd4b2502, 0xeeffbc33),
+ TOBN(0x2056ca5a, 0x6bed0467), TOBN(0x7916a1f7, 0x5b63728c),
+ TOBN(0xd4f9497d, 0x53a4f566), TOBN(0x89734664, 0x97b56810),
+ TOBN(0xf8e1da74, 0x0494a621), TOBN(0x82546a93, 0x8d011c68),
+ TOBN(0x1f3acb19, 0xc61ac162), TOBN(0x52f8fa9c, 0xabad0d3e),
+ TOBN(0x15356523, 0xb4b7ea43), TOBN(0x5a16ad61, 0xae608125),
+ TOBN(0xb0bcb87f, 0x4faed184), TOBN(0x5f236b1d, 0x5029f45f),
+ TOBN(0xd42c7607, 0x0bc6b1fc), TOBN(0xc644324e, 0x68aefce3),
+ TOBN(0x8e191d59, 0x5c5d8446), TOBN(0xc0208077, 0x13ae1979),
+ TOBN(0xadcaee55, 0x3ba59cc7), TOBN(0x20ed6d6b, 0xa2cb81ba),
+ TOBN(0x0952ba19, 0xb6efcffc), TOBN(0x60f12d68, 0x97c0b87c),
+ TOBN(0x4ee2c7c4, 0x9caa30bc), TOBN(0x767238b7, 0x97fbff4e),
+ TOBN(0xebc73921, 0x501b5d92), TOBN(0x3279e3df, 0xc2a37737),
+ TOBN(0x9fc12bc8, 0x6d197543), TOBN(0xfa94dc6f, 0x0a40db4e),
+ TOBN(0x7392b41a, 0x530ccbbd), TOBN(0x87c82146, 0xea823525),
+ TOBN(0xa52f984c, 0x05d98d0c), TOBN(0x2ae57d73, 0x5ef6974c),
+ TOBN(0x9377f7bf, 0x3042a6dd), TOBN(0xb1a007c0, 0x19647a64),
+ TOBN(0xfaa9079a, 0x0cca9767), TOBN(0x3d81a25b, 0xf68f72d5),
+ TOBN(0x752067f8, 0xff81578e), TOBN(0x78622150, 0x9045447d),
+ TOBN(0xc0c22fcf, 0x0505aa6f), TOBN(0x1030f0a6, 0x6bed1c77),
+ TOBN(0x31f29f15, 0x1f0bd739), TOBN(0x2d7989c7, 0xe6debe85),
+ TOBN(0x5c070e72, 0x8e677e98), TOBN(0x0a817bd3, 0x06e81fd5),
+ TOBN(0xc110d830, 0xb0f2ac95), TOBN(0x48d0995a, 0xab20e64e),
+ TOBN(0x0f3e00e1, 0x7729cd9a), TOBN(0x2a570c20, 0xdd556946),
+ TOBN(0x912dbcfd, 0x4e86214d), TOBN(0x2d014ee2, 0xcf615498),
+ TOBN(0x55e2b1e6, 0x3530d76e), TOBN(0xc5135ae4, 0xfd0fd6d1),
+ TOBN(0x0066273a, 0xd4f3049f), TOBN(0xbb8e9893, 0xe7087477),
+ TOBN(0x2dba1ddb, 0x14c6e5fd), TOBN(0xdba37886, 0x51f57e6c),
+ TOBN(0x5aaee0a6, 0x5a72f2cf), TOBN(0x1208bfbf, 0x7bea5642),
+ TOBN(0xf5c6aa3b, 0x67872c37), TOBN(0xd726e083, 0x43f93224),
+ TOBN(0x1854daa5, 0x061f1658), TOBN(0xc0016df1, 0xdf0cd2b3),
+ TOBN(0xc2a3f23e, 0x833d50de), TOBN(0x73b681d2, 0xbbbd3017),
+ TOBN(0x2f046dc4, 0x3ac343c0), TOBN(0x9c847e7d, 0x85716421),
+ TOBN(0xe1e13c91, 0x0917eed4), TOBN(0x3fc9eebd, 0x63a1b9c6),
+ TOBN(0x0f816a72, 0x7fe02299), TOBN(0x6335ccc2, 0x294f3319),
+ TOBN(0x3820179f, 0x4745c5be), TOBN(0xe647b782, 0x922f066e),
+ TOBN(0xc22e49de, 0x02cafb8a), TOBN(0x299bc2ff, 0xfcc2eccc),
+ TOBN(0x9a8feea2, 0x6e0e8282), TOBN(0xa627278b, 0xfe893205),
+ TOBN(0xa7e19733, 0x7933e47b), TOBN(0xf4ff6b13, 0x2e766402),
+ TOBN(0xa4d8be0a, 0x98440d9f), TOBN(0x658f5c2f, 0x38938808),
+ TOBN(0x90b75677, 0xc95b3b3e), TOBN(0xfa044269, 0x3137b6ff),
+ TOBN(0x077b039b, 0x43c47c29), TOBN(0xcca95dd3, 0x8a6445b2),
+ TOBN(0x0b498ba4, 0x2333fc4c), TOBN(0x274f8e68, 0xf736a1b1),
+ TOBN(0x6ca348fd, 0x5f1d4b2e), TOBN(0x24d3be78, 0xa8f10199),
+ TOBN(0x8535f858, 0xca14f530), TOBN(0xa6e7f163, 0x5b982e51),
+ TOBN(0x847c8512, 0x36e1bf62), TOBN(0xf6a7c58e, 0x03448418),
+ TOBN(0x583f3703, 0xf9374ab6), TOBN(0x864f9195, 0x6e564145),
+ TOBN(0x33bc3f48, 0x22526d50), TOBN(0x9f323c80, 0x1262a496),
+ TOBN(0xaa97a7ae, 0x3f046a9a), TOBN(0x70da183e, 0xdf8a039a),
+ TOBN(0x5b68f71c, 0x52aa0ba6), TOBN(0x9be0fe51, 0x21459c2d),
+ TOBN(0xc1e17eb6, 0xcbc613e5), TOBN(0x33131d55, 0x497ea61c),
+ TOBN(0x2f69d39e, 0xaf7eded5), TOBN(0x73c2f434, 0xde6af11b),
+ TOBN(0x4ca52493, 0xa4a375fa), TOBN(0x5f06787c, 0xb833c5c2),
+ TOBN(0x814e091f, 0x3e6e71cf), TOBN(0x76451f57, 0x8b746666)},
+ {
+ TOBN(0x80f9bdef, 0x694db7e0), TOBN(0xedca8787, 0xb9fcddc6),
+ TOBN(0x51981c34, 0x03b8dce1), TOBN(0x4274dcf1, 0x70e10ba1),
+ TOBN(0xf72743b8, 0x6def6d1a), TOBN(0xd25b1670, 0xebdb1866),
+ TOBN(0xc4491e8c, 0x050c6f58), TOBN(0x2be2b2ab, 0x87fbd7f5),
+ TOBN(0x3e0e5c9d, 0xd111f8ec), TOBN(0xbcc33f8d, 0xb7c4e760),
+ TOBN(0x702f9a91, 0xbd392a51), TOBN(0x7da4a795, 0xc132e92d),
+ TOBN(0x1a0b0ae3, 0x0bb1151b), TOBN(0x54febac8, 0x02e32251),
+ TOBN(0xea3a5082, 0x694e9e78), TOBN(0xe58ffec1, 0xe4fe40b8),
+ TOBN(0xf85592fc, 0xd1e0cf9e), TOBN(0xdea75f0d, 0xc0e7b2e8),
+ TOBN(0xc04215cf, 0xc135584e), TOBN(0x174fc727, 0x2f57092a),
+ TOBN(0xe7277877, 0xeb930bea), TOBN(0x504caccb, 0x5eb02a5a),
+ TOBN(0xf9fe08f7, 0xf5241b9b), TOBN(0xe7fb62f4, 0x8d5ca954),
+ TOBN(0xfbb8349d, 0x29c4120b), TOBN(0x9f94391f, 0xc0d0d915),
+ TOBN(0xc4074fa7, 0x5410ba51), TOBN(0xa66adbf6, 0x150a5911),
+ TOBN(0xc164543c, 0x34bfca38), TOBN(0xe0f27560, 0xb9e1ccfc),
+ TOBN(0x99da0f53, 0xe820219c), TOBN(0xe8234498, 0xc6b4997a),
+ TOBN(0xcfb88b76, 0x9d4c5423), TOBN(0x9e56eb10, 0xb0521c49),
+ TOBN(0x418e0b5e, 0xbe8700a1), TOBN(0x00cbaad6, 0xf93cb58a),
+ TOBN(0xe923fbde, 0xd92a5e67), TOBN(0xca4979ac, 0x1f347f11),
+ TOBN(0x89162d85, 0x6bc0585b), TOBN(0xdd6254af, 0xac3c70e3),
+ TOBN(0x7b23c513, 0x516e19e4), TOBN(0x56e2e847, 0xc5c4d593),
+ TOBN(0x9f727d73, 0x5ce71ef6), TOBN(0x5b6304a6, 0xf79a44c5),
+ TOBN(0x6638a736, 0x3ab7e433), TOBN(0x1adea470, 0xfe742f83),
+ TOBN(0xe054b854, 0x5b7fc19f), TOBN(0xf935381a, 0xba1d0698),
+ TOBN(0x546eab2d, 0x799e9a74), TOBN(0x96239e0e, 0xa949f729),
+ TOBN(0xca274c6b, 0x7090055a), TOBN(0x835142c3, 0x9020c9b0),
+ TOBN(0xa405667a, 0xa2e8807f), TOBN(0x29f2c085, 0x1aa3d39e),
+ TOBN(0xcc555d64, 0x42fc72f5), TOBN(0xe856e0e7, 0xfbeacb3c),
+ TOBN(0xb5504f9d, 0x918e4936), TOBN(0x65035ef6, 0xb2513982),
+ TOBN(0x0553a0c2, 0x6f4d9cb9), TOBN(0x6cb10d56, 0xbea85509),
+ TOBN(0x48d957b7, 0xa242da11), TOBN(0x16a4d3dd, 0x672b7268),
+ TOBN(0x3d7e637c, 0x8502a96b), TOBN(0x27c7032b, 0x730d463b),
+ TOBN(0xbdc02b18, 0xe4136a14), TOBN(0xbacf969d, 0x678e32bf),
+ TOBN(0xc98d89a3, 0xdd9c3c03), TOBN(0x7b92420a, 0x23becc4f),
+ TOBN(0xd4b41f78, 0xc64d565c), TOBN(0x9f969d00, 0x10f28295),
+ TOBN(0xec7f7f76, 0xb13d051a), TOBN(0x08945e1e, 0xa92da585),
+ TOBN(0x55366b7d, 0x5846426f), TOBN(0xe7d09e89, 0x247d441d),
+ TOBN(0x510b404d, 0x736fbf48), TOBN(0x7fa003d0, 0xe784bd7d),
+ TOBN(0x25f7614f, 0x17fd9596), TOBN(0x49e0e0a1, 0x35cb98db),
+ TOBN(0x2c65957b, 0x2e83a76a), TOBN(0x5d40da8d, 0xcddbe0f8),
+ TOBN(0xf2b8c405, 0x050bad24), TOBN(0x8918426d, 0xc2aa4823),
+ TOBN(0x2aeab3dd, 0xa38365a7), TOBN(0x72031717, 0x7c91b690),
+ TOBN(0x8b00d699, 0x60a94120), TOBN(0x478a255d, 0xe99eaeec),
+ TOBN(0xbf656a5f, 0x6f60aafd), TOBN(0xdfd7cb75, 0x5dee77b3),
+ TOBN(0x37f68bb4, 0xa595939d), TOBN(0x03556479, 0x28740217),
+ TOBN(0x8e740e7c, 0x84ad7612), TOBN(0xd89bc843, 0x9044695f),
+ TOBN(0xf7f3da5d, 0x85a9184d), TOBN(0x562563bb, 0x9fc0b074),
+ TOBN(0x06d2e6aa, 0xf88a888e), TOBN(0x612d8643, 0x161fbe7c),
+ TOBN(0x465edba7, 0xf64085e7), TOBN(0xb230f304, 0x29aa8511),
+ TOBN(0x53388426, 0xcda2d188), TOBN(0x90885735, 0x4b666649),
+ TOBN(0x6f02ff9a, 0x652f54f6), TOBN(0x65c82294, 0x5fae2bf0),
+ TOBN(0x7816ade0, 0x62f5eee3), TOBN(0xdcdbdf43, 0xfcc56d70),
+ TOBN(0x9fb3bba3, 0x54530bb2), TOBN(0xbde3ef77, 0xcb0869ea),
+ TOBN(0x89bc9046, 0x0b431163), TOBN(0x4d03d7d2, 0xe4819a35),
+ TOBN(0x33ae4f9e, 0x43b6a782), TOBN(0x216db307, 0x9c88a686),
+ TOBN(0x91dd88e0, 0x00ffedd9), TOBN(0xb280da9f, 0x12bd4840),
+ TOBN(0x32a7cb8a, 0x1635e741), TOBN(0xfe14008a, 0x78be02a7),
+ TOBN(0x3fafb334, 0x1b7ae030), TOBN(0x7fd508e7, 0x5add0ce9),
+ TOBN(0x72c83219, 0xd607ad51), TOBN(0x0f229c0a, 0x8d40964a),
+ TOBN(0x1be2c336, 0x1c878da2), TOBN(0xe0c96742, 0xeab2ab86),
+ TOBN(0x458f8691, 0x3e538cd7), TOBN(0xa7001f6c, 0x8e08ad53),
+ TOBN(0x52b8c6e6, 0xbf5d15ff), TOBN(0x548234a4, 0x011215dd),
+ TOBN(0xff5a9d2d, 0x3d5b4045), TOBN(0xb0ffeeb6, 0x4a904190),
+ TOBN(0x55a3aca4, 0x48607f8b), TOBN(0x8cbd665c, 0x30a0672a),
+ TOBN(0x87f834e0, 0x42583068), TOBN(0x02da2aeb, 0xf3f6e683),
+ TOBN(0x6b763e5d, 0x05c12248), TOBN(0x7230378f, 0x65a8aefc),
+ TOBN(0x93bd80b5, 0x71e8e5ca), TOBN(0x53ab041c, 0xb3b62524),
+ TOBN(0x1b860513, 0x6c9c552e), TOBN(0xe84d402c, 0xd5524e66),
+ TOBN(0xa37f3573, 0xf37f5937), TOBN(0xeb0f6c7d, 0xd1e4fca5),
+ TOBN(0x2965a554, 0xac8ab0fc), TOBN(0x17fbf56c, 0x274676ac),
+ TOBN(0x2e2f6bd9, 0xacf7d720), TOBN(0x41fc8f88, 0x10224766),
+ TOBN(0x517a14b3, 0x85d53bef), TOBN(0xdae327a5, 0x7d76a7d1),
+ TOBN(0x6ad0a065, 0xc4818267), TOBN(0x33aa189b, 0x37c1bbc1),
+ TOBN(0x64970b52, 0x27392a92), TOBN(0x21699a1c, 0x2d1535ea),
+ TOBN(0xcd20779c, 0xc2d7a7fd), TOBN(0xe3186059, 0x99c83cf2),
+ TOBN(0x9b69440b, 0x72c0b8c7), TOBN(0xa81497d7, 0x7b9e0e4d),
+ TOBN(0x515d5c89, 0x1f5f82dc), TOBN(0x9a7f67d7, 0x6361079e),
+ TOBN(0xa8da81e3, 0x11a35330), TOBN(0xe44990c4, 0x4b18be1b),
+ TOBN(0xc7d5ed95, 0xaf103e59), TOBN(0xece8aba7, 0x8dac9261),
+ TOBN(0xbe82b099, 0x9394b8d3), TOBN(0x6830f09a, 0x16adfe83),
+ TOBN(0x250a29b4, 0x88172d01), TOBN(0x8b20bd65, 0xcaff9e02),
+ TOBN(0xb8a7661e, 0xe8a6329a), TOBN(0x4520304d, 0xd3fce920),
+ TOBN(0xae45da1f, 0x2b47f7ef), TOBN(0xe07f5288, 0x5bffc540),
+ TOBN(0xf7997009, 0x3464f874), TOBN(0x2244c2cd, 0xa6fa1f38),
+ TOBN(0x43c41ac1, 0x94d7d9b1), TOBN(0x5bafdd82, 0xc82e7f17),
+ TOBN(0xdf0614c1, 0x5fda0fca), TOBN(0x74b043a7, 0xa8ae37ad),
+ TOBN(0x3ba6afa1, 0x9e71734c), TOBN(0x15d5437e, 0x9c450f2e),
+ TOBN(0x4a5883fe, 0x67e242b1), TOBN(0x5143bdc2, 0x2c1953c2),
+ TOBN(0x542b8b53, 0xfc5e8920), TOBN(0x363bf9a8, 0x9a9cee08),
+ TOBN(0x02375f10, 0xc3486e08), TOBN(0x2037543b, 0x8c5e70d2),
+ TOBN(0x7109bccc, 0x625640b4), TOBN(0xcbc1051e, 0x8bc62c3b),
+ TOBN(0xf8455fed, 0x803f26ea), TOBN(0x6badceab, 0xeb372424),
+ TOBN(0xa2a9ce7c, 0x6b53f5f9), TOBN(0x64246595, 0x1b176d99),
+ TOBN(0xb1298d36, 0xb95c081b), TOBN(0x53505bb8, 0x1d9a9ee6),
+ TOBN(0x3f6f9e61, 0xf2ba70b0), TOBN(0xd07e16c9, 0x8afad453),
+ TOBN(0x9f1694bb, 0xe7eb4a6a), TOBN(0xdfebced9, 0x3cb0bc8e),
+ TOBN(0x92d3dcdc, 0x53868c8b), TOBN(0x174311a2, 0x386107a6),
+ TOBN(0x4109e07c, 0x689b4e64), TOBN(0x30e4587f, 0x2df3dcb6),
+ TOBN(0x841aea31, 0x0811b3b2), TOBN(0x6144d41d, 0x0cce43ea),
+ TOBN(0x464c4581, 0x2a9a7803), TOBN(0xd03d371f, 0x3e158930),
+ TOBN(0xc676d7f2, 0xb1f3390b), TOBN(0x9f7a1b8c, 0xa5b61272),
+ TOBN(0x4ebebfc9, 0xc2e127a9), TOBN(0x4602500c, 0x5dd997bf),
+ TOBN(0x7f09771c, 0x4711230f), TOBN(0x058eb37c, 0x020f09c1),
+ TOBN(0xab693d4b, 0xfee5e38b), TOBN(0x9289eb1f, 0x4653cbc0),
+ TOBN(0xbecf46ab, 0xd51b9cf5), TOBN(0xd2aa9c02, 0x9f0121af),
+ TOBN(0x36aaf7d2, 0xe90dc274), TOBN(0x909e4ea0, 0x48b95a3c),
+ TOBN(0xe6b70496, 0x6f32dbdb), TOBN(0x672188a0, 0x8b030b3e),
+ TOBN(0xeeffe5b3, 0xcfb617e2), TOBN(0x87e947de, 0x7c82709e),
+ TOBN(0xa44d2b39, 0x1770f5a7), TOBN(0xe4d4d791, 0x0e44eb82),
+ TOBN(0x42e69d1e, 0x3f69712a), TOBN(0xbf11c4d6, 0xac6a820e),
+ TOBN(0xb5e7f3e5, 0x42c4224c), TOBN(0xd6b4e81c, 0x449d941c),
+ TOBN(0x5d72bd16, 0x5450e878), TOBN(0x6a61e28a, 0xee25ac54),
+ TOBN(0x33272094, 0xe6f1cd95), TOBN(0x7512f30d, 0x0d18673f),
+ TOBN(0x32f7a4ca, 0x5afc1464), TOBN(0x2f095656, 0x6bbb977b),
+ TOBN(0x586f47ca, 0xa8226200), TOBN(0x02c868ad, 0x1ac07369),
+ TOBN(0x4ef2b845, 0xc613acbe), TOBN(0x43d7563e, 0x0386054c),
+ TOBN(0x54da9dc7, 0xab952578), TOBN(0xb5423df2, 0x26e84d0b),
+ TOBN(0xa8b64eeb, 0x9b872042), TOBN(0xac205782, 0x5990f6df),
+ TOBN(0x4ff696eb, 0x21f4c77a), TOBN(0x1a79c3e4, 0xaab273af),
+ TOBN(0x29bc922e, 0x9436b3f1), TOBN(0xff807ef8, 0xd6d9a27a),
+ TOBN(0x82acea3d, 0x778f22a0), TOBN(0xfb10b2e8, 0x5b5e7469),
+ TOBN(0xc0b16980, 0x2818ee7d), TOBN(0x011afff4, 0xc91c1a2f),
+ TOBN(0x95a6d126, 0xad124418), TOBN(0x31c081a5, 0xe72e295f),
+ TOBN(0x36bb283a, 0xf2f4db75), TOBN(0xd115540f, 0x7acef462),
+ TOBN(0xc7f3a8f8, 0x33f6746c), TOBN(0x21e46f65, 0xfea990ca),
+ TOBN(0x915fd5c5, 0xcaddb0a9), TOBN(0xbd41f016, 0x78614555),
+ TOBN(0x346f4434, 0x426ffb58), TOBN(0x80559436, 0x14dbc204),
+ TOBN(0xf3dd20fe, 0x5a969b7f), TOBN(0x9d59e956, 0xe899a39a),
+ TOBN(0xf1b0971c, 0x8ad4cf4b), TOBN(0x03448860, 0x2ffb8fb8),
+ TOBN(0xf071ac3c, 0x65340ba4), TOBN(0x408d0596, 0xb27fd758),
+ TOBN(0xe7c78ea4, 0x98c364b0), TOBN(0xa4aac4a5, 0x051e8ab5),
+ TOBN(0xb9e1d560, 0x485d9002), TOBN(0x9acd518a, 0x88844455),
+ TOBN(0xe4ca688f, 0xd06f56c0), TOBN(0xa48af70d, 0xdf027972),
+ TOBN(0x691f0f04, 0x5e9a609d), TOBN(0xa9dd82cd, 0xee61270e),
+ TOBN(0x8903ca63, 0xa0ef18d3), TOBN(0x9fb7ee35, 0x3d6ca3bd),
+ TOBN(0xa7b4a09c, 0xabf47d03), TOBN(0x4cdada01, 0x1c67de8e),
+ TOBN(0x52003749, 0x9355a244), TOBN(0xe77fd2b6, 0x4f2151a9),
+ TOBN(0x695d6cf6, 0x66b4efcb), TOBN(0xc5a0cacf, 0xda2cfe25),
+ TOBN(0x104efe5c, 0xef811865), TOBN(0xf52813e8, 0x9ea5cc3d),
+ TOBN(0x855683dc, 0x40b58dbc), TOBN(0x0338ecde, 0x175fcb11),
+ TOBN(0xf9a05637, 0x74921592), TOBN(0xb4f1261d, 0xb9bb9d31),
+ TOBN(0x551429b7, 0x4e9c5459), TOBN(0xbe182e6f, 0x6ea71f53),
+ TOBN(0xd3a3b07c, 0xdfc50573), TOBN(0x9ba1afda, 0x62be8d44),
+ TOBN(0x9bcfd2cb, 0x52ab65d3), TOBN(0xdf11d547, 0xa9571802),
+ TOBN(0x099403ee, 0x02a2404a), TOBN(0x497406f4, 0x21088a71),
+ TOBN(0x99479409, 0x5004ae71), TOBN(0xbdb42078, 0xa812c362),
+ TOBN(0x2b72a30f, 0xd8828442), TOBN(0x283add27, 0xfcb5ed1c),
+ TOBN(0xf7c0e200, 0x66a40015), TOBN(0x3e3be641, 0x08b295ef),
+ TOBN(0xac127dc1, 0xe038a675), TOBN(0x729deff3, 0x8c5c6320),
+ TOBN(0xb7df8fd4, 0xa90d2c53), TOBN(0x9b74b0ec, 0x681e7cd3),
+ TOBN(0x5cb5a623, 0xdab407e5), TOBN(0xcdbd3615, 0x76b340c6),
+ TOBN(0xa184415a, 0x7d28392c), TOBN(0xc184c1d8, 0xe96f7830),
+ TOBN(0xc3204f19, 0x81d3a80f), TOBN(0xfde0c841, 0xc8e02432),
+ TOBN(0x78203b3e, 0x8149e0c1), TOBN(0x5904bdbb, 0x08053a73),
+ TOBN(0x30fc1dd1, 0x101b6805), TOBN(0x43c223bc, 0x49aa6d49),
+ TOBN(0x9ed67141, 0x7a174087), TOBN(0x311469a0, 0xd5997008),
+ TOBN(0xb189b684, 0x5e43fc61), TOBN(0xf3282375, 0xe0d3ab57),
+ TOBN(0x4fa34b67, 0xb1181da8), TOBN(0x621ed0b2, 0x99ee52b8),
+ TOBN(0x9b178de1, 0xad990676), TOBN(0xd51de67b, 0x56d54065),
+ TOBN(0x2a2c27c4, 0x7538c201), TOBN(0x33856ec8, 0x38a40f5c),
+ TOBN(0x2522fc15, 0xbe6cdcde), TOBN(0x1e603f33, 0x9f0c6f89),
+ TOBN(0x7994edc3, 0x103e30a6), TOBN(0x033a00db, 0x220c853e),
+ TOBN(0xd3cfa409, 0xf7bb7fd7), TOBN(0x70f8781e, 0x462d18f6),
+ TOBN(0xbbd82980, 0x687fe295), TOBN(0x6eef4c32, 0x595669f3),
+ TOBN(0x86a9303b, 0x2f7e85c3), TOBN(0x5fce4621, 0x71988f9b),
+ TOBN(0x5b935bf6, 0xc138acb5), TOBN(0x30ea7d67, 0x25661212),
+ TOBN(0xef1eb5f4, 0xe51ab9a2), TOBN(0x0587c98a, 0xae067c78),
+ TOBN(0xb3ce1b3c, 0x77ca9ca6), TOBN(0x2a553d4d, 0x54b5f057),
+ TOBN(0xc7898236, 0x4da29ec2), TOBN(0xdbdd5d13, 0xb9c57316),
+ TOBN(0xc57d6e6b, 0x2cd80d47), TOBN(0x80b460cf, 0xfe9e7391),
+ TOBN(0x98648cab, 0xf963c31e), TOBN(0x67f9f633, 0xcc4d32fd),
+ TOBN(0x0af42a9d, 0xfdf7c687), TOBN(0x55f292a3, 0x0b015ea7),
+ TOBN(0x89e468b2, 0xcd21ab3d), TOBN(0xe504f022, 0xc393d392),
+ TOBN(0xab21e1d4, 0xa5013af9), TOBN(0xe3283f78, 0xc2c28acb),
+ TOBN(0xf38b35f6, 0x226bf99f), TOBN(0xe8354274, 0x0e291e69),
+ TOBN(0x61673a15, 0xb20c162d), TOBN(0xc101dc75, 0xb04fbdbe),
+ TOBN(0x8323b4c2, 0x255bd617), TOBN(0x6c969693, 0x6c2a9154),
+ TOBN(0xc6e65860, 0x62679387), TOBN(0x8e01db0c, 0xb8c88e23),
+ TOBN(0x33c42873, 0x893a5559), TOBN(0x7630f04b, 0x47a3e149),
+ TOBN(0xb5d80805, 0xddcf35f8), TOBN(0x582ca080, 0x77dfe732),
+ TOBN(0x2c7156e1, 0x0b1894a0), TOBN(0x92034001, 0xd81c68c0),
+ TOBN(0xed225d00, 0xc8b115b5), TOBN(0x237f9c22, 0x83b907f2),
+ TOBN(0x0ea2f32f, 0x4470e2c0), TOBN(0xb725f7c1, 0x58be4e95),
+ TOBN(0x0f1dcafa, 0xb1ae5463), TOBN(0x59ed5187, 0x1ba2fc04),
+ TOBN(0xf6e0f316, 0xd0115d4d), TOBN(0x5180b12f, 0xd3691599),
+ TOBN(0x157e32c9, 0x527f0a41), TOBN(0x7b0b081d, 0xa8e0ecc0),
+ TOBN(0x6dbaaa8a, 0xbf4f0dd0), TOBN(0x99b289c7, 0x4d252696),
+ TOBN(0x79b7755e, 0xdbf864fe), TOBN(0x6974e2b1, 0x76cad3ab),
+ TOBN(0x35dbbee2, 0x06ddd657), TOBN(0xe7cbdd11, 0x2ff3a96d),
+ TOBN(0x88381968, 0x076be758), TOBN(0x2d737e72, 0x08c91f5d),
+ TOBN(0x5f83ab62, 0x86ec3776), TOBN(0x98aa649d, 0x945fa7a1),
+ TOBN(0xf477ec37, 0x72ef0933), TOBN(0x66f52b1e, 0x098c17b1),
+ TOBN(0x9eec58fb, 0xd803738b), TOBN(0x91aaade7, 0xe4e86aa4),
+ TOBN(0x6b1ae617, 0xa5b51492), TOBN(0x63272121, 0xbbc45974),
+ TOBN(0x7e0e28f0, 0x862c5129), TOBN(0x0a8f79a9, 0x3321a4a0),
+ TOBN(0xe26d1664, 0x5041c88f), TOBN(0x0571b805, 0x53233e3a),
+ TOBN(0xd1b0ccde, 0xc9520711), TOBN(0x55a9e4ed, 0x3c8b84bf),
+ TOBN(0x9426bd39, 0xa1fef314), TOBN(0x4f5f638e, 0x6eb93f2b),
+ TOBN(0xba2a1ed3, 0x2bf9341b), TOBN(0xd63c1321, 0x4d42d5a9),
+ TOBN(0xd2964a89, 0x316dc7c5), TOBN(0xd1759606, 0xca511851),
+ TOBN(0xd8a9201f, 0xf9e6ed35), TOBN(0xb7b5ee45, 0x6736925a),
+ TOBN(0x0a83fbbc, 0x99581af7), TOBN(0x3076bc40, 0x64eeb051),
+ TOBN(0x5511c98c, 0x02dec312), TOBN(0x270de898, 0x238dcb78),
+ TOBN(0x2cf4cf9c, 0x539c08c9), TOBN(0xa70cb65e, 0x38d3b06e),
+ TOBN(0xb12ec10e, 0xcfe57bbd), TOBN(0x82c7b656, 0x35a0c2b5),
+ TOBN(0xddc7d5cd, 0x161c67bd), TOBN(0xe32e8985, 0xae3a32cc),
+ TOBN(0x7aba9444, 0xd11a5529), TOBN(0xe964ed02, 0x2427fa1a),
+ TOBN(0x1528392d, 0x24a1770a), TOBN(0xa152ce2c, 0x12c72fcd),
+ TOBN(0x714553a4, 0x8ec07649), TOBN(0x18b4c290, 0x459dd453),
+ TOBN(0xea32b714, 0x7b64b110), TOBN(0xb871bfa5, 0x2e6f07a2),
+ TOBN(0xb67112e5, 0x9e2e3c9b), TOBN(0xfbf250e5, 0x44aa90f6),
+ TOBN(0xf77aedb8, 0xbd539006), TOBN(0x3b0cdf9a, 0xd172a66f),
+ TOBN(0xedf69fea, 0xf8c51187), TOBN(0x05bb67ec, 0x741e4da7),
+ TOBN(0x47df0f32, 0x08114345), TOBN(0x56facb07, 0xbb9792b1),
+ TOBN(0xf3e007e9, 0x8f6229e4), TOBN(0x62d103f4, 0x526fba0f),
+ TOBN(0x4f33bef7, 0xb0339d79), TOBN(0x9841357b, 0xb59bfec1),
+ TOBN(0xfa8dbb59, 0xc34e6705), TOBN(0xc3c7180b, 0x7fdaa84c),
+ TOBN(0xf95872fc, 0xa4108537), TOBN(0x8750cc3b, 0x932a3e5a),
+ TOBN(0xb61cc69d, 0xb7275d7d), TOBN(0xffa0168b, 0x2e59b2e9),
+ TOBN(0xca032abc, 0x6ecbb493), TOBN(0x1d86dbd3, 0x2c9082d8),
+ TOBN(0xae1e0b67, 0xe28ef5ba), TOBN(0x2c9a4699, 0xcb18e169),
+ TOBN(0x0ecd0e33, 0x1e6bbd20), TOBN(0x571b360e, 0xaf5e81d2),
+ TOBN(0xcd9fea58, 0x101c1d45), TOBN(0x6651788e, 0x18880452),
+ TOBN(0xa9972635, 0x1f8dd446), TOBN(0x44bed022, 0xe37281d0),
+ TOBN(0x094b2b2d, 0x33da525d), TOBN(0xf193678e, 0x13144fd8),
+ TOBN(0xb8ab5ba4, 0xf4c1061d), TOBN(0x4343b5fa, 0xdccbe0f4),
+ TOBN(0xa8702371, 0x63812713), TOBN(0x47bf6d2d, 0xf7611d93),
+ TOBN(0x46729b8c, 0xbd21e1d7), TOBN(0x7484d4e0, 0xd629e77d),
+ TOBN(0x830e6eea, 0x60dbac1f), TOBN(0x23d8c484, 0xda06a2f7),
+ TOBN(0x896714b0, 0x50ca535b), TOBN(0xdc8d3644, 0xebd97a9b),
+ TOBN(0x106ef9fa, 0xb12177b4), TOBN(0xf79bf464, 0x534d5d9c),
+ TOBN(0x2537a349, 0xa6ab360b), TOBN(0xc7c54253, 0xa00c744f),
+ TOBN(0xb3c7a047, 0xe5911a76), TOBN(0x61ffa5c8, 0x647f1ee7),
+ TOBN(0x15aed36f, 0x8f56ab42), TOBN(0x6a0d41b0, 0xa3ff9ac9),
+ TOBN(0x68f469f5, 0xcc30d357), TOBN(0xbe9adf81, 0x6b72be96),
+ TOBN(0x1cd926fe, 0x903ad461), TOBN(0x7e89e38f, 0xcaca441b),
+ TOBN(0xf0f82de5, 0xfacf69d4), TOBN(0x363b7e76, 0x4775344c),
+ TOBN(0x6894f312, 0xb2e36d04), TOBN(0x3c6cb4fe, 0x11d1c9a5),
+ TOBN(0x85d9c339, 0x4008e1f2), TOBN(0x5e9a85ea, 0x249f326c),
+ TOBN(0xdc35c60a, 0x678c5e06), TOBN(0xc08b944f, 0x9f86fba9),
+ TOBN(0xde40c02c, 0x89f71f0f), TOBN(0xad8f3e31, 0xff3da3c0),
+ TOBN(0x3ea5096b, 0x42125ded), TOBN(0x13879cbf, 0xa7379183),
+ TOBN(0x6f4714a5, 0x6b306a0b), TOBN(0x359c2ea6, 0x67646c5e),
+ TOBN(0xfacf8943, 0x07726368), TOBN(0x07a58935, 0x65ff431e),
+ TOBN(0x24d661d1, 0x68754ab0), TOBN(0x801fce1d, 0x6f429a76),
+ TOBN(0xc068a85f, 0xa58ce769), TOBN(0xedc35c54, 0x5d5eca2b),
+ TOBN(0xea31276f, 0xa3f660d1), TOBN(0xa0184ebe, 0xb8fc7167),
+ TOBN(0x0f20f21a, 0x1d8db0ae), TOBN(0xd96d095f, 0x56c35e12),
+ TOBN(0xedf402b5, 0xf8c2a25b), TOBN(0x1bb772b9, 0x059204b6),
+ TOBN(0x50cbeae2, 0x19b4e34c), TOBN(0x93109d80, 0x3fa0845a),
+ TOBN(0x54f7ccf7, 0x8ef59fb5), TOBN(0x3b438fe2, 0x88070963),
+ TOBN(0x9e28c659, 0x31f3ba9b), TOBN(0x9cc31b46, 0xead9da92),
+ TOBN(0x3c2f0ba9, 0xb733aa5f), TOBN(0xdece47cb, 0xf05af235),
+ TOBN(0xf8e3f715, 0xa2ac82a5), TOBN(0xc97ba641, 0x2203f18a),
+ TOBN(0xc3af5504, 0x09c11060), TOBN(0x56ea2c05, 0x46af512d),
+ TOBN(0xfac28daf, 0xf3f28146), TOBN(0x87fab43a, 0x959ef494),
+ },
+ {
+ TOBN(0x09891641, 0xd4c5105f), TOBN(0x1ae80f8e, 0x6d7fbd65),
+ TOBN(0x9d67225f, 0xbee6bdb0), TOBN(0x3b433b59, 0x7fc4d860),
+ TOBN(0x44e66db6, 0x93e85638), TOBN(0xf7b59252, 0xe3e9862f),
+ TOBN(0xdb785157, 0x665c32ec), TOBN(0x702fefd7, 0xae362f50),
+ TOBN(0x3754475d, 0x0fefb0c3), TOBN(0xd48fb56b, 0x46d7c35d),
+ TOBN(0xa070b633, 0x363798a4), TOBN(0xae89f3d2, 0x8fdb98e6),
+ TOBN(0x970b89c8, 0x6363d14c), TOBN(0x89817521, 0x67abd27d),
+ TOBN(0x9bf7d474, 0x44d5a021), TOBN(0xb3083baf, 0xcac72aee),
+ TOBN(0x389741de, 0xbe949a44), TOBN(0x638e9388, 0x546a4fa5),
+ TOBN(0x3fe6419c, 0xa0047bdc), TOBN(0x7047f648, 0xaaea57ca),
+ TOBN(0x54e48a90, 0x41fbab17), TOBN(0xda8e0b28, 0x576bdba2),
+ TOBN(0xe807eebc, 0xc72afddc), TOBN(0x07d3336d, 0xf42577bf),
+ TOBN(0x62a8c244, 0xbfe20925), TOBN(0x91c19ac3, 0x8fdce867),
+ TOBN(0x5a96a5d5, 0xdd387063), TOBN(0x61d587d4, 0x21d324f6),
+ TOBN(0xe87673a2, 0xa37173ea), TOBN(0x23848008, 0x53778b65),
+ TOBN(0x10f8441e, 0x05bab43e), TOBN(0xfa11fe12, 0x4621efbe),
+ TOBN(0x047b772e, 0x81685d7b), TOBN(0x23f27d81, 0xbf34a976),
+ TOBN(0xc27608e2, 0x915f48ef), TOBN(0x3b0b43fa, 0xa521d5c3),
+ TOBN(0x7613fb26, 0x63ca7284), TOBN(0x7f5729b4, 0x1d4db837),
+ TOBN(0x87b14898, 0x583b526b), TOBN(0x00b732a6, 0xbbadd3d1),
+ TOBN(0x8e02f426, 0x2048e396), TOBN(0x436b50b6, 0x383d9de4),
+ TOBN(0xf78d3481, 0x471e85ad), TOBN(0x8b01ea6a, 0xd005c8d6),
+ TOBN(0xd3c7afee, 0x97015c07), TOBN(0x46cdf1a9, 0x4e3ba2ae),
+ TOBN(0x7a42e501, 0x83d3a1d2), TOBN(0xd54b5268, 0xb541dff4),
+ TOBN(0x3f24cf30, 0x4e23e9bc), TOBN(0x4387f816, 0x126e3624),
+ TOBN(0x26a46a03, 0x3b0b6d61), TOBN(0xaf1bc845, 0x8b2d777c),
+ TOBN(0x25c401ba, 0x527de79c), TOBN(0x0e1346d4, 0x4261bbb6),
+ TOBN(0x4b96c44b, 0x287b4bc7), TOBN(0x658493c7, 0x5254562f),
+ TOBN(0x23f949fe, 0xb8a24a20), TOBN(0x17ebfed1, 0xf52ca53f),
+ TOBN(0x9b691bbe, 0xbcfb4853), TOBN(0x5617ff6b, 0x6278a05d),
+ TOBN(0x241b34c5, 0xe3c99ebd), TOBN(0xfc64242e, 0x1784156a),
+ TOBN(0x4206482f, 0x695d67df), TOBN(0xb967ce0e, 0xee27c011),
+ TOBN(0x65db3751, 0x21c80b5d), TOBN(0x2e7a563c, 0xa31ecca0),
+ TOBN(0xe56ffc4e, 0x5238a07e), TOBN(0x3d6c2966, 0x32ced854),
+ TOBN(0xe99d7d1a, 0xaf70b885), TOBN(0xafc3bad9, 0x2d686459),
+ TOBN(0x9c78bf46, 0x0cc8ba5b), TOBN(0x5a439519, 0x18955aa3),
+ TOBN(0xf8b517a8, 0x5fe4e314), TOBN(0xe60234d0, 0xfcb8906f),
+ TOBN(0xffe542ac, 0xf2061b23), TOBN(0x287e191f, 0x6b4cb59c),
+ TOBN(0x21857ddc, 0x09d877d8), TOBN(0x1c23478c, 0x14678941),
+ TOBN(0xbbf0c056, 0xb6e05ea4), TOBN(0x82da4b53, 0xb01594fe),
+ TOBN(0xf7526791, 0xfadb8608), TOBN(0x049e832d, 0x7b74cdf6),
+ TOBN(0xa43581cc, 0xc2b90a34), TOBN(0x73639eb8, 0x9360b10c),
+ TOBN(0x4fba331f, 0xe1e4a71b), TOBN(0x6ffd6b93, 0x8072f919),
+ TOBN(0x6e53271c, 0x65679032), TOBN(0x67206444, 0xf14272ce),
+ TOBN(0xc0f734a3, 0xb2335834), TOBN(0x9526205a, 0x90ef6860),
+ TOBN(0xcb8be717, 0x04e2bb0d), TOBN(0x2418871e, 0x02f383fa),
+ TOBN(0xd7177681, 0x4082c157), TOBN(0xcc914ad0, 0x29c20073),
+ TOBN(0xf186c1eb, 0xe587e728), TOBN(0x6fdb3c22, 0x61bcd5fd),
+ TOBN(0x30d014a6, 0xf2f9f8e9), TOBN(0x963ece23, 0x4fec49d2),
+ TOBN(0x862025c5, 0x9605a8d9), TOBN(0x39874445, 0x19f8929a),
+ TOBN(0x01b6ff65, 0x12bf476a), TOBN(0x598a64d8, 0x09cf7d91),
+ TOBN(0xd7ec7749, 0x93be56ca), TOBN(0x10899785, 0xcbb33615),
+ TOBN(0xb8a092fd, 0x02eee3ad), TOBN(0xa86b3d35, 0x30145270),
+ TOBN(0x323d98c6, 0x8512b675), TOBN(0x4b8bc785, 0x62ebb40f),
+ TOBN(0x7d301f54, 0x413f9cde), TOBN(0xa5e4fb4f, 0x2bab5664),
+ TOBN(0x1d2b252d, 0x1cbfec23), TOBN(0xfcd576bb, 0xe177120d),
+ TOBN(0x04427d3e, 0x83731a34), TOBN(0x2bb9028e, 0xed836e8e),
+ TOBN(0xb36acff8, 0xb612ca7c), TOBN(0xb88fe5ef, 0xd3d9c73a),
+ TOBN(0xbe2a6bc6, 0xedea4eb3), TOBN(0x43b93133, 0x488eec77),
+ TOBN(0xf41ff566, 0xb17106e1), TOBN(0x469e9172, 0x654efa32),
+ TOBN(0xb4480f04, 0x41c23fa3), TOBN(0xb4712eb0, 0xc1989a2e),
+ TOBN(0x3ccbba0f, 0x93a29ca7), TOBN(0x6e205c14, 0xd619428c),
+ TOBN(0x90db7957, 0xb3641686), TOBN(0x0432691d, 0x45ac8b4e),
+ TOBN(0x07a759ac, 0xf64e0350), TOBN(0x0514d89c, 0x9c972517),
+ TOBN(0x1701147f, 0xa8e67fc3), TOBN(0x9e2e0b8b, 0xab2085be),
+ TOBN(0xd5651824, 0xac284e57), TOBN(0x890d4325, 0x74893664),
+ TOBN(0x8a7c5e6e, 0xc55e68a3), TOBN(0xbf12e90b, 0x4339c85a),
+ TOBN(0x31846b85, 0xf922b655), TOBN(0x9a54ce4d, 0x0bf4d700),
+ TOBN(0xd7f4e83a, 0xf1a14295), TOBN(0x916f955c, 0xb285d4f9),
+ TOBN(0xe57bb0e0, 0x99ffdaba), TOBN(0x28a43034, 0xeab0d152),
+ TOBN(0x0a36ffa2, 0xb8a9cef8), TOBN(0x5517407e, 0xb9ec051a),
+ TOBN(0x9c796096, 0xea68e672), TOBN(0x853db5fb, 0xfb3c77fb),
+ TOBN(0x21474ba9, 0xe864a51a), TOBN(0x6c267699, 0x6e8a1b8b),
+ TOBN(0x7c823626, 0x94120a28), TOBN(0xe61e9a48, 0x8383a5db),
+ TOBN(0x7dd75003, 0x9f84216d), TOBN(0xab020d07, 0xad43cd85),
+ TOBN(0x9437ae48, 0xda12c659), TOBN(0x6449c2eb, 0xe65452ad),
+ TOBN(0xcc7c4c1c, 0x2cf9d7c1), TOBN(0x1320886a, 0xee95e5ab),
+ TOBN(0xbb7b9056, 0xbeae170c), TOBN(0xc8a5b250, 0xdbc0d662),
+ TOBN(0x4ed81432, 0xc11d2303), TOBN(0x7da66912, 0x1f03769f),
+ TOBN(0x3ac7a5fd, 0x84539828), TOBN(0x14dada94, 0x3bccdd02),
+ TOBN(0x8b84c321, 0x7ef6b0d1), TOBN(0x52a9477a, 0x7c933f22),
+ TOBN(0x5ef6728a, 0xfd440b82), TOBN(0x5c3bd859, 0x6ce4bd5e),
+ TOBN(0x918b80f5, 0xf22c2d3e), TOBN(0x368d5040, 0xb7bb6cc5),
+ TOBN(0xb66142a1, 0x2695a11c), TOBN(0x60ac583a, 0xeb19ea70),
+ TOBN(0x317cbb98, 0x0eab2437), TOBN(0x8cc08c55, 0x5e2654c8),
+ TOBN(0xfe2d6520, 0xe6d8307f), TOBN(0xe9f147f3, 0x57428993),
+ TOBN(0x5f9c7d14, 0xd2fd6cf1), TOBN(0xa3ecd064, 0x2d4fcbb0),
+ TOBN(0xad83fef0, 0x8e7341f7), TOBN(0x643f23a0, 0x3a63115c),
+ TOBN(0xd38a78ab, 0xe65ab743), TOBN(0xbf7c75b1, 0x35edc89c),
+ TOBN(0x3dd8752e, 0x530df568), TOBN(0xf85c4a76, 0xe308c682),
+ TOBN(0x4c9955b2, 0xe68acf37), TOBN(0xa544df3d, 0xab32af85),
+ TOBN(0x4b8ec3f5, 0xa25cf493), TOBN(0x4d8f2764, 0x1a622feb),
+ TOBN(0x7bb4f7aa, 0xf0dcbc49), TOBN(0x7de551f9, 0x70bbb45b),
+ TOBN(0xcfd0f3e4, 0x9f2ca2e5), TOBN(0xece58709, 0x1f5c76ef),
+ TOBN(0x32920edd, 0x167d79ae), TOBN(0x039df8a2, 0xfa7d7ec1),
+ TOBN(0xf46206c0, 0xbb30af91), TOBN(0x1ff5e2f5, 0x22676b59),
+ TOBN(0x11f4a039, 0x6ea51d66), TOBN(0x506c1445, 0x807d7a26),
+ TOBN(0x60da5705, 0x755a9b24), TOBN(0x8fc8cc32, 0x1f1a319e),
+ TOBN(0x83642d4d, 0x9433d67d), TOBN(0x7fa5cb8f, 0x6a7dd296),
+ TOBN(0x576591db, 0x9b7bde07), TOBN(0x13173d25, 0x419716fb),
+ TOBN(0xea30599d, 0xd5b340ff), TOBN(0xfc6b5297, 0xb0fe76c5),
+ TOBN(0x1c6968c8, 0xab8f5adc), TOBN(0xf723c7f5, 0x901c928d),
+ TOBN(0x4203c321, 0x9773d402), TOBN(0xdf7c6aa3, 0x1b51dd47),
+ TOBN(0x3d49e37a, 0x552be23c), TOBN(0x57febee8, 0x0b5a6e87),
+ TOBN(0xc5ecbee4, 0x7bd8e739), TOBN(0x79d44994, 0xae63bf75),
+ TOBN(0x168bd00f, 0x38fb8923), TOBN(0x75d48ee4, 0xd0533130),
+ TOBN(0x554f77aa, 0xdb5cdf33), TOBN(0x3396e896, 0x3c696769),
+ TOBN(0x2fdddbf2, 0xd3fd674e), TOBN(0xbbb8f6ee, 0x99d0e3e5),
+ TOBN(0x51b90651, 0xcbae2f70), TOBN(0xefc4bc05, 0x93aaa8eb),
+ TOBN(0x8ecd8689, 0xdd1df499), TOBN(0x1aee99a8, 0x22f367a5),
+ TOBN(0x95d485b9, 0xae8274c5), TOBN(0x6c14d445, 0x7d30b39c),
+ TOBN(0xbafea90b, 0xbcc1ef81), TOBN(0x7c5f317a, 0xa459a2ed),
+ TOBN(0x01211075, 0x4ef44227), TOBN(0xa17bed6e, 0xdc20f496),
+ TOBN(0x0cdfe424, 0x819853cd), TOBN(0x13793298, 0xf71e2ce7),
+ TOBN(0x3c1f3078, 0xdbbe307b), TOBN(0x6dd1c20e, 0x76ee9936),
+ TOBN(0x23ee4b57, 0x423caa20), TOBN(0x4ac3793b, 0x8efb840e),
+ TOBN(0x934438eb, 0xed1f8ca0), TOBN(0x3e546658, 0x4ebb25a2),
+ TOBN(0xc415af0e, 0xc069896f), TOBN(0xc13eddb0, 0x9a5aa43d),
+ TOBN(0x7a04204f, 0xd49eb8f6), TOBN(0xd0d5bdfc, 0xd74f1670),
+ TOBN(0x3697e286, 0x56fc0558), TOBN(0x10207371, 0x01cebade),
+ TOBN(0x5f87e690, 0x0647a82b), TOBN(0x908e0ed4, 0x8f40054f),
+ TOBN(0xa9f633d4, 0x79853803), TOBN(0x8ed13c9a, 0x4a28b252),
+ TOBN(0x3e2ef676, 0x1f460f64), TOBN(0x53930b9b, 0x36d06336),
+ TOBN(0x347073ac, 0x8fc4979b), TOBN(0x84380e0e, 0x5ecd5597),
+ TOBN(0xe3b22c6b, 0xc4fe3c39), TOBN(0xba4a8153, 0x6c7bebdf),
+ TOBN(0xf23ab6b7, 0x25693459), TOBN(0x53bc3770, 0x14922b11),
+ TOBN(0x4645c8ab, 0x5afc60db), TOBN(0xaa022355, 0x20b9f2a3),
+ TOBN(0x52a2954c, 0xce0fc507), TOBN(0x8c2731bb, 0x7ce1c2e7),
+ TOBN(0xf39608ab, 0x18a0339d), TOBN(0xac7a658d, 0x3735436c),
+ TOBN(0xb22c2b07, 0xcd992b4f), TOBN(0x4e83daec, 0xf40dcfd4),
+ TOBN(0x8a34c7be, 0x2f39ea3e), TOBN(0xef0c005f, 0xb0a56d2e),
+ TOBN(0x62731f6a, 0x6edd8038), TOBN(0x5721d740, 0x4e3cb075),
+ TOBN(0x1ea41511, 0xfbeeee1b), TOBN(0xd1ef5e73, 0xef1d0c05),
+ TOBN(0x42feefd1, 0x73c07d35), TOBN(0xe530a00a, 0x8a329493),
+ TOBN(0x5d55b7fe, 0xf15ebfb0), TOBN(0x549de03c, 0xd322491a),
+ TOBN(0xf7b5f602, 0x745b3237), TOBN(0x3632a3a2, 0x1ab6e2b6),
+ TOBN(0x0d3bba89, 0x0ef59f78), TOBN(0x0dfc6443, 0xc9e52b9a),
+ TOBN(0x1dc79699, 0x72631447), TOBN(0xef033917, 0xb3be20b1),
+ TOBN(0x0c92735d, 0xb1383948), TOBN(0xc1fc29a2, 0xc0dd7d7d),
+ TOBN(0x6485b697, 0x403ed068), TOBN(0x13bfaab3, 0xaac93bdc),
+ TOBN(0x410dc6a9, 0x0deeaf52), TOBN(0xb003fb02, 0x4c641c15),
+ TOBN(0x1384978c, 0x5bc504c4), TOBN(0x37640487, 0x864a6a77),
+ TOBN(0x05991bc6, 0x222a77da), TOBN(0x62260a57, 0x5e47eb11),
+ TOBN(0xc7af6613, 0xf21b432c), TOBN(0x22f3acc9, 0xab4953e9),
+ TOBN(0x52934922, 0x8e41d155), TOBN(0x4d024568, 0x3ac059ef),
+ TOBN(0xb0201755, 0x4d884411), TOBN(0xce8055cf, 0xa59a178f),
+ TOBN(0xcd77d1af, 0xf6204549), TOBN(0xa0a00a3e, 0xc7066759),
+ TOBN(0x471071ef, 0x0272c229), TOBN(0x009bcf6b, 0xd3c4b6b0),
+ TOBN(0x2a2638a8, 0x22305177), TOBN(0xd51d59df, 0x41645bbf),
+ TOBN(0xa81142fd, 0xc0a7a3c0), TOBN(0xa17eca6d, 0x4c7063ee),
+ TOBN(0x0bb887ed, 0x60d9dcec), TOBN(0xd6d28e51, 0x20ad2455),
+ TOBN(0xebed6308, 0xa67102ba), TOBN(0x042c3114, 0x8bffa408),
+ TOBN(0xfd099ac5, 0x8aa68e30), TOBN(0x7a6a3d7c, 0x1483513e),
+ TOBN(0xffcc6b75, 0xba2d8f0c), TOBN(0x54dacf96, 0x1e78b954),
+ TOBN(0xf645696f, 0xa4a9af89), TOBN(0x3a411940, 0x06ac98ec),
+ TOBN(0x41b8b3f6, 0x22a67a20), TOBN(0x2d0b1e0f, 0x99dec626),
+ TOBN(0x27c89192, 0x40be34e8), TOBN(0xc7162b37, 0x91907f35),
+ TOBN(0x90188ec1, 0xa956702b), TOBN(0xca132f7d, 0xdf93769c),
+ TOBN(0x3ece44f9, 0x0e2025b4), TOBN(0x67aaec69, 0x0c62f14c),
+ TOBN(0xad741418, 0x22e3cc11), TOBN(0xcf9b75c3, 0x7ff9a50e),
+ TOBN(0x02fa2b16, 0x4d348272), TOBN(0xbd99d61a, 0x9959d56d),
+ TOBN(0xbc4f19db, 0x18762916), TOBN(0xcc7cce50, 0x49c1ac80),
+ TOBN(0x4d59ebaa, 0xd846bd83), TOBN(0x8775a9dc, 0xa9202849),
+ TOBN(0x07ec4ae1, 0x6e1f4ca9), TOBN(0x27eb5875, 0xba893f11),
+ TOBN(0x00284d51, 0x662cc565), TOBN(0x82353a6b, 0x0db4138d),
+ TOBN(0xd9c7aaaa, 0xaa32a594), TOBN(0xf5528b5e, 0xa5669c47),
+ TOBN(0xf3220231, 0x2f23c5ff), TOBN(0xe3e8147a, 0x6affa3a1),
+ TOBN(0xfb423d5c, 0x202ddda0), TOBN(0x3d6414ac, 0x6b871bd4),
+ TOBN(0x586f82e1, 0xa51a168a), TOBN(0xb712c671, 0x48ae5448),
+ TOBN(0x9a2e4bd1, 0x76233eb8), TOBN(0x0188223a, 0x78811ca9),
+ TOBN(0x553c5e21, 0xf7c18de1), TOBN(0x7682e451, 0xb27bb286),
+ TOBN(0x3ed036b3, 0x0e51e929), TOBN(0xf487211b, 0xec9cb34f),
+ TOBN(0x0d094277, 0x0c24efc8), TOBN(0x0349fd04, 0xbef737a4),
+ TOBN(0x6d1c9dd2, 0x514cdd28), TOBN(0x29c135ff, 0x30da9521),
+ TOBN(0xea6e4508, 0xf78b0b6f), TOBN(0x176f5dd2, 0x678c143c),
+ TOBN(0x08148418, 0x4be21e65), TOBN(0x27f7525c, 0xe7df38c4),
+ TOBN(0x1fb70e09, 0x748ab1a4), TOBN(0x9cba50a0, 0x5efe4433),
+ TOBN(0x7846c7a6, 0x15f75af2), TOBN(0x2a7c2c57, 0x5ee73ea8),
+ TOBN(0x42e566a4, 0x3f0a449a), TOBN(0x45474c3b, 0xad90fc3d),
+ TOBN(0x7447be3d, 0x8b61d057), TOBN(0x3e9d1cf1, 0x3a4ec092),
+ TOBN(0x1603e453, 0xf380a6e6), TOBN(0x0b86e431, 0x9b1437c2),
+ TOBN(0x7a4173f2, 0xef29610a), TOBN(0x8fa729a7, 0xf03d57f7),
+ TOBN(0x3e186f6e, 0x6c9c217e), TOBN(0xbe1d3079, 0x91919524),
+ TOBN(0x92a62a70, 0x153d4fb1), TOBN(0x32ed3e34, 0xd68c2f71),
+ TOBN(0xd785027f, 0x9eb1a8b7), TOBN(0xbc37eb77, 0xc5b22fe8),
+ TOBN(0x466b34f0, 0xb9d6a191), TOBN(0x008a89af, 0x9a05f816),
+ TOBN(0x19b028fb, 0x7d42c10a), TOBN(0x7fe8c92f, 0x49b3f6b8),
+ TOBN(0x58907cc0, 0xa5a0ade3), TOBN(0xb3154f51, 0x559d1a7c),
+ TOBN(0x5066efb6, 0xd9790ed6), TOBN(0xa77a0cbc, 0xa6aa793b),
+ TOBN(0x1a915f3c, 0x223e042e), TOBN(0x1c5def04, 0x69c5874b),
+ TOBN(0x0e830078, 0x73b6c1da), TOBN(0x55cf85d2, 0xfcd8557a),
+ TOBN(0x0f7c7c76, 0x0460f3b1), TOBN(0x87052acb, 0x46e58063),
+ TOBN(0x09212b80, 0x907eae66), TOBN(0x3cb068e0, 0x4d721c89),
+ TOBN(0xa87941ae, 0xdd45ac1c), TOBN(0xde8d5c0d, 0x0daa0dbb),
+ TOBN(0xda421fdc, 0xe3502e6e), TOBN(0xc8944201, 0x4d89a084),
+ TOBN(0x7307ba5e, 0xf0c24bfb), TOBN(0xda212beb, 0x20bde0ef),
+ TOBN(0xea2da24b, 0xf82ce682), TOBN(0x058d3816, 0x07f71fe4),
+ TOBN(0x35a02462, 0x5ffad8de), TOBN(0xcd7b05dc, 0xaadcefab),
+ TOBN(0xd442f8ed, 0x1d9f54ec), TOBN(0x8be3d618, 0xb2d3b5ca),
+ TOBN(0xe2220ed0, 0xe06b2ce2), TOBN(0x82699a5f, 0x1b0da4c0),
+ TOBN(0x3ff106f5, 0x71c0c3a7), TOBN(0x8f580f5a, 0x0d34180c),
+ TOBN(0x4ebb120e, 0x22d7d375), TOBN(0x5e5782cc, 0xe9513675),
+ TOBN(0x2275580c, 0x99c82a70), TOBN(0xe8359fbf, 0x15ea8c4c),
+ TOBN(0x53b48db8, 0x7b415e70), TOBN(0xaacf2240, 0x100c6014),
+ TOBN(0x9faaccf5, 0xe4652f1d), TOBN(0xbd6fdd2a, 0xd56157b2),
+ TOBN(0xa4f4fb1f, 0x6261ec50), TOBN(0x244e55ad, 0x476bcd52),
+ TOBN(0x881c9305, 0x047d320b), TOBN(0x1ca983d5, 0x6181263f),
+ TOBN(0x354e9a44, 0x278fb8ee), TOBN(0xad2dbc0f, 0x396e4964),
+ TOBN(0x723f3aa2, 0x9268b3de), TOBN(0x0d1ca29a, 0xe6e0609a),
+ TOBN(0x794866aa, 0x6cf44252), TOBN(0x0b59f3e3, 0x01af87ed),
+ TOBN(0xe234e5ff, 0x7f4a6c51), TOBN(0xa8768fd2, 0x61dc2f7e),
+ TOBN(0xdafc7332, 0x0a94d81f), TOBN(0xd7f84282, 0x06938ce1),
+ TOBN(0xae0b3c0e, 0x0546063e), TOBN(0x7fbadcb2, 0x5d61abc6),
+ TOBN(0xd5d7a2c9, 0x369ac400), TOBN(0xa5978d09, 0xae67d10c),
+ TOBN(0x290f211e, 0x4f85eaac), TOBN(0xe61e2ad1, 0xfacac681),
+ TOBN(0xae125225, 0x388384cd), TOBN(0xa7fb68e9, 0xccfde30f),
+ TOBN(0x7a59b936, 0x3daed4c2), TOBN(0x80a9aa40, 0x2606f789),
+ TOBN(0xb40c1ea5, 0xf6a6d90a), TOBN(0x948364d3, 0x514d5885),
+ TOBN(0x062ebc60, 0x70985182), TOBN(0xa6db5b0e, 0x33310895),
+ TOBN(0x64a12175, 0xe329c2f5), TOBN(0xc5f25bd2, 0x90ea237e),
+ TOBN(0x7915c524, 0x2d0a4c23), TOBN(0xeb5d26e4, 0x6bb3cc52),
+ TOBN(0x369a9116, 0xc09e2c92), TOBN(0x0c527f92, 0xcf182cf8),
+ TOBN(0x9e591938, 0x2aede0ac), TOBN(0xb2922208, 0x6cc34939),
+ TOBN(0x3c9d8962, 0x99a34361), TOBN(0x3c81836d, 0xc1905fe6),
+ TOBN(0x4bfeb57f, 0xa001ec5a), TOBN(0xe993f5bb, 0xa0dc5dba),
+ TOBN(0x47884109, 0x724a1380), TOBN(0x8a0369ab, 0x32fe9a04),
+ TOBN(0xea068d60, 0x8c927db8), TOBN(0xbf5f37cf, 0x94655741),
+ TOBN(0x47d402a2, 0x04b6c7ea), TOBN(0x4551c295, 0x6af259cb),
+ TOBN(0x698b71e7, 0xed77ee8b), TOBN(0xbddf7bd0, 0xf309d5c7),
+ TOBN(0x6201c22c, 0x34e780ca), TOBN(0xab04f7d8, 0x4c295ef4),
+ TOBN(0x1c947294, 0x4313a8ce), TOBN(0xe532e4ac, 0x92ca4cfe),
+ TOBN(0x89738f80, 0xd0a7a97a), TOBN(0xec088c88, 0xa580fd5b),
+ TOBN(0x612b1ecc, 0x42ce9e51), TOBN(0x8f9840fd, 0xb25fdd2a),
+ TOBN(0x3cda78c0, 0x01e7f839), TOBN(0x546b3d3a, 0xece05480),
+ TOBN(0x271719a9, 0x80d30916), TOBN(0x45497107, 0x584c20c4),
+ TOBN(0xaf8f9478, 0x5bc78608), TOBN(0x28c7d484, 0x277e2a4c),
+ TOBN(0xfce01767, 0x88a2ffe4), TOBN(0xdc506a35, 0x28e169a5),
+ TOBN(0x0ea10861, 0x7af9c93a), TOBN(0x1ed24361, 0x03fa0e08),
+ TOBN(0x96eaaa92, 0xa3d694e7), TOBN(0xc0f43b4d, 0xef50bc74),
+ TOBN(0xce6aa58c, 0x64114db4), TOBN(0x8218e8ea, 0x7c000fd4),
+ TOBN(0xac815dfb, 0x185f8844), TOBN(0xcd7e90cb, 0x1557abfb),
+ TOBN(0x23d16655, 0xafbfecdf), TOBN(0x80f3271f, 0x085cac4a),
+ TOBN(0x7fc39aa7, 0xd0e62f47), TOBN(0x88d519d1, 0x460a48e5),
+ TOBN(0x59559ac4, 0xd28f101e), TOBN(0x7981d9e9, 0xca9ae816),
+ TOBN(0x5c38652c, 0x9ac38203), TOBN(0x86eaf87f, 0x57657fe5),
+ TOBN(0x568fc472, 0xe21f5416), TOBN(0x2afff39c, 0xe7e597b5),
+ TOBN(0x3adbbb07, 0x256d4eab), TOBN(0x22598692, 0x8285ab89),
+ TOBN(0x35f8112a, 0x041caefe), TOBN(0x95df02e3, 0xa5064c8b),
+ TOBN(0x4d63356e, 0xc7004bf3), TOBN(0x230a08f4, 0xdb83c7de),
+ TOBN(0xca27b270, 0x8709a7b7), TOBN(0x0d1c4cc4, 0xcb9abd2d),
+ TOBN(0x8a0bc66e, 0x7550fee8), TOBN(0x369cd4c7, 0x9cf7247e),
+ TOBN(0x75562e84, 0x92b5b7e7), TOBN(0x8fed0da0, 0x5802af7b),
+ TOBN(0x6a7091c2, 0xe48fb889), TOBN(0x26882c13, 0x7b8a9d06),
+ TOBN(0xa2498663, 0x1b82a0e2), TOBN(0x844ed736, 0x3518152d),
+ TOBN(0x282f476f, 0xd86e27c7), TOBN(0xa04edaca, 0x04afefdc),
+ TOBN(0x8b256ebc, 0x6119e34d), TOBN(0x56a413e9, 0x0787d78b),
+ },
+ {
+ TOBN(0x82ee061d, 0x5a74be50), TOBN(0xe41781c4, 0xdea16ff5),
+ TOBN(0xe0b0c81e, 0x99bfc8a2), TOBN(0x624f4d69, 0x0b547e2d),
+ TOBN(0x3a83545d, 0xbdcc9ae4), TOBN(0x2573dbb6, 0x409b1e8e),
+ TOBN(0x482960c4, 0xa6c93539), TOBN(0xf01059ad, 0x5ae18798),
+ TOBN(0x715c9f97, 0x3112795f), TOBN(0xe8244437, 0x984e6ee1),
+ TOBN(0x55cb4858, 0xecb66bcd), TOBN(0x7c136735, 0xabaffbee),
+ TOBN(0x54661595, 0x5dbec38e), TOBN(0x51c0782c, 0x388ad153),
+ TOBN(0x9ba4c53a, 0xc6e0952f), TOBN(0x27e6782a, 0x1b21dfa8),
+ TOBN(0x682f903d, 0x4ed2dbc2), TOBN(0x0eba59c8, 0x7c3b2d83),
+ TOBN(0x8e9dc84d, 0x9c7e9335), TOBN(0x5f9b21b0, 0x0eb226d7),
+ TOBN(0xe33bd394, 0xaf267bae), TOBN(0xaa86cc25, 0xbe2e15ae),
+ TOBN(0x4f0bf67d, 0x6a8ec500), TOBN(0x5846aa44, 0xf9630658),
+ TOBN(0xfeb09740, 0xe2c2bf15), TOBN(0x627a2205, 0xa9e99704),
+ TOBN(0xec8d73d0, 0xc2fbc565), TOBN(0x223eed8f, 0xc20c8de8),
+ TOBN(0x1ee32583, 0xa8363b49), TOBN(0x1a0b6cb9, 0xc9c2b0a6),
+ TOBN(0x49f7c3d2, 0x90dbc85c), TOBN(0xa8dfbb97, 0x1ef4c1ac),
+ TOBN(0xafb34d4c, 0x65c7c2ab), TOBN(0x1d4610e7, 0xe2c5ea84),
+ TOBN(0x893f6d1b, 0x973c4ab5), TOBN(0xa3cdd7e9, 0x945ba5c4),
+ TOBN(0x60514983, 0x064417ee), TOBN(0x1459b23c, 0xad6bdf2b),
+ TOBN(0x23b2c341, 0x5cf726c3), TOBN(0x3a829635, 0x32d6354a),
+ TOBN(0x294f901f, 0xab192c18), TOBN(0xec5fcbfe, 0x7030164f),
+ TOBN(0xe2e2fcb7, 0xe2246ba6), TOBN(0x1e7c88b3, 0x221a1a0c),
+ TOBN(0x72c7dd93, 0xc92d88c5), TOBN(0x41c2148e, 0x1106fb59),
+ TOBN(0x547dd4f5, 0xa0f60f14), TOBN(0xed9b52b2, 0x63960f31),
+ TOBN(0x6c8349eb, 0xb0a5b358), TOBN(0xb154c5c2, 0x9e7e2ed6),
+ TOBN(0xcad5eccf, 0xeda462db), TOBN(0xf2d6dbe4, 0x2de66b69),
+ TOBN(0x426aedf3, 0x8665e5b2), TOBN(0x488a8513, 0x7b7f5723),
+ TOBN(0x15cc43b3, 0x8bcbb386), TOBN(0x27ad0af3, 0xd791d879),
+ TOBN(0xc16c236e, 0x846e364f), TOBN(0x7f33527c, 0xdea50ca0),
+ TOBN(0xc4810775, 0x0926b86d), TOBN(0x6c2a3609, 0x0598e70c),
+ TOBN(0xa6755e52, 0xf024e924), TOBN(0xe0fa07a4, 0x9db4afca),
+ TOBN(0x15c3ce7d, 0x66831790), TOBN(0x5b4ef350, 0xa6cbb0d6),
+ TOBN(0x2c4aafc4, 0xb6205969), TOBN(0x42563f02, 0xf6c7854f),
+ TOBN(0x016aced5, 0x1d983b48), TOBN(0xfeb356d8, 0x99949755),
+ TOBN(0x8c2a2c81, 0xd1a39bd7), TOBN(0x8f44340f, 0xe6934ae9),
+ TOBN(0x148cf91c, 0x447904da), TOBN(0x7340185f, 0x0f51a926),
+ TOBN(0x2f8f00fb, 0x7409ab46), TOBN(0x057e78e6, 0x80e289b2),
+ TOBN(0x03e5022c, 0xa888e5d1), TOBN(0x3c87111a, 0x9dede4e2),
+ TOBN(0x5b9b0e1c, 0x7809460b), TOBN(0xe751c852, 0x71c9abc7),
+ TOBN(0x8b944e28, 0xc7cc1dc9), TOBN(0x4f201ffa, 0x1d3cfa08),
+ TOBN(0x02fc905c, 0x3e6721ce), TOBN(0xd52d70da, 0xd0b3674c),
+ TOBN(0x5dc2e5ca, 0x18810da4), TOBN(0xa984b273, 0x5c69dd99),
+ TOBN(0x63b92527, 0x84de5ca4), TOBN(0x2f1c9872, 0xc852dec4),
+ TOBN(0x18b03593, 0xc2e3de09), TOBN(0x19d70b01, 0x9813dc2f),
+ TOBN(0x42806b2d, 0xa6dc1d29), TOBN(0xd3030009, 0xf871e144),
+ TOBN(0xa1feb333, 0xaaf49276), TOBN(0xb5583b9e, 0xc70bc04b),
+ TOBN(0x1db0be78, 0x95695f20), TOBN(0xfc841811, 0x89d012b5),
+ TOBN(0x6409f272, 0x05f61643), TOBN(0x40d34174, 0xd5883128),
+ TOBN(0xd79196f5, 0x67419833), TOBN(0x6059e252, 0x863b7b08),
+ TOBN(0x84da1817, 0x1c56700c), TOBN(0x5758ee56, 0xb28d3ec4),
+ TOBN(0x7da2771d, 0x013b0ea6), TOBN(0xfddf524b, 0x54c5e9b9),
+ TOBN(0x7df4faf8, 0x24305d80), TOBN(0x58f5c1bf, 0x3a97763f),
+ TOBN(0xa5af37f1, 0x7c696042), TOBN(0xd4cba22c, 0x4a2538de),
+ TOBN(0x211cb995, 0x9ea42600), TOBN(0xcd105f41, 0x7b069889),
+ TOBN(0xb1e1cf19, 0xddb81e74), TOBN(0x472f2d89, 0x5157b8ca),
+ TOBN(0x086fb008, 0xee9db885), TOBN(0x365cd570, 0x0f26d131),
+ TOBN(0x284b02bb, 0xa2be7053), TOBN(0xdcbbf7c6, 0x7ab9a6d6),
+ TOBN(0x4425559c, 0x20f7a530), TOBN(0x961f2dfa, 0x188767c8),
+ TOBN(0xe2fd9435, 0x70dc80c4), TOBN(0x104d6b63, 0xf0784120),
+ TOBN(0x7f592bc1, 0x53567122), TOBN(0xf6bc1246, 0xf688ad77),
+ TOBN(0x05214c05, 0x0f15dde9), TOBN(0xa47a76a8, 0x0d5f2b82),
+ TOBN(0xbb254d30, 0x62e82b62), TOBN(0x11a05fe0, 0x3ec955ee),
+ TOBN(0x7eaff46e, 0x9d529b36), TOBN(0x55ab1301, 0x8f9e3df6),
+ TOBN(0xc463e371, 0x99317698), TOBN(0xfd251438, 0xccda47ad),
+ TOBN(0xca9c3547, 0x23d695ea), TOBN(0x48ce626e, 0x16e589b5),
+ TOBN(0x6b5b64c7, 0xb187d086), TOBN(0xd02e1794, 0xb2207948),
+ TOBN(0x8b58e98f, 0x7198111d), TOBN(0x90ca6305, 0xdcf9c3cc),
+ TOBN(0x5691fe72, 0xf34089b0), TOBN(0x60941af1, 0xfc7c80ff),
+ TOBN(0xa09bc0a2, 0x22eb51e5), TOBN(0xc0bb7244, 0xaa9cf09a),
+ TOBN(0x36a8077f, 0x80159f06), TOBN(0x8b5c989e, 0xdddc560e),
+ TOBN(0x19d2f316, 0x512e1f43), TOBN(0x02eac554, 0xad08ff62),
+ TOBN(0x012ab84c, 0x07d20b4e), TOBN(0x37d1e115, 0xd6d4e4e1),
+ TOBN(0xb6443e1a, 0xab7b19a8), TOBN(0xf08d067e, 0xdef8cd45),
+ TOBN(0x63adf3e9, 0x685e03da), TOBN(0xcf15a10e, 0x4792b916),
+ TOBN(0xf44bcce5, 0xb738a425), TOBN(0xebe131d5, 0x9636b2fd),
+ TOBN(0x94068841, 0x7850d605), TOBN(0x09684eaa, 0xb40d749d),
+ TOBN(0x8c3c669c, 0x72ba075b), TOBN(0x89f78b55, 0xba469015),
+ TOBN(0x5706aade, 0x3e9f8ba8), TOBN(0x6d8bd565, 0xb32d7ed7),
+ TOBN(0x25f4e63b, 0x805f08d6), TOBN(0x7f48200d, 0xc3bcc1b5),
+ TOBN(0x4e801968, 0xb025d847), TOBN(0x74afac04, 0x87cbe0a8),
+ TOBN(0x43ed2c2b, 0x7e63d690), TOBN(0xefb6bbf0, 0x0223cdb8),
+ TOBN(0x4fec3cae, 0x2884d3fe), TOBN(0x065ecce6, 0xd75e25a4),
+ TOBN(0x6c2294ce, 0x69f79071), TOBN(0x0d9a8e5f, 0x044b8666),
+ TOBN(0x5009f238, 0x17b69d8f), TOBN(0x3c29f8fe, 0xc5dfdaf7),
+ TOBN(0x9067528f, 0xebae68c4), TOBN(0x5b385632, 0x30c5ba21),
+ TOBN(0x540df119, 0x1fdd1aec), TOBN(0xcf37825b, 0xcfba4c78),
+ TOBN(0x77eff980, 0xbeb11454), TOBN(0x40a1a991, 0x60c1b066),
+ TOBN(0xe8018980, 0xf889a1c7), TOBN(0xb9c52ae9, 0x76c24be0),
+ TOBN(0x05fbbcce, 0x45650ef4), TOBN(0xae000f10, 0x8aa29ac7),
+ TOBN(0x884b7172, 0x4f04c470), TOBN(0x7cd4fde2, 0x19bb5c25),
+ TOBN(0x6477b22a, 0xe8840869), TOBN(0xa8868859, 0x5fbd0686),
+ TOBN(0xf23cc02e, 0x1116dfba), TOBN(0x76cd563f, 0xd87d7776),
+ TOBN(0xe2a37598, 0xa9d82abf), TOBN(0x5f188ccb, 0xe6c170f5),
+ TOBN(0x81682200, 0x5066b087), TOBN(0xda22c212, 0xc7155ada),
+ TOBN(0x151e5d3a, 0xfbddb479), TOBN(0x4b606b84, 0x6d715b99),
+ TOBN(0x4a73b54b, 0xf997cb2e), TOBN(0x9a1bfe43, 0x3ecd8b66),
+ TOBN(0x1c312809, 0x2a67d48a), TOBN(0xcd6a671e, 0x031fa9e2),
+ TOBN(0xbec3312a, 0x0e43a34a), TOBN(0x1d935639, 0x55ef47d3),
+ TOBN(0x5ea02489, 0x8fea73ea), TOBN(0x8247b364, 0xa035afb2),
+ TOBN(0xb58300a6, 0x5265b54c), TOBN(0x3286662f, 0x722c7148),
+ TOBN(0xb77fd76b, 0xb4ec4c20), TOBN(0xf0a12fa7, 0x0f3fe3fd),
+ TOBN(0xf845bbf5, 0x41d8c7e8), TOBN(0xe4d969ca, 0x5ec10aa8),
+ TOBN(0x4c0053b7, 0x43e232a3), TOBN(0xdc7a3fac, 0x37f8a45a),
+ TOBN(0x3c4261c5, 0x20d81c8f), TOBN(0xfd4b3453, 0xb00eab00),
+ TOBN(0x76d48f86, 0xd36e3062), TOBN(0x626c5277, 0xa143ff02),
+ TOBN(0x538174de, 0xaf76f42e), TOBN(0x2267aa86, 0x6407ceac),
+ TOBN(0xfad76351, 0x72e572d5), TOBN(0xab861af7, 0xba7330eb),
+ TOBN(0xa0a1c8c7, 0x418d8657), TOBN(0x988821cb, 0x20289a52),
+ TOBN(0x79732522, 0xcccc18ad), TOBN(0xaadf3f8d, 0xf1a6e027),
+ TOBN(0xf7382c93, 0x17c2354d), TOBN(0x5ce1680c, 0xd818b689),
+ TOBN(0x359ebbfc, 0xd9ecbee9), TOBN(0x4330689c, 0x1cae62ac),
+ TOBN(0xb55ce5b4, 0xc51ac38a), TOBN(0x7921dfea, 0xfe238ee8),
+ TOBN(0x3972bef8, 0x271d1ca5), TOBN(0x3e423bc7, 0xe8aabd18),
+ TOBN(0x57b09f3f, 0x44a3e5e3), TOBN(0x5da886ae, 0x7b444d66),
+ TOBN(0x68206634, 0xa9964375), TOBN(0x356a2fa3, 0x699cd0ff),
+ TOBN(0xaf0faa24, 0xdba515e9), TOBN(0x536e1f5c, 0xb321d79a),
+ TOBN(0xd3b9913a, 0x5c04e4ea), TOBN(0xd549dcfe, 0xd6f11513),
+ TOBN(0xee227bf5, 0x79fd1d94), TOBN(0x9f35afee, 0xb43f2c67),
+ TOBN(0xd2638d24, 0xf1314f53), TOBN(0x62baf948, 0xcabcd822),
+ TOBN(0x5542de29, 0x4ef48db0), TOBN(0xb3eb6a04, 0xfc5f6bb2),
+ TOBN(0x23c110ae, 0x1208e16a), TOBN(0x1a4d15b5, 0xf8363e24),
+ TOBN(0x30716844, 0x164be00b), TOBN(0xa8e24824, 0xf6f4690d),
+ TOBN(0x548773a2, 0x90b170cf), TOBN(0xa1bef331, 0x42f191f4),
+ TOBN(0x70f418d0, 0x9247aa97), TOBN(0xea06028e, 0x48be9147),
+ TOBN(0xe13122f3, 0xdbfb894e), TOBN(0xbe9b79f6, 0xce274b18),
+ TOBN(0x85a49de5, 0xca58aadf), TOBN(0x24957758, 0x11487351),
+ TOBN(0x111def61, 0xbb939099), TOBN(0x1d6a974a, 0x26d13694),
+ TOBN(0x4474b4ce, 0xd3fc253b), TOBN(0x3a1485e6, 0x4c5db15e),
+ TOBN(0xe79667b4, 0x147c15b4), TOBN(0xe34f553b, 0x7bc61301),
+ TOBN(0x032b80f8, 0x17094381), TOBN(0x55d8bafd, 0x723eaa21),
+ TOBN(0x5a987995, 0xf1c0e74e), TOBN(0x5a9b292e, 0xebba289c),
+ TOBN(0x413cd4b2, 0xeb4c8251), TOBN(0x98b5d243, 0xd162db0a),
+ TOBN(0xbb47bf66, 0x68342520), TOBN(0x08d68949, 0xbaa862d1),
+ TOBN(0x11f349c7, 0xe906abcd), TOBN(0x454ce985, 0xed7bf00e),
+ TOBN(0xacab5c9e, 0xb55b803b), TOBN(0xb03468ea, 0x31e3c16d),
+ TOBN(0x5c24213d, 0xd273bf12), TOBN(0x211538eb, 0x71587887),
+ TOBN(0x198e4a2f, 0x731dea2d), TOBN(0xd5856cf2, 0x74ed7b2a),
+ TOBN(0x86a632eb, 0x13a664fe), TOBN(0x932cd909, 0xbda41291),
+ TOBN(0x850e95d4, 0xc0c4ddc0), TOBN(0xc0f422f8, 0x347fc2c9),
+ TOBN(0xe68cbec4, 0x86076bcb), TOBN(0xf9e7c0c0, 0xcd6cd286),
+ TOBN(0x65994ddb, 0x0f5f27ca), TOBN(0xe85461fb, 0xa80d59ff),
+ TOBN(0xff05481a, 0x66601023), TOBN(0xc665427a, 0xfc9ebbfb),
+ TOBN(0xb0571a69, 0x7587fd52), TOBN(0x935289f8, 0x8d49efce),
+ TOBN(0x61becc60, 0xea420688), TOBN(0xb22639d9, 0x13a786af),
+ TOBN(0x1a8e6220, 0x361ecf90), TOBN(0x001f23e0, 0x25506463),
+ TOBN(0xe4ae9b5d, 0x0a5c2b79), TOBN(0xebc9cdad, 0xd8149db5),
+ TOBN(0xb33164a1, 0x934aa728), TOBN(0x750eb00e, 0xae9b60f3),
+ TOBN(0x5a91615b, 0x9b9cfbfd), TOBN(0x97015cbf, 0xef45f7f6),
+ TOBN(0xb462c4a5, 0xbf5151df), TOBN(0x21adcc41, 0xb07118f2),
+ TOBN(0xd60c545b, 0x043fa42c), TOBN(0xfc21aa54, 0xe96be1ab),
+ TOBN(0xe84bc32f, 0x4e51ea80), TOBN(0x3dae45f0, 0x259b5d8d),
+ TOBN(0xbb73c7eb, 0xc38f1b5e), TOBN(0xe405a74a, 0xe8ae617d),
+ TOBN(0xbb1ae9c6, 0x9f1c56bd), TOBN(0x8c176b98, 0x49f196a4),
+ TOBN(0xc448f311, 0x6875092b), TOBN(0xb5afe3de, 0x9f976033),
+ TOBN(0xa8dafd49, 0x145813e5), TOBN(0x687fc4d9, 0xe2b34226),
+ TOBN(0xf2dfc92d, 0x4c7ff57f), TOBN(0x004e3fc1, 0x401f1b46),
+ TOBN(0x5afddab6, 0x1430c9ab), TOBN(0x0bdd41d3, 0x2238e997),
+ TOBN(0xf0947430, 0x418042ae), TOBN(0x71f9adda, 0xcdddc4cb),
+ TOBN(0x7090c016, 0xc52dd907), TOBN(0xd9bdf44d, 0x29e2047f),
+ TOBN(0xe6f1fe80, 0x1b1011a6), TOBN(0xb63accbc, 0xd9acdc78),
+ TOBN(0xcfc7e235, 0x1272a95b), TOBN(0x0c667717, 0xa6276ac8),
+ TOBN(0x3c0d3709, 0xe2d7eef7), TOBN(0x5add2b06, 0x9a685b3e),
+ TOBN(0x363ad32d, 0x14ea5d65), TOBN(0xf8e01f06, 0x8d7dd506),
+ TOBN(0xc9ea2213, 0x75b4aac6), TOBN(0xed2a2bf9, 0x0d353466),
+ TOBN(0x439d79b5, 0xe9d3a7c3), TOBN(0x8e0ee5a6, 0x81b7f34b),
+ TOBN(0xcf3dacf5, 0x1dc4ba75), TOBN(0x1d3d1773, 0xeb3310c7),
+ TOBN(0xa8e67112, 0x7747ae83), TOBN(0x31f43160, 0x197d6b40),
+ TOBN(0x0521ccee, 0xcd961400), TOBN(0x67246f11, 0xf6535768),
+ TOBN(0x702fcc5a, 0xef0c3133), TOBN(0x247cc45d, 0x7e16693b),
+ TOBN(0xfd484e49, 0xc729b749), TOBN(0x522cef7d, 0xb218320f),
+ TOBN(0xe56ef405, 0x59ab93b3), TOBN(0x225fba11, 0x9f181071),
+ TOBN(0x33bd6595, 0x15330ed0), TOBN(0xc4be69d5, 0x1ddb32f7),
+ TOBN(0x264c7668, 0x0448087c), TOBN(0xac30903f, 0x71432dae),
+ TOBN(0x3851b266, 0x00f9bf47), TOBN(0x400ed311, 0x6cdd6d03),
+ TOBN(0x045e79fe, 0xf8fd2424), TOBN(0xfdfd974a, 0xfa6da98b),
+ TOBN(0x45c9f641, 0x0c1e673a), TOBN(0x76f2e733, 0x5b2c5168),
+ TOBN(0x1adaebb5, 0x2a601753), TOBN(0xb286514c, 0xc57c2d49),
+ TOBN(0xd8769670, 0x1e0bfd24), TOBN(0x950c547e, 0x04478922),
+ TOBN(0xd1d41969, 0xe5d32bfe), TOBN(0x30bc1472, 0x750d6c3e),
+ TOBN(0x8f3679fe, 0xe0e27f3a), TOBN(0x8f64a7dc, 0xa4a6ee0c),
+ TOBN(0x2fe59937, 0x633dfb1f), TOBN(0xea82c395, 0x977f2547),
+ TOBN(0xcbdfdf1a, 0x661ea646), TOBN(0xc7ccc591, 0xb9085451),
+ TOBN(0x82177962, 0x81761e13), TOBN(0xda57596f, 0x9196885c),
+ TOBN(0xbc17e849, 0x28ffbd70), TOBN(0x1e6e0a41, 0x2671d36f),
+ TOBN(0x61ae872c, 0x4152fcf5), TOBN(0x441c87b0, 0x9e77e754),
+ TOBN(0xd0799dd5, 0xa34dff09), TOBN(0x766b4e44, 0x88a6b171),
+ TOBN(0xdc06a512, 0x11f1c792), TOBN(0xea02ae93, 0x4be35c3e),
+ TOBN(0xe5ca4d6d, 0xe90c469e), TOBN(0x4df4368e, 0x56e4ff5c),
+ TOBN(0x7817acab, 0x4baef62e), TOBN(0x9f5a2202, 0xa85b91e8),
+ TOBN(0x9666ebe6, 0x6ce57610), TOBN(0x32ad31f3, 0xf73bfe03),
+ TOBN(0x628330a4, 0x25bcf4d6), TOBN(0xea950593, 0x515056e6),
+ TOBN(0x59811c89, 0xe1332156), TOBN(0xc89cf1fe, 0x8c11b2d7),
+ TOBN(0x75b63913, 0x04e60cc0), TOBN(0xce811e8d, 0x4625d375),
+ TOBN(0x030e43fc, 0x2d26e562), TOBN(0xfbb30b4b, 0x608d36a0),
+ TOBN(0x634ff82c, 0x48528118), TOBN(0x7c6fe085, 0xcd285911),
+ TOBN(0x7f2830c0, 0x99358f28), TOBN(0x2e60a95e, 0x665e6c09),
+ TOBN(0x08407d3d, 0x9b785dbf), TOBN(0x530889ab, 0xa759bce7),
+ TOBN(0xf228e0e6, 0x52f61239), TOBN(0x2b6d1461, 0x6879be3c),
+ TOBN(0xe6902c04, 0x51a7bbf7), TOBN(0x30ad99f0, 0x76f24a64),
+ TOBN(0x66d9317a, 0x98bc6da0), TOBN(0xf4f877f3, 0xcb596ac0),
+ TOBN(0xb05ff62d, 0x4c44f119), TOBN(0x4555f536, 0xe9b77416),
+ TOBN(0xc7c0d059, 0x8caed63b), TOBN(0x0cd2b7ce, 0xc358b2a9),
+ TOBN(0x3f33287b, 0x46945fa3), TOBN(0xf8785b20, 0xd67c8791),
+ TOBN(0xc54a7a61, 0x9637bd08), TOBN(0x54d4598c, 0x18be79d7),
+ TOBN(0x889e5acb, 0xc46d7ce1), TOBN(0x9a515bb7, 0x8b085877),
+ TOBN(0xfac1a03d, 0x0b7a5050), TOBN(0x7d3e738a, 0xf2926035),
+ TOBN(0x861cc2ce, 0x2a6cb0eb), TOBN(0x6f2e2955, 0x8f7adc79),
+ TOBN(0x61c4d451, 0x33016376), TOBN(0xd9fd2c80, 0x5ad59090),
+ TOBN(0xe5a83738, 0xb2b836a1), TOBN(0x855b41a0, 0x7c0d6622),
+ TOBN(0x186fe317, 0x7cc19af1), TOBN(0x6465c1ff, 0xfdd99acb),
+ TOBN(0x46e5c23f, 0x6974b99e), TOBN(0x75a7cf8b, 0xa2717cbe),
+ TOBN(0x4d2ebc3f, 0x062be658), TOBN(0x094b4447, 0x5f209c98),
+ TOBN(0x4af285ed, 0xb940cb5a), TOBN(0x6706d792, 0x7cc82f10),
+ TOBN(0xc8c8776c, 0x030526fa), TOBN(0xfa8e6f76, 0xa0da9140),
+ TOBN(0x77ea9d34, 0x591ee4f0), TOBN(0x5f46e337, 0x40274166),
+ TOBN(0x1bdf98bb, 0xea671457), TOBN(0xd7c08b46, 0x862a1fe2),
+ TOBN(0x46cc303c, 0x1c08ad63), TOBN(0x99543440, 0x4c845e7b),
+ TOBN(0x1b8fbdb5, 0x48f36bf7), TOBN(0x5b82c392, 0x8c8273a7),
+ TOBN(0x08f712c4, 0x928435d5), TOBN(0x071cf0f1, 0x79330380),
+ TOBN(0xc74c2d24, 0xa8da054a), TOBN(0xcb0e7201, 0x43c46b5c),
+ TOBN(0x0ad7337a, 0xc0b7eff3), TOBN(0x8552225e, 0xc5e48b3c),
+ TOBN(0xe6f78b0c, 0x73f13a5f), TOBN(0x5e70062e, 0x82349cbe),
+ TOBN(0x6b8d5048, 0xe7073969), TOBN(0x392d2a29, 0xc33cb3d2),
+ TOBN(0xee4f727c, 0x4ecaa20f), TOBN(0xa068c99e, 0x2ccde707),
+ TOBN(0xfcd5651f, 0xb87a2913), TOBN(0xea3e3c15, 0x3cc252f0),
+ TOBN(0x777d92df, 0x3b6cd3e4), TOBN(0x7a414143, 0xc5a732e7),
+ TOBN(0xa895951a, 0xa71ff493), TOBN(0xfe980c92, 0xbbd37cf6),
+ TOBN(0x45bd5e64, 0xdecfeeff), TOBN(0x910dc2a9, 0xa44c43e9),
+ TOBN(0xcb403f26, 0xcca9f54d), TOBN(0x928bbdfb, 0x9303f6db),
+ TOBN(0x3c37951e, 0xa9eee67c), TOBN(0x3bd61a52, 0xf79961c3),
+ TOBN(0x09a238e6, 0x395c9a79), TOBN(0x6940ca2d, 0x61eb352d),
+ TOBN(0x7d1e5c5e, 0xc1875631), TOBN(0x1e19742c, 0x1e1b20d1),
+ TOBN(0x4633d908, 0x23fc2e6e), TOBN(0xa76e29a9, 0x08959149),
+ TOBN(0x61069d9c, 0x84ed7da5), TOBN(0x0baa11cf, 0x5dbcad51),
+ TOBN(0xd01eec64, 0x961849da), TOBN(0x93b75f1f, 0xaf3d8c28),
+ TOBN(0x57bc4f9f, 0x1ca2ee44), TOBN(0x5a26322d, 0x00e00558),
+ TOBN(0x1888d658, 0x61a023ef), TOBN(0x1d72aab4, 0xb9e5246e),
+ TOBN(0xa9a26348, 0xe5563ec0), TOBN(0xa0971963, 0xc3439a43),
+ TOBN(0x567dd54b, 0xadb9b5b7), TOBN(0x73fac1a1, 0xc45a524b),
+ TOBN(0x8fe97ef7, 0xfe38e608), TOBN(0x608748d2, 0x3f384f48),
+ TOBN(0xb0571794, 0xc486094f), TOBN(0x869254a3, 0x8bf3a8d6),
+ TOBN(0x148a8dd1, 0x310b0e25), TOBN(0x99ab9f3f, 0x9aa3f7d8),
+ TOBN(0x0927c68a, 0x6706c02e), TOBN(0x22b5e76c, 0x69790e6c),
+ TOBN(0x6c325260, 0x6c71376c), TOBN(0x53a57690, 0x09ef6657),
+ TOBN(0x8d63f852, 0xedffcf3a), TOBN(0xb4d2ed04, 0x3c0a6f55),
+ TOBN(0xdb3aa8de, 0x12519b9e), TOBN(0x5d38e9c4, 0x1e0a569a),
+ TOBN(0x871528bf, 0x303747e2), TOBN(0xa208e77c, 0xf5b5c18d),
+ TOBN(0x9d129c88, 0xca6bf923), TOBN(0xbcbf197f, 0xbf02839f),
+ TOBN(0x9b9bf030, 0x27323194), TOBN(0x3b055a8b, 0x339ca59d),
+ TOBN(0xb46b2312, 0x0f669520), TOBN(0x19789f1f, 0x497e5f24),
+ TOBN(0x9c499468, 0xaaf01801), TOBN(0x72ee1190, 0x8b69d59c),
+ TOBN(0x8bd39595, 0xacf4c079), TOBN(0x3ee11ece, 0x8e0cd048),
+ TOBN(0xebde86ec, 0x1ed66f18), TOBN(0x225d906b, 0xd61fce43),
+ TOBN(0x5cab07d6, 0xe8bed74d), TOBN(0x16e4617f, 0x27855ab7),
+ TOBN(0x6568aadd, 0xb2fbc3dd), TOBN(0xedb5484f, 0x8aeddf5b),
+ TOBN(0x878f20e8, 0x6dcf2fad), TOBN(0x3516497c, 0x615f5699),
+ },
+ {
+ TOBN(0xef0a3fec, 0xfa181e69), TOBN(0x9ea02f81, 0x30d69a98),
+ TOBN(0xb2e9cf8e, 0x66eab95d), TOBN(0x520f2beb, 0x24720021),
+ TOBN(0x621c540a, 0x1df84361), TOBN(0x12037721, 0x71fa6d5d),
+ TOBN(0x6e3c7b51, 0x0ff5f6ff), TOBN(0x817a069b, 0xabb2bef3),
+ TOBN(0x83572fb6, 0xb294cda6), TOBN(0x6ce9bf75, 0xb9039f34),
+ TOBN(0x20e012f0, 0x095cbb21), TOBN(0xa0aecc1b, 0xd063f0da),
+ TOBN(0x57c21c3a, 0xf02909e5), TOBN(0xc7d59ecf, 0x48ce9cdc),
+ TOBN(0x2732b844, 0x8ae336f8), TOBN(0x056e3723, 0x3f4f85f4),
+ TOBN(0x8a10b531, 0x89e800ca), TOBN(0x50fe0c17, 0x145208fd),
+ TOBN(0x9e43c0d3, 0xb714ba37), TOBN(0x427d200e, 0x34189acc),
+ TOBN(0x05dee24f, 0xe616e2c0), TOBN(0x9c25f4c8, 0xee1854c1),
+ TOBN(0x4d3222a5, 0x8f342a73), TOBN(0x0807804f, 0xa027c952),
+ TOBN(0xc222653a, 0x4f0d56f3), TOBN(0x961e4047, 0xca28b805),
+ TOBN(0x2c03f8b0, 0x4a73434b), TOBN(0x4c966787, 0xab712a19),
+ TOBN(0xcc196c42, 0x864fee42), TOBN(0xc1be93da, 0x5b0ece5c),
+ TOBN(0xa87d9f22, 0xc131c159), TOBN(0x2bb6d593, 0xdce45655),
+ TOBN(0x22c49ec9, 0xb809b7ce), TOBN(0x8a41486b, 0xe2c72c2c),
+ TOBN(0x813b9420, 0xfea0bf36), TOBN(0xb3d36ee9, 0xa66dac69),
+ TOBN(0x6fddc08a, 0x328cc987), TOBN(0x0a3bcd2c, 0x3a326461),
+ TOBN(0x7103c49d, 0xd810dbba), TOBN(0xf9d81a28, 0x4b78a4c4),
+ TOBN(0x3de865ad, 0xe4d55941), TOBN(0xdedafa5e, 0x30384087),
+ TOBN(0x6f414abb, 0x4ef18b9b), TOBN(0x9ee9ea42, 0xfaee5268),
+ TOBN(0x260faa16, 0x37a55a4a), TOBN(0xeb19a514, 0x015f93b9),
+ TOBN(0x51d7ebd2, 0x9e9c3598), TOBN(0x523fc56d, 0x1932178e),
+ TOBN(0x501d070c, 0xb98fe684), TOBN(0xd60fbe9a, 0x124a1458),
+ TOBN(0xa45761c8, 0x92bc6b3f), TOBN(0xf5384858, 0xfe6f27cb),
+ TOBN(0x4b0271f7, 0xb59e763b), TOBN(0x3d4606a9, 0x5b5a8e5e),
+ TOBN(0x1eda5d9b, 0x05a48292), TOBN(0xda7731d0, 0xe6fec446),
+ TOBN(0xa3e33693, 0x90d45871), TOBN(0xe9764040, 0x06166d8d),
+ TOBN(0xb5c33682, 0x89a90403), TOBN(0x4bd17983, 0x72f1d637),
+ TOBN(0xa616679e, 0xd5d2c53a), TOBN(0x5ec4bcd8, 0xfdcf3b87),
+ TOBN(0xae6d7613, 0xb66a694e), TOBN(0x7460fc76, 0xe3fc27e5),
+ TOBN(0x70469b82, 0x95caabee), TOBN(0xde024ca5, 0x889501e3),
+ TOBN(0x6bdadc06, 0x076ed265), TOBN(0x0cb1236b, 0x5a0ef8b2),
+ TOBN(0x4065ddbf, 0x0972ebf9), TOBN(0xf1dd3875, 0x22aca432),
+ TOBN(0xa88b97cf, 0x744aff76), TOBN(0xd1359afd, 0xfe8e3d24),
+ TOBN(0x52a3ba2b, 0x91502cf3), TOBN(0x2c3832a8, 0x084db75d),
+ TOBN(0x04a12ddd, 0xde30b1c9), TOBN(0x7802eabc, 0xe31fd60c),
+ TOBN(0x33707327, 0xa37fddab), TOBN(0x65d6f2ab, 0xfaafa973),
+ TOBN(0x3525c5b8, 0x11e6f91a), TOBN(0x76aeb0c9, 0x5f46530b),
+ TOBN(0xe8815ff6, 0x2f93a675), TOBN(0xa6ec9684, 0x05f48679),
+ TOBN(0x6dcbb556, 0x358ae884), TOBN(0x0af61472, 0xe19e3873),
+ TOBN(0x72334372, 0xa5f696be), TOBN(0xc65e57ea, 0x6f22fb70),
+ TOBN(0x268da30c, 0x946cea90), TOBN(0x136a8a87, 0x65681b2a),
+ TOBN(0xad5e81dc, 0x0f9f44d4), TOBN(0xf09a6960, 0x2c46585a),
+ TOBN(0xd1649164, 0xc447d1b1), TOBN(0x3b4b36c8, 0x879dc8b1),
+ TOBN(0x20d4177b, 0x3b6b234c), TOBN(0x096a2505, 0x1730d9d0),
+ TOBN(0x0611b9b8, 0xef80531d), TOBN(0xba904b3b, 0x64bb495d),
+ TOBN(0x1192d9d4, 0x93a3147a), TOBN(0x9f30a5dc, 0x9a565545),
+ TOBN(0x90b1f9cb, 0x6ef07212), TOBN(0x29958546, 0x0d87fc13),
+ TOBN(0xd3323eff, 0xc17db9ba), TOBN(0xcb18548c, 0xcb1644a8),
+ TOBN(0x18a306d4, 0x4f49ffbc), TOBN(0x28d658f1, 0x4c2e8684),
+ TOBN(0x44ba60cd, 0xa99f8c71), TOBN(0x67b7abdb, 0x4bf742ff),
+ TOBN(0x66310f9c, 0x914b3f99), TOBN(0xae430a32, 0xf412c161),
+ TOBN(0x1e6776d3, 0x88ace52f), TOBN(0x4bc0fa24, 0x52d7067d),
+ TOBN(0x03c286aa, 0x8f07cd1b), TOBN(0x4cb8f38c, 0xa985b2c1),
+ TOBN(0x83ccbe80, 0x8c3bff36), TOBN(0x005a0bd2, 0x5263e575),
+ TOBN(0x460d7dda, 0x259bdcd1), TOBN(0x4a1c5642, 0xfa5cab6b),
+ TOBN(0x2b7bdbb9, 0x9fe4fc88), TOBN(0x09418e28, 0xcc97bbb5),
+ TOBN(0xd8274fb4, 0xa12321ae), TOBN(0xb137007d, 0x5c87b64e),
+ TOBN(0x80531fe1, 0xc63c4962), TOBN(0x50541e89, 0x981fdb25),
+ TOBN(0xdc1291a1, 0xfd4c2b6b), TOBN(0xc0693a17, 0xa6df4fca),
+ TOBN(0xb2c4604e, 0x0117f203), TOBN(0x245f1963, 0x0a99b8d0),
+ TOBN(0xaedc20aa, 0xc6212c44), TOBN(0xb1ed4e56, 0x520f52a8),
+ TOBN(0xfe48f575, 0xf8547be3), TOBN(0x0a7033cd, 0xa9e45f98),
+ TOBN(0x4b45d3a9, 0x18c50100), TOBN(0xb2a6cd6a, 0xa61d41da),
+ TOBN(0x60bbb4f5, 0x57933c6b), TOBN(0xa7538ebd, 0x2b0d7ffc),
+ TOBN(0x9ea3ab8d, 0x8cd626b6), TOBN(0x8273a484, 0x3601625a),
+ TOBN(0x88859845, 0x0168e508), TOBN(0x8cbc9bb2, 0x99a94abd),
+ TOBN(0x713ac792, 0xfab0a671), TOBN(0xa3995b19, 0x6c9ebffc),
+ TOBN(0xe711668e, 0x1239e152), TOBN(0x56892558, 0xbbb8dff4),
+ TOBN(0x8bfc7dab, 0xdbf17963), TOBN(0x5b59fe5a, 0xb3de1253),
+ TOBN(0x7e3320eb, 0x34a9f7ae), TOBN(0xe5e8cf72, 0xd751efe4),
+ TOBN(0x7ea003bc, 0xd9be2f37), TOBN(0xc0f551a0, 0xb6c08ef7),
+ TOBN(0x56606268, 0x038f6725), TOBN(0x1dd38e35, 0x6d92d3b6),
+ TOBN(0x07dfce7c, 0xc3cbd686), TOBN(0x4e549e04, 0x651c5da8),
+ TOBN(0x4058f93b, 0x08b19340), TOBN(0xc2fae6f4, 0xcac6d89d),
+ TOBN(0x4bad8a8c, 0x8f159cc7), TOBN(0x0ddba4b3, 0xcb0b601c),
+ TOBN(0xda4fc7b5, 0x1dd95f8c), TOBN(0x1d163cd7, 0xcea5c255),
+ TOBN(0x30707d06, 0x274a8c4c), TOBN(0x79d9e008, 0x2802e9ce),
+ TOBN(0x02a29ebf, 0xe6ddd505), TOBN(0x37064e74, 0xb50bed1a),
+ TOBN(0x3f6bae65, 0xa7327d57), TOBN(0x3846f5f1, 0xf83920bc),
+ TOBN(0x87c37491, 0x60df1b9b), TOBN(0x4cfb2895, 0x2d1da29f),
+ TOBN(0x10a478ca, 0x4ed1743c), TOBN(0x390c6030, 0x3edd47c6),
+ TOBN(0x8f3e5312, 0x8c0a78de), TOBN(0xccd02bda, 0x1e85df70),
+ TOBN(0xd6c75c03, 0xa61b6582), TOBN(0x0762921c, 0xfc0eebd1),
+ TOBN(0xd34d0823, 0xd85010c0), TOBN(0xd73aaacb, 0x0044cf1f),
+ TOBN(0xfb4159bb, 0xa3b5e78a), TOBN(0x2287c7f7, 0xe5826f3f),
+ TOBN(0x4aeaf742, 0x580b1a01), TOBN(0xf080415d, 0x60423b79),
+ TOBN(0xe12622cd, 0xa7dea144), TOBN(0x49ea4996, 0x59d62472),
+ TOBN(0xb42991ef, 0x571f3913), TOBN(0x0610f214, 0xf5b25a8a),
+ TOBN(0x47adc585, 0x30b79e8f), TOBN(0xf90e3df6, 0x07a065a2),
+ TOBN(0x5d0a5deb, 0x43e2e034), TOBN(0x53fb5a34, 0x444024aa),
+ TOBN(0xa8628c68, 0x6b0c9f7f), TOBN(0x9c69c29c, 0xac563656),
+ TOBN(0x5a231feb, 0xbace47b6), TOBN(0xbdce0289, 0x9ea5a2ec),
+ TOBN(0x05da1fac, 0x9463853e), TOBN(0x96812c52, 0x509e78aa),
+ TOBN(0xd3fb5771, 0x57151692), TOBN(0xeb2721f8, 0xd98e1c44),
+ TOBN(0xc0506087, 0x32399be1), TOBN(0xda5a5511, 0xd979d8b8),
+ TOBN(0x737ed55d, 0xc6f56780), TOBN(0xe20d3004, 0x0dc7a7f4),
+ TOBN(0x02ce7301, 0xf5941a03), TOBN(0x91ef5215, 0xed30f83a),
+ TOBN(0x28727fc1, 0x4092d85f), TOBN(0x72d223c6, 0x5c49e41a),
+ TOBN(0xa7cf30a2, 0xba6a4d81), TOBN(0x7c086209, 0xb030d87d),
+ TOBN(0x04844c7d, 0xfc588b09), TOBN(0x728cd499, 0x5874bbb0),
+ TOBN(0xcc1281ee, 0xe84c0495), TOBN(0x0769b5ba, 0xec31958f),
+ TOBN(0x665c228b, 0xf99c2471), TOBN(0xf2d8a11b, 0x191eb110),
+ TOBN(0x4594f494, 0xd36d7024), TOBN(0x482ded8b, 0xcdcb25a1),
+ TOBN(0xc958a9d8, 0xdadd4885), TOBN(0x7004477e, 0xf1d2b547),
+ TOBN(0x0a45f6ef, 0x2a0af550), TOBN(0x4fc739d6, 0x2f8d6351),
+ TOBN(0x75cdaf27, 0x786f08a9), TOBN(0x8700bb26, 0x42c2737f),
+ TOBN(0x855a7141, 0x1c4e2670), TOBN(0x810188c1, 0x15076fef),
+ TOBN(0xc251d0c9, 0xabcd3297), TOBN(0xae4c8967, 0xf48108eb),
+ TOBN(0xbd146de7, 0x18ceed30), TOBN(0xf9d4f07a, 0xc986bced),
+ TOBN(0x5ad98ed5, 0x83fa1e08), TOBN(0x7780d33e, 0xbeabd1fb),
+ TOBN(0xe330513c, 0x903b1196), TOBN(0xba11de9e, 0xa47bc8c4),
+ TOBN(0x684334da, 0x02c2d064), TOBN(0x7ecf360d, 0xa48de23b),
+ TOBN(0x57a1b474, 0x0a9089d8), TOBN(0xf28fa439, 0xff36734c),
+ TOBN(0xf2a482cb, 0xea4570b3), TOBN(0xee65d68b, 0xa5ebcee9),
+ TOBN(0x988d0036, 0xb9694cd5), TOBN(0x53edd0e9, 0x37885d32),
+ TOBN(0xe37e3307, 0xbeb9bc6d), TOBN(0xe9abb907, 0x9f5c6768),
+ TOBN(0x4396ccd5, 0x51f2160f), TOBN(0x2500888c, 0x47336da6),
+ TOBN(0x383f9ed9, 0x926fce43), TOBN(0x809dd1c7, 0x04da2930),
+ TOBN(0x30f6f596, 0x8a4cb227), TOBN(0x0d700c7f, 0x73a56b38),
+ TOBN(0x1825ea33, 0xab64a065), TOBN(0xaab9b735, 0x1338df80),
+ TOBN(0x1516100d, 0x9b63f57f), TOBN(0x2574395a, 0x27a6a634),
+ TOBN(0xb5560fb6, 0x700a1acd), TOBN(0xe823fd73, 0xfd999681),
+ TOBN(0xda915d1f, 0x6cb4e1ba), TOBN(0x0d030118, 0x6ebe00a3),
+ TOBN(0x744fb0c9, 0x89fca8cd), TOBN(0x970d01db, 0xf9da0e0b),
+ TOBN(0x0ad8c564, 0x7931d76f), TOBN(0xb15737bf, 0xf659b96a),
+ TOBN(0xdc9933e8, 0xa8b484e7), TOBN(0xb2fdbdf9, 0x7a26dec7),
+ TOBN(0x2349e9a4, 0x9f1f0136), TOBN(0x7860368e, 0x70fddddb),
+ TOBN(0xd93d2c1c, 0xf9ad3e18), TOBN(0x6d6c5f17, 0x689f4e79),
+ TOBN(0x7a544d91, 0xb24ff1b6), TOBN(0x3e12a5eb, 0xfe16cd8c),
+ TOBN(0x543574e9, 0xa56b872f), TOBN(0xa1ad550c, 0xfcf68ea2),
+ TOBN(0x689e37d2, 0x3f560ef7), TOBN(0x8c54b9ca, 0xc9d47a8b),
+ TOBN(0x46d40a4a, 0x088ac342), TOBN(0xec450c7c, 0x1576c6d0),
+ TOBN(0xb589e31c, 0x1f9689e9), TOBN(0xdacf2602, 0xb8781718),
+ TOBN(0xa89237c6, 0xc8cb6b42), TOBN(0x1326fc93, 0xb96ef381),
+ TOBN(0x55d56c6d, 0xb5f07825), TOBN(0xacba2eea, 0x7449e22d),
+ TOBN(0x74e0887a, 0x633c3000), TOBN(0xcb6cd172, 0xd7cbcf71),
+ TOBN(0x309e81de, 0xc36cf1be), TOBN(0x07a18a6d, 0x60ae399b),
+ TOBN(0xb36c2679, 0x9edce57e), TOBN(0x52b892f4, 0xdf001d41),
+ TOBN(0xd884ae5d, 0x16a1f2c6), TOBN(0x9b329424, 0xefcc370a),
+ TOBN(0x3120daf2, 0xbd2e21df), TOBN(0x55298d2d, 0x02470a99),
+ TOBN(0x0b78af6c, 0xa05db32e), TOBN(0x5c76a331, 0x601f5636),
+ TOBN(0xaae861ff, 0xf8a4f29c), TOBN(0x70dc9240, 0xd68f8d49),
+ TOBN(0x960e649f, 0x81b1321c), TOBN(0x3d2c801b, 0x8792e4ce),
+ TOBN(0xf479f772, 0x42521876), TOBN(0x0bed93bc, 0x416c79b1),
+ TOBN(0xa67fbc05, 0x263e5bc9), TOBN(0x01e8e630, 0x521db049),
+ TOBN(0x76f26738, 0xc6f3431e), TOBN(0xe609cb02, 0xe3267541),
+ TOBN(0xb10cff2d, 0x818c877c), TOBN(0x1f0e75ce, 0x786a13cb),
+ TOBN(0xf4fdca64, 0x1158544d), TOBN(0x5d777e89, 0x6cb71ed0),
+ TOBN(0x3c233737, 0xa9aa4755), TOBN(0x7b453192, 0xe527ab40),
+ TOBN(0xdb59f688, 0x39f05ffe), TOBN(0x8f4f4be0, 0x6d82574e),
+ TOBN(0xcce3450c, 0xee292d1b), TOBN(0xaa448a12, 0x61ccd086),
+ TOBN(0xabce91b3, 0xf7914967), TOBN(0x4537f09b, 0x1908a5ed),
+ TOBN(0xa812421e, 0xf51042e7), TOBN(0xfaf5cebc, 0xec0b3a34),
+ TOBN(0x730ffd87, 0x4ca6b39a), TOBN(0x70fb72ed, 0x02efd342),
+ TOBN(0xeb4735f9, 0xd75c8edb), TOBN(0xc11f2157, 0xc278aa51),
+ TOBN(0xc459f635, 0xbf3bfebf), TOBN(0x3a1ff0b4, 0x6bd9601f),
+ TOBN(0xc9d12823, 0xc420cb73), TOBN(0x3e9af3e2, 0x3c2915a3),
+ TOBN(0xe0c82c72, 0xb41c3440), TOBN(0x175239e5, 0xe3039a5f),
+ TOBN(0xe1084b8a, 0x558795a3), TOBN(0x328d0a1d, 0xd01e5c60),
+ TOBN(0x0a495f2e, 0xd3788a04), TOBN(0x25d8ff16, 0x66c11a9f),
+ TOBN(0xf5155f05, 0x9ed692d6), TOBN(0x954fa107, 0x4f425fe4),
+ TOBN(0xd16aabf2, 0xe98aaa99), TOBN(0x90cd8ba0, 0x96b0f88a),
+ TOBN(0x957f4782, 0xc154026a), TOBN(0x54ee0734, 0x52af56d2),
+ TOBN(0xbcf89e54, 0x45b4147a), TOBN(0x3d102f21, 0x9a52816c),
+ TOBN(0x6808517e, 0x39b62e77), TOBN(0x92e25421, 0x69169ad8),
+ TOBN(0xd721d871, 0xbb608558), TOBN(0x60e4ebae, 0xf6d4ff9b),
+ TOBN(0x0ba10819, 0x41f2763e), TOBN(0xca2e45be, 0x51ee3247),
+ TOBN(0x66d172ec, 0x2bfd7a5f), TOBN(0x528a8f2f, 0x74d0b12d),
+ TOBN(0xe17f1e38, 0xdabe70dc), TOBN(0x1d5d7316, 0x9f93983c),
+ TOBN(0x51b2184a, 0xdf423e31), TOBN(0xcb417291, 0xaedb1a10),
+ TOBN(0x2054ca93, 0x625bcab9), TOBN(0x54396860, 0xa98998f0),
+ TOBN(0x4e53f6c4, 0xa54ae57e), TOBN(0x0ffeb590, 0xee648e9d),
+ TOBN(0xfbbdaadc, 0x6afaf6bc), TOBN(0xf88ae796, 0xaa3bfb8a),
+ TOBN(0x209f1d44, 0xd2359ed9), TOBN(0xac68dd03, 0xf3544ce2),
+ TOBN(0xf378da47, 0xfd51e569), TOBN(0xe1abd860, 0x2cc80097),
+ TOBN(0x23ca18d9, 0x343b6e3a), TOBN(0x480797e8, 0xb40a1bae),
+ TOBN(0xd1f0c717, 0x533f3e67), TOBN(0x44896970, 0x06e6cdfc),
+ TOBN(0x8ca21055, 0x52a82e8d), TOBN(0xb2caf785, 0x78460cdc),
+ TOBN(0x4c1b7b62, 0xe9037178), TOBN(0xefc09d2c, 0xdb514b58),
+ TOBN(0x5f2df9ee, 0x9113be5c), TOBN(0x2fbda78f, 0xb3f9271c),
+ TOBN(0xe09a81af, 0x8f83fc54), TOBN(0x06b13866, 0x8afb5141),
+ TOBN(0x38f6480f, 0x43e3865d), TOBN(0x72dd77a8, 0x1ddf47d9),
+ TOBN(0xf2a8e971, 0x4c205ff7), TOBN(0x46d449d8, 0x9d088ad8),
+ TOBN(0x926619ea, 0x185d706f), TOBN(0xe47e02eb, 0xc7dd7f62),
+ TOBN(0xe7f120a7, 0x8cbc2031), TOBN(0xc18bef00, 0x998d4ac9),
+ TOBN(0x18f37a9c, 0x6bdf22da), TOBN(0xefbc432f, 0x90dc82df),
+ TOBN(0xc52cef8e, 0x5d703651), TOBN(0x82887ba0, 0xd99881a5),
+ TOBN(0x7cec9dda, 0xb920ec1d), TOBN(0xd0d7e8c3, 0xec3e8d3b),
+ TOBN(0x445bc395, 0x4ca88747), TOBN(0xedeaa2e0, 0x9fd53535),
+ TOBN(0x461b1d93, 0x6cc87475), TOBN(0xd92a52e2, 0x6d2383bd),
+ TOBN(0xfabccb59, 0xd7903546), TOBN(0x6111a761, 0x3d14b112),
+ TOBN(0x0ae584fe, 0xb3d5f612), TOBN(0x5ea69b8d, 0x60e828ec),
+ TOBN(0x6c078985, 0x54087030), TOBN(0x649cab04, 0xac4821fe),
+ TOBN(0x25ecedcf, 0x8bdce214), TOBN(0xb5622f72, 0x86af7361),
+ TOBN(0x0e1227aa, 0x7038b9e2), TOBN(0xd0efb273, 0xac20fa77),
+ TOBN(0x817ff88b, 0x79df975b), TOBN(0x856bf286, 0x1999503e),
+ TOBN(0xb4d5351f, 0x5038ec46), TOBN(0x740a52c5, 0xfc42af6e),
+ TOBN(0x2e38bb15, 0x2cbb1a3f), TOBN(0xc3eb99fe, 0x17a83429),
+ TOBN(0xca4fcbf1, 0xdd66bb74), TOBN(0x880784d6, 0xcde5e8fc),
+ TOBN(0xddc84c1c, 0xb4e7a0be), TOBN(0x8780510d, 0xbd15a72f),
+ TOBN(0x44bcf1af, 0x81ec30e1), TOBN(0x141e50a8, 0x0a61073e),
+ TOBN(0x0d955718, 0x47be87ae), TOBN(0x68a61417, 0xf76a4372),
+ TOBN(0xf57e7e87, 0xc607c3d3), TOBN(0x043afaf8, 0x5252f332),
+ TOBN(0xcc14e121, 0x1552a4d2), TOBN(0xb6dee692, 0xbb4d4ab4),
+ TOBN(0xb6ab74c8, 0xa03816a4), TOBN(0x84001ae4, 0x6f394a29),
+ TOBN(0x5bed8344, 0xd795fb45), TOBN(0x57326e7d, 0xb79f55a5),
+ TOBN(0xc9533ce0, 0x4accdffc), TOBN(0x53473caf, 0x3993fa04),
+ TOBN(0x7906eb93, 0xa13df4c8), TOBN(0xa73e51f6, 0x97cbe46f),
+ TOBN(0xd1ab3ae1, 0x0ae4ccf8), TOBN(0x25614508, 0x8a5b3dbc),
+ TOBN(0x61eff962, 0x11a71b27), TOBN(0xdf71412b, 0x6bb7fa39),
+ TOBN(0xb31ba6b8, 0x2bd7f3ef), TOBN(0xb0b9c415, 0x69180d29),
+ TOBN(0xeec14552, 0x014cdde5), TOBN(0x702c624b, 0x227b4bbb),
+ TOBN(0x2b15e8c2, 0xd3e988f3), TOBN(0xee3bcc6d, 0xa4f7fd04),
+ TOBN(0x9d00822a, 0x42ac6c85), TOBN(0x2db0cea6, 0x1df9f2b7),
+ TOBN(0xd7cad2ab, 0x42de1e58), TOBN(0x346ed526, 0x2d6fbb61),
+ TOBN(0xb3962995, 0x1a2faf09), TOBN(0x2fa8a580, 0x7c25612e),
+ TOBN(0x30ae04da, 0x7cf56490), TOBN(0x75662908, 0x0eea3961),
+ TOBN(0x3609f5c5, 0x3d080847), TOBN(0xcb081d39, 0x5241d4f6),
+ TOBN(0xb4fb3810, 0x77961a63), TOBN(0xc20c5984, 0x2abb66fc),
+ TOBN(0x3d40aa7c, 0xf902f245), TOBN(0x9cb12736, 0x4e536b1e),
+ TOBN(0x5eda24da, 0x99b3134f), TOBN(0xafbd9c69, 0x5cd011af),
+ TOBN(0x9a16e30a, 0xc7088c7d), TOBN(0x5ab65710, 0x3207389f),
+ TOBN(0x1b09547f, 0xe7407a53), TOBN(0x2322f9d7, 0x4fdc6eab),
+ TOBN(0xc0f2f22d, 0x7430de4d), TOBN(0x19382696, 0xe68ca9a9),
+ TOBN(0x17f1eff1, 0x918e5868), TOBN(0xe3b5b635, 0x586f4204),
+ TOBN(0x146ef980, 0x3fbc4341), TOBN(0x359f2c80, 0x5b5eed4e),
+ TOBN(0x9f35744e, 0x7482e41d), TOBN(0x9a9ac3ec, 0xf3b224c2),
+ TOBN(0x9161a6fe, 0x91fc50ae), TOBN(0x89ccc66b, 0xc613fa7c),
+ TOBN(0x89268b14, 0xc732f15a), TOBN(0x7cd6f4e2, 0xb467ed03),
+ TOBN(0xfbf79869, 0xce56b40e), TOBN(0xf93e094c, 0xc02dde98),
+ TOBN(0xefe0c3a8, 0xedee2cd7), TOBN(0x90f3ffc0, 0xb268fd42),
+ TOBN(0x81a7fd56, 0x08241aed), TOBN(0x95ab7ad8, 0x00b1afe8),
+ TOBN(0x40127056, 0x3e310d52), TOBN(0xd3ffdeb1, 0x09d9fc43),
+ TOBN(0xc8f85c91, 0xd11a8594), TOBN(0x2e74d258, 0x31cf6db8),
+ TOBN(0x829c7ca3, 0x02b5dfd0), TOBN(0xe389cfbe, 0x69143c86),
+ TOBN(0xd01b6405, 0x941768d8), TOBN(0x45103995, 0x03bf825d),
+ TOBN(0xcc4ee166, 0x56cd17e2), TOBN(0xbea3c283, 0xba037e79),
+ TOBN(0x4e1ac06e, 0xd9a47520), TOBN(0xfbfe18aa, 0xaf852404),
+ TOBN(0x5615f8e2, 0x8087648a), TOBN(0x7301e47e, 0xb9d150d9),
+ TOBN(0x79f9f9dd, 0xb299b977), TOBN(0x76697a7b, 0xa5b78314),
+ TOBN(0x10d67468, 0x7d7c90e7), TOBN(0x7afffe03, 0x937210b5),
+ TOBN(0x5aef3e4b, 0x28c22cee), TOBN(0xefb0ecd8, 0x09fd55ae),
+ TOBN(0x4cea7132, 0x0d2a5d6a), TOBN(0x9cfb5fa1, 0x01db6357),
+ TOBN(0x395e0b57, 0xf36e1ac5), TOBN(0x008fa9ad, 0x36cafb7d),
+ TOBN(0x8f6cdf70, 0x5308c4db), TOBN(0x51527a37, 0x95ed2477),
+ TOBN(0xba0dee30, 0x5bd21311), TOBN(0x6ed41b22, 0x909c90d7),
+ TOBN(0xc5f6b758, 0x7c8696d3), TOBN(0x0db8eaa8, 0x3ce83a80),
+ TOBN(0xd297fe37, 0xb24b4b6f), TOBN(0xfe58afe8, 0x522d1f0d),
+ TOBN(0x97358736, 0x8c98dbd9), TOBN(0x6bc226ca, 0x9454a527),
+ TOBN(0xa12b384e, 0xce53c2d0), TOBN(0x779d897d, 0x5e4606da),
+ TOBN(0xa53e47b0, 0x73ec12b0), TOBN(0x462dbbba, 0x5756f1ad),
+ TOBN(0x69fe09f2, 0xcafe37b6), TOBN(0x273d1ebf, 0xecce2e17),
+ TOBN(0x8ac1d538, 0x3cf607fd), TOBN(0x8035f7ff, 0x12e10c25),
+ },
+ {
+ TOBN(0x854d34c7, 0x7e6c5520), TOBN(0xc27df9ef, 0xdcb9ea58),
+ TOBN(0x405f2369, 0xd686666d), TOBN(0x29d1febf, 0x0417aa85),
+ TOBN(0x9846819e, 0x93470afe), TOBN(0x3e6a9669, 0xe2a27f9e),
+ TOBN(0x24d008a2, 0xe31e6504), TOBN(0xdba7cecf, 0x9cb7680a),
+ TOBN(0xecaff541, 0x338d6e43), TOBN(0x56f7dd73, 0x4541d5cc),
+ TOBN(0xb5d426de, 0x96bc88ca), TOBN(0x48d94f6b, 0x9ed3a2c3),
+ TOBN(0x6354a3bb, 0x2ef8279c), TOBN(0xd575465b, 0x0b1867f2),
+ TOBN(0xef99b0ff, 0x95225151), TOBN(0xf3e19d88, 0xf94500d8),
+ TOBN(0x92a83268, 0xe32dd620), TOBN(0x913ec99f, 0x627849a2),
+ TOBN(0xedd8fdfa, 0x2c378882), TOBN(0xaf96f33e, 0xee6f8cfe),
+ TOBN(0xc06737e5, 0xdc3fa8a5), TOBN(0x236bb531, 0xb0b03a1d),
+ TOBN(0x33e59f29, 0x89f037b0), TOBN(0x13f9b5a7, 0xd9a12a53),
+ TOBN(0x0d0df6ce, 0x51efb310), TOBN(0xcb5b2eb4, 0x958df5be),
+ TOBN(0xd6459e29, 0x36158e59), TOBN(0x82aae2b9, 0x1466e336),
+ TOBN(0xfb658a39, 0x411aa636), TOBN(0x7152ecc5, 0xd4c0a933),
+ TOBN(0xf10c758a, 0x49f026b7), TOBN(0xf4837f97, 0xcb09311f),
+ TOBN(0xddfb02c4, 0xc753c45f), TOBN(0x18ca81b6, 0xf9c840fe),
+ TOBN(0x846fd09a, 0xb0f8a3e6), TOBN(0xb1162add, 0xe7733dbc),
+ TOBN(0x7070ad20, 0x236e3ab6), TOBN(0xf88cdaf5, 0xb2a56326),
+ TOBN(0x05fc8719, 0x997cbc7a), TOBN(0x442cd452, 0x4b665272),
+ TOBN(0x7807f364, 0xb71698f5), TOBN(0x6ba418d2, 0x9f7b605e),
+ TOBN(0xfd20b00f, 0xa03b2cbb), TOBN(0x883eca37, 0xda54386f),
+ TOBN(0xff0be43f, 0xf3437f24), TOBN(0xe910b432, 0xa48bb33c),
+ TOBN(0x4963a128, 0x329df765), TOBN(0xac1dd556, 0xbe2fe6f7),
+ TOBN(0x557610f9, 0x24a0a3fc), TOBN(0x38e17bf4, 0xe881c3f9),
+ TOBN(0x6ba84faf, 0xed0dac99), TOBN(0xd4a222c3, 0x59eeb918),
+ TOBN(0xc79c1dbe, 0x13f542b6), TOBN(0x1fc65e0d, 0xe425d457),
+ TOBN(0xeffb754f, 0x1debb779), TOBN(0x638d8fd0, 0x9e08af60),
+ TOBN(0x994f523a, 0x626332d5), TOBN(0x7bc38833, 0x5561bb44),
+ TOBN(0x005ed4b0, 0x3d845ea2), TOBN(0xd39d3ee1, 0xc2a1f08a),
+ TOBN(0x6561fdd3, 0xe7676b0d), TOBN(0x620e35ff, 0xfb706017),
+ TOBN(0x36ce424f, 0xf264f9a8), TOBN(0xc4c3419f, 0xda2681f7),
+ TOBN(0xfb6afd2f, 0x69beb6e8), TOBN(0x3a50b993, 0x6d700d03),
+ TOBN(0xc840b2ad, 0x0c83a14f), TOBN(0x573207be, 0x54085bef),
+ TOBN(0x5af882e3, 0x09fe7e5b), TOBN(0x957678a4, 0x3b40a7e1),
+ TOBN(0x172d4bdd, 0x543056e2), TOBN(0x9c1b26b4, 0x0df13c0a),
+ TOBN(0x1c30861c, 0xf405ff06), TOBN(0xebac86bd, 0x486e828b),
+ TOBN(0xe791a971, 0x636933fc), TOBN(0x50e7c2be, 0x7aeee947),
+ TOBN(0xc3d4a095, 0xfa90d767), TOBN(0xae60eb7b, 0xe670ab7b),
+ TOBN(0x17633a64, 0x397b056d), TOBN(0x93a21f33, 0x105012aa),
+ TOBN(0x663c370b, 0xabb88643), TOBN(0x91df36d7, 0x22e21599),
+ TOBN(0x183ba835, 0x8b761671), TOBN(0x381eea1d, 0x728f3bf1),
+ TOBN(0xb9b2f1ba, 0x39966e6c), TOBN(0x7c464a28, 0xe7295492),
+ TOBN(0x0fd5f70a, 0x09b26b7f), TOBN(0xa9aba1f9, 0xfbe009df),
+ TOBN(0x857c1f22, 0x369b87ad), TOBN(0x3c00e5d9, 0x32fca556),
+ TOBN(0x1ad74cab, 0x90b06466), TOBN(0xa7112386, 0x550faaf2),
+ TOBN(0x7435e198, 0x6d9bd5f5), TOBN(0x2dcc7e38, 0x59c3463f),
+ TOBN(0xdc7df748, 0xca7bd4b2), TOBN(0x13cd4c08, 0x9dec2f31),
+ TOBN(0x0d3b5df8, 0xe3237710), TOBN(0x0dadb26e, 0xcbd2f7b0),
+ TOBN(0x9f5966ab, 0xe4aa082b), TOBN(0x666ec8de, 0x350e966e),
+ TOBN(0x1bfd1ed5, 0xee524216), TOBN(0xcd93c59b, 0x41dab0b6),
+ TOBN(0x658a8435, 0xd186d6ba), TOBN(0x1b7d34d2, 0x159d1195),
+ TOBN(0x5936e460, 0x22caf46b), TOBN(0x6a45dd8f, 0x9a96fe4f),
+ TOBN(0xf7925434, 0xb98f474e), TOBN(0x41410412, 0x0053ef15),
+ TOBN(0x71cf8d12, 0x41de97bf), TOBN(0xb8547b61, 0xbd80bef4),
+ TOBN(0xb47d3970, 0xc4db0037), TOBN(0xf1bcd328, 0xfef20dff),
+ TOBN(0x31a92e09, 0x10caad67), TOBN(0x1f591960, 0x5531a1e1),
+ TOBN(0x3bb852e0, 0x5f4fc840), TOBN(0x63e297ca, 0x93a72c6c),
+ TOBN(0x3c2b0b2e, 0x49abad67), TOBN(0x6ec405fc, 0xed3db0d9),
+ TOBN(0xdc14a530, 0x7fef1d40), TOBN(0xccd19846, 0x280896fc),
+ TOBN(0x00f83176, 0x9bb81648), TOBN(0xd69eb485, 0x653120d0),
+ TOBN(0xd17d75f4, 0x4ccabc62), TOBN(0x34a07f82, 0xb749fcb1),
+ TOBN(0x2c3af787, 0xbbfb5554), TOBN(0xb06ed4d0, 0x62e283f8),
+ TOBN(0x5722889f, 0xa19213a0), TOBN(0x162b085e, 0xdcf3c7b4),
+ TOBN(0xbcaecb31, 0xe0dd3eca), TOBN(0xc6237fbc, 0xe52f13a5),
+ TOBN(0xcc2b6b03, 0x27bac297), TOBN(0x2ae1cac5, 0xb917f54a),
+ TOBN(0x474807d4, 0x7845ae4f), TOBN(0xfec7dd92, 0xce5972e0),
+ TOBN(0xc3bd2541, 0x1d7915bb), TOBN(0x66f85dc4, 0xd94907ca),
+ TOBN(0xd981b888, 0xbdbcf0ca), TOBN(0xd75f5da6, 0xdf279e9f),
+ TOBN(0x128bbf24, 0x7054e934), TOBN(0x3c6ff6e5, 0x81db134b),
+ TOBN(0x795b7cf4, 0x047d26e4), TOBN(0xf370f7b8, 0x5049ec37),
+ TOBN(0xc6712d4d, 0xced945af), TOBN(0xdf30b5ec, 0x095642bc),
+ TOBN(0x9b034c62, 0x4896246e), TOBN(0x5652c016, 0xee90bbd1),
+ TOBN(0xeb38636f, 0x87fedb73), TOBN(0x5e32f847, 0x0135a613),
+ TOBN(0x0703b312, 0xcf933c83), TOBN(0xd05bb76e, 0x1a7f47e6),
+ TOBN(0x825e4f0c, 0x949c2415), TOBN(0x569e5622, 0x7250d6f8),
+ TOBN(0xbbe9eb3a, 0x6568013e), TOBN(0x8dbd203f, 0x22f243fc),
+ TOBN(0x9dbd7694, 0xb342734a), TOBN(0x8f6d12f8, 0x46afa984),
+ TOBN(0xb98610a2, 0xc9eade29), TOBN(0xbab4f323, 0x47dd0f18),
+ TOBN(0x5779737b, 0x671c0d46), TOBN(0x10b6a7c6, 0xd3e0a42a),
+ TOBN(0xfb19ddf3, 0x3035b41c), TOBN(0xd336343f, 0x99c45895),
+ TOBN(0x61fe4938, 0x54c857e5), TOBN(0xc4d506be, 0xae4e57d5),
+ TOBN(0x3cd8c8cb, 0xbbc33f75), TOBN(0x7281f08a, 0x9262c77d),
+ TOBN(0x083f4ea6, 0xf11a2823), TOBN(0x8895041e, 0x9fba2e33),
+ TOBN(0xfcdfea49, 0x9c438edf), TOBN(0x7678dcc3, 0x91edba44),
+ TOBN(0xf07b3b87, 0xe2ba50f0), TOBN(0xc13888ef, 0x43948c1b),
+ TOBN(0xc2135ad4, 0x1140af42), TOBN(0x8e5104f3, 0x926ed1a7),
+ TOBN(0xf24430cb, 0x88f6695f), TOBN(0x0ce0637b, 0x6d73c120),
+ TOBN(0xb2db01e6, 0xfe631e8f), TOBN(0x1c5563d7, 0xd7bdd24b),
+ TOBN(0x8daea3ba, 0x369ad44f), TOBN(0x000c81b6, 0x8187a9f9),
+ TOBN(0x5f48a951, 0xaae1fd9a), TOBN(0xe35626c7, 0x8d5aed8a),
+ TOBN(0x20952763, 0x0498c622), TOBN(0x76d17634, 0x773aa504),
+ TOBN(0x36d90dda, 0xeb300f7a), TOBN(0x9dcf7dfc, 0xedb5e801),
+ TOBN(0x645cb268, 0x74d5244c), TOBN(0xa127ee79, 0x348e3aa2),
+ TOBN(0x488acc53, 0x575f1dbb), TOBN(0x95037e85, 0x80e6161e),
+ TOBN(0x57e59283, 0x292650d0), TOBN(0xabe67d99, 0x14938216),
+ TOBN(0x3c7f944b, 0x3f8e1065), TOBN(0xed908cb6, 0x330e8924),
+ TOBN(0x08ee8fd5, 0x6f530136), TOBN(0x2227b7d5, 0xd7ffc169),
+ TOBN(0x4f55c893, 0xb5cd6dd5), TOBN(0x82225e11, 0xa62796e8),
+ TOBN(0x5c6cead1, 0xcb18e12c), TOBN(0x4381ae0c, 0x84f5a51a),
+ TOBN(0x345913d3, 0x7fafa4c8), TOBN(0x3d918082, 0x0491aac0),
+ TOBN(0x9347871f, 0x3e69264c), TOBN(0xbea9dd3c, 0xb4f4f0cd),
+ TOBN(0xbda5d067, 0x3eadd3e7), TOBN(0x0033c1b8, 0x0573bcd8),
+ TOBN(0x25589379, 0x5da2486c), TOBN(0xcb89ee5b, 0x86abbee7),
+ TOBN(0x8fe0a8f3, 0x22532e5d), TOBN(0xb6410ff0, 0x727dfc4c),
+ TOBN(0x619b9d58, 0x226726db), TOBN(0x5ec25669, 0x7a2b2dc7),
+ TOBN(0xaf4d2e06, 0x4c3beb01), TOBN(0x852123d0, 0x7acea556),
+ TOBN(0x0e9470fa, 0xf783487a), TOBN(0x75a7ea04, 0x5664b3eb),
+ TOBN(0x4ad78f35, 0x6798e4ba), TOBN(0x9214e6e5, 0xc7d0e091),
+ TOBN(0xc420b488, 0xb1290403), TOBN(0x64049e0a, 0xfc295749),
+ TOBN(0x03ef5af1, 0x3ae9841f), TOBN(0xdbe4ca19, 0xb0b662a6),
+ TOBN(0x46845c5f, 0xfa453458), TOBN(0xf8dabf19, 0x10b66722),
+ TOBN(0xb650f0aa, 0xcce2793b), TOBN(0x71db851e, 0xc5ec47c1),
+ TOBN(0x3eb78f3e, 0x3b234fa9), TOBN(0xb0c60f35, 0xfc0106ce),
+ TOBN(0x05427121, 0x774eadbd), TOBN(0x25367faf, 0xce323863),
+ TOBN(0x7541b5c9, 0xcd086976), TOBN(0x4ff069e2, 0xdc507ad1),
+ TOBN(0x74145256, 0x8776e667), TOBN(0x6e76142c, 0xb23c6bb5),
+ TOBN(0xdbf30712, 0x1b3a8a87), TOBN(0x60e7363e, 0x98450836),
+ TOBN(0x5741450e, 0xb7366d80), TOBN(0xe4ee14ca, 0x4837dbdf),
+ TOBN(0xa765eb9b, 0x69d4316f), TOBN(0x04548dca, 0x8ef43825),
+ TOBN(0x9c9f4e4c, 0x5ae888eb), TOBN(0x733abb51, 0x56e9ac99),
+ TOBN(0xdaad3c20, 0xba6ac029), TOBN(0x9b8dd3d3, 0x2ba3e38e),
+ TOBN(0xa9bb4c92, 0x0bc5d11a), TOBN(0xf20127a7, 0x9c5f88a3),
+ TOBN(0x4f52b06e, 0x161d3cb8), TOBN(0x26c1ff09, 0x6afaf0a6),
+ TOBN(0x32670d2f, 0x7189e71f), TOBN(0xc6438748, 0x5ecf91e7),
+ TOBN(0x15758e57, 0xdb757a21), TOBN(0x427d09f8, 0x290a9ce5),
+ TOBN(0x846a308f, 0x38384a7a), TOBN(0xaac3acb4, 0xb0732b99),
+ TOBN(0x9e941009, 0x17845819), TOBN(0x95cba111, 0xa7ce5e03),
+ TOBN(0x6f3d4f7f, 0xb00009c4), TOBN(0xb8396c27, 0x8ff28b5f),
+ TOBN(0xb1a9ae43, 0x1c97975d), TOBN(0x9d7ba8af, 0xe5d9fed5),
+ TOBN(0x338cf09f, 0x34f485b6), TOBN(0xbc0ddacc, 0x64122516),
+ TOBN(0xa450da12, 0x05d471fe), TOBN(0x4c3a6250, 0x628dd8c9),
+ TOBN(0x69c7d103, 0xd1295837), TOBN(0xa2893e50, 0x3807eb2f),
+ TOBN(0xd6e1e1de, 0xbdb41491), TOBN(0xc630745b, 0x5e138235),
+ TOBN(0xc892109e, 0x48661ae1), TOBN(0x8d17e7eb, 0xea2b2674),
+ TOBN(0x00ec0f87, 0xc328d6b5), TOBN(0x6d858645, 0xf079ff9e),
+ TOBN(0x6cdf243e, 0x19115ead), TOBN(0x1ce1393e, 0x4bac4fcf),
+ TOBN(0x2c960ed0, 0x9c29f25b), TOBN(0x59be4d8e, 0x9d388a05),
+ TOBN(0x0d46e06c, 0xd0def72b), TOBN(0xb923db5d, 0xe0342748),
+ TOBN(0xf7d3aacd, 0x936d4a3d), TOBN(0x558519cc, 0x0b0b099e),
+ TOBN(0x3ea8ebf8, 0x827097ef), TOBN(0x259353db, 0xd054f55d),
+ TOBN(0x84c89abc, 0x6d2ed089), TOBN(0x5c548b69, 0x8e096a7c),
+ TOBN(0xd587f616, 0x994b995d), TOBN(0x4d1531f6, 0xa5845601),
+ TOBN(0x792ab31e, 0x451fd9f0), TOBN(0xc8b57bb2, 0x65adf6ca),
+ TOBN(0x68440fcb, 0x1cd5ad73), TOBN(0xb9c860e6, 0x6144da4f),
+ TOBN(0x2ab286aa, 0x8462beb8), TOBN(0xcc6b8fff, 0xef46797f),
+ TOBN(0xac820da4, 0x20c8a471), TOBN(0x69ae05a1, 0x77ff7faf),
+ TOBN(0xb9163f39, 0xbfb5da77), TOBN(0xbd03e590, 0x2c73ab7a),
+ TOBN(0x7e862b5e, 0xb2940d9e), TOBN(0x3c663d86, 0x4b9af564),
+ TOBN(0xd8309031, 0xbde3033d), TOBN(0x298231b2, 0xd42c5bc6),
+ TOBN(0x42090d2c, 0x552ad093), TOBN(0xa4799d1c, 0xff854695),
+ TOBN(0x0a88b5d6, 0xd31f0d00), TOBN(0xf8b40825, 0xa2f26b46),
+ TOBN(0xec29b1ed, 0xf1bd7218), TOBN(0xd491c53b, 0x4b24c86e),
+ TOBN(0xd2fe588f, 0x3395ea65), TOBN(0x6f3764f7, 0x4456ef15),
+ TOBN(0xdb43116d, 0xcdc34800), TOBN(0xcdbcd456, 0xc1e33955),
+ TOBN(0xefdb5540, 0x74ab286b), TOBN(0x948c7a51, 0xd18c5d7c),
+ TOBN(0xeb81aa37, 0x7378058e), TOBN(0x41c746a1, 0x04411154),
+ TOBN(0xa10c73bc, 0xfb828ac7), TOBN(0x6439be91, 0x9d972b29),
+ TOBN(0x4bf3b4b0, 0x43a2fbad), TOBN(0x39e6dadf, 0x82b5e840),
+ TOBN(0x4f716408, 0x6397bd4c), TOBN(0x0f7de568, 0x7f1eeccb),
+ TOBN(0x5865c5a1, 0xd2ffbfc1), TOBN(0xf74211fa, 0x4ccb6451),
+ TOBN(0x66368a88, 0xc0b32558), TOBN(0x5b539dc2, 0x9ad7812e),
+ TOBN(0x579483d0, 0x2f3af6f6), TOBN(0x52132078, 0x99934ece),
+ TOBN(0x50b9650f, 0xdcc9e983), TOBN(0xca989ec9, 0xaee42b8a),
+ TOBN(0x6a44c829, 0xd6f62f99), TOBN(0x8f06a309, 0x4c2a7c0c),
+ TOBN(0x4ea2b3a0, 0x98a0cb0a), TOBN(0x5c547b70, 0xbeee8364),
+ TOBN(0x461d40e1, 0x682afe11), TOBN(0x9e0fc77a, 0x7b41c0a8),
+ TOBN(0x79e4aefd, 0xe20d5d36), TOBN(0x2916e520, 0x32dd9f63),
+ TOBN(0xf59e52e8, 0x3f883faf), TOBN(0x396f9639, 0x2b868d35),
+ TOBN(0xc902a9df, 0x4ca19881), TOBN(0x0fc96822, 0xdb2401a6),
+ TOBN(0x41237587, 0x66f1c68d), TOBN(0x10fc6de3, 0xfb476c0d),
+ TOBN(0xf8b6b579, 0x841f5d90), TOBN(0x2ba8446c, 0xfa24f44a),
+ TOBN(0xa237b920, 0xef4a9975), TOBN(0x60bb6004, 0x2330435f),
+ TOBN(0xd6f4ab5a, 0xcfb7e7b5), TOBN(0xb2ac5097, 0x83435391),
+ TOBN(0xf036ee2f, 0xb0d1ea67), TOBN(0xae779a6a, 0x74c56230),
+ TOBN(0x59bff8c8, 0xab838ae6), TOBN(0xcd83ca99, 0x9b38e6f0),
+ TOBN(0xbb27bef5, 0xe33deed3), TOBN(0xe6356f6f, 0x001892a8),
+ TOBN(0xbf3be6cc, 0x7adfbd3e), TOBN(0xaecbc81c, 0x33d1ac9d),
+ TOBN(0xe4feb909, 0xe6e861dc), TOBN(0x90a247a4, 0x53f5f801),
+ TOBN(0x01c50acb, 0x27346e57), TOBN(0xce29242e, 0x461acc1b),
+ TOBN(0x04dd214a, 0x2f998a91), TOBN(0x271ee9b1, 0xd4baf27b),
+ TOBN(0x7e3027d1, 0xe8c26722), TOBN(0x21d1645c, 0x1820dce5),
+ TOBN(0x086f242c, 0x7501779c), TOBN(0xf0061407, 0xfa0e8009),
+ TOBN(0xf23ce477, 0x60187129), TOBN(0x05bbdedb, 0x0fde9bd0),
+ TOBN(0x682f4832, 0x25d98473), TOBN(0xf207fe85, 0x5c658427),
+ TOBN(0xb6fdd7ba, 0x4166ffa1), TOBN(0x0c314056, 0x9eed799d),
+ TOBN(0x0db8048f, 0x4107e28f), TOBN(0x74ed3871, 0x41216840),
+ TOBN(0x74489f8f, 0x56a3c06e), TOBN(0x1e1c005b, 0x12777134),
+ TOBN(0xdb332a73, 0xf37ec3c3), TOBN(0xc65259bd, 0xdd59eba0),
+ TOBN(0x2291709c, 0xdb4d3257), TOBN(0x9a793b25, 0xbd389390),
+ TOBN(0xf39fe34b, 0xe43756f0), TOBN(0x2f76bdce, 0x9afb56c9),
+ TOBN(0x9f37867a, 0x61208b27), TOBN(0xea1d4307, 0x089972c3),
+ TOBN(0x8c595330, 0x8bdf623a), TOBN(0x5f5accda, 0x8441fb7d),
+ TOBN(0xfafa9418, 0x32ddfd95), TOBN(0x6ad40c5a, 0x0fde9be7),
+ TOBN(0x43faba89, 0xaeca8709), TOBN(0xc64a7cf1, 0x2c248a9d),
+ TOBN(0x16620252, 0x72637a76), TOBN(0xaee1c791, 0x22b8d1bb),
+ TOBN(0xf0f798fd, 0x21a843b2), TOBN(0x56e4ed4d, 0x8d005cb1),
+ TOBN(0x355f7780, 0x1f0d8abe), TOBN(0x197b04cf, 0x34522326),
+ TOBN(0x41f9b31f, 0xfd42c13f), TOBN(0x5ef7feb2, 0xb40f933d),
+ TOBN(0x27326f42, 0x5d60bad4), TOBN(0x027ecdb2, 0x8c92cf89),
+ TOBN(0x04aae4d1, 0x4e3352fe), TOBN(0x08414d2f, 0x73591b90),
+ TOBN(0x5ed6124e, 0xb7da7d60), TOBN(0xb985b931, 0x4d13d4ec),
+ TOBN(0xa592d3ab, 0x96bf36f9), TOBN(0x012dbed5, 0xbbdf51df),
+ TOBN(0xa57963c0, 0xdf6c177d), TOBN(0x010ec869, 0x87ca29cf),
+ TOBN(0xba1700f6, 0xbf926dff), TOBN(0x7c9fdbd1, 0xf4bf6bc2),
+ TOBN(0xdc18dc8f, 0x64da11f5), TOBN(0xa6074b7a, 0xd938ae75),
+ TOBN(0x14270066, 0xe84f44a4), TOBN(0x99998d38, 0xd27b954e),
+ TOBN(0xc1be8ab2, 0xb4f38e9a), TOBN(0x8bb55bbf, 0x15c01016),
+ TOBN(0xf73472b4, 0x0ea2ab30), TOBN(0xd365a340, 0xf73d68dd),
+ TOBN(0xc01a7168, 0x19c2e1eb), TOBN(0x32f49e37, 0x34061719),
+ TOBN(0xb73c57f1, 0x01d8b4d6), TOBN(0x03c8423c, 0x26b47700),
+ TOBN(0x321d0bc8, 0xa4d8826a), TOBN(0x6004213c, 0x4bc0e638),
+ TOBN(0xf78c64a1, 0xc1c06681), TOBN(0x16e0a16f, 0xef018e50),
+ TOBN(0x31cbdf91, 0xdb42b2b3), TOBN(0xf8f4ffce, 0xe0d36f58),
+ TOBN(0xcdcc71cd, 0x4cc5e3e0), TOBN(0xd55c7cfa, 0xa129e3e0),
+ TOBN(0xccdb6ba0, 0x0fb2cbf1), TOBN(0x6aba0005, 0xc4bce3cb),
+ TOBN(0x501cdb30, 0xd232cfc4), TOBN(0x9ddcf12e, 0xd58a3cef),
+ TOBN(0x02d2cf9c, 0x87e09149), TOBN(0xdc5d7ec7, 0x2c976257),
+ TOBN(0x6447986e, 0x0b50d7dd), TOBN(0x88fdbaf7, 0x807f112a),
+ TOBN(0x58c9822a, 0xb00ae9f6), TOBN(0x6abfb950, 0x6d3d27e0),
+ TOBN(0xd0a74487, 0x8a429f4f), TOBN(0x0649712b, 0xdb516609),
+ TOBN(0xb826ba57, 0xe769b5df), TOBN(0x82335df2, 0x1fc7aaf2),
+ TOBN(0x2389f067, 0x5c93d995), TOBN(0x59ac367a, 0x68677be6),
+ TOBN(0xa77985ff, 0x21d9951b), TOBN(0x038956fb, 0x85011cce),
+ TOBN(0x608e48cb, 0xbb734e37), TOBN(0xc08c0bf2, 0x2be5b26f),
+ TOBN(0x17bbdd3b, 0xf9b1a0d9), TOBN(0xeac7d898, 0x10483319),
+ TOBN(0xc95c4baf, 0xbc1a6dea), TOBN(0xfdd0e2bf, 0x172aafdb),
+ TOBN(0x40373cbc, 0x8235c41a), TOBN(0x14303f21, 0xfb6f41d5),
+ TOBN(0xba063621, 0x0408f237), TOBN(0xcad3b09a, 0xecd2d1ed),
+ TOBN(0x4667855a, 0x52abb6a2), TOBN(0xba9157dc, 0xaa8b417b),
+ TOBN(0xfe7f3507, 0x4f013efb), TOBN(0x1b112c4b, 0xaa38c4a2),
+ TOBN(0xa1406a60, 0x9ba64345), TOBN(0xe53cba33, 0x6993c80b),
+ TOBN(0x45466063, 0xded40d23), TOBN(0x3d5f1f4d, 0x54908e25),
+ TOBN(0x9ebefe62, 0x403c3c31), TOBN(0x274ea0b5, 0x0672a624),
+ TOBN(0xff818d99, 0x451d1b71), TOBN(0x80e82643, 0x8f79cf79),
+ TOBN(0xa165df13, 0x73ce37f5), TOBN(0xa744ef4f, 0xfe3a21fd),
+ TOBN(0x73f1e7f5, 0xcf551396), TOBN(0xc616898e, 0x868c676b),
+ TOBN(0x671c28c7, 0x8c442c36), TOBN(0xcfe5e558, 0x5e0a317d),
+ TOBN(0x1242d818, 0x7051f476), TOBN(0x56fad2a6, 0x14f03442),
+ TOBN(0x262068bc, 0x0a44d0f6), TOBN(0xdfa2cd6e, 0xce6edf4e),
+ TOBN(0x0f43813a, 0xd15d1517), TOBN(0x61214cb2, 0x377d44f5),
+ TOBN(0xd399aa29, 0xc639b35f), TOBN(0x42136d71, 0x54c51c19),
+ TOBN(0x9774711b, 0x08417221), TOBN(0x0a5546b3, 0x52545a57),
+ TOBN(0x80624c41, 0x1150582d), TOBN(0x9ec5c418, 0xfbc555bc),
+ TOBN(0x2c87dcad, 0x771849f1), TOBN(0xb0c932c5, 0x01d7bf6f),
+ TOBN(0x6aa5cd3e, 0x89116eb2), TOBN(0xd378c25a, 0x51ca7bd3),
+ TOBN(0xc612a0da, 0x9e6e3e31), TOBN(0x0417a54d, 0xb68ad5d0),
+ TOBN(0x00451e4a, 0x22c6edb8), TOBN(0x9fbfe019, 0xb42827ce),
+ TOBN(0x2fa92505, 0xba9384a2), TOBN(0x21b8596e, 0x64ad69c1),
+ TOBN(0x8f4fcc49, 0x983b35a6), TOBN(0xde093760, 0x72754672),
+ TOBN(0x2f14ccc8, 0xf7bffe6d), TOBN(0x27566bff, 0x5d94263d),
+ TOBN(0xb5b4e9c6, 0x2df3ec30), TOBN(0x94f1d7d5, 0x3e6ea6ba),
+ TOBN(0x97b7851a, 0xaaca5e9b), TOBN(0x518aa521, 0x56713b97),
+ TOBN(0x3357e8c7, 0x150a61f6), TOBN(0x7842e7e2, 0xec2c2b69),
+ TOBN(0x8dffaf65, 0x6868a548), TOBN(0xd963bd82, 0xe068fc81),
+ TOBN(0x64da5c8b, 0x65917733), TOBN(0x927090ff, 0x7b247328),
+ },
+ {
+ TOBN(0x214bc9a7, 0xd298c241), TOBN(0xe3b697ba, 0x56807cfd),
+ TOBN(0xef1c7802, 0x4564eadb), TOBN(0xdde8cdcf, 0xb48149c5),
+ TOBN(0x946bf0a7, 0x5a4d2604), TOBN(0x27154d7f, 0x6c1538af),
+ TOBN(0x95cc9230, 0xde5b1fcc), TOBN(0xd88519e9, 0x66864f82),
+ TOBN(0xb828dd1a, 0x7cb1282c), TOBN(0xa08d7626, 0xbe46973a),
+ TOBN(0x6baf8d40, 0xe708d6b2), TOBN(0x72571fa1, 0x4daeb3f3),
+ TOBN(0x85b1732f, 0xf22dfd98), TOBN(0x87ab01a7, 0x0087108d),
+ TOBN(0xaaaafea8, 0x5988207a), TOBN(0xccc832f8, 0x69f00755),
+ TOBN(0x964d950e, 0x36ff3bf0), TOBN(0x8ad20f6f, 0xf0b34638),
+ TOBN(0x4d9177b3, 0xb5d7585f), TOBN(0xcf839760, 0xef3f019f),
+ TOBN(0x582fc5b3, 0x8288c545), TOBN(0x2f8e4e9b, 0x13116bd1),
+ TOBN(0xf91e1b2f, 0x332120ef), TOBN(0xcf568724, 0x2a17dd23),
+ TOBN(0x488f1185, 0xca8d9d1a), TOBN(0xadf2c77d, 0xd987ded2),
+ TOBN(0x5f3039f0, 0x60c46124), TOBN(0xe5d70b75, 0x71e095f4),
+ TOBN(0x82d58650, 0x6260e70f), TOBN(0x39d75ea7, 0xf750d105),
+ TOBN(0x8cf3d0b1, 0x75bac364), TOBN(0xf3a7564d, 0x21d01329),
+ TOBN(0x182f04cd, 0x2f52d2a7), TOBN(0x4fde149a, 0xe2df565a),
+ TOBN(0xb80c5eec, 0xa79fb2f7), TOBN(0xab491d7b, 0x22ddc897),
+ TOBN(0x99d76c18, 0xc6312c7f), TOBN(0xca0d5f3d, 0x6aa41a57),
+ TOBN(0x71207325, 0xd15363a0), TOBN(0xe82aa265, 0xbeb252c2),
+ TOBN(0x94ab4700, 0xec3128c2), TOBN(0x6c76d862, 0x8e383f49),
+ TOBN(0xdc36b150, 0xc03024eb), TOBN(0xfb439477, 0x53daac69),
+ TOBN(0xfc68764a, 0x8dc79623), TOBN(0x5b86995d, 0xb440fbb2),
+ TOBN(0xd66879bf, 0xccc5ee0d), TOBN(0x05228942, 0x95aa8bd3),
+ TOBN(0xb51a40a5, 0x1e6a75c1), TOBN(0x24327c76, 0x0ea7d817),
+ TOBN(0x06630182, 0x07774597), TOBN(0xd6fdbec3, 0x97fa7164),
+ TOBN(0x20c99dfb, 0x13c90f48), TOBN(0xd6ac5273, 0x686ef263),
+ TOBN(0xc6a50bdc, 0xfef64eeb), TOBN(0xcd87b281, 0x86fdfc32),
+ TOBN(0xb24aa43e, 0x3fcd3efc), TOBN(0xdd26c034, 0xb8088e9a),
+ TOBN(0xa5ef4dc9, 0xbd3d46ea), TOBN(0xa2f99d58, 0x8a4c6a6f),
+ TOBN(0xddabd355, 0x2f1da46c), TOBN(0x72c3f8ce, 0x1afacdd1),
+ TOBN(0xd90c4eee, 0x92d40578), TOBN(0xd28bb41f, 0xca623b94),
+ TOBN(0x50fc0711, 0x745edc11), TOBN(0x9dd9ad7d, 0x3dc87558),
+ TOBN(0xce6931fb, 0xb49d1e64), TOBN(0x6c77a0a2, 0xc98bd0f9),
+ TOBN(0x62b9a629, 0x6baf7cb1), TOBN(0xcf065f91, 0xccf72d22),
+ TOBN(0x7203cce9, 0x79639071), TOBN(0x09ae4885, 0xf9cb732f),
+ TOBN(0x5e7c3bec, 0xee8314f3), TOBN(0x1c068aed, 0xdbea298f),
+ TOBN(0x08d381f1, 0x7c80acec), TOBN(0x03b56be8, 0xe330495b),
+ TOBN(0xaeffb8f2, 0x9222882d), TOBN(0x95ff38f6, 0xc4af8bf7),
+ TOBN(0x50e32d35, 0x1fc57d8c), TOBN(0x6635be52, 0x17b444f0),
+ TOBN(0x04d15276, 0xa5177900), TOBN(0x4e1dbb47, 0xf6858752),
+ TOBN(0x5b475622, 0xc615796c), TOBN(0xa6fa0387, 0x691867bf),
+ TOBN(0xed7f5d56, 0x2844c6d0), TOBN(0xc633cf9b, 0x03a2477d),
+ TOBN(0xf6be5c40, 0x2d3721d6), TOBN(0xaf312eb7, 0xe9fd68e6),
+ TOBN(0x242792d2, 0xe7417ce1), TOBN(0xff42bc71, 0x970ee7f5),
+ TOBN(0x1ff4dc6d, 0x5c67a41e), TOBN(0x77709b7b, 0x20882a58),
+ TOBN(0x3554731d, 0xbe217f2c), TOBN(0x2af2a8cd, 0x5bb72177),
+ TOBN(0x58eee769, 0x591dd059), TOBN(0xbb2930c9, 0x4bba6477),
+ TOBN(0x863ee047, 0x7d930cfc), TOBN(0x4c262ad1, 0x396fd1f4),
+ TOBN(0xf4765bc8, 0x039af7e1), TOBN(0x2519834b, 0x5ba104f6),
+ TOBN(0x7cd61b4c, 0xd105f961), TOBN(0xa5415da5, 0xd63bca54),
+ TOBN(0x778280a0, 0x88a1f17c), TOBN(0xc4968949, 0x2329512c),
+ TOBN(0x174a9126, 0xcecdaa7a), TOBN(0xfc8c7e0e, 0x0b13247b),
+ TOBN(0x29c110d2, 0x3484c1c4), TOBN(0xf8eb8757, 0x831dfc3b),
+ TOBN(0x022f0212, 0xc0067452), TOBN(0x3f6f69ee, 0x7b9b926c),
+ TOBN(0x09032da0, 0xef42daf4), TOBN(0x79f00ade, 0x83f80de4),
+ TOBN(0x6210db71, 0x81236c97), TOBN(0x74f7685b, 0x3ee0781f),
+ TOBN(0x4df7da7b, 0xa3e41372), TOBN(0x2aae38b1, 0xb1a1553e),
+ TOBN(0x1688e222, 0xf6dd9d1b), TOBN(0x57695448, 0x5b8b6487),
+ TOBN(0x478d2127, 0x4b2edeaa), TOBN(0xb2818fa5, 0x1e85956a),
+ TOBN(0x1e6addda, 0xf176f2c0), TOBN(0x01ca4604, 0xe2572658),
+ TOBN(0x0a404ded, 0x85342ffb), TOBN(0x8cf60f96, 0x441838d6),
+ TOBN(0x9bbc691c, 0xc9071c4a), TOBN(0xfd588744, 0x34442803),
+ TOBN(0x97101c85, 0x809c0d81), TOBN(0xa7fb754c, 0x8c456f7f),
+ TOBN(0xc95f3c5c, 0xd51805e1), TOBN(0xab4ccd39, 0xb299dca8),
+ TOBN(0x3e03d20b, 0x47eaf500), TOBN(0xfa3165c1, 0xd7b80893),
+ TOBN(0x005e8b54, 0xe160e552), TOBN(0xdc4972ba, 0x9019d11f),
+ TOBN(0x21a6972e, 0x0c9a4a7a), TOBN(0xa52c258f, 0x37840fd7),
+ TOBN(0xf8559ff4, 0xc1e99d81), TOBN(0x08e1a7d6, 0xa3c617c0),
+ TOBN(0xb398fd43, 0x248c6ba7), TOBN(0x6ffedd91, 0xd1283794),
+ TOBN(0x8a6a59d2, 0xd629d208), TOBN(0xa9d141d5, 0x3490530e),
+ TOBN(0x42f6fc18, 0x38505989), TOBN(0x09bf250d, 0x479d94ee),
+ TOBN(0x223ad3b1, 0xb3822790), TOBN(0x6c5926c0, 0x93b8971c),
+ TOBN(0x609efc7e, 0x75f7fa62), TOBN(0x45d66a6d, 0x1ec2d989),
+ TOBN(0x4422d663, 0x987d2792), TOBN(0x4a73caad, 0x3eb31d2b),
+ TOBN(0xf06c2ac1, 0xa32cb9e6), TOBN(0xd9445c5f, 0x91aeba84),
+ TOBN(0x6af7a1d5, 0xaf71013f), TOBN(0xe68216e5, 0x0bedc946),
+ TOBN(0xf4cba30b, 0xd27370a0), TOBN(0x7981afbf, 0x870421cc),
+ TOBN(0x02496a67, 0x9449f0e1), TOBN(0x86cfc4be, 0x0a47edae),
+ TOBN(0x3073c936, 0xb1feca22), TOBN(0xf5694612, 0x03f8f8fb),
+ TOBN(0xd063b723, 0x901515ea), TOBN(0x4c6c77a5, 0x749cf038),
+ TOBN(0x6361e360, 0xab9e5059), TOBN(0x596cf171, 0xa76a37c0),
+ TOBN(0x800f53fa, 0x6530ae7a), TOBN(0x0f5e631e, 0x0792a7a6),
+ TOBN(0x5cc29c24, 0xefdb81c9), TOBN(0xa269e868, 0x3f9c40ba),
+ TOBN(0xec14f9e1, 0x2cb7191e), TOBN(0x78ea1bd8, 0xe5b08ea6),
+ TOBN(0x3c65aa9b, 0x46332bb9), TOBN(0x84cc22b3, 0xbf80ce25),
+ TOBN(0x0098e9e9, 0xd49d5bf1), TOBN(0xcd4ec1c6, 0x19087da4),
+ TOBN(0x3c9d07c5, 0xaef6e357), TOBN(0x839a0268, 0x9f8f64b8),
+ TOBN(0xc5e9eb62, 0xc6d8607f), TOBN(0x759689f5, 0x6aa995e4),
+ TOBN(0x70464669, 0xbbb48317), TOBN(0x921474bf, 0xe402417d),
+ TOBN(0xcabe135b, 0x2a354c8c), TOBN(0xd51e52d2, 0x812fa4b5),
+ TOBN(0xec741096, 0x53311fe8), TOBN(0x4f774535, 0xb864514b),
+ TOBN(0xbcadd671, 0x5bde48f8), TOBN(0xc9703873, 0x2189bc7d),
+ TOBN(0x5d45299e, 0xc709ee8a), TOBN(0xd1287ee2, 0x845aaff8),
+ TOBN(0x7d1f8874, 0xdb1dbf1f), TOBN(0xea46588b, 0x990c88d6),
+ TOBN(0x60ba649a, 0x84368313), TOBN(0xd5fdcbce, 0x60d543ae),
+ TOBN(0x90b46d43, 0x810d5ab0), TOBN(0x6739d8f9, 0x04d7e5cc),
+ TOBN(0x021c1a58, 0x0d337c33), TOBN(0x00a61162, 0x68e67c40),
+ TOBN(0x95ef413b, 0x379f0a1f), TOBN(0xfe126605, 0xe9e2ab95),
+ TOBN(0x67578b85, 0x2f5f199c), TOBN(0xf5c00329, 0x2cb84913),
+ TOBN(0xf7956430, 0x37577dd8), TOBN(0x83b82af4, 0x29c5fe88),
+ TOBN(0x9c1bea26, 0xcdbdc132), TOBN(0x589fa086, 0x9c04339e),
+ TOBN(0x033e9538, 0xb13799df), TOBN(0x85fa8b21, 0xd295d034),
+ TOBN(0xdf17f73f, 0xbd9ddcca), TOBN(0xf32bd122, 0xddb66334),
+ TOBN(0x55ef88a7, 0x858b044c), TOBN(0x1f0d69c2, 0x5aa9e397),
+ TOBN(0x55fd9cc3, 0x40d85559), TOBN(0xc774df72, 0x7785ddb2),
+ TOBN(0x5dcce9f6, 0xd3bd2e1c), TOBN(0xeb30da20, 0xa85dfed0),
+ TOBN(0x5ed7f5bb, 0xd3ed09c4), TOBN(0x7d42a35c, 0x82a9c1bd),
+ TOBN(0xcf3de995, 0x9890272d), TOBN(0x75f3432a, 0x3e713a10),
+ TOBN(0x5e13479f, 0xe28227b8), TOBN(0xb8561ea9, 0xfefacdc8),
+ TOBN(0xa6a297a0, 0x8332aafd), TOBN(0x9b0d8bb5, 0x73809b62),
+ TOBN(0xd2fa1cfd, 0x0c63036f), TOBN(0x7a16eb55, 0xbd64bda8),
+ TOBN(0x3f5cf5f6, 0x78e62ddc), TOBN(0x2267c454, 0x07fd752b),
+ TOBN(0x5e361b6b, 0x5e437bbe), TOBN(0x95c59501, 0x8354e075),
+ TOBN(0xec725f85, 0xf2b254d9), TOBN(0x844b617d, 0x2cb52b4e),
+ TOBN(0xed8554f5, 0xcf425fb5), TOBN(0xab67703e, 0x2af9f312),
+ TOBN(0x4cc34ec1, 0x3cf48283), TOBN(0xb09daa25, 0x9c8a705e),
+ TOBN(0xd1e9d0d0, 0x5b7d4f84), TOBN(0x4df6ef64, 0xdb38929d),
+ TOBN(0xe16b0763, 0xaa21ba46), TOBN(0xc6b1d178, 0xa293f8fb),
+ TOBN(0x0ff5b602, 0xd520aabf), TOBN(0x94d671bd, 0xc339397a),
+ TOBN(0x7c7d98cf, 0x4f5792fa), TOBN(0x7c5e0d67, 0x11215261),
+ TOBN(0x9b19a631, 0xa7c5a6d4), TOBN(0xc8511a62, 0x7a45274d),
+ TOBN(0x0c16621c, 0xa5a60d99), TOBN(0xf7fbab88, 0xcf5e48cb),
+ TOBN(0xab1e6ca2, 0xf7ddee08), TOBN(0x83bd08ce, 0xe7867f3c),
+ TOBN(0xf7e48e8a, 0x2ac13e27), TOBN(0x4494f6df, 0x4eb1a9f5),
+ TOBN(0xedbf84eb, 0x981f0a62), TOBN(0x49badc32, 0x536438f0),
+ TOBN(0x50bea541, 0x004f7571), TOBN(0xbac67d10, 0xdf1c94ee),
+ TOBN(0x253d73a1, 0xb727bc31), TOBN(0xb3d01cf2, 0x30686e28),
+ TOBN(0x51b77b1b, 0x55fd0b8b), TOBN(0xa099d183, 0xfeec3173),
+ TOBN(0x202b1fb7, 0x670e72b7), TOBN(0xadc88b33, 0xa8e1635f),
+ TOBN(0x34e8216a, 0xf989d905), TOBN(0xc2e68d20, 0x29b58d01),
+ TOBN(0x11f81c92, 0x6fe55a93), TOBN(0x15f1462a, 0x8f296f40),
+ TOBN(0x1915d375, 0xea3d62f2), TOBN(0xa17765a3, 0x01c8977d),
+ TOBN(0x7559710a, 0xe47b26f6), TOBN(0xe0bd29c8, 0x535077a5),
+ TOBN(0x615f976d, 0x08d84858), TOBN(0x370dfe85, 0x69ced5c1),
+ TOBN(0xbbc7503c, 0xa734fa56), TOBN(0xfbb9f1ec, 0x91ac4574),
+ TOBN(0x95d7ec53, 0x060dd7ef), TOBN(0xeef2dacd, 0x6e657979),
+ TOBN(0x54511af3, 0xe2a08235), TOBN(0x1e324aa4, 0x1f4aea3d),
+ TOBN(0x550e7e71, 0xe6e67671), TOBN(0xbccd5190, 0xbf52faf7),
+ TOBN(0xf880d316, 0x223cc62a), TOBN(0x0d402c7e, 0x2b32eb5d),
+ TOBN(0xa40bc039, 0x306a5a3b), TOBN(0x4e0a41fd, 0x96783a1b),
+ TOBN(0xa1e8d39a, 0x0253cdd4), TOBN(0x6480be26, 0xc7388638),
+ TOBN(0xee365e1d, 0x2285f382), TOBN(0x188d8d8f, 0xec0b5c36),
+ TOBN(0x34ef1a48, 0x1f0f4d82), TOBN(0x1a8f43e1, 0xa487d29a),
+ TOBN(0x8168226d, 0x77aefb3a), TOBN(0xf69a751e, 0x1e72c253),
+ TOBN(0x8e04359a, 0xe9594df1), TOBN(0x475ffd7d, 0xd14c0467),
+ TOBN(0xb5a2c2b1, 0x3844e95c), TOBN(0x85caf647, 0xdd12ef94),
+ TOBN(0x1ecd2a9f, 0xf1063d00), TOBN(0x1dd2e229, 0x23843311),
+ TOBN(0x38f0e09d, 0x73d17244), TOBN(0x3ede7746, 0x8fc653f1),
+ TOBN(0xae4459f5, 0xdc20e21c), TOBN(0x00db2ffa, 0x6a8599ea),
+ TOBN(0x11682c39, 0x30cfd905), TOBN(0x4934d074, 0xa5c112a6),
+ TOBN(0xbdf063c5, 0x568bfe95), TOBN(0x779a440a, 0x016c441a),
+ TOBN(0x0c23f218, 0x97d6fbdc), TOBN(0xd3a5cd87, 0xe0776aac),
+ TOBN(0xcee37f72, 0xd712e8db), TOBN(0xfb28c70d, 0x26f74e8d),
+ TOBN(0xffe0c728, 0xb61301a0), TOBN(0xa6282168, 0xd3724354),
+ TOBN(0x7ff4cb00, 0x768ffedc), TOBN(0xc51b3088, 0x03b02de9),
+ TOBN(0xa5a8147c, 0x3902dda5), TOBN(0x35d2f706, 0xfe6973b4),
+ TOBN(0x5ac2efcf, 0xc257457e), TOBN(0x933f48d4, 0x8700611b),
+ TOBN(0xc365af88, 0x4912beb2), TOBN(0x7f5a4de6, 0x162edf94),
+ TOBN(0xc646ba7c, 0x0c32f34b), TOBN(0x632c6af3, 0xb2091074),
+ TOBN(0x58d4f2e3, 0x753e43a9), TOBN(0x70e1d217, 0x24d4e23f),
+ TOBN(0xb24bf729, 0xafede6a6), TOBN(0x7f4a94d8, 0x710c8b60),
+ TOBN(0xaad90a96, 0x8d4faa6a), TOBN(0xd9ed0b32, 0xb066b690),
+ TOBN(0x52fcd37b, 0x78b6dbfd), TOBN(0x0b64615e, 0x8bd2b431),
+ TOBN(0x228e2048, 0xcfb9fad5), TOBN(0xbeaa386d, 0x240b76bd),
+ TOBN(0x2d6681c8, 0x90dad7bc), TOBN(0x3e553fc3, 0x06d38f5e),
+ TOBN(0xf27cdb9b, 0x9d5f9750), TOBN(0x3e85c52a, 0xd28c5b0e),
+ TOBN(0x190795af, 0x5247c39b), TOBN(0x547831eb, 0xbddd6828),
+ TOBN(0xf327a227, 0x4a82f424), TOBN(0x36919c78, 0x7e47f89d),
+ TOBN(0xe4783919, 0x43c7392c), TOBN(0xf101b9aa, 0x2316fefe),
+ TOBN(0xbcdc9e9c, 0x1c5009d2), TOBN(0xfb55ea13, 0x9cd18345),
+ TOBN(0xf5b5e231, 0xa3ce77c7), TOBN(0xde6b4527, 0xd2f2cb3d),
+ TOBN(0x10f6a333, 0x9bb26f5f), TOBN(0x1e85db8e, 0x044d85b6),
+ TOBN(0xc3697a08, 0x94197e54), TOBN(0x65e18cc0, 0xa7cb4ea8),
+ TOBN(0xa38c4f50, 0xa471fe6e), TOBN(0xf031747a, 0x2f13439c),
+ TOBN(0x53c4a6ba, 0xc007318b), TOBN(0xa8da3ee5, 0x1deccb3d),
+ TOBN(0x0555b31c, 0x558216b1), TOBN(0x90c7810c, 0x2f79e6c2),
+ TOBN(0x9b669f4d, 0xfe8eed3c), TOBN(0x70398ec8, 0xe0fac126),
+ TOBN(0xa96a449e, 0xf701b235), TOBN(0x0ceecdb3, 0xeb94f395),
+ TOBN(0x285fc368, 0xd0cb7431), TOBN(0x0d37bb52, 0x16a18c64),
+ TOBN(0x05110d38, 0xb880d2dd), TOBN(0xa60f177b, 0x65930d57),
+ TOBN(0x7da34a67, 0xf36235f5), TOBN(0x47f5e17c, 0x183816b9),
+ TOBN(0xc7664b57, 0xdb394af4), TOBN(0x39ba215d, 0x7036f789),
+ TOBN(0x46d2ca0e, 0x2f27b472), TOBN(0xc42647ee, 0xf73a84b7),
+ TOBN(0x44bc7545, 0x64488f1d), TOBN(0xaa922708, 0xf4cf85d5),
+ TOBN(0x721a01d5, 0x53e4df63), TOBN(0x649c0c51, 0x5db46ced),
+ TOBN(0x6bf0d64e, 0x3cffcb6c), TOBN(0xe3bf93fe, 0x50f71d96),
+ TOBN(0x75044558, 0xbcc194a0), TOBN(0x16ae3372, 0x6afdc554),
+ TOBN(0xbfc01adf, 0x5ca48f3f), TOBN(0x64352f06, 0xe22a9b84),
+ TOBN(0xcee54da1, 0xc1099e4a), TOBN(0xbbda54e8, 0xfa1b89c0),
+ TOBN(0x166a3df5, 0x6f6e55fb), TOBN(0x1ca44a24, 0x20176f88),
+ TOBN(0x936afd88, 0xdfb7b5ff), TOBN(0xe34c2437, 0x8611d4a0),
+ TOBN(0x7effbb75, 0x86142103), TOBN(0x6704ba1b, 0x1f34fc4d),
+ TOBN(0x7c2a468f, 0x10c1b122), TOBN(0x36b3a610, 0x8c6aace9),
+ TOBN(0xabfcc0a7, 0x75a0d050), TOBN(0x066f9197, 0x3ce33e32),
+ TOBN(0xce905ef4, 0x29fe09be), TOBN(0x89ee25ba, 0xa8376351),
+ TOBN(0x2a3ede22, 0xfd29dc76), TOBN(0x7fd32ed9, 0x36f17260),
+ TOBN(0x0cadcf68, 0x284b4126), TOBN(0x63422f08, 0xa7951fc8),
+ TOBN(0x562b24f4, 0x0807e199), TOBN(0xfe9ce5d1, 0x22ad4490),
+ TOBN(0xc2f51b10, 0x0db2b1b4), TOBN(0xeb3613ff, 0xe4541d0d),
+ TOBN(0xbd2c4a05, 0x2680813b), TOBN(0x527aa55d, 0x561b08d6),
+ TOBN(0xa9f8a40e, 0xa7205558), TOBN(0xe3eea56f, 0x243d0bec),
+ TOBN(0x7b853817, 0xa0ff58b3), TOBN(0xb67d3f65, 0x1a69e627),
+ TOBN(0x0b76bbb9, 0xa869b5d6), TOBN(0xa3afeb82, 0x546723ed),
+ TOBN(0x5f24416d, 0x3e554892), TOBN(0x8413b53d, 0x430e2a45),
+ TOBN(0x99c56aee, 0x9032a2a0), TOBN(0x09432bf6, 0xeec367b1),
+ TOBN(0x552850c6, 0xdaf0ecc1), TOBN(0x49ebce55, 0x5bc92048),
+ TOBN(0xdfb66ba6, 0x54811307), TOBN(0x1b84f797, 0x6f298597),
+ TOBN(0x79590481, 0x8d1d7a0d), TOBN(0xd9fabe03, 0x3a6fa556),
+ TOBN(0xa40f9c59, 0xba9e5d35), TOBN(0xcb1771c1, 0xf6247577),
+ TOBN(0x542a47ca, 0xe9a6312b), TOBN(0xa34b3560, 0x552dd8c5),
+ TOBN(0xfdf94de0, 0x0d794716), TOBN(0xd46124a9, 0x9c623094),
+ TOBN(0x56b7435d, 0x68afe8b4), TOBN(0x27f20540, 0x6c0d8ea1),
+ TOBN(0x12b77e14, 0x73186898), TOBN(0xdbc3dd46, 0x7479490f),
+ TOBN(0x951a9842, 0xc03b0c05), TOBN(0x8b1b3bb3, 0x7921bc96),
+ TOBN(0xa573b346, 0x2b202e0a), TOBN(0x77e4665d, 0x47254d56),
+ TOBN(0x08b70dfc, 0xd23e3984), TOBN(0xab86e8bc, 0xebd14236),
+ TOBN(0xaa3e07f8, 0x57114ba7), TOBN(0x5ac71689, 0xab0ef4f2),
+ TOBN(0x88fca384, 0x0139d9af), TOBN(0x72733f88, 0x76644af0),
+ TOBN(0xf122f72a, 0x65d74f4a), TOBN(0x13931577, 0xa5626c7a),
+ TOBN(0xd5b5d9eb, 0x70f8d5a4), TOBN(0x375adde7, 0xd7bbb228),
+ TOBN(0x31e88b86, 0x0c1c0b32), TOBN(0xd1f568c4, 0x173edbaa),
+ TOBN(0x1592fc83, 0x5459df02), TOBN(0x2beac0fb, 0x0fcd9a7e),
+ TOBN(0xb0a6fdb8, 0x1b473b0a), TOBN(0xe3224c6f, 0x0fe8fc48),
+ TOBN(0x680bd00e, 0xe87edf5b), TOBN(0x30385f02, 0x20e77cf5),
+ TOBN(0xe9ab98c0, 0x4d42d1b2), TOBN(0x72d191d2, 0xd3816d77),
+ TOBN(0x1564daca, 0x0917d9e5), TOBN(0x394eab59, 0x1f8fed7f),
+ TOBN(0xa209aa8d, 0x7fbb3896), TOBN(0x5564f3b9, 0xbe6ac98e),
+ TOBN(0xead21d05, 0xd73654ef), TOBN(0x68d1a9c4, 0x13d78d74),
+ TOBN(0x61e01708, 0x6d4973a0), TOBN(0x83da3500, 0x46e6d32a),
+ TOBN(0x6a3dfca4, 0x68ae0118), TOBN(0xa1b9a4c9, 0xd02da069),
+ TOBN(0x0b2ff9c7, 0xebab8302), TOBN(0x98af07c3, 0x944ba436),
+ TOBN(0x85997326, 0x995f0f9f), TOBN(0x467fade0, 0x71b58bc6),
+ TOBN(0x47e4495a, 0xbd625a2b), TOBN(0xfdd2d01d, 0x33c3b8cd),
+ TOBN(0x2c38ae28, 0xc693f9fa), TOBN(0x48622329, 0x348f7999),
+ TOBN(0x97bf738e, 0x2161f583), TOBN(0x15ee2fa7, 0x565e8cc9),
+ TOBN(0xa1a5c845, 0x5777e189), TOBN(0xcc10bee0, 0x456f2829),
+ TOBN(0x8ad95c56, 0xda762bd5), TOBN(0x152e2214, 0xe9d91da8),
+ TOBN(0x975b0e72, 0x7cb23c74), TOBN(0xfd5d7670, 0xa90c66df),
+ TOBN(0xb5b5b8ad, 0x225ffc53), TOBN(0xab6dff73, 0xfaded2ae),
+ TOBN(0xebd56781, 0x6f4cbe9d), TOBN(0x0ed8b249, 0x6a574bd7),
+ TOBN(0x41c246fe, 0x81a881fa), TOBN(0x91564805, 0xc3db9c70),
+ TOBN(0xd7c12b08, 0x5b862809), TOBN(0x1facd1f1, 0x55858d7b),
+ TOBN(0x7693747c, 0xaf09e92a), TOBN(0x3b69dcba, 0x189a425f),
+ TOBN(0x0be28e9f, 0x967365ef), TOBN(0x57300eb2, 0xe801f5c9),
+ TOBN(0x93b8ac6a, 0xd583352f), TOBN(0xa2cf1f89, 0xcd05b2b7),
+ TOBN(0x7c0c9b74, 0x4dcc40cc), TOBN(0xfee38c45, 0xada523fb),
+ TOBN(0xb49a4dec, 0x1099cc4d), TOBN(0x325c377f, 0x69f069c6),
+ TOBN(0xe12458ce, 0x476cc9ff), TOBN(0x580e0b6c, 0xc6d4cb63),
+ TOBN(0xd561c8b7, 0x9072289b), TOBN(0x0377f264, 0xa619e6da),
+ TOBN(0x26685362, 0x88e591a5), TOBN(0xa453a7bd, 0x7523ca2b),
+ TOBN(0x8a9536d2, 0xc1df4533), TOBN(0xc8e50f2f, 0xbe972f79),
+ TOBN(0xd433e50f, 0x6d3549cf), TOBN(0x6f33696f, 0xfacd665e),
+ TOBN(0x695bfdac, 0xce11fcb4), TOBN(0x810ee252, 0xaf7c9860),
+ TOBN(0x65450fe1, 0x7159bb2c), TOBN(0xf7dfbebe, 0x758b357b),
+ TOBN(0x2b057e74, 0xd69fea72), TOBN(0xd485717a, 0x92731745),
+ },
+ {
+ TOBN(0x896c42e8, 0xee36860c), TOBN(0xdaf04dfd, 0x4113c22d),
+ TOBN(0x1adbb7b7, 0x44104213), TOBN(0xe5fd5fa1, 0x1fd394ea),
+ TOBN(0x68235d94, 0x1a4e0551), TOBN(0x6772cfbe, 0x18d10151),
+ TOBN(0x276071e3, 0x09984523), TOBN(0xe4e879de, 0x5a56ba98),
+ TOBN(0xaaafafb0, 0x285b9491), TOBN(0x01a0be88, 0x1e4c705e),
+ TOBN(0xff1d4f5d, 0x2ad9caab), TOBN(0x6e349a4a, 0xc37a233f),
+ TOBN(0xcf1c1246, 0x4a1c6a16), TOBN(0xd99e6b66, 0x29383260),
+ TOBN(0xea3d4366, 0x5f6d5471), TOBN(0x36974d04, 0xff8cc89b),
+ TOBN(0xc26c49a1, 0xcfe89d80), TOBN(0xb42c026d, 0xda9c8371),
+ TOBN(0xca6c013a, 0xdad066d2), TOBN(0xfb8f7228, 0x56a4f3ee),
+ TOBN(0x08b579ec, 0xd850935b), TOBN(0x34c1a74c, 0xd631e1b3),
+ TOBN(0xcb5fe596, 0xac198534), TOBN(0x39ff21f6, 0xe1f24f25),
+ TOBN(0x27f29e14, 0x8f929057), TOBN(0x7a64ae06, 0xc0c853df),
+ TOBN(0x256cd183, 0x58e9c5ce), TOBN(0x9d9cce82, 0xded092a5),
+ TOBN(0xcc6e5979, 0x6e93b7c7), TOBN(0xe1e47092, 0x31bb9e27),
+ TOBN(0xb70b3083, 0xaa9e29a0), TOBN(0xbf181a75, 0x3785e644),
+ TOBN(0xf53f2c65, 0x8ead09f7), TOBN(0x1335e1d5, 0x9780d14d),
+ TOBN(0x69cc20e0, 0xcd1b66bc), TOBN(0x9b670a37, 0xbbe0bfc8),
+ TOBN(0xce53dc81, 0x28efbeed), TOBN(0x0c74e77c, 0x8326a6e5),
+ TOBN(0x3604e0d2, 0xb88e9a63), TOBN(0xbab38fca, 0x13dc2248),
+ TOBN(0x8ed6e8c8, 0x5c0a3f1e), TOBN(0xbcad2492, 0x7c87c37f),
+ TOBN(0xfdfb62bb, 0x9ee3b78d), TOBN(0xeba8e477, 0xcbceba46),
+ TOBN(0x37d38cb0, 0xeeaede4b), TOBN(0x0bc498e8, 0x7976deb6),
+ TOBN(0xb2944c04, 0x6b6147fb), TOBN(0x8b123f35, 0xf71f9609),
+ TOBN(0xa155dcc7, 0xde79dc24), TOBN(0xf1168a32, 0x558f69cd),
+ TOBN(0xbac21595, 0x0d1850df), TOBN(0x15c8295b, 0xb204c848),
+ TOBN(0xf661aa36, 0x7d8184ff), TOBN(0xc396228e, 0x30447bdb),
+ TOBN(0x11cd5143, 0xbde4a59e), TOBN(0xe3a26e3b, 0x6beab5e6),
+ TOBN(0xd3b3a13f, 0x1402b9d0), TOBN(0x573441c3, 0x2c7bc863),
+ TOBN(0x4b301ec4, 0x578c3e6e), TOBN(0xc26fc9c4, 0x0adaf57e),
+ TOBN(0x96e71bfd, 0x7493cea3), TOBN(0xd05d4b3f, 0x1af81456),
+ TOBN(0xdaca2a8a, 0x6a8c608f), TOBN(0x53ef07f6, 0x0725b276),
+ TOBN(0x07a5fbd2, 0x7824fc56), TOBN(0x34675218, 0x13289077),
+ TOBN(0x5bf69fd5, 0xe0c48349), TOBN(0xa613ddd3, 0xb6aa7875),
+ TOBN(0x7f78c19c, 0x5450d866), TOBN(0x46f4409c, 0x8f84a481),
+ TOBN(0x9f1d1928, 0x90fce239), TOBN(0x016c4168, 0xb2ce44b9),
+ TOBN(0xbae023f0, 0xc7435978), TOBN(0xb152c888, 0x20e30e19),
+ TOBN(0x9c241645, 0xe3fa6faf), TOBN(0x735d95c1, 0x84823e60),
+ TOBN(0x03197573, 0x03955317), TOBN(0x0b4b02a9, 0xf03b4995),
+ TOBN(0x076bf559, 0x70274600), TOBN(0x32c5cc53, 0xaaf57508),
+ TOBN(0xe8af6d1f, 0x60624129), TOBN(0xb7bc5d64, 0x9a5e2b5e),
+ TOBN(0x3814b048, 0x5f082d72), TOBN(0x76f267f2, 0xce19677a),
+ TOBN(0x626c630f, 0xb36eed93), TOBN(0x55230cd7, 0x3bf56803),
+ TOBN(0x78837949, 0xce2736a0), TOBN(0x0d792d60, 0xaa6c55f1),
+ TOBN(0x0318dbfd, 0xd5c7c5d2), TOBN(0xb38f8da7, 0x072b342d),
+ TOBN(0x3569bddc, 0x7b8de38a), TOBN(0xf25b5887, 0xa1c94842),
+ TOBN(0xb2d5b284, 0x2946ad60), TOBN(0x854f29ad, 0xe9d1707e),
+ TOBN(0xaa5159dc, 0x2c6a4509), TOBN(0x899f94c0, 0x57189837),
+ TOBN(0xcf6adc51, 0xf4a55b03), TOBN(0x261762de, 0x35e3b2d5),
+ TOBN(0x4cc43012, 0x04827b51), TOBN(0xcd22a113, 0xc6021442),
+ TOBN(0xce2fd61a, 0x247c9569), TOBN(0x59a50973, 0xd152beca),
+ TOBN(0x6c835a11, 0x63a716d4), TOBN(0xc26455ed, 0x187dedcf),
+ TOBN(0x27f536e0, 0x49ce89e7), TOBN(0x18908539, 0xcc890cb5),
+ TOBN(0x308909ab, 0xd83c2aa1), TOBN(0xecd3142b, 0x1ab73bd3),
+ TOBN(0x6a85bf59, 0xb3f5ab84), TOBN(0x3c320a68, 0xf2bea4c6),
+ TOBN(0xad8dc538, 0x6da4541f), TOBN(0xeaf34eb0, 0xb7c41186),
+ TOBN(0x1c780129, 0x977c97c4), TOBN(0x5ff9beeb, 0xc57eb9fa),
+ TOBN(0xa24d0524, 0xc822c478), TOBN(0xfd8eec2a, 0x461cd415),
+ TOBN(0xfbde194e, 0xf027458c), TOBN(0xb4ff5319, 0x1d1be115),
+ TOBN(0x63f874d9, 0x4866d6f4), TOBN(0x35c75015, 0xb21ad0c9),
+ TOBN(0xa6b5c9d6, 0x46ac49d2), TOBN(0x42c77c0b, 0x83137aa9),
+ TOBN(0x24d000fc, 0x68225a38), TOBN(0x0f63cfc8, 0x2fe1e907),
+ TOBN(0x22d1b01b, 0xc6441f95), TOBN(0x7d38f719, 0xec8e448f),
+ TOBN(0x9b33fa5f, 0x787fb1ba), TOBN(0x94dcfda1, 0x190158df),
+ TOBN(0xc47cb339, 0x5f6d4a09), TOBN(0x6b4f355c, 0xee52b826),
+ TOBN(0x3d100f5d, 0xf51b930a), TOBN(0xf4512fac, 0x9f668f69),
+ TOBN(0x546781d5, 0x206c4c74), TOBN(0xd021d4d4, 0xcb4d2e48),
+ TOBN(0x494a54c2, 0xca085c2d), TOBN(0xf1dbaca4, 0x520850a8),
+ TOBN(0x63c79326, 0x490a1aca), TOBN(0xcb64dd9c, 0x41526b02),
+ TOBN(0xbb772591, 0xa2979258), TOBN(0x3f582970, 0x48d97846),
+ TOBN(0xd66b70d1, 0x7c213ba7), TOBN(0xc28febb5, 0xe8a0ced4),
+ TOBN(0x6b911831, 0xc10338c1), TOBN(0x0d54e389, 0xbf0126f3),
+ TOBN(0x7048d460, 0x4af206ee), TOBN(0x786c88f6, 0x77e97cb9),
+ TOBN(0xd4375ae1, 0xac64802e), TOBN(0x469bcfe1, 0xd53ec11c),
+ TOBN(0xfc9b340d, 0x47062230), TOBN(0xe743bb57, 0xc5b4a3ac),
+ TOBN(0xfe00b4aa, 0x59ef45ac), TOBN(0x29a4ef23, 0x59edf188),
+ TOBN(0x40242efe, 0xb483689b), TOBN(0x2575d3f6, 0x513ac262),
+ TOBN(0xf30037c8, 0x0ca6db72), TOBN(0xc9fcce82, 0x98864be2),
+ TOBN(0x84a112ff, 0x0149362d), TOBN(0x95e57582, 0x1c4ae971),
+ TOBN(0x1fa4b1a8, 0x945cf86c), TOBN(0x4525a734, 0x0b024a2f),
+ TOBN(0xe76c8b62, 0x8f338360), TOBN(0x483ff593, 0x28edf32b),
+ TOBN(0x67e8e90a, 0x298b1aec), TOBN(0x9caab338, 0x736d9a21),
+ TOBN(0x5c09d2fd, 0x66892709), TOBN(0x2496b4dc, 0xb55a1d41),
+ TOBN(0x93f5fb1a, 0xe24a4394), TOBN(0x08c75049, 0x6fa8f6c1),
+ TOBN(0xcaead1c2, 0xc905d85f), TOBN(0xe9d7f790, 0x0733ae57),
+ TOBN(0x24c9a65c, 0xf07cdd94), TOBN(0x7389359c, 0xa4b55931),
+ TOBN(0xf58709b7, 0x367e45f7), TOBN(0x1f203067, 0xcb7e7adc),
+ TOBN(0x82444bff, 0xc7b72818), TOBN(0x07303b35, 0xbaac8033),
+ TOBN(0x1e1ee4e4, 0xd13b7ea1), TOBN(0xe6489b24, 0xe0e74180),
+ TOBN(0xa5f2c610, 0x7e70ef70), TOBN(0xa1655412, 0xbdd10894),
+ TOBN(0x555ebefb, 0x7af4194e), TOBN(0x533c1c3c, 0x8e89bd9c),
+ TOBN(0x735b9b57, 0x89895856), TOBN(0x15fb3cd2, 0x567f5c15),
+ TOBN(0x057fed45, 0x526f09fd), TOBN(0xe8a4f10c, 0x8128240a),
+ TOBN(0x9332efc4, 0xff2bfd8d), TOBN(0x214e77a0, 0xbd35aa31),
+ TOBN(0x32896d73, 0x14faa40e), TOBN(0x767867ec, 0x01e5f186),
+ TOBN(0xc9adf8f1, 0x17a1813e), TOBN(0xcb6cda78, 0x54741795),
+ TOBN(0xb7521b6d, 0x349d51aa), TOBN(0xf56b5a9e, 0xe3c7b8e9),
+ TOBN(0xc6f1e5c9, 0x32a096df), TOBN(0x083667c4, 0xa3635024),
+ TOBN(0x365ea135, 0x18087f2f), TOBN(0xf1b8eaac, 0xd136e45d),
+ TOBN(0xc8a0e484, 0x73aec989), TOBN(0xd75a324b, 0x142c9259),
+ TOBN(0xb7b4d001, 0x01dae185), TOBN(0x45434e0b, 0x9b7a94bc),
+ TOBN(0xf54339af, 0xfbd8cb0b), TOBN(0xdcc4569e, 0xe98ef49e),
+ TOBN(0x7789318a, 0x09a51299), TOBN(0x81b4d206, 0xb2b025d8),
+ TOBN(0xf64aa418, 0xfae85792), TOBN(0x3e50258f, 0xacd7baf7),
+ TOBN(0xdce84cdb, 0x2996864b), TOBN(0xa2e67089, 0x1f485fa4),
+ TOBN(0xb28b2bb6, 0x534c6a5a), TOBN(0x31a7ec6b, 0xc94b9d39),
+ TOBN(0x1d217766, 0xd6bc20da), TOBN(0x4acdb5ec, 0x86761190),
+ TOBN(0x68726328, 0x73701063), TOBN(0x4d24ee7c, 0x2128c29b),
+ TOBN(0xc072ebd3, 0xa19fd868), TOBN(0x612e481c, 0xdb8ddd3b),
+ TOBN(0xb4e1d754, 0x1a64d852), TOBN(0x00ef95ac, 0xc4c6c4ab),
+ TOBN(0x1536d2ed, 0xaa0a6c46), TOBN(0x61294086, 0x43774790),
+ TOBN(0x54af25e8, 0x343fda10), TOBN(0x9ff9d98d, 0xfd25d6f2),
+ TOBN(0x0746af7c, 0x468b8835), TOBN(0x977a31cb, 0x730ecea7),
+ TOBN(0xa5096b80, 0xc2cf4a81), TOBN(0xaa986833, 0x6458c37a),
+ TOBN(0x6af29bf3, 0xa6bd9d34), TOBN(0x6a62fe9b, 0x33c5d854),
+ TOBN(0x50e6c304, 0xb7133b5e), TOBN(0x04b60159, 0x7d6e6848),
+ TOBN(0x4cd296df, 0x5579bea4), TOBN(0x10e35ac8, 0x5ceedaf1),
+ TOBN(0x04c4c5fd, 0xe3bcc5b1), TOBN(0x95f9ee8a, 0x89412cf9),
+ TOBN(0x2c9459ee, 0x82b6eb0f), TOBN(0x2e845765, 0x95c2aadd),
+ TOBN(0x774a84ae, 0xd327fcfe), TOBN(0xd8c93722, 0x0368d476),
+ TOBN(0x0dbd5748, 0xf83e8a3b), TOBN(0xa579aa96, 0x8d2495f3),
+ TOBN(0x535996a0, 0xae496e9b), TOBN(0x07afbfe9, 0xb7f9bcc2),
+ TOBN(0x3ac1dc6d, 0x5b7bd293), TOBN(0x3b592cff, 0x7022323d),
+ TOBN(0xba0deb98, 0x9c0a3e76), TOBN(0x18e78e9f, 0x4b197acb),
+ TOBN(0x211cde10, 0x296c36ef), TOBN(0x7ee89672, 0x82c4da77),
+ TOBN(0xb617d270, 0xa57836da), TOBN(0xf0cd9c31, 0x9cb7560b),
+ TOBN(0x01fdcbf7, 0xe455fe90), TOBN(0x3fb53cbb, 0x7e7334f3),
+ TOBN(0x781e2ea4, 0x4e7de4ec), TOBN(0x8adab3ad, 0x0b384fd0),
+ TOBN(0x129eee2f, 0x53d64829), TOBN(0x7a471e17, 0xa261492b),
+ TOBN(0xe4f9adb9, 0xe4cb4a2c), TOBN(0x3d359f6f, 0x97ba2c2d),
+ TOBN(0x346c6786, 0x0aacd697), TOBN(0x92b444c3, 0x75c2f8a8),
+ TOBN(0xc79fa117, 0xd85df44e), TOBN(0x56782372, 0x398ddf31),
+ TOBN(0x60e690f2, 0xbbbab3b8), TOBN(0x4851f8ae, 0x8b04816b),
+ TOBN(0xc72046ab, 0x9c92e4d2), TOBN(0x518c74a1, 0x7cf3136b),
+ TOBN(0xff4eb50a, 0xf9877d4c), TOBN(0x14578d90, 0xa919cabb),
+ TOBN(0x8218f8c4, 0xac5eb2b6), TOBN(0xa3ccc547, 0x542016e4),
+ TOBN(0x025bf48e, 0x327f8349), TOBN(0xf3e97346, 0xf43cb641),
+ TOBN(0xdc2bafdf, 0x500f1085), TOBN(0x57167876, 0x2f063055),
+ TOBN(0x5bd914b9, 0x411925a6), TOBN(0x7c078d48, 0xa1123de5),
+ TOBN(0xee6bf835, 0x182b165d), TOBN(0xb11b5e5b, 0xba519727),
+ TOBN(0xe33ea76c, 0x1eea7b85), TOBN(0x2352b461, 0x92d4f85e),
+ TOBN(0xf101d334, 0xafe115bb), TOBN(0xfabc1294, 0x889175a3),
+ TOBN(0x7f6bcdc0, 0x5233f925), TOBN(0xe0a802db, 0xe77fec55),
+ TOBN(0xbdb47b75, 0x8069b659), TOBN(0x1c5e12de, 0xf98fbd74),
+ TOBN(0x869c58c6, 0x4b8457ee), TOBN(0xa5360f69, 0x4f7ea9f7),
+ TOBN(0xe576c09f, 0xf460b38f), TOBN(0x6b70d548, 0x22b7fb36),
+ TOBN(0x3fd237f1, 0x3bfae315), TOBN(0x33797852, 0xcbdff369),
+ TOBN(0x97df25f5, 0x25b516f9), TOBN(0x46f388f2, 0xba38ad2d),
+ TOBN(0x656c4658, 0x89d8ddbb), TOBN(0x8830b26e, 0x70f38ee8),
+ TOBN(0x4320fd5c, 0xde1212b0), TOBN(0xc34f30cf, 0xe4a2edb2),
+ TOBN(0xabb131a3, 0x56ab64b8), TOBN(0x7f77f0cc, 0xd99c5d26),
+ TOBN(0x66856a37, 0xbf981d94), TOBN(0x19e76d09, 0x738bd76e),
+ TOBN(0xe76c8ac3, 0x96238f39), TOBN(0xc0a482be, 0xa830b366),
+ TOBN(0xb7b8eaff, 0x0b4eb499), TOBN(0x8ecd83bc, 0x4bfb4865),
+ TOBN(0x971b2cb7, 0xa2f3776f), TOBN(0xb42176a4, 0xf4b88adf),
+ TOBN(0xb9617df5, 0xbe1fa446), TOBN(0x8b32d508, 0xcd031bd2),
+ TOBN(0x1c6bd47d, 0x53b618c0), TOBN(0xc424f46c, 0x6a227923),
+ TOBN(0x7303ffde, 0xdd92d964), TOBN(0xe9712878, 0x71b5abf2),
+ TOBN(0x8f48a632, 0xf815561d), TOBN(0x85f48ff5, 0xd3c055d1),
+ TOBN(0x222a1427, 0x7525684f), TOBN(0xd0d841a0, 0x67360cc3),
+ TOBN(0x4245a926, 0x0b9267c6), TOBN(0xc78913f1, 0xcf07f863),
+ TOBN(0xaa844c8e, 0x4d0d9e24), TOBN(0xa42ad522, 0x3d5f9017),
+ TOBN(0xbd371749, 0xa2c989d5), TOBN(0x928292df, 0xe1f5e78e),
+ TOBN(0x493b383e, 0x0a1ea6da), TOBN(0x5136fd8d, 0x13aee529),
+ TOBN(0x860c44b1, 0xf2c34a99), TOBN(0x3b00aca4, 0xbf5855ac),
+ TOBN(0xabf6aaa0, 0xfaaf37be), TOBN(0x65f43682, 0x2a53ec08),
+ TOBN(0x1d9a5801, 0xa11b12e1), TOBN(0x78a7ab2c, 0xe20ed475),
+ TOBN(0x0de1067e, 0x9a41e0d5), TOBN(0x30473f5f, 0x305023ea),
+ TOBN(0xdd3ae09d, 0x169c7d97), TOBN(0x5cd5baa4, 0xcfaef9cd),
+ TOBN(0x5cd7440b, 0x65a44803), TOBN(0xdc13966a, 0x47f364de),
+ TOBN(0x077b2be8, 0x2b8357c1), TOBN(0x0cb1b4c5, 0xe9d57c2a),
+ TOBN(0x7a4ceb32, 0x05ff363e), TOBN(0xf310fa4d, 0xca35a9ef),
+ TOBN(0xdbb7b352, 0xf97f68c6), TOBN(0x0c773b50, 0x0b02cf58),
+ TOBN(0xea2e4821, 0x3c1f96d9), TOBN(0xffb357b0, 0xeee01815),
+ TOBN(0xb9c924cd, 0xe0f28039), TOBN(0x0b36c95a, 0x46a3fbe4),
+ TOBN(0x1faaaea4, 0x5e46db6c), TOBN(0xcae575c3, 0x1928aaff),
+ TOBN(0x7f671302, 0xa70dab86), TOBN(0xfcbd12a9, 0x71c58cfc),
+ TOBN(0xcbef9acf, 0xbee0cb92), TOBN(0x573da0b9, 0xf8c1b583),
+ TOBN(0x4752fcfe, 0x0d41d550), TOBN(0xe7eec0e3, 0x2155cffe),
+ TOBN(0x0fc39fcb, 0x545ae248), TOBN(0x522cb8d1, 0x8065f44e),
+ TOBN(0x263c962a, 0x70cbb96c), TOBN(0xe034362a, 0xbcd124a9),
+ TOBN(0xf120db28, 0x3c2ae58d), TOBN(0xb9a38d49, 0xfef6d507),
+ TOBN(0xb1fd2a82, 0x1ff140fd), TOBN(0xbd162f30, 0x20aee7e0),
+ TOBN(0x4e17a5d4, 0xcb251949), TOBN(0x2aebcb83, 0x4f7e1c3d),
+ TOBN(0x608eb25f, 0x937b0527), TOBN(0xf42e1e47, 0xeb7d9997),
+ TOBN(0xeba699c4, 0xb8a53a29), TOBN(0x1f921c71, 0xe091b536),
+ TOBN(0xcce29e7b, 0x5b26bbd5), TOBN(0x7a8ef5ed, 0x3b61a680),
+ TOBN(0xe5ef8043, 0xba1f1c7e), TOBN(0x16ea8217, 0x18158dda),
+ TOBN(0x01778a2b, 0x599ff0f9), TOBN(0x68a923d7, 0x8104fc6b),
+ TOBN(0x5bfa44df, 0xda694ff3), TOBN(0x4f7199db, 0xf7667f12),
+ TOBN(0xc06d8ff6, 0xe46f2a79), TOBN(0x08b5dead, 0xe9f8131d),
+ TOBN(0x02519a59, 0xabb4ce7c), TOBN(0xc4f710bc, 0xb42aec3e),
+ TOBN(0x3d77b057, 0x78bde41a), TOBN(0x6474bf80, 0xb4186b5a),
+ TOBN(0x048b3f67, 0x88c65741), TOBN(0xc64519de, 0x03c7c154),
+ TOBN(0xdf073846, 0x0edfcc4f), TOBN(0x319aa737, 0x48f1aa6b),
+ TOBN(0x8b9f8a02, 0xca909f77), TOBN(0x90258139, 0x7580bfef),
+ TOBN(0xd8bfd3ca, 0xc0c22719), TOBN(0xc60209e4, 0xc9ca151e),
+ TOBN(0x7a744ab5, 0xd9a1a69c), TOBN(0x6de5048b, 0x14937f8f),
+ TOBN(0x171938d8, 0xe115ac04), TOBN(0x7df70940, 0x1c6b16d2),
+ TOBN(0xa6aeb663, 0x7f8e94e7), TOBN(0xc130388e, 0x2a2cf094),
+ TOBN(0x1850be84, 0x77f54e6e), TOBN(0x9f258a72, 0x65d60fe5),
+ TOBN(0xff7ff0c0, 0x6c9146d6), TOBN(0x039aaf90, 0xe63a830b),
+ TOBN(0x38f27a73, 0x9460342f), TOBN(0x4703148c, 0x3f795f8a),
+ TOBN(0x1bb5467b, 0x9681a97e), TOBN(0x00931ba5, 0xecaeb594),
+ TOBN(0xcdb6719d, 0x786f337c), TOBN(0xd9c01cd2, 0xe704397d),
+ TOBN(0x0f4a3f20, 0x555c2fef), TOBN(0x00452509, 0x7c0af223),
+ TOBN(0x54a58047, 0x84db8e76), TOBN(0x3bacf1aa, 0x93c8aa06),
+ TOBN(0x11ca957c, 0xf7919422), TOBN(0x50641053, 0x78cdaa40),
+ TOBN(0x7a303874, 0x9f7144ae), TOBN(0x170c963f, 0x43d4acfd),
+ TOBN(0x5e148149, 0x58ddd3ef), TOBN(0xa7bde582, 0x9e72dba8),
+ TOBN(0x0769da8b, 0x6fa68750), TOBN(0xfa64e532, 0x572e0249),
+ TOBN(0xfcaadf9d, 0x2619ad31), TOBN(0x87882daa, 0xa7b349cd),
+ TOBN(0x9f6eb731, 0x6c67a775), TOBN(0xcb10471a, 0xefc5d0b1),
+ TOBN(0xb433750c, 0xe1b806b2), TOBN(0x19c5714d, 0x57b1ae7e),
+ TOBN(0xc0dc8b7b, 0xed03fd3f), TOBN(0xdd03344f, 0x31bc194e),
+ TOBN(0xa66c52a7, 0x8c6320b5), TOBN(0x8bc82ce3, 0xd0b6fd93),
+ TOBN(0xf8e13501, 0xb35f1341), TOBN(0xe53156dd, 0x25a43e42),
+ TOBN(0xd3adf27e, 0x4daeb85c), TOBN(0xb81d8379, 0xbbeddeb5),
+ TOBN(0x1b0b546e, 0x2e435867), TOBN(0x9020eb94, 0xeba5dd60),
+ TOBN(0x37d91161, 0x8210cb9d), TOBN(0x4c596b31, 0x5c91f1cf),
+ TOBN(0xb228a90f, 0x0e0b040d), TOBN(0xbaf02d82, 0x45ff897f),
+ TOBN(0x2aac79e6, 0x00fa6122), TOBN(0x24828817, 0x8e36f557),
+ TOBN(0xb9521d31, 0x113ec356), TOBN(0x9e48861e, 0x15eff1f8),
+ TOBN(0x2aa1d412, 0xe0d41715), TOBN(0x71f86203, 0x53f131b8),
+ TOBN(0xf60da8da, 0x3fd19408), TOBN(0x4aa716dc, 0x278d9d99),
+ TOBN(0x394531f7, 0xa8c51c90), TOBN(0xb560b0e8, 0xf59db51c),
+ TOBN(0xa28fc992, 0xfa34bdad), TOBN(0xf024fa14, 0x9cd4f8bd),
+ TOBN(0x5cf530f7, 0x23a9d0d3), TOBN(0x615ca193, 0xe28c9b56),
+ TOBN(0x6d2a483d, 0x6f73c51e), TOBN(0xa4cb2412, 0xea0dc2dd),
+ TOBN(0x50663c41, 0x1eb917ff), TOBN(0x3d3a74cf, 0xeade299e),
+ TOBN(0x29b3990f, 0x4a7a9202), TOBN(0xa9bccf59, 0xa7b15c3d),
+ TOBN(0x66a3ccdc, 0xa5df9208), TOBN(0x48027c14, 0x43f2f929),
+ TOBN(0xd385377c, 0x40b557f0), TOBN(0xe001c366, 0xcd684660),
+ TOBN(0x1b18ed6b, 0xe2183a27), TOBN(0x879738d8, 0x63210329),
+ TOBN(0xa687c74b, 0xbda94882), TOBN(0xd1bbcc48, 0xa684b299),
+ TOBN(0xaf6f1112, 0x863b3724), TOBN(0x6943d1b4, 0x2c8ce9f8),
+ TOBN(0xe044a3bb, 0x098cafb4), TOBN(0x27ed2310, 0x60d48caf),
+ TOBN(0x542b5675, 0x3a31b84d), TOBN(0xcbf3dd50, 0xfcddbed7),
+ TOBN(0x25031f16, 0x41b1d830), TOBN(0xa7ec851d, 0xcb0c1e27),
+ TOBN(0xac1c8fe0, 0xb5ae75db), TOBN(0xb24c7557, 0x08c52120),
+ TOBN(0x57f811dc, 0x1d4636c3), TOBN(0xf8436526, 0x681a9939),
+ TOBN(0x1f6bc6d9, 0x9c81adb3), TOBN(0x840f8ac3, 0x5b7d80d4),
+ TOBN(0x731a9811, 0xf4387f1a), TOBN(0x7c501cd3, 0xb5156880),
+ TOBN(0xa5ca4a07, 0xdfe68867), TOBN(0xf123d8f0, 0x5fcea120),
+ TOBN(0x1fbb0e71, 0xd607039e), TOBN(0x2b70e215, 0xcd3a4546),
+ TOBN(0x32d2f01d, 0x53324091), TOBN(0xb796ff08, 0x180ab19b),
+ TOBN(0x32d87a86, 0x3c57c4aa), TOBN(0x2aed9caf, 0xb7c49a27),
+ TOBN(0x9fb35eac, 0x31630d98), TOBN(0x338e8cdf, 0x5c3e20a3),
+ TOBN(0x80f16182, 0x66cde8db), TOBN(0x4e159980, 0x2d72fd36),
+ TOBN(0xd7b8f13b, 0x9b6e5072), TOBN(0xf5213907, 0x3b7b5dc1),
+ TOBN(0x4d431f1d, 0x8ce4396e), TOBN(0x37a1a680, 0xa7ed2142),
+ TOBN(0xbf375696, 0xd01aaf6b), TOBN(0xaa1c0c54, 0xe63aab66),
+ TOBN(0x3014368b, 0x4ed80940), TOBN(0x67e6d056, 0x7a6fcedd),
+ TOBN(0x7c208c49, 0xca97579f), TOBN(0xfe3d7a81, 0xa23597f6),
+ TOBN(0x5e203202, 0x7e096ae2), TOBN(0xb1f3e1e7, 0x24b39366),
+ TOBN(0x26da26f3, 0x2fdcdffc), TOBN(0x79422f1d, 0x6097be83),
+ },
+ {
+ TOBN(0x263a2cfb, 0x9db3b381), TOBN(0x9c3a2dee, 0xd4df0a4b),
+ TOBN(0x728d06e9, 0x7d04e61f), TOBN(0x8b1adfbc, 0x42449325),
+ TOBN(0x6ec1d939, 0x7e053a1b), TOBN(0xee2be5c7, 0x66daf707),
+ TOBN(0x80ba1e14, 0x810ac7ab), TOBN(0xdd2ae778, 0xf530f174),
+ TOBN(0x0435d97a, 0x205b9d8b), TOBN(0x6eb8f064, 0x056756d4),
+ TOBN(0xd5e88a8b, 0xb6f8210e), TOBN(0x070ef12d, 0xec9fd9ea),
+ TOBN(0x4d849505, 0x3bcc876a), TOBN(0x12a75338, 0xa7404ce3),
+ TOBN(0xd22b49e1, 0xb8a1db5e), TOBN(0xec1f2051, 0x14bfa5ad),
+ TOBN(0xadbaeb79, 0xb6828f36), TOBN(0x9d7a0258, 0x01bd5b9e),
+ TOBN(0xeda01e0d, 0x1e844b0c), TOBN(0x4b625175, 0x887edfc9),
+ TOBN(0x14109fdd, 0x9669b621), TOBN(0x88a2ca56, 0xf6f87b98),
+ TOBN(0xfe2eb788, 0x170df6bc), TOBN(0x0cea06f4, 0xffa473f9),
+ TOBN(0x43ed81b5, 0xc4e83d33), TOBN(0xd9f35879, 0x5efd488b),
+ TOBN(0x164a620f, 0x9deb4d0f), TOBN(0xc6927bdb, 0xac6a7394),
+ TOBN(0x45c28df7, 0x9f9e0f03), TOBN(0x2868661e, 0xfcd7e1a9),
+ TOBN(0x7cf4e8d0, 0xffa348f1), TOBN(0x6bd4c284, 0x398538e0),
+ TOBN(0x2618a091, 0x289a8619), TOBN(0xef796e60, 0x6671b173),
+ TOBN(0x664e46e5, 0x9090c632), TOBN(0xa38062d4, 0x1e66f8fb),
+ TOBN(0x6c744a20, 0x0573274e), TOBN(0xd07b67e4, 0xa9271394),
+ TOBN(0x391223b2, 0x6bdc0e20), TOBN(0xbe2d93f1, 0xeb0a05a7),
+ TOBN(0xf23e2e53, 0x3f36d141), TOBN(0xe84bb3d4, 0x4dfca442),
+ TOBN(0xb804a48d, 0x6b7c023a), TOBN(0x1e16a8fa, 0x76431c3b),
+ TOBN(0x1b5452ad, 0xddd472e0), TOBN(0x7d405ee7, 0x0d1ee127),
+ TOBN(0x50fc6f1d, 0xffa27599), TOBN(0x351ac53c, 0xbf391b35),
+ TOBN(0x7efa14b8, 0x4444896b), TOBN(0x64974d2f, 0xf94027fb),
+ TOBN(0xefdcd0e8, 0xde84487d), TOBN(0x8c45b260, 0x2b48989b),
+ TOBN(0xa8fcbbc2, 0xd8463487), TOBN(0xd1b2b3f7, 0x3fbc476c),
+ TOBN(0x21d005b7, 0xc8f443c0), TOBN(0x518f2e67, 0x40c0139c),
+ TOBN(0x56036e8c, 0x06d75fc1), TOBN(0x2dcf7bb7, 0x3249a89f),
+ TOBN(0x81dd1d3d, 0xe245e7dd), TOBN(0xf578dc4b, 0xebd6e2a7),
+ TOBN(0x4c028903, 0xdf2ce7a0), TOBN(0xaee36288, 0x9c39afac),
+ TOBN(0xdc847c31, 0x146404ab), TOBN(0x6304c0d8, 0xa4e97818),
+ TOBN(0xae51dca2, 0xa91f6791), TOBN(0x2abe4190, 0x9baa9efc),
+ TOBN(0xd9d2e2f4, 0x559c7ac1), TOBN(0xe82f4b51, 0xfc9f773a),
+ TOBN(0xa7713027, 0x4073e81c), TOBN(0xc0276fac, 0xfbb596fc),
+ TOBN(0x1d819fc9, 0xa684f70c), TOBN(0x29b47fdd, 0xc9f7b1e0),
+ TOBN(0x358de103, 0x459b1940), TOBN(0xec881c59, 0x5b013e93),
+ TOBN(0x51574c93, 0x49532ad3), TOBN(0x2db1d445, 0xb37b46de),
+ TOBN(0xc6445b87, 0xdf239fd8), TOBN(0xc718af75, 0x151d24ee),
+ TOBN(0xaea1c4a4, 0xf43c6259), TOBN(0x40c0e5d7, 0x70be02f7),
+ TOBN(0x6a4590f4, 0x721b33f2), TOBN(0x2124f1fb, 0xfedf04ea),
+ TOBN(0xf8e53cde, 0x9745efe7), TOBN(0xe7e10432, 0x65f046d9),
+ TOBN(0xc3fca28e, 0xe4d0c7e6), TOBN(0x847e339a, 0x87253b1b),
+ TOBN(0x9b595348, 0x3743e643), TOBN(0xcb6a0a0b, 0x4fd12fc5),
+ TOBN(0xfb6836c3, 0x27d02dcc), TOBN(0x5ad00982, 0x7a68bcc2),
+ TOBN(0x1b24b44c, 0x005e912d), TOBN(0xcc83d20f, 0x811fdcfe),
+ TOBN(0x36527ec1, 0x666fba0c), TOBN(0x69948197, 0x14754635),
+ TOBN(0xfcdcb1a8, 0x556da9c2), TOBN(0xa5934267, 0x81a732b2),
+ TOBN(0xec1214ed, 0xa714181d), TOBN(0x609ac13b, 0x6067b341),
+ TOBN(0xff4b4c97, 0xa545df1f), TOBN(0xa1240501, 0x34d2076b),
+ TOBN(0x6efa0c23, 0x1409ca97), TOBN(0x254cc1a8, 0x20638c43),
+ TOBN(0xd4e363af, 0xdcfb46cd), TOBN(0x62c2adc3, 0x03942a27),
+ TOBN(0xc67b9df0, 0x56e46483), TOBN(0xa55abb20, 0x63736356),
+ TOBN(0xab93c098, 0xc551bc52), TOBN(0x382b49f9, 0xb15fe64b),
+ TOBN(0x9ec221ad, 0x4dff8d47), TOBN(0x79caf615, 0x437df4d6),
+ TOBN(0x5f13dc64, 0xbb456509), TOBN(0xe4c589d9, 0x191f0714),
+ TOBN(0x27b6a8ab, 0x3fd40e09), TOBN(0xe455842e, 0x77313ea9),
+ TOBN(0x8b51d1e2, 0x1f55988b), TOBN(0x5716dd73, 0x062bbbfc),
+ TOBN(0x633c11e5, 0x4e8bf3de), TOBN(0x9a0e77b6, 0x1b85be3b),
+ TOBN(0x56510729, 0x0911cca6), TOBN(0x27e76495, 0xefa6590f),
+ TOBN(0xe4ac8b33, 0x070d3aab), TOBN(0x2643672b, 0x9a2cd5e5),
+ TOBN(0x52eff79b, 0x1cfc9173), TOBN(0x665ca49b, 0x90a7c13f),
+ TOBN(0x5a8dda59, 0xb3efb998), TOBN(0x8a5b922d, 0x052f1341),
+ TOBN(0xae9ebbab, 0x3cf9a530), TOBN(0x35986e7b, 0xf56da4d7),
+ TOBN(0x3a636b5c, 0xff3513cc), TOBN(0xbb0cf8ba, 0x3198f7dd),
+ TOBN(0xb8d40522, 0x41f16f86), TOBN(0x760575d8, 0xde13a7bf),
+ TOBN(0x36f74e16, 0x9f7aa181), TOBN(0x163a3ecf, 0xf509ed1c),
+ TOBN(0x6aead61f, 0x3c40a491), TOBN(0x158c95fc, 0xdfe8fcaa),
+ TOBN(0xa3991b6e, 0x13cda46f), TOBN(0x79482415, 0x342faed0),
+ TOBN(0xf3ba5bde, 0x666b5970), TOBN(0x1d52e6bc, 0xb26ab6dd),
+ TOBN(0x768ba1e7, 0x8608dd3d), TOBN(0x4930db2a, 0xea076586),
+ TOBN(0xd9575714, 0xe7dc1afa), TOBN(0x1fc7bf7d, 0xf7c58817),
+ TOBN(0x6b47accd, 0xd9eee96c), TOBN(0x0ca277fb, 0xe58cec37),
+ TOBN(0x113fe413, 0xe702c42a), TOBN(0xdd1764ee, 0xc47cbe51),
+ TOBN(0x041e7cde, 0x7b3ed739), TOBN(0x50cb7459, 0x5ce9e1c0),
+ TOBN(0x35568513, 0x2925b212), TOBN(0x7cff95c4, 0x001b081c),
+ TOBN(0x63ee4cbd, 0x8088b454), TOBN(0xdb7f32f7, 0x9a9e0c8a),
+ TOBN(0xb377d418, 0x6b2447cb), TOBN(0xe3e982aa, 0xd370219b),
+ TOBN(0x06ccc1e4, 0xc2a2a593), TOBN(0x72c36865, 0x0773f24f),
+ TOBN(0xa13b4da7, 0x95859423), TOBN(0x8bbf1d33, 0x75040c8f),
+ TOBN(0x726f0973, 0xda50c991), TOBN(0x48afcd5b, 0x822d6ee2),
+ TOBN(0xe5fc718b, 0x20fd7771), TOBN(0xb9e8e77d, 0xfd0807a1),
+ TOBN(0x7f5e0f44, 0x99a7703d), TOBN(0x6972930e, 0x618e36f3),
+ TOBN(0x2b7c77b8, 0x23807bbe), TOBN(0xe5b82405, 0xcb27ff50),
+ TOBN(0xba8b8be3, 0xbd379062), TOBN(0xd64b7a1d, 0x2dce4a92),
+ TOBN(0x040a73c5, 0xb2952e37), TOBN(0x0a9e252e, 0xd438aeca),
+ TOBN(0xdd43956b, 0xc39d3bcb), TOBN(0x1a31ca00, 0xb32b2d63),
+ TOBN(0xd67133b8, 0x5c417a18), TOBN(0xd08e4790, 0x2ef442c8),
+ TOBN(0x98cb1ae9, 0x255c0980), TOBN(0x4bd86381, 0x2b4a739f),
+ TOBN(0x5a5c31e1, 0x1e4a45a1), TOBN(0x1e5d55fe, 0x9cb0db2f),
+ TOBN(0x74661b06, 0x8ff5cc29), TOBN(0x026b389f, 0x0eb8a4f4),
+ TOBN(0x536b21a4, 0x58848c24), TOBN(0x2e5bf8ec, 0x81dc72b0),
+ TOBN(0x03c187d0, 0xad886aac), TOBN(0x5c16878a, 0xb771b645),
+ TOBN(0xb07dfc6f, 0xc74045ab), TOBN(0x2c6360bf, 0x7800caed),
+ TOBN(0x24295bb5, 0xb9c972a3), TOBN(0xc9e6f88e, 0x7c9a6dba),
+ TOBN(0x90ffbf24, 0x92a79aa6), TOBN(0xde29d50a, 0x41c26ac2),
+ TOBN(0x9f0af483, 0xd309cbe6), TOBN(0x5b020d8a, 0xe0bced4f),
+ TOBN(0x606e986d, 0xb38023e3), TOBN(0xad8f2c9d, 0x1abc6933),
+ TOBN(0x19292e1d, 0xe7400e93), TOBN(0xfe3e18a9, 0x52be5e4d),
+ TOBN(0xe8e9771d, 0x2e0680bf), TOBN(0x8c5bec98, 0xc54db063),
+ TOBN(0x2af9662a, 0x74a55d1f), TOBN(0xe3fbf28f, 0x046f66d8),
+ TOBN(0xa3a72ab4, 0xd4dc4794), TOBN(0x09779f45, 0x5c7c2dd8),
+ TOBN(0xd893bdaf, 0xc3d19d8d), TOBN(0xd5a75094, 0x57d6a6df),
+ TOBN(0x8cf8fef9, 0x952e6255), TOBN(0x3da67cfb, 0xda9a8aff),
+ TOBN(0x4c23f62a, 0x2c160dcd), TOBN(0x34e6c5e3, 0x8f90eaef),
+ TOBN(0x35865519, 0xa9a65d5a), TOBN(0x07c48aae, 0x8fd38a3d),
+ TOBN(0xb7e7aeda, 0x50068527), TOBN(0x2c09ef23, 0x1c90936a),
+ TOBN(0x31ecfeb6, 0xe879324c), TOBN(0xa0871f6b, 0xfb0ec938),
+ TOBN(0xb1f0fb68, 0xd84d835d), TOBN(0xc90caf39, 0x861dc1e6),
+ TOBN(0x12e5b046, 0x7594f8d7), TOBN(0x26897ae2, 0x65012b92),
+ TOBN(0xbcf68a08, 0xa4d6755d), TOBN(0x403ee41c, 0x0991fbda),
+ TOBN(0x733e343e, 0x3bbf17e8), TOBN(0xd2c7980d, 0x679b3d65),
+ TOBN(0x33056232, 0xd2e11305), TOBN(0x966be492, 0xf3c07a6f),
+ TOBN(0x6a8878ff, 0xbb15509d), TOBN(0xff221101, 0x0a9b59a4),
+ TOBN(0x6c9f564a, 0xabe30129), TOBN(0xc6f2c940, 0x336e64cf),
+ TOBN(0x0fe75262, 0x8b0c8022), TOBN(0xbe0267e9, 0x6ae8db87),
+ TOBN(0x22e192f1, 0x93bc042b), TOBN(0xf085b534, 0xb237c458),
+ TOBN(0xa0d192bd, 0x832c4168), TOBN(0x7a76e9e3, 0xbdf6271d),
+ TOBN(0x52a882fa, 0xb88911b5), TOBN(0xc85345e4, 0xb4db0eb5),
+ TOBN(0xa3be02a6, 0x81a7c3ff), TOBN(0x51889c8c, 0xf0ec0469),
+ TOBN(0x9d031369, 0xa5e829e5), TOBN(0xcbb4c6fc, 0x1607aa41),
+ TOBN(0x75ac59a6, 0x241d84c1), TOBN(0xc043f2bf, 0x8829e0ee),
+ TOBN(0x82a38f75, 0x8ea5e185), TOBN(0x8bda40b9, 0xd87cbd9f),
+ TOBN(0x9e65e75e, 0x2d8fc601), TOBN(0x3d515f74, 0xa35690b3),
+ TOBN(0x534acf4f, 0xda79e5ac), TOBN(0x68b83b3a, 0x8630215f),
+ TOBN(0x5c748b2e, 0xd085756e), TOBN(0xb0317258, 0xe5d37cb2),
+ TOBN(0x6735841a, 0xc5ccc2c4), TOBN(0x7d7dc96b, 0x3d9d5069),
+ TOBN(0xa147e410, 0xfd1754bd), TOBN(0x65296e94, 0xd399ddd5),
+ TOBN(0xf6b5b2d0, 0xbc8fa5bc), TOBN(0x8a5ead67, 0x500c277b),
+ TOBN(0x214625e6, 0xdfa08a5d), TOBN(0x51fdfedc, 0x959cf047),
+ TOBN(0x6bc9430b, 0x289fca32), TOBN(0xe36ff0cf, 0x9d9bdc3f),
+ TOBN(0x2fe187cb, 0x58ea0ede), TOBN(0xed66af20, 0x5a900b3f),
+ TOBN(0x00e0968b, 0x5fa9f4d6), TOBN(0x2d4066ce, 0x37a362e7),
+ TOBN(0xa99a9748, 0xbd07e772), TOBN(0x710989c0, 0x06a4f1d0),
+ TOBN(0xd5dedf35, 0xce40cbd8), TOBN(0xab55c5f0, 0x1743293d),
+ TOBN(0x766f1144, 0x8aa24e2c), TOBN(0x94d874f8, 0x605fbcb4),
+ TOBN(0xa365f0e8, 0xa518001b), TOBN(0xee605eb6, 0x9d04ef0f),
+ TOBN(0x5a3915cd, 0xba8d4d25), TOBN(0x44c0e1b8, 0xb5113472),
+ TOBN(0xcbb024e8, 0x8b6740dc), TOBN(0x89087a53, 0xee1d4f0c),
+ TOBN(0xa88fa05c, 0x1fc4e372), TOBN(0x8bf395cb, 0xaf8b3af2),
+ TOBN(0x1e71c9a1, 0xdeb8568b), TOBN(0xa35daea0, 0x80fb3d32),
+ TOBN(0xe8b6f266, 0x2cf8fb81), TOBN(0x6d51afe8, 0x9490696a),
+ TOBN(0x81beac6e, 0x51803a19), TOBN(0xe3d24b7f, 0x86219080),
+ TOBN(0x727cfd9d, 0xdf6f463c), TOBN(0x8c6865ca, 0x72284ee8),
+ TOBN(0x32c88b7d, 0xb743f4ef), TOBN(0x3793909b, 0xe7d11dce),
+ TOBN(0xd398f922, 0x2ff2ebe8), TOBN(0x2c70ca44, 0xe5e49796),
+ TOBN(0xdf4d9929, 0xcb1131b1), TOBN(0x7826f298, 0x25888e79),
+ TOBN(0x4d3a112c, 0xf1d8740a), TOBN(0x00384cb6, 0x270afa8b),
+ TOBN(0xcb64125b, 0x3ab48095), TOBN(0x3451c256, 0x62d05106),
+ TOBN(0xd73d577d, 0xa4955845), TOBN(0x39570c16, 0xbf9f4433),
+ TOBN(0xd7dfaad3, 0xadecf263), TOBN(0xf1c3d8d1, 0xdc76e102),
+ TOBN(0x5e774a58, 0x54c6a836), TOBN(0xdad4b672, 0x3e92d47b),
+ TOBN(0xbe7e990f, 0xf0d796a0), TOBN(0x5fc62478, 0xdf0e8b02),
+ TOBN(0x8aae8bf4, 0x030c00ad), TOBN(0x3d2db93b, 0x9004ba0f),
+ TOBN(0xe48c8a79, 0xd85d5ddc), TOBN(0xe907caa7, 0x6bb07f34),
+ TOBN(0x58db343a, 0xa39eaed5), TOBN(0x0ea6e007, 0xadaf5724),
+ TOBN(0xe00df169, 0xd23233f3), TOBN(0x3e322796, 0x77cb637f),
+ TOBN(0x1f897c0e, 0x1da0cf6c), TOBN(0xa651f5d8, 0x31d6bbdd),
+ TOBN(0xdd61af19, 0x1a230c76), TOBN(0xbd527272, 0xcdaa5e4a),
+ TOBN(0xca753636, 0xd0abcd7e), TOBN(0x78bdd37c, 0x370bd8dc),
+ TOBN(0xc23916c2, 0x17cd93fe), TOBN(0x65b97a4d, 0xdadce6e2),
+ TOBN(0xe04ed4eb, 0x174e42f8), TOBN(0x1491ccaa, 0xbb21480a),
+ TOBN(0x145a8280, 0x23196332), TOBN(0x3c3862d7, 0x587b479a),
+ TOBN(0x9f4a88a3, 0x01dcd0ed), TOBN(0x4da2b7ef, 0x3ea12f1f),
+ TOBN(0xf8e7ae33, 0xb126e48e), TOBN(0x404a0b32, 0xf494e237),
+ TOBN(0x9beac474, 0xc55acadb), TOBN(0x4ee5cf3b, 0xcbec9fd9),
+ TOBN(0x336b33b9, 0x7df3c8c3), TOBN(0xbd905fe3, 0xb76808fd),
+ TOBN(0x8f436981, 0xaa45c16a), TOBN(0x255c5bfa, 0x3dd27b62),
+ TOBN(0x71965cbf, 0xc3dd9b4d), TOBN(0xce23edbf, 0xfc068a87),
+ TOBN(0xb78d4725, 0x745b029b), TOBN(0x74610713, 0xcefdd9bd),
+ TOBN(0x7116f75f, 0x1266bf52), TOBN(0x02046722, 0x18e49bb6),
+ TOBN(0xdf43df9f, 0x3d6f19e3), TOBN(0xef1bc7d0, 0xe685cb2f),
+ TOBN(0xcddb27c1, 0x7078c432), TOBN(0xe1961b9c, 0xb77fedb7),
+ TOBN(0x1edc2f5c, 0xc2290570), TOBN(0x2c3fefca, 0x19cbd886),
+ TOBN(0xcf880a36, 0xc2af389a), TOBN(0x96c610fd, 0xbda71cea),
+ TOBN(0xf03977a9, 0x32aa8463), TOBN(0x8eb7763f, 0x8586d90a),
+ TOBN(0x3f342454, 0x2a296e77), TOBN(0xc8718683, 0x42837a35),
+ TOBN(0x7dc71090, 0x6a09c731), TOBN(0x54778ffb, 0x51b816db),
+ TOBN(0x6b33bfec, 0xaf06defd), TOBN(0xfe3c105f, 0x8592b70b),
+ TOBN(0xf937fda4, 0x61da6114), TOBN(0x3c13e651, 0x4c266ad7),
+ TOBN(0xe363a829, 0x855938e8), TOBN(0x2eeb5d9e, 0x9de54b72),
+ TOBN(0xbeb93b0e, 0x20ccfab9), TOBN(0x3dffbb5f, 0x25e61a25),
+ TOBN(0x7f655e43, 0x1acc093d), TOBN(0x0cb6cc3d, 0x3964ce61),
+ TOBN(0x6ab283a1, 0xe5e9b460), TOBN(0x55d787c5, 0xa1c7e72d),
+ TOBN(0x4d2efd47, 0xdeadbf02), TOBN(0x11e80219, 0xac459068),
+ TOBN(0x810c7626, 0x71f311f0), TOBN(0xfa17ef8d, 0x4ab6ef53),
+ TOBN(0xaf47fd25, 0x93e43bff), TOBN(0x5cb5ff3f, 0x0be40632),
+ TOBN(0x54687106, 0x8ee61da3), TOBN(0x7764196e, 0xb08afd0f),
+ TOBN(0x831ab3ed, 0xf0290a8f), TOBN(0xcae81966, 0xcb47c387),
+ TOBN(0xaad7dece, 0x184efb4f), TOBN(0xdcfc53b3, 0x4749110e),
+ TOBN(0x6698f23c, 0x4cb632f9), TOBN(0xc42a1ad6, 0xb91f8067),
+ TOBN(0xb116a81d, 0x6284180a), TOBN(0xebedf5f8, 0xe901326f),
+ TOBN(0xf2274c9f, 0x97e3e044), TOBN(0x42018520, 0x11d09fc9),
+ TOBN(0x56a65f17, 0xd18e6e23), TOBN(0x2ea61e2a, 0x352b683c),
+ TOBN(0x27d291bc, 0x575eaa94), TOBN(0x9e7bc721, 0xb8ff522d),
+ TOBN(0x5f7268bf, 0xa7f04d6f), TOBN(0x5868c73f, 0xaba41748),
+ TOBN(0x9f85c2db, 0x7be0eead), TOBN(0x511e7842, 0xff719135),
+ TOBN(0x5a06b1e9, 0xc5ea90d7), TOBN(0x0c19e283, 0x26fab631),
+ TOBN(0x8af8f0cf, 0xe9206c55), TOBN(0x89389cb4, 0x3553c06a),
+ TOBN(0x39dbed97, 0xf65f8004), TOBN(0x0621b037, 0xc508991d),
+ TOBN(0x1c52e635, 0x96e78cc4), TOBN(0x5385c8b2, 0x0c06b4a8),
+ TOBN(0xd84ddfdb, 0xb0e87d03), TOBN(0xc49dfb66, 0x934bafad),
+ TOBN(0x7071e170, 0x59f70772), TOBN(0x3a073a84, 0x3a1db56b),
+ TOBN(0x03494903, 0x3b8af190), TOBN(0x7d882de3, 0xd32920f0),
+ TOBN(0x91633f0a, 0xb2cf8940), TOBN(0x72b0b178, 0x6f948f51),
+ TOBN(0x2d28dc30, 0x782653c8), TOBN(0x88829849, 0xdb903a05),
+ TOBN(0xb8095d0c, 0x6a19d2bb), TOBN(0x4b9e7f0c, 0x86f782cb),
+ TOBN(0x7af73988, 0x2d907064), TOBN(0xd12be0fe, 0x8b32643c),
+ TOBN(0x358ed23d, 0x0e165dc3), TOBN(0x3d47ce62, 0x4e2378ce),
+ TOBN(0x7e2bb0b9, 0xfeb8a087), TOBN(0x3246e8ae, 0xe29e10b9),
+ TOBN(0x459f4ec7, 0x03ce2b4d), TOBN(0xe9b4ca1b, 0xbbc077cf),
+ TOBN(0x2613b4f2, 0x0e9940c1), TOBN(0xfc598bb9, 0x047d1eb1),
+ TOBN(0x9744c62b, 0x45036099), TOBN(0xa9dee742, 0x167c65d8),
+ TOBN(0x0c511525, 0xdabe1943), TOBN(0xda110554, 0x93c6c624),
+ TOBN(0xae00a52c, 0x651a3be2), TOBN(0xcda5111d, 0x884449a6),
+ TOBN(0x063c06f4, 0xff33bed1), TOBN(0x73baaf9a, 0x0d3d76b4),
+ TOBN(0x52fb0c9d, 0x7fc63668), TOBN(0x6886c9dd, 0x0c039cde),
+ TOBN(0x602bd599, 0x55b22351), TOBN(0xb00cab02, 0x360c7c13),
+ TOBN(0x8cb616bc, 0x81b69442), TOBN(0x41486700, 0xb55c3cee),
+ TOBN(0x71093281, 0xf49ba278), TOBN(0xad956d9c, 0x64a50710),
+ TOBN(0x9561f28b, 0x638a7e81), TOBN(0x54155cdf, 0x5980ddc3),
+ TOBN(0xb2db4a96, 0xd26f247a), TOBN(0x9d774e4e, 0x4787d100),
+ TOBN(0x1a9e6e2e, 0x078637d2), TOBN(0x1c363e2d, 0x5e0ae06a),
+ TOBN(0x7493483e, 0xe9cfa354), TOBN(0x76843cb3, 0x7f74b98d),
+ TOBN(0xbaca6591, 0xd4b66947), TOBN(0xb452ce98, 0x04460a8c),
+ TOBN(0x6830d246, 0x43768f55), TOBN(0xf4197ed8, 0x7dff12df),
+ TOBN(0x6521b472, 0x400dd0f7), TOBN(0x59f5ca8f, 0x4b1e7093),
+ TOBN(0x6feff11b, 0x080338ae), TOBN(0x0ada31f6, 0xa29ca3c6),
+ TOBN(0x24794eb6, 0x94a2c215), TOBN(0xd83a43ab, 0x05a57ab4),
+ TOBN(0x264a543a, 0x2a6f89fe), TOBN(0x2c2a3868, 0xdd5ec7c2),
+ TOBN(0xd3373940, 0x8439d9b2), TOBN(0x715ea672, 0x0acd1f11),
+ TOBN(0x42c1d235, 0xe7e6cc19), TOBN(0x81ce6e96, 0xb990585c),
+ TOBN(0x04e5dfe0, 0xd809c7bd), TOBN(0xd7b2580c, 0x8f1050ab),
+ TOBN(0x6d91ad78, 0xd8a4176f), TOBN(0x0af556ee, 0x4e2e897c),
+ TOBN(0x162a8b73, 0x921de0ac), TOBN(0x52ac9c22, 0x7ea78400),
+ TOBN(0xee2a4eea, 0xefce2174), TOBN(0xbe61844e, 0x6d637f79),
+ TOBN(0x0491f1bc, 0x789a283b), TOBN(0x72d3ac3d, 0x880836f4),
+ TOBN(0xaa1c5ea3, 0x88e5402d), TOBN(0x1b192421, 0xd5cc473d),
+ TOBN(0x5c0b9998, 0x9dc84cac), TOBN(0xb0a8482d, 0x9c6e75b8),
+ TOBN(0x639961d0, 0x3a191ce2), TOBN(0xda3bc865, 0x6d837930),
+ TOBN(0xca990653, 0x056e6f8f), TOBN(0x84861c41, 0x64d133a7),
+ TOBN(0x8b403276, 0x746abe40), TOBN(0xb7b4d51a, 0xebf8e303),
+ TOBN(0x05b43211, 0x220a255d), TOBN(0xc997152c, 0x02419e6e),
+ TOBN(0x76ff47b6, 0x630c2fea), TOBN(0x50518677, 0x281fdade),
+ TOBN(0x3283b8ba, 0xcf902b0b), TOBN(0x8d4b4eb5, 0x37db303b),
+ TOBN(0xcc89f42d, 0x755011bc), TOBN(0xb43d74bb, 0xdd09d19b),
+ TOBN(0x65746bc9, 0x8adba350), TOBN(0x364eaf8c, 0xb51c1927),
+ TOBN(0x13c76596, 0x10ad72ec), TOBN(0x30045121, 0xf8d40c20),
+ TOBN(0x6d2d99b7, 0xea7b979b), TOBN(0xcd78cd74, 0xe6fb3bcd),
+ TOBN(0x11e45a9e, 0x86cffbfe), TOBN(0x78a61cf4, 0x637024f6),
+ TOBN(0xd06bc872, 0x3d502295), TOBN(0xf1376854, 0x458cb288),
+ TOBN(0xb9db26a1, 0x342f8586), TOBN(0xf33effcf, 0x4beee09e),
+ TOBN(0xd7e0c4cd, 0xb30cfb3a), TOBN(0x6d09b8c1, 0x6c9db4c8),
+ TOBN(0x40ba1a42, 0x07c8d9df), TOBN(0x6fd495f7, 0x1c52c66d),
+ TOBN(0xfb0e169f, 0x275264da), TOBN(0x80c2b746, 0xe57d8362),
+ TOBN(0xedd987f7, 0x49ad7222), TOBN(0xfdc229af, 0x4398ec7b),
+ },
+ {
+ TOBN(0xb0d1ed84, 0x52666a58), TOBN(0x4bcb6e00, 0xe6a9c3c2),
+ TOBN(0x3c57411c, 0x26906408), TOBN(0xcfc20755, 0x13556400),
+ TOBN(0xa08b1c50, 0x5294dba3), TOBN(0xa30ba286, 0x8b7dd31e),
+ TOBN(0xd70ba90e, 0x991eca74), TOBN(0x094e142c, 0xe762c2b9),
+ TOBN(0xb81d783e, 0x979f3925), TOBN(0x1efd130a, 0xaf4c89a7),
+ TOBN(0x525c2144, 0xfd1bf7fa), TOBN(0x4b296904, 0x1b265a9e),
+ TOBN(0xed8e9634, 0xb9db65b6), TOBN(0x35c82e32, 0x03599d8a),
+ TOBN(0xdaa7a54f, 0x403563f3), TOBN(0x9df088ad, 0x022c38ab),
+ TOBN(0xe5cfb066, 0xbb3fd30a), TOBN(0x429169da, 0xeff0354e),
+ TOBN(0x809cf852, 0x3524e36c), TOBN(0x136f4fb3, 0x0155be1d),
+ TOBN(0x4826af01, 0x1fbba712), TOBN(0x6ef0f0b4, 0x506ba1a1),
+ TOBN(0xd9928b31, 0x77aea73e), TOBN(0xe2bf6af2, 0x5eaa244e),
+ TOBN(0x8d084f12, 0x4237b64b), TOBN(0x688ebe99, 0xe3ecfd07),
+ TOBN(0x57b8a70c, 0xf6845dd8), TOBN(0x808fc59c, 0x5da4a325),
+ TOBN(0xa9032b2b, 0xa3585862), TOBN(0xb66825d5, 0xedf29386),
+ TOBN(0xb5a5a8db, 0x431ec29b), TOBN(0xbb143a98, 0x3a1e8dc8),
+ TOBN(0x35ee94ce, 0x12ae381b), TOBN(0x3a7f176c, 0x86ccda90),
+ TOBN(0xc63a657e, 0x4606eaca), TOBN(0x9ae5a380, 0x43cd04df),
+ TOBN(0x9bec8d15, 0xed251b46), TOBN(0x1f5d6d30, 0xcaca5e64),
+ TOBN(0x347b3b35, 0x9ff20f07), TOBN(0x4d65f034, 0xf7e4b286),
+ TOBN(0x9e93ba24, 0xf111661e), TOBN(0xedced484, 0xb105eb04),
+ TOBN(0x96dc9ba1, 0xf424b578), TOBN(0xbf8f66b7, 0xe83e9069),
+ TOBN(0x872d4df4, 0xd7ed8216), TOBN(0xbf07f377, 0x8e2cbecf),
+ TOBN(0x4281d899, 0x98e73754), TOBN(0xfec85fbb, 0x8aab8708),
+ TOBN(0x9a3c0dee, 0xa5ba5b0b), TOBN(0xe6a116ce, 0x42d05299),
+ TOBN(0xae9775fe, 0xe9b02d42), TOBN(0x72b05200, 0xa1545cb6),
+ TOBN(0xbc506f7d, 0x31a3b4ea), TOBN(0xe5893078, 0x8bbd9b32),
+ TOBN(0xc8bc5f37, 0xe4b12a97), TOBN(0x6b000c06, 0x4a73b671),
+ TOBN(0x13b5bf22, 0x765fa7d0), TOBN(0x59805bf0, 0x1d6a5370),
+ TOBN(0x67a5e29d, 0x4280db98), TOBN(0x4f53916f, 0x776b1ce3),
+ TOBN(0x714ff61f, 0x33ddf626), TOBN(0x4206238e, 0xa085d103),
+ TOBN(0x1c50d4b7, 0xe5809ee3), TOBN(0x999f450d, 0x85f8eb1d),
+ TOBN(0x658a6051, 0xe4c79e9b), TOBN(0x1394cb73, 0xc66a9fea),
+ TOBN(0x27f31ed5, 0xc6be7b23), TOBN(0xf4c88f36, 0x5aa6f8fe),
+ TOBN(0x0fb0721f, 0x4aaa499e), TOBN(0x68b3a7d5, 0xe3fb2a6b),
+ TOBN(0xa788097d, 0x3a92851d), TOBN(0x060e7f8a, 0xe96f4913),
+ TOBN(0x82eebe73, 0x1a3a93bc), TOBN(0x42bbf465, 0xa21adc1a),
+ TOBN(0xc10b6fa4, 0xef030efd), TOBN(0x247aa4c7, 0x87b097bb),
+ TOBN(0x8b8dc632, 0xf60c77da), TOBN(0x6ffbc26a, 0xc223523e),
+ TOBN(0xa4f6ff11, 0x344579cf), TOBN(0x5825653c, 0x980250f6),
+ TOBN(0xb2dd097e, 0xbc1aa2b9), TOBN(0x07889393, 0x37a0333a),
+ TOBN(0x1cf55e71, 0x37a0db38), TOBN(0x2648487f, 0x792c1613),
+ TOBN(0xdad01336, 0x3fcef261), TOBN(0x6239c81d, 0x0eabf129),
+ TOBN(0x8ee761de, 0x9d276be2), TOBN(0x406a7a34, 0x1eda6ad3),
+ TOBN(0x4bf367ba, 0x4a493b31), TOBN(0x54f20a52, 0x9bf7f026),
+ TOBN(0xb696e062, 0x9795914b), TOBN(0xcddab96d, 0x8bf236ac),
+ TOBN(0x4ff2c70a, 0xed25ea13), TOBN(0xfa1d09eb, 0x81cbbbe7),
+ TOBN(0x88fc8c87, 0x468544c5), TOBN(0x847a670d, 0x696b3317),
+ TOBN(0xf133421e, 0x64bcb626), TOBN(0xaea638c8, 0x26dee0b5),
+ TOBN(0xd6e7680b, 0xb310346c), TOBN(0xe06f4097, 0xd5d4ced3),
+ TOBN(0x09961452, 0x7512a30b), TOBN(0xf3d867fd, 0xe589a59a),
+ TOBN(0x2e73254f, 0x52d0c180), TOBN(0x9063d8a3, 0x333c74ac),
+ TOBN(0xeda6c595, 0xd314e7bc), TOBN(0x2ee7464b, 0x467899ed),
+ TOBN(0x1cef423c, 0x0a1ed5d3), TOBN(0x217e76ea, 0x69cc7613),
+ TOBN(0x27ccce1f, 0xe7cda917), TOBN(0x12d8016b, 0x8a893f16),
+ TOBN(0xbcd6de84, 0x9fc74f6b), TOBN(0xfa5817e2, 0xf3144e61),
+ TOBN(0x1f354164, 0x0821ee4c), TOBN(0x1583eab4, 0x0bc61992),
+ TOBN(0x7490caf6, 0x1d72879f), TOBN(0x998ad9f3, 0xf76ae7b2),
+ TOBN(0x1e181950, 0xa41157f7), TOBN(0xa9d7e1e6, 0xe8da3a7e),
+ TOBN(0x963784eb, 0x8426b95f), TOBN(0x0ee4ed6e, 0x542e2a10),
+ TOBN(0xb79d4cc5, 0xac751e7b), TOBN(0x93f96472, 0xfd4211bd),
+ TOBN(0x8c72d3d2, 0xc8de4fc6), TOBN(0x7b69cbf5, 0xdf44f064),
+ TOBN(0x3da90ca2, 0xf4bf94e1), TOBN(0x1a5325f8, 0xf12894e2),
+ TOBN(0x0a437f6c, 0x7917d60b), TOBN(0x9be70486, 0x96c9cb5d),
+ TOBN(0xb4d880bf, 0xe1dc5c05), TOBN(0xd738adda, 0xeebeeb57),
+ TOBN(0x6f0119d3, 0xdf0fe6a3), TOBN(0x5c686e55, 0x66eaaf5a),
+ TOBN(0x9cb10b50, 0xdfd0b7ec), TOBN(0xbdd0264b, 0x6a497c21),
+ TOBN(0xfc093514, 0x8c546c96), TOBN(0x58a947fa, 0x79dbf42a),
+ TOBN(0xc0b48d4e, 0x49ccd6d7), TOBN(0xff8fb02c, 0x88bd5580),
+ TOBN(0xc75235e9, 0x07d473b2), TOBN(0x4fab1ac5, 0xa2188af3),
+ TOBN(0x030fa3bc, 0x97576ec0), TOBN(0xe8c946e8, 0x0b7e7d2f),
+ TOBN(0x40a5c9cc, 0x70305600), TOBN(0x6d8260a9, 0xc8b013b4),
+ TOBN(0x0368304f, 0x70bba85c), TOBN(0xad090da1, 0xa4a0d311),
+ TOBN(0x7170e870, 0x2415eec1), TOBN(0xbfba35fe, 0x8461ea47),
+ TOBN(0x6279019a, 0xc1e91938), TOBN(0xa47638f3, 0x1afc415f),
+ TOBN(0x36c65cbb, 0xbcba0e0f), TOBN(0x02160efb, 0x034e2c48),
+ TOBN(0xe6c51073, 0x615cd9e4), TOBN(0x498ec047, 0xf1243c06),
+ TOBN(0x3e5a8809, 0xb17b3d8c), TOBN(0x5cd99e61, 0x0cc565f1),
+ TOBN(0x81e312df, 0x7851dafe), TOBN(0xf156f5ba, 0xa79061e2),
+ TOBN(0x80d62b71, 0x880c590e), TOBN(0xbec9746f, 0x0a39faa1),
+ TOBN(0x1d98a9c1, 0xc8ed1f7a), TOBN(0x09e43bb5, 0xa81d5ff2),
+ TOBN(0xd5f00f68, 0x0da0794a), TOBN(0x412050d9, 0x661aa836),
+ TOBN(0xa89f7c4e, 0x90747e40), TOBN(0x6dc05ebb, 0xb62a3686),
+ TOBN(0xdf4de847, 0x308e3353), TOBN(0x53868fbb, 0x9fb53bb9),
+ TOBN(0x2b09d2c3, 0xcfdcf7dd), TOBN(0x41a9fce3, 0x723fcab4),
+ TOBN(0x73d905f7, 0x07f57ca3), TOBN(0x080f9fb1, 0xac8e1555),
+ TOBN(0x7c088e84, 0x9ba7a531), TOBN(0x07d35586, 0xed9a147f),
+ TOBN(0x602846ab, 0xaf48c336), TOBN(0x7320fd32, 0x0ccf0e79),
+ TOBN(0xaa780798, 0xb18bd1ff), TOBN(0x52c2e300, 0xafdd2905),
+ TOBN(0xf27ea3d6, 0x434267cd), TOBN(0x8b96d16d, 0x15605b5f),
+ TOBN(0x7bb31049, 0x4b45706b), TOBN(0xe7f58b8e, 0x743d25f8),
+ TOBN(0xe9b5e45b, 0x87f30076), TOBN(0xd19448d6, 0x5d053d5a),
+ TOBN(0x1ecc8cb9, 0xd3210a04), TOBN(0x6bc7d463, 0xdafb5269),
+ TOBN(0x3e59b10a, 0x67c3489f), TOBN(0x1769788c, 0x65641e1b),
+ TOBN(0x8a53b82d, 0xbd6cb838), TOBN(0x7066d6e6, 0x236d5f22),
+ TOBN(0x03aa1c61, 0x6908536e), TOBN(0xc971da0d, 0x66ae9809),
+ TOBN(0x01b3a86b, 0xc49a2fac), TOBN(0x3b8420c0, 0x3092e77a),
+ TOBN(0x02057300, 0x7d6fb556), TOBN(0x6941b2a1, 0xbff40a87),
+ TOBN(0x140b6308, 0x0658ff2a), TOBN(0x87804363, 0x3424ab36),
+ TOBN(0x0253bd51, 0x5751e299), TOBN(0xc75bcd76, 0x449c3e3a),
+ TOBN(0x92eb4090, 0x7f8f875d), TOBN(0x9c9d754e, 0x56c26bbf),
+ TOBN(0x158cea61, 0x8110bbe7), TOBN(0x62a6b802, 0x745f91ea),
+ TOBN(0xa79c41aa, 0xc6e7394b), TOBN(0x445b6a83, 0xad57ef10),
+ TOBN(0x0c5277eb, 0x6ea6f40c), TOBN(0x319fe96b, 0x88633365),
+ TOBN(0x0b0fc61f, 0x385f63cb), TOBN(0x41250c84, 0x22bdd127),
+ TOBN(0x67d153f1, 0x09e942c2), TOBN(0x60920d08, 0xc021ad5d),
+ TOBN(0x229f5746, 0x724d81a5), TOBN(0xb7ffb892, 0x5bba3299),
+ TOBN(0x518c51a1, 0xde413032), TOBN(0x2a9bfe77, 0x3c2fd94c),
+ TOBN(0xcbcde239, 0x3191f4fd), TOBN(0x43093e16, 0xd3d6ada1),
+ TOBN(0x184579f3, 0x58769606), TOBN(0x2c94a8b3, 0xd236625c),
+ TOBN(0x6922b9c0, 0x5c437d8e), TOBN(0x3d4ae423, 0xd8d9f3c8),
+ TOBN(0xf72c31c1, 0x2e7090a2), TOBN(0x4ac3f5f3, 0xd76a55bd),
+ TOBN(0x342508fc, 0x6b6af991), TOBN(0x0d527100, 0x1b5cebbd),
+ TOBN(0xb84740d0, 0xdd440dd7), TOBN(0x748ef841, 0x780162fd),
+ TOBN(0xa8dbfe0e, 0xdfc6fafb), TOBN(0xeadfdf05, 0xf7300f27),
+ TOBN(0x7d06555f, 0xfeba4ec9), TOBN(0x12c56f83, 0x9e25fa97),
+ TOBN(0x77f84203, 0xd39b8c34), TOBN(0xed8b1be6, 0x3125eddb),
+ TOBN(0x5bbf2441, 0xf6e39dc5), TOBN(0xb00f6ee6, 0x6a5d678a),
+ TOBN(0xba456ecf, 0x57d0ea99), TOBN(0xdcae0f58, 0x17e06c43),
+ TOBN(0x01643de4, 0x0f5b4baa), TOBN(0x2c324341, 0xd161b9be),
+ TOBN(0x80177f55, 0xe126d468), TOBN(0xed325f1f, 0x76748e09),
+ TOBN(0x6116004a, 0xcfa9bdc2), TOBN(0x2d8607e6, 0x3a9fb468),
+ TOBN(0x0e573e27, 0x6009d660), TOBN(0x3a525d2e, 0x8d10c5a1),
+ TOBN(0xd26cb45c, 0x3b9009a0), TOBN(0xb6b0cdc0, 0xde9d7448),
+ TOBN(0x949c9976, 0xe1337c26), TOBN(0x6faadebd, 0xd73d68e5),
+ TOBN(0x9e158614, 0xf1b768d9), TOBN(0x22dfa557, 0x9cc4f069),
+ TOBN(0xccd6da17, 0xbe93c6d6), TOBN(0x24866c61, 0xa504f5b9),
+ TOBN(0x2121353c, 0x8d694da1), TOBN(0x1c6ca580, 0x0140b8c6),
+ TOBN(0xc245ad8c, 0xe964021e), TOBN(0xb83bffba, 0x032b82b3),
+ TOBN(0xfaa220c6, 0x47ef9898), TOBN(0x7e8d3ac6, 0x982c948a),
+ TOBN(0x1faa2091, 0xbc2d124a), TOBN(0xbd54c3dd, 0x05b15ff4),
+ TOBN(0x386bf3ab, 0xc87c6fb7), TOBN(0xfb2b0563, 0xfdeb6f66),
+ TOBN(0x4e77c557, 0x5b45afb4), TOBN(0xe9ded649, 0xefb8912d),
+ TOBN(0x7ec9bbf5, 0x42f6e557), TOBN(0x2570dfff, 0x62671f00),
+ TOBN(0x2b3bfb78, 0x88e084bd), TOBN(0xa024b238, 0xf37fe5b4),
+ TOBN(0x44e7dc04, 0x95649aee), TOBN(0x498ca255, 0x5e7ec1d8),
+ TOBN(0x3bc766ea, 0xaaa07e86), TOBN(0x0db6facb, 0xf3608586),
+ TOBN(0xbadd2549, 0xbdc259c8), TOBN(0x95af3c6e, 0x041c649f),
+ TOBN(0xb36a928c, 0x02e30afb), TOBN(0x9b5356ad, 0x008a88b8),
+ TOBN(0x4b67a5f1, 0xcf1d9e9d), TOBN(0xc6542e47, 0xa5d8d8ce),
+ TOBN(0x73061fe8, 0x7adfb6cc), TOBN(0xcc826fd3, 0x98678141),
+ TOBN(0x00e758b1, 0x3c80515a), TOBN(0x6afe3247, 0x41485083),
+ TOBN(0x0fcb08b9, 0xb6ae8a75), TOBN(0xb8cf388d, 0x4acf51e1),
+ TOBN(0x344a5560, 0x6961b9d6), TOBN(0x1a6778b8, 0x6a97fd0c),
+ TOBN(0xd840fdc1, 0xecc4c7e3), TOBN(0xde9fe47d, 0x16db68cc),
+ TOBN(0xe95f89de, 0xa3e216aa), TOBN(0x84f1a6a4, 0x9594a8be),
+ TOBN(0x7ddc7d72, 0x5a7b162b), TOBN(0xc5cfda19, 0xadc817a3),
+ TOBN(0x80a5d350, 0x78b58d46), TOBN(0x93365b13, 0x82978f19),
+ TOBN(0x2e44d225, 0x26a1fc90), TOBN(0x0d6d10d2, 0x4d70705d),
+ TOBN(0xd94b6b10, 0xd70c45f4), TOBN(0x0f201022, 0xb216c079),
+ TOBN(0xcec966c5, 0x658fde41), TOBN(0xa8d2bc7d, 0x7e27601d),
+ TOBN(0xbfcce3e1, 0xff230be7), TOBN(0x3394ff6b, 0x0033ffb5),
+ TOBN(0xd890c509, 0x8132c9af), TOBN(0xaac4b0eb, 0x361e7868),
+ TOBN(0x5194ded3, 0xe82d15aa), TOBN(0x4550bd2e, 0x23ae6b7d),
+ TOBN(0x3fda318e, 0xea5399d4), TOBN(0xd989bffa, 0x91638b80),
+ TOBN(0x5ea124d0, 0xa14aa12d), TOBN(0x1fb1b899, 0x3667b944),
+ TOBN(0x95ec7969, 0x44c44d6a), TOBN(0x91df144a, 0x57e86137),
+ TOBN(0x915fd620, 0x73adac44), TOBN(0x8f01732d, 0x59a83801),
+ TOBN(0xec579d25, 0x3aa0a633), TOBN(0x06de5e7c, 0xc9d6d59c),
+ TOBN(0xc132f958, 0xb1ef8010), TOBN(0x29476f96, 0xe65c1a02),
+ TOBN(0x336a77c0, 0xd34c3565), TOBN(0xef1105b2, 0x1b9f1e9e),
+ TOBN(0x63e6d08b, 0xf9e08002), TOBN(0x9aff2f21, 0xc613809e),
+ TOBN(0xb5754f85, 0x3a80e75d), TOBN(0xde71853e, 0x6bbda681),
+ TOBN(0x86f041df, 0x8197fd7a), TOBN(0x8b332e08, 0x127817fa),
+ TOBN(0x05d99be8, 0xb9c20cda), TOBN(0x89f7aad5, 0xd5cd0c98),
+ TOBN(0x7ef936fe, 0x5bb94183), TOBN(0x92ca0753, 0xb05cd7f2),
+ TOBN(0x9d65db11, 0x74a1e035), TOBN(0x02628cc8, 0x13eaea92),
+ TOBN(0xf2d9e242, 0x49e4fbf2), TOBN(0x94fdfd9b, 0xe384f8b7),
+ TOBN(0x65f56054, 0x63428c6b), TOBN(0x2f7205b2, 0x90b409a5),
+ TOBN(0xf778bb78, 0xff45ae11), TOBN(0xa13045be, 0xc5ee53b2),
+ TOBN(0xe00a14ff, 0x03ef77fe), TOBN(0x689cd59f, 0xffef8bef),
+ TOBN(0x3578f0ed, 0x1e9ade22), TOBN(0xe99f3ec0, 0x6268b6a8),
+ TOBN(0xa2057d91, 0xea1b3c3e), TOBN(0x2d1a7053, 0xb8823a4a),
+ TOBN(0xabbb336a, 0x2cca451e), TOBN(0xcd2466e3, 0x2218bb5d),
+ TOBN(0x3ac1f42f, 0xc8cb762d), TOBN(0x7e312aae, 0x7690211f),
+ TOBN(0xebb9bd73, 0x45d07450), TOBN(0x207c4b82, 0x46c2213f),
+ TOBN(0x99d425c1, 0x375913ec), TOBN(0x94e45e96, 0x67908220),
+ TOBN(0xc08f3087, 0xcd67dbf6), TOBN(0xa5670fbe, 0xc0887056),
+ TOBN(0x6717b64a, 0x66f5b8fc), TOBN(0xd5a56aea, 0x786fec28),
+ TOBN(0xa8c3f55f, 0xc0ff4952), TOBN(0xa77fefae, 0x457ac49b),
+ TOBN(0x29882d7c, 0x98379d44), TOBN(0xd000bdfb, 0x509edc8a),
+ TOBN(0xc6f95979, 0xe66fe464), TOBN(0x504a6115, 0xfa61bde0),
+ TOBN(0x56b3b871, 0xeffea31a), TOBN(0x2d3de26d, 0xf0c21a54),
+ TOBN(0x21dbff31, 0x834753bf), TOBN(0xe67ecf49, 0x69269d86),
+ TOBN(0x7a176952, 0x151fe690), TOBN(0x03515804, 0x7f2adb5f),
+ TOBN(0xee794b15, 0xd1b62a8d), TOBN(0xf004ceec, 0xaae454e6),
+ TOBN(0x0897ea7c, 0xf0386fac), TOBN(0x3b62ff12, 0xd1fca751),
+ TOBN(0x154181df, 0x1b7a04ec), TOBN(0x2008e04a, 0xfb5847ec),
+ TOBN(0xd147148e, 0x41dbd772), TOBN(0x2b419f73, 0x22942654),
+ TOBN(0x669f30d3, 0xe9c544f7), TOBN(0x52a2c223, 0xc8540149),
+ TOBN(0x5da9ee14, 0x634dfb02), TOBN(0x5f074ff0, 0xf47869f3),
+ TOBN(0x74ee878d, 0xa3933acc), TOBN(0xe6510651, 0x4fe35ed1),
+ TOBN(0xb3eb9482, 0xf1012e7a), TOBN(0x51013cc0, 0xa8a566ae),
+ TOBN(0xdd5e9243, 0x47c00d3b), TOBN(0x7fde089d, 0x946bb0e5),
+ TOBN(0x030754fe, 0xc731b4b3), TOBN(0x12a136a4, 0x99fda062),
+ TOBN(0x7c1064b8, 0x5a1a35bc), TOBN(0xbf1f5763, 0x446c84ef),
+ TOBN(0xed29a56d, 0xa16d4b34), TOBN(0x7fba9d09, 0xdca21c4f),
+ TOBN(0x66d7ac00, 0x6d8de486), TOBN(0x60061987, 0x73a2a5e1),
+ TOBN(0x8b400f86, 0x9da28ff0), TOBN(0x3133f708, 0x43c4599c),
+ TOBN(0x9911c9b8, 0xee28cb0d), TOBN(0xcd7e2874, 0x8e0af61d),
+ TOBN(0x5a85f0f2, 0x72ed91fc), TOBN(0x85214f31, 0x9cd4a373),
+ TOBN(0x881fe5be, 0x1925253c), TOBN(0xd8dc98e0, 0x91e8bc76),
+ TOBN(0x7120affe, 0x585cc3a2), TOBN(0x724952ed, 0x735bf97a),
+ TOBN(0x5581e7dc, 0x3eb34581), TOBN(0x5cbff4f2, 0xe52ee57d),
+ TOBN(0x8d320a0e, 0x87d8cc7b), TOBN(0x9beaa7f3, 0xf1d280d0),
+ TOBN(0x7a0b9571, 0x9beec704), TOBN(0x9126332e, 0x5b7f0057),
+ TOBN(0x01fbc1b4, 0x8ed3bd6d), TOBN(0x35bb2c12, 0xd945eb24),
+ TOBN(0x6404694e, 0x9a8ae255), TOBN(0xb6092eec, 0x8d6abfb3),
+ TOBN(0x4d76143f, 0xcc058865), TOBN(0x7b0a5af2, 0x6e249922),
+ TOBN(0x8aef9440, 0x6a50d353), TOBN(0xe11e4bcc, 0x64f0e07a),
+ TOBN(0x4472993a, 0xa14a90fa), TOBN(0x7706e20c, 0xba0c51d4),
+ TOBN(0xf403292f, 0x1532672d), TOBN(0x52573bfa, 0x21829382),
+ TOBN(0x6a7bb6a9, 0x3b5bdb83), TOBN(0x08da65c0, 0xa4a72318),
+ TOBN(0xc58d22aa, 0x63eb065f), TOBN(0x1717596c, 0x1b15d685),
+ TOBN(0x112df0d0, 0xb266d88b), TOBN(0xf688ae97, 0x5941945a),
+ TOBN(0x487386e3, 0x7c292cac), TOBN(0x42f3b50d, 0x57d6985c),
+ TOBN(0x6da4f998, 0x6a90fc34), TOBN(0xc8f257d3, 0x65ca8a8d),
+ TOBN(0xc2feabca, 0x6951f762), TOBN(0xe1bc81d0, 0x74c323ac),
+ TOBN(0x1bc68f67, 0x251a2a12), TOBN(0x10d86587, 0xbe8a70dc),
+ TOBN(0xd648af7f, 0xf0f84d2e), TOBN(0xf0aa9ebc, 0x6a43ac92),
+ TOBN(0x69e3be04, 0x27596893), TOBN(0xb6bb02a6, 0x45bf452b),
+ TOBN(0x0875c11a, 0xf4c698c8), TOBN(0x6652b5c7, 0xbece3794),
+ TOBN(0x7b3755fd, 0x4f5c0499), TOBN(0x6ea16558, 0xb5532b38),
+ TOBN(0xd1c69889, 0xa2e96ef7), TOBN(0x9c773c3a, 0x61ed8f48),
+ TOBN(0x2b653a40, 0x9b323abc), TOBN(0xe26605e1, 0xf0e1d791),
+ TOBN(0x45d41064, 0x4a87157a), TOBN(0x8f9a78b7, 0xcbbce616),
+ TOBN(0xcf1e44aa, 0xc407eddd), TOBN(0x81ddd1d8, 0xa35b964f),
+ TOBN(0x473e339e, 0xfd083999), TOBN(0x6c94bdde, 0x8e796802),
+ TOBN(0x5a304ada, 0x8545d185), TOBN(0x82ae44ea, 0x738bb8cb),
+ TOBN(0x628a35e3, 0xdf87e10e), TOBN(0xd3624f3d, 0xa15b9fe3),
+ TOBN(0xcc44209b, 0x14be4254), TOBN(0x7d0efcbc, 0xbdbc2ea5),
+ TOBN(0x1f603362, 0x04c37bbe), TOBN(0x21f363f5, 0x56a5852c),
+ TOBN(0xa1503d1c, 0xa8501550), TOBN(0x2251e0e1, 0xd8ab10bb),
+ TOBN(0xde129c96, 0x6961c51c), TOBN(0x1f7246a4, 0x81910f68),
+ TOBN(0x2eb744ee, 0x5f2591f2), TOBN(0x3c47d33f, 0x5e627157),
+ TOBN(0x4d6d62c9, 0x22f3bd68), TOBN(0x6120a64b, 0xcb8df856),
+ TOBN(0x3a9ac6c0, 0x7b5d07df), TOBN(0xa92b9558, 0x7ef39783),
+ TOBN(0xe128a134, 0xab3a9b4f), TOBN(0x41c18807, 0xb1252f05),
+ TOBN(0xfc7ed089, 0x80ba9b1c), TOBN(0xac8dc6de, 0xc532a9dd),
+ TOBN(0xbf829cef, 0x55246809), TOBN(0x101b784f, 0x5b4ee80f),
+ TOBN(0xc09945bb, 0xb6f11603), TOBN(0x57b09dbe, 0x41d2801e),
+ TOBN(0xfba5202f, 0xa97534a8), TOBN(0x7fd8ae5f, 0xc17b9614),
+ TOBN(0xa50ba666, 0x78308435), TOBN(0x9572f77c, 0xd3868c4d),
+ TOBN(0x0cef7bfd, 0x2dd7aab0), TOBN(0xe7958e08, 0x2c7c79ff),
+ TOBN(0x81262e42, 0x25346689), TOBN(0x716da290, 0xb07c7004),
+ TOBN(0x35f911ea, 0xb7950ee3), TOBN(0x6fd72969, 0x261d21b5),
+ TOBN(0x52389803, 0x08b640d3), TOBN(0x5b0026ee, 0x887f12a1),
+ TOBN(0x20e21660, 0x742e9311), TOBN(0x0ef6d541, 0x5ff77ff7),
+ TOBN(0x969127f0, 0xf9c41135), TOBN(0xf21d60c9, 0x68a64993),
+ TOBN(0x656e5d0c, 0xe541875c), TOBN(0xf1e0f84e, 0xa1d3c233),
+ TOBN(0x9bcca359, 0x06002d60), TOBN(0xbe2da60c, 0x06191552),
+ TOBN(0x5da8bbae, 0x61181ec3), TOBN(0x9f04b823, 0x65806f19),
+ TOBN(0xf1604a7d, 0xd4b79bb8), TOBN(0xaee806fb, 0x52c878c8),
+ TOBN(0x34144f11, 0x8d47b8e8), TOBN(0x72edf52b, 0x949f9054),
+ TOBN(0xebfca84e, 0x2127015a), TOBN(0x9051d0c0, 0x9cb7cef3),
+ TOBN(0x86e8fe58, 0x296deec8), TOBN(0x33b28188, 0x41010d74),
+ },
+ {
+ TOBN(0x01079383, 0x171b445f), TOBN(0x9bcf21e3, 0x8131ad4c),
+ TOBN(0x8cdfe205, 0xc93987e8), TOBN(0xe63f4152, 0xc92e8c8f),
+ TOBN(0x729462a9, 0x30add43d), TOBN(0x62ebb143, 0xc980f05a),
+ TOBN(0x4f3954e5, 0x3b06e968), TOBN(0xfe1d75ad, 0x242cf6b1),
+ TOBN(0x5f95c6c7, 0xaf8685c8), TOBN(0xd4c1c8ce, 0x2f8f01aa),
+ TOBN(0xc44bbe32, 0x2574692a), TOBN(0xb8003478, 0xd4a4a068),
+ TOBN(0x7c8fc6e5, 0x2eca3cdb), TOBN(0xea1db16b, 0xec04d399),
+ TOBN(0xb05bc82e, 0x8f2bc5cf), TOBN(0x763d517f, 0xf44793d2),
+ TOBN(0x4451c1b8, 0x08bd98d0), TOBN(0x644b1cd4, 0x6575f240),
+ TOBN(0x6907eb33, 0x7375d270), TOBN(0x56c8bebd, 0xfa2286bd),
+ TOBN(0xc713d2ac, 0xc4632b46), TOBN(0x17da427a, 0xafd60242),
+ TOBN(0x313065b7, 0xc95c7546), TOBN(0xf8239898, 0xbf17a3de),
+ TOBN(0xf3b7963f, 0x4c830320), TOBN(0x842c7aa0, 0x903203e3),
+ TOBN(0xaf22ca0a, 0xe7327afb), TOBN(0x38e13092, 0x967609b6),
+ TOBN(0x73b8fb62, 0x757558f1), TOBN(0x3cc3e831, 0xf7eca8c1),
+ TOBN(0xe4174474, 0xf6331627), TOBN(0xa77989ca, 0xc3c40234),
+ TOBN(0xe5fd17a1, 0x44a081e0), TOBN(0xd797fb7d, 0xb70e296a),
+ TOBN(0x2b472b30, 0x481f719c), TOBN(0x0e632a98, 0xfe6f8c52),
+ TOBN(0x89ccd116, 0xc5f0c284), TOBN(0xf51088af, 0x2d987c62),
+ TOBN(0x2a2bccda, 0x4c2de6cf), TOBN(0x810f9efe, 0xf679f0f9),
+ TOBN(0xb0f394b9, 0x7ffe4b3e), TOBN(0x0b691d21, 0xe5fa5d21),
+ TOBN(0xb0bd7747, 0x9dfbbc75), TOBN(0xd2830fda, 0xfaf78b00),
+ TOBN(0xf78c249c, 0x52434f57), TOBN(0x4b1f7545, 0x98096dab),
+ TOBN(0x73bf6f94, 0x8ff8c0b3), TOBN(0x34aef03d, 0x454e134c),
+ TOBN(0xf8d151f4, 0xb7ac7ec5), TOBN(0xd6ceb95a, 0xe50da7d5),
+ TOBN(0xa1b492b0, 0xdc3a0eb8), TOBN(0x75157b69, 0xb3dd2863),
+ TOBN(0xe2c4c74e, 0xc5413d62), TOBN(0xbe329ff7, 0xbc5fc4c7),
+ TOBN(0x835a2aea, 0x60fa9dda), TOBN(0xf117f5ad, 0x7445cb87),
+ TOBN(0xae8317f4, 0xb0166f7a), TOBN(0xfbd3e3f7, 0xceec74e6),
+ TOBN(0xfdb516ac, 0xe0874bfd), TOBN(0x3d846019, 0xc681f3a3),
+ TOBN(0x0b12ee5c, 0x7c1620b0), TOBN(0xba68b4dd, 0x2b63c501),
+ TOBN(0xac03cd32, 0x6668c51e), TOBN(0x2a6279f7, 0x4e0bcb5b),
+ TOBN(0x17bd69b0, 0x6ae85c10), TOBN(0x72946979, 0x1dfdd3a6),
+ TOBN(0xd9a03268, 0x2c078bec), TOBN(0x41c6a658, 0xbfd68a52),
+ TOBN(0xcdea1024, 0x0e023900), TOBN(0xbaeec121, 0xb10d144d),
+ TOBN(0x5a600e74, 0x058ab8dc), TOBN(0x1333af21, 0xbb89ccdd),
+ TOBN(0xdf25eae0, 0x3aaba1f1), TOBN(0x2cada16e, 0x3b7144cf),
+ TOBN(0x657ee27d, 0x71ab98bc), TOBN(0x99088b4c, 0x7a6fc96e),
+ TOBN(0x05d5c0a0, 0x3549dbd4), TOBN(0x42cbdf8f, 0xf158c3ac),
+ TOBN(0x3fb6b3b0, 0x87edd685), TOBN(0x22071cf6, 0x86f064d0),
+ TOBN(0xd2d6721f, 0xff2811e5), TOBN(0xdb81b703, 0xfe7fae8c),
+ TOBN(0x3cfb74ef, 0xd3f1f7bb), TOBN(0x0cdbcd76, 0x16cdeb5d),
+ TOBN(0x4f39642a, 0x566a808c), TOBN(0x02b74454, 0x340064d6),
+ TOBN(0xfabbadca, 0x0528fa6f), TOBN(0xe4c3074c, 0xd3fc0bb6),
+ TOBN(0xb32cb8b0, 0xb796d219), TOBN(0xc3e95f4f, 0x34741dd9),
+ TOBN(0x87212125, 0x68edf6f5), TOBN(0x7a03aee4, 0xa2b9cb8e),
+ TOBN(0x0cd3c376, 0xf53a89aa), TOBN(0x0d8af9b1, 0x948a28dc),
+ TOBN(0xcf86a3f4, 0x902ab04f), TOBN(0x8aacb62a, 0x7f42002d),
+ TOBN(0x106985eb, 0xf62ffd52), TOBN(0xe670b54e, 0x5797bf10),
+ TOBN(0x4b405209, 0xc5e30aef), TOBN(0x12c97a20, 0x4365b5e9),
+ TOBN(0x104646ce, 0x1fe32093), TOBN(0x13cb4ff6, 0x3907a8c9),
+ TOBN(0x8b9f30d1, 0xd46e726b), TOBN(0xe1985e21, 0xaba0f499),
+ TOBN(0xc573dea9, 0x10a230cd), TOBN(0x24f46a93, 0xcd30f947),
+ TOBN(0xf2623fcf, 0xabe2010a), TOBN(0x3f278cb2, 0x73f00e4f),
+ TOBN(0xed55c67d, 0x50b920eb), TOBN(0xf1cb9a2d, 0x8e760571),
+ TOBN(0x7c50d109, 0x0895b709), TOBN(0x4207cf07, 0x190d4369),
+ TOBN(0x3b027e81, 0xc4127fe1), TOBN(0xa9f8b9ad, 0x3ae9c566),
+ TOBN(0x5ab10851, 0xacbfbba5), TOBN(0xa747d648, 0x569556f5),
+ TOBN(0xcc172b5c, 0x2ba97bf7), TOBN(0x15e0f77d, 0xbcfa3324),
+ TOBN(0xa345b797, 0x7686279d), TOBN(0x5a723480, 0xe38003d3),
+ TOBN(0xfd8e139f, 0x8f5fcda8), TOBN(0xf3e558c4, 0xbdee5bfd),
+ TOBN(0xd76cbaf4, 0xe33f9f77), TOBN(0x3a4c97a4, 0x71771969),
+ TOBN(0xda27e84b, 0xf6dce6a7), TOBN(0xff373d96, 0x13e6c2d1),
+ TOBN(0xf115193c, 0xd759a6e9), TOBN(0x3f9b7025, 0x63d2262c),
+ TOBN(0xd9764a31, 0x317cd062), TOBN(0x30779d8e, 0x199f8332),
+ TOBN(0xd8074106, 0x16b11b0b), TOBN(0x7917ab9f, 0x78aeaed8),
+ TOBN(0xb67a9cbe, 0x28fb1d8e), TOBN(0x2e313563, 0x136eda33),
+ TOBN(0x010b7069, 0xa371a86c), TOBN(0x44d90fa2, 0x6744e6b7),
+ TOBN(0x68190867, 0xd6b3e243), TOBN(0x9fe6cd9d, 0x59048c48),
+ TOBN(0xb900b028, 0x95731538), TOBN(0xa012062f, 0x32cae04f),
+ TOBN(0x8107c8bc, 0x9399d082), TOBN(0x47e8c54a, 0x41df12e2),
+ TOBN(0x14ba5117, 0xb6ef3f73), TOBN(0x22260bea, 0x81362f0b),
+ TOBN(0x90ea261e, 0x1a18cc20), TOBN(0x2192999f, 0x2321d636),
+ TOBN(0xef64d314, 0xe311b6a0), TOBN(0xd7401e4c, 0x3b54a1f5),
+ TOBN(0x19019983, 0x6fbca2ba), TOBN(0x46ad3293, 0x8fbffc4b),
+ TOBN(0xa142d3f6, 0x3786bf40), TOBN(0xeb5cbc26, 0xb67039fc),
+ TOBN(0x9cb0ae6c, 0x252bd479), TOBN(0x05e0f88a, 0x12b5848f),
+ TOBN(0x78f6d2b2, 0xa5c97663), TOBN(0x6f6e149b, 0xc162225c),
+ TOBN(0xe602235c, 0xde601a89), TOBN(0xd17bbe98, 0xf373be1f),
+ TOBN(0xcaf49a5b, 0xa8471827), TOBN(0x7e1a0a85, 0x18aaa116),
+ TOBN(0x6c833196, 0x270580c3), TOBN(0x1e233839, 0xf1c98a14),
+ TOBN(0x67b2f7b4, 0xae34e0a5), TOBN(0x47ac8745, 0xd8ce7289),
+ TOBN(0x2b74779a, 0x100dd467), TOBN(0x274a4337, 0x4ee50d09),
+ TOBN(0x603dcf13, 0x83608bc9), TOBN(0xcd9da6c3, 0xc89e8388),
+ TOBN(0x2660199f, 0x355116ac), TOBN(0xcc38bb59, 0xb6d18eed),
+ TOBN(0x3075f31f, 0x2f4bc071), TOBN(0x9774457f, 0x265dc57e),
+ TOBN(0x06a6a9c8, 0xc6db88bb), TOBN(0x6429d07f, 0x4ec98e04),
+ TOBN(0x8d05e57b, 0x05ecaa8b), TOBN(0x20f140b1, 0x7872ea7b),
+ TOBN(0xdf8c0f09, 0xca494693), TOBN(0x48d3a020, 0xf252e909),
+ TOBN(0x4c5c29af, 0x57b14b12), TOBN(0x7e6fa37d, 0xbf47ad1c),
+ TOBN(0x66e7b506, 0x49a0c938), TOBN(0xb72c0d48, 0x6be5f41f),
+ TOBN(0x6a6242b8, 0xb2359412), TOBN(0xcd35c774, 0x8e859480),
+ TOBN(0x12536fea, 0x87baa627), TOBN(0x58c1fec1, 0xf72aa680),
+ TOBN(0x6c29b637, 0x601e5dc9), TOBN(0x9e3c3c1c, 0xde9e01b9),
+ TOBN(0xefc8127b, 0x2bcfe0b0), TOBN(0x35107102, 0x2a12f50d),
+ TOBN(0x6ccd6cb1, 0x4879b397), TOBN(0xf792f804, 0xf8a82f21),
+ TOBN(0x509d4804, 0xa9b46402), TOBN(0xedddf85d, 0xc10f0850),
+ TOBN(0x928410dc, 0x4b6208aa), TOBN(0xf6229c46, 0x391012dc),
+ TOBN(0xc5a7c41e, 0x7727b9b6), TOBN(0x289e4e4b, 0xaa444842),
+ TOBN(0x049ba1d9, 0xe9a947ea), TOBN(0x44f9e47f, 0x83c8debc),
+ TOBN(0xfa77a1fe, 0x611f8b8e), TOBN(0xfd2e416a, 0xf518f427),
+ TOBN(0xc5fffa70, 0x114ebac3), TOBN(0xfe57c4e9, 0x5d89697b),
+ TOBN(0xfdd053ac, 0xb1aaf613), TOBN(0x31df210f, 0xea585a45),
+ TOBN(0x318cc10e, 0x24985034), TOBN(0x1a38efd1, 0x5f1d6130),
+ TOBN(0xbf86f237, 0x0b1e9e21), TOBN(0xb258514d, 0x1dbe88aa),
+ TOBN(0x1e38a588, 0x90c1baf9), TOBN(0x2936a01e, 0xbdb9b692),
+ TOBN(0xd576de98, 0x6dd5b20c), TOBN(0xb586bf71, 0x70f98ecf),
+ TOBN(0xcccf0f12, 0xc42d2fd7), TOBN(0x8717e61c, 0xfb35bd7b),
+ TOBN(0x8b1e5722, 0x35e6fc06), TOBN(0x3477728f, 0x0b3e13d5),
+ TOBN(0x150c294d, 0xaa8a7372), TOBN(0xc0291d43, 0x3bfa528a),
+ TOBN(0xc6c8bc67, 0xcec5a196), TOBN(0xdeeb31e4, 0x5c2e8a7c),
+ TOBN(0xba93e244, 0xfb6e1c51), TOBN(0xb9f8b71b, 0x2e28e156),
+ TOBN(0xce65a287, 0x968a2ab9), TOBN(0xe3c5ce69, 0x46bbcb1f),
+ TOBN(0xf8c835b9, 0xe7ae3f30), TOBN(0x16bbee26, 0xff72b82b),
+ TOBN(0x665e2017, 0xfd42cd22), TOBN(0x1e139970, 0xf8b1d2a0),
+ TOBN(0x125cda29, 0x79204932), TOBN(0x7aee94a5, 0x49c3bee5),
+ TOBN(0x68c70160, 0x89821a66), TOBN(0xf7c37678, 0x8f981669),
+ TOBN(0xd90829fc, 0x48cc3645), TOBN(0x346af049, 0xd70addfc),
+ TOBN(0x2057b232, 0x370bf29c), TOBN(0xf90c73ce, 0x42e650ee),
+ TOBN(0xe03386ea, 0xa126ab90), TOBN(0x0e266e7e, 0x975a087b),
+ TOBN(0x80578eb9, 0x0fca65d9), TOBN(0x7e2989ea, 0x16af45b8),
+ TOBN(0x7438212d, 0xcac75a4e), TOBN(0x38c7ca39, 0x4fef36b8),
+ TOBN(0x8650c494, 0xd402676a), TOBN(0x26ab5a66, 0xf72c7c48),
+ TOBN(0x4e6cb426, 0xce3a464e), TOBN(0xf8f99896, 0x2b72f841),
+ TOBN(0x8c318491, 0x1a335cc8), TOBN(0x563459ba, 0x6a5913e4),
+ TOBN(0x1b920d61, 0xc7b32919), TOBN(0x805ab8b6, 0xa02425ad),
+ TOBN(0x2ac512da, 0x8d006086), TOBN(0x6ca4846a, 0xbcf5c0fd),
+ TOBN(0xafea51d8, 0xac2138d7), TOBN(0xcb647545, 0x344cd443),
+ TOBN(0x0429ee8f, 0xbd7d9040), TOBN(0xee66a2de, 0x819b9c96),
+ TOBN(0x54f9ec25, 0xdea7d744), TOBN(0x2ffea642, 0x671721bb),
+ TOBN(0x4f19dbd1, 0x114344ea), TOBN(0x04304536, 0xfd0dbc8b),
+ TOBN(0x014b50aa, 0x29ec7f91), TOBN(0xb5fc22fe, 0xbb06014d),
+ TOBN(0x60d963a9, 0x1ee682e0), TOBN(0xdf48abc0, 0xfe85c727),
+ TOBN(0x0cadba13, 0x2e707c2d), TOBN(0xde608d3a, 0xa645aeff),
+ TOBN(0x05f1c28b, 0xedafd883), TOBN(0x3c362ede, 0xbd94de1f),
+ TOBN(0x8dd0629d, 0x13593e41), TOBN(0x0a5e736f, 0x766d6eaf),
+ TOBN(0xbfa92311, 0xf68cf9d1), TOBN(0xa4f9ef87, 0xc1797556),
+ TOBN(0x10d75a1f, 0x5601c209), TOBN(0x651c374c, 0x09b07361),
+ TOBN(0x49950b58, 0x88b5cead), TOBN(0x0ef00058, 0x6fa9dbaa),
+ TOBN(0xf51ddc26, 0x4e15f33a), TOBN(0x1f8b5ca6, 0x2ef46140),
+ TOBN(0x343ac0a3, 0xee9523f0), TOBN(0xbb75eab2, 0x975ea978),
+ TOBN(0x1bccf332, 0x107387f4), TOBN(0x790f9259, 0x9ab0062e),
+ TOBN(0xf1a363ad, 0x1e4f6a5f), TOBN(0x06e08b84, 0x62519a50),
+ TOBN(0x60915187, 0x7265f1ee), TOBN(0x6a80ca34, 0x93ae985e),
+ TOBN(0x81b29768, 0xaaba4864), TOBN(0xb13cabf2, 0x8d52a7d6),
+ TOBN(0xb5c36348, 0x8ead03f1), TOBN(0xc932ad95, 0x81c7c1c0),
+ TOBN(0x5452708e, 0xcae1e27b), TOBN(0x9dac4269, 0x1b0df648),
+ TOBN(0x233e3f0c, 0xdfcdb8bc), TOBN(0xe6ceccdf, 0xec540174),
+ TOBN(0xbd0d845e, 0x95081181), TOBN(0xcc8a7920, 0x699355d5),
+ TOBN(0x111c0f6d, 0xc3b375a8), TOBN(0xfd95bc6b, 0xfd51e0dc),
+ TOBN(0x4a106a26, 0x6888523a), TOBN(0x4d142bd6, 0xcb01a06d),
+ TOBN(0x79bfd289, 0xadb9b397), TOBN(0x0bdbfb94, 0xe9863914),
+ TOBN(0x29d8a229, 0x1660f6a6), TOBN(0x7f6abcd6, 0x551c042d),
+ TOBN(0x13039deb, 0x0ac3ffe8), TOBN(0xa01be628, 0xec8523fb),
+ TOBN(0x6ea34103, 0x0ca1c328), TOBN(0xc74114bd, 0xb903928e),
+ TOBN(0x8aa4ff4e, 0x9e9144b0), TOBN(0x7064091f, 0x7f9a4b17),
+ TOBN(0xa3f4f521, 0xe447f2c4), TOBN(0x81b8da7a, 0x604291f0),
+ TOBN(0xd680bc46, 0x7d5926de), TOBN(0x84f21fd5, 0x34a1202f),
+ TOBN(0x1d1e3181, 0x4e9df3d8), TOBN(0x1ca4861a, 0x39ab8d34),
+ TOBN(0x809ddeec, 0x5b19aa4a), TOBN(0x59f72f7e, 0x4d329366),
+ TOBN(0xa2f93f41, 0x386d5087), TOBN(0x40bf739c, 0xdd67d64f),
+ TOBN(0xb4494205, 0x66702158), TOBN(0xc33c65be, 0x73b1e178),
+ TOBN(0xcdcd657c, 0x38ca6153), TOBN(0x97f4519a, 0xdc791976),
+ TOBN(0xcc7c7f29, 0xcd6e1f39), TOBN(0x38de9cfb, 0x7e3c3932),
+ TOBN(0xe448eba3, 0x7b793f85), TOBN(0xe9f8dbf9, 0xf067e914),
+ TOBN(0xc0390266, 0xf114ae87), TOBN(0x39ed75a7, 0xcd6a8e2a),
+ TOBN(0xadb14848, 0x7ffba390), TOBN(0x67f8cb8b, 0x6af9bc09),
+ TOBN(0x322c3848, 0x9c7476db), TOBN(0xa320fecf, 0x52a538d6),
+ TOBN(0xe0493002, 0xb2aced2b), TOBN(0xdfba1809, 0x616bd430),
+ TOBN(0x531c4644, 0xc331be70), TOBN(0xbc04d32e, 0x90d2e450),
+ TOBN(0x1805a0d1, 0x0f9f142d), TOBN(0x2c44a0c5, 0x47ee5a23),
+ TOBN(0x31875a43, 0x3989b4e3), TOBN(0x6b1949fd, 0x0c063481),
+ TOBN(0x2dfb9e08, 0xbe0f4492), TOBN(0x3ff0da03, 0xe9d5e517),
+ TOBN(0x03dbe9a1, 0xf79466a8), TOBN(0x0b87bcd0, 0x15ea9932),
+ TOBN(0xeb64fc83, 0xab1f58ab), TOBN(0x6d9598da, 0x817edc8a),
+ TOBN(0x699cff66, 0x1d3b67e5), TOBN(0x645c0f29, 0x92635853),
+ TOBN(0x253cdd82, 0xeabaf21c), TOBN(0x82b9602a, 0x2241659e),
+ TOBN(0x2cae07ec, 0x2d9f7091), TOBN(0xbe4c720c, 0x8b48cd9b),
+ TOBN(0x6ce5bc03, 0x6f08d6c9), TOBN(0x36e8a997, 0xaf10bf40),
+ TOBN(0x83422d21, 0x3e10ff12), TOBN(0x7b26d3eb, 0xbcc12494),
+ TOBN(0xb240d2d0, 0xc9469ad6), TOBN(0xc4a11b4d, 0x30afa05b),
+ TOBN(0x4b604ace, 0xdd6ba286), TOBN(0x18486600, 0x3ee2864c),
+ TOBN(0x5869d6ba, 0x8d9ce5be), TOBN(0x0d8f68c5, 0xff4bfb0d),
+ TOBN(0xb69f210b, 0x5700cf73), TOBN(0x61f6653a, 0x6d37c135),
+ TOBN(0xff3d432b, 0x5aff5a48), TOBN(0x0d81c4b9, 0x72ba3a69),
+ TOBN(0xee879ae9, 0xfa1899ef), TOBN(0xbac7e2a0, 0x2d6acafd),
+ TOBN(0xd6d93f6c, 0x1c664399), TOBN(0x4c288de1, 0x5bcb135d),
+ TOBN(0x83031dab, 0x9dab7cbf), TOBN(0xfe23feb0, 0x3abbf5f0),
+ TOBN(0x9f1b2466, 0xcdedca85), TOBN(0x140bb710, 0x1a09538c),
+ TOBN(0xac8ae851, 0x5e11115d), TOBN(0x0d63ff67, 0x6f03f59e),
+ TOBN(0x755e5551, 0x7d234afb), TOBN(0x61c2db4e, 0x7e208fc1),
+ TOBN(0xaa9859ce, 0xf28a4b5d), TOBN(0xbdd6d4fc, 0x34af030f),
+ TOBN(0xd1c4a26d, 0x3be01cb1), TOBN(0x9ba14ffc, 0x243aa07c),
+ TOBN(0xf95cd3a9, 0xb2503502), TOBN(0xe379bc06, 0x7d2a93ab),
+ TOBN(0x3efc18e9, 0xd4ca8d68), TOBN(0x083558ec, 0x80bb412a),
+ TOBN(0xd903b940, 0x9645a968), TOBN(0xa499f0b6, 0x9ba6054f),
+ TOBN(0x208b573c, 0xb8349abe), TOBN(0x3baab3e5, 0x30b4fc1c),
+ TOBN(0x87e978ba, 0xcb524990), TOBN(0x3524194e, 0xccdf0e80),
+ TOBN(0x62711725, 0x7d4bcc42), TOBN(0xe90a3d9b, 0xb90109ba),
+ TOBN(0x3b1bdd57, 0x1323e1e0), TOBN(0xb78e9bd5, 0x5eae1599),
+ TOBN(0x0794b746, 0x9e03d278), TOBN(0x80178605, 0xd70e6297),
+ TOBN(0x171792f8, 0x99c97855), TOBN(0x11b393ee, 0xf5a86b5c),
+ TOBN(0x48ef6582, 0xd8884f27), TOBN(0xbd44737a, 0xbf19ba5f),
+ TOBN(0x8698de4c, 0xa42062c6), TOBN(0x8975eb80, 0x61ce9c54),
+ TOBN(0xd50e57c7, 0xd7fe71f3), TOBN(0x15342190, 0xbc97ce38),
+ TOBN(0x51bda2de, 0x4df07b63), TOBN(0xba12aeae, 0x200eb87d),
+ TOBN(0xabe135d2, 0xa9b4f8f6), TOBN(0x04619d65, 0xfad6d99c),
+ TOBN(0x4a6683a7, 0x7994937c), TOBN(0x7a778c8b, 0x6f94f09a),
+ TOBN(0x8c508623, 0x20a71b89), TOBN(0x241a2aed, 0x1c229165),
+ TOBN(0x352be595, 0xaaf83a99), TOBN(0x9fbfee7f, 0x1562bac8),
+ TOBN(0xeaf658b9, 0x5c4017e3), TOBN(0x1dc7f9e0, 0x15120b86),
+ TOBN(0xd84f13dd, 0x4c034d6f), TOBN(0x283dd737, 0xeaea3038),
+ TOBN(0x197f2609, 0xcd85d6a2), TOBN(0x6ebbc345, 0xfae60177),
+ TOBN(0xb80f031b, 0x4e12fede), TOBN(0xde55d0c2, 0x07a2186b),
+ TOBN(0x1fb3e37f, 0x24dcdd5a), TOBN(0x8d602da5, 0x7ed191fb),
+ TOBN(0x108fb056, 0x76023e0d), TOBN(0x70178c71, 0x459c20c0),
+ TOBN(0xfad5a386, 0x3fe54cf0), TOBN(0xa4a3ec4f, 0x02bbb475),
+ TOBN(0x1aa5ec20, 0x919d94d7), TOBN(0x5d3b63b5, 0xa81e4ab3),
+ TOBN(0x7fa733d8, 0x5ad3d2af), TOBN(0xfbc586dd, 0xd1ac7a37),
+ TOBN(0x282925de, 0x40779614), TOBN(0xfe0ffffb, 0xe74a242a),
+ TOBN(0x3f39e67f, 0x906151e5), TOBN(0xcea27f5f, 0x55e10649),
+ TOBN(0xdca1d4e1, 0xc17cf7b7), TOBN(0x0c326d12, 0x2fe2362d),
+ TOBN(0x05f7ac33, 0x7dd35df3), TOBN(0x0c3b7639, 0xc396dbdf),
+ TOBN(0x0912f5ac, 0x03b7db1c), TOBN(0x9dea4b70, 0x5c9ed4a9),
+ TOBN(0x475e6e53, 0xaae3f639), TOBN(0xfaba0e7c, 0xfc278bac),
+ TOBN(0x16f9e221, 0x9490375f), TOBN(0xaebf9746, 0xa5a7ed0a),
+ TOBN(0x45f9af3f, 0xf41ad5d6), TOBN(0x03c4623c, 0xb2e99224),
+ TOBN(0x82c5bb5c, 0xb3cf56aa), TOBN(0x64311819, 0x34567ed3),
+ TOBN(0xec57f211, 0x8be489ac), TOBN(0x2821895d, 0xb9a1104b),
+ TOBN(0x610dc875, 0x6064e007), TOBN(0x8e526f3f, 0x5b20d0fe),
+ TOBN(0x6e71ca77, 0x5b645aee), TOBN(0x3d1dcb9f, 0x800e10ff),
+ TOBN(0x36b51162, 0x189cf6de), TOBN(0x2c5a3e30, 0x6bb17353),
+ TOBN(0xc186cd3e, 0x2a6c6fbf), TOBN(0xa74516fa, 0x4bf97906),
+ TOBN(0x5b4b8f4b, 0x279d6901), TOBN(0x0c4e57b4, 0x2b573743),
+ TOBN(0x75fdb229, 0xb6e386b6), TOBN(0xb46793fd, 0x99deac27),
+ TOBN(0xeeec47ea, 0xcf712629), TOBN(0xe965f3c4, 0xcbc3b2dd),
+ TOBN(0x8dd1fb83, 0x425c6559), TOBN(0x7fc00ee6, 0x0af06fda),
+ TOBN(0xe98c9225, 0x33d956df), TOBN(0x0f1ef335, 0x4fbdc8a2),
+ TOBN(0x2abb5145, 0xb79b8ea2), TOBN(0x40fd2945, 0xbdbff288),
+ TOBN(0x6a814ac4, 0xd7185db7), TOBN(0xc4329d6f, 0xc084609a),
+ TOBN(0xc9ba7b52, 0xed1be45d), TOBN(0x891dd20d, 0xe4cd2c74),
+ TOBN(0x5a4d4a7f, 0x824139b1), TOBN(0x66c17716, 0xb873c710),
+ TOBN(0x5e5bc141, 0x2843c4e0), TOBN(0xd5ac4817, 0xb97eb5bf),
+ TOBN(0xc0f8af54, 0x450c95c7), TOBN(0xc91b3fa0, 0x318406c5),
+ TOBN(0x360c340a, 0xab9d97f8), TOBN(0xfb57bd07, 0x90a2d611),
+ TOBN(0x4339ae3c, 0xa6a6f7e5), TOBN(0x9c1fcd2a, 0x2feb8a10),
+ TOBN(0x972bcca9, 0xc7ea7432), TOBN(0x1b0b924c, 0x308076f6),
+ TOBN(0x80b2814a, 0x2a5b4ca5), TOBN(0x2f78f55b, 0x61ef3b29),
+ TOBN(0xf838744a, 0xc18a414f), TOBN(0xc611eaae, 0x903d0a86),
+ TOBN(0x94dabc16, 0x2a453f55), TOBN(0xe6f2e3da, 0x14efb279),
+ TOBN(0x5b7a6017, 0x9320dc3c), TOBN(0x692e382f, 0x8df6b5a4),
+ TOBN(0x3f5e15e0, 0x2d40fa90), TOBN(0xc87883ae, 0x643dd318),
+ TOBN(0x511053e4, 0x53544774), TOBN(0x834d0ecc, 0x3adba2bc),
+ TOBN(0x4215d7f7, 0xbae371f5), TOBN(0xfcfd57bf, 0x6c8663bc),
+ TOBN(0xded2383d, 0xd6901b1d), TOBN(0x3b49fbb4, 0xb5587dc3),
+ TOBN(0xfd44a08d, 0x07625f62), TOBN(0x3ee4d65b, 0x9de9b762),
+ },
+ {
+ TOBN(0x64e5137d, 0x0d63d1fa), TOBN(0x658fc052, 0x02a9d89f),
+ TOBN(0x48894874, 0x50436309), TOBN(0xe9ae30f8, 0xd598da61),
+ TOBN(0x2ed710d1, 0x818baf91), TOBN(0xe27e9e06, 0x8b6a0c20),
+ TOBN(0x1e28dcfb, 0x1c1a6b44), TOBN(0x883acb64, 0xd6ac57dc),
+ TOBN(0x8735728d, 0xc2c6ff70), TOBN(0x79d6122f, 0xc5dc2235),
+ TOBN(0x23f5d003, 0x19e277f9), TOBN(0x7ee84e25, 0xdded8cc7),
+ TOBN(0x91a8afb0, 0x63cd880a), TOBN(0x3f3ea7c6, 0x3574af60),
+ TOBN(0x0cfcdc84, 0x02de7f42), TOBN(0x62d0792f, 0xb31aa152),
+ TOBN(0x8e1b4e43, 0x8a5807ce), TOBN(0xad283893, 0xe4109a7e),
+ TOBN(0xc30cc9cb, 0xafd59dda), TOBN(0xf65f36c6, 0x3d8d8093),
+ TOBN(0xdf31469e, 0xa60d32b2), TOBN(0xee93df4b, 0x3e8191c8),
+ TOBN(0x9c1017c5, 0x355bdeb5), TOBN(0xd2623185, 0x8616aa28),
+ TOBN(0xb02c83f9, 0xdec31a21), TOBN(0x988c8b23, 0x6ad9d573),
+ TOBN(0x53e983ae, 0xa57be365), TOBN(0xe968734d, 0x646f834e),
+ TOBN(0x9137ea8f, 0x5da6309b), TOBN(0x10f3a624, 0xc1f1ce16),
+ TOBN(0x782a9ea2, 0xca440921), TOBN(0xdf94739e, 0x5b46f1b5),
+ TOBN(0x9f9be006, 0xcce85c9b), TOBN(0x360e70d6, 0xa4c7c2d3),
+ TOBN(0x2cd5beea, 0xaefa1e60), TOBN(0x64cf63c0, 0x8c3d2b6d),
+ TOBN(0xfb107fa3, 0xe1cf6f90), TOBN(0xb7e937c6, 0xd5e044e6),
+ TOBN(0x74e8ca78, 0xce34db9f), TOBN(0x4f8b36c1, 0x3e210bd0),
+ TOBN(0x1df165a4, 0x34a35ea8), TOBN(0x3418e0f7, 0x4d4412f6),
+ TOBN(0x5af1f8af, 0x518836c3), TOBN(0x42ceef4d, 0x130e1965),
+ TOBN(0x5560ca0b, 0x543a1957), TOBN(0xc33761e5, 0x886cb123),
+ TOBN(0x66624b1f, 0xfe98ed30), TOBN(0xf772f4bf, 0x1090997d),
+ TOBN(0xf4e540bb, 0x4885d410), TOBN(0x7287f810, 0x9ba5f8d7),
+ TOBN(0x22d0d865, 0xde98dfb1), TOBN(0x49ff51a1, 0xbcfbb8a3),
+ TOBN(0xb6b6fa53, 0x6bc3012e), TOBN(0x3d31fd72, 0x170d541d),
+ TOBN(0x8018724f, 0x4b0f4966), TOBN(0x79e7399f, 0x87dbde07),
+ TOBN(0x56f8410e, 0xf4f8b16a), TOBN(0x97241afe, 0xc47b266a),
+ TOBN(0x0a406b8e, 0x6d9c87c1), TOBN(0x803f3e02, 0xcd42ab1b),
+ TOBN(0x7f0309a8, 0x04dbec69), TOBN(0xa83b85f7, 0x3bbad05f),
+ TOBN(0xc6097273, 0xad8e197f), TOBN(0xc097440e, 0x5067adc1),
+ TOBN(0x730eafb6, 0x3524ff16), TOBN(0xd7f9b51e, 0x823fc6ce),
+ TOBN(0x27bd0d32, 0x443e4ac0), TOBN(0x40c59ad9, 0x4d66f217),
+ TOBN(0x6c33136f, 0x17c387a4), TOBN(0x5043b8d5, 0xeb86804d),
+ TOBN(0x74970312, 0x675a73c9), TOBN(0x838fdb31, 0xf16669b6),
+ TOBN(0xc507b6dd, 0x418e7ddd), TOBN(0x39888d93, 0x472f19d6),
+ TOBN(0x7eae26be, 0x0c27eb4d), TOBN(0x17b53ed3, 0xfbabb884),
+ TOBN(0xfc27021b, 0x2b01ae4f), TOBN(0x88462e87, 0xcf488682),
+ TOBN(0xbee096ec, 0x215e2d87), TOBN(0xeb2fea9a, 0xd242e29b),
+ TOBN(0x5d985b5f, 0xb821fc28), TOBN(0x89d2e197, 0xdc1e2ad2),
+ TOBN(0x55b566b8, 0x9030ba62), TOBN(0xe3fd41b5, 0x4f41b1c6),
+ TOBN(0xb738ac2e, 0xb9a96d61), TOBN(0x7f8567ca, 0x369443f4),
+ TOBN(0x8698622d, 0xf803a440), TOBN(0x2b586236, 0x8fe2f4dc),
+ TOBN(0xbbcc00c7, 0x56b95bce), TOBN(0x5ec03906, 0x616da680),
+ TOBN(0x79162ee6, 0x72214252), TOBN(0x43132b63, 0x86a892d2),
+ TOBN(0x4bdd3ff2, 0x2f3263bf), TOBN(0xd5b3733c, 0x9cd0a142),
+ TOBN(0x592eaa82, 0x44415ccb), TOBN(0x663e8924, 0x8d5474ea),
+ TOBN(0x8058a25e, 0x5236344e), TOBN(0x82e8df9d, 0xbda76ee6),
+ TOBN(0xdcf6efd8, 0x11cc3d22), TOBN(0x00089cda, 0x3b4ab529),
+ TOBN(0x91d3a071, 0xbd38a3db), TOBN(0x4ea97fc0, 0xef72b925),
+ TOBN(0x0c9fc15b, 0xea3edf75), TOBN(0x5a6297cd, 0xa4348ed3),
+ TOBN(0x0d38ab35, 0xce7c42d4), TOBN(0x9fd493ef, 0x82feab10),
+ TOBN(0x46056b6d, 0x82111b45), TOBN(0xda11dae1, 0x73efc5c3),
+ TOBN(0xdc740278, 0x5545a7fb), TOBN(0xbdb2601c, 0x40d507e6),
+ TOBN(0x121dfeeb, 0x7066fa58), TOBN(0x214369a8, 0x39ae8c2a),
+ TOBN(0x195709cb, 0x06e0956c), TOBN(0x4c9d254f, 0x010cd34b),
+ TOBN(0xf51e13f7, 0x0471a532), TOBN(0xe19d6791, 0x1e73054d),
+ TOBN(0xf702a628, 0xdb5c7be3), TOBN(0xc7141218, 0xb24dde05),
+ TOBN(0xdc18233c, 0xf29b2e2e), TOBN(0x3a6bd1e8, 0x85342dba),
+ TOBN(0x3f747fa0, 0xb311898c), TOBN(0xe2a272e4, 0xcd0eac65),
+ TOBN(0x4bba5851, 0xf914d0bc), TOBN(0x7a1a9660, 0xc4a43ee3),
+ TOBN(0xe5a367ce, 0xa1c8cde9), TOBN(0x9d958ba9, 0x7271abe3),
+ TOBN(0xf3ff7eb6, 0x3d1615cd), TOBN(0xa2280dce, 0xf5ae20b0),
+ TOBN(0x56dba5c1, 0xcf640147), TOBN(0xea5a2e3d, 0x5e83d118),
+ TOBN(0x04cd6b6d, 0xda24c511), TOBN(0x1c0f4671, 0xe854d214),
+ TOBN(0x91a6b7a9, 0x69565381), TOBN(0xdc966240, 0xdecf1f5b),
+ TOBN(0x1b22d21c, 0xfcf5d009), TOBN(0x2a05f641, 0x9021dbd5),
+ TOBN(0x8c0ed566, 0xd4312483), TOBN(0x5179a95d, 0x643e216f),
+ TOBN(0xcc185fec, 0x17044493), TOBN(0xb3063339, 0x54991a21),
+ TOBN(0xd801ecdb, 0x0081a726), TOBN(0x0149b0c6, 0x4fa89bbb),
+ TOBN(0xafe9065a, 0x4391b6b9), TOBN(0xedc92786, 0xd633f3a3),
+ TOBN(0xe408c24a, 0xae6a8e13), TOBN(0x85833fde, 0x9f3897ab),
+ TOBN(0x43800e7e, 0xd81a0715), TOBN(0xde08e346, 0xb44ffc5f),
+ TOBN(0x7094184c, 0xcdeff2e0), TOBN(0x49f9387b, 0x165eaed1),
+ TOBN(0x635d6129, 0x777c468a), TOBN(0x8c0dcfd1, 0x538c2dd8),
+ TOBN(0xd6d9d9e3, 0x7a6a308b), TOBN(0x62375830, 0x4c2767d3),
+ TOBN(0x874a8bc6, 0xf38cbeb6), TOBN(0xd94d3f1a, 0xccb6fd9e),
+ TOBN(0x92a9735b, 0xba21f248), TOBN(0x272ad0e5, 0x6cd1efb0),
+ TOBN(0x7437b69c, 0x05b03284), TOBN(0xe7f04702, 0x6948c225),
+ TOBN(0x8a56c04a, 0xcba2ecec), TOBN(0x0c181270, 0xe3a73e41),
+ TOBN(0x6cb34e9d, 0x03e93725), TOBN(0xf77c8713, 0x496521a9),
+ TOBN(0x94569183, 0xfa7f9f90), TOBN(0xf2e7aa4c, 0x8c9707ad),
+ TOBN(0xced2c9ba, 0x26c1c9a3), TOBN(0x9109fe96, 0x40197507),
+ TOBN(0x9ae868a9, 0xe9adfe1c), TOBN(0x3984403d, 0x314e39bb),
+ TOBN(0xb5875720, 0xf2fe378f), TOBN(0x33f901e0, 0xba44a628),
+ TOBN(0xea1125fe, 0x3652438c), TOBN(0xae9ec4e6, 0x9dd1f20b),
+ TOBN(0x1e740d9e, 0xbebf7fbd), TOBN(0x6dbd3ddc, 0x42dbe79c),
+ TOBN(0x62082aec, 0xedd36776), TOBN(0xf612c478, 0xe9859039),
+ TOBN(0xa493b201, 0x032f7065), TOBN(0xebd4d8f2, 0x4ff9b211),
+ TOBN(0x3f23a0aa, 0xaac4cb32), TOBN(0xea3aadb7, 0x15ed4005),
+ TOBN(0xacf17ea4, 0xafa27e63), TOBN(0x56125c1a, 0xc11fd66c),
+ TOBN(0x266344a4, 0x3794f8dc), TOBN(0xdcca923a, 0x483c5c36),
+ TOBN(0x2d6b6bbf, 0x3f9d10a0), TOBN(0xb320c5ca, 0x81d9bdf3),
+ TOBN(0x620e28ff, 0x47b50a95), TOBN(0x933e3b01, 0xcef03371),
+ TOBN(0xf081bf85, 0x99100153), TOBN(0x183be9a0, 0xc3a8c8d6),
+ TOBN(0x4e3ddc5a, 0xd6bbe24d), TOBN(0xc6c74630, 0x53843795),
+ TOBN(0x78193dd7, 0x65ec2d4c), TOBN(0xb8df26cc, 0xcd3c89b2),
+ TOBN(0x98dbe399, 0x5a483f8d), TOBN(0x72d8a957, 0x7dd3313a),
+ TOBN(0x65087294, 0xab0bd375), TOBN(0xfcd89248, 0x7c259d16),
+ TOBN(0x8a9443d7, 0x7613aa81), TOBN(0x80100800, 0x85fe6584),
+ TOBN(0x70fc4dbc, 0x7fb10288), TOBN(0xf58280d3, 0xe86beee8),
+ TOBN(0x14fdd82f, 0x7c978c38), TOBN(0xdf1204c1, 0x0de44d7b),
+ TOBN(0xa08a1c84, 0x4160252f), TOBN(0x591554ca, 0xc17646a5),
+ TOBN(0x214a37d6, 0xa05bd525), TOBN(0x48d5f09b, 0x07957b3c),
+ TOBN(0x0247cdcb, 0xd7109bc9), TOBN(0x40f9e4bb, 0x30599ce7),
+ TOBN(0xc325fa03, 0xf46ad2ec), TOBN(0x00f766cf, 0xc3e3f9ee),
+ TOBN(0xab556668, 0xd43a4577), TOBN(0x68d30a61, 0x3ee03b93),
+ TOBN(0x7ddc81ea, 0x77b46a08), TOBN(0xcf5a6477, 0xc7480699),
+ TOBN(0x43a8cb34, 0x6633f683), TOBN(0x1b867e6b, 0x92363c60),
+ TOBN(0x43921114, 0x1f60558e), TOBN(0xcdbcdd63, 0x2f41450e),
+ TOBN(0x7fc04601, 0xcc630e8b), TOBN(0xea7c66d5, 0x97038b43),
+ TOBN(0x7259b8a5, 0x04e99fd8), TOBN(0x98a8dd12, 0x4785549a),
+ TOBN(0x0e459a7c, 0x840552e1), TOBN(0xcdfcf4d0, 0x4bb0909e),
+ TOBN(0x34a86db2, 0x53758da7), TOBN(0xe643bb83, 0xeac997e1),
+ TOBN(0x96400bd7, 0x530c5b7e), TOBN(0x9f97af87, 0xb41c8b52),
+ TOBN(0x34fc8820, 0xfbeee3f9), TOBN(0x93e53490, 0x49091afd),
+ TOBN(0x764b9be5, 0x9a31f35c), TOBN(0x71f37864, 0x57e3d924),
+ TOBN(0x02fb34e0, 0x943aa75e), TOBN(0xa18c9c58, 0xab8ff6e4),
+ TOBN(0x080f31b1, 0x33cf0d19), TOBN(0x5c9682db, 0x083518a7),
+ TOBN(0x873d4ca6, 0xb709c3de), TOBN(0x64a84262, 0x3575b8f0),
+ TOBN(0x6275da1f, 0x020154bb), TOBN(0x97678caa, 0xd17cf1ab),
+ TOBN(0x8779795f, 0x951a95c3), TOBN(0xdd35b163, 0x50fccc08),
+ TOBN(0x32709627, 0x33d8f031), TOBN(0x3c5ab10a, 0x498dd85c),
+ TOBN(0xb6c185c3, 0x41dca566), TOBN(0x7de7feda, 0xd8622aa3),
+ TOBN(0x99e84d92, 0x901b6dfb), TOBN(0x30a02b0e, 0x7c4ad288),
+ TOBN(0xc7c81daa, 0x2fd3cf36), TOBN(0xd1319547, 0xdf89e59f),
+ TOBN(0xb2be8184, 0xcd496733), TOBN(0xd5f449eb, 0x93d3412b),
+ TOBN(0x7ea41b1b, 0x25fe531d), TOBN(0xf9797432, 0x6a1d5646),
+ TOBN(0x86067f72, 0x2bde501a), TOBN(0xf91481c0, 0x0c85e89c),
+ TOBN(0xca8ee465, 0xf8b05bc6), TOBN(0x1844e1cf, 0x02e83cda),
+ TOBN(0xca82114a, 0xb4dbe33b), TOBN(0x0f9f8769, 0x4eabfde2),
+ TOBN(0x4936b1c0, 0x38b27fe2), TOBN(0x63b6359b, 0xaba402df),
+ TOBN(0x40c0ea2f, 0x656bdbab), TOBN(0x9c992a89, 0x6580c39c),
+ TOBN(0x600e8f15, 0x2a60aed1), TOBN(0xeb089ca4, 0xe0bf49df),
+ TOBN(0x9c233d7d, 0x2d42d99a), TOBN(0x648d3f95, 0x4c6bc2fa),
+ TOBN(0xdcc383a8, 0xe1add3f3), TOBN(0xf42c0c6a, 0x4f64a348),
+ TOBN(0x2abd176f, 0x0030dbdb), TOBN(0x4de501a3, 0x7d6c215e),
+ TOBN(0x4a107c1f, 0x4b9a64bc), TOBN(0xa77f0ad3, 0x2496cd59),
+ TOBN(0xfb78ac62, 0x7688dffb), TOBN(0x7025a2ca, 0x67937d8e),
+ TOBN(0xfde8b2d1, 0xd1a8f4e7), TOBN(0xf5b3da47, 0x7354927c),
+ TOBN(0xe48606a3, 0xd9205735), TOBN(0xac477cc6, 0xe177b917),
+ TOBN(0xfb1f73d2, 0xa883239a), TOBN(0xe12572f6, 0xcc8b8357),
+ TOBN(0x9d355e9c, 0xfb1f4f86), TOBN(0x89b795f8, 0xd9f3ec6e),
+ TOBN(0x27be56f1, 0xb54398dc), TOBN(0x1890efd7, 0x3fedeed5),
+ TOBN(0x62f77f1f, 0x9c6d0140), TOBN(0x7ef0e314, 0x596f0ee4),
+ TOBN(0x50ca6631, 0xcc61dab3), TOBN(0x4a39801d, 0xf4866e4f),
+ TOBN(0x66c8d032, 0xae363b39), TOBN(0x22c591e5, 0x2ead66aa),
+ TOBN(0x954ba308, 0xde02a53e), TOBN(0x2a6c060f, 0xd389f357),
+ TOBN(0xe6cfcde8, 0xfbf40b66), TOBN(0x8e02fc56, 0xc6340ce1),
+ TOBN(0xe4957795, 0x73adb4ba), TOBN(0x7b86122c, 0xa7b03805),
+ TOBN(0x63f83512, 0x0c8e6fa6), TOBN(0x83660ea0, 0x057d7804),
+ TOBN(0xbad79105, 0x21ba473c), TOBN(0xb6c50bee, 0xded5389d),
+ TOBN(0xee2caf4d, 0xaa7c9bc0), TOBN(0xd97b8de4, 0x8c4e98a7),
+ TOBN(0xa9f63e70, 0xab3bbddb), TOBN(0x3898aabf, 0x2597815a),
+ TOBN(0x7659af89, 0xac15b3d9), TOBN(0xedf7725b, 0x703ce784),
+ TOBN(0x25470fab, 0xe085116b), TOBN(0x04a43375, 0x87285310),
+ TOBN(0x4e39187e, 0xe2bfd52f), TOBN(0x36166b44, 0x7d9ebc74),
+ TOBN(0x92ad433c, 0xfd4b322c), TOBN(0x726aa817, 0xba79ab51),
+ TOBN(0xf96eacd8, 0xc1db15eb), TOBN(0xfaf71e91, 0x0476be63),
+ TOBN(0xdd69a640, 0x641fad98), TOBN(0xb7995918, 0x29622559),
+ TOBN(0x03c6daa5, 0xde4199dc), TOBN(0x92cadc97, 0xad545eb4),
+ TOBN(0x1028238b, 0x256534e4), TOBN(0x73e80ce6, 0x8595409a),
+ TOBN(0x690d4c66, 0xd05dc59b), TOBN(0xc95f7b8f, 0x981dee80),
+ TOBN(0xf4337014, 0xd856ac25), TOBN(0x441bd9dd, 0xac524dca),
+ TOBN(0x640b3d85, 0x5f0499f5), TOBN(0x39cf84a9, 0xd5fda182),
+ TOBN(0x04e7b055, 0xb2aa95a0), TOBN(0x29e33f0a, 0x0ddf1860),
+ TOBN(0x082e74b5, 0x423f6b43), TOBN(0x217edeb9, 0x0aaa2b0f),
+ TOBN(0x58b83f35, 0x83cbea55), TOBN(0xc485ee4d, 0xbc185d70),
+ TOBN(0x833ff03b, 0x1e5f6992), TOBN(0xb5b9b9cc, 0xcf0c0dd5),
+ TOBN(0x7caaee8e, 0x4e9e8a50), TOBN(0x462e907b, 0x6269dafd),
+ TOBN(0x6ed5cee9, 0xfbe791c6), TOBN(0x68ca3259, 0xed430790),
+ TOBN(0x2b72bdf2, 0x13b5ba88), TOBN(0x60294c8a, 0x35ef0ac4),
+ TOBN(0x9c3230ed, 0x19b99b08), TOBN(0x560fff17, 0x6c2589aa),
+ TOBN(0x552b8487, 0xd6770374), TOBN(0xa373202d, 0x9a56f685),
+ TOBN(0xd3e7f907, 0x45f175d9), TOBN(0x3c2f315f, 0xd080d810),
+ TOBN(0x1130e9dd, 0x7b9520e8), TOBN(0xc078f9e2, 0x0af037b5),
+ TOBN(0x38cd2ec7, 0x1e9c104c), TOBN(0x0f684368, 0xc472fe92),
+ TOBN(0xd3f1b5ed, 0x6247e7ef), TOBN(0xb32d33a9, 0x396dfe21),
+ TOBN(0x46f59cf4, 0x4a9aa2c2), TOBN(0x69cd5168, 0xff0f7e41),
+ TOBN(0x3f59da0f, 0x4b3234da), TOBN(0xcf0b0235, 0xb4579ebe),
+ TOBN(0x6d1cbb25, 0x6d2476c7), TOBN(0x4f0837e6, 0x9dc30f08),
+ TOBN(0x9a4075bb, 0x906f6e98), TOBN(0x253bb434, 0xc761e7d1),
+ TOBN(0xde2e645f, 0x6e73af10), TOBN(0xb89a4060, 0x0c5f131c),
+ TOBN(0xd12840c5, 0xb8cc037f), TOBN(0x3d093a5b, 0x7405bb47),
+ TOBN(0x6202c253, 0x206348b8), TOBN(0xbf5d57fc, 0xc55a3ca7),
+ TOBN(0x89f6c90c, 0x8c3bef48), TOBN(0x23ac7623, 0x5a0a960a),
+ TOBN(0xdfbd3d6b, 0x552b42ab), TOBN(0x3ef22458, 0x132061f6),
+ TOBN(0xd74e9bda, 0xc97e6516), TOBN(0x88779360, 0xc230f49e),
+ TOBN(0xa6ec1de3, 0x1e74ea49), TOBN(0x581dcee5, 0x3fb645a2),
+ TOBN(0xbaef2391, 0x8f483f14), TOBN(0x6d2dddfc, 0xd137d13b),
+ TOBN(0x54cde50e, 0xd2743a42), TOBN(0x89a34fc5, 0xe4d97e67),
+ TOBN(0x13f1f5b3, 0x12e08ce5), TOBN(0xa80540b8, 0xa7f0b2ca),
+ TOBN(0x854bcf77, 0x01982805), TOBN(0xb8653ffd, 0x233bea04),
+ TOBN(0x8e7b8787, 0x02b0b4c9), TOBN(0x2675261f, 0x9acb170a),
+ TOBN(0x061a9d90, 0x930c14e5), TOBN(0xb59b30e0, 0xdef0abea),
+ TOBN(0x1dc19ea6, 0x0200ec7d), TOBN(0xb6f4a3f9, 0x0bce132b),
+ TOBN(0xb8d5de90, 0xf13e27e0), TOBN(0xbaee5ef0, 0x1fade16f),
+ TOBN(0x6f406aaa, 0xe4c6cf38), TOBN(0xab4cfe06, 0xd1369815),
+ TOBN(0x0dcffe87, 0xefd550c6), TOBN(0x9d4f59c7, 0x75ff7d39),
+ TOBN(0xb02553b1, 0x51deb6ad), TOBN(0x812399a4, 0xb1877749),
+ TOBN(0xce90f71f, 0xca6006e1), TOBN(0xc32363a6, 0xb02b6e77),
+ TOBN(0x02284fbe, 0xdc36c64d), TOBN(0x86c81e31, 0xa7e1ae61),
+ TOBN(0x2576c7e5, 0xb909d94a), TOBN(0x8b6f7d02, 0x818b2bb0),
+ TOBN(0xeca3ed07, 0x56faa38a), TOBN(0xa3790e6c, 0x9305bb54),
+ TOBN(0xd784eeda, 0x7bc73061), TOBN(0xbd56d369, 0x6dd50614),
+ TOBN(0xd6575949, 0x229a8aa9), TOBN(0xdcca8f47, 0x4595ec28),
+ TOBN(0x814305c1, 0x06ab4fe6), TOBN(0xc8c39768, 0x24f43f16),
+ TOBN(0xe2a45f36, 0x523f2b36), TOBN(0x995c6493, 0x920d93bb),
+ TOBN(0xf8afdab7, 0x90f1632b), TOBN(0x79ebbecd, 0x1c295954),
+ TOBN(0xc7bb3ddb, 0x79592f48), TOBN(0x67216a7b, 0x5f88e998),
+ TOBN(0xd91f098b, 0xbc01193e), TOBN(0xf7d928a5, 0xb1db83fc),
+ TOBN(0x55e38417, 0xe991f600), TOBN(0x2a91113e, 0x2981a934),
+ TOBN(0xcbc9d648, 0x06b13bde), TOBN(0xb011b6ac, 0x0755ff44),
+ TOBN(0x6f4cb518, 0x045ec613), TOBN(0x522d2d31, 0xc2f5930a),
+ TOBN(0x5acae1af, 0x382e65de), TOBN(0x57643067, 0x27bc966f),
+ TOBN(0x5e12705d, 0x1c7193f0), TOBN(0xf0f32f47, 0x3be8858e),
+ TOBN(0x785c3d7d, 0x96c6dfc7), TOBN(0xd75b4a20, 0xbf31795d),
+ TOBN(0x91acf17b, 0x342659d4), TOBN(0xe596ea34, 0x44f0378f),
+ TOBN(0x4515708f, 0xce52129d), TOBN(0x17387e1e, 0x79f2f585),
+ TOBN(0x72cfd2e9, 0x49dee168), TOBN(0x1ae05223, 0x3e2af239),
+ TOBN(0x009e75be, 0x1d94066a), TOBN(0x6cca31c7, 0x38abf413),
+ TOBN(0xb50bd61d, 0x9bc49908), TOBN(0x4a9b4a8c, 0xf5e2bc1e),
+ TOBN(0xeb6cc5f7, 0x946f83ac), TOBN(0x27da93fc, 0xebffab28),
+ TOBN(0xea314c96, 0x4821c8c5), TOBN(0x8de49ded, 0xa83c15f4),
+ TOBN(0x7a64cf20, 0x7af33004), TOBN(0x45f1bfeb, 0xc9627e10),
+ TOBN(0x878b0626, 0x54b9df60), TOBN(0x5e4fdc3c, 0xa95c0b33),
+ TOBN(0xe54a37ca, 0xc2035d8e), TOBN(0x9087cda9, 0x80f20b8c),
+ TOBN(0x36f61c23, 0x8319ade4), TOBN(0x766f287a, 0xde8cfdf8),
+ TOBN(0x48821948, 0x346f3705), TOBN(0x49a7b853, 0x16e4f4a2),
+ TOBN(0xb9b3f8a7, 0x5cedadfd), TOBN(0x8f562815, 0x8db2a815),
+ TOBN(0xc0b7d554, 0x01f68f95), TOBN(0x12971e27, 0x688a208e),
+ TOBN(0xc9f8b696, 0xd0ff34fc), TOBN(0x20824de2, 0x1222718c),
+ TOBN(0x7213cf9f, 0x0c95284d), TOBN(0xe2ad741b, 0xdc158240),
+ TOBN(0x0ee3a6df, 0x54043ccf), TOBN(0x16ff479b, 0xd84412b3),
+ TOBN(0xf6c74ee0, 0xdfc98af0), TOBN(0xa78a169f, 0x52fcd2fb),
+ TOBN(0xd8ae8746, 0x99c930e9), TOBN(0x1d33e858, 0x49e117a5),
+ TOBN(0x7581fcb4, 0x6624759f), TOBN(0xde50644f, 0x5bedc01d),
+ TOBN(0xbeec5d00, 0xcaf3155e), TOBN(0x672d66ac, 0xbc73e75f),
+ TOBN(0x86b9d8c6, 0x270b01db), TOBN(0xd249ef83, 0x50f55b79),
+ TOBN(0x6131d6d4, 0x73978fe3), TOBN(0xcc4e4542, 0x754b00a1),
+ TOBN(0x4e05df05, 0x57dfcfe9), TOBN(0x94b29cdd, 0x51ef6bf0),
+ TOBN(0xe4530cff, 0x9bc7edf2), TOBN(0x8ac236fd, 0xd3da65f3),
+ TOBN(0x0faf7d5f, 0xc8eb0b48), TOBN(0x4d2de14c, 0x660eb039),
+ TOBN(0xc006bba7, 0x60430e54), TOBN(0x10a2d0d6, 0xda3289ab),
+ TOBN(0x9c037a5d, 0xd7979c59), TOBN(0x04d1f3d3, 0xa116d944),
+ TOBN(0x9ff22473, 0x8a0983cd), TOBN(0x28e25b38, 0xc883cabb),
+ TOBN(0xe968dba5, 0x47a58995), TOBN(0x2c80b505, 0x774eebdf),
+ TOBN(0xee763b71, 0x4a953beb), TOBN(0x502e223f, 0x1642e7f6),
+ TOBN(0x6fe4b641, 0x61d5e722), TOBN(0x9d37c5b0, 0xdbef5316),
+ TOBN(0x0115ed70, 0xf8330bc7), TOBN(0x139850e6, 0x75a72789),
+ TOBN(0x27d7faec, 0xffceccc2), TOBN(0x3016a860, 0x4fd9f7f6),
+ TOBN(0xc492ec64, 0x4cd8f64c), TOBN(0x58a2d790, 0x279d7b51),
+ TOBN(0x0ced1fc5, 0x1fc75256), TOBN(0x3e658aed, 0x8f433017),
+ TOBN(0x0b61942e, 0x05da59eb), TOBN(0xba3d60a3, 0x0ddc3722),
+ TOBN(0x7c311cd1, 0x742e7f87), TOBN(0x6473ffee, 0xf6b01b6e),
+ },
+ {
+ TOBN(0x8303604f, 0x692ac542), TOBN(0xf079ffe1, 0x227b91d3),
+ TOBN(0x19f63e63, 0x15aaf9bd), TOBN(0xf99ee565, 0xf1f344fb),
+ TOBN(0x8a1d661f, 0xd6219199), TOBN(0x8c883bc6, 0xd48ce41c),
+ TOBN(0x1065118f, 0x3c74d904), TOBN(0x713889ee, 0x0faf8b1b),
+ TOBN(0x972b3f8f, 0x81a1b3be), TOBN(0x4f3ce145, 0xce2764a0),
+ TOBN(0xe2d0f1cc, 0x28c4f5f7), TOBN(0xdeee0c0d, 0xc7f3985b),
+ TOBN(0x7df4adc0, 0xd39e25c3), TOBN(0x40619820, 0xc467a080),
+ TOBN(0x440ebc93, 0x61cf5a58), TOBN(0x527729a6, 0x422ad600),
+ TOBN(0xca6c0937, 0xb1b76ba6), TOBN(0x1a2eab85, 0x4d2026dc),
+ TOBN(0xb1715e15, 0x19d9ae0a), TOBN(0xf1ad9199, 0xbac4a026),
+ TOBN(0x35b3dfb8, 0x07ea7b0e), TOBN(0xedf5496f, 0x3ed9eb89),
+ TOBN(0x8932e5ff, 0x2d6d08ab), TOBN(0xf314874e, 0x25bd2731),
+ TOBN(0xefb26a75, 0x3f73f449), TOBN(0x1d1c94f8, 0x8d44fc79),
+ TOBN(0x49f0fbc5, 0x3bc0dc4d), TOBN(0xb747ea0b, 0x3698a0d0),
+ TOBN(0x5218c3fe, 0x228d291e), TOBN(0x35b804b5, 0x43c129d6),
+ TOBN(0xfac859b8, 0xd1acc516), TOBN(0x6c10697d, 0x95d6e668),
+ TOBN(0xc38e438f, 0x0876fd4e), TOBN(0x45f0c307, 0x83d2f383),
+ TOBN(0x203cc2ec, 0xb10934cb), TOBN(0x6a8f2439, 0x2c9d46ee),
+ TOBN(0xf16b431b, 0x65ccde7b), TOBN(0x41e2cd18, 0x27e76a6f),
+ TOBN(0xb9c8cf8f, 0x4e3484d7), TOBN(0x64426efd, 0x8315244a),
+ TOBN(0x1c0a8e44, 0xfc94dea3), TOBN(0x34c8cdbf, 0xdad6a0b0),
+ TOBN(0x919c3840, 0x04113cef), TOBN(0xfd32fba4, 0x15490ffa),
+ TOBN(0x58d190f6, 0x795dcfb7), TOBN(0xfef01b03, 0x83588baf),
+ TOBN(0x9e6d1d63, 0xca1fc1c0), TOBN(0x53173f96, 0xf0a41ac9),
+ TOBN(0x2b1d402a, 0xba16f73b), TOBN(0x2fb31014, 0x8cf9b9fc),
+ TOBN(0x2d51e60e, 0x446ef7bf), TOBN(0xc731021b, 0xb91e1745),
+ TOBN(0x9d3b4724, 0x4fee99d4), TOBN(0x4bca48b6, 0xfac5c1ea),
+ TOBN(0x70f5f514, 0xbbea9af7), TOBN(0x751f55a5, 0x974c283a),
+ TOBN(0x6e30251a, 0xcb452fdb), TOBN(0x31ee6965, 0x50f30650),
+ TOBN(0xb0b3e508, 0x933548d9), TOBN(0xb8949a4f, 0xf4b0ef5b),
+ TOBN(0x208b8326, 0x3c88f3bd), TOBN(0xab147c30, 0xdb1d9989),
+ TOBN(0xed6515fd, 0x44d4df03), TOBN(0x17a12f75, 0xe72eb0c5),
+ TOBN(0x3b59796d, 0x36cf69db), TOBN(0x1219eee9, 0x56670c18),
+ TOBN(0xfe3341f7, 0x7a070d8e), TOBN(0x9b70130b, 0xa327f90c),
+ TOBN(0x36a32462, 0x0ae18e0e), TOBN(0x2021a623, 0x46c0a638),
+ TOBN(0x251b5817, 0xc62eb0d4), TOBN(0x87bfbcdf, 0x4c762293),
+ TOBN(0xf78ab505, 0xcdd61d64), TOBN(0x8c7a53fc, 0xc8c18857),
+ TOBN(0xa653ce6f, 0x16147515), TOBN(0x9c923aa5, 0xea7d52d5),
+ TOBN(0xc24709cb, 0x5c18871f), TOBN(0x7d53bec8, 0x73b3cc74),
+ TOBN(0x59264aff, 0xfdd1d4c4), TOBN(0x5555917e, 0x240da582),
+ TOBN(0xcae8bbda, 0x548f5a0e), TOBN(0x1910eaba, 0x3bbfbbe1),
+ TOBN(0xae579685, 0x7677afc3), TOBN(0x49ea61f1, 0x73ff0b5c),
+ TOBN(0x78655478, 0x4f7c3922), TOBN(0x95d337cd, 0x20c68eef),
+ TOBN(0x68f1e1e5, 0xdf779ab9), TOBN(0x14b491b0, 0xb5cf69a8),
+ TOBN(0x7a6cbbe0, 0x28e3fe89), TOBN(0xe7e1fee4, 0xc5aac0eb),
+ TOBN(0x7f47eda5, 0x697e5140), TOBN(0x4f450137, 0xb454921f),
+ TOBN(0xdb625f84, 0x95cd8185), TOBN(0x74be0ba1, 0xcdb2e583),
+ TOBN(0xaee4fd7c, 0xdd5e6de4), TOBN(0x4251437d, 0xe8101739),
+ TOBN(0x686d72a0, 0xac620366), TOBN(0x4be3fb9c, 0xb6d59344),
+ TOBN(0x6e8b44e7, 0xa1eb75b9), TOBN(0x84e39da3, 0x91a5c10c),
+ TOBN(0x37cc1490, 0xb38f0409), TOBN(0x02951943, 0x2c2ade82),
+ TOBN(0x9b688783, 0x1190a2d8), TOBN(0x25627d14, 0x231182ba),
+ TOBN(0x6eb550aa, 0x658a6d87), TOBN(0x1405aaa7, 0xcf9c7325),
+ TOBN(0xd147142e, 0x5c8748c9), TOBN(0x7f637e4f, 0x53ede0e0),
+ TOBN(0xf8ca2776, 0x14ffad2c), TOBN(0xe58fb1bd, 0xbafb6791),
+ TOBN(0x17158c23, 0xbf8f93fc), TOBN(0x7f15b373, 0x0a4a4655),
+ TOBN(0x39d4add2, 0xd842ca72), TOBN(0xa71e4391, 0x3ed96305),
+ TOBN(0x5bb09cbe, 0x6700be14), TOBN(0x68d69d54, 0xd8befcf6),
+ TOBN(0xa45f5367, 0x37183bcf), TOBN(0x7152b7bb, 0x3370dff7),
+ TOBN(0xcf887baa, 0xbf12525b), TOBN(0xe7ac7bdd, 0xd6d1e3cd),
+ TOBN(0x25914f78, 0x81fdad90), TOBN(0xcf638f56, 0x0d2cf6ab),
+ TOBN(0xb90bc03f, 0xcc054de5), TOBN(0x932811a7, 0x18b06350),
+ TOBN(0x2f00b330, 0x9bbd11ff), TOBN(0x76108a6f, 0xb4044974),
+ TOBN(0x801bb9e0, 0xa851d266), TOBN(0x0dd099be, 0xbf8990c1),
+ TOBN(0x58c5aaaa, 0xabe32986), TOBN(0x0fe9dd2a, 0x50d59c27),
+ TOBN(0x84951ff4, 0x8d307305), TOBN(0x6c23f829, 0x86529b78),
+ TOBN(0x50bb2218, 0x0b136a79), TOBN(0x7e2174de, 0x77a20996),
+ TOBN(0x6f00a4b9, 0xc0bb4da6), TOBN(0x89a25a17, 0xefdde8da),
+ TOBN(0xf728a27e, 0xc11ee01d), TOBN(0xf900553a, 0xe5f10dfb),
+ TOBN(0x189a83c8, 0x02ec893c), TOBN(0x3ca5bdc1, 0x23f66d77),
+ TOBN(0x98781537, 0x97eada9f), TOBN(0x59c50ab3, 0x10256230),
+ TOBN(0x346042d9, 0x323c69b3), TOBN(0x1b715a6d, 0x2c460449),
+ TOBN(0xa41dd476, 0x6ae06e0b), TOBN(0xcdd7888e, 0x9d42e25f),
+ TOBN(0x0f395f74, 0x56b25a20), TOBN(0xeadfe0ae, 0x8700e27e),
+ TOBN(0xb09d52a9, 0x69950093), TOBN(0x3525d9cb, 0x327f8d40),
+ TOBN(0xb8235a94, 0x67df886a), TOBN(0x77e4b0dd, 0x035faec2),
+ TOBN(0x115eb20a, 0x517d7061), TOBN(0x77fe3433, 0x6c2df683),
+ TOBN(0x6870ddc7, 0xcdc6fc67), TOBN(0xb1610588, 0x0b87de83),
+ TOBN(0x343584ca, 0xd9c4ddbe), TOBN(0xb3164f1c, 0x3d754be2),
+ TOBN(0x0731ed3a, 0xc1e6c894), TOBN(0x26327dec, 0x4f6b904c),
+ TOBN(0x9d49c6de, 0x97b5cd32), TOBN(0x40835dae, 0xb5eceecd),
+ TOBN(0xc66350ed, 0xd9ded7fe), TOBN(0x8aeebb5c, 0x7a678804),
+ TOBN(0x51d42fb7, 0x5b8ee9ec), TOBN(0xd7a17bdd, 0x8e3ca118),
+ TOBN(0x40d7511a, 0x2ef4400e), TOBN(0xc48990ac, 0x875a66f4),
+ TOBN(0x8de07d2a, 0x2199e347), TOBN(0xbee75556, 0x2a39e051),
+ TOBN(0x56918786, 0x916e51dc), TOBN(0xeb191313, 0x4a2d89ec),
+ TOBN(0x6679610d, 0x37d341ed), TOBN(0x434fbb41, 0x56d51c2b),
+ TOBN(0xe54b7ee7, 0xd7492dba), TOBN(0xaa33a79a, 0x59021493),
+ TOBN(0x49fc5054, 0xe4bd6d3d), TOBN(0x09540f04, 0x5ab551d0),
+ TOBN(0x8acc9085, 0x4942d3a6), TOBN(0x231af02f, 0x2d28323b),
+ TOBN(0x93458cac, 0x0992c163), TOBN(0x1fef8e71, 0x888e3bb4),
+ TOBN(0x27578da5, 0xbe8c268c), TOBN(0xcc8be792, 0xe805ec00),
+ TOBN(0x29267bae, 0xc61c3855), TOBN(0xebff429d, 0x58c1fd3b),
+ TOBN(0x22d886c0, 0x8c0b93b8), TOBN(0xca5e00b2, 0x2ddb8953),
+ TOBN(0xcf330117, 0xc3fed8b7), TOBN(0xd49ac6fa, 0x819c01f6),
+ TOBN(0x6ddaa6bd, 0x3c0fbd54), TOBN(0x91743068, 0x8049a2cf),
+ TOBN(0xd67f981e, 0xaff2ef81), TOBN(0xc3654d35, 0x2818ae80),
+ TOBN(0x81d05044, 0x1b2aa892), TOBN(0x2db067bf, 0x3d099328),
+ TOBN(0xe7c79e86, 0x703dcc97), TOBN(0xe66f9b37, 0xe133e215),
+ TOBN(0xcdf119a6, 0xe39a7a5c), TOBN(0x47c60de3, 0x876f1b61),
+ TOBN(0x6e405939, 0xd860f1b2), TOBN(0x3e9a1dbc, 0xf5ed4d4a),
+ TOBN(0x3f23619e, 0xc9b6bcbd), TOBN(0x5ee790cf, 0x734e4497),
+ TOBN(0xf0a834b1, 0x5bdaf9bb), TOBN(0x02cedda7, 0x4ca295f0),
+ TOBN(0x4619aa2b, 0xcb8e378c), TOBN(0xe5613244, 0xcc987ea4),
+ TOBN(0x0bc022cc, 0x76b23a50), TOBN(0x4a2793ad, 0x0a6c21ce),
+ TOBN(0x38328780, 0x89cac3f5), TOBN(0x29176f1b, 0xcba26d56),
+ TOBN(0x06296187, 0x4f6f59eb), TOBN(0x86e9bca9, 0x8bdc658e),
+ TOBN(0x2ca9c4d3, 0x57e30402), TOBN(0x5438b216, 0x516a09bb),
+ TOBN(0x0a6a063c, 0x7672765a), TOBN(0x37a3ce64, 0x0547b9bf),
+ TOBN(0x42c099c8, 0x98b1a633), TOBN(0xb5ab800d, 0x05ee6961),
+ TOBN(0xf1963f59, 0x11a5acd6), TOBN(0xbaee6157, 0x46201063),
+ TOBN(0x36d9a649, 0xa596210a), TOBN(0xaed04363, 0x1ba7138c),
+ TOBN(0xcf817d1c, 0xa4a82b76), TOBN(0x5586960e, 0xf3806be9),
+ TOBN(0x7ab67c89, 0x09dc6bb5), TOBN(0x52ace7a0, 0x114fe7eb),
+ TOBN(0xcd987618, 0xcbbc9b70), TOBN(0x4f06fd5a, 0x604ca5e1),
+ TOBN(0x90af14ca, 0x6dbde133), TOBN(0x1afe4322, 0x948a3264),
+ TOBN(0xa70d2ca6, 0xc44b2c6c), TOBN(0xab726799, 0x0ef87dfe),
+ TOBN(0x310f64dc, 0x2e696377), TOBN(0x49b42e68, 0x4c8126a0),
+ TOBN(0x0ea444c3, 0xcea0b176), TOBN(0x53a8ddf7, 0xcb269182),
+ TOBN(0xf3e674eb, 0xbbba9dcb), TOBN(0x0d2878a8, 0xd8669d33),
+ TOBN(0x04b935d5, 0xd019b6a3), TOBN(0xbb5cf88e, 0x406f1e46),
+ TOBN(0xa1912d16, 0x5b57c111), TOBN(0x9803fc21, 0x19ebfd78),
+ TOBN(0x4f231c9e, 0xc07764a9), TOBN(0xd93286ee, 0xb75bd055),
+ TOBN(0x83a9457d, 0x8ee6c9de), TOBN(0x04695915, 0x6087ec90),
+ TOBN(0x14c6dd8a, 0x58d6cd46), TOBN(0x9cb633b5, 0x8e6634d2),
+ TOBN(0xc1305047, 0xf81bc328), TOBN(0x12ede0e2, 0x26a177e5),
+ TOBN(0x332cca62, 0x065a6f4f), TOBN(0xc3a47ecd, 0x67be487b),
+ TOBN(0x741eb187, 0x0f47ed1c), TOBN(0x99e66e58, 0xe7598b14),
+ TOBN(0x6f0544ca, 0x63d0ff12), TOBN(0xe5efc784, 0xb610a05f),
+ TOBN(0xf72917b1, 0x7cad7b47), TOBN(0x3ff6ea20, 0xf2cac0c0),
+ TOBN(0xcc23791b, 0xf21db8b7), TOBN(0x7dac70b1, 0xd7d93565),
+ TOBN(0x682cda1d, 0x694bdaad), TOBN(0xeb88bb8c, 0x1023516d),
+ TOBN(0xc4c634b4, 0xdfdbeb1b), TOBN(0x22f5ca72, 0xb4ee4dea),
+ TOBN(0x1045a368, 0xe6524821), TOBN(0xed9e8a3f, 0x052b18b2),
+ TOBN(0x9b7f2cb1, 0xb961f49a), TOBN(0x7fee2ec1, 0x7b009670),
+ TOBN(0x350d8754, 0x22507a6d), TOBN(0x561bd711, 0x4db55f1d),
+ TOBN(0x4c189ccc, 0x320bbcaf), TOBN(0x568434cf, 0xdf1de48c),
+ TOBN(0x6af1b00e, 0x0fa8f128), TOBN(0xf0ba9d02, 0x8907583c),
+ TOBN(0x735a4004, 0x32ff9f60), TOBN(0x3dd8e4b6, 0xc25dcf33),
+ TOBN(0xf2230f16, 0x42c74cef), TOBN(0xd8117623, 0x013fa8ad),
+ TOBN(0x36822876, 0xf51fe76e), TOBN(0x8a6811cc, 0x11d62589),
+ TOBN(0xc3fc7e65, 0x46225718), TOBN(0xb7df2c9f, 0xc82fdbcd),
+ TOBN(0x3b1d4e52, 0xdd7b205b), TOBN(0xb6959478, 0x47a2e414),
+ TOBN(0x05e4d793, 0xefa91148), TOBN(0xb47ed446, 0xfd2e9675),
+ TOBN(0x1a7098b9, 0x04c9d9bf), TOBN(0x661e2881, 0x1b793048),
+ TOBN(0xb1a16966, 0xb01ee461), TOBN(0xbc521308, 0x2954746f),
+ TOBN(0xc909a0fc, 0x2477de50), TOBN(0xd80bb41c, 0x7dbd51ef),
+ TOBN(0xa85be7ec, 0x53294905), TOBN(0x6d465b18, 0x83958f97),
+ TOBN(0x16f6f330, 0xfb6840fd), TOBN(0xfaaeb214, 0x3401e6c8),
+ TOBN(0xaf83d30f, 0xccb5b4f8), TOBN(0x22885739, 0x266dec4b),
+ TOBN(0x51b4367c, 0x7bc467df), TOBN(0x926562e3, 0xd842d27a),
+ TOBN(0xdfcb6614, 0x0fea14a6), TOBN(0xeb394dae, 0xf2734cd9),
+ TOBN(0x3eeae5d2, 0x11c0be98), TOBN(0xb1e6ed11, 0x814e8165),
+ TOBN(0x191086bc, 0xe52bce1c), TOBN(0x14b74cc6, 0xa75a04da),
+ TOBN(0x63cf1186, 0x8c060985), TOBN(0x071047de, 0x2dbd7f7c),
+ TOBN(0x4e433b8b, 0xce0942ca), TOBN(0xecbac447, 0xd8fec61d),
+ TOBN(0x8f0ed0e2, 0xebf3232f), TOBN(0xfff80f9e, 0xc52a2edd),
+ TOBN(0xad9ab433, 0x75b55fdb), TOBN(0x73ca7820, 0xe42e0c11),
+ TOBN(0x6dace0a0, 0xe6251b46), TOBN(0x89bc6b5c, 0x4c0d932d),
+ TOBN(0x3438cd77, 0x095da19a), TOBN(0x2f24a939, 0x8d48bdfb),
+ TOBN(0x99b47e46, 0x766561b7), TOBN(0x736600e6, 0x0ed0322a),
+ TOBN(0x06a47cb1, 0x638e1865), TOBN(0x927c1c2d, 0xcb136000),
+ TOBN(0x29542337, 0x0cc5df69), TOBN(0x99b37c02, 0x09d649a9),
+ TOBN(0xc5f0043c, 0x6aefdb27), TOBN(0x6cdd9987, 0x1be95c27),
+ TOBN(0x69850931, 0x390420d2), TOBN(0x299c40ac, 0x0983efa4),
+ TOBN(0x3a05e778, 0xaf39aead), TOBN(0x84274408, 0x43a45193),
+ TOBN(0x6bcd0fb9, 0x91a711a0), TOBN(0x461592c8, 0x9f52ab17),
+ TOBN(0xb49302b4, 0xda3c6ed6), TOBN(0xc51fddc7, 0x330d7067),
+ TOBN(0x94babeb6, 0xda50d531), TOBN(0x521b840d, 0xa6a7b9da),
+ TOBN(0x5305151e, 0x404bdc89), TOBN(0x1bcde201, 0xd0d07449),
+ TOBN(0xf427a78b, 0x3b76a59a), TOBN(0xf84841ce, 0x07791a1b),
+ TOBN(0xebd314be, 0xbf91ed1c), TOBN(0x8e61d34c, 0xbf172943),
+ TOBN(0x1d5dc451, 0x5541b892), TOBN(0xb186ee41, 0xfc9d9e54),
+ TOBN(0x9d9f345e, 0xd5bf610d), TOBN(0x3e7ba65d, 0xf6acca9f),
+ TOBN(0x9dda787a, 0xa8369486), TOBN(0x09f9dab7, 0x8eb5ba53),
+ TOBN(0x5afb2033, 0xd6481bc3), TOBN(0x76f4ce30, 0xafa62104),
+ TOBN(0xa8fa00cf, 0xf4f066b5), TOBN(0x89ab5143, 0x461dafc2),
+ TOBN(0x44339ed7, 0xa3389998), TOBN(0x2ff862f1, 0xbc214903),
+ TOBN(0x2c88f985, 0xb05556e3), TOBN(0xcd96058e, 0x3467081e),
+ TOBN(0x7d6a4176, 0xedc637ea), TOBN(0xe1743d09, 0x36a5acdc),
+ TOBN(0x66fd72e2, 0x7eb37726), TOBN(0xf7fa264e, 0x1481a037),
+ TOBN(0x9fbd3bde, 0x45f4aa79), TOBN(0xed1e0147, 0x767c3e22),
+ TOBN(0x7621f979, 0x82e7abe2), TOBN(0x19eedc72, 0x45f633f8),
+ TOBN(0xe69b155e, 0x6137bf3a), TOBN(0xa0ad13ce, 0x414ee94e),
+ TOBN(0x93e3d524, 0x1c0e651a), TOBN(0xab1a6e2a, 0x02ce227e),
+ TOBN(0xe7af1797, 0x4ab27eca), TOBN(0x245446de, 0xbd444f39),
+ TOBN(0x59e22a21, 0x56c07613), TOBN(0x43deafce, 0xf4275498),
+ TOBN(0x10834ccb, 0x67fd0946), TOBN(0xa75841e5, 0x47406edf),
+ TOBN(0xebd6a677, 0x7b0ac93d), TOBN(0xa6e37b0d, 0x78f5e0d7),
+ TOBN(0x2516c096, 0x76f5492b), TOBN(0x1e4bf888, 0x9ac05f3a),
+ TOBN(0xcdb42ce0, 0x4df0ba2b), TOBN(0x935d5cfd, 0x5062341b),
+ TOBN(0x8a303333, 0x82acac20), TOBN(0x429438c4, 0x5198b00e),
+ TOBN(0x1d083bc9, 0x049d33fa), TOBN(0x58b82dda, 0x946f67ff),
+ TOBN(0xac3e2db8, 0x67a1d6a3), TOBN(0x62e6bead, 0x1798aac8),
+ TOBN(0xfc85980f, 0xde46c58c), TOBN(0xa7f69379, 0x69c8d7be),
+ TOBN(0x23557927, 0x837b35ec), TOBN(0x06a933d8, 0xe0790c0c),
+ TOBN(0x827c0e9b, 0x077ff55d), TOBN(0x53977798, 0xbb26e680),
+ TOBN(0x59530874, 0x1d9cb54f), TOBN(0xcca3f449, 0x4aac53ef),
+ TOBN(0x11dc5c87, 0xa07eda0f), TOBN(0xc138bccf, 0xfd6400c8),
+ TOBN(0x549680d3, 0x13e5da72), TOBN(0xc93eed82, 0x4540617e),
+ TOBN(0xfd3db157, 0x4d0b75c0), TOBN(0x9716eb42, 0x6386075b),
+ TOBN(0x0639605c, 0x817b2c16), TOBN(0x09915109, 0xf1e4f201),
+ TOBN(0x35c9a928, 0x5cca6c3b), TOBN(0xb25f7d1a, 0x3505c900),
+ TOBN(0xeb9f7d20, 0x630480c4), TOBN(0xc3c7b8c6, 0x2a1a501c),
+ TOBN(0x3f99183c, 0x5a1f8e24), TOBN(0xfdb118fa, 0x9dd255f0),
+ TOBN(0xb9b18b90, 0xc27f62a6), TOBN(0xe8f732f7, 0x396ec191),
+ TOBN(0x524a2d91, 0x0be786ab), TOBN(0x5d32adef, 0x0ac5a0f5),
+ TOBN(0x9b53d4d6, 0x9725f694), TOBN(0x032a76c6, 0x0510ba89),
+ TOBN(0x840391a3, 0xebeb1544), TOBN(0x44b7b88c, 0x3ed73ac3),
+ TOBN(0xd24bae7a, 0x256cb8b3), TOBN(0x7ceb151a, 0xe394cb12),
+ TOBN(0xbd6b66d0, 0x5bc1e6a8), TOBN(0xec70cecb, 0x090f07bf),
+ TOBN(0x270644ed, 0x7d937589), TOBN(0xee9e1a3d, 0x5f1dccfe),
+ TOBN(0xb0d40a84, 0x745b98d2), TOBN(0xda429a21, 0x2556ed40),
+ TOBN(0xf676eced, 0x85148cb9), TOBN(0x5a22d40c, 0xded18936),
+ TOBN(0x3bc4b9e5, 0x70e8a4ce), TOBN(0xbfd1445b, 0x9eae0379),
+ TOBN(0xf23f2c0c, 0x1a0bd47e), TOBN(0xa9c0bb31, 0xe1845531),
+ TOBN(0x9ddc4d60, 0x0a4c3f6b), TOBN(0xbdfaad79, 0x2c15ef44),
+ TOBN(0xce55a236, 0x7f484acc), TOBN(0x08653ca7, 0x055b1f15),
+ TOBN(0x2efa8724, 0x538873a3), TOBN(0x09299e5d, 0xace1c7e7),
+ TOBN(0x07afab66, 0xade332ba), TOBN(0x9be1fdf6, 0x92dd71b7),
+ TOBN(0xa49b5d59, 0x5758b11c), TOBN(0x0b852893, 0xc8654f40),
+ TOBN(0xb63ef6f4, 0x52379447), TOBN(0xd4957d29, 0x105e690c),
+ TOBN(0x7d484363, 0x646559b0), TOBN(0xf4a8273c, 0x49788a8e),
+ TOBN(0xee406cb8, 0x34ce54a9), TOBN(0x1e1c260f, 0xf86fda9b),
+ TOBN(0xe150e228, 0xcf6a4a81), TOBN(0x1fa3b6a3, 0x1b488772),
+ TOBN(0x1e6ff110, 0xc5a9c15b), TOBN(0xc6133b91, 0x8ad6aa47),
+ TOBN(0x8ac5d55c, 0x9dffa978), TOBN(0xba1d1c1d, 0x5f3965f2),
+ TOBN(0xf969f4e0, 0x7732b52f), TOBN(0xfceecdb5, 0xa5172a07),
+ TOBN(0xb0120a5f, 0x10f2b8f5), TOBN(0xc83a6cdf, 0x5c4c2f63),
+ TOBN(0x4d47a491, 0xf8f9c213), TOBN(0xd9e1cce5, 0xd3f1bbd5),
+ TOBN(0x0d91bc7c, 0xaba7e372), TOBN(0xfcdc74c8, 0xdfd1a2db),
+ TOBN(0x05efa800, 0x374618e5), TOBN(0x11216969, 0x15a7925e),
+ TOBN(0xd4c89823, 0xf6021c5d), TOBN(0x880d5e84, 0xeff14423),
+ TOBN(0x6523bc5a, 0x6dcd1396), TOBN(0xd1acfdfc, 0x113c978b),
+ TOBN(0xb0c164e8, 0xbbb66840), TOBN(0xf7f4301e, 0x72b58459),
+ TOBN(0xc29ad4a6, 0xa638e8ec), TOBN(0xf5ab8961, 0x46b78699),
+ TOBN(0x9dbd7974, 0x0e954750), TOBN(0x0121de88, 0x64f9d2c6),
+ TOBN(0x2e597b42, 0xd985232e), TOBN(0x55b6c3c5, 0x53451777),
+ TOBN(0xbb53e547, 0x519cb9fb), TOBN(0xf134019f, 0x8428600d),
+ TOBN(0x5a473176, 0xe081791a), TOBN(0x2f3e2263, 0x35fb0c08),
+ TOBN(0xb28c3017, 0x73d273b0), TOBN(0xccd21076, 0x7721ef9a),
+ TOBN(0x054cc292, 0xb650dc39), TOBN(0x662246de, 0x6188045e),
+ TOBN(0x904b52fa, 0x6b83c0d1), TOBN(0xa72df267, 0x97e9cd46),
+ TOBN(0x886b43cd, 0x899725e4), TOBN(0x2b651688, 0xd849ff22),
+ TOBN(0x60479b79, 0x02f34533), TOBN(0x5e354c14, 0x0c77c148),
+ TOBN(0xb4bb7581, 0xa8537c78), TOBN(0x188043d7, 0xefe1495f),
+ TOBN(0x9ba12f42, 0x8c1d5026), TOBN(0x2e0c8a26, 0x93d4aaab),
+ TOBN(0xbdba7b8b, 0xaa57c450), TOBN(0x140c9ad6, 0x9bbdafef),
+ TOBN(0x2067aa42, 0x25ac0f18), TOBN(0xf7b1295b, 0x04d1fbf3),
+ TOBN(0x14829111, 0xa4b04824), TOBN(0x2ce3f192, 0x33bd5e91),
+ TOBN(0x9c7a1d55, 0x8f2e1b72), TOBN(0xfe932286, 0x302aa243),
+ TOBN(0x497ca7b4, 0xd4be9554), TOBN(0xb8e821b8, 0xe0547a6e),
+ TOBN(0xfb2838be, 0x67e573e0), TOBN(0x05891db9, 0x4084c44b),
+ TOBN(0x91311373, 0x96c1c2c5), TOBN(0x6aebfa3f, 0xd958444b),
+ TOBN(0xac9cdce9, 0xe56e55c1), TOBN(0x7148ced3, 0x2caa46d0),
+ TOBN(0x2e10c7ef, 0xb61fe8eb), TOBN(0x9fd835da, 0xff97cf4d),
+ },
+ {
+ TOBN(0xa36da109, 0x081e9387), TOBN(0xfb9780d7, 0x8c935828),
+ TOBN(0xd5940332, 0xe540b015), TOBN(0xc9d7b51b, 0xe0f466fa),
+ TOBN(0xfaadcd41, 0xd6d9f671), TOBN(0xba6c1e28, 0xb1a2ac17),
+ TOBN(0x066a7833, 0xed201e5f), TOBN(0x19d99719, 0xf90f462b),
+ TOBN(0xf431f462, 0x060b5f61), TOBN(0xa56f46b4, 0x7bd057c2),
+ TOBN(0x348dca6c, 0x47e1bf65), TOBN(0x9a38783e, 0x41bcf1ff),
+ TOBN(0x7a5d33a9, 0xda710718), TOBN(0x5a779987, 0x2e0aeaf6),
+ TOBN(0xca87314d, 0x2d29d187), TOBN(0xfa0edc3e, 0xc687d733),
+ TOBN(0x9df33621, 0x6a31e09b), TOBN(0xde89e44d, 0xc1350e35),
+ TOBN(0x29214871, 0x4ca0cf52), TOBN(0xdf379672, 0x0b88a538),
+ TOBN(0xc92a510a, 0x2591d61b), TOBN(0x79aa87d7, 0x585b447b),
+ TOBN(0xf67db604, 0xe5287f77), TOBN(0x1697c8bf, 0x5efe7a80),
+ TOBN(0x1c894849, 0xcb198ac7), TOBN(0xa884a93d, 0x0f264665),
+ TOBN(0x2da964ef, 0x9b200678), TOBN(0x3c351b87, 0x009834e6),
+ TOBN(0xafb2ef9f, 0xe2c4b44b), TOBN(0x580f6c47, 0x3326790c),
+ TOBN(0xb8480521, 0x0b02264a), TOBN(0x8ba6f9e2, 0x42a194e2),
+ TOBN(0xfc87975f, 0x8fb54738), TOBN(0x35160788, 0x27c3ead3),
+ TOBN(0x834116d2, 0xb74a085a), TOBN(0x53c99a73, 0xa62fe996),
+ TOBN(0x87585be0, 0x5b81c51b), TOBN(0x925bafa8, 0xbe0852b7),
+ TOBN(0x76a4fafd, 0xa84d19a7), TOBN(0x39a45982, 0x585206d4),
+ TOBN(0x499b6ab6, 0x5eb03c0e), TOBN(0xf19b7954, 0x72bc3fde),
+ TOBN(0xa86b5b9c, 0x6e3a80d2), TOBN(0xe4377508, 0x6d42819f),
+ TOBN(0xc1663650, 0xbb3ee8a3), TOBN(0x75eb14fc, 0xb132075f),
+ TOBN(0xa8ccc906, 0x7ad834f6), TOBN(0xea6a2474, 0xe6e92ffd),
+ TOBN(0x9d72fd95, 0x0f8d6758), TOBN(0xcb84e101, 0x408c07dd),
+ TOBN(0xb9114bfd, 0xa5e23221), TOBN(0x358b5fe2, 0xe94e742c),
+ TOBN(0x1c0577ec, 0x95f40e75), TOBN(0xf0155451, 0x3d73f3d6),
+ TOBN(0x9d55cd67, 0xbd1b9b66), TOBN(0x63e86e78, 0xaf8d63c7),
+ TOBN(0x39d934ab, 0xd3c095f1), TOBN(0x04b261be, 0xe4b76d71),
+ TOBN(0x1d2e6970, 0xe73e6984), TOBN(0x879fb23b, 0x5e5fcb11),
+ TOBN(0x11506c72, 0xdfd75490), TOBN(0x3a97d085, 0x61bcf1c1),
+ TOBN(0x43201d82, 0xbf5e7007), TOBN(0x7f0ac52f, 0x798232a7),
+ TOBN(0x2715cbc4, 0x6eb564d4), TOBN(0x8d6c752c, 0x9e570e29),
+ TOBN(0xf80247c8, 0x9ef5fd5d), TOBN(0xc3c66b46, 0xd53eb514),
+ TOBN(0x9666b401, 0x0f87de56), TOBN(0xce62c06f, 0xc6c603b5),
+ TOBN(0xae7b4c60, 0x7e4fc942), TOBN(0x38ac0b77, 0x663a9c19),
+ TOBN(0xcb4d20ee, 0x4b049136), TOBN(0x8b63bf12, 0x356a4613),
+ TOBN(0x1221aef6, 0x70e08128), TOBN(0xe62d8c51, 0x4acb6b16),
+ TOBN(0x71f64a67, 0x379e7896), TOBN(0xb25237a2, 0xcafd7fa5),
+ TOBN(0xf077bd98, 0x3841ba6a), TOBN(0xc4ac0244, 0x3cd16e7e),
+ TOBN(0x548ba869, 0x21fea4ca), TOBN(0xd36d0817, 0xf3dfdac1),
+ TOBN(0x09d8d71f, 0xf4685faf), TOBN(0x8eff66be, 0xc52c459a),
+ TOBN(0x182faee7, 0x0b57235e), TOBN(0xee3c39b1, 0x0106712b),
+ TOBN(0x5107331f, 0xc0fcdcb0), TOBN(0x669fb9dc, 0xa51054ba),
+ TOBN(0xb25101fb, 0x319d7682), TOBN(0xb0293129, 0x0a982fee),
+ TOBN(0x51c1c9b9, 0x0261b344), TOBN(0x0e008c5b, 0xbfd371fa),
+ TOBN(0xd866dd1c, 0x0278ca33), TOBN(0x666f76a6, 0xe5aa53b1),
+ TOBN(0xe5cfb779, 0x6013a2cf), TOBN(0x1d3a1aad, 0xa3521836),
+ TOBN(0xcedd2531, 0x73faa485), TOBN(0xc8ee6c4f, 0xc0a76878),
+ TOBN(0xddbccfc9, 0x2a11667d), TOBN(0x1a418ea9, 0x1c2f695a),
+ TOBN(0xdb11bd92, 0x51f73971), TOBN(0x3e4b3c82, 0xda2ed89f),
+ TOBN(0x9a44f3f4, 0xe73e0319), TOBN(0xd1e3de0f, 0x303431af),
+ TOBN(0x3c5604ff, 0x50f75f9c), TOBN(0x1d8eddf3, 0x7e752b22),
+ TOBN(0x0ef074dd, 0x3c9a1118), TOBN(0xd0ffc172, 0xccb86d7b),
+ TOBN(0xabd1ece3, 0x037d90f2), TOBN(0xe3f307d6, 0x6055856c),
+ TOBN(0x422f9328, 0x7e4c6daf), TOBN(0x902aac66, 0x334879a0),
+ TOBN(0xb6a1e7bf, 0x94cdfade), TOBN(0x6c97e1ed, 0x7fc6d634),
+ TOBN(0x662ad24d, 0xa2fb63f8), TOBN(0xf81be1b9, 0xa5928405),
+ TOBN(0x86d765e4, 0xd14b4206), TOBN(0xbecc2e0e, 0x8fa0db65),
+ TOBN(0xa28838e0, 0xb17fc76c), TOBN(0xe49a602a, 0xe37cf24e),
+ TOBN(0x76b4131a, 0x567193ec), TOBN(0xaf3c305a, 0xe5f6e70b),
+ TOBN(0x9587bd39, 0x031eebdd), TOBN(0x5709def8, 0x71bbe831),
+ TOBN(0x57059983, 0x0eb2b669), TOBN(0x4d80ce1b, 0x875b7029),
+ TOBN(0x838a7da8, 0x0364ac16), TOBN(0x2f431d23, 0xbe1c83ab),
+ TOBN(0xe56812a6, 0xf9294dd3), TOBN(0xb448d01f, 0x9b4b0d77),
+ TOBN(0xf3ae6061, 0x04e8305c), TOBN(0x2bead645, 0x94d8c63e),
+ TOBN(0x0a85434d, 0x84fd8b07), TOBN(0x537b983f, 0xf7a9dee5),
+ TOBN(0xedcc5f18, 0xef55bd85), TOBN(0x2041af62, 0x21c6cf8b),
+ TOBN(0x8e52874c, 0xb940c71e), TOBN(0x211935a9, 0xdb5f4b3a),
+ TOBN(0x94350492, 0x301b1dc3), TOBN(0x33d2646d, 0x29958620),
+ TOBN(0x16b0d64b, 0xef911404), TOBN(0x9d1f25ea, 0x9a3c5ef4),
+ TOBN(0x20f200eb, 0x4a352c78), TOBN(0x43929f2c, 0x4bd0b428),
+ TOBN(0xa5656667, 0xc7196e29), TOBN(0x7992c2f0, 0x9391be48),
+ TOBN(0xaaa97cbd, 0x9ee0cd6e), TOBN(0x51b0310c, 0x3dc8c9bf),
+ TOBN(0x237f8acf, 0xdd9f22cb), TOBN(0xbb1d81a1, 0xb585d584),
+ TOBN(0x8d5d85f5, 0x8c416388), TOBN(0x0d6e5a5a, 0x42fe474f),
+ TOBN(0xe7812766, 0x38235d4e), TOBN(0x1c62bd67, 0x496e3298),
+ TOBN(0x8378660c, 0x3f175bc8), TOBN(0x4d04e189, 0x17afdd4d),
+ TOBN(0x32a81601, 0x85a8068c), TOBN(0xdb58e4e1, 0x92b29a85),
+ TOBN(0xe8a65b86, 0xc70d8a3b), TOBN(0x5f0e6f4e, 0x98a0403b),
+ TOBN(0x08129684, 0x69ed2370), TOBN(0x34dc30bd, 0x0871ee26),
+ TOBN(0x3a5ce948, 0x7c9c5b05), TOBN(0x7d487b80, 0x43a90c87),
+ TOBN(0x4089ba37, 0xdd0e7179), TOBN(0x45f80191, 0xb4041811),
+ TOBN(0x1c3e1058, 0x98747ba5), TOBN(0x98c4e13a, 0x6e1ae592),
+ TOBN(0xd44636e6, 0xe82c9f9e), TOBN(0x711db87c, 0xc33a1043),
+ TOBN(0x6f431263, 0xaa8aec05), TOBN(0x43ff120d, 0x2744a4aa),
+ TOBN(0xd3bd892f, 0xae77779b), TOBN(0xf0fe0cc9, 0x8cdc9f82),
+ TOBN(0xca5f7fe6, 0xf1c5b1bc), TOBN(0xcc63a682, 0x44929a72),
+ TOBN(0xc7eaba0c, 0x09dbe19a), TOBN(0x2f3585ad, 0x6b5c73c2),
+ TOBN(0x8ab8924b, 0x0ae50c30), TOBN(0x17fcd27a, 0x638b30ba),
+ TOBN(0xaf414d34, 0x10b3d5a5), TOBN(0x09c107d2, 0x2a9accf1),
+ TOBN(0x15dac49f, 0x946a6242), TOBN(0xaec3df2a, 0xd707d642),
+ TOBN(0x2c2492b7, 0x3f894ae0), TOBN(0xf59df3e5, 0xb75f18ce),
+ TOBN(0x7cb740d2, 0x8f53cad0), TOBN(0x3eb585fb, 0xc4f01294),
+ TOBN(0x17da0c86, 0x32c7f717), TOBN(0xeb8c795b, 0xaf943f4c),
+ TOBN(0x4ee23fb5, 0xf67c51d2), TOBN(0xef187575, 0x68889949),
+ TOBN(0xa6b4bdb2, 0x0389168b), TOBN(0xc4ecd258, 0xea577d03),
+ TOBN(0x3a63782b, 0x55743082), TOBN(0x6f678f4c, 0xc72f08cd),
+ TOBN(0x553511cf, 0x65e58dd8), TOBN(0xd53b4e3e, 0xd402c0cd),
+ TOBN(0x37de3e29, 0xa037c14c), TOBN(0x86b6c516, 0xc05712aa),
+ TOBN(0x2834da3e, 0xb38dff6f), TOBN(0xbe012c52, 0xea636be8),
+ TOBN(0x292d238c, 0x61dd37f8), TOBN(0x0e54523f, 0x8f8142db),
+ TOBN(0xe31eb436, 0x036a05d8), TOBN(0x83e3cdff, 0x1e93c0ff),
+ TOBN(0x3fd2fe0f, 0x50821ddf), TOBN(0xc8e19b0d, 0xff9eb33b),
+ TOBN(0xc8cc943f, 0xb569a5fe), TOBN(0xad0090d4, 0xd4342d75),
+ TOBN(0x82090b4b, 0xcaeca000), TOBN(0xca39687f, 0x1bd410eb),
+ TOBN(0xe7bb0df7, 0x65959d77), TOBN(0x39d78218, 0x9c964999),
+ TOBN(0xd87f62e8, 0xb2415451), TOBN(0xe5efb774, 0xbed76108),
+ TOBN(0x3ea011a4, 0xe822f0d0), TOBN(0xbc647ad1, 0x5a8704f8),
+ TOBN(0xbb315b35, 0x50c6820f), TOBN(0x863dec3d, 0xb7e76bec),
+ TOBN(0x01ff5d3a, 0xf017bfc7), TOBN(0x20054439, 0x976b8229),
+ TOBN(0x067fca37, 0x0bbd0d3b), TOBN(0xf63dde64, 0x7f5e3d0f),
+ TOBN(0x22dbefb3, 0x2a4c94e9), TOBN(0xafbff0fe, 0x96f8278a),
+ TOBN(0x80aea0b1, 0x3503793d), TOBN(0xb2238029, 0x5f06cd29),
+ TOBN(0x65703e57, 0x8ec3feca), TOBN(0x06c38314, 0x393e7053),
+ TOBN(0xa0b751eb, 0x7c6734c4), TOBN(0xd2e8a435, 0xc59f0f1e),
+ TOBN(0x147d9052, 0x5e9ca895), TOBN(0x2f4dd31e, 0x972072df),
+ TOBN(0xa16fda8e, 0xe6c6755c), TOBN(0xc66826ff, 0xcf196558),
+ TOBN(0x1f1a76a3, 0x0cf43895), TOBN(0xa9d604e0, 0x83c3097b),
+ TOBN(0xe1908309, 0x66390e0e), TOBN(0xa50bf753, 0xb3c85eff),
+ TOBN(0x0696bdde, 0xf6a70251), TOBN(0x548b801b, 0x3c6ab16a),
+ TOBN(0x37fcf704, 0xa4d08762), TOBN(0x090b3def, 0xdff76c4e),
+ TOBN(0x87e8cb89, 0x69cb9158), TOBN(0x44a90744, 0x995ece43),
+ TOBN(0xf85395f4, 0x0ad9fbf5), TOBN(0x49b0f6c5, 0x4fb0c82d),
+ TOBN(0x75d9bc15, 0xadf7cccf), TOBN(0x81a3e5d6, 0xdfa1e1b0),
+ TOBN(0x8c39e444, 0x249bc17e), TOBN(0xf37dccb2, 0x8ea7fd43),
+ TOBN(0xda654873, 0x907fba12), TOBN(0x35daa6da, 0x4a372904),
+ TOBN(0x0564cfc6, 0x6283a6c5), TOBN(0xd09fa4f6, 0x4a9395bf),
+ TOBN(0x688e9ec9, 0xaeb19a36), TOBN(0xd913f1ce, 0xc7bfbfb4),
+ TOBN(0x797b9a3c, 0x61c2faa6), TOBN(0x2f979bec, 0x6a0a9c12),
+ TOBN(0xb5969d0f, 0x359679ec), TOBN(0xebcf523d, 0x079b0460),
+ TOBN(0xfd6b0008, 0x10fab870), TOBN(0x3f2edcda, 0x9373a39c),
+ TOBN(0x0d64f9a7, 0x6f568431), TOBN(0xf848c27c, 0x02f8898c),
+ TOBN(0xf418ade1, 0x260b5bd5), TOBN(0xc1f3e323, 0x6973dee8),
+ TOBN(0x46e9319c, 0x26c185dd), TOBN(0x6d85b7d8, 0x546f0ac4),
+ TOBN(0x427965f2, 0x247f9d57), TOBN(0xb519b636, 0xb0035f48),
+ TOBN(0x6b6163a9, 0xab87d59c), TOBN(0xff9f58c3, 0x39caaa11),
+ TOBN(0x4ac39cde, 0x3177387b), TOBN(0x5f6557c2, 0x873e77f9),
+ TOBN(0x67504006, 0x36a83041), TOBN(0x9b1c96ca, 0x75ef196c),
+ TOBN(0xf34283de, 0xb08c7940), TOBN(0x7ea09644, 0x1128c316),
+ TOBN(0xb510b3b5, 0x6aa39dff), TOBN(0x59b43da2, 0x9f8e4d8c),
+ TOBN(0xa8ce31fd, 0x9e4c4b9f), TOBN(0x0e20be26, 0xc1303c01),
+ TOBN(0x18187182, 0xe8ee47c9), TOBN(0xd9687cdb, 0x7db98101),
+ TOBN(0x7a520e4d, 0xa1e14ff6), TOBN(0x429808ba, 0x8836d572),
+ TOBN(0xa37ca60d, 0x4944b663), TOBN(0xf901f7a9, 0xa3f91ae5),
+ TOBN(0xe4e3e76e, 0x9e36e3b1), TOBN(0x9aa219cf, 0x29d93250),
+ TOBN(0x347fe275, 0x056a2512), TOBN(0xa4d643d9, 0xde65d95c),
+ TOBN(0x9669d396, 0x699fc3ed), TOBN(0xb598dee2, 0xcf8c6bbe),
+ TOBN(0x682ac1e5, 0xdda9e5c6), TOBN(0x4e0d3c72, 0xcaa9fc95),
+ TOBN(0x17faaade, 0x772bea44), TOBN(0x5ef8428c, 0xab0009c8),
+ TOBN(0xcc4ce47a, 0x460ff016), TOBN(0xda6d12bf, 0x725281cb),
+ TOBN(0x44c67848, 0x0223aad2), TOBN(0x6e342afa, 0x36256e28),
+ TOBN(0x1400bb0b, 0x93a37c04), TOBN(0x62b1bc9b, 0xdd10bd96),
+ TOBN(0x7251adeb, 0x0dac46b7), TOBN(0x7d33b92e, 0x7be4ef51),
+ TOBN(0x28b2a94b, 0xe61fa29a), TOBN(0x4b2be13f, 0x06422233),
+ TOBN(0x36d6d062, 0x330d8d37), TOBN(0x5ef80e1e, 0xb28ca005),
+ TOBN(0x174d4699, 0x6d16768e), TOBN(0x9fc4ff6a, 0x628bf217),
+ TOBN(0x77705a94, 0x154e490d), TOBN(0x9d96dd28, 0x8d2d997a),
+ TOBN(0x77e2d9d8, 0xce5d72c4), TOBN(0x9d06c5a4, 0xc11c714f),
+ TOBN(0x02aa5136, 0x79e4a03e), TOBN(0x1386b3c2, 0x030ff28b),
+ TOBN(0xfe82e8a6, 0xfb283f61), TOBN(0x7df203e5, 0xf3abc3fb),
+ TOBN(0xeec7c351, 0x3a4d3622), TOBN(0xf7d17dbf, 0xdf762761),
+ TOBN(0xc3956e44, 0x522055f0), TOBN(0xde3012db, 0x8fa748db),
+ TOBN(0xca9fcb63, 0xbf1dcc14), TOBN(0xa56d9dcf, 0xbe4e2f3a),
+ TOBN(0xb86186b6, 0x8bcec9c2), TOBN(0x7cf24df9, 0x680b9f06),
+ TOBN(0xc46b45ea, 0xc0d29281), TOBN(0xfff42bc5, 0x07b10e12),
+ TOBN(0x12263c40, 0x4d289427), TOBN(0x3d5f1899, 0xb4848ec4),
+ TOBN(0x11f97010, 0xd040800c), TOBN(0xb4c5f529, 0x300feb20),
+ TOBN(0xcc543f8f, 0xde94fdcb), TOBN(0xe96af739, 0xc7c2f05e),
+ TOBN(0xaa5e0036, 0x882692e1), TOBN(0x09c75b68, 0x950d4ae9),
+ TOBN(0x62f63df2, 0xb5932a7a), TOBN(0x2658252e, 0xde0979ad),
+ TOBN(0x2a19343f, 0xb5e69631), TOBN(0x718c7501, 0x525b666b),
+ TOBN(0x26a42d69, 0xea40dc3a), TOBN(0xdc84ad22, 0xaecc018f),
+ TOBN(0x25c36c7b, 0x3270f04a), TOBN(0x46ba6d47, 0x50fa72ed),
+ TOBN(0x6c37d1c5, 0x93e58a8e), TOBN(0xa2394731, 0x120c088c),
+ TOBN(0xc3be4263, 0xcb6e86da), TOBN(0x2c417d36, 0x7126d038),
+ TOBN(0x5b70f9c5, 0x8b6f8efa), TOBN(0x671a2faa, 0x37718536),
+ TOBN(0xd3ced3c6, 0xb539c92b), TOBN(0xe56f1bd9, 0xa31203c2),
+ TOBN(0x8b096ec4, 0x9ff3c8eb), TOBN(0x2deae432, 0x43491cea),
+ TOBN(0x2465c6eb, 0x17943794), TOBN(0x5d267e66, 0x20586843),
+ TOBN(0x9d3d116d, 0xb07159d0), TOBN(0xae07a67f, 0xc1896210),
+ TOBN(0x8fc84d87, 0xbb961579), TOBN(0x30009e49, 0x1c1f8dd6),
+ TOBN(0x8a8caf22, 0xe3132819), TOBN(0xcffa197c, 0xf23ab4ff),
+ TOBN(0x58103a44, 0x205dd687), TOBN(0x57b796c3, 0x0ded67a2),
+ TOBN(0x0b9c3a6c, 0xa1779ad7), TOBN(0xa33cfe2e, 0x357c09c5),
+ TOBN(0x2ea29315, 0x3db4a57e), TOBN(0x91959695, 0x8ebeb52e),
+ TOBN(0x118db9a6, 0xe546c879), TOBN(0x8e996df4, 0x6295c8d6),
+ TOBN(0xdd990484, 0x55ec806b), TOBN(0x24f291ca, 0x165c1035),
+ TOBN(0xcca523bb, 0x440e2229), TOBN(0x324673a2, 0x73ef4d04),
+ TOBN(0xaf3adf34, 0x3e11ec39), TOBN(0x6136d7f1, 0xdc5968d3),
+ TOBN(0x7a7b2899, 0xb053a927), TOBN(0x3eaa2661, 0xae067ecd),
+ TOBN(0x8549b9c8, 0x02779cd9), TOBN(0x061d7940, 0xc53385ea),
+ TOBN(0x3e0ba883, 0xf06d18bd), TOBN(0x4ba6de53, 0xb2700843),
+ TOBN(0xb966b668, 0x591a9e4d), TOBN(0x93f67567, 0x7f4fa0ed),
+ TOBN(0x5a02711b, 0x4347237b), TOBN(0xbc041e2f, 0xe794608e),
+ TOBN(0x55af10f5, 0x70f73d8c), TOBN(0xd2d4d4f7, 0xbb7564f7),
+ TOBN(0xd7d27a89, 0xb3e93ce7), TOBN(0xf7b5a875, 0x5d3a2c1b),
+ TOBN(0xb29e68a0, 0x255b218a), TOBN(0xb533837e, 0x8af76754),
+ TOBN(0xd1b05a73, 0x579fab2e), TOBN(0xb41055a1, 0xecd74385),
+ TOBN(0xb2369274, 0x445e9115), TOBN(0x2972a7c4, 0xf520274e),
+ TOBN(0x6c08334e, 0xf678e68a), TOBN(0x4e4160f0, 0x99b057ed),
+ TOBN(0x3cfe11b8, 0x52ccb69a), TOBN(0x2fd1823a, 0x21c8f772),
+ TOBN(0xdf7f072f, 0x3298f055), TOBN(0x8c0566f9, 0xfec74a6e),
+ TOBN(0xe549e019, 0x5bb4d041), TOBN(0x7c3930ba, 0x9208d850),
+ TOBN(0xe07141fc, 0xaaa2902b), TOBN(0x539ad799, 0xe4f69ad3),
+ TOBN(0xa6453f94, 0x813f9ffd), TOBN(0xc58d3c48, 0x375bc2f7),
+ TOBN(0xb3326fad, 0x5dc64e96), TOBN(0x3aafcaa9, 0xb240e354),
+ TOBN(0x1d1b0903, 0xaca1e7a9), TOBN(0x4ceb9767, 0x1211b8a0),
+ TOBN(0xeca83e49, 0xe32a858e), TOBN(0x4c32892e, 0xae907bad),
+ TOBN(0xd5b42ab6, 0x2eb9b494), TOBN(0x7fde3ee2, 0x1eabae1b),
+ TOBN(0x13b5ab09, 0xcaf54957), TOBN(0xbfb028be, 0xe5f5d5d5),
+ TOBN(0x928a0650, 0x2003e2c0), TOBN(0x90793aac, 0x67476843),
+ TOBN(0x5e942e79, 0xc81710a0), TOBN(0x557e4a36, 0x27ccadd4),
+ TOBN(0x72a2bc56, 0x4bcf6d0c), TOBN(0x09ee5f43, 0x26d7b80c),
+ TOBN(0x6b70dbe9, 0xd4292f19), TOBN(0x56f74c26, 0x63f16b18),
+ TOBN(0xc23db0f7, 0x35fbb42a), TOBN(0xb606bdf6, 0x6ae10040),
+ TOBN(0x1eb15d4d, 0x044573ac), TOBN(0x7dc3cf86, 0x556b0ba4),
+ TOBN(0x97af9a33, 0xc60df6f7), TOBN(0x0b1ef85c, 0xa716ce8c),
+ TOBN(0x2922f884, 0xc96958be), TOBN(0x7c32fa94, 0x35690963),
+ TOBN(0x2d7f667c, 0xeaa00061), TOBN(0xeaaf7c17, 0x3547365c),
+ TOBN(0x1eb4de46, 0x87032d58), TOBN(0xc54f3d83, 0x5e2c79e0),
+ TOBN(0x07818df4, 0x5d04ef23), TOBN(0x55faa9c8, 0x673d41b4),
+ TOBN(0xced64f6f, 0x89b95355), TOBN(0x4860d2ea, 0xb7415c84),
+ TOBN(0x5fdb9bd2, 0x050ebad3), TOBN(0xdb53e0cc, 0x6685a5bf),
+ TOBN(0xb830c031, 0x9feb6593), TOBN(0xdd87f310, 0x6accff17),
+ TOBN(0x2303ebab, 0x9f555c10), TOBN(0x94603695, 0x287e7065),
+ TOBN(0xf88311c3, 0x2e83358c), TOBN(0x508dd9b4, 0xeefb0178),
+ TOBN(0x7ca23706, 0x2dba8652), TOBN(0x62aac5a3, 0x0047abe5),
+ TOBN(0x9a61d2a0, 0x8b1ea7b3), TOBN(0xd495ab63, 0xae8b1485),
+ TOBN(0x38740f84, 0x87052f99), TOBN(0x178ebe5b, 0xb2974eea),
+ TOBN(0x030bbcca, 0x5b36d17f), TOBN(0xb5e4cce3, 0xaaf86eea),
+ TOBN(0xb51a0220, 0x68f8e9e0), TOBN(0xa4348796, 0x09eb3e75),
+ TOBN(0xbe592309, 0xeef1a752), TOBN(0x5d7162d7, 0x6f2aa1ed),
+ TOBN(0xaebfb5ed, 0x0f007dd2), TOBN(0x255e14b2, 0xc89edd22),
+ TOBN(0xba85e072, 0x0303b697), TOBN(0xc5d17e25, 0xf05720ff),
+ TOBN(0x02b58d6e, 0x5128ebb6), TOBN(0x2c80242d, 0xd754e113),
+ TOBN(0x919fca5f, 0xabfae1ca), TOBN(0x937afaac, 0x1a21459b),
+ TOBN(0x9e0ca91c, 0x1f66a4d2), TOBN(0x194cc7f3, 0x23ec1331),
+ TOBN(0xad25143a, 0x8aa11690), TOBN(0xbe40ad8d, 0x09b59e08),
+ TOBN(0x37d60d9b, 0xe750860a), TOBN(0x6c53b008, 0xc6bf434c),
+ TOBN(0xb572415d, 0x1356eb80), TOBN(0xb8bf9da3, 0x9578ded8),
+ TOBN(0x22658e36, 0x5e8fb38b), TOBN(0x9b70ce22, 0x5af8cb22),
+ TOBN(0x7c00018a, 0x829a8180), TOBN(0x84329f93, 0xb81ed295),
+ TOBN(0x7c343ea2, 0x5f3cea83), TOBN(0x38f8655f, 0x67586536),
+ TOBN(0xa661a0d0, 0x1d3ec517), TOBN(0x98744652, 0x512321ae),
+ TOBN(0x084ca591, 0xeca92598), TOBN(0xa9bb9dc9, 0x1dcb3feb),
+ TOBN(0x14c54355, 0x78b4c240), TOBN(0x5ed62a3b, 0x610cafdc),
+ TOBN(0x07512f37, 0x1b38846b), TOBN(0x571bb70a, 0xb0e38161),
+ TOBN(0xb556b95b, 0x2da705d2), TOBN(0x3ef8ada6, 0xb1a08f98),
+ TOBN(0x85302ca7, 0xddecfbe5), TOBN(0x0e530573, 0x943105cd),
+ TOBN(0x60554d55, 0x21a9255d), TOBN(0x63a32fa1, 0xf2f3802a),
+ TOBN(0x35c8c5b0, 0xcd477875), TOBN(0x97f458ea, 0x6ad42da1),
+ TOBN(0x832d7080, 0xeb6b242d), TOBN(0xd30bd023, 0x3b71e246),
+ TOBN(0x7027991b, 0xbe31139d), TOBN(0x68797e91, 0x462e4e53),
+ TOBN(0x423fe20a, 0x6b4e185a), TOBN(0x82f2c67e, 0x42d9b707),
+ TOBN(0x25c81768, 0x4cf7811b), TOBN(0xbd53005e, 0x045bb95d),
+ },
+ {
+ TOBN(0xe5f649be, 0x9d8e68fd), TOBN(0xdb0f0533, 0x1b044320),
+ TOBN(0xf6fde9b3, 0xe0c33398), TOBN(0x92f4209b, 0x66c8cfae),
+ TOBN(0xe9d1afcc, 0x1a739d4b), TOBN(0x09aea75f, 0xa28ab8de),
+ TOBN(0x14375fb5, 0xeac6f1d0), TOBN(0x6420b560, 0x708f7aa5),
+ TOBN(0x9eae499c, 0x6254dc41), TOBN(0x7e293924, 0x7a837e7e),
+ TOBN(0x74aec08c, 0x090524a7), TOBN(0xf82b9219, 0x8d6f55f2),
+ TOBN(0x493c962e, 0x1402cec5), TOBN(0x9f17ca17, 0xfa2f30e7),
+ TOBN(0xbcd783e8, 0xe9b879cb), TOBN(0xea3d8c14, 0x5a6f145f),
+ TOBN(0xdede15e7, 0x5e0dee6e), TOBN(0x74f24872, 0xdc628aa2),
+ TOBN(0xd3e9c4fe, 0x7861bb93), TOBN(0x56d4822a, 0x6187b2e0),
+ TOBN(0xb66417cf, 0xc59826f9), TOBN(0xca260969, 0x2408169e),
+ TOBN(0xedf69d06, 0xc79ef885), TOBN(0x00031f8a, 0xdc7d138f),
+ TOBN(0x103c46e6, 0x0ebcf726), TOBN(0x4482b831, 0x6231470e),
+ TOBN(0x6f6dfaca, 0x487c2109), TOBN(0x2e0ace97, 0x62e666ef),
+ TOBN(0x3246a9d3, 0x1f8d1f42), TOBN(0x1b1e83f1, 0x574944d2),
+ TOBN(0x13dfa63a, 0xa57f334b), TOBN(0x0cf8daed, 0x9f025d81),
+ TOBN(0x30d78ea8, 0x00ee11c1), TOBN(0xeb053cd4, 0xb5e3dd75),
+ TOBN(0x9b65b13e, 0xd58c43c5), TOBN(0xc3ad49bd, 0xbd151663),
+ TOBN(0x99fd8e41, 0xb6427990), TOBN(0x12cf15bd, 0x707eae1e),
+ TOBN(0x29ad4f1b, 0x1aabb71e), TOBN(0x5143e74d, 0x07545d0e),
+ TOBN(0x30266336, 0xc88bdee1), TOBN(0x25f29306, 0x5876767c),
+ TOBN(0x9c078571, 0xc6731996), TOBN(0xc88690b2, 0xed552951),
+ TOBN(0x274f2c2d, 0x852705b4), TOBN(0xb0bf8d44, 0x4e09552d),
+ TOBN(0x7628beeb, 0x986575d1), TOBN(0x407be238, 0x7f864651),
+ TOBN(0x0e5e3049, 0xa639fc6b), TOBN(0xe75c35d9, 0x86003625),
+ TOBN(0x0cf35bd8, 0x5dcc1646), TOBN(0x8bcaced2, 0x6c26273a),
+ TOBN(0xe22ecf1d, 0xb5536742), TOBN(0x013dd897, 0x1a9e068b),
+ TOBN(0x17f411cb, 0x8a7909c5), TOBN(0x5757ac98, 0x861dd506),
+ TOBN(0x85de1f0d, 0x1e935abb), TOBN(0xdefd10b4, 0x154de37a),
+ TOBN(0xb8d9e392, 0x369cebb5), TOBN(0x54d5ef9b, 0x761324be),
+ TOBN(0x4d6341ba, 0x74f17e26), TOBN(0xc0a0e3c8, 0x78c1dde4),
+ TOBN(0xa6d77581, 0x87d918fd), TOBN(0x66876015, 0x02ca3a13),
+ TOBN(0xc7313e9c, 0xf36658f0), TOBN(0xc433ef1c, 0x71f8057e),
+ TOBN(0x85326246, 0x1b6a835a), TOBN(0xc8f05398, 0x7c86394c),
+ TOBN(0xff398cdf, 0xe983c4a1), TOBN(0xbf5e8162, 0x03b7b931),
+ TOBN(0x93193c46, 0xb7b9045b), TOBN(0x1e4ebf5d, 0xa4a6e46b),
+ TOBN(0xf9942a60, 0x43a24fe7), TOBN(0x29c1191e, 0xffb3492b),
+ TOBN(0x9f662449, 0x902fde05), TOBN(0xc792a7ac, 0x6713c32d),
+ TOBN(0x2fd88ad8, 0xb737982c), TOBN(0x7e3a0319, 0xa21e60e3),
+ TOBN(0x09b0de44, 0x7383591a), TOBN(0x6df141ee, 0x8310a456),
+ TOBN(0xaec1a039, 0xe6d6f471), TOBN(0x14b2ba0f, 0x1198d12e),
+ TOBN(0xebc1a160, 0x3aeee5ac), TOBN(0x401f4836, 0xe0b964ce),
+ TOBN(0x2ee43796, 0x4fd03f66), TOBN(0x3fdb4e49, 0xdd8f3f12),
+ TOBN(0x6ef267f6, 0x29380f18), TOBN(0x3e8e9670, 0x8da64d16),
+ TOBN(0xbc19180c, 0x207674f1), TOBN(0x112e09a7, 0x33ae8fdb),
+ TOBN(0x99667554, 0x6aaeb71e), TOBN(0x79432af1, 0xe101b1c7),
+ TOBN(0xd5eb558f, 0xde2ddec6), TOBN(0x81392d1f, 0x5357753f),
+ TOBN(0xa7a76b97, 0x3ae1158a), TOBN(0x416fbbff, 0x4a899991),
+ TOBN(0x9e65fdfd, 0x0d4a9dcf), TOBN(0x7bc29e48, 0x944ddf12),
+ TOBN(0xbc1a92d9, 0x3c856866), TOBN(0x273c6905, 0x6e98dfe2),
+ TOBN(0x69fce418, 0xcdfaa6b8), TOBN(0x606bd823, 0x5061c69f),
+ TOBN(0x42d495a0, 0x6af75e27), TOBN(0x8ed3d505, 0x6d873a1f),
+ TOBN(0xaf552841, 0x6ab25b6a), TOBN(0xc6c0ffc7, 0x2b1a4523),
+ TOBN(0xab18827b, 0x21c99e03), TOBN(0x060e8648, 0x9034691b),
+ TOBN(0x5207f90f, 0x93c7f398), TOBN(0x9f4a96cb, 0x82f8d10b),
+ TOBN(0xdd71cd79, 0x3ad0f9e3), TOBN(0x84f435d2, 0xfc3a54f5),
+ TOBN(0x4b03c55b, 0x8e33787f), TOBN(0xef42f975, 0xa6384673),
+ TOBN(0xff7304f7, 0x5051b9f0), TOBN(0x18aca1dc, 0x741c87c2),
+ TOBN(0x56f120a7, 0x2d4bfe80), TOBN(0xfd823b3d, 0x053e732c),
+ TOBN(0x11bccfe4, 0x7537ca16), TOBN(0xdf6c9c74, 0x1b5a996b),
+ TOBN(0xee7332c7, 0x904fc3fa), TOBN(0x14a23f45, 0xc7e3636a),
+ TOBN(0xc38659c3, 0xf091d9aa), TOBN(0x4a995e5d, 0xb12d8540),
+ TOBN(0x20a53bec, 0xf3a5598a), TOBN(0x56534b17, 0xb1eaa995),
+ TOBN(0x9ed3dca4, 0xbf04e03c), TOBN(0x716c563a, 0xd8d56268),
+ TOBN(0x27ba77a4, 0x1d6178e7), TOBN(0xe4c80c40, 0x68a1ff8e),
+ TOBN(0x75011099, 0x0a13f63d), TOBN(0x7bf33521, 0xa61d46f3),
+ TOBN(0x0aff218e, 0x10b365bb), TOBN(0x81021804, 0x0fd7ea75),
+ TOBN(0x05a3fd8a, 0xa4b3a925), TOBN(0xb829e75f, 0x9b3db4e6),
+ TOBN(0x6bdc75a5, 0x4d53e5fb), TOBN(0x04a5dc02, 0xd52717e3),
+ TOBN(0x86af502f, 0xe9a42ec2), TOBN(0x8867e8fb, 0x2630e382),
+ TOBN(0xbf845c6e, 0xbec9889b), TOBN(0x54f491f2, 0xcb47c98d),
+ TOBN(0xa3091fba, 0x790c2a12), TOBN(0xd7f6fd78, 0xc20f708b),
+ TOBN(0xa569ac30, 0xacde5e17), TOBN(0xd0f996d0, 0x6852b4d7),
+ TOBN(0xe51d4bb5, 0x4609ae54), TOBN(0x3fa37d17, 0x0daed061),
+ TOBN(0x62a88684, 0x34b8fb41), TOBN(0x99a2acbd, 0x9efb64f1),
+ TOBN(0xb75c1a5e, 0x6448e1f2), TOBN(0xfa99951a, 0x42b5a069),
+ TOBN(0x6d956e89, 0x2f3b26e7), TOBN(0xf4709860, 0xda875247),
+ TOBN(0x3ad15179, 0x2482dda3), TOBN(0xd64110e3, 0x017d82f0),
+ TOBN(0x14928d2c, 0xfad414e4), TOBN(0x2b155f58, 0x2ed02b24),
+ TOBN(0x481a141b, 0xcb821bf1), TOBN(0x12e3c770, 0x4f81f5da),
+ TOBN(0xe49c5de5, 0x9fff8381), TOBN(0x11053232, 0x5bbec894),
+ TOBN(0xa0d051cc, 0x454d88c4), TOBN(0x4f6db89c, 0x1f8e531b),
+ TOBN(0x34fe3fd6, 0xca563a44), TOBN(0x7f5c2215, 0x58da8ab9),
+ TOBN(0x8445016d, 0x9474f0a1), TOBN(0x17d34d61, 0xcb7d8a0a),
+ TOBN(0x8e9d3910, 0x1c474019), TOBN(0xcaff2629, 0xd52ceefb),
+ TOBN(0xf9cf3e32, 0xc1622c2b), TOBN(0xd4b95e3c, 0xe9071a05),
+ TOBN(0xfbbca61f, 0x1594438c), TOBN(0x1eb6e6a6, 0x04aadedf),
+ TOBN(0x853027f4, 0x68e14940), TOBN(0x221d322a, 0xdfabda9c),
+ TOBN(0xed8ea9f6, 0xb7cb179a), TOBN(0xdc7b764d, 0xb7934dcc),
+ TOBN(0xfcb13940, 0x5e09180d), TOBN(0x6629a6bf, 0xb47dc2dd),
+ TOBN(0xbfc55e4e, 0x9f5a915e), TOBN(0xb1db9d37, 0x6204441e),
+ TOBN(0xf82d68cf, 0x930c5f53), TOBN(0x17d3a142, 0xcbb605b1),
+ TOBN(0xdd5944ea, 0x308780f2), TOBN(0xdc8de761, 0x3845f5e4),
+ TOBN(0x6beaba7d, 0x7624d7a3), TOBN(0x1e709afd, 0x304df11e),
+ TOBN(0x95364376, 0x02170456), TOBN(0xbf204b3a, 0xc8f94b64),
+ TOBN(0x4e53af7c, 0x5680ca68), TOBN(0x0526074a, 0xe0c67574),
+ TOBN(0x95d8cef8, 0xecd92af6), TOBN(0xe6b9fa7a, 0x6cd1745a),
+ TOBN(0x3d546d3d, 0xa325c3e4), TOBN(0x1f57691d, 0x9ae93aae),
+ TOBN(0xe891f3fe, 0x9d2e1a33), TOBN(0xd430093f, 0xac063d35),
+ TOBN(0xeda59b12, 0x5513a327), TOBN(0xdc2134f3, 0x5536f18f),
+ TOBN(0xaa51fe2c, 0x5c210286), TOBN(0x3f68aaee, 0x1cab658c),
+ TOBN(0x5a23a00b, 0xf9357292), TOBN(0x9a626f39, 0x7efdabed),
+ TOBN(0xfe2b3bf3, 0x199d78e3), TOBN(0xb7a2af77, 0x71bbc345),
+ TOBN(0x3d19827a, 0x1e59802c), TOBN(0x823bbc15, 0xb487a51c),
+ TOBN(0x856139f2, 0x99d0a422), TOBN(0x9ac3df65, 0xf456c6fb),
+ TOBN(0xaddf65c6, 0x701f8bd6), TOBN(0x149f321e, 0x3758df87),
+ TOBN(0xb1ecf714, 0x721b7eba), TOBN(0xe17df098, 0x31a3312a),
+ TOBN(0xdb2fd6ec, 0xd5c4d581), TOBN(0xfd02996f, 0x8fcea1b3),
+ TOBN(0xe29fa63e, 0x7882f14f), TOBN(0xc9f6dc35, 0x07c6cadc),
+ TOBN(0x46f22d6f, 0xb882bed0), TOBN(0x1a45755b, 0xd118e52c),
+ TOBN(0x9f2c7c27, 0x7c4608cf), TOBN(0x7ccbdf32, 0x568012c2),
+ TOBN(0xfcb0aedd, 0x61729b0e), TOBN(0x7ca2ca9e, 0xf7d75dbf),
+ TOBN(0xf58fecb1, 0x6f640f62), TOBN(0xe274b92b, 0x39f51946),
+ TOBN(0x7f4dfc04, 0x6288af44), TOBN(0x0a91f32a, 0xeac329e5),
+ TOBN(0x43ad274b, 0xd6aaba31), TOBN(0x719a1640, 0x0f6884f9),
+ TOBN(0x685d29f6, 0xdaf91e20), TOBN(0x5ec1cc33, 0x27e49d52),
+ TOBN(0x38f4de96, 0x3b54a059), TOBN(0x0e0015e5, 0xefbcfdb3),
+ TOBN(0x177d23d9, 0x4dbb8da6), TOBN(0x98724aa2, 0x97a617ad),
+ TOBN(0x30f0885b, 0xfdb6558e), TOBN(0xf9f7a28a, 0xc7899a96),
+ TOBN(0xd2ae8ac8, 0x872dc112), TOBN(0xfa0642ca, 0x73c3c459),
+ TOBN(0x15296981, 0xe7dfc8d6), TOBN(0x67cd4450, 0x1fb5b94a),
+ TOBN(0x0ec71cf1, 0x0eddfd37), TOBN(0xc7e5eeb3, 0x9a8eddc7),
+ TOBN(0x02ac8e3d, 0x81d95028), TOBN(0x0088f172, 0x70b0e35d),
+ TOBN(0xec041fab, 0xe1881fe3), TOBN(0x62cf71b8, 0xd99e7faa),
+ TOBN(0x5043dea7, 0xe0f222c2), TOBN(0x309d42ac, 0x72e65142),
+ TOBN(0x94fe9ddd, 0x9216cd30), TOBN(0xd6539c7d, 0x0f87feec),
+ TOBN(0x03c5a57c, 0x432ac7d7), TOBN(0x72692cf0, 0x327fda10),
+ TOBN(0xec28c85f, 0x280698de), TOBN(0x2331fb46, 0x7ec283b1),
+ TOBN(0xd34bfa32, 0x2867e633), TOBN(0x78709a82, 0x0a9cc815),
+ TOBN(0xb7fe6964, 0x875e2fa5), TOBN(0x25cc064f, 0x9e98bfb5),
+ TOBN(0x9eb0151c, 0x493a65c5), TOBN(0x5fb5d941, 0x53182464),
+ TOBN(0x69e6f130, 0xf04618e2), TOBN(0xa8ecec22, 0xf89c8ab6),
+ TOBN(0xcd6ac88b, 0xb96209bd), TOBN(0x65fa8cdb, 0xb3e1c9e0),
+ TOBN(0xa47d22f5, 0x4a8d8eac), TOBN(0x83895cdf, 0x8d33f963),
+ TOBN(0xa8adca59, 0xb56cd3d1), TOBN(0x10c8350b, 0xdaf38232),
+ TOBN(0x2b161fb3, 0xa5080a9f), TOBN(0xbe7f5c64, 0x3af65b3a),
+ TOBN(0x2c754039, 0x97403a11), TOBN(0x94626cf7, 0x121b96af),
+ TOBN(0x431de7c4, 0x6a983ec2), TOBN(0x3780dd3a, 0x52cc3df7),
+ TOBN(0xe28a0e46, 0x2baf8e3b), TOBN(0xabe68aad, 0x51d299ae),
+ TOBN(0x603eb8f9, 0x647a2408), TOBN(0x14c61ed6, 0x5c750981),
+ TOBN(0x88b34414, 0xc53352e7), TOBN(0x5a34889c, 0x1337d46e),
+ TOBN(0x612c1560, 0xf95f2bc8), TOBN(0x8a3f8441, 0xd4807a3a),
+ TOBN(0x680d9e97, 0x5224da68), TOBN(0x60cd6e88, 0xc3eb00e9),
+ TOBN(0x3875a98e, 0x9a6bc375), TOBN(0xdc80f924, 0x4fd554c2),
+ TOBN(0x6c4b3415, 0x6ac77407), TOBN(0xa1e5ea8f, 0x25420681),
+ TOBN(0x541bfa14, 0x4607a458), TOBN(0x5dbc7e7a, 0x96d7fbf9),
+ TOBN(0x646a851b, 0x31590a47), TOBN(0x039e85ba, 0x15ee6df8),
+ TOBN(0xd19fa231, 0xd7b43fc0), TOBN(0x84bc8be8, 0x299a0e04),
+ TOBN(0x2b9d2936, 0xf20df03a), TOBN(0x24054382, 0x8608d472),
+ TOBN(0x76b6ba04, 0x9149202a), TOBN(0xb21c3831, 0x3670e7b7),
+ TOBN(0xddd93059, 0xd6fdee10), TOBN(0x9da47ad3, 0x78488e71),
+ TOBN(0x99cc1dfd, 0xa0fcfb25), TOBN(0x42abde10, 0x64696954),
+ TOBN(0x14cc15fc, 0x17eab9fe), TOBN(0xd6e863e4, 0xd3e70972),
+ TOBN(0x29a7765c, 0x6432112c), TOBN(0x88660001, 0x5b0774d8),
+ TOBN(0x3729175a, 0x2c088eae), TOBN(0x13afbcae, 0x8230b8d4),
+ TOBN(0x44768151, 0x915f4379), TOBN(0xf086431a, 0xd8d22812),
+ TOBN(0x37461955, 0xc298b974), TOBN(0x905fb5f0, 0xf8711e04),
+ TOBN(0x787abf3a, 0xfe969d18), TOBN(0x392167c2, 0x6f6a494e),
+ TOBN(0xfc7a0d2d, 0x28c511da), TOBN(0xf127c7dc, 0xb66a262d),
+ TOBN(0xf9c4bb95, 0xfd63fdf0), TOBN(0x90016589, 0x3913ef46),
+ TOBN(0x74d2a73c, 0x11aa600d), TOBN(0x2f5379bd, 0x9fb5ab52),
+ TOBN(0xe49e53a4, 0x7fb70068), TOBN(0x68dd39e5, 0x404aa9a7),
+ TOBN(0xb9b0cf57, 0x2ecaa9c3), TOBN(0xba0e103b, 0xe824826b),
+ TOBN(0x60c2198b, 0x4631a3c4), TOBN(0xc5ff84ab, 0xfa8966a2),
+ TOBN(0x2d6ebe22, 0xac95aff8), TOBN(0x1c9bb6db, 0xb5a46d09),
+ TOBN(0x419062da, 0x53ee4f8d), TOBN(0x7b9042d0, 0xbb97efef),
+ TOBN(0x0f87f080, 0x830cf6bd), TOBN(0x4861d19a, 0x6ec8a6c6),
+ TOBN(0xd3a0daa1, 0x202f01aa), TOBN(0xb0111674, 0xf25afbd5),
+ TOBN(0x6d00d6cf, 0x1afb20d9), TOBN(0x13695000, 0x40671bc5),
+ TOBN(0x913ab0dc, 0x2485ea9b), TOBN(0x1f2bed06, 0x9eef61ac),
+ TOBN(0x850c8217, 0x6d799e20), TOBN(0x93415f37, 0x3271c2de),
+ TOBN(0x5afb06e9, 0x6c4f5910), TOBN(0x688a52df, 0xc4e9e421),
+ TOBN(0x30495ba3, 0xe2a9a6db), TOBN(0x4601303d, 0x58f9268b),
+ TOBN(0xbe3b0dad, 0x7eb0f04f), TOBN(0x4ea47250, 0x4456936d),
+ TOBN(0x8caf8798, 0xd33fd3e7), TOBN(0x1ccd8a89, 0xeb433708),
+ TOBN(0x9effe3e8, 0x87fd50ad), TOBN(0xbe240a56, 0x6b29c4df),
+ TOBN(0xec4ffd98, 0xca0e7ebd), TOBN(0xf586783a, 0xe748616e),
+ TOBN(0xa5b00d8f, 0xc77baa99), TOBN(0x0acada29, 0xb4f34c9c),
+ TOBN(0x36dad67d, 0x0fe723ac), TOBN(0x1d8e53a5, 0x39c36c1e),
+ TOBN(0xe4dd342d, 0x1f4bea41), TOBN(0x64fd5e35, 0xebc9e4e0),
+ TOBN(0x96f01f90, 0x57908805), TOBN(0xb5b9ea3d, 0x5ed480dd),
+ TOBN(0x366c5dc2, 0x3efd2dd0), TOBN(0xed2fe305, 0x6e9dfa27),
+ TOBN(0x4575e892, 0x6e9197e2), TOBN(0x11719c09, 0xab502a5d),
+ TOBN(0x264c7bec, 0xe81f213f), TOBN(0x741b9241, 0x55f5c457),
+ TOBN(0x78ac7b68, 0x49a5f4f4), TOBN(0xf91d70a2, 0x9fc45b7d),
+ TOBN(0x39b05544, 0xb0f5f355), TOBN(0x11f06bce, 0xeef930d9),
+ TOBN(0xdb84d25d, 0x038d05e1), TOBN(0x04838ee5, 0xbacc1d51),
+ TOBN(0x9da3ce86, 0x9e8ee00b), TOBN(0xc3412057, 0xc36eda1f),
+ TOBN(0xae80b913, 0x64d9c2f4), TOBN(0x7468bac3, 0xa010a8ff),
+ TOBN(0xdfd20037, 0x37359d41), TOBN(0x1a0f5ab8, 0x15efeacc),
+ TOBN(0x7c25ad2f, 0x659d0ce0), TOBN(0x4011bcbb, 0x6785cff1),
+ TOBN(0x128b9912, 0x7e2192c7), TOBN(0xa549d8e1, 0x13ccb0e8),
+ TOBN(0x805588d8, 0xc85438b1), TOBN(0x5680332d, 0xbc25cb27),
+ TOBN(0xdcd1bc96, 0x1a4bfdf4), TOBN(0x779ff428, 0x706f6566),
+ TOBN(0x8bbee998, 0xf059987a), TOBN(0xf6ce8cf2, 0xcc686de7),
+ TOBN(0xf8ad3c4a, 0x953cfdb2), TOBN(0xd1d426d9, 0x2205da36),
+ TOBN(0xb3c0f13f, 0xc781a241), TOBN(0x3e89360e, 0xd75362a8),
+ TOBN(0xccd05863, 0xc8a91184), TOBN(0x9bd0c9b7, 0xefa8a7f4),
+ TOBN(0x97ee4d53, 0x8a912a4b), TOBN(0xde5e15f8, 0xbcf518fd),
+ TOBN(0x6a055bf8, 0xc467e1e0), TOBN(0x10be4b4b, 0x1587e256),
+ TOBN(0xd90c14f2, 0x668621c9), TOBN(0xd5518f51, 0xab9c92c1),
+ TOBN(0x8e6a0100, 0xd6d47b3c), TOBN(0xcbe980dd, 0x66716175),
+ TOBN(0x500d3f10, 0xddd83683), TOBN(0x3b6cb35d, 0x99cac73c),
+ TOBN(0x53730c8b, 0x6083d550), TOBN(0xcf159767, 0xdf0a1987),
+ TOBN(0x84bfcf53, 0x43ad73b3), TOBN(0x1b528c20, 0x4f035a94),
+ TOBN(0x4294edf7, 0x33eeac69), TOBN(0xb6283e83, 0x817f3240),
+ TOBN(0xc3fdc959, 0x0a5f25b1), TOBN(0xefaf8aa5, 0x5844ee22),
+ TOBN(0xde269ba5, 0xdbdde4de), TOBN(0xe3347160, 0xc56133bf),
+ TOBN(0xc1184219, 0x8d9ea9f8), TOBN(0x090de5db, 0xf3fc1ab5),
+ TOBN(0x404c37b1, 0x0bf22cda), TOBN(0x7de20ec8, 0xf5618894),
+ TOBN(0x754c588e, 0xecdaecab), TOBN(0x6ca4b0ed, 0x88342743),
+ TOBN(0x76f08bdd, 0xf4a938ec), TOBN(0xd182de89, 0x91493ccb),
+ TOBN(0xd652c53e, 0xc8a4186a), TOBN(0xb3e878db, 0x946d8e33),
+ TOBN(0x088453c0, 0x5f37663c), TOBN(0x5cd9daaa, 0xb407748b),
+ TOBN(0xa1f5197f, 0x586d5e72), TOBN(0x47500be8, 0xc443ca59),
+ TOBN(0x78ef35b2, 0xe2652424), TOBN(0x09c5d26f, 0x6dd7767d),
+ TOBN(0x7175a79a, 0xa74d3f7b), TOBN(0x0428fd8d, 0xcf5ea459),
+ TOBN(0x511cb97c, 0xa5d1746d), TOBN(0x36363939, 0xe71d1278),
+ TOBN(0xcf2df955, 0x10350bf4), TOBN(0xb3817439, 0x60aae782),
+ TOBN(0xa748c0e4, 0x3e688809), TOBN(0x98021fbf, 0xd7a5a006),
+ TOBN(0x9076a70c, 0x0e367a98), TOBN(0xbea1bc15, 0x0f62b7c2),
+ TOBN(0x2645a68c, 0x30fe0343), TOBN(0xacaffa78, 0x699dc14f),
+ TOBN(0xf4469964, 0x457bf9c4), TOBN(0x0db6407b, 0x0d2ead83),
+ TOBN(0x68d56cad, 0xb2c6f3eb), TOBN(0x3b512e73, 0xf376356c),
+ TOBN(0xe43b0e1f, 0xfce10408), TOBN(0x89ddc003, 0x5a5e257d),
+ TOBN(0xb0ae0d12, 0x0362e5b3), TOBN(0x07f983c7, 0xb0519161),
+ TOBN(0xc2e94d15, 0x5d5231e7), TOBN(0xcff22aed, 0x0b4f9513),
+ TOBN(0xb02588dd, 0x6ad0b0b5), TOBN(0xb967d1ac, 0x11d0dcd5),
+ TOBN(0x8dac6bc6, 0xcf777b6c), TOBN(0x0062bdbd, 0x4c6d1959),
+ TOBN(0x53da71b5, 0x0ef5cc85), TOBN(0x07012c7d, 0x4006f14f),
+ TOBN(0x4617f962, 0xac47800d), TOBN(0x53365f2b, 0xc102ed75),
+ TOBN(0xb422efcb, 0x4ab8c9d3), TOBN(0x195cb26b, 0x34af31c9),
+ TOBN(0x3a926e29, 0x05f2c4ce), TOBN(0xbd2bdecb, 0x9856966c),
+ TOBN(0x5d16ab3a, 0x85527015), TOBN(0x9f81609e, 0x4486c231),
+ TOBN(0xd8b96b2c, 0xda350002), TOBN(0xbd054690, 0xfa1b7d36),
+ TOBN(0xdc90ebf5, 0xe71d79bc), TOBN(0xf241b6f9, 0x08964e4e),
+ TOBN(0x7c838643, 0x2fe3cd4c), TOBN(0xe0f33acb, 0xb4bc633c),
+ TOBN(0xb4a9ecec, 0x3d139f1f), TOBN(0x05ce69cd, 0xdc4a1f49),
+ TOBN(0xa19d1b16, 0xf5f98aaf), TOBN(0x45bb71d6, 0x6f23e0ef),
+ TOBN(0x33789fcd, 0x46cdfdd3), TOBN(0x9b8e2978, 0xcee040ca),
+ TOBN(0x9c69b246, 0xae0a6828), TOBN(0xba533d24, 0x7078d5aa),
+ TOBN(0x7a2e42c0, 0x7bb4fbdb), TOBN(0xcfb4879a, 0x7035385c),
+ TOBN(0x8c3dd30b, 0x3281705b), TOBN(0x7e361c6c, 0x404fe081),
+ TOBN(0x7b21649c, 0x3f604edf), TOBN(0x5dbf6a3f, 0xe52ffe47),
+ TOBN(0xc41b7c23, 0x4b54d9bf), TOBN(0x1374e681, 0x3511c3d9),
+ TOBN(0x1863bf16, 0xc1b2b758), TOBN(0x90e78507, 0x1e9e6a96),
+ TOBN(0xab4bf98d, 0x5d86f174), TOBN(0xd74e0bd3, 0x85e96fe4),
+ TOBN(0x8afde39f, 0xcac5d344), TOBN(0x90946dbc, 0xbd91b847),
+ TOBN(0xf5b42358, 0xfe1a838c), TOBN(0x05aae6c5, 0x620ac9d8),
+ TOBN(0x8e193bd8, 0xa1ce5a0b), TOBN(0x8f710571, 0x4dabfd72),
+ TOBN(0x8d8fdd48, 0x182caaac), TOBN(0x8c4aeefa, 0x040745cf),
+ TOBN(0x73c6c30a, 0xf3b93e6d), TOBN(0x991241f3, 0x16f42011),
+ TOBN(0xa0158eea, 0xe457a477), TOBN(0xd19857db, 0xee6ddc05),
+ TOBN(0xb3265224, 0x18c41671), TOBN(0x3ffdfc7e, 0x3c2c0d58),
+ TOBN(0x3a3a5254, 0x26ee7cda), TOBN(0x341b0869, 0xdf02c3a8),
+ TOBN(0xa023bf42, 0x723bbfc8), TOBN(0x3d15002a, 0x14452691),
+ },
+ {
+ TOBN(0x5ef7324c, 0x85edfa30), TOBN(0x25976554, 0x87d4f3da),
+ TOBN(0x352f5bc0, 0xdcb50c86), TOBN(0x8f6927b0, 0x4832a96c),
+ TOBN(0xd08ee1ba, 0x55f2f94c), TOBN(0x6a996f99, 0x344b45fa),
+ TOBN(0xe133cb8d, 0xa8aa455d), TOBN(0x5d0721ec, 0x758dc1f7),
+ TOBN(0x6ba7a920, 0x79e5fb67), TOBN(0xe1331feb, 0x70aa725e),
+ TOBN(0x5080ccf5, 0x7df5d837), TOBN(0xe4cae01d, 0x7ff72e21),
+ TOBN(0xd9243ee6, 0x0412a77d), TOBN(0x06ff7cac, 0xdf449025),
+ TOBN(0xbe75f7cd, 0x23ef5a31), TOBN(0xbc957822, 0x0ddef7a8),
+ TOBN(0x8cf7230c, 0xb0ce1c55), TOBN(0x5b534d05, 0x0bbfb607),
+ TOBN(0xee1ef113, 0x0e16363b), TOBN(0x27e0aa7a, 0xb4999e82),
+ TOBN(0xce1dac2d, 0x79362c41), TOBN(0x67920c90, 0x91bb6cb0),
+ TOBN(0x1e648d63, 0x2223df24), TOBN(0x0f7d9eef, 0xe32e8f28),
+ TOBN(0x6943f39a, 0xfa833834), TOBN(0x22951722, 0xa6328562),
+ TOBN(0x81d63dd5, 0x4170fc10), TOBN(0x9f5fa58f, 0xaecc2e6d),
+ TOBN(0xb66c8725, 0xe77d9a3b), TOBN(0x11235cea, 0x6384ebe0),
+ TOBN(0x06a8c118, 0x5845e24a), TOBN(0x0137b286, 0xebd093b1),
+ TOBN(0xc589e1ce, 0x44ace150), TOBN(0xe0f8d3d9, 0x4381e97c),
+ TOBN(0x59e99b11, 0x62c5a4b8), TOBN(0x90d262f7, 0xfd0ec9f9),
+ TOBN(0xfbc854c9, 0x283e13c9), TOBN(0x2d04fde7, 0xaedc7085),
+ TOBN(0x057d7765, 0x47dcbecb), TOBN(0x8dbdf591, 0x9a76fa5f),
+ TOBN(0xd0150695, 0x0de1e578), TOBN(0x2e1463e7, 0xe9f72bc6),
+ TOBN(0xffa68441, 0x1b39eca5), TOBN(0x673c8530, 0x7c037f2f),
+ TOBN(0xd0d6a600, 0x747f91da), TOBN(0xb08d43e1, 0xc9cb78e9),
+ TOBN(0x0fc0c644, 0x27b5cef5), TOBN(0x5c1d160a, 0xa60a2fd6),
+ TOBN(0xf98cae53, 0x28c8e13b), TOBN(0x375f10c4, 0xb2eddcd1),
+ TOBN(0xd4eb8b7f, 0x5cce06ad), TOBN(0xb4669f45, 0x80a2e1ef),
+ TOBN(0xd593f9d0, 0x5bbd8699), TOBN(0x5528a4c9, 0xe7976d13),
+ TOBN(0x3923e095, 0x1c7e28d3), TOBN(0xb9293790, 0x3f6bb577),
+ TOBN(0xdb567d6a, 0xc42bd6d2), TOBN(0x6df86468, 0xbb1f96ae),
+ TOBN(0x0efe5b1a, 0x4843b28e), TOBN(0x961bbb05, 0x6379b240),
+ TOBN(0xb6caf5f0, 0x70a6a26b), TOBN(0x70686c0d, 0x328e6e39),
+ TOBN(0x80da06cf, 0x895fc8d3), TOBN(0x804d8810, 0xb363fdc9),
+ TOBN(0xbe22877b, 0x207f1670), TOBN(0x9b0dd188, 0x4e615291),
+ TOBN(0x625ae8dc, 0x97a3c2bf), TOBN(0x08584ef7, 0x439b86e8),
+ TOBN(0xde7190a5, 0xdcd898ff), TOBN(0x26286c40, 0x2058ee3d),
+ TOBN(0x3db0b217, 0x5f87b1c1), TOBN(0xcc334771, 0x102a6db5),
+ TOBN(0xd99de954, 0x2f770fb1), TOBN(0x97c1c620, 0x4cd7535e),
+ TOBN(0xd3b6c448, 0x3f09cefc), TOBN(0xd725af15, 0x5a63b4f8),
+ TOBN(0x0c95d24f, 0xc01e20ec), TOBN(0xdfd37494, 0x9ae7121f),
+ TOBN(0x7d6ddb72, 0xec77b7ec), TOBN(0xfe079d3b, 0x0353a4ae),
+ TOBN(0x3066e70a, 0x2e6ac8d2), TOBN(0x9c6b5a43, 0x106e5c05),
+ TOBN(0x52d3c6f5, 0xede59b8c), TOBN(0x30d6a5c3, 0xfccec9ae),
+ TOBN(0xedec7c22, 0x4fc0a9ef), TOBN(0x190ff083, 0x95c16ced),
+ TOBN(0xbe12ec8f, 0x94de0fde), TOBN(0x0d131ab8, 0x852d3433),
+ TOBN(0x42ace07e, 0x85701291), TOBN(0x94793ed9, 0x194061a8),
+ TOBN(0x30e83ed6, 0xd7f4a485), TOBN(0x9eec7269, 0xf9eeff4d),
+ TOBN(0x90acba59, 0x0c9d8005), TOBN(0x5feca458, 0x1e79b9d1),
+ TOBN(0x8fbe5427, 0x1d506a1e), TOBN(0xa32b2c8e, 0x2439cfa7),
+ TOBN(0x1671c173, 0x73dd0b4e), TOBN(0x37a28214, 0x44a054c6),
+ TOBN(0x81760a1b, 0x4e8b53f1), TOBN(0xa6c04224, 0xf9f93b9e),
+ TOBN(0x18784b34, 0xcf671e3c), TOBN(0x81bbecd2, 0xcda9b994),
+ TOBN(0x38831979, 0xb2ab3848), TOBN(0xef54feb7, 0xf2e03c2d),
+ TOBN(0xcf197ca7, 0xfb8088fa), TOBN(0x01427247, 0x4ddc96c5),
+ TOBN(0xa2d2550a, 0x30777176), TOBN(0x53469898, 0x4d0cf71d),
+ TOBN(0x6ce937b8, 0x3a2aaac6), TOBN(0xe9f91dc3, 0x5af38d9b),
+ TOBN(0x2598ad83, 0xc8bf2899), TOBN(0x8e706ac9, 0xb5536c16),
+ TOBN(0x40dc7495, 0xf688dc98), TOBN(0x26490cd7, 0x124c4afc),
+ TOBN(0xe651ec84, 0x1f18775c), TOBN(0x393ea6c3, 0xb4fdaf4a),
+ TOBN(0x1e1f3343, 0x7f338e0d), TOBN(0x39fb832b, 0x6053e7b5),
+ TOBN(0x46e702da, 0x619e14d5), TOBN(0x859cacd1, 0xcdeef6e0),
+ TOBN(0x63b99ce7, 0x4462007d), TOBN(0xb8ab48a5, 0x4cb5f5b7),
+ TOBN(0x9ec673d2, 0xf55edde7), TOBN(0xd1567f74, 0x8cfaefda),
+ TOBN(0x46381b6b, 0x0887bcec), TOBN(0x694497ce, 0xe178f3c2),
+ TOBN(0x5e6525e3, 0x1e6266cb), TOBN(0x5931de26, 0x697d6413),
+ TOBN(0x87f8df7c, 0x0e58d493), TOBN(0xb1ae5ed0, 0x58b73f12),
+ TOBN(0xc368f784, 0xdea0c34d), TOBN(0x9bd0a120, 0x859a91a0),
+ TOBN(0xb00d88b7, 0xcc863c68), TOBN(0x3a1cc11e, 0x3d1f4d65),
+ TOBN(0xea38e0e7, 0x0aa85593), TOBN(0x37f13e98, 0x7dc4aee8),
+ TOBN(0x10d38667, 0xbc947bad), TOBN(0x738e07ce, 0x2a36ee2e),
+ TOBN(0xc93470cd, 0xc577fcac), TOBN(0xdee1b616, 0x2782470d),
+ TOBN(0x36a25e67, 0x2e793d12), TOBN(0xd6aa6cae, 0xe0f186da),
+ TOBN(0x474d0fd9, 0x80e07af7), TOBN(0xf7cdc47d, 0xba8a5cd4),
+ TOBN(0x28af6d9d, 0xab15247f), TOBN(0x7c789c10, 0x493a537f),
+ TOBN(0x7ac9b110, 0x23a334e7), TOBN(0x0236ac09, 0x12c9c277),
+ TOBN(0xa7e5bd25, 0x1d7a5144), TOBN(0x098b9c2a, 0xf13ec4ec),
+ TOBN(0x3639daca, 0xd3f0abca), TOBN(0x642da81a, 0xa23960f9),
+ TOBN(0x7d2e5c05, 0x4f7269b1), TOBN(0xfcf30777, 0xe287c385),
+ TOBN(0x10edc84f, 0xf2a46f21), TOBN(0x35441757, 0x4f43fa36),
+ TOBN(0xf1327899, 0xfd703431), TOBN(0xa438d7a6, 0x16dd587a),
+ TOBN(0x65c34c57, 0xe9c8352d), TOBN(0xa728edab, 0x5cc5a24e),
+ TOBN(0xaed78abc, 0x42531689), TOBN(0x0a51a0e8, 0x010963ef),
+ TOBN(0x5776fa0a, 0xd717d9b3), TOBN(0xf356c239, 0x7dd3428b),
+ TOBN(0x29903fff, 0x8d3a3dac), TOBN(0x409597fa, 0x3d94491f),
+ TOBN(0x4cd7a5ff, 0xbf4a56a4), TOBN(0xe5096474, 0x8adab462),
+ TOBN(0xa97b5126, 0x5c3427b0), TOBN(0x6401405c, 0xd282c9bd),
+ TOBN(0x3629f8d7, 0x222c5c45), TOBN(0xb1c02c16, 0xe8d50aed),
+ TOBN(0xbea2ed75, 0xd9635bc9), TOBN(0x226790c7, 0x6e24552f),
+ TOBN(0x3c33f2a3, 0x65f1d066), TOBN(0x2a43463e, 0x6dfccc2e),
+ TOBN(0x8cc3453a, 0xdb483761), TOBN(0xe7cc6085, 0x65d5672b),
+ TOBN(0x277ed6cb, 0xde3efc87), TOBN(0x19f2f368, 0x69234eaf),
+ TOBN(0x9aaf4317, 0x5c0b800b), TOBN(0x1f1e7c89, 0x8b6da6e2),
+ TOBN(0x6cfb4715, 0xb94ec75e), TOBN(0xd590dd5f, 0x453118c2),
+ TOBN(0x14e49da1, 0x1f17a34c), TOBN(0x5420ab39, 0x235a1456),
+ TOBN(0xb7637241, 0x2f50363b), TOBN(0x7b15d623, 0xc3fabb6e),
+ TOBN(0xa0ef40b1, 0xe274e49c), TOBN(0x5cf50744, 0x96b1860a),
+ TOBN(0xd6583fbf, 0x66afe5a4), TOBN(0x44240510, 0xf47e3e9a),
+ TOBN(0x99254343, 0x11b2d595), TOBN(0xf1367499, 0xeec8df57),
+ TOBN(0x3cb12c61, 0x3e73dd05), TOBN(0xd248c033, 0x7dac102a),
+ TOBN(0xcf154f13, 0xa77739f5), TOBN(0xbf4288cb, 0x23d2af42),
+ TOBN(0xaa64c9b6, 0x32e4a1cf), TOBN(0xee8c07a8, 0xc8a208f3),
+ TOBN(0xe10d4999, 0x6fe8393f), TOBN(0x0f809a3f, 0xe91f3a32),
+ TOBN(0x61096d1c, 0x802f63c8), TOBN(0x289e1462, 0x57750d3d),
+ TOBN(0xed06167e, 0x9889feea), TOBN(0xd5c9c0e2, 0xe0993909),
+ TOBN(0x46fca0d8, 0x56508ac6), TOBN(0x91826047, 0x4f1b8e83),
+ TOBN(0x4f2c877a, 0x9a4a2751), TOBN(0x71bd0072, 0xcae6fead),
+ TOBN(0x38df8dcc, 0x06aa1941), TOBN(0x5a074b4c, 0x63beeaa8),
+ TOBN(0xd6d65934, 0xc1cec8ed), TOBN(0xa6ecb49e, 0xaabc03bd),
+ TOBN(0xaade91c2, 0xde8a8415), TOBN(0xcfb0efdf, 0x691136e0),
+ TOBN(0x11af45ee, 0x23ab3495), TOBN(0xa132df88, 0x0b77463d),
+ TOBN(0x8923c15c, 0x815d06f4), TOBN(0xc3ceb3f5, 0x0d61a436),
+ TOBN(0xaf52291d, 0xe88fb1da), TOBN(0xea057974, 0x1da12179),
+ TOBN(0xb0d7218c, 0xd2fef720), TOBN(0x6c0899c9, 0x8e1d8845),
+ TOBN(0x98157504, 0x752ddad7), TOBN(0xd60bd74f, 0xa1a68a97),
+ TOBN(0x7047a3a9, 0xf658fb99), TOBN(0x1f5d86d6, 0x5f8511e4),
+ TOBN(0xb8a4bc42, 0x4b5a6d88), TOBN(0x69eb2c33, 0x1abefa7d),
+ TOBN(0x95bf39e8, 0x13c9c510), TOBN(0xf571960a, 0xd48aab43),
+ TOBN(0x7e8cfbcf, 0x704e23c6), TOBN(0xc71b7d22, 0x28aaa65b),
+ TOBN(0xa041b2bd, 0x245e3c83), TOBN(0x69b98834, 0xd21854ff),
+ TOBN(0x89d227a3, 0x963bfeec), TOBN(0x99947aaa, 0xde7da7cb),
+ TOBN(0x1d9ee9db, 0xee68a9b1), TOBN(0x0a08f003, 0x698ec368),
+ TOBN(0xe9ea4094, 0x78ef2487), TOBN(0xc8d2d415, 0x02cfec26),
+ TOBN(0xc52f9a6e, 0xb7dcf328), TOBN(0x0ed489e3, 0x85b6a937),
+ TOBN(0x9b94986b, 0xbef3366e), TOBN(0x0de59c70, 0xedddddb8),
+ TOBN(0xffdb748c, 0xeadddbe2), TOBN(0x9b9784bb, 0x8266ea40),
+ TOBN(0x142b5502, 0x1a93507a), TOBN(0xb4cd1187, 0x8d3c06cf),
+ TOBN(0xdf70e76a, 0x91ec3f40), TOBN(0x484e81ad, 0x4e7553c2),
+ TOBN(0x830f87b5, 0x272e9d6e), TOBN(0xea1c93e5, 0xc6ff514a),
+ TOBN(0x67cc2adc, 0xc4192a8e), TOBN(0xc77e27e2, 0x42f4535a),
+ TOBN(0x9cdbab36, 0xd2b713c5), TOBN(0x86274ea0, 0xcf7b0cd3),
+ TOBN(0x784680f3, 0x09af826b), TOBN(0xbfcc837a, 0x0c72dea3),
+ TOBN(0xa8bdfe9d, 0xd6529b73), TOBN(0x708aa228, 0x63a88002),
+ TOBN(0x6c7a9a54, 0xc91d45b9), TOBN(0xdf1a38bb, 0xfd004f56),
+ TOBN(0x2e8c9a26, 0xb8bad853), TOBN(0x2d52cea3, 0x3723eae7),
+ TOBN(0x054d6d81, 0x56ca2830), TOBN(0xa3317d14, 0x9a8dc411),
+ TOBN(0xa08662fe, 0xfd4ddeda), TOBN(0xed2a153a, 0xb55d792b),
+ TOBN(0x7035c16a, 0xbfc6e944), TOBN(0xb6bc5834, 0x00171cf3),
+ TOBN(0xe27152b3, 0x83d102b6), TOBN(0xfe695a47, 0x0646b848),
+ TOBN(0xa5bb09d8, 0x916e6d37), TOBN(0xb4269d64, 0x0d17015e),
+ TOBN(0x8d8156a1, 0x0a1d2285), TOBN(0xfeef6c51, 0x46d26d72),
+ TOBN(0x9dac57c8, 0x4c5434a7), TOBN(0x0282e5be, 0x59d39e31),
+ TOBN(0xedfff181, 0x721c486d), TOBN(0x301baf10, 0xbc58824e),
+ TOBN(0x8136a6aa, 0x00570031), TOBN(0x55aaf78c, 0x1cddde68),
+ TOBN(0x26829371, 0x59c63952), TOBN(0x3a3bd274, 0x8bc25baf),
+ TOBN(0xecdf8657, 0xb7e52dc3), TOBN(0x2dd8c087, 0xfd78e6c8),
+ TOBN(0x20553274, 0xf5531461), TOBN(0x8b4a1281, 0x5d95499b),
+ TOBN(0xe2c8763a, 0x1a80f9d2), TOBN(0xd1dbe32b, 0x4ddec758),
+ TOBN(0xaf12210d, 0x30c34169), TOBN(0xba74a953, 0x78baa533),
+ TOBN(0x3d133c6e, 0xa438f254), TOBN(0xa431531a, 0x201bef5b),
+ TOBN(0x15295e22, 0xf669d7ec), TOBN(0xca374f64, 0x357fb515),
+ TOBN(0x8a8406ff, 0xeaa3fdb3), TOBN(0x106ae448, 0xdf3f2da8),
+ TOBN(0x8f9b0a90, 0x33c8e9a1), TOBN(0x234645e2, 0x71ad5885),
+ TOBN(0x3d083224, 0x1c0aed14), TOBN(0xf10a7d3e, 0x7a942d46),
+ TOBN(0x7c11deee, 0x40d5c9be), TOBN(0xb2bae7ff, 0xba84ed98),
+ TOBN(0x93e97139, 0xaad58ddd), TOBN(0x3d872796, 0x3f6d1fa3),
+ TOBN(0x483aca81, 0x8569ff13), TOBN(0x8b89a5fb, 0x9a600f72),
+ TOBN(0x4cbc27c3, 0xc06f2b86), TOBN(0x22130713, 0x63ad9c0b),
+ TOBN(0xb5358b1e, 0x48ac2840), TOBN(0x18311294, 0xecba9477),
+ TOBN(0xda58f990, 0xa6946b43), TOBN(0x3098baf9, 0x9ab41819),
+ TOBN(0x66c4c158, 0x4198da52), TOBN(0xab4fc17c, 0x146bfd1b),
+ TOBN(0x2f0a4c3c, 0xbf36a908), TOBN(0x2ae9e34b, 0x58cf7838),
+ TOBN(0xf411529e, 0x3fa11b1f), TOBN(0x21e43677, 0x974af2b4),
+ TOBN(0x7c20958e, 0xc230793b), TOBN(0x710ea885, 0x16e840f3),
+ TOBN(0xfc0b21fc, 0xc5dc67cf), TOBN(0x08d51647, 0x88405718),
+ TOBN(0xd955c21f, 0xcfe49eb7), TOBN(0x9722a5d5, 0x56dd4a1f),
+ TOBN(0xc9ef50e2, 0xc861baa5), TOBN(0xc0c21a5d, 0x9505ac3e),
+ TOBN(0xaf6b9a33, 0x8b7c063f), TOBN(0xc6370339, 0x2f4779c1),
+ TOBN(0x22df99c7, 0x638167c3), TOBN(0xfe6ffe76, 0x795db30c),
+ TOBN(0x2b822d33, 0xa4854989), TOBN(0xfef031dd, 0x30563aa5),
+ TOBN(0x16b09f82, 0xd57c667f), TOBN(0xc70312ce, 0xcc0b76f1),
+ TOBN(0xbf04a9e6, 0xc9118aec), TOBN(0x82fcb419, 0x3409d133),
+ TOBN(0x1a8ab385, 0xab45d44d), TOBN(0xfba07222, 0x617b83a3),
+ TOBN(0xb05f50dd, 0x58e81b52), TOBN(0x1d8db553, 0x21ce5aff),
+ TOBN(0x3097b8d4, 0xe344a873), TOBN(0x7d8d116d, 0xfe36d53e),
+ TOBN(0x6db22f58, 0x7875e750), TOBN(0x2dc5e373, 0x43e144ea),
+ TOBN(0xc05f32e6, 0xe799eb95), TOBN(0xe9e5f4df, 0x6899e6ec),
+ TOBN(0xbdc3bd68, 0x1fab23d5), TOBN(0xb72b8ab7, 0x73af60e6),
+ TOBN(0x8db27ae0, 0x2cecc84a), TOBN(0x600016d8, 0x7bdb871c),
+ TOBN(0x42a44b13, 0xd7c46f58), TOBN(0xb8919727, 0xc3a77d39),
+ TOBN(0xcfc6bbbd, 0xdafd6088), TOBN(0x1a740146, 0x6bd20d39),
+ TOBN(0x8c747abd, 0x98c41072), TOBN(0x4c91e765, 0xbdf68ea1),
+ TOBN(0x7c95e5ca, 0x08819a78), TOBN(0xcf48b729, 0xc9587921),
+ TOBN(0x091c7c5f, 0xdebbcc7d), TOBN(0x6f287404, 0xf0e05149),
+ TOBN(0xf83b5ac2, 0x26cd44ec), TOBN(0x88ae32a6, 0xcfea250e),
+ TOBN(0x6ac5047a, 0x1d06ebc5), TOBN(0xc7e550b4, 0xd434f781),
+ TOBN(0x61ab1cf2, 0x5c727bd2), TOBN(0x2e4badb1, 0x1cf915b0),
+ TOBN(0x1b4dadec, 0xf69d3920), TOBN(0xe61b1ca6, 0xf14c1dfe),
+ TOBN(0x90b479cc, 0xbd6bd51f), TOBN(0x8024e401, 0x8045ec30),
+ TOBN(0xcab29ca3, 0x25ef0e62), TOBN(0x4f2e9416, 0x49e4ebc0),
+ TOBN(0x45eb40ec, 0x0ccced58), TOBN(0x25cd4b9c, 0x0da44f98),
+ TOBN(0x43e06458, 0x871812c6), TOBN(0x99f80d55, 0x16cef651),
+ TOBN(0x571340c9, 0xce6dc153), TOBN(0x138d5117, 0xd8665521),
+ TOBN(0xacdb45bc, 0x4e07014d), TOBN(0x2f34bb38, 0x84b60b91),
+ TOBN(0xf44a4fd2, 0x2ae8921e), TOBN(0xb039288e, 0x892ba1e2),
+ TOBN(0x9da50174, 0xb1c180b2), TOBN(0x6b70ab66, 0x1693dc87),
+ TOBN(0x7e9babc9, 0xe7057481), TOBN(0x4581ddef, 0x9c80dc41),
+ TOBN(0x0c890da9, 0x51294682), TOBN(0x0b5629d3, 0x3f4736e5),
+ TOBN(0x2340c79e, 0xb06f5b41), TOBN(0xa42e84ce, 0x4e243469),
+ TOBN(0xf9a20135, 0x045a71a9), TOBN(0xefbfb415, 0xd27b6fb6),
+ TOBN(0x25ebea23, 0x9d33cd6f), TOBN(0x9caedb88, 0xaa6c0af8),
+ TOBN(0x53dc7e9a, 0xd9ce6f96), TOBN(0x3897f9fd, 0x51e0b15a),
+ TOBN(0xf51cb1f8, 0x8e5d788e), TOBN(0x1aec7ba8, 0xe1d490ee),
+ TOBN(0x265991e0, 0xcc58cb3c), TOBN(0x9f306e8c, 0x9fc3ad31),
+ TOBN(0x5fed006e, 0x5040a0ac), TOBN(0xca9d5043, 0xfb476f2e),
+ TOBN(0xa19c06e8, 0xbeea7a23), TOBN(0xd2865801, 0x0edabb63),
+ TOBN(0xdb92293f, 0x6967469a), TOBN(0x2894d839, 0x8d8a8ed8),
+ TOBN(0x87c9e406, 0xbbc77122), TOBN(0x8671c6f1, 0x2ea3a26a),
+ TOBN(0xe42df8d6, 0xd7de9853), TOBN(0x2e3ce346, 0xb1f2bcc7),
+ TOBN(0xda601dfc, 0x899d50cf), TOBN(0xbfc913de, 0xfb1b598f),
+ TOBN(0x81c4909f, 0xe61f7908), TOBN(0x192e304f, 0x9bbc7b29),
+ TOBN(0xc3ed8738, 0xc104b338), TOBN(0xedbe9e47, 0x783f5d61),
+ TOBN(0x0c06e9be, 0x2db30660), TOBN(0xda3e613f, 0xc0eb7d8e),
+ TOBN(0xd8fa3e97, 0x322e096e), TOBN(0xfebd91e8, 0xd336e247),
+ TOBN(0x8f13ccc4, 0xdf655a49), TOBN(0xa9e00dfc, 0x5eb20210),
+ TOBN(0x84631d0f, 0xc656b6ea), TOBN(0x93a058cd, 0xd8c0d947),
+ TOBN(0x6846904a, 0x67bd3448), TOBN(0x4a3d4e1a, 0xf394fd5c),
+ TOBN(0xc102c1a5, 0xdb225f52), TOBN(0xe3455bba, 0xfc4f5e9a),
+ TOBN(0x6b36985b, 0x4b9ad1ce), TOBN(0xa9818536, 0x5bb7f793),
+ TOBN(0x6c25e1d0, 0x48b1a416), TOBN(0x1381dd53, 0x3c81bee7),
+ TOBN(0xd2a30d61, 0x7a4a7620), TOBN(0xc8412926, 0x39b8944c),
+ TOBN(0x3c1c6fbe, 0x7a97c33a), TOBN(0x941e541d, 0x938664e7),
+ TOBN(0x417499e8, 0x4a34f239), TOBN(0x15fdb83c, 0xb90402d5),
+ TOBN(0xb75f46bf, 0x433aa832), TOBN(0xb61e15af, 0x63215db1),
+ TOBN(0xaabe59d4, 0xa127f89a), TOBN(0x5d541e0c, 0x07e816da),
+ TOBN(0xaaba0659, 0xa618b692), TOBN(0x55327733, 0x17266026),
+ TOBN(0xaf53a0fc, 0x95f57552), TOBN(0x32947650, 0x6cacb0c9),
+ TOBN(0x253ff58d, 0xc821be01), TOBN(0xb0309531, 0xa06f1146),
+ TOBN(0x59bbbdf5, 0x05c2e54d), TOBN(0x158f27ad, 0x26e8dd22),
+ TOBN(0xcc5b7ffb, 0x397e1e53), TOBN(0xae03f65b, 0x7fc1e50d),
+ TOBN(0xa9784ebd, 0x9c95f0f9), TOBN(0x5ed9deb2, 0x24640771),
+ TOBN(0x31244af7, 0x035561c4), TOBN(0x87332f3a, 0x7ee857de),
+ TOBN(0x09e16e9e, 0x2b9e0d88), TOBN(0x52d910f4, 0x56a06049),
+ TOBN(0x507ed477, 0xa9592f48), TOBN(0x85cb917b, 0x2365d678),
+ TOBN(0xf8511c93, 0x4c8998d1), TOBN(0x2186a3f1, 0x730ea58f),
+ TOBN(0x50189626, 0xb2029db0), TOBN(0x9137a6d9, 0x02ceb75a),
+ TOBN(0x2fe17f37, 0x748bc82c), TOBN(0x87c2e931, 0x80469f8c),
+ TOBN(0x850f71cd, 0xbf891aa2), TOBN(0x0ca1b89b, 0x75ec3d8d),
+ TOBN(0x516c43aa, 0x5e1cd3cd), TOBN(0x89397808, 0x9a887c28),
+ TOBN(0x0059c699, 0xddea1f9f), TOBN(0x7737d6fa, 0x8e6868f7),
+ TOBN(0x6d93746a, 0x60f1524b), TOBN(0x36985e55, 0xba052aa7),
+ TOBN(0x41b1d322, 0xed923ea5), TOBN(0x3429759f, 0x25852a11),
+ TOBN(0xbeca6ec3, 0x092e9f41), TOBN(0x3a238c66, 0x62256bbd),
+ TOBN(0xd82958ea, 0x70ad487d), TOBN(0x4ac8aaf9, 0x65610d93),
+ TOBN(0x3fa101b1, 0x5e4ccab0), TOBN(0x9bf430f2, 0x9de14bfb),
+ TOBN(0xa10f5cc6, 0x6531899d), TOBN(0x590005fb, 0xea8ce17d),
+ TOBN(0xc437912f, 0x24544cb6), TOBN(0x9987b71a, 0xd79ac2e3),
+ TOBN(0x13e3d9dd, 0xc058a212), TOBN(0x00075aac, 0xd2de9606),
+ TOBN(0x80ab508b, 0x6cac8369), TOBN(0x87842be7, 0xf54f6c89),
+ TOBN(0xa7ad663d, 0x6bc532a4), TOBN(0x67813de7, 0x78a91bc8),
+ TOBN(0x5dcb61ce, 0xc3427239), TOBN(0x5f3c7cf0, 0xc56934d9),
+ TOBN(0xc079e0fb, 0xe3191591), TOBN(0xe40896bd, 0xb01aada7),
+ TOBN(0x8d466791, 0x0492d25f), TOBN(0x8aeb30c9, 0xe7408276),
+ TOBN(0xe9437495, 0x9287aacc), TOBN(0x23d4708d, 0x79fe03d4),
+ TOBN(0x8cda9cf2, 0xd0c05199), TOBN(0x502fbc22, 0xfae78454),
+ TOBN(0xc0bda9df, 0xf572a182), TOBN(0x5f9b71b8, 0x6158b372),
+ TOBN(0xe0f33a59, 0x2b82dd07), TOBN(0x76302735, 0x9523032e),
+ TOBN(0x7fe1a721, 0xc4505a32), TOBN(0x7b6e3e82, 0xf796409f),
+ },
+ {
+ TOBN(0xe3417bc0, 0x35d0b34a), TOBN(0x440b386b, 0x8327c0a7),
+ TOBN(0x8fb7262d, 0xac0362d1), TOBN(0x2c41114c, 0xe0cdf943),
+ TOBN(0x2ba5cef1, 0xad95a0b1), TOBN(0xc09b37a8, 0x67d54362),
+ TOBN(0x26d6cdd2, 0x01e486c9), TOBN(0x20477abf, 0x42ff9297),
+ TOBN(0xa004dcb3, 0x292a9287), TOBN(0xddc15cf6, 0x77b092c7),
+ TOBN(0x083a8464, 0x806c0605), TOBN(0x4a68df70, 0x3db997b0),
+ TOBN(0x9c134e45, 0x05bf7dd0), TOBN(0xa4e63d39, 0x8ccf7f8c),
+ TOBN(0xa6e6517f, 0x41b5f8af), TOBN(0xaa8b9342, 0xad7bc1cc),
+ TOBN(0x126f35b5, 0x1e706ad9), TOBN(0xb99cebb4, 0xc3a9ebdf),
+ TOBN(0xa75389af, 0xbf608d90), TOBN(0x76113c4f, 0xc6c89858),
+ TOBN(0x80de8eb0, 0x97e2b5aa), TOBN(0x7e1022cc, 0x63b91304),
+ TOBN(0x3bdab605, 0x6ccc066c), TOBN(0x33cbb144, 0xb2edf900),
+ TOBN(0xc4176471, 0x7af715d2), TOBN(0xe2f7f594, 0xd0134a96),
+ TOBN(0x2c1873ef, 0xa41ec956), TOBN(0xe4e7b4f6, 0x77821304),
+ TOBN(0xe5c8ff97, 0x88d5374a), TOBN(0x2b915e63, 0x80823d5b),
+ TOBN(0xea6bc755, 0xb2ee8fe2), TOBN(0x6657624c, 0xe7112651),
+ TOBN(0x157af101, 0xdace5aca), TOBN(0xc4fdbcf2, 0x11a6a267),
+ TOBN(0xdaddf340, 0xc49c8609), TOBN(0x97e49f52, 0xe9604a65),
+ TOBN(0x9be8e790, 0x937e2ad5), TOBN(0x846e2508, 0x326e17f1),
+ TOBN(0x3f38007a, 0x0bbbc0dc), TOBN(0xcf03603f, 0xb11e16d6),
+ TOBN(0xd6f800e0, 0x7442f1d5), TOBN(0x475607d1, 0x66e0e3ab),
+ TOBN(0x82807f16, 0xb7c64047), TOBN(0x8858e1e3, 0xa749883d),
+ TOBN(0x5859120b, 0x8231ee10), TOBN(0x1b80e7eb, 0x638a1ece),
+ TOBN(0xcb72525a, 0xc6aa73a4), TOBN(0xa7cdea3d, 0x844423ac),
+ TOBN(0x5ed0c007, 0xf8ae7c38), TOBN(0x6db07a5c, 0x3d740192),
+ TOBN(0xbe5e9c2a, 0x5fe36db3), TOBN(0xd5b9d57a, 0x76e95046),
+ TOBN(0x54ac32e7, 0x8eba20f2), TOBN(0xef11ca8f, 0x71b9a352),
+ TOBN(0x305e373e, 0xff98a658), TOBN(0xffe5a100, 0x823eb667),
+ TOBN(0x57477b11, 0xe51732d2), TOBN(0xdfd6eb28, 0x2538fc0e),
+ TOBN(0x5c43b0cc, 0x3b39eec5), TOBN(0x6af12778, 0xcb36cc57),
+ TOBN(0x70b0852d, 0x06c425ae), TOBN(0x6df92f8c, 0x5c221b9b),
+ TOBN(0x6c8d4f9e, 0xce826d9c), TOBN(0xf59aba7b, 0xb49359c3),
+ TOBN(0x5c8ed8d5, 0xda64309d), TOBN(0x61a6de56, 0x91b30704),
+ TOBN(0xd6b52f6a, 0x2f9b5808), TOBN(0x0eee4194, 0x98c958a7),
+ TOBN(0xcddd9aab, 0x771e4caa), TOBN(0x83965dfd, 0x78bc21be),
+ TOBN(0x02affce3, 0xb3b504f5), TOBN(0x30847a21, 0x561c8291),
+ TOBN(0xd2eb2cf1, 0x52bfda05), TOBN(0xe0e4c4e9, 0x6197b98c),
+ TOBN(0x1d35076c, 0xf8a1726f), TOBN(0x6c06085b, 0x2db11e3d),
+ TOBN(0x15c0c4d7, 0x4463ba14), TOBN(0x9d292f83, 0x0030238c),
+ TOBN(0x1311ee8b, 0x3727536d), TOBN(0xfeea86ef, 0xbeaedc1e),
+ TOBN(0xb9d18cd3, 0x66131e2e), TOBN(0xf31d974f, 0x80fe2682),
+ TOBN(0xb6e49e0f, 0xe4160289), TOBN(0x7c48ec0b, 0x08e92799),
+ TOBN(0x818111d8, 0xd1989aa7), TOBN(0xb34fa0aa, 0xebf926f9),
+ TOBN(0xdb5fe2f5, 0xa245474a), TOBN(0xf80a6ebb, 0x3c7ca756),
+ TOBN(0xa7f96054, 0xafa05dd8), TOBN(0x26dfcf21, 0xfcaf119e),
+ TOBN(0xe20ef2e3, 0x0564bb59), TOBN(0xef4dca50, 0x61cb02b8),
+ TOBN(0xcda7838a, 0x65d30672), TOBN(0x8b08d534, 0xfd657e86),
+ TOBN(0x4c5b4395, 0x46d595c8), TOBN(0x39b58725, 0x425cb836),
+ TOBN(0x8ea61059, 0x3de9abe3), TOBN(0x40434881, 0x9cdc03be),
+ TOBN(0x9b261245, 0xcfedce8c), TOBN(0x78c318b4, 0xcf5234a1),
+ TOBN(0x510bcf16, 0xfde24c99), TOBN(0x2a77cb75, 0xa2c2ff5d),
+ TOBN(0x9c895c2b, 0x27960fb4), TOBN(0xd30ce975, 0xb0eda42b),
+ TOBN(0xfda85393, 0x1a62cc26), TOBN(0x23c69b96, 0x50c0e052),
+ TOBN(0xa227df15, 0xbfc633f3), TOBN(0x2ac78848, 0x1bae7d48),
+ TOBN(0x487878f9, 0x187d073d), TOBN(0x6c2be919, 0x967f807d),
+ TOBN(0x765861d8, 0x336e6d8f), TOBN(0x88b8974c, 0xce528a43),
+ TOBN(0x09521177, 0xff57d051), TOBN(0x2ff38037, 0xfb6a1961),
+ TOBN(0xfc0aba74, 0xa3d76ad4), TOBN(0x7c764803, 0x25a7ec17),
+ TOBN(0x7532d75f, 0x48879bc8), TOBN(0xea7eacc0, 0x58ce6bc1),
+ TOBN(0xc82176b4, 0x8e896c16), TOBN(0x9a30e0b2, 0x2c750fed),
+ TOBN(0xc37e2c2e, 0x421d3aa4), TOBN(0xf926407c, 0xe84fa840),
+ TOBN(0x18abc03d, 0x1454e41c), TOBN(0x26605ecd, 0x3f7af644),
+ TOBN(0x242341a6, 0xd6a5eabf), TOBN(0x1edb84f4, 0x216b668e),
+ TOBN(0xd836edb8, 0x04010102), TOBN(0x5b337ce7, 0x945e1d8c),
+ TOBN(0xd2075c77, 0xc055dc14), TOBN(0x2a0ffa25, 0x81d89cdf),
+ TOBN(0x8ce815ea, 0x6ffdcbaf), TOBN(0xa3428878, 0xfb648867),
+ TOBN(0x277699cf, 0x884655fb), TOBN(0xfa5b5bd6, 0x364d3e41),
+ TOBN(0x01f680c6, 0x441e1cb7), TOBN(0x3fd61e66, 0xb70a7d67),
+ TOBN(0x666ba2dc, 0xcc78cf66), TOBN(0xb3018174, 0x6fdbff77),
+ TOBN(0x8d4dd0db, 0x168d4668), TOBN(0x259455d0, 0x1dab3a2a),
+ TOBN(0xf58564c5, 0xcde3acec), TOBN(0x77141925, 0x13adb276),
+ TOBN(0x527d725d, 0x8a303f65), TOBN(0x55deb6c9, 0xe6f38f7b),
+ TOBN(0xfd5bb657, 0xb1fa70fb), TOBN(0xfa07f50f, 0xd8073a00),
+ TOBN(0xf72e3aa7, 0xbca02500), TOBN(0xf68f895d, 0x9975740d),
+ TOBN(0x30112060, 0x5cae2a6a), TOBN(0x01bd7218, 0x02874842),
+ TOBN(0x3d423891, 0x7ce47bd3), TOBN(0xa66663c1, 0x789544f6),
+ TOBN(0x864d05d7, 0x3272d838), TOBN(0xe22924f9, 0xfa6295c5),
+ TOBN(0x8189593f, 0x6c2fda32), TOBN(0x330d7189, 0xb184b544),
+ TOBN(0x79efa62c, 0xbde1f714), TOBN(0x35771c94, 0xe5cb1a63),
+ TOBN(0x2f4826b8, 0x641c8332), TOBN(0x00a894fb, 0xc8cee854),
+ TOBN(0xb4b9a39b, 0x36194d40), TOBN(0xe857a7c5, 0x77612601),
+ TOBN(0xf4209dd2, 0x4ecf2f58), TOBN(0x82b9e66d, 0x5a033487),
+ TOBN(0xc1e36934, 0xe4e8b9dd), TOBN(0xd2372c9d, 0xa42377d7),
+ TOBN(0x51dc94c7, 0x0e3ae43b), TOBN(0x4c57761e, 0x04474f6f),
+ TOBN(0xdcdacd0a, 0x1058a318), TOBN(0x369cf3f5, 0x78053a9a),
+ TOBN(0xc6c3de50, 0x31c68de2), TOBN(0x4653a576, 0x3c4b6d9f),
+ TOBN(0x1688dd5a, 0xaa4e5c97), TOBN(0x5be80aa1, 0xb7ab3c74),
+ TOBN(0x70cefe7c, 0xbc65c283), TOBN(0x57f95f13, 0x06867091),
+ TOBN(0xa39114e2, 0x4415503b), TOBN(0xc08ff7c6, 0x4cbb17e9),
+ TOBN(0x1eff674d, 0xd7dec966), TOBN(0x6d4690af, 0x53376f63),
+ TOBN(0xff6fe32e, 0xea74237b), TOBN(0xc436d17e, 0xcd57508e),
+ TOBN(0x15aa28e1, 0xedcc40fe), TOBN(0x0d769c04, 0x581bbb44),
+ TOBN(0xc240b6de, 0x34eaacda), TOBN(0xd9e116e8, 0x2ba0f1de),
+ TOBN(0xcbe45ec7, 0x79438e55), TOBN(0x91787c9d, 0x96f752d7),
+ TOBN(0x897f532b, 0xf129ac2f), TOBN(0xd307b7c8, 0x5a36e22c),
+ TOBN(0x91940675, 0x749fb8f3), TOBN(0xd14f95d0, 0x157fdb28),
+ TOBN(0xfe51d029, 0x6ae55043), TOBN(0x8931e98f, 0x44a87de1),
+ TOBN(0xe57f1cc6, 0x09e4fee2), TOBN(0x0d063b67, 0x4e072d92),
+ TOBN(0x70a998b9, 0xed0e4316), TOBN(0xe74a736b, 0x306aca46),
+ TOBN(0xecf0fbf2, 0x4fda97c7), TOBN(0xa40f65cb, 0x3e178d93),
+ TOBN(0x16253604, 0x16df4285), TOBN(0xb0c9babb, 0xd0c56ae2),
+ TOBN(0x73032b19, 0xcfc5cfc3), TOBN(0xe497e5c3, 0x09752056),
+ TOBN(0x12096bb4, 0x164bda96), TOBN(0x1ee42419, 0xa0b74da1),
+ TOBN(0x8fc36243, 0x403826ba), TOBN(0x0c8f0069, 0xdc09e660),
+ TOBN(0x8667e981, 0xc27253c9), TOBN(0x05a6aefb, 0x92b36a45),
+ TOBN(0xa62c4b36, 0x9cb7bb46), TOBN(0x8394f375, 0x11f7027b),
+ TOBN(0x747bc79c, 0x5f109d0f), TOBN(0xcad88a76, 0x5b8cc60a),
+ TOBN(0x80c5a66b, 0x58f09e68), TOBN(0xe753d451, 0xf6127eac),
+ TOBN(0xc44b74a1, 0x5b0ec6f5), TOBN(0x47989fe4, 0x5289b2b8),
+ TOBN(0x745f8484, 0x58d6fc73), TOBN(0xec362a6f, 0xf61c70ab),
+ TOBN(0x070c98a7, 0xb3a8ad41), TOBN(0x73a20fc0, 0x7b63db51),
+ TOBN(0xed2c2173, 0xf44c35f4), TOBN(0x8a56149d, 0x9acc9dca),
+ TOBN(0x98f17881, 0x9ac6e0f4), TOBN(0x360fdeaf, 0xa413b5ed),
+ TOBN(0x0625b8f4, 0xa300b0fd), TOBN(0xf1f4d76a, 0x5b3222d3),
+ TOBN(0x9d6f5109, 0x587f76b8), TOBN(0x8b4ee08d, 0x2317fdb5),
+ TOBN(0x88089bb7, 0x8c68b095), TOBN(0x95570e9a, 0x5808d9b9),
+ TOBN(0xa395c36f, 0x35d33ae7), TOBN(0x200ea123, 0x50bb5a94),
+ TOBN(0x20c789bd, 0x0bafe84b), TOBN(0x243ef52d, 0x0919276a),
+ TOBN(0x3934c577, 0xe23ae233), TOBN(0xb93807af, 0xa460d1ec),
+ TOBN(0xb72a53b1, 0xf8fa76a4), TOBN(0xd8914cb0, 0xc3ca4491),
+ TOBN(0x2e128494, 0x3fb42622), TOBN(0x3b2700ac, 0x500907d5),
+ TOBN(0xf370fb09, 0x1a95ec63), TOBN(0xf8f30be2, 0x31b6dfbd),
+ TOBN(0xf2b2f8d2, 0x69e55f15), TOBN(0x1fead851, 0xcc1323e9),
+ TOBN(0xfa366010, 0xd9e5eef6), TOBN(0x64d487b0, 0xe316107e),
+ TOBN(0x4c076b86, 0xd23ddc82), TOBN(0x03fd344c, 0x7e0143f0),
+ TOBN(0xa95362ff, 0x317af2c5), TOBN(0x0add3db7, 0xe18b7a4f),
+ TOBN(0x9c673e3f, 0x8260e01b), TOBN(0xfbeb49e5, 0x54a1cc91),
+ TOBN(0x91351bf2, 0x92f2e433), TOBN(0xc755e7ec, 0x851141eb),
+ TOBN(0xc9a95139, 0x29607745), TOBN(0x0ca07420, 0xa26f2b28),
+ TOBN(0xcb2790e7, 0x4bc6f9dd), TOBN(0x345bbb58, 0xadcaffc0),
+ TOBN(0xc65ea38c, 0xbe0f27a2), TOBN(0x67c24d7c, 0x641fcb56),
+ TOBN(0x2c25f0a7, 0xa9e2c757), TOBN(0x93f5cdb0, 0x16f16c49),
+ TOBN(0x2ca5a9d7, 0xc5ee30a1), TOBN(0xd1593635, 0xb909b729),
+ TOBN(0x804ce9f3, 0xdadeff48), TOBN(0xec464751, 0xb07c30c3),
+ TOBN(0x89d65ff3, 0x9e49af6a), TOBN(0xf2d6238a, 0x6f3d01bc),
+ TOBN(0x1095561e, 0x0bced843), TOBN(0x51789e12, 0xc8a13fd8),
+ TOBN(0xd633f929, 0x763231df), TOBN(0x46df9f7d, 0xe7cbddef),
+ TOBN(0x01c889c0, 0xcb265da8), TOBN(0xfce1ad10, 0xaf4336d2),
+ TOBN(0x8d110df6, 0xfc6a0a7e), TOBN(0xdd431b98, 0x6da425dc),
+ TOBN(0xcdc4aeab, 0x1834aabe), TOBN(0x84deb124, 0x8439b7fc),
+ TOBN(0x8796f169, 0x3c2a5998), TOBN(0x9b9247b4, 0x7947190d),
+ TOBN(0x55b9d9a5, 0x11597014), TOBN(0x7e9dd70d, 0x7b1566ee),
+ TOBN(0x94ad78f7, 0xcbcd5e64), TOBN(0x0359ac17, 0x9bd4c032),
+ TOBN(0x3b11baaf, 0x7cc222ae), TOBN(0xa6a6e284, 0xba78e812),
+ TOBN(0x8392053f, 0x24cea1a0), TOBN(0xc97bce4a, 0x33621491),
+ TOBN(0x7eb1db34, 0x35399ee9), TOBN(0x473f78ef, 0xece81ad1),
+ TOBN(0x41d72fe0, 0xf63d3d0d), TOBN(0xe620b880, 0xafab62fc),
+ TOBN(0x92096bc9, 0x93158383), TOBN(0x41a21357, 0x8f896f6c),
+ TOBN(0x1b5ee2fa, 0xc7dcfcab), TOBN(0x650acfde, 0x9546e007),
+ TOBN(0xc081b749, 0xb1b02e07), TOBN(0xda9e41a0, 0xf9eca03d),
+ TOBN(0x013ba727, 0x175a54ab), TOBN(0xca0cd190, 0xea5d8d10),
+ TOBN(0x85ea52c0, 0x95fd96a9), TOBN(0x2c591b9f, 0xbc5c3940),
+ TOBN(0x6fb4d4e4, 0x2bad4d5f), TOBN(0xfa4c3590, 0xfef0059b),
+ TOBN(0x6a10218a, 0xf5122294), TOBN(0x9a78a81a, 0xa85751d1),
+ TOBN(0x04f20579, 0xa98e84e7), TOBN(0xfe1242c0, 0x4997e5b5),
+ TOBN(0xe77a273b, 0xca21e1e4), TOBN(0xfcc8b1ef, 0x9411939d),
+ TOBN(0xe20ea302, 0x92d0487a), TOBN(0x1442dbec, 0x294b91fe),
+ TOBN(0x1f7a4afe, 0xbb6b0e8f), TOBN(0x1700ef74, 0x6889c318),
+ TOBN(0xf5bbffc3, 0x70f1fc62), TOBN(0x3b31d4b6, 0x69c79cca),
+ TOBN(0xe8bc2aab, 0xa7f6340d), TOBN(0xb0b08ab4, 0xa725e10a),
+ TOBN(0x44f05701, 0xae340050), TOBN(0xba4b3016, 0x1cf0c569),
+ TOBN(0x5aa29f83, 0xfbe19a51), TOBN(0x1b9ed428, 0xb71d752e),
+ TOBN(0x1666e54e, 0xeb4819f5), TOBN(0x616cdfed, 0x9e18b75b),
+ TOBN(0x112ed5be, 0x3ee27b0b), TOBN(0xfbf28319, 0x44c7de4d),
+ TOBN(0xd685ec85, 0xe0e60d84), TOBN(0x68037e30, 0x1db7ee78),
+ TOBN(0x5b65bdcd, 0x003c4d6e), TOBN(0x33e7363a, 0x93e29a6a),
+ TOBN(0x995b3a61, 0x08d0756c), TOBN(0xd727f85c, 0x2faf134b),
+ TOBN(0xfac6edf7, 0x1d337823), TOBN(0x99b9aa50, 0x0439b8b4),
+ TOBN(0x722eb104, 0xe2b4e075), TOBN(0x49987295, 0x437c4926),
+ TOBN(0xb1e4c0e4, 0x46a9b82d), TOBN(0xd0cb3197, 0x57a006f5),
+ TOBN(0xf3de0f7d, 0xd7808c56), TOBN(0xb5c54d8f, 0x51f89772),
+ TOBN(0x500a114a, 0xadbd31aa), TOBN(0x9afaaaa6, 0x295f6cab),
+ TOBN(0x94705e21, 0x04cf667a), TOBN(0xfc2a811b, 0x9d3935d7),
+ TOBN(0x560b0280, 0x6d09267c), TOBN(0xf19ed119, 0xf780e53b),
+ TOBN(0xf0227c09, 0x067b6269), TOBN(0x967b8533, 0x5caef599),
+ TOBN(0x155b9243, 0x68efeebc), TOBN(0xcd6d34f5, 0xc497bae6),
+ TOBN(0x1dd8d5d3, 0x6cceb370), TOBN(0x2aeac579, 0xa78d7bf9),
+ TOBN(0x5d65017d, 0x70b67a62), TOBN(0x70c8e44f, 0x17c53f67),
+ TOBN(0xd1fc0950, 0x86a34d09), TOBN(0xe0fca256, 0xe7134907),
+ TOBN(0xe24fa29c, 0x80fdd315), TOBN(0x2c4acd03, 0xd87499ad),
+ TOBN(0xbaaf7517, 0x3b5a9ba6), TOBN(0xb9cbe1f6, 0x12e51a51),
+ TOBN(0xd88edae3, 0x5e154897), TOBN(0xe4309c3c, 0x77b66ca0),
+ TOBN(0xf5555805, 0xf67f3746), TOBN(0x85fc37ba, 0xa36401ff),
+ TOBN(0xdf86e2ca, 0xd9499a53), TOBN(0x6270b2a3, 0xecbc955b),
+ TOBN(0xafae64f5, 0x974ad33b), TOBN(0x04d85977, 0xfe7b2df1),
+ TOBN(0x2a3db3ff, 0x4ab03f73), TOBN(0x0b87878a, 0x8702740a),
+ TOBN(0x6d263f01, 0x5a061732), TOBN(0xc25430ce, 0xa32a1901),
+ TOBN(0xf7ebab3d, 0xdb155018), TOBN(0x3a86f693, 0x63a9b78e),
+ TOBN(0x349ae368, 0xda9f3804), TOBN(0x470f07fe, 0xa164349c),
+ TOBN(0xd52f4cc9, 0x8562baa5), TOBN(0xc74a9e86, 0x2b290df3),
+ TOBN(0xd3a1aa35, 0x43471a24), TOBN(0x239446be, 0xb8194511),
+ TOBN(0xbec2dd00, 0x81dcd44d), TOBN(0xca3d7f0f, 0xc42ac82d),
+ TOBN(0x1f3db085, 0xfdaf4520), TOBN(0xbb6d3e80, 0x4549daf2),
+ TOBN(0xf5969d8a, 0x19ad5c42), TOBN(0x7052b13d, 0xdbfd1511),
+ TOBN(0x11890d1b, 0x682b9060), TOBN(0xa71d3883, 0xac34452c),
+ TOBN(0xa438055b, 0x783805b4), TOBN(0x43241277, 0x4725b23e),
+ TOBN(0xf20cf96e, 0x4901bbed), TOBN(0x6419c710, 0xf432a2bb),
+ TOBN(0x57a0fbb9, 0xdfa9cd7d), TOBN(0x589111e4, 0x00daa249),
+ TOBN(0x19809a33, 0x7b60554e), TOBN(0xea5f8887, 0xede283a4),
+ TOBN(0x2d713802, 0x503bfd35), TOBN(0x151bb0af, 0x585d2a53),
+ TOBN(0x40b08f74, 0x43b30ca8), TOBN(0xe10b5bba, 0xd9934583),
+ TOBN(0xe8a546d6, 0xb51110ad), TOBN(0x1dd50e66, 0x28e0b6c5),
+ TOBN(0x292e9d54, 0xcff2b821), TOBN(0x3882555d, 0x47281760),
+ TOBN(0x134838f8, 0x3724d6e3), TOBN(0xf2c679e0, 0x22ddcda1),
+ TOBN(0x40ee8815, 0x6d2a5768), TOBN(0x7f227bd2, 0x1c1e7e2d),
+ TOBN(0x487ba134, 0xd04ff443), TOBN(0x76e2ff3d, 0xc614e54b),
+ TOBN(0x36b88d6f, 0xa3177ec7), TOBN(0xbf731d51, 0x2328fff5),
+ TOBN(0x758caea2, 0x49ba158e), TOBN(0x5ab8ff4c, 0x02938188),
+ TOBN(0x33e16056, 0x35edc56d), TOBN(0x5a69d349, 0x7e940d79),
+ TOBN(0x6c4fd001, 0x03866dcb), TOBN(0x20a38f57, 0x4893cdef),
+ TOBN(0xfbf3e790, 0xfac3a15b), TOBN(0x6ed7ea2e, 0x7a4f8e6b),
+ TOBN(0xa663eb4f, 0xbc3aca86), TOBN(0x22061ea5, 0x080d53f7),
+ TOBN(0x2480dfe6, 0xf546783f), TOBN(0xd38bc6da, 0x5a0a641e),
+ TOBN(0xfb093cd1, 0x2ede8965), TOBN(0x89654db4, 0xacb455cf),
+ TOBN(0x413cbf9a, 0x26e1adee), TOBN(0x291f3764, 0x373294d4),
+ TOBN(0x00797257, 0x648083fe), TOBN(0x25f504d3, 0x208cc341),
+ TOBN(0x635a8e5e, 0xc3a0ee43), TOBN(0x70aaebca, 0x679898ff),
+ TOBN(0x9ee9f547, 0x5dc63d56), TOBN(0xce987966, 0xffb34d00),
+ TOBN(0xf9f86b19, 0x5e26310a), TOBN(0x9e435484, 0x382a8ca8),
+ TOBN(0x253bcb81, 0xc2352fe4), TOBN(0xa4eac8b0, 0x4474b571),
+ TOBN(0xc1b97512, 0xc1ad8cf8), TOBN(0x193b4e9e, 0x99e0b697),
+ TOBN(0x939d2716, 0x01e85df0), TOBN(0x4fb265b3, 0xcd44eafd),
+ TOBN(0x321e7dcd, 0xe51e1ae2), TOBN(0x8e3a8ca6, 0xe3d8b096),
+ TOBN(0x8de46cb0, 0x52604998), TOBN(0x91099ad8, 0x39072aa7),
+ TOBN(0x2617f91c, 0x93aa96b8), TOBN(0x0fc8716b, 0x7fca2e13),
+ TOBN(0xa7106f5e, 0x95328723), TOBN(0xd1c9c40b, 0x262e6522),
+ TOBN(0xb9bafe86, 0x42b7c094), TOBN(0x1873439d, 0x1543c021),
+ TOBN(0xe1baa5de, 0x5cbefd5d), TOBN(0xa363fc5e, 0x521e8aff),
+ TOBN(0xefe6320d, 0xf862eaac), TOBN(0x14419c63, 0x22c647dc),
+ TOBN(0x0e06707c, 0x4e46d428), TOBN(0xcb6c834f, 0x4a178f8f),
+ TOBN(0x0f993a45, 0xd30f917c), TOBN(0xd4c4b049, 0x9879afee),
+ TOBN(0xb6142a1e, 0x70500063), TOBN(0x7c9b41c3, 0xa5d9d605),
+ TOBN(0xbc00fc2f, 0x2f8ba2c7), TOBN(0x0966eb2f, 0x7c67aa28),
+ TOBN(0x13f7b516, 0x5a786972), TOBN(0x3bfb7557, 0x8a2fbba0),
+ TOBN(0x131c4f23, 0x5a2b9620), TOBN(0xbff3ed27, 0x6faf46be),
+ TOBN(0x9b4473d1, 0x7e172323), TOBN(0x421e8878, 0x339f6246),
+ TOBN(0x0fa8587a, 0x25a41632), TOBN(0xc0814124, 0xa35b6c93),
+ TOBN(0x2b18a9f5, 0x59ebb8db), TOBN(0x264e3357, 0x76edb29c),
+ TOBN(0xaf245ccd, 0xc87c51e2), TOBN(0x16b3015b, 0x501e6214),
+ TOBN(0xbb31c560, 0x0a3882ce), TOBN(0x6961bb94, 0xfec11e04),
+ TOBN(0x3b825b8d, 0xeff7a3a0), TOBN(0xbec33738, 0xb1df7326),
+ TOBN(0x68ad747c, 0x99604a1f), TOBN(0xd154c934, 0x9a3bd499),
+ TOBN(0xac33506f, 0x1cc7a906), TOBN(0x73bb5392, 0x6c560e8f),
+ TOBN(0x6428fcbe, 0x263e3944), TOBN(0xc11828d5, 0x1c387434),
+ TOBN(0x3cd04be1, 0x3e4b12ff), TOBN(0xc3aad9f9, 0x2d88667c),
+ TOBN(0xc52ddcf8, 0x248120cf), TOBN(0x985a892e, 0x2a389532),
+ TOBN(0xfbb4b21b, 0x3bb85fa0), TOBN(0xf95375e0, 0x8dfc6269),
+ TOBN(0xfb4fb06c, 0x7ee2acea), TOBN(0x6785426e, 0x309c4d1f),
+ TOBN(0x659b17c8, 0xd8ceb147), TOBN(0x9b649eee, 0xb70a5554),
+ TOBN(0x6b7fa0b5, 0xac6bc634), TOBN(0xd99fe2c7, 0x1d6e732f),
+ TOBN(0x30e6e762, 0x8d3abba2), TOBN(0x18fee6e7, 0xa797b799),
+ TOBN(0x5c9d360d, 0xc696464d), TOBN(0xe3baeb48, 0x27bfde12),
+ TOBN(0x2bf5db47, 0xf23206d5), TOBN(0x2f6d3420, 0x1d260152),
+ TOBN(0x17b87653, 0x3f8ff89a), TOBN(0x5157c30c, 0x378fa458),
+ TOBN(0x7517c5c5, 0x2d4fb936), TOBN(0xef22f7ac, 0xe6518cdc),
+ TOBN(0xdeb483e6, 0xbf847a64), TOBN(0xf5084558, 0x92e0fa89),
+ },
+ {
+ TOBN(0xab9659d8, 0xdf7304d4), TOBN(0xb71bcf1b, 0xff210e8e),
+ TOBN(0xa9a2438b, 0xd73fbd60), TOBN(0x4595cd1f, 0x5d11b4de),
+ TOBN(0x9c0d329a, 0x4835859d), TOBN(0x4a0f0d2d, 0x7dbb6e56),
+ TOBN(0xc6038e5e, 0xdf928a4e), TOBN(0xc9429621, 0x8f5ad154),
+ TOBN(0x91213462, 0xf23f2d92), TOBN(0x6cab71bd, 0x60b94078),
+ TOBN(0x6bdd0a63, 0x176cde20), TOBN(0x54c9b20c, 0xee4d54bc),
+ TOBN(0x3cd2d8aa, 0x9f2ac02f), TOBN(0x03f8e617, 0x206eedb0),
+ TOBN(0xc7f68e16, 0x93086434), TOBN(0x831469c5, 0x92dd3db9),
+ TOBN(0x8521df24, 0x8f981354), TOBN(0x587e23ec, 0x3588a259),
+ TOBN(0xcbedf281, 0xd7a0992c), TOBN(0x06930a55, 0x38961407),
+ TOBN(0x09320deb, 0xbe5bbe21), TOBN(0xa7ffa5b5, 0x2491817f),
+ TOBN(0xe6c8b4d9, 0x09065160), TOBN(0xac4f3992, 0xfff6d2a9),
+ TOBN(0x7aa7a158, 0x3ae9c1bd), TOBN(0xe0af6d98, 0xe37ce240),
+ TOBN(0xe54342d9, 0x28ab38b4), TOBN(0xe8b75007, 0x0a1c98ca),
+ TOBN(0xefce86af, 0xe02358f2), TOBN(0x31b8b856, 0xea921228),
+ TOBN(0x052a1912, 0x0a1c67fc), TOBN(0xb4069ea4, 0xe3aead59),
+ TOBN(0x3232d6e2, 0x7fa03cb3), TOBN(0xdb938e5b, 0x0fdd7d88),
+ TOBN(0x04c1d2cd, 0x2ccbfc5d), TOBN(0xd2f45c12, 0xaf3a580f),
+ TOBN(0x592620b5, 0x7883e614), TOBN(0x5fd27e68, 0xbe7c5f26),
+ TOBN(0x139e45a9, 0x1567e1e3), TOBN(0x2cc71d2d, 0x44d8aaaf),
+ TOBN(0x4a9090cd, 0xe36d0757), TOBN(0xf722d7b1, 0xd9a29382),
+ TOBN(0xfb7fb04c, 0x04b48ddf), TOBN(0x628ad2a7, 0xebe16f43),
+ TOBN(0xcd3fbfb5, 0x20226040), TOBN(0x6c34ecb1, 0x5104b6c4),
+ TOBN(0x30c0754e, 0xc903c188), TOBN(0xec336b08, 0x2d23cab0),
+ TOBN(0x473d62a2, 0x1e206ee5), TOBN(0xf1e27480, 0x8c49a633),
+ TOBN(0x87ab956c, 0xe9f6b2c3), TOBN(0x61830b48, 0x62b606ea),
+ TOBN(0x67cd6846, 0xe78e815f), TOBN(0xfe40139f, 0x4c02082a),
+ TOBN(0x52bbbfcb, 0x952ec365), TOBN(0x74c11642, 0x6b9836ab),
+ TOBN(0x9f51439e, 0x558df019), TOBN(0x230da4ba, 0xac712b27),
+ TOBN(0x518919e3, 0x55185a24), TOBN(0x4dcefcdd, 0x84b78f50),
+ TOBN(0xa7d90fb2, 0xa47d4c5a), TOBN(0x55ac9abf, 0xb30e009e),
+ TOBN(0xfd2fc359, 0x74eed273), TOBN(0xb72d824c, 0xdbea8faf),
+ TOBN(0xce721a74, 0x4513e2ca), TOBN(0x0b418612, 0x38240b2c),
+ TOBN(0x05199968, 0xd5baa450), TOBN(0xeb1757ed, 0x2b0e8c25),
+ TOBN(0x6ebc3e28, 0x3dfac6d5), TOBN(0xb2431e2e, 0x48a237f5),
+ TOBN(0x2acb5e23, 0x52f61499), TOBN(0x5558a2a7, 0xe06c936b),
+ TOBN(0xd213f923, 0xcbb13d1b), TOBN(0x98799f42, 0x5bfb9bfe),
+ TOBN(0x1ae8ddc9, 0x701144a9), TOBN(0x0b8b3bb6, 0x4c5595ee),
+ TOBN(0x0ea9ef2e, 0x3ecebb21), TOBN(0x17cb6c4b, 0x3671f9a7),
+ TOBN(0x47ef464f, 0x726f1d1f), TOBN(0x171b9484, 0x6943a276),
+ TOBN(0x51a4ae2d, 0x7ef0329c), TOBN(0x08509222, 0x91c4402a),
+ TOBN(0x64a61d35, 0xafd45bbc), TOBN(0x38f096fe, 0x3035a851),
+ TOBN(0xc7468b74, 0xa1dec027), TOBN(0xe8cf10e7, 0x4fc7dcba),
+ TOBN(0xea35ff40, 0xf4a06353), TOBN(0x0b4c0dfa, 0x8b77dd66),
+ TOBN(0x779b8552, 0xde7e5c19), TOBN(0xfab28609, 0xc1c0256c),
+ TOBN(0x64f58eee, 0xabd4743d), TOBN(0x4e8ef838, 0x7b6cc93b),
+ TOBN(0xee650d26, 0x4cb1bf3d), TOBN(0x4c1f9d09, 0x73dedf61),
+ TOBN(0xaef7c9d7, 0xbfb70ced), TOBN(0x1ec0507e, 0x1641de1e),
+ TOBN(0xcd7e5cc7, 0xcde45079), TOBN(0xde173c9a, 0x516ac9e4),
+ TOBN(0x517a8494, 0xc170315c), TOBN(0x438fd905, 0x91d8e8fb),
+ TOBN(0x5145c506, 0xc7d9630b), TOBN(0x6457a87b, 0xf47d4d75),
+ TOBN(0xd31646bf, 0x0d9a80e8), TOBN(0x453add2b, 0xcef3aabe),
+ TOBN(0xc9941109, 0xa607419d), TOBN(0xfaa71e62, 0xbb6bca80),
+ TOBN(0x34158c13, 0x07c431f3), TOBN(0x594abebc, 0x992bc47a),
+ TOBN(0x6dfea691, 0xeb78399f), TOBN(0x48aafb35, 0x3f42cba4),
+ TOBN(0xedcd65af, 0x077c04f0), TOBN(0x1a29a366, 0xe884491a),
+ TOBN(0x023a40e5, 0x1c21f2bf), TOBN(0xf99a513c, 0xa5057aee),
+ TOBN(0xa3fe7e25, 0xbcab072e), TOBN(0x8568d2e1, 0x40e32bcf),
+ TOBN(0x904594eb, 0xd3f69d9f), TOBN(0x181a9733, 0x07affab1),
+ TOBN(0xe4d68d76, 0xb6e330f4), TOBN(0x87a6dafb, 0xc75a7fc1),
+ TOBN(0x549db2b5, 0xef7d9289), TOBN(0x2480d4a8, 0x197f015a),
+ TOBN(0x61d5590b, 0xc40493b6), TOBN(0x3a55b52e, 0x6f780331),
+ TOBN(0x40eb8115, 0x309eadb0), TOBN(0xdea7de5a, 0x92e5c625),
+ TOBN(0x64d631f0, 0xcc6a3d5a), TOBN(0x9d5e9d7c, 0x93e8dd61),
+ TOBN(0xf297bef5, 0x206d3ffc), TOBN(0x23d5e033, 0x7d808bd4),
+ TOBN(0x4a4f6912, 0xd24cf5ba), TOBN(0xe4d8163b, 0x09cdaa8a),
+ TOBN(0x0e0de9ef, 0xd3082e8e), TOBN(0x4fe1246c, 0x0192f360),
+ TOBN(0x1f900150, 0x4b8eee0a), TOBN(0x5219da81, 0xf1da391b),
+ TOBN(0x7bf6a5c1, 0xf7ea25aa), TOBN(0xd165e6bf, 0xfbb07d5f),
+ TOBN(0xe3539361, 0x89e78671), TOBN(0xa3fcac89, 0x2bac4219),
+ TOBN(0xdfab6fd4, 0xf0baa8ab), TOBN(0x5a4adac1, 0xe2c1c2e5),
+ TOBN(0x6cd75e31, 0x40d85849), TOBN(0xce263fea, 0x19b39181),
+ TOBN(0xcb6803d3, 0x07032c72), TOBN(0x7f40d5ce, 0x790968c8),
+ TOBN(0xa6de86bd, 0xdce978f0), TOBN(0x25547c4f, 0x368f751c),
+ TOBN(0xb1e685fd, 0x65fb2a9e), TOBN(0xce69336f, 0x1eb9179c),
+ TOBN(0xb15d1c27, 0x12504442), TOBN(0xb7df465c, 0xb911a06b),
+ TOBN(0xb8d804a3, 0x315980cd), TOBN(0x693bc492, 0xfa3bebf7),
+ TOBN(0x3578aeee, 0x2253c504), TOBN(0x158de498, 0xcd2474a2),
+ TOBN(0x1331f5c7, 0xcfda8368), TOBN(0xd2d7bbb3, 0x78d7177e),
+ TOBN(0xdf61133a, 0xf3c1e46e), TOBN(0x5836ce7d, 0xd30e7be8),
+ TOBN(0x83084f19, 0x94f834cb), TOBN(0xd35653d4, 0x429ed782),
+ TOBN(0xa542f16f, 0x59e58243), TOBN(0xc2b52f65, 0x0470a22d),
+ TOBN(0xe3b6221b, 0x18f23d96), TOBN(0xcb05abac, 0x3f5252b4),
+ TOBN(0xca00938b, 0x87d61402), TOBN(0x2f186cdd, 0x411933e4),
+ TOBN(0xe042ece5, 0x9a29a5c5), TOBN(0xb19b3c07, 0x3b6c8402),
+ TOBN(0xc97667c7, 0x19d92684), TOBN(0xb5624622, 0xebc66372),
+ TOBN(0x0cb96e65, 0x3c04fa02), TOBN(0x83a7176c, 0x8eaa39aa),
+ TOBN(0x2033561d, 0xeaa1633f), TOBN(0x45a9d086, 0x4533df73),
+ TOBN(0xe0542c1d, 0x3dc090bc), TOBN(0x82c996ef, 0xaa59c167),
+ TOBN(0xe3f735e8, 0x0ee7fc4d), TOBN(0x7b179393, 0x7c35db79),
+ TOBN(0xb6419e25, 0xf8c5dbfd), TOBN(0x4d9d7a1e, 0x1f327b04),
+ TOBN(0x979f6f9b, 0x298dfca8), TOBN(0xc7c5dff1, 0x8de9366a),
+ TOBN(0x1b7a588d, 0x04c82bdd), TOBN(0x68005534, 0xf8319dfd),
+ TOBN(0xde8a55b5, 0xd8eb9580), TOBN(0x5ea886da, 0x8d5bca81),
+ TOBN(0xe8530a01, 0x252a0b4d), TOBN(0x1bffb4fe, 0x35eaa0a1),
+ TOBN(0x2ad828b1, 0xd8e99563), TOBN(0x7de96ef5, 0x95f9cd87),
+ TOBN(0x4abb2d0c, 0xd77d970c), TOBN(0x03cfb933, 0xd33ef9cb),
+ TOBN(0xb0547c01, 0x8b211fe9), TOBN(0x2fe64809, 0xa56ed1c6),
+ TOBN(0xcb7d5624, 0xc2ac98cc), TOBN(0x2a1372c0, 0x1a393e33),
+ TOBN(0xc8d1ec1c, 0x29660521), TOBN(0xf3d31b04, 0xb37ac3e9),
+ TOBN(0xa29ae9df, 0x5ece6e7c), TOBN(0x0603ac8f, 0x0facfb55),
+ TOBN(0xcfe85b7a, 0xdda233a5), TOBN(0xe618919f, 0xbd75f0b8),
+ TOBN(0xf555a3d2, 0x99bf1603), TOBN(0x1f43afc9, 0xf184255a),
+ TOBN(0xdcdaf341, 0x319a3e02), TOBN(0xd3b117ef, 0x03903a39),
+ TOBN(0xe095da13, 0x65d1d131), TOBN(0x86f16367, 0xc37ad03e),
+ TOBN(0x5f37389e, 0x462cd8dd), TOBN(0xc103fa04, 0xd67a60e6),
+ TOBN(0x57c34344, 0xf4b478f0), TOBN(0xce91edd8, 0xe117c98d),
+ TOBN(0x001777b0, 0x231fc12e), TOBN(0x11ae47f2, 0xb207bccb),
+ TOBN(0xd983cf8d, 0x20f8a242), TOBN(0x7aff5b1d, 0xf22e1ad8),
+ TOBN(0x68fd11d0, 0x7fc4feb3), TOBN(0x5d53ae90, 0xb0f1c3e1),
+ TOBN(0x50fb7905, 0xec041803), TOBN(0x85e3c977, 0x14404888),
+ TOBN(0x0e67faed, 0xac628d8f), TOBN(0x2e865150, 0x6668532c),
+ TOBN(0x15acaaa4, 0x6a67a6b0), TOBN(0xf4cdee25, 0xb25cec41),
+ TOBN(0x49ee565a, 0xe4c6701e), TOBN(0x2a04ca66, 0xfc7d63d8),
+ TOBN(0xeb105018, 0xef0543fb), TOBN(0xf709a4f5, 0xd1b0d81d),
+ TOBN(0x5b906ee6, 0x2915d333), TOBN(0xf4a87412, 0x96f1f0ab),
+ TOBN(0xb6b82fa7, 0x4d82f4c2), TOBN(0x90725a60, 0x6804efb3),
+ TOBN(0xbc82ec46, 0xadc3425e), TOBN(0xb7b80581, 0x2787843e),
+ TOBN(0xdf46d91c, 0xdd1fc74c), TOBN(0xdc1c62cb, 0xe783a6c4),
+ TOBN(0x59d1b9f3, 0x1a04cbba), TOBN(0xd87f6f72, 0x95e40764),
+ TOBN(0x02b4cfc1, 0x317f4a76), TOBN(0x8d2703eb, 0x91036bce),
+ TOBN(0x98206cc6, 0xa5e72a56), TOBN(0x57be9ed1, 0xcf53fb0f),
+ TOBN(0x09374571, 0xef0b17ac), TOBN(0x74b2655e, 0xd9181b38),
+ TOBN(0xc8f80ea8, 0x89935d0e), TOBN(0xc0d9e942, 0x91529936),
+ TOBN(0x19686041, 0x1e84e0e5), TOBN(0xa5db84d3, 0xaea34c93),
+ TOBN(0xf9d5bb19, 0x7073a732), TOBN(0xb8d2fe56, 0x6bcfd7c0),
+ TOBN(0x45775f36, 0xf3eb82fa), TOBN(0x8cb20ccc, 0xfdff8b58),
+ TOBN(0x1659b65f, 0x8374c110), TOBN(0xb8b4a422, 0x330c789a),
+ TOBN(0x75e3c3ea, 0x6fe8208b), TOBN(0xbd74b9e4, 0x286e78fe),
+ TOBN(0x0be2e81b, 0xd7d93a1a), TOBN(0x7ed06e27, 0xdd0a5aae),
+ TOBN(0x721f5a58, 0x6be8b800), TOBN(0x428299d1, 0xd846db28),
+ TOBN(0x95cb8e6b, 0x5be88ed3), TOBN(0xc3186b23, 0x1c034e11),
+ TOBN(0xa6312c9e, 0x8977d99b), TOBN(0xbe944331, 0x83f531e7),
+ TOBN(0x8232c0c2, 0x18d3b1d4), TOBN(0x617aae8b, 0xe1247b73),
+ TOBN(0x40153fc4, 0x282aec3b), TOBN(0xc6063d2f, 0xf7b8f823),
+ TOBN(0x68f10e58, 0x3304f94c), TOBN(0x31efae74, 0xee676346),
+ TOBN(0xbadb6c6d, 0x40a9b97c), TOBN(0x14702c63, 0x4f666256),
+ TOBN(0xdeb954f1, 0x5184b2e3), TOBN(0x5184a526, 0x94b6ca40),
+ TOBN(0xfff05337, 0x003c32ea), TOBN(0x5aa374dd, 0x205974c7),
+ TOBN(0x9a763854, 0x4b0dd71a), TOBN(0x459cd27f, 0xdeb947ec),
+ TOBN(0xa6e28161, 0x459c2b92), TOBN(0x2f020fa8, 0x75ee8ef5),
+ TOBN(0xb132ec2d, 0x30b06310), TOBN(0xc3e15899, 0xbc6a4530),
+ TOBN(0xdc5f53fe, 0xaa3f451a), TOBN(0x3a3c7f23, 0xc2d9acac),
+ TOBN(0x2ec2f892, 0x6b27e58b), TOBN(0x68466ee7, 0xd742799f),
+ TOBN(0x98324dd4, 0x1fa26613), TOBN(0xa2dc6dab, 0xbdc29d63),
+ TOBN(0xf9675faa, 0xd712d657), TOBN(0x813994be, 0x21fd8d15),
+ TOBN(0x5ccbb722, 0xfd4f7553), TOBN(0x5135ff8b, 0xf3a36b20),
+ TOBN(0x44be28af, 0x69559df5), TOBN(0x40b65bed, 0x9d41bf30),
+ TOBN(0xd98bf2a4, 0x3734e520), TOBN(0x5e3abbe3, 0x209bdcba),
+ TOBN(0x77c76553, 0xbc945b35), TOBN(0x5331c093, 0xc6ef14aa),
+ TOBN(0x518ffe29, 0x76b60c80), TOBN(0x2285593b, 0x7ace16f8),
+ TOBN(0xab1f64cc, 0xbe2b9784), TOBN(0xe8f2c0d9, 0xab2421b6),
+ TOBN(0x617d7174, 0xc1df065c), TOBN(0xafeeb5ab, 0x5f6578fa),
+ TOBN(0x16ff1329, 0x263b54a8), TOBN(0x45c55808, 0xc990dce3),
+ TOBN(0x42eab6c0, 0xecc8c177), TOBN(0x799ea9b5, 0x5982ecaa),
+ TOBN(0xf65da244, 0xb607ef8e), TOBN(0x8ab226ce, 0x32a3fc2c),
+ TOBN(0x745741e5, 0x7ea973dc), TOBN(0x5c00ca70, 0x20888f2e),
+ TOBN(0x7cdce3cf, 0x45fd9cf1), TOBN(0x8a741ef1, 0x5507f872),
+ TOBN(0x47c51c2f, 0x196b4cec), TOBN(0x70d08e43, 0xc97ea618),
+ TOBN(0x930da15c, 0x15b18a2b), TOBN(0x33b6c678, 0x2f610514),
+ TOBN(0xc662e4f8, 0x07ac9794), TOBN(0x1eccf050, 0xba06cb79),
+ TOBN(0x1ff08623, 0xe7d954e5), TOBN(0x6ef2c5fb, 0x24cf71c3),
+ TOBN(0xb2c063d2, 0x67978453), TOBN(0xa0cf3796, 0x1d654af8),
+ TOBN(0x7cb242ea, 0x7ebdaa37), TOBN(0x206e0b10, 0xb86747e0),
+ TOBN(0x481dae5f, 0xd5ecfefc), TOBN(0x07084fd8, 0xc2bff8fc),
+ TOBN(0x8040a01a, 0xea324596), TOBN(0x4c646980, 0xd4de4036),
+ TOBN(0x9eb8ab4e, 0xd65abfc3), TOBN(0xe01cb91f, 0x13541ec7),
+ TOBN(0x8f029adb, 0xfd695012), TOBN(0x9ae28483, 0x3c7569ec),
+ TOBN(0xa5614c9e, 0xa66d80a1), TOBN(0x680a3e44, 0x75f5f911),
+ TOBN(0x0c07b14d, 0xceba4fc1), TOBN(0x891c285b, 0xa13071c1),
+ TOBN(0xcac67ceb, 0x799ece3c), TOBN(0x29b910a9, 0x41e07e27),
+ TOBN(0x66bdb409, 0xf2e43123), TOBN(0x06f8b137, 0x7ac9ecbe),
+ TOBN(0x5981fafd, 0x38547090), TOBN(0x19ab8b9f, 0x85e3415d),
+ TOBN(0xfc28c194, 0xc7e31b27), TOBN(0x843be0aa, 0x6fbcbb42),
+ TOBN(0xf3b1ed43, 0xa6db836c), TOBN(0x2a1330e4, 0x01a45c05),
+ TOBN(0x4f19f3c5, 0x95c1a377), TOBN(0xa85f39d0, 0x44b5ee33),
+ TOBN(0x3da18e6d, 0x4ae52834), TOBN(0x5a403b39, 0x7423dcb0),
+ TOBN(0xbb555e0a, 0xf2374aef), TOBN(0x2ad599c4, 0x1e8ca111),
+ TOBN(0x1b3a2fb9, 0x014b3bf8), TOBN(0x73092684, 0xf66d5007),
+ TOBN(0x079f1426, 0xc4340102), TOBN(0x1827cf81, 0x8fddf4de),
+ TOBN(0xc83605f6, 0xf10ff927), TOBN(0xd3871451, 0x23739fc6),
+ TOBN(0x6d163450, 0xcac1c2cc), TOBN(0x6b521296, 0xa2ec1ac5),
+ TOBN(0x0606c4f9, 0x6e3cb4a5), TOBN(0xe47d3f41, 0x778abff7),
+ TOBN(0x425a8d5e, 0xbe8e3a45), TOBN(0x53ea9e97, 0xa6102160),
+ TOBN(0x477a106e, 0x39cbb688), TOBN(0x532401d2, 0xf3386d32),
+ TOBN(0x8e564f64, 0xb1b9b421), TOBN(0xca9b8388, 0x81dad33f),
+ TOBN(0xb1422b4e, 0x2093913e), TOBN(0x533d2f92, 0x69bc8112),
+ TOBN(0x3fa017be, 0xebe7b2c7), TOBN(0xb2767c4a, 0xcaf197c6),
+ TOBN(0xc925ff87, 0xaedbae9f), TOBN(0x7daf0eb9, 0x36880a54),
+ TOBN(0x9284ddf5, 0x9c4d0e71), TOBN(0x1581cf93, 0x316f8cf5),
+ TOBN(0x3eeca887, 0x3ac1f452), TOBN(0xb417fce9, 0xfb6aeffe),
+ TOBN(0xa5918046, 0xeefb8dc3), TOBN(0x73d318ac, 0x02209400),
+ TOBN(0xe800400f, 0x728693e5), TOBN(0xe87d814b, 0x339927ed),
+ TOBN(0x93e94d3b, 0x57ea9910), TOBN(0xff8a35b6, 0x2245fb69),
+ TOBN(0x043853d7, 0x7f200d34), TOBN(0x470f1e68, 0x0f653ce1),
+ TOBN(0x81ac05bd, 0x59a06379), TOBN(0xa14052c2, 0x03930c29),
+ TOBN(0x6b72fab5, 0x26bc2797), TOBN(0x13670d16, 0x99f16771),
+ TOBN(0x00170052, 0x1e3e48d1), TOBN(0x978fe401, 0xb7adf678),
+ TOBN(0x55ecfb92, 0xd41c5dd4), TOBN(0x5ff8e247, 0xc7b27da5),
+ TOBN(0xe7518272, 0x013fb606), TOBN(0x5768d7e5, 0x2f547a3c),
+ TOBN(0xbb24eaa3, 0x60017a5f), TOBN(0x6b18e6e4, 0x9c64ce9b),
+ TOBN(0xc225c655, 0x103dde07), TOBN(0xfc3672ae, 0x7592f7ea),
+ TOBN(0x9606ad77, 0xd06283a1), TOBN(0x542fc650, 0xe4d59d99),
+ TOBN(0xabb57c49, 0x2a40e7c2), TOBN(0xac948f13, 0xa8db9f55),
+ TOBN(0x6d4c9682, 0xb04465c3), TOBN(0xe3d062fa, 0x6468bd15),
+ TOBN(0xa51729ac, 0x5f318d7e), TOBN(0x1fc87df6, 0x9eb6fc95),
+ TOBN(0x63d146a8, 0x0591f652), TOBN(0xa861b8f7, 0x589621aa),
+ TOBN(0x59f5f15a, 0xce31348c), TOBN(0x8f663391, 0x440da6da),
+ TOBN(0xcfa778ac, 0xb591ffa3), TOBN(0x027ca9c5, 0x4cdfebce),
+ TOBN(0xbe8e05a5, 0x444ea6b3), TOBN(0x8aab4e69, 0xa78d8254),
+ TOBN(0x2437f04f, 0xb474d6b8), TOBN(0x6597ffd4, 0x045b3855),
+ TOBN(0xbb0aea4e, 0xca47ecaa), TOBN(0x568aae83, 0x85c7ebfc),
+ TOBN(0x0e966e64, 0xc73b2383), TOBN(0x49eb3447, 0xd17d8762),
+ TOBN(0xde107821, 0x8da05dab), TOBN(0x443d8baa, 0x016b7236),
+ TOBN(0x163b63a5, 0xea7610d6), TOBN(0xe47e4185, 0xce1ca979),
+ TOBN(0xae648b65, 0x80baa132), TOBN(0xebf53de2, 0x0e0d5b64),
+ TOBN(0x8d3bfcb4, 0xd3c8c1ca), TOBN(0x0d914ef3, 0x5d04b309),
+ TOBN(0x55ef6415, 0x3de7d395), TOBN(0xbde1666f, 0x26b850e8),
+ TOBN(0xdbe1ca6e, 0xd449ab19), TOBN(0x8902b322, 0xe89a2672),
+ TOBN(0xb1674b7e, 0xdacb7a53), TOBN(0x8e9faf6e, 0xf52523ff),
+ TOBN(0x6ba535da, 0x9a85788b), TOBN(0xd21f03ae, 0xbd0626d4),
+ TOBN(0x099f8c47, 0xe873dc64), TOBN(0xcda8564d, 0x018ec97e),
+ TOBN(0x3e8d7a5c, 0xde92c68c), TOBN(0x78e035a1, 0x73323cc4),
+ TOBN(0x3ef26275, 0xf880ff7c), TOBN(0xa4ee3dff, 0x273eedaa),
+ TOBN(0x58823507, 0xaf4e18f8), TOBN(0x967ec9b5, 0x0672f328),
+ TOBN(0x9ded19d9, 0x559d3186), TOBN(0x5e2ab3de, 0x6cdce39c),
+ TOBN(0xabad6e4d, 0x11c226df), TOBN(0xf9783f43, 0x87723014),
+ TOBN(0x9a49a0cf, 0x1a885719), TOBN(0xfc0c1a5a, 0x90da9dbf),
+ TOBN(0x8bbaec49, 0x571d92ac), TOBN(0x569e85fe, 0x4692517f),
+ TOBN(0x8333b014, 0xa14ea4af), TOBN(0x32f2a62f, 0x12e5c5ad),
+ TOBN(0x98c2ce3a, 0x06d89b85), TOBN(0xb90741aa, 0x2ff77a08),
+ TOBN(0x2530defc, 0x01f795a2), TOBN(0xd6e5ba0b, 0x84b3c199),
+ TOBN(0x7d8e8451, 0x12e4c936), TOBN(0xae419f7d, 0xbd0be17b),
+ TOBN(0xa583fc8c, 0x22262bc9), TOBN(0x6b842ac7, 0x91bfe2bd),
+ TOBN(0x33cef4e9, 0x440d6827), TOBN(0x5f69f4de, 0xef81fb14),
+ TOBN(0xf16cf6f6, 0x234fbb92), TOBN(0x76ae3fc3, 0xd9e7e158),
+ TOBN(0x4e89f6c2, 0xe9740b33), TOBN(0x677bc85d, 0x4962d6a1),
+ TOBN(0x6c6d8a7f, 0x68d10d15), TOBN(0x5f9a7224, 0x0257b1cd),
+ TOBN(0x7096b916, 0x4ad85961), TOBN(0x5f8c47f7, 0xe657ab4a),
+ TOBN(0xde57d7d0, 0xf7461d7e), TOBN(0x7eb6094d, 0x80ce5ee2),
+ TOBN(0x0b1e1dfd, 0x34190547), TOBN(0x8a394f43, 0xf05dd150),
+ TOBN(0x0a9eb24d, 0x97df44e6), TOBN(0x78ca06bf, 0x87675719),
+ TOBN(0x6f0b3462, 0x6ffeec22), TOBN(0x9d91bcea, 0x36cdd8fb),
+ TOBN(0xac83363c, 0xa105be47), TOBN(0x81ba76c1, 0x069710e3),
+ TOBN(0x3d1b24cb, 0x28c682c6), TOBN(0x27f25228, 0x8612575b),
+ TOBN(0xb587c779, 0xe8e66e98), TOBN(0x7b0c03e9, 0x405eb1fe),
+ TOBN(0xfdf0d030, 0x15b548e7), TOBN(0xa8be76e0, 0x38b36af7),
+ TOBN(0x4cdab04a, 0x4f310c40), TOBN(0x6287223e, 0xf47ecaec),
+ TOBN(0x678e6055, 0x8b399320), TOBN(0x61fe3fa6, 0xc01e4646),
+ TOBN(0xc482866b, 0x03261a5e), TOBN(0xdfcf45b8, 0x5c2f244a),
+ TOBN(0x8fab9a51, 0x2f684b43), TOBN(0xf796c654, 0xc7220a66),
+ TOBN(0x1d90707e, 0xf5afa58f), TOBN(0x2c421d97, 0x4fdbe0de),
+ TOBN(0xc4f4cda3, 0xaf2ebc2f), TOBN(0xa0af843d, 0xcb4efe24),
+ TOBN(0x53b857c1, 0x9ccd10b1), TOBN(0xddc9d1eb, 0x914d3e04),
+ TOBN(0x7bdec8bb, 0x62771deb), TOBN(0x829277aa, 0x91c5aa81),
+ TOBN(0x7af18dd6, 0x832391ae), TOBN(0x1740f316, 0xc71a84ca),
+ },
+ {
+ TOBN(0x8928e99a, 0xeeaf8c49), TOBN(0xee7aa73d, 0x6e24d728),
+ TOBN(0x4c5007c2, 0xe72b156c), TOBN(0x5fcf57c5, 0xed408a1d),
+ TOBN(0x9f719e39, 0xb6057604), TOBN(0x7d343c01, 0xc2868bbf),
+ TOBN(0x2cca254b, 0x7e103e2d), TOBN(0xe6eb38a9, 0xf131bea2),
+ TOBN(0xb33e624f, 0x8be762b4), TOBN(0x2a9ee4d1, 0x058e3413),
+ TOBN(0x968e6369, 0x67d805fa), TOBN(0x9848949b, 0x7db8bfd7),
+ TOBN(0x5308d7e5, 0xd23a8417), TOBN(0x892f3b1d, 0xf3e29da5),
+ TOBN(0xc95c139e, 0x3dee471f), TOBN(0x8631594d, 0xd757e089),
+ TOBN(0xe0c82a3c, 0xde918dcc), TOBN(0x2e7b5994, 0x26fdcf4b),
+ TOBN(0x82c50249, 0x32cb1b2d), TOBN(0xea613a9d, 0x7657ae07),
+ TOBN(0xc2eb5f6c, 0xf1fdc9f7), TOBN(0xb6eae8b8, 0x879fe682),
+ TOBN(0x253dfee0, 0x591cbc7f), TOBN(0x000da713, 0x3e1290e6),
+ TOBN(0x1083e2ea, 0x1f095615), TOBN(0x0a28ad77, 0x14e68c33),
+ TOBN(0x6bfc0252, 0x3d8818be), TOBN(0xb585113a, 0xf35850cd),
+ TOBN(0x7d935f0b, 0x30df8aa1), TOBN(0xaddda07c, 0x4ab7e3ac),
+ TOBN(0x92c34299, 0x552f00cb), TOBN(0xc33ed1de, 0x2909df6c),
+ TOBN(0x22c2195d, 0x80e87766), TOBN(0x9e99e6d8, 0x9ddf4ac0),
+ TOBN(0x09642e4e, 0x65e74934), TOBN(0x2610ffa2, 0xff1ff241),
+ TOBN(0x4d1d47d4, 0x751c8159), TOBN(0x697b4985, 0xaf3a9363),
+ TOBN(0x0318ca46, 0x87477c33), TOBN(0xa90cb565, 0x9441eff3),
+ TOBN(0x58bb3848, 0x36f024cb), TOBN(0x85be1f77, 0x36016168),
+ TOBN(0x6c59587c, 0xdc7e07f1), TOBN(0x191be071, 0xaf1d8f02),
+ TOBN(0xbf169fa5, 0xcca5e55c), TOBN(0x3864ba3c, 0xf7d04eac),
+ TOBN(0x915e367f, 0x8d7d05db), TOBN(0xb48a876d, 0xa6549e5d),
+ TOBN(0xef89c656, 0x580e40a2), TOBN(0xf194ed8c, 0x728068bc),
+ TOBN(0x74528045, 0xa47990c9), TOBN(0xf53fc7d7, 0x5e1a4649),
+ TOBN(0xbec5ae9b, 0x78593e7d), TOBN(0x2cac4ee3, 0x41db65d7),
+ TOBN(0xa8c1eb24, 0x04a3d39b), TOBN(0x53b7d634, 0x03f8f3ef),
+ TOBN(0x2dc40d48, 0x3e07113c), TOBN(0x6e4a5d39, 0x7d8b63ae),
+ TOBN(0x5582a94b, 0x79684c2b), TOBN(0x932b33d4, 0x622da26c),
+ TOBN(0xf534f651, 0x0dbbf08d), TOBN(0x211d07c9, 0x64c23a52),
+ TOBN(0x0eeece0f, 0xee5bdc9b), TOBN(0xdf178168, 0xf7015558),
+ TOBN(0xd4294635, 0x0a712229), TOBN(0x93cbe448, 0x09273f8c),
+ TOBN(0x00b095ef, 0x8f13bc83), TOBN(0xbb741972, 0x8798978c),
+ TOBN(0x9d7309a2, 0x56dbe6e7), TOBN(0xe578ec56, 0x5a5d39ec),
+ TOBN(0x3961151b, 0x851f9a31), TOBN(0x2da7715d, 0xe5709eb4),
+ TOBN(0x867f3017, 0x53dfabf0), TOBN(0x728d2078, 0xb8e39259),
+ TOBN(0x5c75a0cd, 0x815d9958), TOBN(0xf84867a6, 0x16603be1),
+ TOBN(0xc865b13d, 0x70e35b1c), TOBN(0x02414468, 0x19b03e2c),
+ TOBN(0xe46041da, 0xac1f3121), TOBN(0x7c9017ad, 0x6f028a7c),
+ TOBN(0xabc96de9, 0x0a482873), TOBN(0x4265d6b1, 0xb77e54d4),
+ TOBN(0x68c38e79, 0xa57d88e7), TOBN(0xd461d766, 0x9ce82de3),
+ TOBN(0x817a9ec5, 0x64a7e489), TOBN(0xcc5675cd, 0xa0def5f2),
+ TOBN(0x9a00e785, 0x985d494e), TOBN(0xc626833f, 0x1b03514a),
+ TOBN(0xabe7905a, 0x83cdd60e), TOBN(0x50602fb5, 0xa1170184),
+ TOBN(0x689886cd, 0xb023642a), TOBN(0xd568d090, 0xa6e1fb00),
+ TOBN(0x5b1922c7, 0x0259217f), TOBN(0x93831cd9, 0xc43141e4),
+ TOBN(0xdfca3587, 0x0c95f86e), TOBN(0xdec2057a, 0x568ae828),
+ TOBN(0xc44ea599, 0xf98a759a), TOBN(0x55a0a7a2, 0xf7c23c1d),
+ TOBN(0xd5ffb6e6, 0x94c4f687), TOBN(0x3563cce2, 0x12848478),
+ TOBN(0x812b3517, 0xe7b1fbe1), TOBN(0x8a7dc979, 0x4f7338e0),
+ TOBN(0x211ecee9, 0x52d048db), TOBN(0x2eea4056, 0xc86ea3b8),
+ TOBN(0xd8cb68a7, 0xba772b34), TOBN(0xe16ed341, 0x5f4e2541),
+ TOBN(0x9b32f6a6, 0x0fec14db), TOBN(0xeee376f7, 0x391698be),
+ TOBN(0xe9a7aa17, 0x83674c02), TOBN(0x65832f97, 0x5843022a),
+ TOBN(0x29f3a8da, 0x5ba4990f), TOBN(0x79a59c3a, 0xfb8e3216),
+ TOBN(0x9cdc4d2e, 0xbd19bb16), TOBN(0xc6c7cfd0, 0xb3262d86),
+ TOBN(0xd4ce14d0, 0x969c0b47), TOBN(0x1fa352b7, 0x13e56128),
+ TOBN(0x383d55b8, 0x973db6d3), TOBN(0x71836850, 0xe8e5b7bf),
+ TOBN(0xc7714596, 0xe6bb571f), TOBN(0x259df31f, 0x2d5b2dd2),
+ TOBN(0x568f8925, 0x913cc16d), TOBN(0x18bc5b6d, 0xe1a26f5a),
+ TOBN(0xdfa413be, 0xf5f499ae), TOBN(0xf8835dec, 0xc3f0ae84),
+ TOBN(0xb6e60bd8, 0x65a40ab0), TOBN(0x65596439, 0x194b377e),
+ TOBN(0xbcd85625, 0x92084a69), TOBN(0x5ce433b9, 0x4f23ede0),
+ TOBN(0xe8e8f04f, 0x6ad65143), TOBN(0x11511827, 0xd6e14af6),
+ TOBN(0x3d390a10, 0x8295c0c7), TOBN(0x71e29ee4, 0x621eba16),
+ TOBN(0xa588fc09, 0x63717b46), TOBN(0x02be02fe, 0xe06ad4a2),
+ TOBN(0x931558c6, 0x04c22b22), TOBN(0xbb4d4bd6, 0x12f3c849),
+ TOBN(0x54a4f496, 0x20efd662), TOBN(0x92ba6d20, 0xc5952d14),
+ TOBN(0x2db8ea1e, 0xcc9784c2), TOBN(0x81cc10ca, 0x4b353644),
+ TOBN(0x40b570ad, 0x4b4d7f6c), TOBN(0x5c9f1d96, 0x84a1dcd2),
+ TOBN(0x01379f81, 0x3147e797), TOBN(0xe5c6097b, 0x2bd499f5),
+ TOBN(0x40dcafa6, 0x328e5e20), TOBN(0xf7b5244a, 0x54815550),
+ TOBN(0xb9a4f118, 0x47bfc978), TOBN(0x0ea0e79f, 0xd25825b1),
+ TOBN(0xa50f96eb, 0x646c7ecf), TOBN(0xeb811493, 0x446dea9d),
+ TOBN(0x2af04677, 0xdfabcf69), TOBN(0xbe3a068f, 0xc713f6e8),
+ TOBN(0x860d523d, 0x42e06189), TOBN(0xbf077941, 0x4e3aff13),
+ TOBN(0x0b616dca, 0xc1b20650), TOBN(0xe66dd6d1, 0x2131300d),
+ TOBN(0xd4a0fd67, 0xff99abde), TOBN(0xc9903550, 0xc7aac50d),
+ TOBN(0x022ecf8b, 0x7c46b2d7), TOBN(0x3333b1e8, 0x3abf92af),
+ TOBN(0x11cc113c, 0x6c491c14), TOBN(0x05976688, 0x80dd3f88),
+ TOBN(0xf5b4d9e7, 0x29d932ed), TOBN(0xe982aad8, 0xa2c38b6d),
+ TOBN(0x6f925347, 0x8be0dcf0), TOBN(0x700080ae, 0x65ca53f2),
+ TOBN(0xd8131156, 0x443ca77f), TOBN(0xe92d6942, 0xec51f984),
+ TOBN(0xd2a08af8, 0x85dfe9ae), TOBN(0xd825d9a5, 0x4d2a86ca),
+ TOBN(0x2c53988d, 0x39dff020), TOBN(0xf38b135a, 0x430cdc40),
+ TOBN(0x0c918ae0, 0x62a7150b), TOBN(0xf31fd8de, 0x0c340e9b),
+ TOBN(0xafa0e7ae, 0x4dbbf02e), TOBN(0x5847fb2a, 0x5eba6239),
+ TOBN(0x6b1647dc, 0xdccbac8b), TOBN(0xb642aa78, 0x06f485c8),
+ TOBN(0x873f3765, 0x7038ecdf), TOBN(0x2ce5e865, 0xfa49d3fe),
+ TOBN(0xea223788, 0xc98c4400), TOBN(0x8104a8cd, 0xf1fa5279),
+ TOBN(0xbcf7cc7a, 0x06becfd7), TOBN(0x49424316, 0xc8f974ae),
+ TOBN(0xc0da65e7, 0x84d6365d), TOBN(0xbcb7443f, 0x8f759fb8),
+ TOBN(0x35c712b1, 0x7ae81930), TOBN(0x80428dff, 0x4c6e08ab),
+ TOBN(0xf19dafef, 0xa4faf843), TOBN(0xced8538d, 0xffa9855f),
+ TOBN(0x20ac409c, 0xbe3ac7ce), TOBN(0x358c1fb6, 0x882da71e),
+ TOBN(0xafa9c0e5, 0xfd349961), TOBN(0x2b2cfa51, 0x8421c2fc),
+ TOBN(0x2a80db17, 0xf3a28d38), TOBN(0xa8aba539, 0x5d138e7e),
+ TOBN(0x52012d1d, 0x6e96eb8d), TOBN(0x65d8dea0, 0xcbaf9622),
+ TOBN(0x57735447, 0xb264f56c), TOBN(0xbeebef3f, 0x1b6c8da2),
+ TOBN(0xfc346d98, 0xce785254), TOBN(0xd50e8d72, 0xbb64a161),
+ TOBN(0xc03567c7, 0x49794add), TOBN(0x15a76065, 0x752c7ef6),
+ TOBN(0x59f3a222, 0x961f23d6), TOBN(0x378e4438, 0x73ecc0b0),
+ TOBN(0xc74be434, 0x5a82fde4), TOBN(0xae509af2, 0xd8b9cf34),
+ TOBN(0x4a61ee46, 0x577f44a1), TOBN(0xe09b748c, 0xb611deeb),
+ TOBN(0xc0481b2c, 0xf5f7b884), TOBN(0x35626678, 0x61acfa6b),
+ TOBN(0x37f4c518, 0xbf8d21e6), TOBN(0x22d96531, 0xb205a76d),
+ TOBN(0x37fb85e1, 0x954073c0), TOBN(0xbceafe4f, 0x65b3a567),
+ TOBN(0xefecdef7, 0xbe42a582), TOBN(0xd3fc6080, 0x65046be6),
+ TOBN(0xc9af13c8, 0x09e8dba9), TOBN(0x1e6c9847, 0x641491ff),
+ TOBN(0x3b574925, 0xd30c31f7), TOBN(0xb7eb72ba, 0xac2a2122),
+ TOBN(0x776a0dac, 0xef0859e7), TOBN(0x06fec314, 0x21900942),
+ TOBN(0x2464bc10, 0xf8c22049), TOBN(0x9bfbcce7, 0x875ebf69),
+ TOBN(0xd7a88e2a, 0x4336326b), TOBN(0xda05261c, 0x5bc2acfa),
+ TOBN(0xc29f5bdc, 0xeba7efc8), TOBN(0x471237ca, 0x25dbbf2e),
+ TOBN(0xa72773f2, 0x2975f127), TOBN(0xdc744e8e, 0x04d0b326),
+ TOBN(0x38a7ed16, 0xa56edb73), TOBN(0x64357e37, 0x2c007e70),
+ TOBN(0xa167d15b, 0x5080b400), TOBN(0x07b41164, 0x23de4be1),
+ TOBN(0xb2d91e32, 0x74c89883), TOBN(0x3c162821, 0x2882e7ed),
+ TOBN(0xad6b36ba, 0x7503e482), TOBN(0x48434e8e, 0x0ea34331),
+ TOBN(0x79f4f24f, 0x2c7ae0b9), TOBN(0xc46fbf81, 0x1939b44a),
+ TOBN(0x76fefae8, 0x56595eb1), TOBN(0x417b66ab, 0xcd5f29c7),
+ TOBN(0x5f2332b2, 0xc5ceec20), TOBN(0xd69661ff, 0xe1a1cae2),
+ TOBN(0x5ede7e52, 0x9b0286e6), TOBN(0x9d062529, 0xe276b993),
+ TOBN(0x324794b0, 0x7e50122b), TOBN(0xdd744f8b, 0x4af07ca5),
+ TOBN(0x30a12f08, 0xd63fc97b), TOBN(0x39650f1a, 0x76626d9d),
+ TOBN(0x101b47f7, 0x1fa38477), TOBN(0x3d815f19, 0xd4dc124f),
+ TOBN(0x1569ae95, 0xb26eb58a), TOBN(0xc3cde188, 0x95fb1887),
+ TOBN(0x54e9f37b, 0xf9539a48), TOBN(0xb0100e06, 0x7408c1a5),
+ TOBN(0x821d9811, 0xea580cbb), TOBN(0x8af52d35, 0x86e50c56),
+ TOBN(0xdfbd9d47, 0xdbbf698b), TOBN(0x2961a1ea, 0x03dc1c73),
+ TOBN(0x203d38f8, 0xe76a5df8), TOBN(0x08a53a68, 0x6def707a),
+ TOBN(0x26eefb48, 0x1bee45d4), TOBN(0xb3cee346, 0x3c688036),
+ TOBN(0x463c5315, 0xc42f2469), TOBN(0x19d84d2e, 0x81378162),
+ TOBN(0x22d7c3c5, 0x1c4d349f), TOBN(0x65965844, 0x163d59c5),
+ TOBN(0xcf198c56, 0xb8abceae), TOBN(0x6fb1fb1b, 0x628559d5),
+ TOBN(0x8bbffd06, 0x07bf8fe3), TOBN(0x46259c58, 0x3467734b),
+ TOBN(0xd8953cea, 0x35f7f0d3), TOBN(0x1f0bece2, 0xd65b0ff1),
+ TOBN(0xf7d5b4b3, 0xf3c72914), TOBN(0x29e8ea95, 0x3cb53389),
+ TOBN(0x4a365626, 0x836b6d46), TOBN(0xe849f910, 0xea174fde),
+ TOBN(0x7ec62fbb, 0xf4737f21), TOBN(0xd8dba5ab, 0x6209f5ac),
+ TOBN(0x24b5d7a9, 0xa5f9adbe), TOBN(0x707d28f7, 0xa61dc768),
+ TOBN(0x7711460b, 0xcaa999ea), TOBN(0xba7b174d, 0x1c92e4cc),
+ TOBN(0x3c4bab66, 0x18d4bf2d), TOBN(0xb8f0c980, 0xeb8bd279),
+ TOBN(0x024bea9a, 0x324b4737), TOBN(0xfba9e423, 0x32a83bca),
+ TOBN(0x6e635643, 0xa232dced), TOBN(0x99619367, 0x2571c8ba),
+ TOBN(0xe8c9f357, 0x54b7032b), TOBN(0xf936b3ba, 0x2442d54a),
+ TOBN(0x2263f0f0, 0x8290c65a), TOBN(0x48989780, 0xee2c7fdb),
+ TOBN(0xadc5d55a, 0x13d4f95e), TOBN(0x737cff85, 0xad9b8500),
+ TOBN(0x271c557b, 0x8a73f43d), TOBN(0xbed617a4, 0xe18bc476),
+ TOBN(0x66245401, 0x7dfd8ab2), TOBN(0xae7b89ae, 0x3a2870aa),
+ TOBN(0x1b555f53, 0x23a7e545), TOBN(0x6791e247, 0xbe057e4c),
+ TOBN(0x860136ad, 0x324fa34d), TOBN(0xea111447, 0x4cbeae28),
+ TOBN(0x023a4270, 0xbedd3299), TOBN(0x3d5c3a7f, 0xc1c35c34),
+ TOBN(0xb0f6db67, 0x8d0412d2), TOBN(0xd92625e2, 0xfcdc6b9a),
+ TOBN(0x92ae5ccc, 0x4e28a982), TOBN(0xea251c36, 0x47a3ce7e),
+ TOBN(0x9d658932, 0x790691bf), TOBN(0xed610589, 0x06b736ae),
+ TOBN(0x712c2f04, 0xc0d63b6e), TOBN(0x5cf06fd5, 0xc63d488f),
+ TOBN(0x97363fac, 0xd9588e41), TOBN(0x1f9bf762, 0x2b93257e),
+ TOBN(0xa9d1ffc4, 0x667acace), TOBN(0x1cf4a1aa, 0x0a061ecf),
+ TOBN(0x40e48a49, 0xdc1818d0), TOBN(0x0643ff39, 0xa3621ab0),
+ TOBN(0x5768640c, 0xe39ef639), TOBN(0x1fc099ea, 0x04d86854),
+ TOBN(0x9130b9c3, 0xeccd28fd), TOBN(0xd743cbd2, 0x7eec54ab),
+ TOBN(0x052b146f, 0xe5b475b6), TOBN(0x058d9a82, 0x900a7d1f),
+ TOBN(0x65e02292, 0x91262b72), TOBN(0x96f924f9, 0xbb0edf03),
+ TOBN(0x5cfa59c8, 0xfe206842), TOBN(0xf6037004, 0x5eafa720),
+ TOBN(0x5f30699e, 0x18d7dd96), TOBN(0x381e8782, 0xcbab2495),
+ TOBN(0x91669b46, 0xdd8be949), TOBN(0xb40606f5, 0x26aae8ef),
+ TOBN(0x2812b839, 0xfc6751a4), TOBN(0x16196214, 0xfba800ef),
+ TOBN(0x4398d5ca, 0x4c1a2875), TOBN(0x720c00ee, 0x653d8349),
+ TOBN(0xc2699eb0, 0xd820007c), TOBN(0x880ee660, 0xa39b5825),
+ TOBN(0x70694694, 0x471f6984), TOBN(0xf7d16ea8, 0xe3dda99a),
+ TOBN(0x28d675b2, 0xc0519a23), TOBN(0x9ebf94fe, 0x4f6952e3),
+ TOBN(0xf28bb767, 0xa2294a8a), TOBN(0x85512b4d, 0xfe0af3f5),
+ TOBN(0x18958ba8, 0x99b16a0d), TOBN(0x95c2430c, 0xba7548a7),
+ TOBN(0xb30d1b10, 0xa16be615), TOBN(0xe3ebbb97, 0x85bfb74c),
+ TOBN(0xa3273cfe, 0x18549fdb), TOBN(0xf6e200bf, 0x4fcdb792),
+ TOBN(0x54a76e18, 0x83aba56c), TOBN(0x73ec66f6, 0x89ef6aa2),
+ TOBN(0x8d17add7, 0xd1b9a305), TOBN(0xa959c5b9, 0xb7ae1b9d),
+ TOBN(0x88643522, 0x6bcc094a), TOBN(0xcc5616c4, 0xd7d429b9),
+ TOBN(0xa6dada01, 0xe6a33f7c), TOBN(0xc6217a07, 0x9d4e70ad),
+ TOBN(0xd619a818, 0x09c15b7c), TOBN(0xea06b329, 0x0e80c854),
+ TOBN(0x174811ce, 0xa5f5e7b9), TOBN(0x66dfc310, 0x787c65f4),
+ TOBN(0x4ea7bd69, 0x3316ab54), TOBN(0xc12c4acb, 0x1dcc0f70),
+ TOBN(0xe4308d1a, 0x1e407dd9), TOBN(0xe8a3587c, 0x91afa997),
+ TOBN(0xea296c12, 0xab77b7a5), TOBN(0xb5ad49e4, 0x673c0d52),
+ TOBN(0x40f9b2b2, 0x7006085a), TOBN(0xa88ff340, 0x87bf6ec2),
+ TOBN(0x978603b1, 0x4e3066a6), TOBN(0xb3f99fc2, 0xb5e486e2),
+ TOBN(0x07b53f5e, 0xb2e63645), TOBN(0xbe57e547, 0x84c84232),
+ TOBN(0xd779c216, 0x7214d5cf), TOBN(0x617969cd, 0x029a3aca),
+ TOBN(0xd17668cd, 0x8a7017a0), TOBN(0x77b4d19a, 0xbe9b7ee8),
+ TOBN(0x58fd0e93, 0x9c161776), TOBN(0xa8c4f4ef, 0xd5968a72),
+ TOBN(0x296071cc, 0x67b3de77), TOBN(0xae3c0b8e, 0x634f7905),
+ TOBN(0x67e440c2, 0x8a7100c9), TOBN(0xbb8c3c1b, 0xeb4b9b42),
+ TOBN(0x6d71e8ea, 0xc51b3583), TOBN(0x7591f5af, 0x9525e642),
+ TOBN(0xf73a2f7b, 0x13f509f3), TOBN(0x618487aa, 0x5619ac9b),
+ TOBN(0x3a72e5f7, 0x9d61718a), TOBN(0x00413bcc, 0x7592d28c),
+ TOBN(0x7d9b11d3, 0x963c35cf), TOBN(0x77623bcf, 0xb90a46ed),
+ TOBN(0xdeef273b, 0xdcdd2a50), TOBN(0x4a741f9b, 0x0601846e),
+ TOBN(0x33b89e51, 0x0ec6e929), TOBN(0xcb02319f, 0x8b7f22cd),
+ TOBN(0xbbe1500d, 0x084bae24), TOBN(0x2f0ae8d7, 0x343d2693),
+ TOBN(0xacffb5f2, 0x7cdef811), TOBN(0xaa0c030a, 0x263fb94f),
+ TOBN(0x6eef0d61, 0xa0f442de), TOBN(0xf92e1817, 0x27b139d3),
+ TOBN(0x1ae6deb7, 0x0ad8bc28), TOBN(0xa89e38dc, 0xc0514130),
+ TOBN(0x81eeb865, 0xd2fdca23), TOBN(0x5a15ee08, 0xcc8ef895),
+ TOBN(0x768fa10a, 0x01905614), TOBN(0xeff5b8ef, 0x880ee19b),
+ TOBN(0xf0c0cabb, 0xcb1c8a0e), TOBN(0x2e1ee9cd, 0xb8c838f9),
+ TOBN(0x0587d8b8, 0x8a4a14c0), TOBN(0xf6f27896, 0x2ff698e5),
+ TOBN(0xed38ef1c, 0x89ee6256), TOBN(0xf44ee1fe, 0x6b353b45),
+ TOBN(0x9115c0c7, 0x70e903b3), TOBN(0xc78ec0a1, 0x818f31df),
+ TOBN(0x6c003324, 0xb7dccbc6), TOBN(0xd96dd1f3, 0x163bbc25),
+ TOBN(0x33aa82dd, 0x5cedd805), TOBN(0x123aae4f, 0x7f7eb2f1),
+ TOBN(0x1723fcf5, 0xa26262cd), TOBN(0x1f7f4d5d, 0x0060ebd5),
+ TOBN(0xf19c5c01, 0xb2eaa3af), TOBN(0x2ccb9b14, 0x9790accf),
+ TOBN(0x1f9c1cad, 0x52324aa6), TOBN(0x63200526, 0x7247df54),
+ TOBN(0x5732fe42, 0xbac96f82), TOBN(0x52fe771f, 0x01a1c384),
+ TOBN(0x546ca13d, 0xb1001684), TOBN(0xb56b4eee, 0xa1709f75),
+ TOBN(0x266545a9, 0xd5db8672), TOBN(0xed971c90, 0x1e8f3cfb),
+ TOBN(0x4e7d8691, 0xe3a07b29), TOBN(0x7570d9ec, 0xe4b696b9),
+ TOBN(0xdc5fa067, 0x7bc7e9ae), TOBN(0x68b44caf, 0xc82c4844),
+ TOBN(0x519d34b3, 0xbf44da80), TOBN(0x283834f9, 0x5ab32e66),
+ TOBN(0x6e608797, 0x6278a000), TOBN(0x1e62960e, 0x627312f6),
+ TOBN(0x9b87b27b, 0xe6901c55), TOBN(0x80e78538, 0x24fdbc1f),
+ TOBN(0xbbbc0951, 0x2facc27d), TOBN(0x06394239, 0xac143b5a),
+ TOBN(0x35bb4a40, 0x376c1944), TOBN(0x7cb62694, 0x63da1511),
+ TOBN(0xafd29161, 0xb7148a3b), TOBN(0xa6f9d9ed, 0x4e2ea2ee),
+ TOBN(0x15dc2ca2, 0x880dd212), TOBN(0x903c3813, 0xa61139a9),
+ TOBN(0x2aa7b46d, 0x6c0f8785), TOBN(0x36ce2871, 0x901c60ff),
+ TOBN(0xc683b028, 0xe10d9c12), TOBN(0x7573baa2, 0x032f33d3),
+ TOBN(0x87a9b1f6, 0x67a31b58), TOBN(0xfd3ed11a, 0xf4ffae12),
+ TOBN(0x83dcaa9a, 0x0cb2748e), TOBN(0x8239f018, 0x5d6fdf16),
+ TOBN(0xba67b49c, 0x72753941), TOBN(0x2beec455, 0xc321cb36),
+ TOBN(0x88015606, 0x3f8b84ce), TOBN(0x76417083, 0x8d38c86f),
+ TOBN(0x054f1ca7, 0x598953dd), TOBN(0xc939e110, 0x4e8e7429),
+ TOBN(0x9b1ac2b3, 0x5a914f2f), TOBN(0x39e35ed3, 0xe74b8f9c),
+ TOBN(0xd0debdb2, 0x781b2fb0), TOBN(0x1585638f, 0x2d997ba2),
+ TOBN(0x9c4b646e, 0x9e2fce99), TOBN(0x68a21081, 0x1e80857f),
+ TOBN(0x06d54e44, 0x3643b52a), TOBN(0xde8d6d63, 0x0d8eb843),
+ TOBN(0x70321563, 0x42146a0a), TOBN(0x8ba826f2, 0x5eaa3622),
+ TOBN(0x227a58bd, 0x86138787), TOBN(0x43b6c03c, 0x10281d37),
+ TOBN(0x6326afbb, 0xb54dde39), TOBN(0x744e5e8a, 0xdb6f2d5f),
+ TOBN(0x48b2a99a, 0xcff158e1), TOBN(0xa93c8fa0, 0xef87918f),
+ TOBN(0x2182f956, 0xde058c5c), TOBN(0x216235d2, 0x936f9e7a),
+ TOBN(0xace0c0db, 0xd2e31e67), TOBN(0xc96449bf, 0xf23ac3e7),
+ TOBN(0x7e9a2874, 0x170693bd), TOBN(0xa28e14fd, 0xa45e6335),
+ TOBN(0x5757f6b3, 0x56427344), TOBN(0x822e4556, 0xacf8edf9),
+ TOBN(0x2b7a6ee2, 0xe6a285cd), TOBN(0x5866f211, 0xa9df3af0),
+ TOBN(0x40dde2dd, 0xf845b844), TOBN(0x986c3726, 0x110e5e49),
+ TOBN(0x73680c2a, 0xf7172277), TOBN(0x57b94f0f, 0x0cccb244),
+ TOBN(0xbdff7267, 0x2d438ca7), TOBN(0xbad1ce11, 0xcf4663fd),
+ TOBN(0x9813ed9d, 0xd8f71cae), TOBN(0xf43272a6, 0x961fdaa6),
+ TOBN(0xbeff0119, 0xbd6d1637), TOBN(0xfebc4f91, 0x30361978),
+ TOBN(0x02b37a95, 0x2f41deff), TOBN(0x0e44a59a, 0xe63b89b7),
+ TOBN(0x673257dc, 0x143ff951), TOBN(0x19c02205, 0xd752baf4),
+ TOBN(0x46c23069, 0xc4b7d692), TOBN(0x2e6392c3, 0xfd1502ac),
+ TOBN(0x6057b1a2, 0x1b220846), TOBN(0xe51ff946, 0x0c1b5b63),
+ },
+ {
+ TOBN(0x6e85cb51, 0x566c5c43), TOBN(0xcff9c919, 0x3597f046),
+ TOBN(0x9354e90c, 0x4994d94a), TOBN(0xe0a39332, 0x2147927d),
+ TOBN(0x8427fac1, 0x0dc1eb2b), TOBN(0x88cfd8c2, 0x2ff319fa),
+ TOBN(0xe2d4e684, 0x01965274), TOBN(0xfa2e067d, 0x67aaa746),
+ TOBN(0xb6d92a7f, 0x3e5f9f11), TOBN(0x9afe153a, 0xd6cb3b8e),
+ TOBN(0x4d1a6dd7, 0xddf800bd), TOBN(0xf6c13cc0, 0xcaf17e19),
+ TOBN(0x15f6c58e, 0x325fc3ee), TOBN(0x71095400, 0xa31dc3b2),
+ TOBN(0x168e7c07, 0xafa3d3e7), TOBN(0x3f8417a1, 0x94c7ae2d),
+ TOBN(0xec234772, 0x813b230d), TOBN(0x634d0f5f, 0x17344427),
+ TOBN(0x11548ab1, 0xd77fc56a), TOBN(0x7fab1750, 0xce06af77),
+ TOBN(0xb62c10a7, 0x4f7c4f83), TOBN(0xa7d2edc4, 0x220a67d9),
+ TOBN(0x1c404170, 0x921209a0), TOBN(0x0b9815a0, 0xface59f0),
+ TOBN(0x2842589b, 0x319540c3), TOBN(0x18490f59, 0xa283d6f8),
+ TOBN(0xa2731f84, 0xdaae9fcb), TOBN(0x3db6d960, 0xc3683ba0),
+ TOBN(0xc85c63bb, 0x14611069), TOBN(0xb19436af, 0x0788bf05),
+ TOBN(0x905459df, 0x347460d2), TOBN(0x73f6e094, 0xe11a7db1),
+ TOBN(0xdc7f938e, 0xb6357f37), TOBN(0xc5d00f79, 0x2bd8aa62),
+ TOBN(0xc878dcb9, 0x2ca979fc), TOBN(0x37e83ed9, 0xeb023a99),
+ TOBN(0x6b23e273, 0x1560bf3d), TOBN(0x1086e459, 0x1d0fae61),
+ TOBN(0x78248316, 0x9a9414bd), TOBN(0x1b956bc0, 0xf0ea9ea1),
+ TOBN(0x7b85bb91, 0xc31b9c38), TOBN(0x0c5aa90b, 0x48ef57b5),
+ TOBN(0xdedeb169, 0xaf3bab6f), TOBN(0xe610ad73, 0x2d373685),
+ TOBN(0xf13870df, 0x02ba8e15), TOBN(0x0337edb6, 0x8ca7f771),
+ TOBN(0xe4acf747, 0xb62c036c), TOBN(0xd921d576, 0xb6b94e81),
+ TOBN(0xdbc86439, 0x2c422f7a), TOBN(0xfb635362, 0xed348898),
+ TOBN(0x83084668, 0xc45bfcd1), TOBN(0xc357c9e3, 0x2b315e11),
+ TOBN(0xb173b540, 0x5b2e5b8c), TOBN(0x7e946931, 0xe102b9a4),
+ TOBN(0x17c890eb, 0x7b0fb199), TOBN(0xec225a83, 0xd61b662b),
+ TOBN(0xf306a3c8, 0xee3c76cb), TOBN(0x3cf11623, 0xd32a1f6e),
+ TOBN(0xe6d5ab64, 0x6863e956), TOBN(0x3b8a4cbe, 0x5c005c26),
+ TOBN(0xdcd529a5, 0x9ce6bb27), TOBN(0xc4afaa52, 0x04d4b16f),
+ TOBN(0xb0624a26, 0x7923798d), TOBN(0x85e56df6, 0x6b307fab),
+ TOBN(0x0281893c, 0x2bf29698), TOBN(0x91fc19a4, 0xd7ce7603),
+ TOBN(0x75a5dca3, 0xad9a558f), TOBN(0x40ceb3fa, 0x4d50bf77),
+ TOBN(0x1baf6060, 0xbc9ba369), TOBN(0x927e1037, 0x597888c2),
+ TOBN(0xd936bf19, 0x86a34c07), TOBN(0xd4cf10c1, 0xc34ae980),
+ TOBN(0x3a3e5334, 0x859dd614), TOBN(0x9c475b5b, 0x18d0c8ee),
+ TOBN(0x63080d1f, 0x07cd51d5), TOBN(0xc9c0d0a6, 0xb88b4326),
+ TOBN(0x1ac98691, 0xc234296f), TOBN(0x2a0a83a4, 0x94887fb6),
+ TOBN(0x56511427, 0x0cea9cf2), TOBN(0x5230a6e8, 0xa24802f5),
+ TOBN(0xf7a2bf0f, 0x72e3d5c1), TOBN(0x37717446, 0x4f21439e),
+ TOBN(0xfedcbf25, 0x9ce30334), TOBN(0xe0030a78, 0x7ce202f9),
+ TOBN(0x6f2d9ebf, 0x1202e9ca), TOBN(0xe79dde6c, 0x75e6e591),
+ TOBN(0xf52072af, 0xf1dac4f8), TOBN(0x6c8d087e, 0xbb9b404d),
+ TOBN(0xad0fc73d, 0xbce913af), TOBN(0x909e587b, 0x458a07cb),
+ TOBN(0x1300da84, 0xd4f00c8a), TOBN(0x425cd048, 0xb54466ac),
+ TOBN(0xb59cb9be, 0x90e9d8bf), TOBN(0x991616db, 0x3e431b0e),
+ TOBN(0xd3aa117a, 0x531aecff), TOBN(0x91af92d3, 0x59f4dc3b),
+ TOBN(0x9b1ec292, 0xe93fda29), TOBN(0x76bb6c17, 0xe97d91bc),
+ TOBN(0x7509d95f, 0xaface1e6), TOBN(0x3653fe47, 0xbe855ae3),
+ TOBN(0x73180b28, 0x0f680e75), TOBN(0x75eefd1b, 0xeeb6c26c),
+ TOBN(0xa4cdf29f, 0xb66d4236), TOBN(0x2d70a997, 0x6b5821d8),
+ TOBN(0x7a3ee207, 0x20445c36), TOBN(0x71d1ac82, 0x59877174),
+ TOBN(0x0fc539f7, 0x949f73e9), TOBN(0xd05cf3d7, 0x982e3081),
+ TOBN(0x8758e20b, 0x7b1c7129), TOBN(0xffadcc20, 0x569e61f2),
+ TOBN(0xb05d3a2f, 0x59544c2d), TOBN(0xbe16f5c1, 0x9fff5e53),
+ TOBN(0x73cf65b8, 0xaad58135), TOBN(0x622c2119, 0x037aa5be),
+ TOBN(0x79373b3f, 0x646fd6a0), TOBN(0x0e029db5, 0x0d3978cf),
+ TOBN(0x8bdfc437, 0x94fba037), TOBN(0xaefbd687, 0x620797a6),
+ TOBN(0x3fa5382b, 0xbd30d38e), TOBN(0x7627cfbf, 0x585d7464),
+ TOBN(0xb2330fef, 0x4e4ca463), TOBN(0xbcef7287, 0x3566cc63),
+ TOBN(0xd161d2ca, 0xcf780900), TOBN(0x135dc539, 0x5b54827d),
+ TOBN(0x638f052e, 0x27bf1bc6), TOBN(0x10a224f0, 0x07dfa06c),
+ TOBN(0xe973586d, 0x6d3321da), TOBN(0x8b0c5738, 0x26152c8f),
+ TOBN(0x07ef4f2a, 0x34606074), TOBN(0x80fe7fe8, 0xa0f7047a),
+ TOBN(0x3d1a8152, 0xe1a0e306), TOBN(0x32cf43d8, 0x88da5222),
+ TOBN(0xbf89a95f, 0x5f02ffe6), TOBN(0x3d9eb9a4, 0x806ad3ea),
+ TOBN(0x012c17bb, 0x79c8e55e), TOBN(0xfdcd1a74, 0x99c81dac),
+ TOBN(0x7043178b, 0xb9556098), TOBN(0x4090a1df, 0x801c3886),
+ TOBN(0x759800ff, 0x9b67b912), TOBN(0x3e5c0304, 0x232620c8),
+ TOBN(0x4b9d3c4b, 0x70dceeca), TOBN(0xbb2d3c15, 0x181f648e),
+ TOBN(0xf981d837, 0x6e33345c), TOBN(0xb626289b, 0x0cf2297a),
+ TOBN(0x766ac659, 0x8baebdcf), TOBN(0x1a28ae09, 0x75df01e5),
+ TOBN(0xb71283da, 0x375876d8), TOBN(0x4865a96d, 0x607b9800),
+ TOBN(0x25dd1bcd, 0x237936b2), TOBN(0x332f4f4b, 0x60417494),
+ TOBN(0xd0923d68, 0x370a2147), TOBN(0x497f5dfb, 0xdc842203),
+ TOBN(0x9dc74cbd, 0x32be5e0f), TOBN(0x7475bcb7, 0x17a01375),
+ TOBN(0x438477c9, 0x50d872b1), TOBN(0xcec67879, 0xffe1d63d),
+ TOBN(0x9b006014, 0xd8578c70), TOBN(0xc9ad99a8, 0x78bb6b8b),
+ TOBN(0x6799008e, 0x11fb3806), TOBN(0xcfe81435, 0xcd44cab3),
+ TOBN(0xa2ee1582, 0x2f4fb344), TOBN(0xb8823450, 0x483fa6eb),
+ TOBN(0x622d323d, 0x652c7749), TOBN(0xd8474a98, 0xbeb0a15b),
+ TOBN(0xe43c154d, 0x5d1c00d0), TOBN(0x7fd581d9, 0x0e3e7aac),
+ TOBN(0x2b44c619, 0x2525ddf8), TOBN(0x67a033eb, 0xb8ae9739),
+ TOBN(0x113ffec1, 0x9ef2d2e4), TOBN(0x1bf6767e, 0xd5a0ea7f),
+ TOBN(0x57fff75e, 0x03714c0a), TOBN(0xa23c422e, 0x0a23e9ee),
+ TOBN(0xdd5f6b2d, 0x540f83af), TOBN(0xc2c2c27e, 0x55ea46a7),
+ TOBN(0xeb6b4246, 0x672a1208), TOBN(0xd13599f7, 0xae634f7a),
+ TOBN(0xcf914b5c, 0xd7b32c6e), TOBN(0x61a5a640, 0xeaf61814),
+ TOBN(0x8dc3df8b, 0x208a1bbb), TOBN(0xef627fd6, 0xb6d79aa5),
+ TOBN(0x44232ffc, 0xc4c86bc8), TOBN(0xe6f9231b, 0x061539fe),
+ TOBN(0x1d04f25a, 0x958b9533), TOBN(0x180cf934, 0x49e8c885),
+ TOBN(0x89689595, 0x9884aaf7), TOBN(0xb1959be3, 0x07b348a6),
+ TOBN(0x96250e57, 0x3c147c87), TOBN(0xae0efb3a, 0xdd0c61f8),
+ TOBN(0xed00745e, 0xca8c325e), TOBN(0x3c911696, 0xecff3f70),
+ TOBN(0x73acbc65, 0x319ad41d), TOBN(0x7b01a020, 0xf0b1c7ef),
+ TOBN(0xea32b293, 0x63a1483f), TOBN(0x89eabe71, 0x7a248f96),
+ TOBN(0x9c6231d3, 0x343157e5), TOBN(0x93a375e5, 0xdf3c546d),
+ TOBN(0xe76e9343, 0x6a2afe69), TOBN(0xc4f89100, 0xe166c88e),
+ TOBN(0x248efd0d, 0x4f872093), TOBN(0xae0eb3ea, 0x8fe0ea61),
+ TOBN(0xaf89790d, 0x9d79046e), TOBN(0x4d650f2d, 0x6cee0976),
+ TOBN(0xa3935d9a, 0x43071eca), TOBN(0x66fcd2c9, 0x283b0bfe),
+ TOBN(0x0e665eb5, 0x696605f1), TOBN(0xe77e5d07, 0xa54cd38d),
+ TOBN(0x90ee050a, 0x43d950cf), TOBN(0x86ddebda, 0xd32e69b5),
+ TOBN(0x6ad94a3d, 0xfddf7415), TOBN(0xf7fa1309, 0x3f6e8d5a),
+ TOBN(0xc4831d1d, 0xe9957f75), TOBN(0x7de28501, 0xd5817447),
+ TOBN(0x6f1d7078, 0x9e2aeb6b), TOBN(0xba2b9ff4, 0xf67a53c2),
+ TOBN(0x36963767, 0xdf9defc3), TOBN(0x479deed3, 0x0d38022c),
+ TOBN(0xd2edb89b, 0x3a8631e8), TOBN(0x8de855de, 0x7a213746),
+ TOBN(0xb2056cb7, 0xb00c5f11), TOBN(0xdeaefbd0, 0x2c9b85e4),
+ TOBN(0x03f39a8d, 0xd150892d), TOBN(0x37b84686, 0x218b7985),
+ TOBN(0x36296dd8, 0xb7375f1a), TOBN(0x472cd4b1, 0xb78e898e),
+ TOBN(0x15dff651, 0xe9f05de9), TOBN(0xd4045069, 0x2ce98ba9),
+ TOBN(0x8466a7ae, 0x9b38024c), TOBN(0xb910e700, 0xe5a6b5ef),
+ TOBN(0xae1c56ea, 0xb3aa8f0d), TOBN(0xbab2a507, 0x7eee74a6),
+ TOBN(0x0dca11e2, 0x4b4c4620), TOBN(0xfd896e2e, 0x4c47d1f4),
+ TOBN(0xeb45ae53, 0x308fbd93), TOBN(0x46cd5a2e, 0x02c36fda),
+ TOBN(0x6a3d4e90, 0xbaa48385), TOBN(0xdd55e62e, 0x9dbe9960),
+ TOBN(0xa1406aa0, 0x2a81ede7), TOBN(0x6860dd14, 0xf9274ea7),
+ TOBN(0xcfdcb0c2, 0x80414f86), TOBN(0xff410b10, 0x22f94327),
+ TOBN(0x5a33cc38, 0x49ad467b), TOBN(0xefb48b6c, 0x0a7335f1),
+ TOBN(0x14fb54a4, 0xb153a360), TOBN(0x604aa9d2, 0xb52469cc),
+ TOBN(0x5e9dc486, 0x754e48e9), TOBN(0x693cb455, 0x37471e8e),
+ TOBN(0xfb2fd7cd, 0x8d3b37b6), TOBN(0x63345e16, 0xcf09ff07),
+ TOBN(0x9910ba6b, 0x23a5d896), TOBN(0x1fe19e35, 0x7fe4364e),
+ TOBN(0x6e1da8c3, 0x9a33c677), TOBN(0x15b4488b, 0x29fd9fd0),
+ TOBN(0x1f439254, 0x1a1f22bf), TOBN(0x920a8a70, 0xab8163e8),
+ TOBN(0x3fd1b249, 0x07e5658e), TOBN(0xf2c4f79c, 0xb6ec839b),
+ TOBN(0x1abbc3d0, 0x4aa38d1b), TOBN(0x3b0db35c, 0xb5d9510e),
+ TOBN(0x1754ac78, 0x3e60dec0), TOBN(0x53272fd7, 0xea099b33),
+ TOBN(0x5fb0494f, 0x07a8e107), TOBN(0x4a89e137, 0x6a8191fa),
+ TOBN(0xa113b7f6, 0x3c4ad544), TOBN(0x88a2e909, 0x6cb9897b),
+ TOBN(0x17d55de3, 0xb44a3f84), TOBN(0xacb2f344, 0x17c6c690),
+ TOBN(0x32088168, 0x10232390), TOBN(0xf2e8a61f, 0x6c733bf7),
+ TOBN(0xa774aab6, 0x9c2d7652), TOBN(0xfb5307e3, 0xed95c5bc),
+ TOBN(0xa05c73c2, 0x4981f110), TOBN(0x1baae31c, 0xa39458c9),
+ TOBN(0x1def185b, 0xcbea62e7), TOBN(0xe8ac9eae, 0xeaf63059),
+ TOBN(0x098a8cfd, 0x9921851c), TOBN(0xd959c3f1, 0x3abe2f5b),
+ TOBN(0xa4f19525, 0x20e40ae5), TOBN(0x320789e3, 0x07a24aa1),
+ TOBN(0x259e6927, 0x7392b2bc), TOBN(0x58f6c667, 0x1918668b),
+ TOBN(0xce1db2bb, 0xc55d2d8b), TOBN(0x41d58bb7, 0xf4f6ca56),
+ TOBN(0x7650b680, 0x8f877614), TOBN(0x905e16ba, 0xf4c349ed),
+ TOBN(0xed415140, 0xf661acac), TOBN(0x3b8784f0, 0xcb2270af),
+ TOBN(0x3bc280ac, 0x8a402cba), TOBN(0xd53f7146, 0x0937921a),
+ TOBN(0xc03c8ee5, 0xe5681e83), TOBN(0x62126105, 0xf6ac9e4a),
+ TOBN(0x9503a53f, 0x936b1a38), TOBN(0x3d45e2d4, 0x782fecbd),
+ TOBN(0x69a5c439, 0x76e8ae98), TOBN(0xb53b2eeb, 0xbfb4b00e),
+ TOBN(0xf1674712, 0x72386c89), TOBN(0x30ca34a2, 0x4268bce4),
+ TOBN(0x7f1ed86c, 0x78341730), TOBN(0x8ef5beb8, 0xb525e248),
+ TOBN(0xbbc489fd, 0xb74fbf38), TOBN(0x38a92a0e, 0x91a0b382),
+ TOBN(0x7a77ba3f, 0x22433ccf), TOBN(0xde8362d6, 0xa29f05a9),
+ TOBN(0x7f6a30ea, 0x61189afc), TOBN(0x693b5505, 0x59ef114f),
+ TOBN(0x50266bc0, 0xcd1797a1), TOBN(0xea17b47e, 0xf4b7af2d),
+ TOBN(0xd6c4025c, 0x3df9483e), TOBN(0x8cbb9d9f, 0xa37b18c9),
+ TOBN(0x91cbfd9c, 0x4d8424cf), TOBN(0xdb7048f1, 0xab1c3506),
+ TOBN(0x9eaf641f, 0x028206a3), TOBN(0xf986f3f9, 0x25bdf6ce),
+ TOBN(0x262143b5, 0x224c08dc), TOBN(0x2bbb09b4, 0x81b50c91),
+ TOBN(0xc16ed709, 0xaca8c84f), TOBN(0xa6210d9d, 0xb2850ca8),
+ TOBN(0x6d8df67a, 0x09cb54d6), TOBN(0x91eef6e0, 0x500919a4),
+ TOBN(0x90f61381, 0x0f132857), TOBN(0x9acede47, 0xf8d5028b),
+ TOBN(0x844d1b71, 0x90b771c3), TOBN(0x563b71e4, 0xba6426be),
+ TOBN(0x2efa2e83, 0xbdb802ff), TOBN(0x3410cbab, 0xab5b4a41),
+ TOBN(0x555b2d26, 0x30da84dd), TOBN(0xd0711ae9, 0xee1cc29a),
+ TOBN(0xcf3e8c60, 0x2f547792), TOBN(0x03d7d5de, 0xdc678b35),
+ TOBN(0x071a2fa8, 0xced806b8), TOBN(0x222e6134, 0x697f1478),
+ TOBN(0xdc16fd5d, 0xabfcdbbf), TOBN(0x44912ebf, 0x121b53b8),
+ TOBN(0xac943674, 0x2496c27c), TOBN(0x8ea3176c, 0x1ffc26b0),
+ TOBN(0xb6e224ac, 0x13debf2c), TOBN(0x524cc235, 0xf372a832),
+ TOBN(0xd706e1d8, 0x9f6f1b18), TOBN(0x2552f005, 0x44cce35b),
+ TOBN(0x8c8326c2, 0xa88e31fc), TOBN(0xb5468b2c, 0xf9552047),
+ TOBN(0xce683e88, 0x3ff90f2b), TOBN(0x77947bdf, 0x2f0a5423),
+ TOBN(0xd0a1b28b, 0xed56e328), TOBN(0xaee35253, 0xc20134ac),
+ TOBN(0x7e98367d, 0x3567962f), TOBN(0x379ed61f, 0x8188bffb),
+ TOBN(0x73bba348, 0xfaf130a1), TOBN(0x6c1f75e1, 0x904ed734),
+ TOBN(0x18956642, 0x3b4a79fc), TOBN(0xf20bc83d, 0x54ef4493),
+ TOBN(0x836d425d, 0x9111eca1), TOBN(0xe5b5c318, 0x009a8dcf),
+ TOBN(0x3360b25d, 0x13221bc5), TOBN(0x707baad2, 0x6b3eeaf7),
+ TOBN(0xd7279ed8, 0x743a95a1), TOBN(0x7450a875, 0x969e809f),
+ TOBN(0x32b6bd53, 0xe5d0338f), TOBN(0x1e77f7af, 0x2b883bbc),
+ TOBN(0x90da12cc, 0x1063ecd0), TOBN(0xe2697b58, 0xc315be47),
+ TOBN(0x2771a5bd, 0xda85d534), TOBN(0x53e78c1f, 0xff980eea),
+ TOBN(0xadf1cf84, 0x900385e7), TOBN(0x7d3b14f6, 0xc9387b62),
+ TOBN(0x170e74b0, 0xcb8f2bd2), TOBN(0x2d50b486, 0x827fa993),
+ TOBN(0xcdbe8c9a, 0xf6f32bab), TOBN(0x55e906b0, 0xc3b93ab8),
+ TOBN(0x747f22fc, 0x8fe280d1), TOBN(0xcd8e0de5, 0xb2e114ab),
+ TOBN(0x5ab7dbeb, 0xe10b68b0), TOBN(0x9dc63a9c, 0xa480d4b2),
+ TOBN(0x78d4bc3b, 0x4be1495f), TOBN(0x25eb3db8, 0x9359122d),
+ TOBN(0x3f8ac05b, 0x0809cbdc), TOBN(0xbf4187bb, 0xd37c702f),
+ TOBN(0x84cea069, 0x1416a6a5), TOBN(0x8f860c79, 0x43ef881c),
+ TOBN(0x41311f8a, 0x38038a5d), TOBN(0xe78c2ec0, 0xfc612067),
+ TOBN(0x494d2e81, 0x5ad73581), TOBN(0xb4cc9e00, 0x59604097),
+ TOBN(0xff558aec, 0xf3612cba), TOBN(0x35beef7a, 0x9e36c39e),
+ TOBN(0x1845c7cf, 0xdbcf41b9), TOBN(0x5703662a, 0xaea997c0),
+ TOBN(0x8b925afe, 0xe402f6d8), TOBN(0xd0a1b1ae, 0x4dd72162),
+ TOBN(0x9f47b375, 0x03c41c4b), TOBN(0xa023829b, 0x0391d042),
+ TOBN(0x5f5045c3, 0x503b8b0a), TOBN(0x123c2688, 0x98c010e5),
+ TOBN(0x324ec0cc, 0x36ba06ee), TOBN(0xface3115, 0x3dd2cc0c),
+ TOBN(0xb364f3be, 0xf333e91f), TOBN(0xef8aff73, 0x28e832b0),
+ TOBN(0x1e9bad04, 0x2d05841b), TOBN(0x42f0e3df, 0x356a21e2),
+ TOBN(0xa3270bcb, 0x4add627e), TOBN(0xb09a8158, 0xd322e711),
+ TOBN(0x86e326a1, 0x0fee104a), TOBN(0xad7788f8, 0x3703f65d),
+ TOBN(0x7e765430, 0x47bc4833), TOBN(0x6cee582b, 0x2b9b893a),
+ TOBN(0x9cd2a167, 0xe8f55a7b), TOBN(0xefbee3c6, 0xd9e4190d),
+ TOBN(0x33ee7185, 0xd40c2e9d), TOBN(0x844cc9c5, 0xa380b548),
+ TOBN(0x323f8ecd, 0x66926e04), TOBN(0x0001e38f, 0x8110c1ba),
+ TOBN(0x8dbcac12, 0xfc6a7f07), TOBN(0xd65e1d58, 0x0cec0827),
+ TOBN(0xd2cd4141, 0xbe76ca2d), TOBN(0x7895cf5c, 0xe892f33a),
+ TOBN(0x956d230d, 0x367139d2), TOBN(0xa91abd3e, 0xd012c4c1),
+ TOBN(0x34fa4883, 0x87eb36bf), TOBN(0xc5f07102, 0x914b8fb4),
+ TOBN(0x90f0e579, 0xadb9c95f), TOBN(0xfe6ea8cb, 0x28888195),
+ TOBN(0x7b9b5065, 0xedfa9284), TOBN(0x6c510bd2, 0x2b8c8d65),
+ TOBN(0xd7b8ebef, 0xcbe8aafd), TOBN(0xedb3af98, 0x96b1da07),
+ TOBN(0x28ff779d, 0x6295d426), TOBN(0x0c4f6ac7, 0x3fa3ad7b),
+ TOBN(0xec44d054, 0x8b8e2604), TOBN(0x9b32a66d, 0x8b0050e1),
+ TOBN(0x1f943366, 0xf0476ce2), TOBN(0x7554d953, 0xa602c7b4),
+ TOBN(0xbe35aca6, 0x524f2809), TOBN(0xb6881229, 0xfd4edbea),
+ TOBN(0xe8cd0c8f, 0x508efb63), TOBN(0x9eb5b5c8, 0x6abcefc7),
+ TOBN(0xf5621f5f, 0xb441ab4f), TOBN(0x79e6c046, 0xb76a2b22),
+ TOBN(0x74a4792c, 0xe37a1f69), TOBN(0xcbd252cb, 0x03542b60),
+ TOBN(0x785f65d5, 0xb3c20bd3), TOBN(0x8dea6143, 0x4fabc60c),
+ TOBN(0x45e21446, 0xde673629), TOBN(0x57f7aa1e, 0x703c2d21),
+ TOBN(0xa0e99b7f, 0x98c868c7), TOBN(0x4e42f66d, 0x8b641676),
+ TOBN(0x602884dc, 0x91077896), TOBN(0xa0d690cf, 0xc2c9885b),
+ TOBN(0xfeb4da33, 0x3b9a5187), TOBN(0x5f789598, 0x153c87ee),
+ TOBN(0x2192dd47, 0x52b16dba), TOBN(0xdeefc0e6, 0x3524c1b1),
+ TOBN(0x465ea76e, 0xe4383693), TOBN(0x79401711, 0x361b8d98),
+ TOBN(0xa5f9ace9, 0xf21a15cb), TOBN(0x73d26163, 0xefee9aeb),
+ TOBN(0xcca844b3, 0xe677016c), TOBN(0x6c122b07, 0x57eaee06),
+ TOBN(0xb782dce7, 0x15f09690), TOBN(0x508b9b12, 0x2dfc0fc9),
+ TOBN(0x9015ab4b, 0x65d89fc6), TOBN(0x5e79dab7, 0xd6d5bb0f),
+ TOBN(0x64f021f0, 0x6c775aa2), TOBN(0xdf09d8cc, 0x37c7eca1),
+ TOBN(0x9a761367, 0xef2fa506), TOBN(0xed4ca476, 0x5b81eec6),
+ TOBN(0x262ede36, 0x10bbb8b5), TOBN(0x0737ce83, 0x0641ada3),
+ TOBN(0x4c94288a, 0xe9831ccc), TOBN(0x487fc1ce, 0x8065e635),
+ TOBN(0xb13d7ab3, 0xb8bb3659), TOBN(0xdea5df3e, 0x855e4120),
+ TOBN(0xb9a18573, 0x85eb0244), TOBN(0x1a1b8ea3, 0xa7cfe0a3),
+ TOBN(0x3b837119, 0x67b0867c), TOBN(0x8d5e0d08, 0x9d364520),
+ TOBN(0x52dccc1e, 0xd930f0e3), TOBN(0xefbbcec7, 0xbf20bbaf),
+ TOBN(0x99cffcab, 0x0263ad10), TOBN(0xd8199e6d, 0xfcd18f8a),
+ TOBN(0x64e2773f, 0xe9f10617), TOBN(0x0079e8e1, 0x08704848),
+ TOBN(0x1169989f, 0x8a342283), TOBN(0x8097799c, 0xa83012e6),
+ TOBN(0xece966cb, 0x8a6a9001), TOBN(0x93b3afef, 0x072ac7fc),
+ TOBN(0xe6893a2a, 0x2db3d5ba), TOBN(0x263dc462, 0x89bf4fdc),
+ TOBN(0x8852dfc9, 0xe0396673), TOBN(0x7ac70895, 0x3af362b6),
+ TOBN(0xbb9cce4d, 0x5c2f342b), TOBN(0xbf80907a, 0xb52d7aae),
+ TOBN(0x97f3d3cd, 0x2161bcd0), TOBN(0xb25b0834, 0x0962744d),
+ TOBN(0xc5b18ea5, 0x6c3a1dda), TOBN(0xfe4ec7eb, 0x06c92317),
+ TOBN(0xb787b890, 0xad1c4afe), TOBN(0xdccd9a92, 0x0ede801a),
+ TOBN(0x9ac6ddda, 0xdb58da1f), TOBN(0x22bbc12f, 0xb8cae6ee),
+ TOBN(0xc6f8bced, 0x815c4a43), TOBN(0x8105a92c, 0xf96480c7),
+ TOBN(0x0dc3dbf3, 0x7a859d51), TOBN(0xe3ec7ce6, 0x3041196b),
+ TOBN(0xd9f64b25, 0x0d1067c9), TOBN(0xf2321321, 0x3d1f8dd8),
+ TOBN(0x8b5c619c, 0x76497ee8), TOBN(0x5d2b0ac6, 0xc717370e),
+ TOBN(0x98204cb6, 0x4fcf68e1), TOBN(0x0bdec211, 0x62bc6792),
+ TOBN(0x6973ccef, 0xa63b1011), TOBN(0xf9e3fa97, 0xe0de1ac5),
+ TOBN(0x5efb693e, 0x3d0e0c8b), TOBN(0x037248e9, 0xd2d4fcb4),
+ },
+ {TOBN(0x80802dc9, 0x1ec34f9e), TOBN(0xd8772d35, 0x33810603),
+ TOBN(0x3f06d66c, 0x530cb4f3), TOBN(0x7be5ed0d, 0xc475c129),
+ TOBN(0xcb9e3c19, 0x31e82b10), TOBN(0xc63d2857, 0xc9ff6b4c),
+ TOBN(0xb92118c6, 0x92a1b45e), TOBN(0x0aec4414, 0x7285bbca),
+ TOBN(0xfc189ae7, 0x1e29a3ef), TOBN(0xcbe906f0, 0x4c93302e),
+ TOBN(0xd0107914, 0xceaae10e), TOBN(0xb7a23f34, 0xb68e19f8),
+ TOBN(0xe9d875c2, 0xefd2119d), TOBN(0x03198c6e, 0xfcadc9c8),
+ TOBN(0x65591bf6, 0x4da17113), TOBN(0x3cf0bbf8, 0x3d443038),
+ TOBN(0xae485bb7, 0x2b724759), TOBN(0x945353e1, 0xb2d4c63a),
+ TOBN(0x82159d07, 0xde7d6f2c), TOBN(0x389caef3, 0x4ec5b109),
+ TOBN(0x4a8ebb53, 0xdb65ef14), TOBN(0x2dc2cb7e, 0xdd99de43),
+ TOBN(0x816fa3ed, 0x83f2405f), TOBN(0x73429bb9, 0xc14208a3),
+ TOBN(0xb618d590, 0xb01e6e27), TOBN(0x047e2ccd, 0xe180b2dc),
+ TOBN(0xd1b299b5, 0x04aea4a9), TOBN(0x412c9e1e, 0x9fa403a4),
+ TOBN(0x88d28a36, 0x79407552), TOBN(0x49c50136, 0xf332b8e3),
+ TOBN(0x3a1b6fcc, 0xe668de19), TOBN(0x178851bc, 0x75122b97),
+ TOBN(0xb1e13752, 0xfb85fa4c), TOBN(0xd61257ce, 0x383c8ce9),
+ TOBN(0xd43da670, 0xd2f74dae), TOBN(0xa35aa23f, 0xbf846bbb),
+ TOBN(0x5e74235d, 0x4421fc83), TOBN(0xf6df8ee0, 0xc363473b),
+ TOBN(0x34d7f52a, 0x3c4aa158), TOBN(0x50d05aab, 0x9bc6d22e),
+ TOBN(0x8c56e735, 0xa64785f4), TOBN(0xbc56637b, 0x5f29cd07),
+ TOBN(0x53b2bb80, 0x3ee35067), TOBN(0x50235a0f, 0xdc919270),
+ TOBN(0x191ab6d8, 0xf2c4aa65), TOBN(0xc3475831, 0x8396023b),
+ TOBN(0x80400ba5, 0xf0f805ba), TOBN(0x8881065b, 0x5ec0f80f),
+ TOBN(0xc370e522, 0xcc1b5e83), TOBN(0xde2d4ad1, 0x860b8bfb),
+ TOBN(0xad364df0, 0x67b256df), TOBN(0x8f12502e, 0xe0138997),
+ TOBN(0x503fa0dc, 0x7783920a), TOBN(0xe80014ad, 0xc0bc866a),
+ TOBN(0x3f89b744, 0xd3064ba6), TOBN(0x03511dcd, 0xcba5dba5),
+ TOBN(0x197dd46d, 0x95a7b1a2), TOBN(0x9c4e7ad6, 0x3c6341fb),
+ TOBN(0x426eca29, 0x484c2ece), TOBN(0x9211e489, 0xde7f4f8a),
+ TOBN(0x14997f6e, 0xc78ef1f4), TOBN(0x2b2c0910, 0x06574586),
+ TOBN(0x17286a6e, 0x1c3eede8), TOBN(0x25f92e47, 0x0f60e018),
+ TOBN(0x805c5646, 0x31890a36), TOBN(0x703ef600, 0x57feea5b),
+ TOBN(0x389f747c, 0xaf3c3030), TOBN(0xe0e5daeb, 0x54dd3739),
+ TOBN(0xfe24a4c3, 0xc9c9f155), TOBN(0x7e4bf176, 0xb5393962),
+ TOBN(0x37183de2, 0xaf20bf29), TOBN(0x4a1bd7b5, 0xf95a8c3b),
+ TOBN(0xa83b9699, 0x46191d3d), TOBN(0x281fc8dd, 0x7b87f257),
+ TOBN(0xb18e2c13, 0x54107588), TOBN(0x6372def7, 0x9b2bafe8),
+ TOBN(0xdaf4bb48, 0x0d8972ca), TOBN(0x3f2dd4b7, 0x56167a3f),
+ TOBN(0x1eace32d, 0x84310cf4), TOBN(0xe3bcefaf, 0xe42700aa),
+ TOBN(0x5fe5691e, 0xd785e73d), TOBN(0xa5db5ab6, 0x2ea60467),
+ TOBN(0x02e23d41, 0xdfc6514a), TOBN(0x35e8048e, 0xe03c3665),
+ TOBN(0x3f8b118f, 0x1adaa0f8), TOBN(0x28ec3b45, 0x84ce1a5a),
+ TOBN(0xe8cacc6e, 0x2c6646b8), TOBN(0x1343d185, 0xdbd0e40f),
+ TOBN(0xe5d7f844, 0xcaaa358c), TOBN(0x1a1db7e4, 0x9924182a),
+ TOBN(0xd64cd42d, 0x9c875d9a), TOBN(0xb37b515f, 0x042eeec8),
+ TOBN(0x4d4dd409, 0x7b165fbe), TOBN(0xfc322ed9, 0xe206eff3),
+ TOBN(0x7dee4102, 0x59b7e17e), TOBN(0x55a481c0, 0x8236ca00),
+ TOBN(0x8c885312, 0xc23fc975), TOBN(0x15715806, 0x05d6297b),
+ TOBN(0xa078868e, 0xf78edd39), TOBN(0x956b31e0, 0x03c45e52),
+ TOBN(0x470275d5, 0xff7b33a6), TOBN(0xc8d5dc3a, 0x0c7e673f),
+ TOBN(0x419227b4, 0x7e2f2598), TOBN(0x8b37b634, 0x4c14a975),
+ TOBN(0xd0667ed6, 0x8b11888c), TOBN(0x5e0e8c3e, 0x803e25dc),
+ TOBN(0x34e5d0dc, 0xb987a24a), TOBN(0x9f40ac3b, 0xae920323),
+ TOBN(0x5463de95, 0x34e0f63a), TOBN(0xa128bf92, 0x6b6328f9),
+ TOBN(0x491ccd7c, 0xda64f1b7), TOBN(0x7ef1ec27, 0xc47bde35),
+ TOBN(0xa857240f, 0xa36a2737), TOBN(0x35dc1366, 0x63621bc1),
+ TOBN(0x7a3a6453, 0xd4fb6897), TOBN(0x80f1a439, 0xc929319d),
+ TOBN(0xfc18274b, 0xf8cb0ba0), TOBN(0xb0b53766, 0x8078c5eb),
+ TOBN(0xfb0d4924, 0x1e01d0ef), TOBN(0x50d7c67d, 0x372ab09c),
+ TOBN(0xb4e370af, 0x3aeac968), TOBN(0xe4f7fee9, 0xc4b63266),
+ TOBN(0xb4acd4c2, 0xe3ac5664), TOBN(0xf8910bd2, 0xceb38cbf),
+ TOBN(0x1c3ae50c, 0xc9c0726e), TOBN(0x15309569, 0xd97b40bf),
+ TOBN(0x70884b7f, 0xfd5a5a1b), TOBN(0x3890896a, 0xef8314cd),
+ TOBN(0x58e1515c, 0xa5618c93), TOBN(0xe665432b, 0x77d942d1),
+ TOBN(0xb32181bf, 0xb6f767a8), TOBN(0x753794e8, 0x3a604110),
+ TOBN(0x09afeb7c, 0xe8c0dbcc), TOBN(0x31e02613, 0x598673a3),
+ TOBN(0x5d98e557, 0x7d46db00), TOBN(0xfc21fb8c, 0x9d985b28),
+ TOBN(0xc9040116, 0xb0843e0b), TOBN(0x53b1b3a8, 0x69b04531),
+ TOBN(0xdd1649f0, 0x85d7d830), TOBN(0xbb3bcc87, 0xcb7427e8),
+ TOBN(0x77261100, 0xc93dce83), TOBN(0x7e79da61, 0xa1922a2a),
+ TOBN(0x587a2b02, 0xf3149ce8), TOBN(0x147e1384, 0xde92ec83),
+ TOBN(0x484c83d3, 0xaf077f30), TOBN(0xea78f844, 0x0658b53a),
+ TOBN(0x912076c2, 0x027aec53), TOBN(0xf34714e3, 0x93c8177d),
+ TOBN(0x37ef5d15, 0xc2376c84), TOBN(0x8315b659, 0x3d1aa783),
+ TOBN(0x3a75c484, 0xef852a90), TOBN(0x0ba0c58a, 0x16086bd4),
+ TOBN(0x29688d7a, 0x529a6d48), TOBN(0x9c7f250d, 0xc2f19203),
+ TOBN(0x123042fb, 0x682e2df9), TOBN(0x2b7587e7, 0xad8121bc),
+ TOBN(0x30fc0233, 0xe0182a65), TOBN(0xb82ecf87, 0xe3e1128a),
+ TOBN(0x71682861, 0x93fb098f), TOBN(0x043e21ae, 0x85e9e6a7),
+ TOBN(0xab5b49d6, 0x66c834ea), TOBN(0x3be43e18, 0x47414287),
+ TOBN(0xf40fb859, 0x219a2a47), TOBN(0x0e6559e9, 0xcc58df3c),
+ TOBN(0xfe1dfe8e, 0x0c6615b4), TOBN(0x14abc8fd, 0x56459d70),
+ TOBN(0x7be0fa8e, 0x05de0386), TOBN(0x8e63ef68, 0xe9035c7c),
+ TOBN(0x116401b4, 0x53b31e91), TOBN(0x0cba7ad4, 0x4436b4d8),
+ TOBN(0x9151f9a0, 0x107afd66), TOBN(0xafaca8d0, 0x1f0ee4c4),
+ TOBN(0x75fe5c1d, 0x9ee9761c), TOBN(0x3497a16b, 0xf0c0588f),
+ TOBN(0x3ee2bebd, 0x0304804c), TOBN(0xa8fb9a60, 0xc2c990b9),
+ TOBN(0xd14d32fe, 0x39251114), TOBN(0x36bf25bc, 0xcac73366),
+ TOBN(0xc9562c66, 0xdba7495c), TOBN(0x324d301b, 0x46ad348b),
+ TOBN(0x9f46620c, 0xd670407e), TOBN(0x0ea8d4f1, 0xe3733a01),
+ TOBN(0xd396d532, 0xb0c324e0), TOBN(0x5b211a0e, 0x03c317cd),
+ TOBN(0x090d7d20, 0x5ffe7b37), TOBN(0x3b7f3efb, 0x1747d2da),
+ TOBN(0xa2cb525f, 0xb54fc519), TOBN(0x6e220932, 0xf66a971e),
+ TOBN(0xddc160df, 0xb486d440), TOBN(0x7fcfec46, 0x3fe13465),
+ TOBN(0x83da7e4e, 0x76e4c151), TOBN(0xd6fa48a1, 0xd8d302b5),
+ TOBN(0xc6304f26, 0x5872cd88), TOBN(0x806c1d3c, 0x278b90a1),
+ TOBN(0x3553e725, 0xcaf0bc1c), TOBN(0xff59e603, 0xbb9d8d5c),
+ TOBN(0xa4550f32, 0x7a0b85dd), TOBN(0xdec5720a, 0x93ecc217),
+ TOBN(0x0b88b741, 0x69d62213), TOBN(0x7212f245, 0x5b365955),
+ TOBN(0x20764111, 0xb5cae787), TOBN(0x13cb7f58, 0x1dfd3124),
+ TOBN(0x2dca77da, 0x1175aefb), TOBN(0xeb75466b, 0xffaae775),
+ TOBN(0x74d76f3b, 0xdb6cff32), TOBN(0x7440f37a, 0x61fcda9a),
+ TOBN(0x1bb3ac92, 0xb525028b), TOBN(0x20fbf8f7, 0xa1975f29),
+ TOBN(0x982692e1, 0xdf83097f), TOBN(0x28738f6c, 0x554b0800),
+ TOBN(0xdc703717, 0xa2ce2f2f), TOBN(0x7913b93c, 0x40814194),
+ TOBN(0x04924593, 0x1fe89636), TOBN(0x7b98443f, 0xf78834a6),
+ TOBN(0x11c6ab01, 0x5114a5a1), TOBN(0x60deb383, 0xffba5f4c),
+ TOBN(0x4caa54c6, 0x01a982e6), TOBN(0x1dd35e11, 0x3491cd26),
+ TOBN(0x973c315f, 0x7cbd6b05), TOBN(0xcab00775, 0x52494724),
+ TOBN(0x04659b1f, 0x6565e15a), TOBN(0xbf30f529, 0x8c8fb026),
+ TOBN(0xfc21641b, 0xa8a0de37), TOBN(0xe9c7a366, 0xfa5e5114),
+ TOBN(0xdb849ca5, 0x52f03ad8), TOBN(0xc7e8dbe9, 0x024e35c0),
+ TOBN(0xa1a2bbac, 0xcfc3c789), TOBN(0xbf733e7d, 0x9c26f262),
+ TOBN(0x882ffbf5, 0xb8444823), TOBN(0xb7224e88, 0x6bf8483b),
+ TOBN(0x53023b8b, 0x65bef640), TOBN(0xaabfec91, 0xd4d5f8cd),
+ TOBN(0xa40e1510, 0x079ea1bd), TOBN(0x1ad9addc, 0xd05d5d26),
+ TOBN(0xdb3f2eab, 0x13e68d4f), TOBN(0x1cff1ae2, 0x640f803f),
+ TOBN(0xe0e7b749, 0xd4cee117), TOBN(0x8e9f275b, 0x4036d909),
+ TOBN(0xce34e31d, 0x8f4d4c38), TOBN(0x22b37f69, 0xd75130fc),
+ TOBN(0x83e0f1fd, 0xb4014604), TOBN(0xa8ce9919, 0x89415078),
+ TOBN(0x82375b75, 0x41792efe), TOBN(0x4f59bf5c, 0x97d4515b),
+ TOBN(0xac4f324f, 0x923a277d), TOBN(0xd9bc9b7d, 0x650f3406),
+ TOBN(0xc6fa87d1, 0x8a39bc51), TOBN(0x82588530, 0x5ccc108f),
+ TOBN(0x5ced3c9f, 0x82e4c634), TOBN(0x8efb8314, 0x3a4464f8),
+ TOBN(0xe706381b, 0x7a1dca25), TOBN(0x6cd15a3c, 0x5a2a412b),
+ TOBN(0x9347a8fd, 0xbfcd8fb5), TOBN(0x31db2eef, 0x6e54cd22),
+ TOBN(0xc4aeb11e, 0xf8d8932f), TOBN(0x11e7c1ed, 0x344411af),
+ TOBN(0x2653050c, 0xdc9a151e), TOBN(0x9edbfc08, 0x3bb0a859),
+ TOBN(0x926c81c7, 0xfd5691e7), TOBN(0x9c1b2342, 0x6f39019a),
+ TOBN(0x64a81c8b, 0x7f8474b9), TOBN(0x90657c07, 0x01761819),
+ TOBN(0x390b3331, 0x55e0375a), TOBN(0xc676c626, 0xb6ebc47d),
+ TOBN(0x51623247, 0xb7d6dee8), TOBN(0x0948d927, 0x79659313),
+ TOBN(0x99700161, 0xe9ab35ed), TOBN(0x06cc32b4, 0x8ddde408),
+ TOBN(0x6f2fd664, 0x061ef338), TOBN(0x1606fa02, 0xc202e9ed),
+ TOBN(0x55388bc1, 0x929ba99b), TOBN(0xc4428c5e, 0x1e81df69),
+ TOBN(0xce2028ae, 0xf91b0b2a), TOBN(0xce870a23, 0xf03dfd3f),
+ TOBN(0x66ec2c87, 0x0affe8ed), TOBN(0xb205fb46, 0x284d0c00),
+ TOBN(0xbf5dffe7, 0x44cefa48), TOBN(0xb6fc37a8, 0xa19876d7),
+ TOBN(0xbecfa84c, 0x08b72863), TOBN(0xd7205ff5, 0x2576374f),
+ TOBN(0x80330d32, 0x8887de41), TOBN(0x5de0df0c, 0x869ea534),
+ TOBN(0x13f42753, 0x3c56ea17), TOBN(0xeb1f6069, 0x452b1a78),
+ TOBN(0x50474396, 0xe30ea15c), TOBN(0x575816a1, 0xc1494125),
+ TOBN(0xbe1ce55b, 0xfe6bb38f), TOBN(0xb901a948, 0x96ae30f7),
+ TOBN(0xe5af0f08, 0xd8fc3548), TOBN(0x5010b5d0, 0xd73bfd08),
+ TOBN(0x993d2880, 0x53fe655a), TOBN(0x99f2630b, 0x1c1309fd),
+ TOBN(0xd8677baf, 0xb4e3b76f), TOBN(0x14e51ddc, 0xb840784b),
+ TOBN(0x326c750c, 0xbf0092ce), TOBN(0xc83d306b, 0xf528320f),
+ TOBN(0xc4456715, 0x77d4715c), TOBN(0xd30019f9, 0x6b703235),
+ TOBN(0x207ccb2e, 0xd669e986), TOBN(0x57c824af, 0xf6dbfc28),
+ TOBN(0xf0eb532f, 0xd8f92a23), TOBN(0x4a557fd4, 0x9bb98fd2),
+ TOBN(0xa57acea7, 0xc1e6199a), TOBN(0x0c663820, 0x8b94b1ed),
+ TOBN(0x9b42be8f, 0xf83a9266), TOBN(0xc7741c97, 0x0101bd45),
+ TOBN(0x95770c11, 0x07bd9ceb), TOBN(0x1f50250a, 0x8b2e0744),
+ TOBN(0xf762eec8, 0x1477b654), TOBN(0xc65b900e, 0x15efe59a),
+ TOBN(0x88c96148, 0x9546a897), TOBN(0x7e8025b3, 0xc30b4d7c),
+ TOBN(0xae4065ef, 0x12045cf9), TOBN(0x6fcb2caf, 0x9ccce8bd),
+ TOBN(0x1fa0ba4e, 0xf2cf6525), TOBN(0xf683125d, 0xcb72c312),
+ TOBN(0xa01da4ea, 0xe312410e), TOBN(0x67e28677, 0x6cd8e830),
+ TOBN(0xabd95752, 0x98fb3f07), TOBN(0x05f11e11, 0xeef649a5),
+ TOBN(0xba47faef, 0x9d3472c2), TOBN(0x3adff697, 0xc77d1345),
+ TOBN(0x4761fa04, 0xdd15afee), TOBN(0x64f1f61a, 0xb9e69462),
+ TOBN(0xfa691fab, 0x9bfb9093), TOBN(0x3df8ae8f, 0xa1133dfe),
+ TOBN(0xcd5f8967, 0x58cc710d), TOBN(0xfbb88d50, 0x16c7fe79),
+ TOBN(0x8e011b4c, 0xe88c50d1), TOBN(0x7532e807, 0xa8771c4f),
+ TOBN(0x64c78a48, 0xe2278ee4), TOBN(0x0b283e83, 0x3845072a),
+ TOBN(0x98a6f291, 0x49e69274), TOBN(0xb96e9668, 0x1868b21c),
+ TOBN(0x38f0adc2, 0xb1a8908e), TOBN(0x90afcff7, 0x1feb829d),
+ TOBN(0x9915a383, 0x210b0856), TOBN(0xa5a80602, 0xdef04889),
+ TOBN(0x800e9af9, 0x7c64d509), TOBN(0x81382d0b, 0xb8996f6f),
+ TOBN(0x490eba53, 0x81927e27), TOBN(0x46c63b32, 0x4af50182),
+ TOBN(0x784c5fd9, 0xd3ad62ce), TOBN(0xe4fa1870, 0xf8ae8736),
+ TOBN(0x4ec9d0bc, 0xd7466b25), TOBN(0x84ddbe1a, 0xdb235c65),
+ TOBN(0x5e2645ee, 0x163c1688), TOBN(0x570bd00e, 0x00eba747),
+ TOBN(0xfa51b629, 0x128bfa0f), TOBN(0x92fce1bd, 0x6c1d3b68),
+ TOBN(0x3e7361dc, 0xb66778b1), TOBN(0x9c7d249d, 0x5561d2bb),
+ TOBN(0xa40b28bf, 0x0bbc6229), TOBN(0x1c83c05e, 0xdfd91497),
+ TOBN(0x5f9f5154, 0xf083df05), TOBN(0xbac38b3c, 0xeee66c9d),
+ TOBN(0xf71db7e3, 0xec0dfcfd), TOBN(0xf2ecda8e, 0x8b0a8416),
+ TOBN(0x52fddd86, 0x7812aa66), TOBN(0x2896ef10, 0x4e6f4272),
+ TOBN(0xff27186a, 0x0fe9a745), TOBN(0x08249fcd, 0x49ca70db),
+ TOBN(0x7425a2e6, 0x441cac49), TOBN(0xf4a0885a, 0xece5ff57),
+ TOBN(0x6e2cb731, 0x7d7ead58), TOBN(0xf96cf7d6, 0x1898d104),
+ TOBN(0xafe67c9d, 0x4f2c9a89), TOBN(0x89895a50, 0x1c7bf5bc),
+ TOBN(0xdc7cb8e5, 0x573cecfa), TOBN(0x66497eae, 0xd15f03e6),
+ TOBN(0x6bc0de69, 0x3f084420), TOBN(0x323b9b36, 0xacd532b0),
+ TOBN(0xcfed390a, 0x0115a3c1), TOBN(0x9414c40b, 0x2d65ca0e),
+ TOBN(0x641406bd, 0x2f530c78), TOBN(0x29369a44, 0x833438f2),
+ TOBN(0x996884f5, 0x903fa271), TOBN(0xe6da0fd2, 0xb9da921e),
+ TOBN(0xa6f2f269, 0x5db01e54), TOBN(0x1ee3e9bd, 0x6876214e),
+ TOBN(0xa26e181c, 0xe27a9497), TOBN(0x36d254e4, 0x8e215e04),
+ TOBN(0x42f32a6c, 0x252cabca), TOBN(0x99481487, 0x80b57614),
+ TOBN(0x4c4dfe69, 0x40d9cae1), TOBN(0x05869580, 0x11a10f09),
+ TOBN(0xca287b57, 0x3491b64b), TOBN(0x77862d5d, 0x3fd4a53b),
+ TOBN(0xbf94856e, 0x50349126), TOBN(0x2be30bd1, 0x71c5268f),
+ TOBN(0x10393f19, 0xcbb650a6), TOBN(0x639531fe, 0x778cf9fd),
+ TOBN(0x02556a11, 0xb2935359), TOBN(0xda38aa96, 0xaf8c126e),
+ TOBN(0x47dbe6c2, 0x0960167f), TOBN(0x37bbabb6, 0x501901cd),
+ TOBN(0xb6e979e0, 0x2c947778), TOBN(0xd69a5175, 0x7a1a1dc6),
+ TOBN(0xc3ed5095, 0x9d9faf0c), TOBN(0x4dd9c096, 0x1d5fa5f0),
+ TOBN(0xa0c4304d, 0x64f16ea8), TOBN(0x8b1cac16, 0x7e718623),
+ TOBN(0x0b576546, 0x7c67f03e), TOBN(0x559cf5ad, 0xcbd88c01),
+ TOBN(0x074877bb, 0x0e2af19a), TOBN(0x1f717ec1, 0xa1228c92),
+ TOBN(0x70bcb800, 0x326e8920), TOBN(0xec6e2c5c, 0x4f312804),
+ TOBN(0x426aea7d, 0x3fca4752), TOBN(0xf12c0949, 0x2211f62a),
+ TOBN(0x24beecd8, 0x7be7b6b5), TOBN(0xb77eaf4c, 0x36d7a27d),
+ TOBN(0x154c2781, 0xfda78fd3), TOBN(0x848a83b0, 0x264eeabe),
+ TOBN(0x81287ef0, 0x4ffe2bc4), TOBN(0x7b6d88c6, 0xb6b6fc2a),
+ TOBN(0x805fb947, 0xce417d99), TOBN(0x4b93dcc3, 0x8b916cc4),
+ TOBN(0x72e65bb3, 0x21273323), TOBN(0xbcc1badd, 0x6ea9886e),
+ TOBN(0x0e223011, 0x4bc5ee85), TOBN(0xa561be74, 0xc18ee1e4),
+ TOBN(0x762fd2d4, 0xa6bcf1f1), TOBN(0x50e6a5a4, 0x95231489),
+ TOBN(0xca96001f, 0xa00b500b), TOBN(0x5c098cfc, 0x5d7dcdf5),
+ TOBN(0xa64e2d2e, 0x8c446a85), TOBN(0xbae9bcf1, 0x971f3c62),
+ TOBN(0x4ec22683, 0x8435a2c5), TOBN(0x8ceaed6c, 0x4bad4643),
+ TOBN(0xe9f8fb47, 0xccccf4e3), TOBN(0xbd4f3fa4, 0x1ce3b21e),
+ TOBN(0xd79fb110, 0xa3db3292), TOBN(0xe28a37da, 0xb536c66a),
+ TOBN(0x279ce87b, 0x8e49e6a9), TOBN(0x70ccfe8d, 0xfdcec8e3),
+ TOBN(0x2193e4e0, 0x3ba464b2), TOBN(0x0f39d60e, 0xaca9a398),
+ TOBN(0x7d7932af, 0xf82c12ab), TOBN(0xd8ff50ed, 0x91e7e0f7),
+ TOBN(0xea961058, 0xfa28a7e0), TOBN(0xc726cf25, 0x0bf5ec74),
+ TOBN(0xe74d55c8, 0xdb229666), TOBN(0x0bd9abbf, 0xa57f5799),
+ TOBN(0x7479ef07, 0x4dfc47b3), TOBN(0xd9c65fc3, 0x0c52f91d),
+ TOBN(0x8e0283fe, 0x36a8bde2), TOBN(0xa32a8b5e, 0x7d4b7280),
+ TOBN(0x6a677c61, 0x12e83233), TOBN(0x0fbb3512, 0xdcc9bf28),
+ TOBN(0x562e8ea5, 0x0d780f61), TOBN(0x0db8b22b, 0x1dc4e89c),
+ TOBN(0x0a6fd1fb, 0x89be0144), TOBN(0x8c77d246, 0xca57113b),
+ TOBN(0x4639075d, 0xff09c91c), TOBN(0x5b47b17f, 0x5060824c),
+ TOBN(0x58aea2b0, 0x16287b52), TOBN(0xa1343520, 0xd0cd8eb0),
+ TOBN(0x6148b4d0, 0xc5d58573), TOBN(0xdd2b6170, 0x291c68ae),
+ TOBN(0xa61b3929, 0x1da3b3b7), TOBN(0x5f946d79, 0x08c4ac10),
+ TOBN(0x4105d4a5, 0x7217d583), TOBN(0x5061da3d, 0x25e6de5e),
+ TOBN(0x3113940d, 0xec1b4991), TOBN(0xf12195e1, 0x36f485ae),
+ TOBN(0xa7507fb2, 0x731a2ee0), TOBN(0x95057a8e, 0x6e9e196e),
+ TOBN(0xa3c2c911, 0x2e130136), TOBN(0x97dfbb36, 0x33c60d15),
+ TOBN(0xcaf3c581, 0xb300ee2b), TOBN(0x77f25d90, 0xf4bac8b8),
+ TOBN(0xdb1c4f98, 0x6d840cd6), TOBN(0x471d62c0, 0xe634288c),
+ TOBN(0x8ec2f85e, 0xcec8a161), TOBN(0x41f37cbc, 0xfa6f4ae2),
+ TOBN(0x6793a20f, 0x4b709985), TOBN(0x7a7bd33b, 0xefa8985b),
+ TOBN(0x2c6a3fbd, 0x938e6446), TOBN(0x19042619, 0x2a8d47c1),
+ TOBN(0x16848667, 0xcc36975f), TOBN(0x02acf168, 0x9d5f1dfb),
+ TOBN(0x62d41ad4, 0x613baa94), TOBN(0xb56fbb92, 0x9f684670),
+ TOBN(0xce610d0d, 0xe9e40569), TOBN(0x7b99c65f, 0x35489fef),
+ TOBN(0x0c88ad1b, 0x3df18b97), TOBN(0x81b7d9be, 0x5d0e9edb),
+ TOBN(0xd85218c0, 0xc716cc0a), TOBN(0xf4b5ff90, 0x85691c49),
+ TOBN(0xa4fd666b, 0xce356ac6), TOBN(0x17c72895, 0x4b327a7a),
+ TOBN(0xf93d5085, 0xda6be7de), TOBN(0xff71530e, 0x3301d34e),
+ TOBN(0x4cd96442, 0xd8f448e8), TOBN(0x9283d331, 0x2ed18ffa),
+ TOBN(0x4d33dd99, 0x2a849870), TOBN(0xa716964b, 0x41576335),
+ TOBN(0xff5e3a9b, 0x179be0e5), TOBN(0x5b9d6b1b, 0x83b13632),
+ TOBN(0x3b8bd7d4, 0xa52f313b), TOBN(0xc9dd95a0, 0x637a4660),
+ TOBN(0x30035962, 0x0b3e218f), TOBN(0xce1481a3, 0xc7b28a3c),
+ TOBN(0xab41b43a, 0x43228d83), TOBN(0x24ae1c30, 0x4ad63f99),
+ TOBN(0x8e525f1a, 0x46a51229), TOBN(0x14af860f, 0xcd26d2b4),
+ TOBN(0xd6baef61, 0x3f714aa1), TOBN(0xf51865ad, 0xeb78795e),
+ TOBN(0xd3e21fce, 0xe6a9d694), TOBN(0x82ceb1dd, 0x8a37b527)}};
diff --git a/src/crypto/ec/p256-x86_64.c b/src/crypto/ec/p256-x86_64.c
new file mode 100644
index 0000000..2f7023d
--- /dev/null
+++ b/src/crypto/ec/p256-x86_64.c
@@ -0,0 +1,596 @@
+/* Copyright (c) 2014, Intel Corporation.
+ *
+ * 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. */
+
+/* Developers and authors:
+ * Shay Gueron (1, 2), and Vlad Krasnov (1)
+ * (1) Intel Corporation, Israel Development Center
+ * (2) University of Haifa
+ * Reference:
+ * S.Gueron and V.Krasnov, "Fast Prime Field Elliptic Curve Cryptography with
+ * 256 Bit Primes" */
+
+#include <openssl/ec.h>
+
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <openssl/bn.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+
+#include "../bn/internal.h"
+#include "../ec/internal.h"
+#include "../internal.h"
+
+
+#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
+ !defined(OPENSSL_SMALL)
+
+
+#if defined(__GNUC__)
+#define ALIGN(x) __attribute((aligned(x)))
+#elif defined(_MSC_VER)
+#define ALIGN(x) __declspec(align(x))
+#else
+#define ALIGN(x)
+#endif
+
+#define ALIGNPTR(p, N) ((uint8_t *)p + N - (size_t)p % N)
+#define P256_LIMBS (256 / BN_BITS2)
+
+typedef struct {
+ BN_ULONG X[P256_LIMBS];
+ BN_ULONG Y[P256_LIMBS];
+ BN_ULONG Z[P256_LIMBS];
+} P256_POINT;
+
+typedef struct {
+ BN_ULONG X[P256_LIMBS];
+ BN_ULONG Y[P256_LIMBS];
+} P256_POINT_AFFINE;
+
+typedef P256_POINT_AFFINE PRECOMP256_ROW[64];
+
+/* Functions implemented in assembly */
+
+/* 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 */
+void ecp_nistz256_mul_mont(BN_ULONG res[P256_LIMBS],
+ const BN_ULONG a[P256_LIMBS],
+ const BN_ULONG b[P256_LIMBS]);
+/* Montgomery sqr: res = a*a*2^-256 mod P */
+void ecp_nistz256_sqr_mont(BN_ULONG res[P256_LIMBS],
+ const BN_ULONG a[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]);
+/* 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,
+ const P256_POINT_AFFINE *in_t, int index);
+
+/* One converted into the Montgomery domain */
+static const BN_ULONG ONE[P256_LIMBS] = {
+ TOBN(0x00000000, 0x00000001), TOBN(0xffffffff, 0x00000000),
+ TOBN(0xffffffff, 0xffffffff), TOBN(0x00000000, 0xfffffffe),
+};
+
+/* Precomputed tables for the default generator */
+#include "p256-x86_64-table.h"
+
+/* Recode window to a signed digit, see ecp_nistputil.c for details */
+static unsigned booth_recode_w5(unsigned in) {
+ unsigned s, d;
+
+ s = ~((in >> 5) - 1);
+ d = (1 << 6) - in - 1;
+ d = (d & s) | (in & ~s);
+ d = (d >> 1) + (d & 1);
+
+ return (d << 1) + (s & 1);
+}
+
+static unsigned booth_recode_w7(unsigned in) {
+ unsigned s, d;
+
+ s = ~((in >> 7) - 1);
+ d = (1 << 8) - in - 1;
+ d = (d & s) | (in & ~s);
+ d = (d >> 1) + (d & 1);
+
+ return (d << 1) + (s & 1);
+}
+
+static void copy_conditional(BN_ULONG dst[P256_LIMBS],
+ const BN_ULONG src[P256_LIMBS], BN_ULONG move) {
+ BN_ULONG mask1 = ((BN_ULONG)0) - move;
+ BN_ULONG mask2 = ~mask1;
+
+ dst[0] = (src[0] & mask1) ^ (dst[0] & mask2);
+ dst[1] = (src[1] & mask1) ^ (dst[1] & mask2);
+ dst[2] = (src[2] & mask1) ^ (dst[2] & mask2);
+ dst[3] = (src[3] & mask1) ^ (dst[3] & mask2);
+ if (P256_LIMBS == 8) {
+ dst[4] = (src[4] & mask1) ^ (dst[4] & mask2);
+ dst[5] = (src[5] & mask1) ^ (dst[5] & mask2);
+ dst[6] = (src[6] & mask1) ^ (dst[6] & mask2);
+ dst[7] = (src[7] & mask1) ^ (dst[7] & mask2);
+ }
+}
+
+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);
+void ecp_nistz256_point_add_affine(P256_POINT *r, const P256_POINT *a,
+ const P256_POINT_AFFINE *b);
+
+/* r = in^-1 mod p */
+static void ecp_nistz256_mod_inverse(BN_ULONG r[P256_LIMBS],
+ const BN_ULONG in[P256_LIMBS]) {
+ /* The poly is ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff
+ ffffffff
+ We use FLT and used poly-2 as exponent */
+ BN_ULONG p2[P256_LIMBS];
+ BN_ULONG p4[P256_LIMBS];
+ BN_ULONG p8[P256_LIMBS];
+ BN_ULONG p16[P256_LIMBS];
+ BN_ULONG p32[P256_LIMBS];
+ BN_ULONG res[P256_LIMBS];
+ int i;
+
+ ecp_nistz256_sqr_mont(res, in);
+ ecp_nistz256_mul_mont(p2, res, in); /* 3*p */
+
+ ecp_nistz256_sqr_mont(res, p2);
+ ecp_nistz256_sqr_mont(res, res);
+ ecp_nistz256_mul_mont(p4, res, p2); /* f*p */
+
+ ecp_nistz256_sqr_mont(res, p4);
+ ecp_nistz256_sqr_mont(res, res);
+ ecp_nistz256_sqr_mont(res, res);
+ ecp_nistz256_sqr_mont(res, res);
+ ecp_nistz256_mul_mont(p8, res, p4); /* ff*p */
+
+ ecp_nistz256_sqr_mont(res, p8);
+ for (i = 0; i < 7; i++) {
+ ecp_nistz256_sqr_mont(res, res);
+ }
+ ecp_nistz256_mul_mont(p16, res, p8); /* ffff*p */
+
+ ecp_nistz256_sqr_mont(res, p16);
+ for (i = 0; i < 15; i++) {
+ ecp_nistz256_sqr_mont(res, res);
+ }
+ ecp_nistz256_mul_mont(p32, res, p16); /* ffffffff*p */
+
+ ecp_nistz256_sqr_mont(res, p32);
+ for (i = 0; i < 31; i++) {
+ ecp_nistz256_sqr_mont(res, res);
+ }
+ ecp_nistz256_mul_mont(res, res, in);
+
+ for (i = 0; i < 32 * 4; i++) {
+ ecp_nistz256_sqr_mont(res, res);
+ }
+ ecp_nistz256_mul_mont(res, res, p32);
+
+ for (i = 0; i < 32; i++) {
+ ecp_nistz256_sqr_mont(res, res);
+ }
+ ecp_nistz256_mul_mont(res, res, p32);
+
+ for (i = 0; i < 16; i++) {
+ ecp_nistz256_sqr_mont(res, res);
+ }
+ ecp_nistz256_mul_mont(res, res, p16);
+
+ for (i = 0; i < 8; i++) {
+ ecp_nistz256_sqr_mont(res, res);
+ }
+ ecp_nistz256_mul_mont(res, res, p8);
+
+ ecp_nistz256_sqr_mont(res, res);
+ ecp_nistz256_sqr_mont(res, res);
+ ecp_nistz256_sqr_mont(res, res);
+ ecp_nistz256_sqr_mont(res, res);
+ ecp_nistz256_mul_mont(res, res, p4);
+
+ ecp_nistz256_sqr_mont(res, res);
+ ecp_nistz256_sqr_mont(res, res);
+ ecp_nistz256_mul_mont(res, res, p2);
+
+ ecp_nistz256_sqr_mont(res, res);
+ ecp_nistz256_sqr_mont(res, res);
+ ecp_nistz256_mul_mont(res, res, in);
+
+ memcpy(r, res, sizeof(res));
+}
+
+/* ecp_nistz256_bignum_to_field_elem copies the contents of |in| to |out| and
+ * returns one if it fits. Otherwise it returns zero. */
+static int ecp_nistz256_bignum_to_field_elem(BN_ULONG out[P256_LIMBS],
+ const BIGNUM *in) {
+ if (in->top > P256_LIMBS) {
+ return 0;
+ }
+
+ memset(out, 0, sizeof(BN_ULONG) * P256_LIMBS);
+ memcpy(out, in->d, sizeof(BN_ULONG) * in->top);
+ return 1;
+}
+
+/* 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;
+
+ /* 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];
+
+
+ int ret = 0;
+ BN_CTX *new_ctx = NULL;
+ int ctx_started = 0;
+
+ 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;
+ }
+ ctx = new_ctx;
+ }
+ 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;
+ }
+
+ 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;
+ }
+ }
+
+ for (; j < 33; j++) {
+ p_str[j] = 0;
+ }
+
+ /* 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;
+
+ 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];
+ ALIGN(32) P256_POINT h;
+ unsigned index = 255;
+ unsigned wvalue = p_str[(index - 1) / 8];
+ wvalue = (wvalue >> ((index - 1) % 8)) & kMask;
+
+ ecp_nistz256_select_w5(r, table, booth_recode_w5(wvalue) >> 1);
+
+ while (index >= 5) {
+ if (index != 255) {
+ unsigned off = (index - 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, wvalue >> 1);
+
+ ecp_nistz256_neg(tmp, h.Y);
+ copy_conditional(h.Y, tmp, (wvalue & 1));
+
+ ecp_nistz256_point_add(r, r, &h);
+ }
+
+ index -= kWindowSize;
+
+ ecp_nistz256_point_double(r, r);
+ ecp_nistz256_point_double(r, r);
+ ecp_nistz256_point_double(r, r);
+ ecp_nistz256_point_double(r, r);
+ ecp_nistz256_point_double(r, r);
+ }
+
+ /* Final window */
+ wvalue = p_str[0];
+ wvalue = (wvalue << 1) & kMask;
+
+ wvalue = booth_recode_w5(wvalue);
+
+ ecp_nistz256_select_w5(&h, table, wvalue >> 1);
+
+ ecp_nistz256_neg(tmp, h.Y);
+ copy_conditional(h.Y, tmp, wvalue & 1);
+
+ ecp_nistz256_point_add(r, r, &h);
+
+ ret = 1;
+
+err:
+ if (ctx_started) {
+ BN_CTX_end(ctx);
+ }
+ BN_CTX_free(new_ctx);
+ return ret;
+}
+
+static int ecp_nistz256_points_mul(
+ 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;
+
+ ALIGN(32) union {
+ P256_POINT p;
+ P256_POINT_AFFINE a;
+ } t, p;
+
+ int ret = 0;
+ BN_CTX *new_ctx = NULL;
+ int ctx_started = 0;
+
+ /* Need 256 bits for space for all coordinates. */
+ 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;
+
+ 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;
+ }
+ ctx = new_ctx;
+ }
+ BN_CTX_start(ctx);
+ ctx_started = 1;
+ BIGNUM *tmp_scalar = BN_CTX_get(ctx);
+ if (tmp_scalar == NULL) {
+ goto err;
+ }
+
+ if (!BN_nnmod(tmp_scalar, g_scalar, &group->order, ctx)) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
+ goto err;
+ }
+ g_scalar = tmp_scalar;
+ }
+
+ 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];
+
+ 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;
+ }
+ }
+
+ for (; i < (int) sizeof(p_str); i++) {
+ p_str[i] = 0;
+ }
+
+ /* First window */
+ unsigned wvalue = (p_str[0] << 1) & kMask;
+ unsigned index = kWindowSize;
+
+ 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_neg(p.p.Z, p.p.Y);
+ copy_conditional(p.p.Y, p.p.Z, wvalue & 1);
+
+ memcpy(p.p.Z, ONE, sizeof(ONE));
+
+ 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);
+
+ ecp_nistz256_select_w7(&t.a, precomputed_table[i], wvalue >> 1);
+
+ ecp_nistz256_neg(t.p.Z, t.a.Y);
+ copy_conditional(t.a.Y, t.p.Z, wvalue & 1);
+
+ ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a);
+ }
+ }
+
+ const int p_is_infinity = g_scalar == NULL;
+ if (p_scalar != NULL) {
+ P256_POINT *out = &t.p;
+ if (p_is_infinity) {
+ out = &p.p;
+ }
+
+ 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);
+ }
+ }
+
+ 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;
+}
+
+static int ecp_nistz256_get_affine(const EC_GROUP *group, const EC_POINT *point,
+ BIGNUM *x, BIGNUM *y, BN_CTX *ctx) {
+ BN_ULONG z_inv2[P256_LIMBS];
+ BN_ULONG z_inv3[P256_LIMBS];
+ BN_ULONG x_aff[P256_LIMBS];
+ BN_ULONG y_aff[P256_LIMBS];
+ BN_ULONG point_x[P256_LIMBS], point_y[P256_LIMBS], point_z[P256_LIMBS];
+
+ if (EC_POINT_is_at_infinity(group, point)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
+ return 0;
+ }
+
+ if (!ecp_nistz256_bignum_to_field_elem(point_x, &point->X) ||
+ !ecp_nistz256_bignum_to_field_elem(point_y, &point->Y) ||
+ !ecp_nistz256_bignum_to_field_elem(point_z, &point->Z)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE);
+ return 0;
+ }
+
+ ecp_nistz256_mod_inverse(z_inv3, point_z);
+ ecp_nistz256_sqr_mont(z_inv2, z_inv3);
+ ecp_nistz256_mul_mont(x_aff, z_inv2, point_x);
+
+ if (x != NULL) {
+ 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);
+ }
+
+ if (y != NULL) {
+ ecp_nistz256_mul_mont(z_inv3, z_inv3, z_inv2);
+ ecp_nistz256_mul_mont(y_aff, z_inv3, point_y);
+ 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);
+ }
+
+ return 1;
+}
+
+const EC_METHOD *EC_GFp_nistz256_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,
+ ecp_nistz256_get_affine,
+ ecp_nistz256_points_mul,
+ 0 /* 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;
+}
+
+#endif /* !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
+ !defined(OPENSSL_SMALL) */
diff --git a/src/crypto/ec/simple.c b/src/crypto/ec/simple.c
index 69fd2e4..cef0e94 100644
--- a/src/crypto/ec/simple.c
+++ b/src/crypto/ec/simple.c
@@ -76,50 +76,6 @@
#include "internal.h"
-const EC_METHOD *EC_GFp_simple_method(void) {
- static const EC_METHOD ret = {EC_FLAGS_DEFAULT_OCT,
- ec_GFp_simple_group_init,
- ec_GFp_simple_group_finish,
- ec_GFp_simple_group_clear_finish,
- ec_GFp_simple_group_copy,
- ec_GFp_simple_group_set_curve,
- ec_GFp_simple_group_get_curve,
- ec_GFp_simple_group_get_degree,
- ec_GFp_simple_group_check_discriminant,
- ec_GFp_simple_point_init,
- ec_GFp_simple_point_finish,
- ec_GFp_simple_point_clear_finish,
- ec_GFp_simple_point_copy,
- ec_GFp_simple_point_set_to_infinity,
- ec_GFp_simple_set_Jprojective_coordinates_GFp,
- ec_GFp_simple_get_Jprojective_coordinates_GFp,
- ec_GFp_simple_point_set_affine_coordinates,
- ec_GFp_simple_point_get_affine_coordinates,
- 0,
- 0,
- 0,
- ec_GFp_simple_add,
- ec_GFp_simple_dbl,
- ec_GFp_simple_invert,
- ec_GFp_simple_is_at_infinity,
- ec_GFp_simple_is_on_curve,
- ec_GFp_simple_cmp,
- ec_GFp_simple_make_affine,
- ec_GFp_simple_points_make_affine,
- 0 /* mul */,
- 0 /* precompute_mult */,
- 0 /* have_precompute_mult */,
- ec_GFp_simple_field_mul,
- ec_GFp_simple_field_sqr,
- 0 /* field_div */,
- 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
@@ -172,7 +128,7 @@ int ec_GFp_simple_group_set_curve(EC_GROUP *group, const BIGNUM *p,
/* p must be a prime > 3 */
if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_group_set_curve, EC_R_INVALID_FIELD);
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FIELD);
return 0;
}
@@ -270,7 +226,7 @@ err:
return ret;
}
-int ec_GFp_simple_group_get_degree(const EC_GROUP *group) {
+unsigned ec_GFp_simple_group_get_degree(const EC_GROUP *group) {
return BN_num_bits(&group->field);
}
@@ -283,8 +239,7 @@ int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) {
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_group_check_discriminant,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -492,8 +447,7 @@ int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group,
const BIGNUM *y, BN_CTX *ctx) {
if (x == NULL || y == NULL) {
/* unlike for projective coordinates, we do not tolerate this */
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point_set_affine_coordinates,
- ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
@@ -510,8 +464,7 @@ int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group,
int ret = 0;
if (EC_POINT_is_at_infinity(group, point)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point_get_affine_coordinates,
- EC_R_POINT_AT_INFINITY);
+ OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
return 0;
}
@@ -527,7 +480,7 @@ int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group,
Z_1 = BN_CTX_get(ctx);
Z_2 = BN_CTX_get(ctx);
Z_3 = BN_CTX_get(ctx);
- if (Z_3 == NULL) {
+ if (Z == NULL || Z_1 == NULL || Z_2 == NULL || Z_3 == NULL) {
goto err;
}
@@ -560,8 +513,7 @@ int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group,
}
} else {
if (!BN_mod_inverse(Z_1, Z_, &group->field, ctx)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point_get_affine_coordinates,
- ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
@@ -1183,7 +1135,7 @@ int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
goto err;
}
if (!point->Z_is_one) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_make_affine, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -1269,7 +1221,7 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num,
* non-zero points[i]->Z by its inverse. */
if (!BN_mod_inverse(tmp, prod_Z[num - 1], &group->field, ctx)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_points_make_affine, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
diff --git a/src/crypto/ec/wnaf.c b/src/crypto/ec/wnaf.c
index ae0d73f..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, ec_pre_comp_new, 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
@@ -158,7 +101,7 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) {
if (BN_is_zero(scalar)) {
r = OPENSSL_malloc(1);
if (!r) {
- OPENSSL_PUT_ERROR(EC, compute_wNAF, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
r[0] = 0;
@@ -169,7 +112,7 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) {
if (w <= 0 || w > 7) /* 'signed char' can represent integers with absolute
values less than 2^7 */
{
- OPENSSL_PUT_ERROR(EC, compute_wNAF, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
bit = 1 << w; /* at most 128 */
@@ -181,7 +124,7 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) {
}
if (scalar->d == NULL || scalar->top == 0) {
- OPENSSL_PUT_ERROR(EC, compute_wNAF, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -192,7 +135,7 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) {
* (*ret_len will be set to the actual length, i.e. at most
* BN_num_bits(scalar) + 1) */
if (r == NULL) {
- OPENSSL_PUT_ERROR(EC, compute_wNAF, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
window_val = scalar->d[0] & mask;
@@ -225,7 +168,7 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) {
}
if (digit <= -bit || digit >= bit || !(digit & 1)) {
- OPENSSL_PUT_ERROR(EC, compute_wNAF, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -235,7 +178,7 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) {
* for modified window NAFs, it may also be 2^w
*/
if (window_val != 0 && window_val != next_bit && window_val != bit) {
- OPENSSL_PUT_ERROR(EC, compute_wNAF, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
}
@@ -246,13 +189,13 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) {
window_val += bit * BN_is_bit_set(scalar, j + w);
if (window_val > next_bit) {
- OPENSSL_PUT_ERROR(EC, compute_wNAF, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
}
if (j > len + 1) {
- OPENSSL_PUT_ERROR(EC, compute_wNAF, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
len = j;
@@ -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_wNAF_mul, 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_wNAF_mul, 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_wNAF_mul, EC_R_UNDEFINED_GENERATOR);
+ 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, ec_wNAF_mul, 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) {
@@ -391,22 +283,22 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
}
if (!wsize || !wNAF_len || !wNAF || !val_sub) {
- OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
/* 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,118 +307,18 @@ 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, ec_wNAF_mul, 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, ec_wNAF_mul, 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, ec_wNAF_mul, ERR_R_INTERNAL_ERROR);
- 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, ec_wNAF_mul, ERR_R_INTERNAL_ERROR);
- 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, ec_wNAF_mul, 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, ec_wNAF_mul, 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, ec_wNAF_mul, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
val[num_val] = NULL; /* pivot element */
/* 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);
@@ -537,7 +329,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
}
}
if (!(v == val + num_val)) {
- OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -551,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;
@@ -585,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;
@@ -655,197 +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_wNAF_precompute_mult, 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_wNAF_precompute_mult, 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, ec_wNAF_precompute_mult, 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, ec_wNAF_precompute_mult, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- }
-
- if (!(tmp_point = EC_POINT_new(group)) || !(base = EC_POINT_new(group))) {
- OPENSSL_PUT_ERROR(EC, ec_wNAF_precompute_mult, 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, ec_wNAF_precompute_mult, 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;
-}
-
-
-int ec_wNAF_have_precompute_mult(const EC_GROUP *group) {
- return group->pre_comp != NULL;
-}
diff --git a/src/crypto/ecdh/CMakeLists.txt b/src/crypto/ecdh/CMakeLists.txt
index 346e72d..8eaeae5 100644
--- a/src/crypto/ecdh/CMakeLists.txt
+++ b/src/crypto/ecdh/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
ecdh
diff --git a/src/crypto/ecdh/ecdh.c b/src/crypto/ecdh/ecdh.c
index a011bab..4a1964a 100644
--- a/src/crypto/ecdh/ecdh.c
+++ b/src/crypto/ecdh/ecdh.c
@@ -75,87 +75,79 @@
int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
- EC_KEY *priv_key, void *(*KDF)(const void *in, size_t inlen,
- void *out, size_t *outlen)) {
- BN_CTX *ctx;
- EC_POINT *tmp = NULL;
- BIGNUM *x = NULL, *y = NULL;
- const BIGNUM *priv;
- const EC_GROUP *group;
- int ret = -1;
- size_t buflen;
- uint8_t *buf = NULL;
-
- if ((ctx = BN_CTX_new()) == NULL) {
- goto err;
+ EC_KEY *priv_key,
+ void *(*kdf)(const void *in, size_t inlen, void *out,
+ size_t *outlen)) {
+ const BIGNUM *const priv = EC_KEY_get0_private_key(priv_key);
+ if (priv == NULL) {
+ OPENSSL_PUT_ERROR(ECDH, ECDH_R_NO_PRIVATE_VALUE);
+ return -1;
}
- BN_CTX_start(ctx);
- x = BN_CTX_get(ctx);
- y = BN_CTX_get(ctx);
- priv = EC_KEY_get0_private_key(priv_key);
- if (priv == NULL) {
- OPENSSL_PUT_ERROR(ECDH, ECDH_compute_key, ECDH_R_NO_PRIVATE_VALUE);
- goto err;
+ BN_CTX *ctx = BN_CTX_new();
+ if (ctx == NULL) {
+ return -1;
}
+ BN_CTX_start(ctx);
- group = EC_KEY_get0_group(priv_key);
+ int ret = -1;
+ size_t buflen = 0;
+ uint8_t *buf = NULL;
- tmp = EC_POINT_new(group);
+ const EC_GROUP *const group = EC_KEY_get0_group(priv_key);
+ EC_POINT *tmp = EC_POINT_new(group);
if (tmp == NULL) {
- OPENSSL_PUT_ERROR(ECDH, ECDH_compute_key, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ECDH, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv, ctx)) {
- OPENSSL_PUT_ERROR(ECDH, ECDH_compute_key, ECDH_R_POINT_ARITHMETIC_FAILURE);
+ OPENSSL_PUT_ERROR(ECDH, ECDH_R_POINT_ARITHMETIC_FAILURE);
goto err;
}
- if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, y, ctx)) {
- OPENSSL_PUT_ERROR(ECDH, ECDH_compute_key, ECDH_R_POINT_ARITHMETIC_FAILURE);
+ BIGNUM *x = BN_CTX_get(ctx);
+ if (!x) {
+ OPENSSL_PUT_ERROR(ECDH, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, NULL, ctx)) {
+ OPENSSL_PUT_ERROR(ECDH, ECDH_R_POINT_ARITHMETIC_FAILURE);
goto err;
}
buflen = (EC_GROUP_get_degree(group) + 7) / 8;
buf = OPENSSL_malloc(buflen);
if (buf == NULL) {
- OPENSSL_PUT_ERROR(ECDH, ECDH_compute_key, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ECDH, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!BN_bn2bin_padded(buf, buflen, x)) {
- OPENSSL_PUT_ERROR(ECDH, ECDH_compute_key, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(ECDH, ERR_R_INTERNAL_ERROR);
goto err;
}
- if (KDF != 0) {
- if (KDF(buf, buflen, out, &outlen) == NULL) {
- OPENSSL_PUT_ERROR(ECDH, ECDH_compute_key, ECDH_R_KDF_FAILED);
+ if (kdf != NULL) {
+ if (kdf(buf, buflen, out, &outlen) == NULL) {
+ OPENSSL_PUT_ERROR(ECDH, ECDH_R_KDF_FAILED);
goto err;
}
- ret = outlen;
} else {
/* no KDF, just copy as much as we can */
- if (outlen > buflen) {
+ if (buflen < outlen) {
outlen = buflen;
}
memcpy(out, buf, outlen);
- ret = outlen;
}
+ ret = outlen;
+
err:
- if (tmp) {
- EC_POINT_free(tmp);
- }
- if (ctx) {
- BN_CTX_end(ctx);
- }
- if (ctx) {
- BN_CTX_free(ctx);
- }
- if (buf) {
- OPENSSL_free(buf);
- }
+ OPENSSL_free(buf);
+ EC_POINT_free(tmp);
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
return ret;
}
diff --git a/src/crypto/ecdsa/CMakeLists.txt b/src/crypto/ecdsa/CMakeLists.txt
index f431e59..0cc672e 100644
--- a/src/crypto/ecdsa/CMakeLists.txt
+++ b/src/crypto/ecdsa/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
ecdsa
@@ -19,3 +19,4 @@ add_executable(
)
target_link_libraries(ecdsa_test crypto)
+add_dependencies(all_tests ecdsa_test)
diff --git a/src/crypto/ecdsa/ecdsa.c b/src/crypto/ecdsa/ecdsa.c
index b71799e..16760ed 100644
--- a/src/crypto/ecdsa/ecdsa.c
+++ b/src/crypto/ecdsa/ecdsa.c
@@ -52,9 +52,11 @@
#include <openssl/ecdsa.h>
+#include <assert.h>
#include <string.h>
#include <openssl/bn.h>
+#include <openssl/bytestring.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -81,16 +83,18 @@ int ECDSA_verify(int type, const uint8_t *digest, size_t digest_len,
return eckey->ecdsa_meth->verify(digest, digest_len, sig, sig_len, eckey);
}
- s = ECDSA_SIG_new();
- const uint8_t *sigp = sig;
- if (s == NULL || d2i_ECDSA_SIG(&s, &sigp, sig_len) == NULL ||
- sigp != sig + sig_len) {
+ /* Decode the ECDSA signature. */
+ s = ECDSA_SIG_from_bytes(sig, sig_len);
+ if (s == NULL) {
goto err;
}
- /* Ensure that the signature uses DER and doesn't have trailing garbage. */
- const int der_len = i2d_ECDSA_SIG(s, &der);
- if (der_len < 0 || (size_t) der_len != sig_len || memcmp(sig, der, sig_len)) {
+ /* Defend against potential laxness in the DER parser. */
+ size_t der_len;
+ if (!ECDSA_SIG_to_bytes(&der, &der_len, s) ||
+ der_len != sig_len || memcmp(sig, der, sig_len) != 0) {
+ /* This should never happen. crypto/bytestring is strictly DER. */
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -116,14 +120,14 @@ static int digest_to_bn(BIGNUM *out, const uint8_t *digest, size_t digest_len,
digest_len = (num_bits + 7) / 8;
}
if (!BN_bin2bn(digest, digest_len, out)) {
- OPENSSL_PUT_ERROR(ECDSA, digest_to_bn, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
return 0;
}
/* If still too long truncate remaining bits with a shift */
if ((8 * digest_len > num_bits) &&
!BN_rshift(out, out, 8 - (num_bits & 0x7))) {
- OPENSSL_PUT_ERROR(ECDSA, digest_to_bn, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
return 0;
}
@@ -139,13 +143,13 @@ 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;
if (eckey->ecdsa_meth && eckey->ecdsa_meth->verify) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ECDSA_R_NOT_IMPLEMENTED);
+ OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_NOT_IMPLEMENTED);
return 0;
}
@@ -153,41 +157,36 @@ int ECDSA_do_verify(const uint8_t *digest, size_t digest_len,
if ((group = EC_KEY_get0_group(eckey)) == NULL ||
(pub_key = EC_KEY_get0_public_key(eckey)) == NULL ||
sig == NULL) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ECDSA_R_MISSING_PARAMETERS);
+ OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_MISSING_PARAMETERS);
return 0;
}
ctx = BN_CTX_new();
if (!ctx) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
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 (!X) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_BN_LIB);
- goto err;
- }
-
- if (!EC_GROUP_get_order(group, order, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_EC_LIB);
+ if (u1 == NULL || u2 == NULL || m == NULL || X == NULL) {
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_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) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ECDSA_R_BAD_SIGNATURE);
+ OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE);
ret = 0; /* signature is invalid */
goto err;
}
/* calculate tmp1 = inv(S) mod order */
if (!BN_mod_inverse(u2, sig->s, order, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
goto err;
}
if (!digest_to_bn(m, digest, digest_len, order)) {
@@ -195,37 +194,37 @@ int ECDSA_do_verify(const uint8_t *digest, size_t digest_len,
}
/* u1 = m * tmp mod order */
if (!BN_mod_mul(u1, m, u2, order, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
goto err;
}
/* u2 = r * w mod q */
if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
goto err;
}
point = EC_POINT_new(group);
if (point == NULL) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
goto err;
}
if (!EC_POINT_get_affine_coordinates_GFp(group, point, X, NULL, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
goto err;
}
if (!BN_nnmod(u1, X, order, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
goto err;
}
/* if the signature is correct u1 is equal to sig->r */
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;
@@ -235,19 +234,19 @@ 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;
if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) {
- OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (ctx_in == NULL) {
if ((ctx = BN_CTX_new()) == NULL) {
- OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
return 0;
}
} else {
@@ -256,22 +255,19 @@ 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) {
- OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_MALLOC_FAILURE);
+ if (k == NULL || r == NULL || X == NULL) {
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
goto err;
}
tmp_point = EC_POINT_new(group);
if (tmp_point == NULL) {
- OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_EC_LIB);
- goto err;
- }
- if (!EC_GROUP_get_order(group, order, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_EC_LIB);
+ 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
* generation. The |digest| argument is only empty if |ECDSA_sign_setup| is
@@ -286,8 +282,7 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
ok = BN_rand_range(k, order);
}
if (!ok) {
- OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup,
- ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
+ OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
goto err;
}
} while (BN_is_zero(k));
@@ -307,23 +302,37 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
/* compute r the x-coordinate of generator * k */
if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
goto err;
}
if (!EC_POINT_get_affine_coordinates_GFp(group, tmp_point, X, NULL, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
goto err;
}
if (!BN_nnmod(r, X, order, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
goto err;
}
} while (BN_is_zero(r));
/* compute the inverse of k */
- if (!BN_mod_inverse(k, k, order, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_BN_LIB);
+ if (ec_group_get_mont_data(group) != NULL) {
+ /* We want inverse in constant time, therefore we use that the order must
+ * be prime and thus we can use Fermat's Little Theorem. */
+ if (!BN_set_word(X, 2) ||
+ !BN_sub(X, order, X)) {
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
+ goto err;
+ }
+ BN_set_flags(X, BN_FLG_CONSTTIME);
+ if (!BN_mod_exp_mont_consttime(k, k, X, order, ctx,
+ ec_group_get_mont_data(group))) {
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
+ goto err;
+ }
+ } else if (!BN_mod_inverse(k, k, order, ctx)) {
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
goto err;
}
/* clear old values if necessary */
@@ -343,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;
@@ -357,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;
@@ -365,7 +373,7 @@ ECDSA_SIG *ECDSA_do_sign_ex(const uint8_t *digest, size_t digest_len,
const BIGNUM *priv_key;
if (eckey->ecdsa_meth && eckey->ecdsa_meth->sign) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ECDSA_R_NOT_IMPLEMENTED);
+ OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_NOT_IMPLEMENTED);
return NULL;
}
@@ -373,62 +381,61 @@ ECDSA_SIG *ECDSA_do_sign_ex(const uint8_t *digest, size_t digest_len,
priv_key = EC_KEY_get0_private_key(eckey);
if (group == NULL || priv_key == NULL) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
ret = ECDSA_SIG_new();
if (!ret) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
return NULL;
}
s = ret->s;
- if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||
- (tmp = BN_new()) == NULL || (m = BN_new()) == NULL) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_MALLOC_FAILURE);
+ 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, ECDSA_do_sign_ex, 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;
}
for (;;) {
if (in_kinv == NULL || in_r == NULL) {
if (!ecdsa_sign_setup(eckey, ctx, &kinv, &ret->r, digest, digest_len)) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_ECDSA_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_ECDSA_LIB);
goto err;
}
ckinv = kinv;
} else {
ckinv = in_kinv;
if (BN_copy(ret->r, in_r) == NULL) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
goto err;
}
}
if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
goto err;
}
if (!BN_mod_add_quick(s, tmp, m, order)) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
goto err;
}
if (!BN_mod_mul(s, s, ckinv, order, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
goto err;
}
if (BN_is_zero(s)) {
/* if kinv and r have been supplied by the caller
* don't to generate new kinv and r values */
if (in_kinv != NULL && in_r != NULL) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ECDSA_R_NEED_NEW_SETUP_VALUES);
+ OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_NEED_NEW_SETUP_VALUES);
goto err;
}
} else {
@@ -447,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;
}
@@ -455,20 +461,36 @@ err:
int ECDSA_sign_ex(int type, const uint8_t *digest, size_t digest_len,
uint8_t *sig, unsigned int *sig_len, const BIGNUM *kinv,
const BIGNUM *r, EC_KEY *eckey) {
+ int ret = 0;
ECDSA_SIG *s = NULL;
if (eckey->ecdsa_meth && eckey->ecdsa_meth->sign) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_sign_ex, ECDSA_R_NOT_IMPLEMENTED);
+ OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_NOT_IMPLEMENTED);
*sig_len = 0;
- return 0;
+ goto err;
}
s = ECDSA_do_sign_ex(digest, digest_len, kinv, r, eckey);
if (s == NULL) {
*sig_len = 0;
- return 0;
+ goto err;
+ }
+
+ CBB cbb;
+ CBB_zero(&cbb);
+ size_t len;
+ if (!CBB_init_fixed(&cbb, sig, ECDSA_size(eckey)) ||
+ !ECDSA_SIG_marshal(&cbb, s) ||
+ !CBB_finish(&cbb, NULL, &len)) {
+ OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR);
+ CBB_cleanup(&cbb);
+ *sig_len = 0;
+ goto err;
}
- *sig_len = i2d_ECDSA_SIG(s, &sig);
+ *sig_len = (unsigned)len;
+ ret = 1;
+
+err:
ECDSA_SIG_free(s);
- return 1;
+ return ret;
}
diff --git a/src/crypto/ecdsa/ecdsa_asn1.c b/src/crypto/ecdsa/ecdsa_asn1.c
index f557ca7..3fee191 100644
--- a/src/crypto/ecdsa/ecdsa_asn1.c
+++ b/src/crypto/ecdsa/ecdsa_asn1.c
@@ -52,68 +52,36 @@
#include <openssl/ecdsa.h>
-#include <openssl/asn1.h>
-#include <openssl/asn1t.h>
+#include <limits.h>
+#include <string.h>
+
+#include <openssl/bn.h>
+#include <openssl/bytestring.h>
+#include <openssl/err.h>
#include <openssl/ec_key.h>
#include <openssl/mem.h>
#include "../ec/internal.h"
-DECLARE_ASN1_FUNCTIONS_const(ECDSA_SIG);
-DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECDSA_SIG, ECDSA_SIG);
-
-ASN1_SEQUENCE(ECDSA_SIG) = {
- ASN1_SIMPLE(ECDSA_SIG, r, CBIGNUM),
- ASN1_SIMPLE(ECDSA_SIG, s, CBIGNUM),
-} ASN1_SEQUENCE_END(ECDSA_SIG);
-
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ECDSA_SIG, ECDSA_SIG, ECDSA_SIG);
-
size_t ECDSA_size(const EC_KEY *key) {
- size_t ret, i, group_order_size;
- ASN1_INTEGER bs;
- BIGNUM *order = NULL;
- unsigned char buf[4];
- const EC_GROUP *group;
+ if (key == NULL) {
+ return 0;
+ }
+ size_t group_order_size;
if (key->ecdsa_meth && key->ecdsa_meth->group_order_size) {
group_order_size = key->ecdsa_meth->group_order_size(key);
} else {
- size_t num_bits;
-
- if (key == NULL) {
- return 0;
- }
- group = EC_KEY_get0_group(key);
+ const EC_GROUP *group = EC_KEY_get0_group(key);
if (group == NULL) {
return 0;
}
- order = BN_new();
- if (order == NULL) {
- return 0;
- }
- if (!EC_GROUP_get_order(group, order, NULL)) {
- BN_clear_free(order);
- return 0;
- }
-
- num_bits = BN_num_bits(order);
- group_order_size = (num_bits + 7) / 8;
+ group_order_size = BN_num_bytes(EC_GROUP_get0_order(group));
}
- bs.length = group_order_size;
- bs.data = buf;
- bs.type = V_ASN1_INTEGER;
- /* If the top bit is set the ASN.1 encoding is 1 larger. */
- buf[0] = 0xff;
-
- i = i2d_ASN1_INTEGER(&bs, NULL);
- i += i; /* r and s */
- ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE);
- BN_clear_free(order);
- return ret;
+ return ECDSA_SIG_max_len(group_order_size);
}
ECDSA_SIG *ECDSA_SIG_new(void) {
@@ -139,3 +107,134 @@ void ECDSA_SIG_free(ECDSA_SIG *sig) {
BN_free(sig->s);
OPENSSL_free(sig);
}
+
+ECDSA_SIG *ECDSA_SIG_parse(CBS *cbs) {
+ ECDSA_SIG *ret = ECDSA_SIG_new();
+ if (ret == NULL) {
+ return NULL;
+ }
+ CBS child;
+ if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
+ !BN_cbs2unsigned(&child, ret->r) ||
+ !BN_cbs2unsigned(&child, ret->s) ||
+ CBS_len(&child) != 0) {
+ OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE);
+ ECDSA_SIG_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
+ECDSA_SIG *ECDSA_SIG_from_bytes(const uint8_t *in, size_t in_len) {
+ CBS cbs;
+ CBS_init(&cbs, in, in_len);
+ ECDSA_SIG *ret = ECDSA_SIG_parse(&cbs);
+ if (ret == NULL || CBS_len(&cbs) != 0) {
+ OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE);
+ ECDSA_SIG_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
+int ECDSA_SIG_marshal(CBB *cbb, const ECDSA_SIG *sig) {
+ CBB child;
+ if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
+ !BN_bn2cbb(&child, sig->r) ||
+ !BN_bn2cbb(&child, sig->s) ||
+ !CBB_flush(cbb)) {
+ OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR);
+ return 0;
+ }
+ return 1;
+}
+
+int ECDSA_SIG_to_bytes(uint8_t **out_bytes, size_t *out_len,
+ const ECDSA_SIG *sig) {
+ CBB cbb;
+ CBB_zero(&cbb);
+ if (!CBB_init(&cbb, 0) ||
+ !ECDSA_SIG_marshal(&cbb, sig) ||
+ !CBB_finish(&cbb, out_bytes, out_len)) {
+ OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR);
+ CBB_cleanup(&cbb);
+ return 0;
+ }
+ return 1;
+}
+
+/* der_len_len returns the number of bytes needed to represent a length of |len|
+ * in DER. */
+static size_t der_len_len(size_t len) {
+ if (len < 0x80) {
+ return 1;
+ }
+ size_t ret = 1;
+ while (len > 0) {
+ ret++;
+ len >>= 8;
+ }
+ return ret;
+}
+
+size_t ECDSA_SIG_max_len(size_t order_len) {
+ /* Compute the maximum length of an |order_len| byte integer. Defensively
+ * assume that the leading 0x00 is included. */
+ size_t integer_len = 1 /* tag */ + der_len_len(order_len + 1) + 1 + order_len;
+ if (integer_len < order_len) {
+ return 0;
+ }
+ /* An ECDSA signature is two INTEGERs. */
+ size_t value_len = 2 * integer_len;
+ if (value_len < integer_len) {
+ return 0;
+ }
+ /* Add the header. */
+ size_t ret = 1 /* tag */ + der_len_len(value_len) + value_len;
+ if (ret < value_len) {
+ return 0;
+ }
+ return ret;
+}
+
+ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **out, const uint8_t **inp, long len) {
+ if (len < 0) {
+ return NULL;
+ }
+ CBS cbs;
+ CBS_init(&cbs, *inp, (size_t)len);
+ ECDSA_SIG *ret = ECDSA_SIG_parse(&cbs);
+ if (ret == NULL) {
+ return NULL;
+ }
+ if (out != NULL) {
+ ECDSA_SIG_free(*out);
+ *out = ret;
+ }
+ *inp += (size_t)len - CBS_len(&cbs);
+ return ret;
+}
+
+int i2d_ECDSA_SIG(const ECDSA_SIG *sig, uint8_t **outp) {
+ uint8_t *der;
+ size_t der_len;
+ if (!ECDSA_SIG_to_bytes(&der, &der_len, sig)) {
+ return -1;
+ }
+ if (der_len > INT_MAX) {
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_OVERFLOW);
+ OPENSSL_free(der);
+ return -1;
+ }
+ if (outp != NULL) {
+ if (*outp == NULL) {
+ *outp = der;
+ der = NULL;
+ } else {
+ memcpy(*outp, der, der_len);
+ *outp += der_len;
+ }
+ }
+ OPENSSL_free(der);
+ return (int)der_len;
+}
diff --git a/src/crypto/ecdsa/ecdsa_test.cc b/src/crypto/ecdsa/ecdsa_test.cc
index a6bd7a1..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,
@@ -78,18 +77,13 @@ static bool VerifyECDSASig(Api api, const uint8_t *digest,
switch (api) {
case kEncodedApi: {
- int sig_len = i2d_ECDSA_SIG(ecdsa_sig, NULL);
- if (sig_len <= 0) {
+ uint8_t *der;
+ size_t der_len;
+ if (!ECDSA_SIG_to_bytes(&der, &der_len, ecdsa_sig)) {
return false;
}
- std::vector<uint8_t> signature(static_cast<size_t>(sig_len));
- uint8_t *sig_ptr = bssl::vector_data(&signature);
- sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr);
- if (sig_len <= 0) {
- return false;
- }
- actual_result = ECDSA_verify(0, digest, digest_len, bssl::vector_data(&signature),
- signature.size(), eckey);
+ ScopedOpenSSLBytes delete_der(der);
+ actual_result = ECDSA_verify(0, digest, digest_len, der, der_len, eckey);
break;
}
@@ -123,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;
}
@@ -134,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;
}
@@ -185,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;
@@ -226,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;
}
@@ -235,43 +221,43 @@ 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;
}
fprintf(out, ".");
fflush(out);
// Verify a tampered signature.
- const uint8_t *sig_ptr = bssl::vector_data(&signature);
- ScopedECDSA_SIG ecdsa_sig(d2i_ECDSA_SIG(NULL, &sig_ptr, signature.size()));
+ ScopedECDSA_SIG ecdsa_sig(ECDSA_SIG_from_bytes(
+ 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;
}
@@ -310,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;
}
@@ -325,11 +311,45 @@ static bool TestBuiltin(FILE *out) {
return true;
}
+static bool TestECDSA_SIG_max_len(size_t order_len) {
+ /* Create the largest possible |ECDSA_SIG| of the given constraints. */
+ ScopedECDSA_SIG sig(ECDSA_SIG_new());
+ if (!sig) {
+ return false;
+ }
+ std::vector<uint8_t> bytes(order_len, 0xff);
+ if (!BN_bin2bn(bytes.data(), bytes.size(), sig->r) ||
+ !BN_bin2bn(bytes.data(), bytes.size(), sig->s)) {
+ return false;
+ }
+ /* Serialize it. */
+ uint8_t *der;
+ size_t der_len;
+ if (!ECDSA_SIG_to_bytes(&der, &der_len, sig.get())) {
+ return false;
+ }
+ ScopedOpenSSLBytes delete_der(der);
+
+ size_t max_len = ECDSA_SIG_max_len(order_len);
+ if (max_len != der_len) {
+ fprintf(stderr, "ECDSA_SIG_max_len(%u) returned %u, wanted %u\n",
+ static_cast<unsigned>(order_len), static_cast<unsigned>(max_len),
+ static_cast<unsigned>(der_len));
+ return false;
+ }
+ return true;
+}
+
int main(void) {
CRYPTO_library_init();
ERR_load_crypto_strings();
- if (!TestBuiltin(stdout)) {
+ if (!TestBuiltin(stdout) ||
+ !TestECDSA_SIG_max_len(224/8) ||
+ !TestECDSA_SIG_max_len(256/8) ||
+ !TestECDSA_SIG_max_len(384/8) ||
+ !TestECDSA_SIG_max_len(512/8) ||
+ !TestECDSA_SIG_max_len(10000)) {
printf("\nECDSA test failed\n");
ERR_print_errors_fp(stdout);
return 1;
diff --git a/src/crypto/engine/CMakeLists.txt b/src/crypto/engine/CMakeLists.txt
index e03650e..5667f02 100644
--- a/src/crypto/engine/CMakeLists.txt
+++ b/src/crypto/engine/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
engine
diff --git a/src/crypto/engine/engine.c b/src/crypto/engine/engine.c
index 6c3300d..25ea98d 100644
--- a/src/crypto/engine/engine.c
+++ b/src/crypto/engine/engine.c
@@ -17,8 +17,6 @@
#include <string.h>
#include <assert.h>
-#include <openssl/dh.h>
-#include <openssl/dsa.h>
#include <openssl/ec_key.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -27,8 +25,6 @@
struct engine_st {
- DH_METHOD *dh_method;
- DSA_METHOD *dsa_method;
RSA_METHOD *rsa_method;
ECDSA_METHOD *ecdsa_method;
};
@@ -64,26 +60,6 @@ static int set_method(void **out_member, const void *method, size_t method_size,
return 1;
}
-int ENGINE_set_DH_method(ENGINE *engine, const DH_METHOD *method,
- size_t method_size) {
- return set_method((void **)&engine->dh_method, method, method_size,
- sizeof(DH_METHOD));
-}
-
-DH_METHOD *ENGINE_get_DH_method(const ENGINE *engine) {
- return engine->dh_method;
-}
-
-int ENGINE_set_DSA_method(ENGINE *engine, const DSA_METHOD *method,
- size_t method_size) {
- return set_method((void **)&engine->dsa_method, method, method_size,
- sizeof(DSA_METHOD));
-}
-
-DSA_METHOD *ENGINE_get_DSA_method(const ENGINE *engine) {
- return engine->dsa_method;
-}
-
int ENGINE_set_RSA_method(ENGINE *engine, const RSA_METHOD *method,
size_t method_size) {
return set_method((void **)&engine->rsa_method, method, method_size,
diff --git a/src/crypto/err/CMakeLists.txt b/src/crypto/err/CMakeLists.txt
index 5215eec..a095b54 100644
--- a/src/crypto/err/CMakeLists.txt
+++ b/src/crypto/err/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_custom_command(
OUTPUT err_data.c
@@ -8,10 +8,8 @@ add_custom_command(
asn1.errordata
bio.errordata
bn.errordata
- buf.errordata
cipher.errordata
conf.errordata
- crypto.errordata
dh.errordata
digest.errordata
dsa.errordata
@@ -49,3 +47,4 @@ add_executable(
)
target_link_libraries(err_test crypto)
+add_dependencies(all_tests err_test)
diff --git a/src/crypto/err/asn1.errordata b/src/crypto/err/asn1.errordata
index 44b9c73..b1b0437 100644
--- a/src/crypto/err/asn1.errordata
+++ b/src/crypto/err/asn1.errordata
@@ -1,152 +1,87 @@
-ASN1,function,100,ASN1_BIT_STRING_set_bit
-ASN1,function,101,ASN1_ENUMERATED_set
-ASN1,function,102,ASN1_ENUMERATED_to_BN
-ASN1,function,103,ASN1_GENERALIZEDTIME_adj
-ASN1,function,104,ASN1_INTEGER_set
-ASN1,function,105,ASN1_INTEGER_to_BN
-ASN1,function,106,ASN1_OBJECT_new
-ASN1,function,107,ASN1_PCTX_new
-ASN1,function,108,ASN1_STRING_TABLE_add
-ASN1,function,109,ASN1_STRING_set
-ASN1,function,110,ASN1_STRING_type_new
-ASN1,function,111,ASN1_TIME_adj
-ASN1,function,112,ASN1_UTCTIME_adj
-ASN1,function,113,ASN1_d2i_fp
-ASN1,function,114,ASN1_dup
-ASN1,function,115,ASN1_generate_v3
-ASN1,function,116,ASN1_get_object
-ASN1,function,117,ASN1_i2d_bio
-ASN1,function,118,ASN1_i2d_fp
-ASN1,function,119,ASN1_item_d2i_fp
-ASN1,function,120,ASN1_item_dup
-ASN1,function,121,ASN1_item_ex_d2i
-ASN1,function,122,ASN1_item_i2d_bio
-ASN1,function,123,ASN1_item_i2d_fp
-ASN1,function,124,ASN1_item_pack
-ASN1,function,125,ASN1_item_unpack
-ASN1,function,126,ASN1_mbstring_ncopy
-ASN1,function,127,ASN1_template_new
-ASN1,function,128,BIO_new_NDEF
-ASN1,function,129,BN_to_ASN1_ENUMERATED
-ASN1,function,130,BN_to_ASN1_INTEGER
-ASN1,function,131,a2d_ASN1_OBJECT
-ASN1,function,132,a2i_ASN1_ENUMERATED
-ASN1,function,133,a2i_ASN1_INTEGER
-ASN1,function,134,a2i_ASN1_STRING
-ASN1,function,135,append_exp
-ASN1,function,136,asn1_cb
-ASN1,function,137,asn1_check_tlen
-ASN1,function,138,asn1_collate_primitive
-ASN1,function,139,asn1_collect
-ASN1,function,140,asn1_d2i_ex_primitive
-ASN1,function,141,asn1_d2i_read_bio
-ASN1,function,142,asn1_do_adb
-ASN1,function,143,asn1_ex_c2i
-ASN1,function,144,asn1_find_end
-ASN1,function,145,asn1_item_ex_combine_new
-ASN1,function,146,asn1_str2type
-ASN1,function,147,asn1_template_ex_d2i
-ASN1,function,148,asn1_template_noexp_d2i
-ASN1,function,149,bitstr_cb
-ASN1,function,150,c2i_ASN1_BIT_STRING
-ASN1,function,151,c2i_ASN1_INTEGER
-ASN1,function,152,c2i_ASN1_OBJECT
-ASN1,function,153,collect_data
-ASN1,function,154,d2i_ASN1_BOOLEAN
-ASN1,function,155,d2i_ASN1_OBJECT
-ASN1,function,156,d2i_ASN1_UINTEGER
-ASN1,function,157,d2i_ASN1_UTCTIME
-ASN1,function,158,d2i_ASN1_bytes
-ASN1,function,159,d2i_ASN1_type_bytes
-ASN1,function,160,i2d_ASN1_TIME
-ASN1,function,161,i2d_PrivateKey
-ASN1,function,162,long_c2i
-ASN1,function,163,parse_tagging
-ASN1,reason,100,ASN1_LENGTH_MISMATCH
-ASN1,reason,101,AUX_ERROR
-ASN1,reason,102,BAD_GET_ASN1_OBJECT_CALL
-ASN1,reason,103,BAD_OBJECT_HEADER
-ASN1,reason,104,BMPSTRING_IS_WRONG_LENGTH
-ASN1,reason,105,BN_LIB
-ASN1,reason,106,BOOLEAN_IS_WRONG_LENGTH
-ASN1,reason,107,BUFFER_TOO_SMALL
-ASN1,reason,108,DECODE_ERROR
-ASN1,reason,109,DEPTH_EXCEEDED
-ASN1,reason,110,ENCODE_ERROR
-ASN1,reason,111,ERROR_GETTING_TIME
-ASN1,reason,112,EXPECTING_AN_ASN1_SEQUENCE
-ASN1,reason,113,EXPECTING_AN_INTEGER
-ASN1,reason,114,EXPECTING_AN_OBJECT
-ASN1,reason,115,EXPECTING_A_BOOLEAN
-ASN1,reason,116,EXPECTING_A_TIME
-ASN1,reason,117,EXPLICIT_LENGTH_MISMATCH
-ASN1,reason,118,EXPLICIT_TAG_NOT_CONSTRUCTED
-ASN1,reason,119,FIELD_MISSING
-ASN1,reason,120,FIRST_NUM_TOO_LARGE
-ASN1,reason,121,HEADER_TOO_LONG
-ASN1,reason,122,ILLEGAL_BITSTRING_FORMAT
-ASN1,reason,123,ILLEGAL_BOOLEAN
-ASN1,reason,124,ILLEGAL_CHARACTERS
-ASN1,reason,125,ILLEGAL_FORMAT
-ASN1,reason,126,ILLEGAL_HEX
-ASN1,reason,127,ILLEGAL_IMPLICIT_TAG
-ASN1,reason,128,ILLEGAL_INTEGER
-ASN1,reason,129,ILLEGAL_NESTED_TAGGING
-ASN1,reason,130,ILLEGAL_NULL
-ASN1,reason,131,ILLEGAL_NULL_VALUE
-ASN1,reason,132,ILLEGAL_OBJECT
-ASN1,reason,133,ILLEGAL_OPTIONAL_ANY
-ASN1,reason,134,ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE
-ASN1,reason,135,ILLEGAL_TAGGED_ANY
-ASN1,reason,136,ILLEGAL_TIME_VALUE
-ASN1,reason,137,INTEGER_NOT_ASCII_FORMAT
-ASN1,reason,138,INTEGER_TOO_LARGE_FOR_LONG
-ASN1,reason,139,INVALID_BIT_STRING_BITS_LEFT
-ASN1,reason,140,INVALID_BMPSTRING_LENGTH
-ASN1,reason,141,INVALID_DIGIT
-ASN1,reason,142,INVALID_MODIFIER
-ASN1,reason,143,INVALID_NUMBER
-ASN1,reason,144,INVALID_OBJECT_ENCODING
-ASN1,reason,145,INVALID_SEPARATOR
-ASN1,reason,146,INVALID_TIME_FORMAT
-ASN1,reason,147,INVALID_UNIVERSALSTRING_LENGTH
-ASN1,reason,148,INVALID_UTF8STRING
-ASN1,reason,149,LIST_ERROR
-ASN1,reason,150,MALLOC_FAILURE
-ASN1,reason,151,MISSING_ASN1_EOS
-ASN1,reason,152,MISSING_EOC
-ASN1,reason,153,MISSING_SECOND_NUMBER
-ASN1,reason,154,MISSING_VALUE
-ASN1,reason,155,MSTRING_NOT_UNIVERSAL
-ASN1,reason,156,MSTRING_WRONG_TAG
-ASN1,reason,157,NESTED_ASN1_ERROR
-ASN1,reason,158,NESTED_ASN1_STRING
-ASN1,reason,159,NON_HEX_CHARACTERS
-ASN1,reason,160,NOT_ASCII_FORMAT
-ASN1,reason,161,NOT_ENOUGH_DATA
-ASN1,reason,162,NO_MATCHING_CHOICE_TYPE
-ASN1,reason,163,NULL_IS_WRONG_LENGTH
-ASN1,reason,164,OBJECT_NOT_ASCII_FORMAT
-ASN1,reason,165,ODD_NUMBER_OF_CHARS
-ASN1,reason,166,SECOND_NUMBER_TOO_LARGE
-ASN1,reason,167,SEQUENCE_LENGTH_MISMATCH
-ASN1,reason,168,SEQUENCE_NOT_CONSTRUCTED
-ASN1,reason,169,SEQUENCE_OR_SET_NEEDS_CONFIG
-ASN1,reason,170,SHORT_LINE
-ASN1,reason,171,STREAMING_NOT_SUPPORTED
-ASN1,reason,172,STRING_TOO_LONG
-ASN1,reason,173,STRING_TOO_SHORT
-ASN1,reason,174,TAG_VALUE_TOO_HIGH
-ASN1,reason,175,TIME_NOT_ASCII_FORMAT
-ASN1,reason,176,TOO_LONG
-ASN1,reason,177,TYPE_NOT_CONSTRUCTED
-ASN1,reason,178,TYPE_NOT_PRIMITIVE
-ASN1,reason,179,UNEXPECTED_EOC
-ASN1,reason,180,UNIVERSALSTRING_IS_WRONG_LENGTH
-ASN1,reason,181,UNKNOWN_FORMAT
-ASN1,reason,182,UNKNOWN_TAG
-ASN1,reason,183,UNSUPPORTED_ANY_DEFINED_BY_TYPE
-ASN1,reason,184,UNSUPPORTED_PUBLIC_KEY_TYPE
-ASN1,reason,185,UNSUPPORTED_TYPE
-ASN1,reason,186,WRONG_TAG
-ASN1,reason,187,WRONG_TYPE
+ASN1,100,ASN1_LENGTH_MISMATCH
+ASN1,101,AUX_ERROR
+ASN1,102,BAD_GET_ASN1_OBJECT_CALL
+ASN1,103,BAD_OBJECT_HEADER
+ASN1,104,BMPSTRING_IS_WRONG_LENGTH
+ASN1,105,BN_LIB
+ASN1,106,BOOLEAN_IS_WRONG_LENGTH
+ASN1,107,BUFFER_TOO_SMALL
+ASN1,108,DECODE_ERROR
+ASN1,109,DEPTH_EXCEEDED
+ASN1,110,ENCODE_ERROR
+ASN1,111,ERROR_GETTING_TIME
+ASN1,112,EXPECTING_AN_ASN1_SEQUENCE
+ASN1,113,EXPECTING_AN_INTEGER
+ASN1,114,EXPECTING_AN_OBJECT
+ASN1,115,EXPECTING_A_BOOLEAN
+ASN1,116,EXPECTING_A_TIME
+ASN1,117,EXPLICIT_LENGTH_MISMATCH
+ASN1,118,EXPLICIT_TAG_NOT_CONSTRUCTED
+ASN1,119,FIELD_MISSING
+ASN1,120,FIRST_NUM_TOO_LARGE
+ASN1,121,HEADER_TOO_LONG
+ASN1,122,ILLEGAL_BITSTRING_FORMAT
+ASN1,123,ILLEGAL_BOOLEAN
+ASN1,124,ILLEGAL_CHARACTERS
+ASN1,125,ILLEGAL_FORMAT
+ASN1,126,ILLEGAL_HEX
+ASN1,127,ILLEGAL_IMPLICIT_TAG
+ASN1,128,ILLEGAL_INTEGER
+ASN1,129,ILLEGAL_NESTED_TAGGING
+ASN1,130,ILLEGAL_NULL
+ASN1,131,ILLEGAL_NULL_VALUE
+ASN1,132,ILLEGAL_OBJECT
+ASN1,133,ILLEGAL_OPTIONAL_ANY
+ASN1,134,ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE
+ASN1,135,ILLEGAL_TAGGED_ANY
+ASN1,136,ILLEGAL_TIME_VALUE
+ASN1,137,INTEGER_NOT_ASCII_FORMAT
+ASN1,138,INTEGER_TOO_LARGE_FOR_LONG
+ASN1,139,INVALID_BIT_STRING_BITS_LEFT
+ASN1,140,INVALID_BMPSTRING_LENGTH
+ASN1,141,INVALID_DIGIT
+ASN1,142,INVALID_MODIFIER
+ASN1,143,INVALID_NUMBER
+ASN1,144,INVALID_OBJECT_ENCODING
+ASN1,145,INVALID_SEPARATOR
+ASN1,146,INVALID_TIME_FORMAT
+ASN1,147,INVALID_UNIVERSALSTRING_LENGTH
+ASN1,148,INVALID_UTF8STRING
+ASN1,149,LIST_ERROR
+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/bio.errordata b/src/crypto/err/bio.errordata
index 9f2af02..94b3c97 100644
--- a/src/crypto/err/bio.errordata
+++ b/src/crypto/err/bio.errordata
@@ -1,36 +1,17 @@
-BIO,function,100,BIO_callback_ctrl
-BIO,function,101,BIO_ctrl
-BIO,function,102,BIO_new
-BIO,function,103,BIO_new_file
-BIO,function,104,BIO_new_mem_buf
-BIO,function,118,BIO_printf
-BIO,function,105,BIO_zero_copy_get_read_buf
-BIO,function,106,BIO_zero_copy_get_read_buf_done
-BIO,function,107,BIO_zero_copy_get_write_buf
-BIO,function,108,BIO_zero_copy_get_write_buf_done
-BIO,function,109,bio_io
-BIO,function,110,bio_make_pair
-BIO,function,111,bio_write
-BIO,function,112,buffer_ctrl
-BIO,function,113,conn_ctrl
-BIO,function,114,conn_state
-BIO,function,115,file_ctrl
-BIO,function,116,file_read
-BIO,function,117,mem_write
-BIO,reason,100,BAD_FOPEN_MODE
-BIO,reason,101,BROKEN_PIPE
-BIO,reason,102,CONNECT_ERROR
-BIO,reason,103,ERROR_SETTING_NBIO
-BIO,reason,104,INVALID_ARGUMENT
-BIO,reason,105,IN_USE
-BIO,reason,106,KEEPALIVE
-BIO,reason,107,NBIO_CONNECT_ERROR
-BIO,reason,108,NO_HOSTNAME_SPECIFIED
-BIO,reason,109,NO_PORT_SPECIFIED
-BIO,reason,110,NO_SUCH_FILE
-BIO,reason,111,NULL_PARAMETER
-BIO,reason,112,SYS_LIB
-BIO,reason,113,UNABLE_TO_CREATE_SOCKET
-BIO,reason,114,UNINITIALIZED
-BIO,reason,115,UNSUPPORTED_METHOD
-BIO,reason,116,WRITE_TO_READ_ONLY_BIO
+BIO,100,BAD_FOPEN_MODE
+BIO,101,BROKEN_PIPE
+BIO,102,CONNECT_ERROR
+BIO,103,ERROR_SETTING_NBIO
+BIO,104,INVALID_ARGUMENT
+BIO,105,IN_USE
+BIO,106,KEEPALIVE
+BIO,107,NBIO_CONNECT_ERROR
+BIO,108,NO_HOSTNAME_SPECIFIED
+BIO,109,NO_PORT_SPECIFIED
+BIO,110,NO_SUCH_FILE
+BIO,111,NULL_PARAMETER
+BIO,112,SYS_LIB
+BIO,113,UNABLE_TO_CREATE_SOCKET
+BIO,114,UNINITIALIZED
+BIO,115,UNSUPPORTED_METHOD
+BIO,116,WRITE_TO_READ_ONLY_BIO
diff --git a/src/crypto/err/bn.errordata b/src/crypto/err/bn.errordata
index 6fd4968..76b6392 100644
--- a/src/crypto/err/bn.errordata
+++ b/src/crypto/err/bn.errordata
@@ -1,44 +1,19 @@
-BN,function,100,BN_CTX_get
-BN,function,101,BN_CTX_new
-BN,function,102,BN_CTX_start
-BN,function,103,BN_bn2dec
-BN,function,104,BN_bn2hex
-BN,function,105,BN_div
-BN,function,106,BN_div_recp
-BN,function,107,BN_exp
-BN,function,108,BN_generate_dsa_nonce
-BN,function,109,BN_generate_prime_ex
-BN,function,125,BN_lshift
-BN,function,110,BN_mod_exp2_mont
-BN,function,111,BN_mod_exp_mont
-BN,function,112,BN_mod_exp_mont_consttime
-BN,function,113,BN_mod_exp_mont_word
-BN,function,114,BN_mod_inverse
-BN,function,115,BN_mod_inverse_no_branch
-BN,function,116,BN_mod_lshift_quick
-BN,function,117,BN_mod_sqrt
-BN,function,118,BN_new
-BN,function,119,BN_rand
-BN,function,120,BN_rand_range
-BN,function,126,BN_rshift
-BN,function,121,BN_sqrt
-BN,function,122,BN_usub
-BN,function,123,bn_wexpand
-BN,function,124,mod_exp_recp
-BN,reason,100,ARG2_LT_ARG3
-BN,reason,101,BAD_RECIPROCAL
-BN,reason,102,BIGNUM_TOO_LONG
-BN,reason,103,BITS_TOO_SMALL
-BN,reason,104,CALLED_WITH_EVEN_MODULUS
-BN,reason,105,DIV_BY_ZERO
-BN,reason,106,EXPAND_ON_STATIC_BIGNUM_DATA
-BN,reason,107,INPUT_NOT_REDUCED
-BN,reason,108,INVALID_RANGE
-BN,reason,109,NEGATIVE_NUMBER
-BN,reason,110,NOT_A_SQUARE
-BN,reason,111,NOT_INITIALIZED
-BN,reason,112,NO_INVERSE
-BN,reason,113,PRIVATE_KEY_TOO_LARGE
-BN,reason,114,P_IS_NOT_PRIME
-BN,reason,115,TOO_MANY_ITERATIONS
-BN,reason,116,TOO_MANY_TEMPORARY_VARIABLES
+BN,100,ARG2_LT_ARG3
+BN,117,BAD_ENCODING
+BN,101,BAD_RECIPROCAL
+BN,102,BIGNUM_TOO_LONG
+BN,103,BITS_TOO_SMALL
+BN,104,CALLED_WITH_EVEN_MODULUS
+BN,105,DIV_BY_ZERO
+BN,118,ENCODE_ERROR
+BN,106,EXPAND_ON_STATIC_BIGNUM_DATA
+BN,107,INPUT_NOT_REDUCED
+BN,108,INVALID_RANGE
+BN,109,NEGATIVE_NUMBER
+BN,110,NOT_A_SQUARE
+BN,111,NOT_INITIALIZED
+BN,112,NO_INVERSE
+BN,113,PRIVATE_KEY_TOO_LARGE
+BN,114,P_IS_NOT_PRIME
+BN,115,TOO_MANY_ITERATIONS
+BN,116,TOO_MANY_TEMPORARY_VARIABLES
diff --git a/src/crypto/err/buf.errordata b/src/crypto/err/buf.errordata
deleted file mode 100644
index 01b6c9a..0000000
--- a/src/crypto/err/buf.errordata
+++ /dev/null
@@ -1,4 +0,0 @@
-BUF,function,100,BUF_MEM_new
-BUF,function,101,BUF_memdup
-BUF,function,102,BUF_strndup
-BUF,function,103,buf_mem_grow
diff --git a/src/crypto/err/cipher.errordata b/src/crypto/err/cipher.errordata
index ce8459b..1037505 100644
--- a/src/crypto/err/cipher.errordata
+++ b/src/crypto/err/cipher.errordata
@@ -1,60 +1,25 @@
-CIPHER,function,100,EVP_AEAD_CTX_init
-CIPHER,function,131,EVP_AEAD_CTX_init_with_direction
-CIPHER,function,101,EVP_AEAD_CTX_open
-CIPHER,function,102,EVP_AEAD_CTX_seal
-CIPHER,function,103,EVP_CIPHER_CTX_copy
-CIPHER,function,104,EVP_CIPHER_CTX_ctrl
-CIPHER,function,105,EVP_CIPHER_CTX_set_key_length
-CIPHER,function,106,EVP_CipherInit_ex
-CIPHER,function,107,EVP_DecryptFinal_ex
-CIPHER,function,108,EVP_EncryptFinal_ex
-CIPHER,function,132,aead_aes_ctr_hmac_sha256_init
-CIPHER,function,133,aead_aes_ctr_hmac_sha256_open
-CIPHER,function,134,aead_aes_ctr_hmac_sha256_seal
-CIPHER,function,109,aead_aes_gcm_init
-CIPHER,function,110,aead_aes_gcm_open
-CIPHER,function,111,aead_aes_gcm_seal
-CIPHER,function,112,aead_aes_key_wrap_init
-CIPHER,function,113,aead_aes_key_wrap_open
-CIPHER,function,114,aead_aes_key_wrap_seal
-CIPHER,function,115,aead_chacha20_poly1305_init
-CIPHER,function,116,aead_chacha20_poly1305_open
-CIPHER,function,117,aead_chacha20_poly1305_seal
-CIPHER,function,118,aead_rc4_md5_tls_init
-CIPHER,function,119,aead_rc4_md5_tls_open
-CIPHER,function,120,aead_rc4_md5_tls_seal
-CIPHER,function,121,aead_ssl3_ensure_cipher_init
-CIPHER,function,122,aead_ssl3_init
-CIPHER,function,123,aead_ssl3_open
-CIPHER,function,124,aead_ssl3_seal
-CIPHER,function,125,aead_tls_ensure_cipher_init
-CIPHER,function,126,aead_tls_init
-CIPHER,function,127,aead_tls_open
-CIPHER,function,128,aead_tls_seal
-CIPHER,function,129,aes_init_key
-CIPHER,function,130,aesni_init_key
-CIPHER,reason,100,AES_KEY_SETUP_FAILED
-CIPHER,reason,101,BAD_DECRYPT
-CIPHER,reason,102,BAD_KEY_LENGTH
-CIPHER,reason,103,BUFFER_TOO_SMALL
-CIPHER,reason,104,CTRL_NOT_IMPLEMENTED
-CIPHER,reason,105,CTRL_OPERATION_NOT_IMPLEMENTED
-CIPHER,reason,106,DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH
-CIPHER,reason,107,INITIALIZATION_ERROR
-CIPHER,reason,108,INPUT_NOT_INITIALIZED
-CIPHER,reason,109,INVALID_AD_SIZE
-CIPHER,reason,110,INVALID_KEY_LENGTH
-CIPHER,reason,111,INVALID_NONCE_SIZE
-CIPHER,reason,112,INVALID_OPERATION
-CIPHER,reason,113,IV_TOO_LARGE
-CIPHER,reason,114,NO_CIPHER_SET
-CIPHER,reason,124,NO_DIRECTION_SET
-CIPHER,reason,115,OUTPUT_ALIASES_INPUT
-CIPHER,reason,116,TAG_TOO_LARGE
-CIPHER,reason,117,TOO_LARGE
-CIPHER,reason,118,UNSUPPORTED_AD_SIZE
-CIPHER,reason,119,UNSUPPORTED_INPUT_SIZE
-CIPHER,reason,120,UNSUPPORTED_KEY_SIZE
-CIPHER,reason,121,UNSUPPORTED_NONCE_SIZE
-CIPHER,reason,122,UNSUPPORTED_TAG_SIZE
-CIPHER,reason,123,WRONG_FINAL_BLOCK_LENGTH
+CIPHER,100,AES_KEY_SETUP_FAILED
+CIPHER,101,BAD_DECRYPT
+CIPHER,102,BAD_KEY_LENGTH
+CIPHER,103,BUFFER_TOO_SMALL
+CIPHER,104,CTRL_NOT_IMPLEMENTED
+CIPHER,105,CTRL_OPERATION_NOT_IMPLEMENTED
+CIPHER,106,DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH
+CIPHER,107,INITIALIZATION_ERROR
+CIPHER,108,INPUT_NOT_INITIALIZED
+CIPHER,109,INVALID_AD_SIZE
+CIPHER,110,INVALID_KEY_LENGTH
+CIPHER,111,INVALID_NONCE_SIZE
+CIPHER,112,INVALID_OPERATION
+CIPHER,113,IV_TOO_LARGE
+CIPHER,114,NO_CIPHER_SET
+CIPHER,124,NO_DIRECTION_SET
+CIPHER,115,OUTPUT_ALIASES_INPUT
+CIPHER,116,TAG_TOO_LARGE
+CIPHER,117,TOO_LARGE
+CIPHER,118,UNSUPPORTED_AD_SIZE
+CIPHER,119,UNSUPPORTED_INPUT_SIZE
+CIPHER,120,UNSUPPORTED_KEY_SIZE
+CIPHER,121,UNSUPPORTED_NONCE_SIZE
+CIPHER,122,UNSUPPORTED_TAG_SIZE
+CIPHER,123,WRONG_FINAL_BLOCK_LENGTH
diff --git a/src/crypto/err/conf.errordata b/src/crypto/err/conf.errordata
index 0b96a32..651fabe 100644
--- a/src/crypto/err/conf.errordata
+++ b/src/crypto/err/conf.errordata
@@ -1,10 +1,6 @@
-CONF,function,100,CONF_parse_list
-CONF,function,101,NCONF_load
-CONF,function,102,def_load_bio
-CONF,function,103,str_copy
-CONF,reason,100,LIST_CANNOT_BE_NULL
-CONF,reason,101,MISSING_CLOSE_SQUARE_BRACKET
-CONF,reason,102,MISSING_EQUAL_SIGN
-CONF,reason,103,NO_CLOSE_BRACE
-CONF,reason,104,UNABLE_TO_CREATE_NEW_SECTION
-CONF,reason,105,VARIABLE_HAS_NO_VALUE
+CONF,100,LIST_CANNOT_BE_NULL
+CONF,101,MISSING_CLOSE_SQUARE_BRACKET
+CONF,102,MISSING_EQUAL_SIGN
+CONF,103,NO_CLOSE_BRACE
+CONF,104,UNABLE_TO_CREATE_NEW_SECTION
+CONF,105,VARIABLE_HAS_NO_VALUE
diff --git a/src/crypto/err/crypto.errordata b/src/crypto/err/crypto.errordata
deleted file mode 100644
index 1e0e9d5..0000000
--- a/src/crypto/err/crypto.errordata
+++ /dev/null
@@ -1,4 +0,0 @@
-CRYPTO,function,100,CRYPTO_get_ex_new_index
-CRYPTO,function,101,CRYPTO_set_ex_data
-CRYPTO,function,102,get_class
-CRYPTO,function,103,get_func_pointers
diff --git a/src/crypto/err/dh.errordata b/src/crypto/err/dh.errordata
index 1fd675b..571e218 100644
--- a/src/crypto/err/dh.errordata
+++ b/src/crypto/err/dh.errordata
@@ -1,8 +1,4 @@
-DH,function,100,DH_new_method
-DH,function,101,compute_key
-DH,function,102,generate_key
-DH,function,103,generate_parameters
-DH,reason,100,BAD_GENERATOR
-DH,reason,101,INVALID_PUBKEY
-DH,reason,102,MODULUS_TOO_LARGE
-DH,reason,103,NO_PRIVATE_VALUE
+DH,100,BAD_GENERATOR
+DH,101,INVALID_PUBKEY
+DH,102,MODULUS_TOO_LARGE
+DH,103,NO_PRIVATE_VALUE
diff --git a/src/crypto/err/digest.errordata b/src/crypto/err/digest.errordata
index 95a3622..411e778 100644
--- a/src/crypto/err/digest.errordata
+++ b/src/crypto/err/digest.errordata
@@ -1,3 +1 @@
-DIGEST,function,100,EVP_DigestInit_ex
-DIGEST,function,101,EVP_MD_CTX_copy_ex
-DIGEST,reason,100,INPUT_NOT_INITIALIZED
+DIGEST,100,INPUT_NOT_INITIALIZED
diff --git a/src/crypto/err/dsa.errordata b/src/crypto/err/dsa.errordata
index c2dff23..3c5764a 100644
--- a/src/crypto/err/dsa.errordata
+++ b/src/crypto/err/dsa.errordata
@@ -1,9 +1,4 @@
-DSA,function,100,DSA_new_method
-DSA,function,101,dsa_sig_cb
-DSA,function,102,sign
-DSA,function,103,sign_setup
-DSA,function,104,verify
-DSA,reason,100,BAD_Q_VALUE
-DSA,reason,101,MISSING_PARAMETERS
-DSA,reason,102,MODULUS_TOO_LARGE
-DSA,reason,103,NEED_NEW_SETUP_VALUES
+DSA,100,BAD_Q_VALUE
+DSA,101,MISSING_PARAMETERS
+DSA,102,MODULUS_TOO_LARGE
+DSA,103,NEED_NEW_SETUP_VALUES
diff --git a/src/crypto/err/ec.errordata b/src/crypto/err/ec.errordata
index 252f7ab..e7b4175 100644
--- a/src/crypto/err/ec.errordata
+++ b/src/crypto/err/ec.errordata
@@ -1,95 +1,28 @@
-EC,function,159,BN_to_felem
-EC,function,100,EC_GROUP_copy
-EC,function,101,EC_GROUP_get_curve_GFp
-EC,function,102,EC_GROUP_get_degree
-EC,function,103,EC_GROUP_new_by_curve_name
-EC,function,166,EC_GROUP_new_curve_GFp
-EC,function,104,EC_KEY_check_key
-EC,function,105,EC_KEY_copy
-EC,function,106,EC_KEY_generate_key
-EC,function,165,EC_KEY_new_by_curve_name
-EC,function,107,EC_KEY_new_method
-EC,function,108,EC_KEY_set_public_key_affine_coordinates
-EC,function,109,EC_POINT_add
-EC,function,110,EC_POINT_cmp
-EC,function,111,EC_POINT_copy
-EC,function,112,EC_POINT_dbl
-EC,function,113,EC_POINT_dup
-EC,function,114,EC_POINT_get_affine_coordinates_GFp
-EC,function,115,EC_POINT_invert
-EC,function,116,EC_POINT_is_at_infinity
-EC,function,117,EC_POINT_is_on_curve
-EC,function,118,EC_POINT_make_affine
-EC,function,119,EC_POINT_new
-EC,function,120,EC_POINT_oct2point
-EC,function,121,EC_POINT_point2oct
-EC,function,122,EC_POINT_set_affine_coordinates_GFp
-EC,function,123,EC_POINT_set_compressed_coordinates_GFp
-EC,function,124,EC_POINT_set_to_infinity
-EC,function,125,EC_POINTs_make_affine
-EC,function,126,compute_wNAF
-EC,function,127,d2i_ECPKParameters
-EC,function,128,d2i_ECParameters
-EC,function,129,d2i_ECPrivateKey
-EC,function,130,ec_GFp_mont_field_decode
-EC,function,131,ec_GFp_mont_field_encode
-EC,function,132,ec_GFp_mont_field_mul
-EC,function,133,ec_GFp_mont_field_set_to_one
-EC,function,134,ec_GFp_mont_field_sqr
-EC,function,135,ec_GFp_mont_group_set_curve
-EC,function,160,ec_GFp_nistp256_group_set_curve
-EC,function,161,ec_GFp_nistp256_point_get_affine_coordinates
-EC,function,162,ec_GFp_nistp256_points_mul
-EC,function,136,ec_GFp_simple_group_check_discriminant
-EC,function,137,ec_GFp_simple_group_set_curve
-EC,function,138,ec_GFp_simple_make_affine
-EC,function,139,ec_GFp_simple_oct2point
-EC,function,140,ec_GFp_simple_point2oct
-EC,function,141,ec_GFp_simple_point_get_affine_coordinates
-EC,function,142,ec_GFp_simple_point_set_affine_coordinates
-EC,function,143,ec_GFp_simple_points_make_affine
-EC,function,144,ec_GFp_simple_set_compressed_coordinates
-EC,function,145,ec_asn1_group2pkparameters
-EC,function,146,ec_asn1_pkparameters2group
-EC,function,163,ec_group_copy
-EC,function,147,ec_group_new
-EC,function,148,ec_group_new_curve_GFp
-EC,function,149,ec_group_new_from_data
-EC,function,150,ec_point_set_Jprojective_coordinates_GFp
-EC,function,151,ec_pre_comp_new
-EC,function,152,ec_wNAF_mul
-EC,function,153,ec_wNAF_precompute_mult
-EC,function,154,i2d_ECPKParameters
-EC,function,155,i2d_ECParameters
-EC,function,156,i2d_ECPrivateKey
-EC,function,157,i2o_ECPublicKey
-EC,function,164,nistp256_pre_comp_new
-EC,function,158,o2i_ECPublicKey
-EC,reason,126,BIGNUM_OUT_OF_RANGE
-EC,reason,100,BUFFER_TOO_SMALL
-EC,reason,101,COORDINATES_OUT_OF_RANGE
-EC,reason,102,D2I_ECPKPARAMETERS_FAILURE
-EC,reason,103,EC_GROUP_NEW_BY_NAME_FAILURE
-EC,reason,104,GROUP2PKPARAMETERS_FAILURE
-EC,reason,105,I2D_ECPKPARAMETERS_FAILURE
-EC,reason,106,INCOMPATIBLE_OBJECTS
-EC,reason,107,INVALID_COMPRESSED_POINT
-EC,reason,108,INVALID_COMPRESSION_BIT
-EC,reason,109,INVALID_ENCODING
-EC,reason,110,INVALID_FIELD
-EC,reason,111,INVALID_FORM
-EC,reason,112,INVALID_GROUP_ORDER
-EC,reason,113,INVALID_PRIVATE_KEY
-EC,reason,114,MISSING_PARAMETERS
-EC,reason,115,MISSING_PRIVATE_KEY
-EC,reason,116,NON_NAMED_CURVE
-EC,reason,117,NOT_INITIALIZED
-EC,reason,118,PKPARAMETERS2GROUP_FAILURE
-EC,reason,119,POINT_AT_INFINITY
-EC,reason,120,POINT_IS_NOT_ON_CURVE
-EC,reason,121,SLOT_FULL
-EC,reason,122,UNDEFINED_GENERATOR
-EC,reason,123,UNKNOWN_GROUP
-EC,reason,124,UNKNOWN_ORDER
-EC,reason,127,WRONG_CURVE_PARAMETERS
-EC,reason,125,WRONG_ORDER
+EC,126,BIGNUM_OUT_OF_RANGE
+EC,100,BUFFER_TOO_SMALL
+EC,101,COORDINATES_OUT_OF_RANGE
+EC,102,D2I_ECPKPARAMETERS_FAILURE
+EC,103,EC_GROUP_NEW_BY_NAME_FAILURE
+EC,104,GROUP2PKPARAMETERS_FAILURE
+EC,105,I2D_ECPKPARAMETERS_FAILURE
+EC,106,INCOMPATIBLE_OBJECTS
+EC,107,INVALID_COMPRESSED_POINT
+EC,108,INVALID_COMPRESSION_BIT
+EC,109,INVALID_ENCODING
+EC,110,INVALID_FIELD
+EC,111,INVALID_FORM
+EC,112,INVALID_GROUP_ORDER
+EC,113,INVALID_PRIVATE_KEY
+EC,114,MISSING_PARAMETERS
+EC,115,MISSING_PRIVATE_KEY
+EC,116,NON_NAMED_CURVE
+EC,117,NOT_INITIALIZED
+EC,118,PKPARAMETERS2GROUP_FAILURE
+EC,119,POINT_AT_INFINITY
+EC,120,POINT_IS_NOT_ON_CURVE
+EC,121,SLOT_FULL
+EC,122,UNDEFINED_GENERATOR
+EC,123,UNKNOWN_GROUP
+EC,124,UNKNOWN_ORDER
+EC,127,WRONG_CURVE_PARAMETERS
+EC,125,WRONG_ORDER
diff --git a/src/crypto/err/ecdh.errordata b/src/crypto/err/ecdh.errordata
index 0f1215e..f714c30 100644
--- a/src/crypto/err/ecdh.errordata
+++ b/src/crypto/err/ecdh.errordata
@@ -1,4 +1,3 @@
-ECDH,function,100,ECDH_compute_key
-ECDH,reason,100,KDF_FAILED
-ECDH,reason,101,NO_PRIVATE_VALUE
-ECDH,reason,102,POINT_ARITHMETIC_FAILURE
+ECDH,100,KDF_FAILED
+ECDH,101,NO_PRIVATE_VALUE
+ECDH,102,POINT_ARITHMETIC_FAILURE
diff --git a/src/crypto/err/ecdsa.errordata b/src/crypto/err/ecdsa.errordata
index 97c213e..58ba591 100644
--- a/src/crypto/err/ecdsa.errordata
+++ b/src/crypto/err/ecdsa.errordata
@@ -1,10 +1,6 @@
-ECDSA,function,100,ECDSA_do_sign_ex
-ECDSA,function,101,ECDSA_do_verify
-ECDSA,function,102,ECDSA_sign_ex
-ECDSA,function,103,digest_to_bn
-ECDSA,function,104,ecdsa_sign_setup
-ECDSA,reason,100,BAD_SIGNATURE
-ECDSA,reason,101,MISSING_PARAMETERS
-ECDSA,reason,102,NEED_NEW_SETUP_VALUES
-ECDSA,reason,103,NOT_IMPLEMENTED
-ECDSA,reason,104,RANDOM_NUMBER_GENERATION_FAILED
+ECDSA,100,BAD_SIGNATURE
+ECDSA,105,ENCODE_ERROR
+ECDSA,101,MISSING_PARAMETERS
+ECDSA,102,NEED_NEW_SETUP_VALUES
+ECDSA,103,NOT_IMPLEMENTED
+ECDSA,104,RANDOM_NUMBER_GENERATION_FAILED
diff --git a/src/crypto/err/engine.errordata b/src/crypto/err/engine.errordata
index 1185e88..edbd7b9 100644
--- a/src/crypto/err/engine.errordata
+++ b/src/crypto/err/engine.errordata
@@ -1 +1 @@
-ENGINE,reason,100,OPERATION_NOT_SUPPORTED
+ENGINE,100,OPERATION_NOT_SUPPORTED
diff --git a/src/crypto/err/err.c b/src/crypto/err/err.c
index de1b4a7..9221bf1 100644
--- a/src/crypto/err/err.c
+++ b/src/crypto/err/err.c
@@ -125,10 +125,6 @@
#include "../internal.h"
-extern const uint32_t kOpenSSLFunctionValues[];
-extern const size_t kOpenSSLFunctionValuesLen;
-extern const char kOpenSSLFunctionStringData[];
-
extern const uint32_t kOpenSSLReasonValues[];
extern const size_t kOpenSSLReasonValuesLen;
extern const char kOpenSSLReasonStringData[];
@@ -259,42 +255,43 @@ static uint32_t get_error_values(int inc, int top, const char **file, int *line,
}
uint32_t ERR_get_error(void) {
- return get_error_values(1, 0, NULL, NULL, NULL, NULL);
+ return get_error_values(1 /* inc */, 0 /* bottom */, NULL, NULL, NULL, NULL);
}
uint32_t ERR_get_error_line(const char **file, int *line) {
- return get_error_values(1, 0, file, line, NULL, NULL);
+ return get_error_values(1 /* inc */, 0 /* bottom */, file, line, NULL, NULL);
}
uint32_t ERR_get_error_line_data(const char **file, int *line,
const char **data, int *flags) {
- return get_error_values(1, 0, file, line, data, flags);
+ return get_error_values(1 /* inc */, 0 /* bottom */, file, line, data, flags);
}
uint32_t ERR_peek_error(void) {
- return get_error_values(0, 0, NULL, NULL, NULL, NULL);
+ return get_error_values(0 /* peek */, 0 /* bottom */, NULL, NULL, NULL, NULL);
}
uint32_t ERR_peek_error_line(const char **file, int *line) {
- return get_error_values(0, 0, file, line, NULL, NULL);
+ return get_error_values(0 /* peek */, 0 /* bottom */, file, line, NULL, NULL);
}
uint32_t ERR_peek_error_line_data(const char **file, int *line,
const char **data, int *flags) {
- return get_error_values(0, 0, file, line, data, flags);
+ return get_error_values(0 /* peek */, 0 /* bottom */, file, line, data,
+ flags);
}
uint32_t ERR_peek_last_error(void) {
- return get_error_values(0, 1, NULL, NULL, NULL, NULL);
+ return get_error_values(0 /* peek */, 1 /* top */, NULL, NULL, NULL, NULL);
}
uint32_t ERR_peek_last_error_line(const char **file, int *line) {
- return get_error_values(0, 1, file, line, NULL, NULL);
+ return get_error_values(0 /* peek */, 1 /* top */, file, line, NULL, NULL);
}
uint32_t ERR_peek_last_error_line_data(const char **file, int *line,
const char **data, int *flags) {
- return get_error_values(0, 1, file, line, data, flags);
+ return get_error_values(0 /* peek */, 1 /* top */, file, line, data, flags);
}
void ERR_clear_error(void) {
@@ -361,20 +358,18 @@ char *ERR_error_string(uint32_t packed_error, char *ret) {
}
void ERR_error_string_n(uint32_t packed_error, char *buf, size_t len) {
- char lib_buf[64], func_buf[64], reason_buf[64];
- const char *lib_str, *func_str, *reason_str;
- unsigned lib, func, reason;
+ char lib_buf[64], reason_buf[64];
+ const char *lib_str, *reason_str;
+ unsigned lib, reason;
if (len == 0) {
return;
}
lib = ERR_GET_LIB(packed_error);
- func = ERR_GET_FUNC(packed_error);
reason = ERR_GET_REASON(packed_error);
lib_str = ERR_lib_error_string(packed_error);
- func_str = ERR_func_error_string(packed_error);
reason_str = ERR_reason_error_string(packed_error);
if (lib_str == NULL) {
@@ -382,18 +377,13 @@ void ERR_error_string_n(uint32_t packed_error, char *buf, size_t len) {
lib_str = lib_buf;
}
- if (func_str == NULL) {
- BIO_snprintf(func_buf, sizeof(func_buf), "func(%u)", func);
- func_str = func_buf;
- }
-
- if (reason_str == NULL) {
+ if (reason_str == NULL) {
BIO_snprintf(reason_buf, sizeof(reason_buf), "reason(%u)", reason);
reason_str = reason_buf;
}
- BIO_snprintf(buf, len, "error:%08" PRIx32 ":%s:%s:%s",
- packed_error, lib_str, func_str, reason_str);
+ BIO_snprintf(buf, len, "error:%08" PRIx32 ":%s:OPENSSL_internal:%s",
+ packed_error, lib_str, reason_str);
if (strlen(buf) == len - 1) {
/* output may be truncated; make sure we always have 5 colon-separated
@@ -454,7 +444,7 @@ static const char *err_string_lookup(uint32_t lib, uint32_t key,
* |6 bits| 11 bits | 15 bits |
*
* The |lib| value is a library identifier: one of the |ERR_LIB_*| values.
- * The |key| is either a function or a reason code, depending on the context.
+ * The |key| is a reason code, depending on the context.
* The |offset| is the number of bytes from the start of |string_data| where
* the (NUL terminated) string for this value can be found.
*
@@ -505,8 +495,8 @@ static const char *const kLibraryNames[ERR_NUM_LIBS] = {
"HMAC routines", /* ERR_LIB_HMAC */
"Digest functions", /* ERR_LIB_DIGEST */
"Cipher functions", /* ERR_LIB_CIPHER */
- "User defined functions", /* ERR_LIB_USER */
"HKDF functions", /* ERR_LIB_HKDF */
+ "User defined functions", /* ERR_LIB_USER */
};
const char *ERR_lib_error_string(uint32_t packed_error) {
@@ -519,36 +509,7 @@ const char *ERR_lib_error_string(uint32_t packed_error) {
}
const char *ERR_func_error_string(uint32_t packed_error) {
- const uint32_t lib = ERR_GET_LIB(packed_error);
- const uint32_t func = ERR_GET_FUNC(packed_error);
-
- if (lib == ERR_LIB_SYS) {
- switch (func) {
- case SYS_F_fopen:
- return "fopen";
- case SYS_F_fclose:
- return "fclose";
- case SYS_F_fread:
- return "fread";
- case SYS_F_fwrite:
- return "fwrite";
- case SYS_F_socket:
- return "socket";
- case SYS_F_setsockopt:
- return "setsockopt";
- case SYS_F_connect:
- return "connect";
- case SYS_F_getaddrinfo:
- return "getaddrinfo";
- default:
- return NULL;
- }
- }
-
- return err_string_lookup(ERR_GET_LIB(packed_error),
- ERR_GET_FUNC(packed_error), kOpenSSLFunctionValues,
- kOpenSSLFunctionValuesLen,
- kOpenSSLFunctionStringData);
+ return "OPENSSL_internal";
}
const char *ERR_reason_error_string(uint32_t packed_error) {
@@ -644,7 +605,7 @@ static void err_set_error_data(char *data, int flags) {
error->flags = flags;
}
-void ERR_put_error(int library, int func, int reason, const char *file,
+void ERR_put_error(int library, int unused, int reason, const char *file,
unsigned line) {
ERR_STATE *const state = err_get_state();
struct err_error_st *error;
@@ -654,7 +615,7 @@ void ERR_put_error(int library, int func, int reason, const char *file,
}
if (library == ERR_LIB_SYS && reason == 0) {
-#if defined(WIN32)
+#if defined(OPENSSL_WINDOWS)
reason = GetLastError();
#else
reason = errno;
@@ -670,7 +631,7 @@ void ERR_put_error(int library, int func, int reason, const char *file,
err_clear(error);
error->file = file;
error->line = line;
- error->packed = ERR_PACK(library, func, reason);
+ error->packed = ERR_PACK(library, reason);
}
/* ERR_add_error_data_vdata takes a variable number of const char* pointers,
diff --git a/src/crypto/err/err_data_generate.go b/src/crypto/err/err_data_generate.go
index a5b4cb5..24e0d66 100644
--- a/src/crypto/err/err_data_generate.go
+++ b/src/crypto/err/err_data_generate.go
@@ -59,8 +59,8 @@ var libraryNames = []string{
"HMAC",
"DIGEST",
"CIPHER",
- "USER",
"HKDF",
+ "USER",
}
// stringList is a map from uint32 -> string which can output data for a sorted
@@ -69,7 +69,7 @@ type stringList struct {
// entries is an array of keys and offsets into |stringData|. The
// offsets are in the bottom 15 bits of each uint32 and the key is the
// top 17 bits.
- entries []uint32
+ entries []uint32
// internedStrings contains the same strings as are in |stringData|,
// but allows for easy deduplication. It maps a string to its offset in
// |stringData|.
@@ -146,7 +146,7 @@ func (st *stringList) WriteTo(out stringWriter, name string) {
fmt.Fprintf(out, " 0x%x,\n", v)
}
out.WriteString("};\n\n")
- out.WriteString("const size_t " + values + "Len = sizeof(" + values + ") / sizeof(" + values + "[0]);\n\n");
+ out.WriteString("const size_t " + values + "Len = sizeof(" + values + ") / sizeof(" + values + "[0]);\n\n")
stringData := "kOpenSSL" + name + "StringData"
out.WriteString("const char " + stringData + "[] =\n \"")
@@ -161,8 +161,8 @@ func (st *stringList) WriteTo(out stringWriter, name string) {
}
type errorData struct {
- functions, reasons *stringList
- libraryMap map[string]uint32
+ reasons *stringList
+ libraryMap map[string]uint32
}
func (e *errorData) readErrorDataFile(filename string) error {
@@ -184,8 +184,8 @@ func (e *errorData) readErrorDataFile(filename string) error {
continue
}
parts := bytes.Split(line, comma)
- if len(parts) != 4 {
- return fmt.Errorf("bad line %d in %s: found %d values but want 4", lineNo, filename, len(parts))
+ if len(parts) != 3 {
+ return fmt.Errorf("bad line %d in %s: found %d values but want 3", lineNo, filename, len(parts))
}
libNum, ok := e.libraryMap[string(parts[0])]
if !ok {
@@ -194,26 +194,18 @@ func (e *errorData) readErrorDataFile(filename string) error {
if libNum >= 64 {
return fmt.Errorf("bad line %d in %s: library value too large", lineNo, filename)
}
- key, err := strconv.ParseUint(string(parts[2]), 10 /* base */, 32 /* bit size */)
+ key, err := strconv.ParseUint(string(parts[1]), 10 /* base */, 32 /* bit size */)
if err != nil {
return fmt.Errorf("bad line %d in %s: %s", lineNo, filename, err)
}
if key >= 2048 {
return fmt.Errorf("bad line %d in %s: key too large", lineNo, filename)
}
- value := string(parts[3])
+ value := string(parts[2])
listKey := libNum<<26 | uint32(key)<<15
- switch string(parts[1]) {
- case "function":
- err = e.functions.Add(listKey, value)
- case "reason":
- err = e.reasons.Add(listKey, value)
- default:
- return fmt.Errorf("bad line %d in %s: bad value type", lineNo, filename)
- }
-
+ err = e.reasons.Add(listKey, value)
if err != nil {
return err
}
@@ -224,7 +216,6 @@ func (e *errorData) readErrorDataFile(filename string) error {
func main() {
e := &errorData{
- functions: newStringList(),
reasons: newStringList(),
libraryMap: make(map[string]uint32),
}
@@ -279,9 +270,8 @@ func main() {
for i, name := range libraryNames {
fmt.Fprintf(out, "OPENSSL_COMPILE_ASSERT(ERR_LIB_%s == %d, library_values_changed_%d);\n", name, i+1, i+1)
}
- fmt.Fprintf(out, "OPENSSL_COMPILE_ASSERT(ERR_NUM_LIBS == %d, library_values_changed_num);\n", len(libraryNames) + 1)
+ fmt.Fprintf(out, "OPENSSL_COMPILE_ASSERT(ERR_NUM_LIBS == %d, library_values_changed_num);\n", len(libraryNames)+1)
out.WriteString("\n")
- e.functions.WriteTo(out, "Function")
e.reasons.WriteTo(out, "Reason")
}
diff --git a/src/crypto/err/err_test.cc b/src/crypto/err/err_test.cc
index 98dfb85..d691355 100644
--- a/src/crypto/err/err_test.cc
+++ b/src/crypto/err/err_test.cc
@@ -22,7 +22,7 @@
static bool TestOverflow() {
for (unsigned i = 0; i < ERR_NUM_ERRORS*2; i++) {
- ERR_put_error(1, 2, i+1, "test", 1);
+ ERR_put_error(1, 0 /* unused */, i+1, "test", 1);
}
for (unsigned i = 0; i < ERR_NUM_ERRORS - 1; i++) {
@@ -30,7 +30,7 @@ static bool TestOverflow() {
/* Errors are returned in order they were pushed, with the least recent ones
* removed, up to |ERR_NUM_ERRORS - 1| errors. So the errors returned are
* |ERR_NUM_ERRORS + 2| through |ERR_NUM_ERRORS * 2|, inclusive. */
- if (err == 0 || ERR_GET_REASON(err) != i + ERR_NUM_ERRORS + 2) {
+ if (err == 0 || ((unsigned)ERR_GET_REASON(err)) != i + ERR_NUM_ERRORS + 2) {
fprintf(stderr, "ERR_get_error failed at %u\n", i);
return false;
}
@@ -50,7 +50,7 @@ static bool TestPutError() {
return false;
}
- ERR_put_error(1, 2, 3, "test", 4);
+ ERR_put_error(1, 0 /* unused */, 2, "test", 4);
ERR_add_error_data(1, "testing");
int peeked_line, line, peeked_flags, flags;
@@ -72,8 +72,7 @@ static bool TestPutError() {
line != 4 ||
(flags & ERR_FLAG_STRING) == 0 ||
ERR_GET_LIB(packed_error) != 1 ||
- ERR_GET_FUNC(packed_error) != 2 ||
- ERR_GET_REASON(packed_error) != 3 ||
+ ERR_GET_REASON(packed_error) != 2 ||
strcmp(data, "testing") != 0) {
fprintf(stderr, "Bad error data returned.\n");
return false;
@@ -88,7 +87,7 @@ static bool TestClearError() {
return false;
}
- ERR_put_error(1, 2, 3, "test", 4);
+ ERR_put_error(1, 0 /* unused */, 2, "test", 4);
ERR_clear_error();
if (ERR_get_error() != 0) {
@@ -100,7 +99,7 @@ static bool TestClearError() {
}
static bool TestPrint() {
- ERR_put_error(1, 2, 3, "test", 4);
+ ERR_put_error(1, 0 /* unused */, 2, "test", 4);
ERR_add_error_data(1, "testing");
uint32_t packed_error = ERR_get_error();
@@ -113,11 +112,39 @@ static bool TestPrint() {
}
static bool TestRelease() {
- ERR_put_error(1, 2, 3, "test", 4);
+ ERR_put_error(1, 0 /* unused */, 2, "test", 4);
ERR_remove_thread_state(NULL);
return true;
}
+static bool HasSuffix(const char *str, const char *suffix) {
+ size_t suffix_len = strlen(suffix);
+ size_t str_len = strlen(str);
+ if (str_len < suffix_len) {
+ return false;
+ }
+ return strcmp(str + str_len - suffix_len, suffix) == 0;
+}
+
+static bool TestPutMacro() {
+ int expected_line = __LINE__ + 1;
+ OPENSSL_PUT_ERROR(USER, ERR_R_INTERNAL_ERROR);
+
+ int line;
+ const char *file;
+ uint32_t error = ERR_get_error_line(&file, &line);
+
+ if (!HasSuffix(file, "err_test.cc") ||
+ line != expected_line ||
+ ERR_GET_LIB(error) != ERR_LIB_USER ||
+ ERR_GET_REASON(error) != ERR_R_INTERNAL_ERROR) {
+ fprintf(stderr, "Bad error data returned.\n");
+ return false;
+ }
+
+ return true;
+}
+
int main() {
CRYPTO_library_init();
@@ -125,7 +152,8 @@ int main() {
!TestPutError() ||
!TestClearError() ||
!TestPrint() ||
- !TestRelease()) {
+ !TestRelease() ||
+ !TestPutMacro()) {
return 1;
}
diff --git a/src/crypto/err/evp.errordata b/src/crypto/err/evp.errordata
index 14dd27b..8f8dd48 100644
--- a/src/crypto/err/evp.errordata
+++ b/src/crypto/err/evp.errordata
@@ -1,114 +1,46 @@
-EVP,function,160,EVP_DigestSignAlgorithm
-EVP,function,161,EVP_DigestVerifyInitFromAlgorithm
-EVP,function,162,EVP_PKEY_CTX_ctrl
-EVP,function,163,EVP_PKEY_CTX_dup
-EVP,function,159,EVP_PKEY_CTX_get0_rsa_oaep_label
-EVP,function,164,EVP_PKEY_copy_parameters
-EVP,function,165,EVP_PKEY_decrypt
-EVP,function,166,EVP_PKEY_decrypt_init
-EVP,function,167,EVP_PKEY_derive
-EVP,function,108,EVP_PKEY_derive_init
-EVP,function,168,EVP_PKEY_derive_set_peer
-EVP,function,110,EVP_PKEY_encrypt
-EVP,function,111,EVP_PKEY_encrypt_init
-EVP,function,112,EVP_PKEY_get1_DH
-EVP,function,169,EVP_PKEY_get1_DSA
-EVP,function,114,EVP_PKEY_get1_EC_KEY
-EVP,function,115,EVP_PKEY_get1_RSA
-EVP,function,116,EVP_PKEY_keygen
-EVP,function,170,EVP_PKEY_keygen_init
-EVP,function,171,EVP_PKEY_new
-EVP,function,172,EVP_PKEY_set_type
-EVP,function,120,EVP_PKEY_sign
-EVP,function,121,EVP_PKEY_sign_init
-EVP,function,122,EVP_PKEY_verify
-EVP,function,123,EVP_PKEY_verify_init
-EVP,function,173,check_padding_md
-EVP,function,125,d2i_AutoPrivateKey
-EVP,function,126,d2i_PrivateKey
-EVP,function,127,do_EC_KEY_print
-EVP,function,174,do_dsa_print
-EVP,function,175,do_rsa_print
-EVP,function,129,do_sigver_init
-EVP,function,176,dsa_param_decode
-EVP,function,177,dsa_priv_decode
-EVP,function,178,dsa_priv_encode
-EVP,function,179,dsa_pub_decode
-EVP,function,180,dsa_pub_encode
-EVP,function,181,dsa_sig_print
-EVP,function,130,eckey_param2type
-EVP,function,131,eckey_param_decode
-EVP,function,132,eckey_priv_decode
-EVP,function,133,eckey_priv_encode
-EVP,function,134,eckey_pub_decode
-EVP,function,135,eckey_pub_encode
-EVP,function,136,eckey_type2param
-EVP,function,137,evp_pkey_ctx_new
-EVP,function,138,hmac_signctx
-EVP,function,139,i2d_PublicKey
-EVP,function,182,old_dsa_priv_decode
-EVP,function,140,old_ec_priv_decode
-EVP,function,141,old_rsa_priv_decode
-EVP,function,142,pkey_ec_ctrl
-EVP,function,143,pkey_ec_derive
-EVP,function,144,pkey_ec_keygen
-EVP,function,145,pkey_ec_paramgen
-EVP,function,146,pkey_ec_sign
-EVP,function,158,pkey_hmac_ctrl
-EVP,function,147,pkey_rsa_ctrl
-EVP,function,148,pkey_rsa_decrypt
-EVP,function,149,pkey_rsa_encrypt
-EVP,function,150,pkey_rsa_sign
-EVP,function,151,rsa_algor_to_md
-EVP,function,152,rsa_digest_verify_init_from_algorithm
-EVP,function,153,rsa_mgf1_to_md
-EVP,function,154,rsa_priv_decode
-EVP,function,155,rsa_priv_encode
-EVP,function,156,rsa_pss_to_ctx
-EVP,function,157,rsa_pub_decode
-EVP,reason,151,BN_DECODE_ERROR
-EVP,reason,100,BUFFER_TOO_SMALL
-EVP,reason,101,COMMAND_NOT_SUPPORTED
-EVP,reason,146,CONTEXT_NOT_INITIALISED
-EVP,reason,143,DECODE_ERROR
-EVP,reason,104,DIFFERENT_KEY_TYPES
-EVP,reason,105,DIFFERENT_PARAMETERS
-EVP,reason,147,DIGEST_AND_KEY_TYPE_NOT_SUPPORTED
-EVP,reason,107,EXPECTING_AN_EC_KEY_KEY
-EVP,reason,141,EXPECTING_AN_RSA_KEY
-EVP,reason,109,EXPECTING_A_DH_KEY
-EVP,reason,110,EXPECTING_A_DSA_KEY
-EVP,reason,111,ILLEGAL_OR_UNSUPPORTED_PADDING_MODE
-EVP,reason,112,INVALID_CURVE
-EVP,reason,113,INVALID_DIGEST_LENGTH
-EVP,reason,114,INVALID_DIGEST_TYPE
-EVP,reason,115,INVALID_KEYBITS
-EVP,reason,116,INVALID_MGF1_MD
-EVP,reason,142,INVALID_OPERATION
-EVP,reason,118,INVALID_PADDING_MODE
-EVP,reason,119,INVALID_PSS_PARAMETERS
-EVP,reason,144,INVALID_PSS_SALTLEN
-EVP,reason,121,INVALID_SALT_LENGTH
-EVP,reason,122,INVALID_TRAILER
-EVP,reason,123,KEYS_NOT_SET
-EVP,reason,124,MISSING_PARAMETERS
-EVP,reason,125,NO_DEFAULT_DIGEST
-EVP,reason,126,NO_KEY_SET
-EVP,reason,127,NO_MDC2_SUPPORT
-EVP,reason,128,NO_NID_FOR_CURVE
-EVP,reason,129,NO_OPERATION_SET
-EVP,reason,130,NO_PARAMETERS_SET
-EVP,reason,131,OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE
-EVP,reason,132,OPERATON_NOT_INITIALIZED
-EVP,reason,152,PARAMETER_ENCODING_ERROR
-EVP,reason,133,UNKNOWN_DIGEST
-EVP,reason,134,UNKNOWN_MASK_DIGEST
-EVP,reason,150,UNKNOWN_MESSAGE_DIGEST_ALGORITHM
-EVP,reason,145,UNKNOWN_PUBLIC_KEY_TYPE
-EVP,reason,149,UNKNOWN_SIGNATURE_ALGORITHM
-EVP,reason,138,UNSUPPORTED_ALGORITHM
-EVP,reason,139,UNSUPPORTED_MASK_ALGORITHM
-EVP,reason,140,UNSUPPORTED_MASK_PARAMETER
-EVP,reason,153,UNSUPPORTED_PUBLIC_KEY_TYPE
-EVP,reason,154,UNSUPPORTED_SIGNATURE_TYPE
-EVP,reason,148,WRONG_PUBLIC_KEY_TYPE
+EVP,151,BN_DECODE_ERROR
+EVP,100,BUFFER_TOO_SMALL
+EVP,101,COMMAND_NOT_SUPPORTED
+EVP,146,CONTEXT_NOT_INITIALISED
+EVP,143,DECODE_ERROR
+EVP,104,DIFFERENT_KEY_TYPES
+EVP,105,DIFFERENT_PARAMETERS
+EVP,147,DIGEST_AND_KEY_TYPE_NOT_SUPPORTED
+EVP,107,EXPECTING_AN_EC_KEY_KEY
+EVP,141,EXPECTING_AN_RSA_KEY
+EVP,109,EXPECTING_A_DH_KEY
+EVP,110,EXPECTING_A_DSA_KEY
+EVP,111,ILLEGAL_OR_UNSUPPORTED_PADDING_MODE
+EVP,112,INVALID_CURVE
+EVP,113,INVALID_DIGEST_LENGTH
+EVP,114,INVALID_DIGEST_TYPE
+EVP,115,INVALID_KEYBITS
+EVP,116,INVALID_MGF1_MD
+EVP,142,INVALID_OPERATION
+EVP,118,INVALID_PADDING_MODE
+EVP,119,INVALID_PSS_PARAMETERS
+EVP,144,INVALID_PSS_SALTLEN
+EVP,121,INVALID_SALT_LENGTH
+EVP,122,INVALID_TRAILER
+EVP,123,KEYS_NOT_SET
+EVP,124,MISSING_PARAMETERS
+EVP,125,NO_DEFAULT_DIGEST
+EVP,126,NO_KEY_SET
+EVP,127,NO_MDC2_SUPPORT
+EVP,128,NO_NID_FOR_CURVE
+EVP,129,NO_OPERATION_SET
+EVP,130,NO_PARAMETERS_SET
+EVP,131,OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE
+EVP,132,OPERATON_NOT_INITIALIZED
+EVP,152,PARAMETER_ENCODING_ERROR
+EVP,133,UNKNOWN_DIGEST
+EVP,134,UNKNOWN_MASK_DIGEST
+EVP,150,UNKNOWN_MESSAGE_DIGEST_ALGORITHM
+EVP,145,UNKNOWN_PUBLIC_KEY_TYPE
+EVP,149,UNKNOWN_SIGNATURE_ALGORITHM
+EVP,138,UNSUPPORTED_ALGORITHM
+EVP,139,UNSUPPORTED_MASK_ALGORITHM
+EVP,140,UNSUPPORTED_MASK_PARAMETER
+EVP,153,UNSUPPORTED_PUBLIC_KEY_TYPE
+EVP,154,UNSUPPORTED_SIGNATURE_TYPE
+EVP,148,WRONG_PUBLIC_KEY_TYPE
diff --git a/src/crypto/err/hkdf.errordata b/src/crypto/err/hkdf.errordata
index 878a802..84866de 100644
--- a/src/crypto/err/hkdf.errordata
+++ b/src/crypto/err/hkdf.errordata
@@ -1,2 +1 @@
-HKDF,function,100,HKDF
-HKDF,reason,100,OUTPUT_TOO_LARGE
+HKDF,100,OUTPUT_TOO_LARGE
diff --git a/src/crypto/err/obj.errordata b/src/crypto/err/obj.errordata
index 74e4629..c54435e 100644
--- a/src/crypto/err/obj.errordata
+++ b/src/crypto/err/obj.errordata
@@ -1,5 +1 @@
-OBJ,function,100,OBJ_create
-OBJ,function,101,OBJ_dup
-OBJ,function,102,OBJ_nid2obj
-OBJ,function,103,OBJ_txt2obj
-OBJ,reason,100,UNKNOWN_NID
+OBJ,100,UNKNOWN_NID
diff --git a/src/crypto/err/pem.errordata b/src/crypto/err/pem.errordata
index 42216a7..2a4b73a 100644
--- a/src/crypto/err/pem.errordata
+++ b/src/crypto/err/pem.errordata
@@ -1,39 +1,15 @@
-PEM,function,100,PEM_ASN1_read
-PEM,function,101,PEM_ASN1_read_bio
-PEM,function,102,PEM_ASN1_write
-PEM,function,103,PEM_ASN1_write_bio
-PEM,function,104,PEM_X509_INFO_read
-PEM,function,105,PEM_X509_INFO_read_bio
-PEM,function,106,PEM_X509_INFO_write_bio
-PEM,function,107,PEM_do_header
-PEM,function,108,PEM_get_EVP_CIPHER_INFO
-PEM,function,109,PEM_read
-PEM,function,110,PEM_read_DHparams
-PEM,function,111,PEM_read_PrivateKey
-PEM,function,112,PEM_read_bio
-PEM,function,113,PEM_read_bio_DHparams
-PEM,function,114,PEM_read_bio_Parameters
-PEM,function,115,PEM_read_bio_PrivateKey
-PEM,function,116,PEM_write
-PEM,function,117,PEM_write_PrivateKey
-PEM,function,118,PEM_write_bio
-PEM,function,119,d2i_PKCS8PrivateKey_bio
-PEM,function,120,d2i_PKCS8PrivateKey_fp
-PEM,function,121,do_pk8pkey
-PEM,function,122,do_pk8pkey_fp
-PEM,function,123,load_iv
-PEM,reason,100,BAD_BASE64_DECODE
-PEM,reason,101,BAD_DECRYPT
-PEM,reason,102,BAD_END_LINE
-PEM,reason,103,BAD_IV_CHARS
-PEM,reason,104,BAD_PASSWORD_READ
-PEM,reason,105,CIPHER_IS_NULL
-PEM,reason,106,ERROR_CONVERTING_PRIVATE_KEY
-PEM,reason,107,NOT_DEK_INFO
-PEM,reason,108,NOT_ENCRYPTED
-PEM,reason,109,NOT_PROC_TYPE
-PEM,reason,110,NO_START_LINE
-PEM,reason,111,READ_KEY
-PEM,reason,112,SHORT_HEADER
-PEM,reason,113,UNSUPPORTED_CIPHER
-PEM,reason,114,UNSUPPORTED_ENCRYPTION
+PEM,100,BAD_BASE64_DECODE
+PEM,101,BAD_DECRYPT
+PEM,102,BAD_END_LINE
+PEM,103,BAD_IV_CHARS
+PEM,104,BAD_PASSWORD_READ
+PEM,105,CIPHER_IS_NULL
+PEM,106,ERROR_CONVERTING_PRIVATE_KEY
+PEM,107,NOT_DEK_INFO
+PEM,108,NOT_ENCRYPTED
+PEM,109,NOT_PROC_TYPE
+PEM,110,NO_START_LINE
+PEM,111,READ_KEY
+PEM,112,SHORT_HEADER
+PEM,113,UNSUPPORTED_CIPHER
+PEM,114,UNSUPPORTED_ENCRYPTION
diff --git a/src/crypto/err/pkcs8.errordata b/src/crypto/err/pkcs8.errordata
index 936f3c5..0eb5083 100644
--- a/src/crypto/err/pkcs8.errordata
+++ b/src/crypto/err/pkcs8.errordata
@@ -1,43 +1,25 @@
-PKCS8,function,100,EVP_PKCS82PKEY
-PKCS8,function,101,EVP_PKEY2PKCS8
-PKCS8,function,102,PKCS12_get_key_and_certs
-PKCS8,function,103,PKCS12_handle_content_info
-PKCS8,function,104,PKCS12_handle_content_infos
-PKCS8,function,105,PKCS5_pbe2_set_iv
-PKCS8,function,106,PKCS5_pbe_set
-PKCS8,function,107,PKCS5_pbe_set0_algor
-PKCS8,function,108,PKCS5_pbkdf2_set
-PKCS8,function,109,PKCS8_decrypt
-PKCS8,function,110,PKCS8_encrypt
-PKCS8,function,111,PKCS8_encrypt_pbe
-PKCS8,function,112,pbe_cipher_init
-PKCS8,function,113,pbe_crypt
-PKCS8,function,114,pkcs12_item_decrypt_d2i
-PKCS8,function,115,pkcs12_item_i2d_encrypt
-PKCS8,function,116,pkcs12_key_gen_raw
-PKCS8,function,117,pkcs12_pbe_keyivgen
-PKCS8,reason,100,BAD_PKCS12_DATA
-PKCS8,reason,101,BAD_PKCS12_VERSION
-PKCS8,reason,102,CIPHER_HAS_NO_OBJECT_IDENTIFIER
-PKCS8,reason,103,CRYPT_ERROR
-PKCS8,reason,104,DECODE_ERROR
-PKCS8,reason,105,ENCODE_ERROR
-PKCS8,reason,106,ENCRYPT_ERROR
-PKCS8,reason,107,ERROR_SETTING_CIPHER_PARAMS
-PKCS8,reason,108,INCORRECT_PASSWORD
-PKCS8,reason,109,KEYGEN_FAILURE
-PKCS8,reason,110,KEY_GEN_ERROR
-PKCS8,reason,111,METHOD_NOT_SUPPORTED
-PKCS8,reason,112,MISSING_MAC
-PKCS8,reason,113,MULTIPLE_PRIVATE_KEYS_IN_PKCS12
-PKCS8,reason,114,PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED
-PKCS8,reason,115,PKCS12_TOO_DEEPLY_NESTED
-PKCS8,reason,116,PRIVATE_KEY_DECODE_ERROR
-PKCS8,reason,117,PRIVATE_KEY_ENCODE_ERROR
-PKCS8,reason,118,TOO_LONG
-PKCS8,reason,119,UNKNOWN_ALGORITHM
-PKCS8,reason,120,UNKNOWN_CIPHER
-PKCS8,reason,121,UNKNOWN_CIPHER_ALGORITHM
-PKCS8,reason,122,UNKNOWN_DIGEST
-PKCS8,reason,123,UNKNOWN_HASH
-PKCS8,reason,124,UNSUPPORTED_PRIVATE_KEY_ALGORITHM
+PKCS8,100,BAD_PKCS12_DATA
+PKCS8,101,BAD_PKCS12_VERSION
+PKCS8,102,CIPHER_HAS_NO_OBJECT_IDENTIFIER
+PKCS8,103,CRYPT_ERROR
+PKCS8,104,DECODE_ERROR
+PKCS8,105,ENCODE_ERROR
+PKCS8,106,ENCRYPT_ERROR
+PKCS8,107,ERROR_SETTING_CIPHER_PARAMS
+PKCS8,108,INCORRECT_PASSWORD
+PKCS8,109,KEYGEN_FAILURE
+PKCS8,110,KEY_GEN_ERROR
+PKCS8,111,METHOD_NOT_SUPPORTED
+PKCS8,112,MISSING_MAC
+PKCS8,113,MULTIPLE_PRIVATE_KEYS_IN_PKCS12
+PKCS8,114,PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED
+PKCS8,115,PKCS12_TOO_DEEPLY_NESTED
+PKCS8,116,PRIVATE_KEY_DECODE_ERROR
+PKCS8,117,PRIVATE_KEY_ENCODE_ERROR
+PKCS8,118,TOO_LONG
+PKCS8,119,UNKNOWN_ALGORITHM
+PKCS8,120,UNKNOWN_CIPHER
+PKCS8,121,UNKNOWN_CIPHER_ALGORITHM
+PKCS8,122,UNKNOWN_DIGEST
+PKCS8,123,UNKNOWN_HASH
+PKCS8,124,UNSUPPORTED_PRIVATE_KEY_ALGORITHM
diff --git a/src/crypto/err/rsa.errordata b/src/crypto/err/rsa.errordata
index 64b390d..c19f73c 100644
--- a/src/crypto/err/rsa.errordata
+++ b/src/crypto/err/rsa.errordata
@@ -1,69 +1,46 @@
-RSA,function,100,BN_BLINDING_convert_ex
-RSA,function,101,BN_BLINDING_create_param
-RSA,function,102,BN_BLINDING_invert_ex
-RSA,function,103,BN_BLINDING_new
-RSA,function,104,BN_BLINDING_update
-RSA,function,105,RSA_check_key
-RSA,function,106,RSA_new_method
-RSA,function,107,RSA_padding_add_PKCS1_OAEP_mgf1
-RSA,function,108,RSA_padding_add_PKCS1_PSS_mgf1
-RSA,function,109,RSA_padding_add_PKCS1_type_1
-RSA,function,110,RSA_padding_add_PKCS1_type_2
-RSA,function,111,RSA_padding_add_none
-RSA,function,112,RSA_padding_check_PKCS1_OAEP_mgf1
-RSA,function,113,RSA_padding_check_PKCS1_type_1
-RSA,function,114,RSA_padding_check_PKCS1_type_2
-RSA,function,115,RSA_padding_check_none
-RSA,function,116,RSA_recover_crt_params
-RSA,function,117,RSA_sign
-RSA,function,118,RSA_verify
-RSA,function,119,RSA_verify_PKCS1_PSS_mgf1
-RSA,function,120,decrypt
-RSA,function,121,encrypt
-RSA,function,122,keygen
-RSA,function,123,pkcs1_prefixed_msg
-RSA,function,124,private_transform
-RSA,function,125,rsa_setup_blinding
-RSA,function,126,sign_raw
-RSA,function,127,verify_raw
-RSA,reason,100,BAD_E_VALUE
-RSA,reason,101,BAD_FIXED_HEADER_DECRYPT
-RSA,reason,102,BAD_PAD_BYTE_COUNT
-RSA,reason,103,BAD_RSA_PARAMETERS
-RSA,reason,104,BAD_SIGNATURE
-RSA,reason,105,BLOCK_TYPE_IS_NOT_01
-RSA,reason,106,BN_NOT_INITIALIZED
-RSA,reason,107,CRT_PARAMS_ALREADY_GIVEN
-RSA,reason,108,CRT_VALUES_INCORRECT
-RSA,reason,109,DATA_LEN_NOT_EQUAL_TO_MOD_LEN
-RSA,reason,110,DATA_TOO_LARGE
-RSA,reason,111,DATA_TOO_LARGE_FOR_KEY_SIZE
-RSA,reason,112,DATA_TOO_LARGE_FOR_MODULUS
-RSA,reason,113,DATA_TOO_SMALL
-RSA,reason,114,DATA_TOO_SMALL_FOR_KEY_SIZE
-RSA,reason,115,DIGEST_TOO_BIG_FOR_RSA_KEY
-RSA,reason,116,D_E_NOT_CONGRUENT_TO_1
-RSA,reason,117,EMPTY_PUBLIC_KEY
-RSA,reason,118,FIRST_OCTET_INVALID
-RSA,reason,119,INCONSISTENT_SET_OF_CRT_VALUES
-RSA,reason,120,INTERNAL_ERROR
-RSA,reason,121,INVALID_MESSAGE_LENGTH
-RSA,reason,122,KEY_SIZE_TOO_SMALL
-RSA,reason,123,LAST_OCTET_INVALID
-RSA,reason,124,MODULUS_TOO_LARGE
-RSA,reason,125,NO_PUBLIC_EXPONENT
-RSA,reason,126,NULL_BEFORE_BLOCK_MISSING
-RSA,reason,127,N_NOT_EQUAL_P_Q
-RSA,reason,128,OAEP_DECODING_ERROR
-RSA,reason,129,ONLY_ONE_OF_P_Q_GIVEN
-RSA,reason,130,OUTPUT_BUFFER_TOO_SMALL
-RSA,reason,131,PADDING_CHECK_FAILED
-RSA,reason,132,PKCS_DECODING_ERROR
-RSA,reason,133,SLEN_CHECK_FAILED
-RSA,reason,134,SLEN_RECOVERY_FAILED
-RSA,reason,135,TOO_LONG
-RSA,reason,136,TOO_MANY_ITERATIONS
-RSA,reason,137,UNKNOWN_ALGORITHM_TYPE
-RSA,reason,138,UNKNOWN_PADDING_TYPE
-RSA,reason,139,VALUE_MISSING
-RSA,reason,140,WRONG_SIGNATURE_LENGTH
+RSA,143,BAD_ENCODING
+RSA,100,BAD_E_VALUE
+RSA,101,BAD_FIXED_HEADER_DECRYPT
+RSA,102,BAD_PAD_BYTE_COUNT
+RSA,103,BAD_RSA_PARAMETERS
+RSA,104,BAD_SIGNATURE
+RSA,145,BAD_VERSION
+RSA,105,BLOCK_TYPE_IS_NOT_01
+RSA,106,BN_NOT_INITIALIZED
+RSA,142,CANNOT_RECOVER_MULTI_PRIME_KEY
+RSA,107,CRT_PARAMS_ALREADY_GIVEN
+RSA,108,CRT_VALUES_INCORRECT
+RSA,109,DATA_LEN_NOT_EQUAL_TO_MOD_LEN
+RSA,110,DATA_TOO_LARGE
+RSA,111,DATA_TOO_LARGE_FOR_KEY_SIZE
+RSA,112,DATA_TOO_LARGE_FOR_MODULUS
+RSA,113,DATA_TOO_SMALL
+RSA,114,DATA_TOO_SMALL_FOR_KEY_SIZE
+RSA,115,DIGEST_TOO_BIG_FOR_RSA_KEY
+RSA,116,D_E_NOT_CONGRUENT_TO_1
+RSA,117,EMPTY_PUBLIC_KEY
+RSA,144,ENCODE_ERROR
+RSA,118,FIRST_OCTET_INVALID
+RSA,119,INCONSISTENT_SET_OF_CRT_VALUES
+RSA,120,INTERNAL_ERROR
+RSA,121,INVALID_MESSAGE_LENGTH
+RSA,122,KEY_SIZE_TOO_SMALL
+RSA,123,LAST_OCTET_INVALID
+RSA,124,MODULUS_TOO_LARGE
+RSA,141,MUST_HAVE_AT_LEAST_TWO_PRIMES
+RSA,125,NO_PUBLIC_EXPONENT
+RSA,126,NULL_BEFORE_BLOCK_MISSING
+RSA,127,N_NOT_EQUAL_P_Q
+RSA,128,OAEP_DECODING_ERROR
+RSA,129,ONLY_ONE_OF_P_Q_GIVEN
+RSA,130,OUTPUT_BUFFER_TOO_SMALL
+RSA,131,PADDING_CHECK_FAILED
+RSA,132,PKCS_DECODING_ERROR
+RSA,133,SLEN_CHECK_FAILED
+RSA,134,SLEN_RECOVERY_FAILED
+RSA,135,TOO_LONG
+RSA,136,TOO_MANY_ITERATIONS
+RSA,137,UNKNOWN_ALGORITHM_TYPE
+RSA,138,UNKNOWN_PADDING_TYPE
+RSA,139,VALUE_MISSING
+RSA,140,WRONG_SIGNATURE_LENGTH
diff --git a/src/crypto/err/ssl.errordata b/src/crypto/err/ssl.errordata
index 4ae0a51..3766bb9 100644
--- a/src/crypto/err/ssl.errordata
+++ b/src/crypto/err/ssl.errordata
@@ -1,384 +1,180 @@
-SSL,function,276,SSL_AEAD_CTX_new
-SSL,function,277,SSL_AEAD_CTX_open
-SSL,function,278,SSL_AEAD_CTX_seal
-SSL,function,100,SSL_CTX_check_private_key
-SSL,function,101,SSL_CTX_new
-SSL,function,272,SSL_CTX_set1_tls_channel_id
-SSL,function,102,SSL_CTX_set_cipher_list
-SSL,function,103,SSL_CTX_set_cipher_list_tls11
-SSL,function,104,SSL_CTX_set_session_id_context
-SSL,function,268,SSL_CTX_set_tmp_dh
-SSL,function,269,SSL_CTX_set_tmp_ecdh
-SSL,function,105,SSL_CTX_use_PrivateKey
-SSL,function,106,SSL_CTX_use_PrivateKey_ASN1
-SSL,function,107,SSL_CTX_use_PrivateKey_file
-SSL,function,108,SSL_CTX_use_RSAPrivateKey
-SSL,function,109,SSL_CTX_use_RSAPrivateKey_ASN1
-SSL,function,110,SSL_CTX_use_RSAPrivateKey_file
-SSL,function,111,SSL_CTX_use_certificate
-SSL,function,112,SSL_CTX_use_certificate_ASN1
-SSL,function,113,SSL_CTX_use_certificate_chain_file
-SSL,function,114,SSL_CTX_use_certificate_file
-SSL,function,115,SSL_CTX_use_psk_identity_hint
-SSL,function,116,SSL_SESSION_new
-SSL,function,117,SSL_SESSION_print_fp
-SSL,function,118,SSL_SESSION_set1_id_context
-SSL,function,119,SSL_SESSION_to_bytes_full
-SSL,function,120,SSL_accept
-SSL,function,121,SSL_add_dir_cert_subjects_to_stack
-SSL,function,122,SSL_add_file_cert_subjects_to_stack
-SSL,function,123,SSL_check_private_key
-SSL,function,124,SSL_clear
-SSL,function,125,SSL_connect
-SSL,function,126,SSL_do_handshake
-SSL,function,127,SSL_load_client_CA_file
-SSL,function,128,SSL_new
-SSL,function,129,SSL_peek
-SSL,function,130,SSL_read
-SSL,function,131,SSL_renegotiate
-SSL,function,273,SSL_set1_tls_channel_id
-SSL,function,132,SSL_set_cipher_list
-SSL,function,133,SSL_set_fd
-SSL,function,134,SSL_set_rfd
-SSL,function,135,SSL_set_session_id_context
-SSL,function,274,SSL_set_tlsext_host_name
-SSL,function,270,SSL_set_tmp_dh
-SSL,function,271,SSL_set_tmp_ecdh
-SSL,function,136,SSL_set_wfd
-SSL,function,137,SSL_shutdown
-SSL,function,138,SSL_use_PrivateKey
-SSL,function,139,SSL_use_PrivateKey_ASN1
-SSL,function,140,SSL_use_PrivateKey_file
-SSL,function,141,SSL_use_RSAPrivateKey
-SSL,function,142,SSL_use_RSAPrivateKey_ASN1
-SSL,function,143,SSL_use_RSAPrivateKey_file
-SSL,function,144,SSL_use_certificate
-SSL,function,145,SSL_use_certificate_ASN1
-SSL,function,146,SSL_use_certificate_file
-SSL,function,147,SSL_use_psk_identity_hint
-SSL,function,148,SSL_write
-SSL,function,149,d2i_SSL_SESSION
-SSL,function,150,d2i_SSL_SESSION_get_octet_string
-SSL,function,151,d2i_SSL_SESSION_get_string
-SSL,function,152,do_ssl3_write
-SSL,function,153,dtls1_accept
-SSL,function,154,dtls1_buffer_record
-SSL,function,155,dtls1_check_timeout_num
-SSL,function,156,dtls1_connect
-SSL,function,157,dtls1_do_write
-SSL,function,263,dtls1_get_buffered_message
-SSL,function,158,dtls1_get_hello_verify
-SSL,function,159,dtls1_get_message
-SSL,function,160,dtls1_get_message_fragment
-SSL,function,265,dtls1_hm_fragment_new
-SSL,function,161,dtls1_preprocess_fragment
-SSL,function,264,dtls1_process_fragment
-SSL,function,162,dtls1_process_record
-SSL,function,163,dtls1_read_bytes
-SSL,function,279,dtls1_seal_record
-SSL,function,164,dtls1_send_hello_verify_request
-SSL,function,165,dtls1_write_app_data
-SSL,function,166,i2d_SSL_SESSION
-SSL,function,167,ssl3_accept
-SSL,function,169,ssl3_cert_verify_hash
-SSL,function,170,ssl3_check_cert_and_algorithm
-SSL,function,171,ssl3_connect
-SSL,function,172,ssl3_ctrl
-SSL,function,173,ssl3_ctx_ctrl
-SSL,function,174,ssl3_digest_cached_records
-SSL,function,175,ssl3_do_change_cipher_spec
-SSL,function,176,ssl3_expect_change_cipher_spec
-SSL,function,177,ssl3_get_cert_status
-SSL,function,178,ssl3_get_cert_verify
-SSL,function,179,ssl3_get_certificate_request
-SSL,function,180,ssl3_get_channel_id
-SSL,function,181,ssl3_get_client_certificate
-SSL,function,182,ssl3_get_client_hello
-SSL,function,183,ssl3_get_client_key_exchange
-SSL,function,184,ssl3_get_finished
-SSL,function,185,ssl3_get_initial_bytes
-SSL,function,186,ssl3_get_message
-SSL,function,187,ssl3_get_new_session_ticket
-SSL,function,188,ssl3_get_next_proto
-SSL,function,189,ssl3_get_record
-SSL,function,190,ssl3_get_server_certificate
-SSL,function,191,ssl3_get_server_done
-SSL,function,192,ssl3_get_server_hello
-SSL,function,193,ssl3_get_server_key_exchange
-SSL,function,194,ssl3_get_v2_client_hello
-SSL,function,195,ssl3_handshake_mac
-SSL,function,275,ssl3_output_cert_chain
-SSL,function,196,ssl3_prf
-SSL,function,197,ssl3_read_bytes
-SSL,function,198,ssl3_read_n
-SSL,function,267,ssl3_record_sequence_update
-SSL,function,266,ssl3_seal_record
-SSL,function,199,ssl3_send_cert_verify
-SSL,function,200,ssl3_send_certificate_request
-SSL,function,201,ssl3_send_channel_id
-SSL,function,202,ssl3_send_client_certificate
-SSL,function,203,ssl3_send_client_hello
-SSL,function,204,ssl3_send_client_key_exchange
-SSL,function,205,ssl3_send_server_certificate
-SSL,function,206,ssl3_send_server_hello
-SSL,function,207,ssl3_send_server_key_exchange
-SSL,function,208,ssl3_setup_read_buffer
-SSL,function,209,ssl3_setup_write_buffer
-SSL,function,210,ssl3_write_bytes
-SSL,function,211,ssl3_write_pending
-SSL,function,212,ssl_add_cert_chain
-SSL,function,213,ssl_add_cert_to_buf
-SSL,function,214,ssl_add_clienthello_renegotiate_ext
-SSL,function,215,ssl_add_clienthello_tlsext
-SSL,function,216,ssl_add_clienthello_use_srtp_ext
-SSL,function,217,ssl_add_serverhello_renegotiate_ext
-SSL,function,218,ssl_add_serverhello_tlsext
-SSL,function,219,ssl_add_serverhello_use_srtp_ext
-SSL,function,220,ssl_build_cert_chain
-SSL,function,221,ssl_bytes_to_cipher_list
-SSL,function,222,ssl_cert_dup
-SSL,function,223,ssl_cert_inst
-SSL,function,224,ssl_cert_new
-SSL,function,225,ssl_check_serverhello_tlsext
-SSL,function,226,ssl_check_srvr_ecc_cert_and_alg
-SSL,function,227,ssl_cipher_process_rulestr
-SSL,function,228,ssl_cipher_strength_sort
-SSL,function,229,ssl_create_cipher_list
-SSL,function,230,ssl_ctx_log_master_secret
-SSL,function,231,ssl_ctx_log_rsa_client_key_exchange
-SSL,function,232,ssl_ctx_make_profiles
-SSL,function,233,ssl_get_new_session
-SSL,function,234,ssl_get_prev_session
-SSL,function,235,ssl_get_server_cert_index
-SSL,function,236,ssl_get_sign_pkey
-SSL,function,237,ssl_init_wbio_buffer
-SSL,function,238,ssl_parse_clienthello_renegotiate_ext
-SSL,function,239,ssl_parse_clienthello_tlsext
-SSL,function,240,ssl_parse_clienthello_use_srtp_ext
-SSL,function,241,ssl_parse_serverhello_renegotiate_ext
-SSL,function,242,ssl_parse_serverhello_tlsext
-SSL,function,243,ssl_parse_serverhello_use_srtp_ext
-SSL,function,244,ssl_scan_clienthello_tlsext
-SSL,function,245,ssl_scan_serverhello_tlsext
-SSL,function,246,ssl_sess_cert_new
-SSL,function,247,ssl_set_cert
-SSL,function,248,ssl_set_pkey
-SSL,function,252,ssl_verify_cert_chain
-SSL,function,253,tls12_check_peer_sigalg
-SSL,function,254,tls1_aead_ctx_init
-SSL,function,255,tls1_cert_verify_mac
-SSL,function,256,tls1_change_cipher_state
-SSL,function,257,tls1_change_cipher_state_aead
-SSL,function,258,tls1_check_duplicate_extensions
-SSL,function,259,tls1_enc
-SSL,function,260,tls1_export_keying_material
-SSL,function,261,tls1_prf
-SSL,function,262,tls1_setup_key_block
-SSL,reason,100,APP_DATA_IN_HANDSHAKE
-SSL,reason,101,ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT
-SSL,reason,102,BAD_ALERT
-SSL,reason,103,BAD_CHANGE_CIPHER_SPEC
-SSL,reason,104,BAD_DATA_RETURNED_BY_CALLBACK
-SSL,reason,105,BAD_DH_P_LENGTH
-SSL,reason,106,BAD_DIGEST_LENGTH
-SSL,reason,107,BAD_ECC_CERT
-SSL,reason,108,BAD_ECPOINT
-SSL,reason,109,BAD_HANDSHAKE_LENGTH
-SSL,reason,110,BAD_HANDSHAKE_RECORD
-SSL,reason,111,BAD_HELLO_REQUEST
-SSL,reason,112,BAD_LENGTH
-SSL,reason,113,BAD_PACKET_LENGTH
-SSL,reason,114,BAD_RSA_ENCRYPT
-SSL,reason,115,BAD_SIGNATURE
-SSL,reason,116,BAD_SRTP_MKI_VALUE
-SSL,reason,117,BAD_SRTP_PROTECTION_PROFILE_LIST
-SSL,reason,118,BAD_SSL_FILETYPE
-SSL,reason,119,BAD_WRITE_RETRY
-SSL,reason,120,BIO_NOT_SET
-SSL,reason,121,BN_LIB
-SSL,reason,272,BUFFER_TOO_SMALL
-SSL,reason,122,CANNOT_SERIALIZE_PUBLIC_KEY
-SSL,reason,123,CA_DN_LENGTH_MISMATCH
-SSL,reason,124,CA_DN_TOO_LONG
-SSL,reason,125,CCS_RECEIVED_EARLY
-SSL,reason,126,CERTIFICATE_VERIFY_FAILED
-SSL,reason,127,CERT_CB_ERROR
-SSL,reason,128,CERT_LENGTH_MISMATCH
-SSL,reason,129,CHANNEL_ID_NOT_P256
-SSL,reason,130,CHANNEL_ID_SIGNATURE_INVALID
-SSL,reason,131,CIPHER_CODE_WRONG_LENGTH
-SSL,reason,132,CIPHER_OR_HASH_UNAVAILABLE
-SSL,reason,133,CLIENTHELLO_PARSE_FAILED
-SSL,reason,134,CLIENTHELLO_TLSEXT
-SSL,reason,135,CONNECTION_REJECTED
-SSL,reason,136,CONNECTION_TYPE_NOT_SET
-SSL,reason,137,COOKIE_MISMATCH
-SSL,reason,138,D2I_ECDSA_SIG
-SSL,reason,139,DATA_BETWEEN_CCS_AND_FINISHED
-SSL,reason,140,DATA_LENGTH_TOO_LONG
-SSL,reason,141,DECODE_ERROR
-SSL,reason,142,DECRYPTION_FAILED
-SSL,reason,143,DECRYPTION_FAILED_OR_BAD_RECORD_MAC
-SSL,reason,144,DH_PUBLIC_VALUE_LENGTH_IS_WRONG
-SSL,reason,145,DIGEST_CHECK_FAILED
-SSL,reason,146,DTLS_MESSAGE_TOO_BIG
-SSL,reason,147,ECC_CERT_NOT_FOR_SIGNING
-SSL,reason,148,EMPTY_SRTP_PROTECTION_PROFILE_LIST
-SSL,reason,276,EMS_STATE_INCONSISTENT
-SSL,reason,149,ENCRYPTED_LENGTH_TOO_LONG
-SSL,reason,150,ERROR_IN_RECEIVED_CIPHER_LIST
-SSL,reason,151,EVP_DIGESTSIGNFINAL_FAILED
-SSL,reason,152,EVP_DIGESTSIGNINIT_FAILED
-SSL,reason,153,EXCESSIVE_MESSAGE_SIZE
-SSL,reason,154,EXTRA_DATA_IN_MESSAGE
-SSL,reason,271,FRAGMENT_MISMATCH
-SSL,reason,155,GOT_A_FIN_BEFORE_A_CCS
-SSL,reason,156,GOT_CHANNEL_ID_BEFORE_A_CCS
-SSL,reason,157,GOT_NEXT_PROTO_BEFORE_A_CCS
-SSL,reason,158,GOT_NEXT_PROTO_WITHOUT_EXTENSION
-SSL,reason,159,HANDSHAKE_FAILURE_ON_CLIENT_HELLO
-SSL,reason,160,HANDSHAKE_RECORD_BEFORE_CCS
-SSL,reason,161,HTTPS_PROXY_REQUEST
-SSL,reason,162,HTTP_REQUEST
-SSL,reason,163,INAPPROPRIATE_FALLBACK
-SSL,reason,164,INVALID_COMMAND
-SSL,reason,165,INVALID_MESSAGE
-SSL,reason,166,INVALID_SSL_SESSION
-SSL,reason,167,INVALID_TICKET_KEYS_LENGTH
-SSL,reason,168,LENGTH_MISMATCH
-SSL,reason,169,LIBRARY_HAS_NO_CIPHERS
-SSL,reason,170,MISSING_DH_KEY
-SSL,reason,171,MISSING_ECDSA_SIGNING_CERT
-SSL,reason,172,MISSING_RSA_CERTIFICATE
-SSL,reason,173,MISSING_RSA_ENCRYPTING_CERT
-SSL,reason,174,MISSING_RSA_SIGNING_CERT
-SSL,reason,175,MISSING_TMP_DH_KEY
-SSL,reason,176,MISSING_TMP_ECDH_KEY
-SSL,reason,177,MIXED_SPECIAL_OPERATOR_WITH_GROUPS
-SSL,reason,178,MTU_TOO_SMALL
-SSL,reason,179,NESTED_GROUP
-SSL,reason,180,NO_CERTIFICATES_RETURNED
-SSL,reason,181,NO_CERTIFICATE_ASSIGNED
-SSL,reason,182,NO_CERTIFICATE_SET
-SSL,reason,183,NO_CIPHERS_AVAILABLE
-SSL,reason,184,NO_CIPHERS_PASSED
-SSL,reason,185,NO_CIPHERS_SPECIFIED
-SSL,reason,186,NO_CIPHER_MATCH
-SSL,reason,187,NO_COMPRESSION_SPECIFIED
-SSL,reason,188,NO_METHOD_SPECIFIED
-SSL,reason,189,NO_P256_SUPPORT
-SSL,reason,190,NO_PRIVATE_KEY_ASSIGNED
-SSL,reason,191,NO_RENEGOTIATION
-SSL,reason,192,NO_REQUIRED_DIGEST
-SSL,reason,193,NO_SHARED_CIPHER
-SSL,reason,194,NO_SHARED_SIGATURE_ALGORITHMS
-SSL,reason,195,NO_SRTP_PROFILES
-SSL,reason,196,NULL_SSL_CTX
-SSL,reason,197,NULL_SSL_METHOD_PASSED
-SSL,reason,198,OLD_SESSION_CIPHER_NOT_RETURNED
-SSL,reason,273,OLD_SESSION_VERSION_NOT_RETURNED
-SSL,reason,274,OUTPUT_ALIASES_INPUT
-SSL,reason,199,PACKET_LENGTH_TOO_LONG
-SSL,reason,200,PARSE_TLSEXT
-SSL,reason,201,PATH_TOO_LONG
-SSL,reason,202,PEER_DID_NOT_RETURN_A_CERTIFICATE
-SSL,reason,203,PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE
-SSL,reason,204,PROTOCOL_IS_SHUTDOWN
-SSL,reason,205,PSK_IDENTITY_NOT_FOUND
-SSL,reason,206,PSK_NO_CLIENT_CB
-SSL,reason,207,PSK_NO_SERVER_CB
-SSL,reason,208,READ_BIO_NOT_SET
-SSL,reason,209,READ_TIMEOUT_EXPIRED
-SSL,reason,210,RECORD_LENGTH_MISMATCH
-SSL,reason,211,RECORD_TOO_LARGE
-SSL,reason,212,RENEGOTIATE_EXT_TOO_LONG
-SSL,reason,213,RENEGOTIATION_ENCODING_ERR
-SSL,reason,214,RENEGOTIATION_MISMATCH
-SSL,reason,215,REQUIRED_CIPHER_MISSING
-SSL,reason,275,RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION
-SSL,reason,277,RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION
-SSL,reason,216,SCSV_RECEIVED_WHEN_RENEGOTIATING
-SSL,reason,217,SERVERHELLO_TLSEXT
-SSL,reason,218,SESSION_ID_CONTEXT_UNINITIALIZED
-SSL,reason,219,SESSION_MAY_NOT_BE_CREATED
-SSL,reason,220,SIGNATURE_ALGORITHMS_ERROR
-SSL,reason,221,SRTP_COULD_NOT_ALLOCATE_PROFILES
-SSL,reason,222,SRTP_PROTECTION_PROFILE_LIST_TOO_LONG
-SSL,reason,223,SRTP_UNKNOWN_PROTECTION_PROFILE
-SSL,reason,224,SSL3_EXT_INVALID_SERVERNAME
-SSL,reason,225,SSL3_EXT_INVALID_SERVERNAME_TYPE
-SSL,reason,1042,SSLV3_ALERT_BAD_CERTIFICATE
-SSL,reason,1020,SSLV3_ALERT_BAD_RECORD_MAC
-SSL,reason,1045,SSLV3_ALERT_CERTIFICATE_EXPIRED
-SSL,reason,1044,SSLV3_ALERT_CERTIFICATE_REVOKED
-SSL,reason,1046,SSLV3_ALERT_CERTIFICATE_UNKNOWN
-SSL,reason,1000,SSLV3_ALERT_CLOSE_NOTIFY
-SSL,reason,1030,SSLV3_ALERT_DECOMPRESSION_FAILURE
-SSL,reason,1040,SSLV3_ALERT_HANDSHAKE_FAILURE
-SSL,reason,1047,SSLV3_ALERT_ILLEGAL_PARAMETER
-SSL,reason,1041,SSLV3_ALERT_NO_CERTIFICATE
-SSL,reason,1010,SSLV3_ALERT_UNEXPECTED_MESSAGE
-SSL,reason,1043,SSLV3_ALERT_UNSUPPORTED_CERTIFICATE
-SSL,reason,226,SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION
-SSL,reason,227,SSL_HANDSHAKE_FAILURE
-SSL,reason,228,SSL_SESSION_ID_CALLBACK_FAILED
-SSL,reason,229,SSL_SESSION_ID_CONFLICT
-SSL,reason,230,SSL_SESSION_ID_CONTEXT_TOO_LONG
-SSL,reason,231,SSL_SESSION_ID_HAS_BAD_LENGTH
-SSL,reason,1049,TLSV1_ALERT_ACCESS_DENIED
-SSL,reason,1050,TLSV1_ALERT_DECODE_ERROR
-SSL,reason,1021,TLSV1_ALERT_DECRYPTION_FAILED
-SSL,reason,1051,TLSV1_ALERT_DECRYPT_ERROR
-SSL,reason,1060,TLSV1_ALERT_EXPORT_RESTRICTION
-SSL,reason,1086,TLSV1_ALERT_INAPPROPRIATE_FALLBACK
-SSL,reason,1071,TLSV1_ALERT_INSUFFICIENT_SECURITY
-SSL,reason,1080,TLSV1_ALERT_INTERNAL_ERROR
-SSL,reason,1100,TLSV1_ALERT_NO_RENEGOTIATION
-SSL,reason,1070,TLSV1_ALERT_PROTOCOL_VERSION
-SSL,reason,1022,TLSV1_ALERT_RECORD_OVERFLOW
-SSL,reason,1048,TLSV1_ALERT_UNKNOWN_CA
-SSL,reason,1090,TLSV1_ALERT_USER_CANCELLED
-SSL,reason,1114,TLSV1_BAD_CERTIFICATE_HASH_VALUE
-SSL,reason,1113,TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE
-SSL,reason,1111,TLSV1_CERTIFICATE_UNOBTAINABLE
-SSL,reason,1112,TLSV1_UNRECOGNIZED_NAME
-SSL,reason,1110,TLSV1_UNSUPPORTED_EXTENSION
-SSL,reason,232,TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER
-SSL,reason,233,TLS_ILLEGAL_EXPORTER_LABEL
-SSL,reason,234,TLS_INVALID_ECPOINTFORMAT_LIST
-SSL,reason,235,TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST
-SSL,reason,236,TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG
-SSL,reason,237,TOO_MANY_EMPTY_FRAGMENTS
-SSL,reason,238,UNABLE_TO_FIND_ECDH_PARAMETERS
-SSL,reason,239,UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS
-SSL,reason,240,UNEXPECTED_GROUP_CLOSE
-SSL,reason,241,UNEXPECTED_MESSAGE
-SSL,reason,242,UNEXPECTED_OPERATOR_IN_GROUP
-SSL,reason,243,UNEXPECTED_RECORD
-SSL,reason,244,UNINITIALIZED
-SSL,reason,245,UNKNOWN_ALERT_TYPE
-SSL,reason,246,UNKNOWN_CERTIFICATE_TYPE
-SSL,reason,247,UNKNOWN_CIPHER_RETURNED
-SSL,reason,248,UNKNOWN_CIPHER_TYPE
-SSL,reason,249,UNKNOWN_DIGEST
-SSL,reason,250,UNKNOWN_KEY_EXCHANGE_TYPE
-SSL,reason,251,UNKNOWN_PROTOCOL
-SSL,reason,252,UNKNOWN_SSL_VERSION
-SSL,reason,253,UNKNOWN_STATE
-SSL,reason,254,UNPROCESSED_HANDSHAKE_DATA
-SSL,reason,255,UNSAFE_LEGACY_RENEGOTIATION_DISABLED
-SSL,reason,256,UNSUPPORTED_CIPHER
-SSL,reason,257,UNSUPPORTED_COMPRESSION_ALGORITHM
-SSL,reason,258,UNSUPPORTED_ELLIPTIC_CURVE
-SSL,reason,259,UNSUPPORTED_PROTOCOL
-SSL,reason,260,UNSUPPORTED_SSL_VERSION
-SSL,reason,261,USE_SRTP_NOT_NEGOTIATED
-SSL,reason,262,WRONG_CERTIFICATE_TYPE
-SSL,reason,263,WRONG_CIPHER_RETURNED
-SSL,reason,264,WRONG_CURVE
-SSL,reason,265,WRONG_MESSAGE_TYPE
-SSL,reason,266,WRONG_SIGNATURE_TYPE
-SSL,reason,267,WRONG_SSL_VERSION
-SSL,reason,268,WRONG_VERSION_NUMBER
-SSL,reason,269,X509_LIB
-SSL,reason,270,X509_VERIFICATION_SETUP_PROBLEMS
+SSL,100,APP_DATA_IN_HANDSHAKE
+SSL,101,ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT
+SSL,102,BAD_ALERT
+SSL,103,BAD_CHANGE_CIPHER_SPEC
+SSL,104,BAD_DATA_RETURNED_BY_CALLBACK
+SSL,105,BAD_DH_P_LENGTH
+SSL,106,BAD_DIGEST_LENGTH
+SSL,107,BAD_ECC_CERT
+SSL,108,BAD_ECPOINT
+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
+SSL,1044,SSLV3_ALERT_CERTIFICATE_REVOKED
+SSL,1046,SSLV3_ALERT_CERTIFICATE_UNKNOWN
+SSL,1000,SSLV3_ALERT_CLOSE_NOTIFY
+SSL,1030,SSLV3_ALERT_DECOMPRESSION_FAILURE
+SSL,1040,SSLV3_ALERT_HANDSHAKE_FAILURE
+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,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
+SSL,1051,TLSV1_ALERT_DECRYPT_ERROR
+SSL,1060,TLSV1_ALERT_EXPORT_RESTRICTION
+SSL,1086,TLSV1_ALERT_INAPPROPRIATE_FALLBACK
+SSL,1071,TLSV1_ALERT_INSUFFICIENT_SECURITY
+SSL,1080,TLSV1_ALERT_INTERNAL_ERROR
+SSL,1100,TLSV1_ALERT_NO_RENEGOTIATION
+SSL,1070,TLSV1_ALERT_PROTOCOL_VERSION
+SSL,1022,TLSV1_ALERT_RECORD_OVERFLOW
+SSL,1048,TLSV1_ALERT_UNKNOWN_CA
+SSL,1090,TLSV1_ALERT_USER_CANCELLED
+SSL,1114,TLSV1_BAD_CERTIFICATE_HASH_VALUE
+SSL,1113,TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE
+SSL,1111,TLSV1_CERTIFICATE_UNOBTAINABLE
+SSL,1112,TLSV1_UNRECOGNIZED_NAME
+SSL,1110,TLSV1_UNSUPPORTED_EXTENSION
+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/err/x509.errordata b/src/crypto/err/x509.errordata
index 1b50e36..f4828ce 100644
--- a/src/crypto/err/x509.errordata
+++ b/src/crypto/err/x509.errordata
@@ -1,96 +1,37 @@
-X509,function,100,ASN1_digest
-X509,function,101,ASN1_item_sign_ctx
-X509,function,102,ASN1_item_verify
-X509,function,103,NETSCAPE_SPKI_b64_decode
-X509,function,104,NETSCAPE_SPKI_b64_encode
-X509,function,158,PKCS7_get_CRLs
-X509,function,105,PKCS7_get_certificates
-X509,function,106,X509_ATTRIBUTE_create_by_NID
-X509,function,107,X509_ATTRIBUTE_create_by_OBJ
-X509,function,108,X509_ATTRIBUTE_create_by_txt
-X509,function,109,X509_ATTRIBUTE_get0_data
-X509,function,110,X509_ATTRIBUTE_set1_data
-X509,function,111,X509_CRL_add0_revoked
-X509,function,112,X509_CRL_diff
-X509,function,113,X509_CRL_print_fp
-X509,function,114,X509_EXTENSION_create_by_NID
-X509,function,115,X509_EXTENSION_create_by_OBJ
-X509,function,116,X509_INFO_new
-X509,function,117,X509_NAME_ENTRY_create_by_NID
-X509,function,118,X509_NAME_ENTRY_create_by_txt
-X509,function,119,X509_NAME_ENTRY_set_object
-X509,function,120,X509_NAME_add_entry
-X509,function,121,X509_NAME_oneline
-X509,function,122,X509_NAME_print
-X509,function,123,X509_PKEY_new
-X509,function,124,X509_PUBKEY_get
-X509,function,125,X509_PUBKEY_set
-X509,function,126,X509_REQ_check_private_key
-X509,function,127,X509_REQ_to_X509
-X509,function,128,X509_STORE_CTX_get1_issuer
-X509,function,129,X509_STORE_CTX_init
-X509,function,130,X509_STORE_CTX_new
-X509,function,131,X509_STORE_CTX_purpose_inherit
-X509,function,132,X509_STORE_add_cert
-X509,function,133,X509_STORE_add_crl
-X509,function,134,X509_TRUST_add
-X509,function,135,X509_TRUST_set
-X509,function,136,X509_check_private_key
-X509,function,137,X509_get_pubkey_parameters
-X509,function,138,X509_load_cert_crl_file
-X509,function,139,X509_load_cert_file
-X509,function,140,X509_load_crl_file
-X509,function,141,X509_print_ex_fp
-X509,function,142,X509_to_X509_REQ
-X509,function,143,X509_verify_cert
-X509,function,144,X509at_add1_attr
-X509,function,145,X509v3_add_ext
-X509,function,146,add_cert_dir
-X509,function,147,by_file_ctrl
-X509,function,148,check_policy
-X509,function,149,dir_ctrl
-X509,function,150,get_cert_by_subject
-X509,function,151,i2d_DSA_PUBKEY
-X509,function,152,i2d_EC_PUBKEY
-X509,function,153,i2d_RSA_PUBKEY
-X509,function,157,pkcs7_parse_header
-X509,function,154,x509_name_encode
-X509,function,155,x509_name_ex_d2i
-X509,function,156,x509_name_ex_new
-X509,reason,100,AKID_MISMATCH
-X509,reason,101,BAD_PKCS7_VERSION
-X509,reason,102,BAD_X509_FILETYPE
-X509,reason,103,BASE64_DECODE_ERROR
-X509,reason,104,CANT_CHECK_DH_KEY
-X509,reason,105,CERT_ALREADY_IN_HASH_TABLE
-X509,reason,106,CRL_ALREADY_DELTA
-X509,reason,107,CRL_VERIFY_FAILURE
-X509,reason,108,IDP_MISMATCH
-X509,reason,109,INVALID_BIT_STRING_BITS_LEFT
-X509,reason,110,INVALID_DIRECTORY
-X509,reason,111,INVALID_FIELD_NAME
-X509,reason,112,INVALID_TRUST
-X509,reason,113,ISSUER_MISMATCH
-X509,reason,114,KEY_TYPE_MISMATCH
-X509,reason,115,KEY_VALUES_MISMATCH
-X509,reason,116,LOADING_CERT_DIR
-X509,reason,117,LOADING_DEFAULTS
-X509,reason,118,METHOD_NOT_SUPPORTED
-X509,reason,119,NEWER_CRL_NOT_NEWER
-X509,reason,120,NOT_PKCS7_SIGNED_DATA
-X509,reason,121,NO_CERTIFICATES_INCLUDED
-X509,reason,122,NO_CERT_SET_FOR_US_TO_VERIFY
-X509,reason,136,NO_CRLS_INCLUDED
-X509,reason,123,NO_CRL_NUMBER
-X509,reason,124,PUBLIC_KEY_DECODE_ERROR
-X509,reason,125,PUBLIC_KEY_ENCODE_ERROR
-X509,reason,126,SHOULD_RETRY
-X509,reason,127,UNABLE_TO_FIND_PARAMETERS_IN_CHAIN
-X509,reason,128,UNABLE_TO_GET_CERTS_PUBLIC_KEY
-X509,reason,129,UNKNOWN_KEY_TYPE
-X509,reason,130,UNKNOWN_NID
-X509,reason,131,UNKNOWN_PURPOSE_ID
-X509,reason,132,UNKNOWN_TRUST_ID
-X509,reason,133,UNSUPPORTED_ALGORITHM
-X509,reason,134,WRONG_LOOKUP_TYPE
-X509,reason,135,WRONG_TYPE
+X509,100,AKID_MISMATCH
+X509,101,BAD_PKCS7_VERSION
+X509,102,BAD_X509_FILETYPE
+X509,103,BASE64_DECODE_ERROR
+X509,104,CANT_CHECK_DH_KEY
+X509,105,CERT_ALREADY_IN_HASH_TABLE
+X509,106,CRL_ALREADY_DELTA
+X509,107,CRL_VERIFY_FAILURE
+X509,108,IDP_MISMATCH
+X509,109,INVALID_BIT_STRING_BITS_LEFT
+X509,110,INVALID_DIRECTORY
+X509,111,INVALID_FIELD_NAME
+X509,112,INVALID_TRUST
+X509,113,ISSUER_MISMATCH
+X509,114,KEY_TYPE_MISMATCH
+X509,115,KEY_VALUES_MISMATCH
+X509,116,LOADING_CERT_DIR
+X509,117,LOADING_DEFAULTS
+X509,118,METHOD_NOT_SUPPORTED
+X509,119,NEWER_CRL_NOT_NEWER
+X509,120,NOT_PKCS7_SIGNED_DATA
+X509,121,NO_CERTIFICATES_INCLUDED
+X509,122,NO_CERT_SET_FOR_US_TO_VERIFY
+X509,136,NO_CRLS_INCLUDED
+X509,123,NO_CRL_NUMBER
+X509,124,PUBLIC_KEY_DECODE_ERROR
+X509,125,PUBLIC_KEY_ENCODE_ERROR
+X509,126,SHOULD_RETRY
+X509,127,UNABLE_TO_FIND_PARAMETERS_IN_CHAIN
+X509,128,UNABLE_TO_GET_CERTS_PUBLIC_KEY
+X509,129,UNKNOWN_KEY_TYPE
+X509,130,UNKNOWN_NID
+X509,131,UNKNOWN_PURPOSE_ID
+X509,132,UNKNOWN_TRUST_ID
+X509,133,UNSUPPORTED_ALGORITHM
+X509,134,WRONG_LOOKUP_TYPE
+X509,135,WRONG_TYPE
diff --git a/src/crypto/err/x509v3.errordata b/src/crypto/err/x509v3.errordata
index 059e677..e53b780 100644
--- a/src/crypto/err/x509v3.errordata
+++ b/src/crypto/err/x509v3.errordata
@@ -1,120 +1,63 @@
-X509V3,function,100,SXNET_add_id_INTEGER
-X509V3,function,101,SXNET_add_id_asc
-X509V3,function,102,SXNET_add_id_ulong
-X509V3,function,103,SXNET_get_id_asc
-X509V3,function,104,SXNET_get_id_ulong
-X509V3,function,105,X509V3_EXT_add
-X509V3,function,106,X509V3_EXT_add_alias
-X509V3,function,107,X509V3_EXT_free
-X509V3,function,108,X509V3_EXT_i2d
-X509V3,function,109,X509V3_EXT_nconf
-X509V3,function,110,X509V3_add1_i2d
-X509V3,function,111,X509V3_add_value
-X509V3,function,112,X509V3_get_section
-X509V3,function,113,X509V3_get_string
-X509V3,function,114,X509V3_get_value_bool
-X509V3,function,115,X509V3_parse_list
-X509V3,function,116,X509_PURPOSE_add
-X509V3,function,117,X509_PURPOSE_set
-X509V3,function,118,a2i_GENERAL_NAME
-X509V3,function,119,copy_email
-X509V3,function,120,copy_issuer
-X509V3,function,121,do_dirname
-X509V3,function,122,do_ext_i2d
-X509V3,function,123,do_ext_nconf
-X509V3,function,124,gnames_from_sectname
-X509V3,function,125,hex_to_string
-X509V3,function,126,i2s_ASN1_ENUMERATED
-X509V3,function,127,i2s_ASN1_IA5STRING
-X509V3,function,128,i2s_ASN1_INTEGER
-X509V3,function,129,i2v_AUTHORITY_INFO_ACCESS
-X509V3,function,130,notice_section
-X509V3,function,131,nref_nos
-X509V3,function,132,policy_section
-X509V3,function,133,process_pci_value
-X509V3,function,134,r2i_certpol
-X509V3,function,135,r2i_pci
-X509V3,function,136,s2i_ASN1_IA5STRING
-X509V3,function,137,s2i_ASN1_INTEGER
-X509V3,function,138,s2i_ASN1_OCTET_STRING
-X509V3,function,139,s2i_skey_id
-X509V3,function,140,set_dist_point_name
-X509V3,function,141,string_to_hex
-X509V3,function,142,v2i_ASN1_BIT_STRING
-X509V3,function,143,v2i_AUTHORITY_INFO_ACCESS
-X509V3,function,144,v2i_AUTHORITY_KEYID
-X509V3,function,145,v2i_BASIC_CONSTRAINTS
-X509V3,function,146,v2i_EXTENDED_KEY_USAGE
-X509V3,function,147,v2i_GENERAL_NAMES
-X509V3,function,148,v2i_GENERAL_NAME_ex
-X509V3,function,149,v2i_NAME_CONSTRAINTS
-X509V3,function,150,v2i_POLICY_CONSTRAINTS
-X509V3,function,151,v2i_POLICY_MAPPINGS
-X509V3,function,152,v2i_crld
-X509V3,function,153,v2i_idp
-X509V3,function,154,v2i_issuer_alt
-X509V3,function,155,v2i_subject_alt
-X509V3,function,156,v3_generic_extension
-X509V3,reason,100,BAD_IP_ADDRESS
-X509V3,reason,101,BAD_OBJECT
-X509V3,reason,102,BN_DEC2BN_ERROR
-X509V3,reason,103,BN_TO_ASN1_INTEGER_ERROR
-X509V3,reason,104,CANNOT_FIND_FREE_FUNCTION
-X509V3,reason,105,DIRNAME_ERROR
-X509V3,reason,106,DISTPOINT_ALREADY_SET
-X509V3,reason,107,DUPLICATE_ZONE_ID
-X509V3,reason,108,ERROR_CONVERTING_ZONE
-X509V3,reason,109,ERROR_CREATING_EXTENSION
-X509V3,reason,110,ERROR_IN_EXTENSION
-X509V3,reason,111,EXPECTED_A_SECTION_NAME
-X509V3,reason,112,EXTENSION_EXISTS
-X509V3,reason,113,EXTENSION_NAME_ERROR
-X509V3,reason,114,EXTENSION_NOT_FOUND
-X509V3,reason,115,EXTENSION_SETTING_NOT_SUPPORTED
-X509V3,reason,116,EXTENSION_VALUE_ERROR
-X509V3,reason,117,ILLEGAL_EMPTY_EXTENSION
-X509V3,reason,118,ILLEGAL_HEX_DIGIT
-X509V3,reason,119,INCORRECT_POLICY_SYNTAX_TAG
-X509V3,reason,120,INVALID_BOOLEAN_STRING
-X509V3,reason,121,INVALID_EXTENSION_STRING
-X509V3,reason,122,INVALID_MULTIPLE_RDNS
-X509V3,reason,123,INVALID_NAME
-X509V3,reason,124,INVALID_NULL_ARGUMENT
-X509V3,reason,125,INVALID_NULL_NAME
-X509V3,reason,126,INVALID_NULL_VALUE
-X509V3,reason,127,INVALID_NUMBER
-X509V3,reason,128,INVALID_NUMBERS
-X509V3,reason,129,INVALID_OBJECT_IDENTIFIER
-X509V3,reason,130,INVALID_OPTION
-X509V3,reason,131,INVALID_POLICY_IDENTIFIER
-X509V3,reason,132,INVALID_PROXY_POLICY_SETTING
-X509V3,reason,133,INVALID_PURPOSE
-X509V3,reason,134,INVALID_SECTION
-X509V3,reason,135,INVALID_SYNTAX
-X509V3,reason,136,ISSUER_DECODE_ERROR
-X509V3,reason,137,MISSING_VALUE
-X509V3,reason,138,NEED_ORGANIZATION_AND_NUMBERS
-X509V3,reason,139,NO_CONFIG_DATABASE
-X509V3,reason,140,NO_ISSUER_CERTIFICATE
-X509V3,reason,141,NO_ISSUER_DETAILS
-X509V3,reason,142,NO_POLICY_IDENTIFIER
-X509V3,reason,143,NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED
-X509V3,reason,144,NO_PUBLIC_KEY
-X509V3,reason,145,NO_SUBJECT_DETAILS
-X509V3,reason,146,ODD_NUMBER_OF_DIGITS
-X509V3,reason,147,OPERATION_NOT_DEFINED
-X509V3,reason,148,OTHERNAME_ERROR
-X509V3,reason,149,POLICY_LANGUAGE_ALREADY_DEFINED
-X509V3,reason,150,POLICY_PATH_LENGTH
-X509V3,reason,151,POLICY_PATH_LENGTH_ALREADY_DEFINED
-X509V3,reason,152,POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY
-X509V3,reason,153,SECTION_NOT_FOUND
-X509V3,reason,154,UNABLE_TO_GET_ISSUER_DETAILS
-X509V3,reason,155,UNABLE_TO_GET_ISSUER_KEYID
-X509V3,reason,156,UNKNOWN_BIT_STRING_ARGUMENT
-X509V3,reason,157,UNKNOWN_EXTENSION
-X509V3,reason,158,UNKNOWN_EXTENSION_NAME
-X509V3,reason,159,UNKNOWN_OPTION
-X509V3,reason,160,UNSUPPORTED_OPTION
-X509V3,reason,161,UNSUPPORTED_TYPE
-X509V3,reason,162,USER_TOO_LONG
+X509V3,100,BAD_IP_ADDRESS
+X509V3,101,BAD_OBJECT
+X509V3,102,BN_DEC2BN_ERROR
+X509V3,103,BN_TO_ASN1_INTEGER_ERROR
+X509V3,104,CANNOT_FIND_FREE_FUNCTION
+X509V3,105,DIRNAME_ERROR
+X509V3,106,DISTPOINT_ALREADY_SET
+X509V3,107,DUPLICATE_ZONE_ID
+X509V3,108,ERROR_CONVERTING_ZONE
+X509V3,109,ERROR_CREATING_EXTENSION
+X509V3,110,ERROR_IN_EXTENSION
+X509V3,111,EXPECTED_A_SECTION_NAME
+X509V3,112,EXTENSION_EXISTS
+X509V3,113,EXTENSION_NAME_ERROR
+X509V3,114,EXTENSION_NOT_FOUND
+X509V3,115,EXTENSION_SETTING_NOT_SUPPORTED
+X509V3,116,EXTENSION_VALUE_ERROR
+X509V3,117,ILLEGAL_EMPTY_EXTENSION
+X509V3,118,ILLEGAL_HEX_DIGIT
+X509V3,119,INCORRECT_POLICY_SYNTAX_TAG
+X509V3,120,INVALID_BOOLEAN_STRING
+X509V3,121,INVALID_EXTENSION_STRING
+X509V3,122,INVALID_MULTIPLE_RDNS
+X509V3,123,INVALID_NAME
+X509V3,124,INVALID_NULL_ARGUMENT
+X509V3,125,INVALID_NULL_NAME
+X509V3,126,INVALID_NULL_VALUE
+X509V3,127,INVALID_NUMBER
+X509V3,128,INVALID_NUMBERS
+X509V3,129,INVALID_OBJECT_IDENTIFIER
+X509V3,130,INVALID_OPTION
+X509V3,131,INVALID_POLICY_IDENTIFIER
+X509V3,132,INVALID_PROXY_POLICY_SETTING
+X509V3,133,INVALID_PURPOSE
+X509V3,134,INVALID_SECTION
+X509V3,135,INVALID_SYNTAX
+X509V3,136,ISSUER_DECODE_ERROR
+X509V3,137,MISSING_VALUE
+X509V3,138,NEED_ORGANIZATION_AND_NUMBERS
+X509V3,139,NO_CONFIG_DATABASE
+X509V3,140,NO_ISSUER_CERTIFICATE
+X509V3,141,NO_ISSUER_DETAILS
+X509V3,142,NO_POLICY_IDENTIFIER
+X509V3,143,NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED
+X509V3,144,NO_PUBLIC_KEY
+X509V3,145,NO_SUBJECT_DETAILS
+X509V3,146,ODD_NUMBER_OF_DIGITS
+X509V3,147,OPERATION_NOT_DEFINED
+X509V3,148,OTHERNAME_ERROR
+X509V3,149,POLICY_LANGUAGE_ALREADY_DEFINED
+X509V3,150,POLICY_PATH_LENGTH
+X509V3,151,POLICY_PATH_LENGTH_ALREADY_DEFINED
+X509V3,152,POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY
+X509V3,153,SECTION_NOT_FOUND
+X509V3,154,UNABLE_TO_GET_ISSUER_DETAILS
+X509V3,155,UNABLE_TO_GET_ISSUER_KEYID
+X509V3,156,UNKNOWN_BIT_STRING_ARGUMENT
+X509V3,157,UNKNOWN_EXTENSION
+X509V3,158,UNKNOWN_EXTENSION_NAME
+X509V3,159,UNKNOWN_OPTION
+X509V3,160,UNSUPPORTED_OPTION
+X509V3,161,UNSUPPORTED_TYPE
+X509V3,162,USER_TOO_LONG
diff --git a/src/crypto/evp/CMakeLists.txt b/src/crypto/evp/CMakeLists.txt
index 5769fa4..000f076 100644
--- a/src/crypto/evp/CMakeLists.txt
+++ b/src/crypto/evp/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
evp
@@ -6,15 +6,13 @@ add_library(
OBJECT
algorithm.c
- asn1.c
digestsign.c
evp.c
+ evp_asn1.c
evp_ctx.c
p_dsa_asn1.c
p_ec.c
p_ec_asn1.c
- p_hmac.c
- p_hmac_asn1.c
p_rsa.c
p_rsa_asn1.c
pbkdf.c
@@ -49,3 +47,4 @@ add_executable(
target_link_libraries(evp_extra_test crypto)
target_link_libraries(evp_test crypto)
target_link_libraries(pbkdf_test crypto)
+add_dependencies(all_tests evp_extra_test evp_test pbkdf_test)
diff --git a/src/crypto/evp/algorithm.c b/src/crypto/evp/algorithm.c
index ea28dfa..63bc77a 100644
--- a/src/crypto/evp/algorithm.c
+++ b/src/crypto/evp/algorithm.c
@@ -74,8 +74,7 @@ int EVP_DigestSignAlgorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor) {
digest = EVP_MD_CTX_md(ctx);
pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
if (!digest || !pkey) {
- OPENSSL_PUT_ERROR(EVP, EVP_DigestSignAlgorithm,
- EVP_R_CONTEXT_NOT_INITIALISED);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_CONTEXT_NOT_INITIALISED);
return 0;
}
@@ -97,8 +96,7 @@ int EVP_DigestSignAlgorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor) {
* that. */
if (!OBJ_find_sigid_by_algs(&sign_nid, EVP_MD_type(digest),
pkey->ameth->pkey_id)) {
- OPENSSL_PUT_ERROR(EVP, EVP_DigestSignAlgorithm,
- EVP_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
return 0;
}
@@ -122,24 +120,21 @@ int EVP_DigestVerifyInitFromAlgorithm(EVP_MD_CTX *ctx,
/* Convert signature OID into digest and public key OIDs */
if (!OBJ_find_sigid_algs(OBJ_obj2nid(algor->algorithm), &digest_nid,
&pkey_nid)) {
- OPENSSL_PUT_ERROR(EVP, EVP_DigestVerifyInitFromAlgorithm,
- EVP_R_UNKNOWN_SIGNATURE_ALGORITHM);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_SIGNATURE_ALGORITHM);
return 0;
}
/* Check public key OID matches public key type */
ameth = EVP_PKEY_asn1_find(NULL, pkey_nid);
if (ameth == NULL || ameth->pkey_id != pkey->ameth->pkey_id) {
- OPENSSL_PUT_ERROR(EVP, EVP_DigestVerifyInitFromAlgorithm,
- EVP_R_WRONG_PUBLIC_KEY_TYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_WRONG_PUBLIC_KEY_TYPE);
return 0;
}
/* NID_undef signals that there are custom parameters to set. */
if (digest_nid == NID_undef) {
if (!pkey->ameth || !pkey->ameth->digest_verify_init_from_algorithm) {
- OPENSSL_PUT_ERROR(EVP, EVP_DigestVerifyInitFromAlgorithm,
- EVP_R_UNKNOWN_SIGNATURE_ALGORITHM);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_SIGNATURE_ALGORITHM);
return 0;
}
@@ -149,8 +144,7 @@ int EVP_DigestVerifyInitFromAlgorithm(EVP_MD_CTX *ctx,
/* Otherwise, initialize with the digest from the OID. */
digest = EVP_get_digestbynid(digest_nid);
if (digest == NULL) {
- OPENSSL_PUT_ERROR(EVP, EVP_DigestVerifyInitFromAlgorithm,
- EVP_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
return 0;
}
diff --git a/src/crypto/evp/digestsign.c b/src/crypto/evp/digestsign.c
index c163d40..69c483a 100644
--- a/src/crypto/evp/digestsign.c
+++ b/src/crypto/evp/digestsign.c
@@ -55,24 +55,15 @@
#include <openssl/evp.h>
-#include <openssl/digest.h>
#include <openssl/err.h>
#include "internal.h"
#include "../digest/internal.h"
-/* md_begin_digset is a callback from the |EVP_MD_CTX| code that is called when
- * a new digest is begun. */
-static int md_begin_digest(EVP_MD_CTX *ctx) {
- return EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG,
- EVP_PKEY_CTRL_DIGESTINIT, 0, ctx);
-}
-
static const struct evp_md_pctx_ops md_pctx_ops = {
EVP_PKEY_CTX_free,
EVP_PKEY_CTX_dup,
- md_begin_digest,
};
static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
@@ -87,30 +78,16 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
ctx->pctx_ops = &md_pctx_ops;
if (type == NULL) {
- type = EVP_sha1();
- }
-
- if (type == NULL) {
- OPENSSL_PUT_ERROR(EVP, do_sigver_init, EVP_R_NO_DEFAULT_DIGEST);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_NO_DEFAULT_DIGEST);
return 0;
}
if (is_verify) {
- if (ctx->pctx->pmeth->verifyctx_init) {
- if (!ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx)) {
- return 0;
- }
- ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX;
- } else if (!EVP_PKEY_verify_init(ctx->pctx)) {
+ if (!EVP_PKEY_verify_init(ctx->pctx)) {
return 0;
}
} else {
- if (ctx->pctx->pmeth->signctx_init) {
- if (!ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx)) {
- return 0;
- }
- ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX;
- } else if (!EVP_PKEY_sign_init(ctx->pctx)) {
+ if (!EVP_PKEY_sign_init(ctx->pctx)) {
return 0;
}
}
@@ -146,59 +123,37 @@ int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) {
int EVP_DigestSignFinal(EVP_MD_CTX *ctx, uint8_t *out_sig,
size_t *out_sig_len) {
- int r = 0;
- const int has_signctx = ctx->pctx->pmeth->signctx != NULL;
-
if (out_sig) {
EVP_MD_CTX tmp_ctx;
+ int ret;
uint8_t md[EVP_MAX_MD_SIZE];
unsigned int mdlen;
EVP_MD_CTX_init(&tmp_ctx);
- if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx)) {
- return 0;
- }
- if (has_signctx) {
- r = tmp_ctx.pctx->pmeth->signctx(tmp_ctx.pctx, out_sig, out_sig_len, &tmp_ctx);
- } else {
- r = EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen);
- if (r) {
- r = EVP_PKEY_sign(ctx->pctx, out_sig, out_sig_len, md, mdlen);
- }
- }
+ ret = EVP_MD_CTX_copy_ex(&tmp_ctx, ctx) &&
+ EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen) &&
+ EVP_PKEY_sign(ctx->pctx, out_sig, out_sig_len, md, mdlen);
EVP_MD_CTX_cleanup(&tmp_ctx);
- return r;
+
+ return ret;
} else {
- if (has_signctx) {
- return ctx->pctx->pmeth->signctx(ctx->pctx, out_sig, out_sig_len, ctx);
- } else {
- size_t s = EVP_MD_size(ctx->digest);
- return EVP_PKEY_sign(ctx->pctx, out_sig, out_sig_len, NULL, s);
- }
+ size_t s = EVP_MD_size(ctx->digest);
+ return EVP_PKEY_sign(ctx->pctx, out_sig, out_sig_len, NULL, s);
}
}
int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig,
size_t sig_len) {
EVP_MD_CTX tmp_ctx;
+ int ret;
uint8_t md[EVP_MAX_MD_SIZE];
- int r;
unsigned int mdlen;
EVP_MD_CTX_init(&tmp_ctx);
- if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx)) {
- return 0;
- }
- if (ctx->pctx->pmeth->verifyctx) {
- r = tmp_ctx.pctx->pmeth->verifyctx(tmp_ctx.pctx, sig, sig_len, &tmp_ctx);
- } else {
- r = EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen);
- if (r) {
- r = EVP_PKEY_verify(ctx->pctx, sig, sig_len, md, mdlen);
- }
- }
-
+ ret = EVP_MD_CTX_copy_ex(&tmp_ctx, ctx) &&
+ EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen) &&
+ EVP_PKEY_verify(ctx->pctx, sig, sig_len, md, mdlen);
EVP_MD_CTX_cleanup(&tmp_ctx);
- return r;
+ return ret;
}
diff --git a/src/crypto/evp/evp.c b/src/crypto/evp/evp.c
index 0ad5c27..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,17 +72,12 @@
#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 hmac_asn1_meth;
-extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meth;
-
EVP_PKEY *EVP_PKEY_new(void) {
EVP_PKEY *ret;
ret = OPENSSL_malloc(sizeof(EVP_PKEY));
if (ret == NULL) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -159,12 +153,12 @@ int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {
int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) {
if (to->type != from->type) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_copy_parameters, EVP_R_DIFFERENT_KEY_TYPES);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES);
goto err;
}
if (EVP_PKEY_missing_parameters(from)) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_copy_parameters, EVP_R_MISSING_PARAMETERS);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS);
goto err;
}
@@ -207,8 +201,6 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pengine, int nid) {
case EVP_PKEY_RSA:
case EVP_PKEY_RSA2:
return &rsa_asn1_meth;
- case EVP_PKEY_HMAC:
- return &hmac_asn1_meth;
case EVP_PKEY_EC:
return &ec_asn1_meth;
case EVP_PKEY_DSA:
@@ -226,32 +218,6 @@ int EVP_PKEY_type(int nid) {
return meth->pkey_id;
}
-EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, const uint8_t *mac_key,
- size_t mac_key_len) {
- EVP_PKEY_CTX *mac_ctx = NULL;
- EVP_PKEY *ret = NULL;
-
- mac_ctx = EVP_PKEY_CTX_new_id(type, e);
- if (!mac_ctx) {
- return NULL;
- }
-
- if (!EVP_PKEY_keygen_init(mac_ctx) ||
- !EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN,
- EVP_PKEY_CTRL_SET_MAC_KEY, mac_key_len,
- (uint8_t *)mac_key) ||
- !EVP_PKEY_keygen(mac_ctx, &ret)) {
- ret = NULL;
- goto merr;
- }
-
-merr:
- if (mac_ctx) {
- EVP_PKEY_CTX_free(mac_ctx);
- }
- return ret;
-}
-
int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) {
if (EVP_PKEY_assign_RSA(pkey, key)) {
RSA_up_ref(key);
@@ -264,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_PKEY_get1_RSA, EVP_R_EXPECTING_AN_RSA_KEY);
+ 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);
@@ -285,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_PKEY_get1_DSA, EVP_R_EXPECTING_A_DSA_KEY);
+ 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);
@@ -306,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_PKEY_get1_EC_KEY, EVP_R_EXPECTING_AN_EC_KEY_KEY);
+ 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_PKEY_get1_DH, 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) {
@@ -349,10 +315,10 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pengine,
size_t len) {
if (len == 3 && memcmp(name, "RSA", 3) == 0) {
return &rsa_asn1_meth;
- } else if (len == 4 && memcmp(name, "HMAC", 4) == 0) {
- return &hmac_asn1_meth;
} if (len == 2 && memcmp(name, "EC", 2) == 0) {
return &ec_asn1_meth;
+ } else if (len == 3 && memcmp(name, "DSA", 3) == 0) {
+ return &dsa_asn1_meth;
}
return NULL;
}
@@ -366,7 +332,7 @@ int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) {
ameth = EVP_PKEY_asn1_find(NULL, type);
if (ameth == NULL) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_set_type, EVP_R_UNSUPPORTED_ALGORITHM);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
ERR_add_error_dataf("algorithm %d (%s)", type, OBJ_nid2sn(type));
return 0;
}
@@ -436,10 +402,6 @@ int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) {
0, (void *)out_md);
}
-EVP_PKEY *EVP_PKEY_dup(EVP_PKEY *pkey) {
- return EVP_PKEY_up_ref(pkey);
-}
-
void OpenSSL_add_all_algorithms(void) {}
void OpenSSL_add_all_ciphers(void) {}
diff --git a/src/crypto/evp/asn1.c b/src/crypto/evp/evp_asn1.c
index 3df9f52..c57f411 100644
--- a/src/crypto/evp/asn1.c
+++ b/src/crypto/evp/evp_asn1.c
@@ -71,7 +71,7 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp,
if (out == NULL || *out == NULL) {
ret = EVP_PKEY_new();
if (ret == NULL) {
- OPENSSL_PUT_ERROR(EVP, d2i_PrivateKey, ERR_R_EVP_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_EVP_LIB);
return NULL;
}
} else {
@@ -79,22 +79,28 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp,
}
if (!EVP_PKEY_set_type(ret, type)) {
- OPENSSL_PUT_ERROR(EVP, d2i_PrivateKey, EVP_R_UNKNOWN_PUBLIC_KEY_TYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_PUBLIC_KEY_TYPE);
goto err;
}
+ const uint8_t *in = *inp;
if (!ret->ameth->old_priv_decode ||
- !ret->ameth->old_priv_decode(ret, inp, len)) {
+ !ret->ameth->old_priv_decode(ret, &in, len)) {
if (ret->ameth->priv_decode) {
- PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, inp, len);
+ /* Reset |in| in case |old_priv_decode| advanced it on error. */
+ in = *inp;
+ PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &in, len);
if (!p8) {
goto err;
}
EVP_PKEY_free(ret);
ret = EVP_PKCS82PKEY(p8);
PKCS8_PRIV_KEY_INFO_free(p8);
+ if (ret == NULL) {
+ goto err;
+ }
} else {
- OPENSSL_PUT_ERROR(EVP, d2i_PrivateKey, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_ASN1_LIB);
goto err;
}
}
@@ -102,6 +108,7 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp,
if (out != NULL) {
*out = ret;
}
+ *inp = in;
return ret;
err:
@@ -129,17 +136,22 @@ EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, long len) {
keytype = EVP_PKEY_EC;
} else if (sk_ASN1_TYPE_num(inkey) == 3) {
/* This seems to be PKCS8, not traditional format */
- PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, inp, len);
+ p = *inp;
+ PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len);
EVP_PKEY *ret;
sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
if (!p8) {
- OPENSSL_PUT_ERROR(EVP, d2i_AutoPrivateKey,
- EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
return NULL;
}
ret = EVP_PKCS82PKEY(p8);
PKCS8_PRIV_KEY_INFO_free(p8);
+ if (ret == NULL) {
+ return NULL;
+ }
+
+ *inp = p;
if (out) {
*out = ret;
}
@@ -161,7 +173,7 @@ int i2d_PublicKey(EVP_PKEY *key, uint8_t **outp) {
case EVP_PKEY_EC:
return i2o_ECPublicKey(key->pkey.ec, outp);
default:
- OPENSSL_PUT_ERROR(EVP, i2d_PublicKey, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
return -1;
}
}
diff --git a/src/crypto/evp/evp_ctx.c b/src/crypto/evp/evp_ctx.c
index 9f42274..9e038cd 100644
--- a/src/crypto/evp/evp_ctx.c
+++ b/src/crypto/evp/evp_ctx.c
@@ -66,13 +66,8 @@
#include "internal.h"
-extern const EVP_PKEY_METHOD rsa_pkey_meth;
-extern const EVP_PKEY_METHOD hmac_pkey_meth;
-extern const EVP_PKEY_METHOD ec_pkey_meth;
-
static const EVP_PKEY_METHOD *const evp_methods[] = {
&rsa_pkey_meth,
- &hmac_pkey_meth,
&ec_pkey_meth,
};
@@ -102,7 +97,7 @@ static EVP_PKEY_CTX *evp_pkey_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) {
pmeth = evp_pkey_meth_find(id);
if (pmeth == NULL) {
- OPENSSL_PUT_ERROR(EVP, evp_pkey_ctx_new, EVP_R_UNSUPPORTED_ALGORITHM);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
const char *name = OBJ_nid2sn(id);
ERR_add_error_dataf("algorithm %d (%s)", id, name);
return NULL;
@@ -110,7 +105,7 @@ static EVP_PKEY_CTX *evp_pkey_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) {
ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
if (!ret) {
- OPENSSL_PUT_ERROR(EVP, evp_pkey_ctx_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
return NULL;
}
memset(ret, 0, sizeof(EVP_PKEY_CTX));
@@ -192,7 +187,7 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx) {
err:
EVP_PKEY_CTX_free(rctx);
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_dup, ERR_LIB_EVP);
+ OPENSSL_PUT_ERROR(EVP, ERR_LIB_EVP);
return NULL;
}
@@ -207,7 +202,7 @@ void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx) { return ctx->app_data; }
int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd,
int p1, void *p2) {
if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_ctrl, EVP_R_COMMAND_NOT_SUPPORTED);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED);
return 0;
}
if (keytype != -1 && ctx->pmeth->pkey_id != keytype) {
@@ -215,12 +210,12 @@ int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd,
}
if (ctx->operation == EVP_PKEY_OP_UNDEFINED) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_ctrl, EVP_R_NO_OPERATION_SET);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_NO_OPERATION_SET);
return 0;
}
if (optype != -1 && !(ctx->operation & optype)) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_ctrl, EVP_R_INVALID_OPERATION);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_OPERATION);
return 0;
}
@@ -229,8 +224,7 @@ int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd,
int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) {
if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_sign_init,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
@@ -250,12 +244,11 @@ int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) {
int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *sig_len,
const uint8_t *data, size_t data_len) {
if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_sign,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
if (ctx->operation != EVP_PKEY_OP_SIGN) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_sign, EVP_R_OPERATON_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED);
return 0;
}
return ctx->pmeth->sign(ctx, sig, sig_len, data, data_len);
@@ -263,8 +256,7 @@ int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *sig_len,
int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) {
if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_verify_init,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
ctx->operation = EVP_PKEY_OP_VERIFY;
@@ -282,12 +274,11 @@ int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) {
int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t sig_len,
const uint8_t *data, size_t data_len) {
if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_verify,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
if (ctx->operation != EVP_PKEY_OP_VERIFY) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_verify, EVP_R_OPERATON_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED);
return 0;
}
return ctx->pmeth->verify(ctx, sig, sig_len, data, data_len);
@@ -295,8 +286,7 @@ int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t sig_len,
int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) {
if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_encrypt_init,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
ctx->operation = EVP_PKEY_OP_ENCRYPT;
@@ -313,12 +303,11 @@ int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) {
int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen,
const uint8_t *in, size_t inlen) {
if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_encrypt,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
if (ctx->operation != EVP_PKEY_OP_ENCRYPT) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_encrypt, EVP_R_OPERATON_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED);
return 0;
}
return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen);
@@ -326,8 +315,7 @@ int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen,
int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) {
if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_decrypt_init,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
ctx->operation = EVP_PKEY_OP_DECRYPT;
@@ -344,12 +332,11 @@ int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) {
int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen,
const uint8_t *in, size_t inlen) {
if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_decrypt,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
if (ctx->operation != EVP_PKEY_OP_DECRYPT) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_decrypt, EVP_R_OPERATON_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED);
return 0;
}
return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
@@ -357,8 +344,7 @@ int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen,
int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) {
if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive_init,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
ctx->operation = EVP_PKEY_OP_DERIVE;
@@ -377,15 +363,13 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) {
if (!ctx || !ctx->pmeth ||
!(ctx->pmeth->derive || ctx->pmeth->encrypt || ctx->pmeth->decrypt) ||
!ctx->pmeth->ctrl) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive_set_peer,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
if (ctx->operation != EVP_PKEY_OP_DERIVE &&
ctx->operation != EVP_PKEY_OP_ENCRYPT &&
ctx->operation != EVP_PKEY_OP_DECRYPT) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive_set_peer,
- EVP_R_OPERATON_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED);
return 0;
}
@@ -400,12 +384,12 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) {
}
if (!ctx->pkey) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive_set_peer, EVP_R_NO_KEY_SET);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET);
return 0;
}
if (ctx->pkey->type != peer->type) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive_set_peer, EVP_R_DIFFERENT_KEY_TYPES);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES);
return 0;
}
@@ -416,8 +400,7 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) {
* -2 is OK for us here, as well as 1, so we can check for 0 only. */
if (!EVP_PKEY_missing_parameters(peer) &&
!EVP_PKEY_cmp_parameters(ctx->pkey, peer)) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive_set_peer,
- EVP_R_DIFFERENT_PARAMETERS);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_PARAMETERS);
return 0;
}
@@ -437,12 +420,11 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) {
int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *out_key_len) {
if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
if (ctx->operation != EVP_PKEY_OP_DERIVE) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive, EVP_R_OPERATON_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED);
return 0;
}
return ctx->pmeth->derive(ctx, key, out_key_len);
@@ -450,8 +432,7 @@ int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *out_key_len) {
int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) {
if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_keygen_init,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
ctx->operation = EVP_PKEY_OP_KEYGEN;
@@ -467,12 +448,11 @@ int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) {
int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) {
if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_keygen,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
if (ctx->operation != EVP_PKEY_OP_KEYGEN) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_keygen, EVP_R_OPERATON_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED);
return 0;
}
@@ -483,7 +463,7 @@ int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) {
if (!*ppkey) {
*ppkey = EVP_PKEY_new();
if (!*ppkey) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_keygen, ERR_LIB_EVP);
+ OPENSSL_PUT_ERROR(EVP, ERR_LIB_EVP);
return 0;
}
}
diff --git a/src/crypto/evp/evp_extra_test.cc b/src/crypto/evp/evp_extra_test.cc
index 674547d..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[] = {
@@ -321,9 +401,46 @@ static const uint8_t kExampleBadECKeyDER[] = {
0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51
};
+// kExampleBadECKeyDER2 is a sample EC private key encoded as an ECPrivateKey
+// structure, but with the curve OID swapped out for 1.1.1.1.1.1.1.1.1. It is
+// then concatenated with an ECPrivateKey wrapped in a PrivateKeyInfo,
+// optional public key omitted, and with the private key chopped off.
+static const uint8_t kExampleBadECKeyDER2[] = {
+ 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x07, 0x0f, 0x08, 0x72, 0x7a,
+ 0xd4, 0xa0, 0x4a, 0x9c, 0xdd, 0x59, 0xc9, 0x4d, 0x89, 0x68, 0x77, 0x08,
+ 0xb5, 0x6f, 0xc9, 0x5d, 0x30, 0x77, 0x0e, 0xe8, 0xd1, 0xc9, 0xce, 0x0a,
+ 0x8b, 0xb4, 0x6a, 0xa0, 0x0a, 0x06, 0x08, 0x29, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0xe6, 0x2b, 0x69,
+ 0xe2, 0xbf, 0x65, 0x9f, 0x97, 0xbe, 0x2f, 0x1e, 0x0d, 0x94, 0x8a, 0x4c,
+ 0xd5, 0x97, 0x6b, 0xb7, 0xa9, 0x1e, 0x0d, 0x46, 0xfb, 0xdd, 0xa9, 0xa9,
+ 0x1e, 0x9d, 0xdc, 0xba, 0x5a, 0x01, 0xe7, 0xd6, 0x97, 0xa8, 0x0a, 0x18,
+ 0xf9, 0xc3, 0xc4, 0xa3, 0x1e, 0x56, 0xe2, 0x7c, 0x83, 0x48, 0xdb, 0x16,
+ 0x1a, 0x1c, 0xf5, 0x1d, 0x7e, 0xf1, 0x94, 0x2d, 0x4b, 0xcf, 0x72, 0x22,
+ 0xc1, 0x30, 0x41, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
+ 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
+ 0x03, 0x01, 0x07, 0x04, 0x27, 0x30, 0x25, 0x02, 0x01, 0x01, 0x04, 0x20,
+ 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() {
- const uint8_t *derp = kExampleRSAKeyDER;
- ScopedRSA rsa(d2i_RSAPrivateKey(nullptr, &derp, sizeof(kExampleRSAKeyDER)));
+ ScopedRSA rsa(RSA_private_key_from_bytes(kExampleRSAKeyDER,
+ sizeof(kExampleRSAKeyDER)));
if (!rsa) {
return nullptr;
}
@@ -355,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;
}
@@ -411,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);
@@ -421,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;
}
@@ -456,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;
}
@@ -473,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)) ||
@@ -498,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) {
@@ -515,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;
@@ -530,6 +746,64 @@ static bool TestEVP_PKCS82PKEY(void) {
fprintf(stderr, "Imported invalid EC key\n");
return false;
}
+ ERR_clear_error();
+
+ return true;
+}
+
+// Testd2i_PrivateKey tests |d2i_PrivateKey|.
+static bool Testd2i_PrivateKey(void) {
+ const uint8_t *derp = kExampleRSAKeyDER;
+ ScopedEVP_PKEY pkey(d2i_PrivateKey(EVP_PKEY_RSA, nullptr, &derp,
+ sizeof(kExampleRSAKeyDER)));
+ if (!pkey || derp != kExampleRSAKeyDER + sizeof(kExampleRSAKeyDER)) {
+ fprintf(stderr, "Failed to import raw RSA key.\n");
+ return false;
+ }
+
+ derp = kExampleDSAKeyDER;
+ pkey.reset(d2i_PrivateKey(EVP_PKEY_DSA, nullptr, &derp,
+ sizeof(kExampleDSAKeyDER)));
+ if (!pkey || derp != kExampleDSAKeyDER + sizeof(kExampleDSAKeyDER)) {
+ fprintf(stderr, "Failed to import raw DSA key.\n");
+ return false;
+ }
+
+ derp = kExampleRSAKeyPKCS8;
+ pkey.reset(d2i_PrivateKey(EVP_PKEY_RSA, nullptr, &derp,
+ sizeof(kExampleRSAKeyPKCS8)));
+ if (!pkey || derp != kExampleRSAKeyPKCS8 + sizeof(kExampleRSAKeyPKCS8)) {
+ fprintf(stderr, "Failed to import PKCS#8 RSA key.\n");
+ return false;
+ }
+
+ derp = kExampleECKeyDER;
+ pkey.reset(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &derp,
+ sizeof(kExampleECKeyDER)));
+ if (!pkey || derp != kExampleECKeyDER + sizeof(kExampleECKeyDER)) {
+ fprintf(stderr, "Failed to import raw EC key.\n");
+ return false;
+ }
+
+ derp = kExampleBadECKeyDER;
+ pkey.reset(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &derp,
+ sizeof(kExampleBadECKeyDER)));
+ if (pkey) {
+ fprintf(stderr, "Imported invalid EC key.\n");
+ return false;
+ }
+ ERR_clear_error();
+
+ // Copy the input into a |malloc|'d vector to flag memory errors.
+ std::vector<uint8_t> copy(kExampleBadECKeyDER2, kExampleBadECKeyDER2 +
+ sizeof(kExampleBadECKeyDER2));
+ derp = copy.data();
+ pkey.reset(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &derp, copy.size()));
+ if (pkey) {
+ fprintf(stderr, "Imported invalid EC key #2.\n");
+ return false;
+ }
+ ERR_clear_error();
return true;
}
@@ -562,36 +836,26 @@ int main(void) {
return 1;
}
- if (!Testd2i_AutoPrivateKey(kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER),
- EVP_PKEY_RSA)) {
- fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyDER) failed\n");
+ if (!TestBadPSSParameters()) {
+ fprintf(stderr, "TestBadPSSParameters 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 (!Testd2i_AutoPrivateKey()) {
+ fprintf(stderr, "Testd2i_AutoPrivateKey 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 (!TestEVP_PKCS82PKEY()) {
+ fprintf(stderr, "TestEVP_PKCS82PKEY failed\n");
ERR_print_errors_fp(stderr);
return 1;
}
- if (!TestEVP_PKCS82PKEY()) {
- fprintf(stderr, "TestEVP_PKCS82PKEY failed\n");
+ if (!Testd2i_PrivateKey()) {
+ fprintf(stderr, "Testd2i_PrivateKey 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 239f868..7fedc15 100644
--- a/src/crypto/evp/evp_test.cc
+++ b/src/crypto/evp/evp_test.cc
@@ -56,10 +56,19 @@
#include <stdlib.h>
#include <string.h>
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable: 4702)
+#endif
+
#include <map>
#include <string>
#include <vector>
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
#include <openssl/bio.h>
#include <openssl/crypto.h>
#include <openssl/digest.h>
@@ -69,14 +78,12 @@
#include "../test/file_test.h"
#include "../test/scoped_types.h"
-#include "../test/stl_compat.h"
-// evp_test dispatches between multiple test types. HMAC tests test the legacy
-// EVP_PKEY_HMAC API. PrivateKey tests take a key name parameter and single
-// block, decode it as a PEM private key, and save it under that key name.
-// Decrypt, Sign, and Verify tests take a previously imported key name as
-// parameter and test their respective operations.
+// evp_test dispatches between multiple test types. PrivateKey tests take a key
+// name parameter and single block, decode it as a PEM private key, and save it
+// under that key name. Decrypt, Sign, and Verify tests take a previously
+// imported key name as parameter and test their respective operations.
static const EVP_MD *GetDigest(FileTest *t, const std::string &name) {
if (name == "MD5") {
@@ -120,54 +127,10 @@ static bool ImportPrivateKey(FileTest *t, KeyMap *key_map) {
return true;
}
-static bool TestHMAC(FileTest *t) {
- std::string digest_str;
- if (!t->GetAttribute(&digest_str, "HMAC")) {
- return false;
- }
- const EVP_MD *digest = GetDigest(t, digest_str);
- if (digest == nullptr) {
- return false;
- }
-
- std::vector<uint8_t> key, input, output;
- if (!t->GetBytes(&key, "Key") ||
- !t->GetBytes(&input, "Input") ||
- !t->GetBytes(&output, "Output")) {
- return false;
- }
-
- ScopedEVP_PKEY pkey(EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, nullptr,
- bssl::vector_data(&key),
- key.size()));
- ScopedEVP_MD_CTX mctx;
- if (!pkey ||
- !EVP_DigestSignInit(mctx.get(), nullptr, digest, nullptr, pkey.get()) ||
- !EVP_DigestSignUpdate(mctx.get(), bssl::vector_data(&input),
- input.size())) {
- return false;
- }
-
- size_t len;
- std::vector<uint8_t> actual;
- if (!EVP_DigestSignFinal(mctx.get(), nullptr, &len)) {
- return false;
- }
- actual.resize(len);
- if (!EVP_DigestSignFinal(mctx.get(), bssl::vector_data(&actual), &len)) {
- return false;
- }
- actual.resize(len);
- return t->ExpectBytesEqual(bssl::vector_data(&output), output.size(),
- bssl::vector_data(&actual), actual.size());
-}
-
static bool TestEVP(FileTest *t, void *arg) {
KeyMap *key_map = reinterpret_cast<KeyMap*>(arg);
if (t->GetType() == "PrivateKey") {
return ImportPrivateKey(t, key_map);
- } else if (t->GetType() == "HMAC") {
- return TestHMAC(t);
}
int (*key_op_init)(EVP_PKEY_CTX *ctx);
@@ -215,11 +178,11 @@ 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.
- ERR_put_error(ERR_LIB_USER, 0, ERR_R_EVP_LIB, __FILE__, __LINE__);
+ OPENSSL_PUT_ERROR(USER, ERR_R_EVP_LIB);
return false;
}
return true;
@@ -227,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/evp_tests.txt b/src/crypto/evp/evp_tests.txt
index cccfa4f..97ddaa0 100644
--- a/src/crypto/evp/evp_tests.txt
+++ b/src/crypto/evp/evp_tests.txt
@@ -163,12 +163,11 @@ Digest = SHA1
Input = "0123456789ABCDEF1234"
Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec800
# This operation fails without an error code, so ERR_R_EVP_LIB is surfaced.
-Error = public key routines
+Error = BAD_SIGNATURE
# BER signature
Verify = P-256
Digest = SHA1
Input = "0123456789ABCDEF1234"
Output = 3080022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec80000
-# This operation fails without an error code, so ERR_R_EVP_LIB is surfaced.
-Error = public key routines
+Error = BAD_SIGNATURE
diff --git a/src/crypto/evp/internal.h b/src/crypto/evp/internal.h
index 08a7bfb..aa52d53 100644
--- a/src/crypto/evp/internal.h
+++ b/src/crypto/evp/internal.h
@@ -89,8 +89,7 @@ struct evp_pkey_asn1_method_st {
int pkey_base_id;
unsigned long pkey_flags;
- char *pem_str;
- char *info;
+ const char *pem_str;
int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub);
int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk);
@@ -115,8 +114,8 @@ struct evp_pkey_asn1_method_st {
int (*pkey_size)(const EVP_PKEY *pk);
int (*pkey_bits)(const EVP_PKEY *pk);
- int (*param_decode)(EVP_PKEY *pkey, const unsigned char **pder, int derlen);
- int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder);
+ int (*param_decode)(EVP_PKEY *pkey, const uint8_t **pder, int derlen);
+ int (*param_encode)(const EVP_PKEY *pkey, uint8_t **pder);
int (*param_missing)(const EVP_PKEY *pk);
int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from);
int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
@@ -130,9 +129,9 @@ struct evp_pkey_asn1_method_st {
/* Legacy functions for old PEM */
- int (*old_priv_decode)(EVP_PKEY *pkey, const unsigned char **pder,
+ int (*old_priv_decode)(EVP_PKEY *pkey, const uint8_t **pder,
int derlen);
- int (*old_priv_encode)(const EVP_PKEY *pkey, unsigned char **pder);
+ int (*old_priv_encode)(const EVP_PKEY *pkey, uint8_t **pder);
/* Converting parameters to/from AlgorithmIdentifier (X509_ALGOR). */
int (*digest_verify_init_from_algorithm)(EVP_MD_CTX *ctx,
@@ -153,15 +152,12 @@ typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx);
#define EVP_PKEY_OP_SIGN (1 << 3)
#define EVP_PKEY_OP_VERIFY (1 << 4)
#define EVP_PKEY_OP_VERIFYRECOVER (1 << 5)
-#define EVP_PKEY_OP_SIGNCTX (1 << 6)
-#define EVP_PKEY_OP_VERIFYCTX (1 << 7)
-#define EVP_PKEY_OP_ENCRYPT (1 << 8)
-#define EVP_PKEY_OP_DECRYPT (1 << 9)
-#define EVP_PKEY_OP_DERIVE (1 << 10)
+#define EVP_PKEY_OP_ENCRYPT (1 << 6)
+#define EVP_PKEY_OP_DECRYPT (1 << 7)
+#define EVP_PKEY_OP_DERIVE (1 << 8)
#define EVP_PKEY_OP_TYPE_SIG \
- (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER | \
- EVP_PKEY_OP_SIGNCTX | EVP_PKEY_OP_VERIFYCTX)
+ (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER)
#define EVP_PKEY_OP_TYPE_CRYPT (EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT)
@@ -181,13 +177,8 @@ typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx);
OPENSSL_EXPORT int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
int cmd, int p1, void *p2);
-/* EVP_PKEY_CTRL_DIGESTINIT is an internal value. It's called by
- * EVP_DigestInit_ex to signal the |EVP_PKEY| that a digest operation is
- * starting.
- *
- * TODO(davidben): This is only needed to support the deprecated HMAC |EVP_PKEY|
- * types. */
-#define EVP_PKEY_CTRL_DIGESTINIT 3
+#define EVP_PKEY_CTRL_MD 1
+#define EVP_PKEY_CTRL_GET_MD 2
/* EVP_PKEY_CTRL_PEER_KEY is called with different values of |p1|:
* 0: Is called from |EVP_PKEY_derive_set_peer| and |p2| contains a peer key.
@@ -198,21 +189,12 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
* (EC)DH always return one in this case.
* 3: Is called with |p2| == NULL to set whether the peer's key was used.
* (EC)DH always return one in this case. This was only used for GOST. */
-#define EVP_PKEY_CTRL_PEER_KEY 4
-
-/* EVP_PKEY_CTRL_SET_MAC_KEY sets a MAC key. For example, this can be done an
- * |EVP_PKEY_CTX| prior to calling |EVP_PKEY_keygen| in order to generate an
- * HMAC |EVP_PKEY| with the given key. It returns one on success and zero on
- * error. */
-#define EVP_PKEY_CTRL_SET_MAC_KEY 5
+#define EVP_PKEY_CTRL_PEER_KEY 3
/* EVP_PKEY_ALG_CTRL is the base value from which key-type specific ctrl
* commands are numbered. */
#define EVP_PKEY_ALG_CTRL 0x1000
-#define EVP_PKEY_CTRL_MD 1
-#define EVP_PKEY_CTRL_GET_MD 2
-
#define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1)
#define EVP_PKEY_CTRL_GET_RSA_PADDING (EVP_PKEY_ALG_CTRL + 2)
#define EVP_PKEY_CTRL_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 3)
@@ -260,36 +242,34 @@ struct evp_pkey_method_st {
int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
int (*sign_init)(EVP_PKEY_CTX *ctx);
- int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
- const unsigned char *tbs, size_t tbslen);
+ int (*sign)(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen,
+ const uint8_t *tbs, size_t tbslen);
int (*verify_init)(EVP_PKEY_CTX *ctx);
- int (*verify)(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen,
- const unsigned char *tbs, size_t tbslen);
-
- int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
- int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
- EVP_MD_CTX *mctx);
-
- int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
- int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig, int siglen,
- EVP_MD_CTX *mctx);
+ int (*verify)(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen,
+ const uint8_t *tbs, size_t tbslen);
int (*encrypt_init)(EVP_PKEY_CTX *ctx);
- int (*encrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
- const unsigned char *in, size_t inlen);
+ int (*encrypt)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen,
+ const uint8_t *in, size_t inlen);
int (*decrypt_init)(EVP_PKEY_CTX *ctx);
- int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
- const unsigned char *in, size_t inlen);
+ int (*decrypt)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen,
+ const uint8_t *in, size_t inlen);
int (*derive_init)(EVP_PKEY_CTX *ctx);
- int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
+ int (*derive)(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *keylen);
int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
- int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value);
} /* 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_dsa_asn1.c b/src/crypto/evp/p_dsa_asn1.c
index 2c3326e..3c89e5e 100644
--- a/src/crypto/evp/p_dsa_asn1.c
+++ b/src/crypto/evp/p_dsa_asn1.c
@@ -91,29 +91,29 @@ static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) {
dsa = d2i_DSAparams(NULL, &pm, pmlen);
if (dsa == NULL) {
- OPENSSL_PUT_ERROR(EVP, dsa_pub_decode, EVP_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
goto err;
}
} else if (ptype == V_ASN1_NULL || ptype == V_ASN1_UNDEF) {
dsa = DSA_new();
if (dsa == NULL) {
- OPENSSL_PUT_ERROR(EVP, dsa_pub_decode, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
goto err;
}
} else {
- OPENSSL_PUT_ERROR(EVP, dsa_pub_decode, EVP_R_PARAMETER_ENCODING_ERROR);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_PARAMETER_ENCODING_ERROR);
goto err;
}
public_key = d2i_ASN1_INTEGER(NULL, &p, pklen);
if (public_key == NULL) {
- OPENSSL_PUT_ERROR(EVP, dsa_pub_decode, EVP_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
goto err;
}
dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL);
if (dsa->pub_key == NULL) {
- OPENSSL_PUT_ERROR(EVP, dsa_pub_decode, EVP_R_BN_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_BN_DECODE_ERROR);
goto err;
}
@@ -129,21 +129,37 @@ err:
static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) {
DSA *dsa;
- void *pval = NULL;
+ ASN1_STRING *pval = NULL;
uint8_t *penc = NULL;
int penclen;
dsa = pkey->pkey.dsa;
dsa->write_params = 0;
- penclen = i2d_DSAPublicKey(dsa, &penc);
+ int ptype;
+ if (dsa->p && dsa->q && dsa->g) {
+ pval = ASN1_STRING_new();
+ if (!pval) {
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ pval->length = i2d_DSAparams(dsa, &pval->data);
+ if (pval->length <= 0) {
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ ptype = V_ASN1_SEQUENCE;
+ } else {
+ ptype = V_ASN1_UNDEF;
+ }
+ penclen = i2d_DSAPublicKey(dsa, &penc);
if (penclen <= 0) {
- OPENSSL_PUT_ERROR(EVP, dsa_pub_encode, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
goto err;
}
- if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA), V_ASN1_UNDEF, pval,
+ if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA), ptype, pval,
penc, penclen)) {
return 1;
}
@@ -192,23 +208,23 @@ static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) {
/* We have parameters. Now set private key */
dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL);
if (dsa->priv_key == NULL) {
- OPENSSL_PUT_ERROR(EVP, dsa_priv_decode, ERR_LIB_BN);
+ OPENSSL_PUT_ERROR(EVP, ERR_LIB_BN);
goto dsaerr;
}
/* Calculate public key. */
dsa->pub_key = BN_new();
if (dsa->pub_key == NULL) {
- OPENSSL_PUT_ERROR(EVP, dsa_priv_decode, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
goto dsaerr;
}
ctx = BN_CTX_new();
if (ctx == NULL) {
- OPENSSL_PUT_ERROR(EVP, dsa_priv_decode, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
goto dsaerr;
}
if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) {
- OPENSSL_PUT_ERROR(EVP, dsa_priv_decode, ERR_LIB_BN);
+ OPENSSL_PUT_ERROR(EVP, ERR_LIB_BN);
goto dsaerr;
}
@@ -219,7 +235,7 @@ static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) {
return 1;
decerr:
- OPENSSL_PUT_ERROR(EVP, dsa_priv_decode, EVP_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
dsaerr:
BN_CTX_free(ctx);
@@ -235,19 +251,19 @@ static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) {
int dplen;
if (!pkey->pkey.dsa || !pkey->pkey.dsa->priv_key) {
- OPENSSL_PUT_ERROR(EVP, dsa_priv_encode, EVP_R_MISSING_PARAMETERS);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS);
goto err;
}
params = ASN1_STRING_new();
if (!params) {
- OPENSSL_PUT_ERROR(EVP, dsa_priv_encode, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
goto err;
}
params->length = i2d_DSAparams(pkey->pkey.dsa, &params->data);
if (params->length <= 0) {
- OPENSSL_PUT_ERROR(EVP, dsa_priv_encode, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
goto err;
}
params->type = V_ASN1_SEQUENCE;
@@ -256,13 +272,14 @@ static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) {
prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL);
if (!prkey) {
- OPENSSL_PUT_ERROR(EVP, dsa_priv_encode, ERR_LIB_BN);
+ OPENSSL_PUT_ERROR(EVP, ERR_LIB_BN);
goto err;
}
dplen = i2d_ASN1_INTEGER(prkey, &dp);
ASN1_INTEGER_free(prkey);
+ prkey = NULL;
if (!PKCS8_pkey_set0(p8, (ASN1_OBJECT *)OBJ_nid2obj(NID_dsa), 0,
V_ASN1_SEQUENCE, params, dp, dplen)) {
@@ -375,7 +392,7 @@ static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) {
m = (uint8_t *)OPENSSL_malloc(buf_len + 10);
if (m == NULL) {
- OPENSSL_PUT_ERROR(EVP, do_dsa_print, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -404,7 +421,7 @@ static int dsa_param_decode(EVP_PKEY *pkey, const uint8_t **pder, int derlen) {
DSA *dsa;
dsa = d2i_DSAparams(NULL, pder, derlen);
if (dsa == NULL) {
- OPENSSL_PUT_ERROR(EVP, dsa_param_decode, ERR_R_DSA_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_DSA_LIB);
return 0;
}
EVP_PKEY_assign_DSA(pkey, dsa);
@@ -435,7 +452,7 @@ static int old_dsa_priv_decode(EVP_PKEY *pkey, const uint8_t **pder,
DSA *dsa;
dsa = d2i_DSAPrivateKey(NULL, pder, derlen);
if (dsa == NULL) {
- OPENSSL_PUT_ERROR(EVP, old_dsa_priv_decode, ERR_R_DSA_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_DSA_LIB);
return 0;
}
EVP_PKEY_assign_DSA(pkey, dsa);
@@ -469,7 +486,7 @@ static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
update_buflen(dsa_sig->s, &buf_len);
m = OPENSSL_malloc(buf_len + 10);
if (m == NULL) {
- OPENSSL_PUT_ERROR(EVP, dsa_sig_print, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -492,7 +509,6 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = {
0,
"DSA",
- "OpenSSL DSA method",
dsa_pub_decode,
dsa_pub_encode,
@@ -520,4 +536,7 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = {
int_dsa_free,
old_dsa_priv_decode,
old_dsa_priv_encode,
+
+ NULL /* digest_verify_init_from_algorithm */,
+ NULL /* digest_sign_algorithm */,
};
diff --git a/src/crypto/evp/p_ec.c b/src/crypto/evp/p_ec.c
index 73c00d8..77f213d 100644
--- a/src/crypto/evp/p_ec.c
+++ b/src/crypto/evp/p_ec.c
@@ -125,25 +125,18 @@ static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx) {
static int pkey_ec_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen,
const uint8_t *tbs, size_t tbslen) {
- int type;
unsigned int sltmp;
- EC_PKEY_CTX *dctx = ctx->data;
EC_KEY *ec = ctx->pkey->pkey.ec;
if (!sig) {
*siglen = ECDSA_size(ec);
return 1;
} else if (*siglen < (size_t)ECDSA_size(ec)) {
- OPENSSL_PUT_ERROR(EVP, pkey_ec_sign, EVP_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL);
return 0;
}
- type = NID_sha1;
- if (dctx->md) {
- type = EVP_MD_type(dctx->md);
- }
-
- if (!ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec)) {
+ if (!ECDSA_sign(0, tbs, tbslen, sig, &sltmp, ec)) {
return 0;
}
*siglen = (size_t)sltmp;
@@ -152,16 +145,7 @@ static int pkey_ec_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen,
static int pkey_ec_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen,
const uint8_t *tbs, size_t tbslen) {
- int type;
- EC_PKEY_CTX *dctx = ctx->data;
- EC_KEY *ec = ctx->pkey->pkey.ec;
-
- type = NID_sha1;
- if (dctx->md) {
- type = EVP_MD_type(dctx->md);
- }
-
- return ECDSA_verify(type, tbs, tbslen, sig, siglen, ec);
+ return ECDSA_verify(0, tbs, tbslen, sig, siglen, ctx->pkey->pkey.ec);
}
static int pkey_ec_derive(EVP_PKEY_CTX *ctx, uint8_t *key,
@@ -172,7 +156,7 @@ static int pkey_ec_derive(EVP_PKEY_CTX *ctx, uint8_t *key,
EC_KEY *eckey;
if (!ctx->pkey || !ctx->peerkey) {
- OPENSSL_PUT_ERROR(EVP, pkey_ec_derive, EVP_R_KEYS_NOT_SET);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_KEYS_NOT_SET);
return 0;
}
@@ -207,7 +191,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
group = EC_GROUP_new_by_curve_name(p1);
if (group == NULL) {
- OPENSSL_PUT_ERROR(EVP, pkey_ec_ctrl, EVP_R_INVALID_CURVE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_CURVE);
return 0;
}
EC_GROUP_free(dctx->gen_group);
@@ -221,7 +205,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha512) {
- OPENSSL_PUT_ERROR(EVP, pkey_ec_ctrl, EVP_R_INVALID_DIGEST_TYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_DIGEST_TYPE);
return 0;
}
dctx->md = p2;
@@ -232,12 +216,11 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
return 1;
case EVP_PKEY_CTRL_PEER_KEY:
- /* Default behaviour is OK */
- case EVP_PKEY_CTRL_DIGESTINIT:
+ /* Default behaviour is OK */
return 1;
default:
- OPENSSL_PUT_ERROR(EVP, pkey_ec_ctrl, EVP_R_COMMAND_NOT_SUPPORTED);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED);
return 0;
}
}
@@ -248,7 +231,7 @@ static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) {
int ret = 0;
if (dctx->gen_group == NULL) {
- OPENSSL_PUT_ERROR(EVP, pkey_ec_paramgen, EVP_R_NO_PARAMETERS_SET);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_NO_PARAMETERS_SET);
return 0;
}
ec = EC_KEY_new();
@@ -268,7 +251,7 @@ static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) {
EC_KEY *ec = NULL;
EC_PKEY_CTX *dctx = ctx->data;
if (ctx->pkey == NULL && dctx->gen_group == NULL) {
- OPENSSL_PUT_ERROR(EVP, pkey_ec_keygen, EVP_R_NO_PARAMETERS_SET);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_NO_PARAMETERS_SET);
return 0;
}
ec = EC_KEY_new();
@@ -290,12 +273,11 @@ static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) {
}
const EVP_PKEY_METHOD ec_pkey_meth = {
- EVP_PKEY_EC, 0 /* flags */, pkey_ec_init,
- pkey_ec_copy, pkey_ec_cleanup, 0 /* paramgen_init */,
- pkey_ec_paramgen, 0 /* keygen_init */, pkey_ec_keygen,
- 0 /* sign_init */, pkey_ec_sign, 0 /* verify_init */,
- pkey_ec_verify, 0 /* signctx_init */, 0 /* signctx */,
- 0 /* verifyctx_init */, 0 /* verifyctx */, 0 /* encrypt_init */,
- 0 /* encrypt */, 0 /* decrypt_init */, 0 /* decrypt */,
- 0 /* derive_init */, pkey_ec_derive, pkey_ec_ctrl,
+ EVP_PKEY_EC, 0 /* flags */, pkey_ec_init,
+ pkey_ec_copy, pkey_ec_cleanup, 0 /* paramgen_init */,
+ pkey_ec_paramgen, 0 /* keygen_init */, pkey_ec_keygen,
+ 0 /* sign_init */, pkey_ec_sign, 0 /* verify_init */,
+ pkey_ec_verify, 0 /* encrypt_init */, 0 /* encrypt */,
+ 0 /* decrypt_init */, 0 /* decrypt */, 0 /* derive_init */,
+ pkey_ec_derive, pkey_ec_ctrl,
};
diff --git a/src/crypto/evp/p_ec_asn1.c b/src/crypto/evp/p_ec_asn1.c
index fbbf4e7..f40b976 100644
--- a/src/crypto/evp/p_ec_asn1.c
+++ b/src/crypto/evp/p_ec_asn1.c
@@ -71,13 +71,13 @@ static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key) {
int nid;
if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) {
- OPENSSL_PUT_ERROR(EVP, eckey_param2type, EVP_R_MISSING_PARAMETERS);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS);
return 0;
}
nid = EC_GROUP_get_curve_name(group);
if (nid == NID_undef) {
- OPENSSL_PUT_ERROR(EVP, eckey_param2type, EVP_R_NO_NID_FOR_CURVE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_NO_NID_FOR_CURVE);
return 0;
}
@@ -94,7 +94,7 @@ static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) {
int penclen;
if (!eckey_param2type(&ptype, &pval, ec_key)) {
- OPENSSL_PUT_ERROR(EVP, eckey_pub_encode, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
return 0;
}
penclen = i2o_ECPublicKey(ec_key, NULL);
@@ -137,7 +137,7 @@ static EC_KEY *eckey_type2param(int ptype, void *pval) {
eckey = d2i_ECParameters(NULL, &pm, pmlen);
if (eckey == NULL) {
- OPENSSL_PUT_ERROR(EVP, eckey_type2param, EVP_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
goto err;
}
} else if (ptype == V_ASN1_OBJECT) {
@@ -150,7 +150,7 @@ static EC_KEY *eckey_type2param(int ptype, void *pval) {
goto err;
}
} else {
- OPENSSL_PUT_ERROR(EVP, eckey_type2param, EVP_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
goto err;
}
@@ -177,13 +177,13 @@ static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) {
eckey = eckey_type2param(ptype, pval);
if (!eckey) {
- OPENSSL_PUT_ERROR(EVP, eckey_pub_decode, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
return 0;
}
/* We have parameters now set public key */
if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
- OPENSSL_PUT_ERROR(EVP, eckey_pub_decode, EVP_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
goto err;
}
@@ -232,7 +232,7 @@ static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) {
/* We have parameters now set private key */
if (!d2i_ECPrivateKey(&eckey, &p, pklen)) {
- OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, EVP_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
goto ecerr;
}
@@ -246,23 +246,23 @@ static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) {
group = EC_KEY_get0_group(eckey);
pub_key = EC_POINT_new(group);
if (pub_key == NULL) {
- OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
goto ecliberr;
}
if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) {
EC_POINT_free(pub_key);
- OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
goto ecliberr;
}
priv_key = EC_KEY_get0_private_key(eckey);
if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) {
EC_POINT_free(pub_key);
- OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
goto ecliberr;
}
if (EC_KEY_set_public_key(eckey, pub_key) == 0) {
EC_POINT_free(pub_key);
- OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
goto ecliberr;
}
EC_POINT_free(pub_key);
@@ -272,7 +272,7 @@ static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) {
return 1;
ecliberr:
- OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
ecerr:
if (eckey) {
EC_KEY_free(eckey);
@@ -290,7 +290,7 @@ static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) {
ec_key = pkey->pkey.ec;
if (!eckey_param2type(&ptype, &pval, ec_key)) {
- OPENSSL_PUT_ERROR(EVP, eckey_priv_encode, EVP_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
return 0;
}
@@ -304,20 +304,20 @@ static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) {
eplen = i2d_ECPrivateKey(ec_key, NULL);
if (!eplen) {
EC_KEY_set_enc_flags(ec_key, old_flags);
- OPENSSL_PUT_ERROR(EVP, eckey_priv_encode, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
return 0;
}
ep = (uint8_t *)OPENSSL_malloc(eplen);
if (!ep) {
EC_KEY_set_enc_flags(ec_key, old_flags);
- OPENSSL_PUT_ERROR(EVP, eckey_priv_encode, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
return 0;
}
p = ep;
if (!i2d_ECPrivateKey(ec_key, &p)) {
EC_KEY_set_enc_flags(ec_key, old_flags);
OPENSSL_free(ep);
- OPENSSL_PUT_ERROR(EVP, eckey_priv_encode, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
return 0;
}
/* restore old encoding flags */
@@ -325,6 +325,7 @@ static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) {
if (!PKCS8_pkey_set0(p8, (ASN1_OBJECT *)OBJ_nid2obj(NID_X9_62_id_ecPublicKey),
0, ptype, pval, ep, eplen)) {
+ OPENSSL_free(ep);
return 0;
}
@@ -336,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) {
@@ -386,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;
@@ -457,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;
}
@@ -478,10 +466,9 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
err:
if (!ret) {
- OPENSSL_PUT_ERROR(EVP, do_EC_KEY_print, reason);
+ OPENSSL_PUT_ERROR(EVP, reason);
}
OPENSSL_free(pub_key_bytes);
- BN_free(order);
BN_CTX_free(ctx);
OPENSSL_free(buffer);
return ret;
@@ -491,7 +478,7 @@ static int eckey_param_decode(EVP_PKEY *pkey, const uint8_t **pder,
int derlen) {
EC_KEY *eckey;
if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) {
- OPENSSL_PUT_ERROR(EVP, eckey_param_decode, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
return 0;
}
EVP_PKEY_assign_EC_KEY(pkey, eckey);
@@ -526,7 +513,7 @@ static int old_ec_priv_decode(EVP_PKEY *pkey, const uint8_t **pder,
int derlen) {
EC_KEY *ec;
if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) {
- OPENSSL_PUT_ERROR(EVP, old_ec_priv_decode, EVP_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
return 0;
}
EVP_PKEY_assign_EC_KEY(pkey, ec);
@@ -542,7 +529,6 @@ const EVP_PKEY_ASN1_METHOD ec_asn1_meth = {
EVP_PKEY_EC,
0,
"EC",
- "OpenSSL EC algorithm",
eckey_pub_decode,
eckey_pub_encode,
@@ -569,5 +555,8 @@ const EVP_PKEY_ASN1_METHOD ec_asn1_meth = {
int_ec_free,
old_ec_priv_decode,
- old_ec_priv_encode
+ old_ec_priv_encode,
+
+ NULL /* digest_verify_init_from_algorithm */,
+ NULL /* digest_sign_algorithm */,
};
diff --git a/src/crypto/evp/p_hmac.c b/src/crypto/evp/p_hmac.c
deleted file mode 100644
index 7d3254a..0000000
--- a/src/crypto/evp/p_hmac.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2007.
- */
-/* ====================================================================
- * Copyright (c) 2007 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com). */
-
-#include <openssl/evp.h>
-
-#include <string.h>
-
-#include <openssl/asn1.h>
-#include <openssl/err.h>
-#include <openssl/hmac.h>
-#include <openssl/mem.h>
-#include <openssl/obj.h>
-
-#include "internal.h"
-#include "../digest/internal.h"
-
-
-typedef struct {
- const EVP_MD *md; /* MD for HMAC use */
- ASN1_OCTET_STRING ktmp; /* Temp storage for key */
- HMAC_CTX ctx;
-} HMAC_PKEY_CTX;
-
-static int pkey_hmac_init(EVP_PKEY_CTX *ctx) {
- HMAC_PKEY_CTX *hctx;
- hctx = OPENSSL_malloc(sizeof(HMAC_PKEY_CTX));
- if (!hctx) {
- return 0;
- }
- memset(hctx, 0, sizeof(HMAC_PKEY_CTX));
- hctx->ktmp.type = V_ASN1_OCTET_STRING;
- HMAC_CTX_init(&hctx->ctx);
-
- ctx->data = hctx;
-
- return 1;
-}
-
-static int pkey_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) {
- HMAC_PKEY_CTX *sctx, *dctx;
- if (!pkey_hmac_init(dst)) {
- return 0;
- }
- sctx = src->data;
- dctx = dst->data;
- dctx->md = sctx->md;
- HMAC_CTX_init(&dctx->ctx);
- if (!HMAC_CTX_copy_ex(&dctx->ctx, &sctx->ctx)) {
- return 0;
- }
- if (sctx->ktmp.data) {
- if (!ASN1_OCTET_STRING_set(&dctx->ktmp, sctx->ktmp.data,
- sctx->ktmp.length)) {
- return 0;
- }
- }
- return 1;
-}
-
-static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx) {
- HMAC_PKEY_CTX *hctx = ctx->data;
-
- if (hctx == NULL) {
- return;
- }
-
- HMAC_CTX_cleanup(&hctx->ctx);
- if (hctx->ktmp.data) {
- if (hctx->ktmp.length) {
- OPENSSL_cleanse(hctx->ktmp.data, hctx->ktmp.length);
- }
- OPENSSL_free(hctx->ktmp.data);
- hctx->ktmp.data = NULL;
- }
- OPENSSL_free(hctx);
-}
-
-static int pkey_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) {
- ASN1_OCTET_STRING *hkey = NULL;
- HMAC_PKEY_CTX *hctx = ctx->data;
-
- if (!hctx->ktmp.data) {
- return 0;
- }
- hkey = ASN1_OCTET_STRING_dup(&hctx->ktmp);
- if (!hkey) {
- return 0;
- }
- EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, hkey);
-
- return 1;
-}
-
-static void int_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
- HMAC_PKEY_CTX *hctx = ctx->pctx->data;
- HMAC_Update(&hctx->ctx, data, count);
-}
-
-static int hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) {
- /* |mctx| gets repurposed as a hook to call |HMAC_Update|. Suppress the
- * automatic setting of |mctx->update| and the rest of its initialization. */
- EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
- mctx->update = int_update;
- return 1;
-}
-
-static int hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
- EVP_MD_CTX *mctx) {
- unsigned int hlen;
- HMAC_PKEY_CTX *hctx = ctx->data;
- size_t md_size = EVP_MD_CTX_size(mctx);
-
- if (!sig) {
- *siglen = md_size;
- return 1;
- } else if (*siglen < md_size) {
- OPENSSL_PUT_ERROR(EVP, hmac_signctx, EVP_R_BUFFER_TOO_SMALL);
- return 0;
- }
-
- if (!HMAC_Final(&hctx->ctx, sig, &hlen)) {
- return 0;
- }
- *siglen = (size_t)hlen;
- return 1;
-}
-
-static int pkey_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
- HMAC_PKEY_CTX *hctx = ctx->data;
- ASN1_OCTET_STRING *key;
-
- switch (type) {
- case EVP_PKEY_CTRL_SET_MAC_KEY:
- if ((!p2 && p1 > 0) || (p1 < -1)) {
- return 0;
- }
- if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1)) {
- return 0;
- }
- break;
-
- case EVP_PKEY_CTRL_MD:
- hctx->md = p2;
- break;
-
- case EVP_PKEY_CTRL_DIGESTINIT:
- key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
- if (!HMAC_Init_ex(&hctx->ctx, key->data, key->length, hctx->md,
- ctx->engine)) {
- return 0;
- }
- break;
-
- default:
- OPENSSL_PUT_ERROR(EVP, pkey_hmac_ctrl, EVP_R_COMMAND_NOT_SUPPORTED);
- return 0;
- }
- return 1;
-}
-
-const EVP_PKEY_METHOD hmac_pkey_meth = {
- EVP_PKEY_HMAC, 0 /* flags */, pkey_hmac_init,
- pkey_hmac_copy, pkey_hmac_cleanup, 0 /* paramgen_init */,
- 0 /* paramgen */, 0 /* keygen_init */, pkey_hmac_keygen,
- 0 /* sign_init */, 0 /* sign */, 0 /* verify_init */,
- 0 /* verify */, hmac_signctx_init, hmac_signctx,
- 0 /* verifyctx_init */, 0 /* verifyctx */, 0 /* encrypt_init */,
- 0 /* encrypt */, 0 /* decrypt_init */, 0 /* decrypt */,
- 0 /* derive_init */, 0 /* derive */, pkey_hmac_ctrl,
- 0,
-};
diff --git a/src/crypto/evp/p_hmac_asn1.c b/src/crypto/evp/p_hmac_asn1.c
deleted file mode 100644
index 8aa6676..0000000
--- a/src/crypto/evp/p_hmac_asn1.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2007.
- */
-/* ====================================================================
- * Copyright (c) 2007 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com). */
-
-#include <openssl/evp.h>
-
-#include <openssl/asn1.h>
-#include <openssl/digest.h>
-#include <openssl/mem.h>
-#include <openssl/obj.h>
-
-#include "internal.h"
-
-
-static int hmac_size(const EVP_PKEY *pkey) { return EVP_MAX_MD_SIZE; }
-
-static void hmac_key_free(EVP_PKEY *pkey) {
- ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr;
- if (os) {
- if (os->data) {
- OPENSSL_cleanse(os->data, os->length);
- }
- ASN1_OCTET_STRING_free(os);
- }
-}
-
-const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = {
- EVP_PKEY_HMAC, EVP_PKEY_HMAC, 0 /* flags */,
- "HMAC", "OpenSSL HMAC method", 0 /* pub_decode */,
- 0 /* pub_encode */, 0 /* pub_cmp */, 0 /* pub_print */,
- 0 /*priv_decode */, 0 /* priv_encode */, 0 /* priv_print */,
- 0 /* pkey_opaque */, 0 /* pkey_supports_digest */,
- hmac_size, 0 /* pkey_bits */, 0 /* param_decode */,
- 0 /* param_encode*/, 0 /* param_missing*/, 0 /* param_copy*/,
- 0 /* param_cmp*/, 0 /* param_print*/, 0 /* sig_print*/,
- hmac_key_free, 0 /* old_priv_decode */,
- 0 /* old_priv_encode */
-};
diff --git a/src/crypto/evp/p_rsa.c b/src/crypto/evp/p_rsa.c
index 5abc075..895d351 100644
--- a/src/crypto/evp/p_rsa.c
+++ b/src/crypto/evp/p_rsa.c
@@ -174,7 +174,7 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen,
}
if (*siglen < key_len) {
- OPENSSL_PUT_ERROR(EVP, pkey_rsa_sign, EVP_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL);
return 0;
}
@@ -182,12 +182,12 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen,
unsigned int out_len;
if (tbslen != EVP_MD_size(rctx->md)) {
- OPENSSL_PUT_ERROR(EVP, pkey_rsa_sign, EVP_R_INVALID_DIGEST_LENGTH);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_DIGEST_LENGTH);
return 0;
}
if (EVP_MD_type(rctx->md) == NID_mdc2) {
- OPENSSL_PUT_ERROR(EVP, pkey_rsa_sign, EVP_R_NO_MDC2_SUPPORT);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_NO_MDC2_SUPPORT);
return 0;
}
@@ -268,7 +268,7 @@ static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen,
}
if (*outlen < key_len) {
- OPENSSL_PUT_ERROR(EVP, pkey_rsa_encrypt, EVP_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL);
return 0;
}
@@ -300,7 +300,7 @@ static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out,
}
if (*outlen < key_len) {
- OPENSSL_PUT_ERROR(EVP, pkey_rsa_decrypt, EVP_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL);
return 0;
}
@@ -333,7 +333,7 @@ static int check_padding_md(const EVP_MD *md, int padding) {
}
if (padding == RSA_NO_PADDING) {
- OPENSSL_PUT_ERROR(EVP, check_padding_md, EVP_R_INVALID_PADDING_MODE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE);
return 0;
}
@@ -361,8 +361,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
0 == (ctx->operation & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) ||
(p1 == RSA_PKCS1_OAEP_PADDING &&
0 == (ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))) {
- OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl,
- EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
return 0;
}
if ((p1 == RSA_PKCS1_PSS_PADDING || p1 == RSA_PKCS1_OAEP_PADDING) &&
@@ -379,7 +378,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
case EVP_PKEY_CTRL_RSA_PSS_SALTLEN:
case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN:
if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) {
- OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PSS_SALTLEN);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PSS_SALTLEN);
return 0;
}
if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) {
@@ -394,7 +393,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
case EVP_PKEY_CTRL_RSA_KEYGEN_BITS:
if (p1 < 256) {
- OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_KEYBITS);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_KEYBITS);
return 0;
}
rctx->nbits = p1;
@@ -411,7 +410,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
case EVP_PKEY_CTRL_RSA_OAEP_MD:
case EVP_PKEY_CTRL_GET_RSA_OAEP_MD:
if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
- OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PADDING_MODE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE);
return 0;
}
if (type == EVP_PKEY_CTRL_GET_RSA_OAEP_MD) {
@@ -436,7 +435,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
case EVP_PKEY_CTRL_GET_RSA_MGF1_MD:
if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING &&
rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
- OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_MGF1_MD);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_MGF1_MD);
return 0;
}
if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) {
@@ -452,13 +451,11 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
case EVP_PKEY_CTRL_RSA_OAEP_LABEL:
if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
- OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PADDING_MODE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE);
return 0;
}
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 {
@@ -469,17 +466,14 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL:
if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
- OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PADDING_MODE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE);
return 0;
}
CBS_init((CBS *)p2, rctx->oaep_label, rctx->oaep_labellen);
return 1;
- case EVP_PKEY_CTRL_DIGESTINIT:
- return 1;
-
default:
- OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_COMMAND_NOT_SUPPORTED);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED);
return 0;
}
}
@@ -509,14 +503,13 @@ static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) {
}
const EVP_PKEY_METHOD rsa_pkey_meth = {
- EVP_PKEY_RSA, 0 /* flags */, pkey_rsa_init,
- pkey_rsa_copy, pkey_rsa_cleanup, 0 /* paramgen_init */,
- 0 /* paramgen */, 0 /* keygen_init */, pkey_rsa_keygen,
- 0 /* sign_init */, pkey_rsa_sign, 0 /* verify_init */,
- pkey_rsa_verify, 0 /* signctx_init */, 0 /* signctx */,
- 0 /* verifyctx_init */, 0 /* verifyctx */, 0 /* encrypt_init */,
- pkey_rsa_encrypt, 0 /* decrypt_init */, pkey_rsa_decrypt,
- 0 /* derive_init */, 0 /* derive */, pkey_rsa_ctrl,
+ EVP_PKEY_RSA, 0 /* flags */, pkey_rsa_init,
+ pkey_rsa_copy, pkey_rsa_cleanup, 0 /* paramgen_init */,
+ 0 /* paramgen */, 0 /* keygen_init */, pkey_rsa_keygen,
+ 0 /* sign_init */, pkey_rsa_sign, 0 /* verify_init */,
+ pkey_rsa_verify, 0 /* encrypt_init */, pkey_rsa_encrypt,
+ 0 /* decrypt_init */, pkey_rsa_decrypt, 0 /* derive_init */,
+ 0 /* derive */, pkey_rsa_ctrl,
};
int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int padding) {
@@ -593,7 +586,7 @@ int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx,
return -1;
}
if (CBS_len(&label) > INT_MAX) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_get0_rsa_oaep_label, ERR_R_OVERFLOW);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_OVERFLOW);
return -1;
}
*out_label = CBS_data(&label);
diff --git a/src/crypto/evp/p_rsa_asn1.c b/src/crypto/evp/p_rsa_asn1.c
index 1e2d3f6..db38d5c 100644
--- a/src/crypto/evp/p_rsa_asn1.c
+++ b/src/crypto/evp/p_rsa_asn1.c
@@ -57,6 +57,7 @@
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
+#include <openssl/bytestring.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -69,16 +70,14 @@
static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) {
- uint8_t *encoded = NULL;
- int len;
- len = i2d_RSAPublicKey(pkey->pkey.rsa, &encoded);
-
- if (len <= 0) {
+ uint8_t *encoded;
+ size_t encoded_len;
+ if (!RSA_public_key_to_bytes(&encoded, &encoded_len, pkey->pkey.rsa)) {
return 0;
}
if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_RSA), V_ASN1_NULL, NULL,
- encoded, len)) {
+ encoded, encoded_len)) {
OPENSSL_free(encoded);
return 0;
}
@@ -89,16 +88,25 @@ static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) {
static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) {
const uint8_t *p;
int pklen;
- RSA *rsa;
-
if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, pubkey)) {
return 0;
}
- rsa = d2i_RSAPublicKey(NULL, &p, pklen);
- if (rsa == NULL) {
- OPENSSL_PUT_ERROR(EVP, rsa_pub_decode, ERR_R_RSA_LIB);
+
+ /* Estonian IDs issued between September 2014 to September 2015 are
+ * broken. See https://crbug.com/532048 and https://crbug.com/534766.
+ *
+ * TODO(davidben): Switch this to the strict version in March 2016 or when
+ * Chromium can force client certificates down a different codepath, whichever
+ * comes first. */
+ CBS cbs;
+ CBS_init(&cbs, p, pklen);
+ RSA *rsa = RSA_parse_public_key_buggy(&cbs);
+ if (rsa == NULL || CBS_len(&cbs) != 0) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+ RSA_free(rsa);
return 0;
}
+
EVP_PKEY_assign_RSA(pkey, rsa);
return 1;
}
@@ -109,20 +117,17 @@ static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {
}
static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) {
- uint8_t *rk = NULL;
- int rklen;
-
- rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk);
-
- if (rklen <= 0) {
- OPENSSL_PUT_ERROR(EVP, rsa_priv_encode, ERR_R_MALLOC_FAILURE);
+ uint8_t *encoded;
+ size_t encoded_len;
+ if (!RSA_private_key_to_bytes(&encoded, &encoded_len, pkey->pkey.rsa)) {
return 0;
}
/* TODO(fork): const correctness in next line. */
if (!PKCS8_pkey_set0(p8, (ASN1_OBJECT *)OBJ_nid2obj(NID_rsaEncryption), 0,
- V_ASN1_NULL, NULL, rk, rklen)) {
- OPENSSL_PUT_ERROR(EVP, rsa_priv_encode, ERR_R_MALLOC_FAILURE);
+ V_ASN1_NULL, NULL, encoded, encoded_len)) {
+ OPENSSL_free(encoded);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -132,16 +137,14 @@ static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) {
static int rsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) {
const uint8_t *p;
int pklen;
- RSA *rsa;
-
if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8)) {
- OPENSSL_PUT_ERROR(EVP, rsa_priv_decode, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
return 0;
}
- rsa = d2i_RSAPrivateKey(NULL, &p, pklen);
+ RSA *rsa = RSA_private_key_from_bytes(p, pklen);
if (rsa == NULL) {
- OPENSSL_PUT_ERROR(EVP, rsa_priv_decode, ERR_R_RSA_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_RSA_LIB);
return 0;
}
@@ -198,11 +201,24 @@ static int do_rsa_print(BIO *out, const RSA *rsa, int off,
update_buflen(rsa->dmp1, &buf_len);
update_buflen(rsa->dmq1, &buf_len);
update_buflen(rsa->iqmp, &buf_len);
+
+ if (rsa->additional_primes != NULL) {
+ size_t i;
+
+ for (i = 0; i < sk_RSA_additional_prime_num(rsa->additional_primes);
+ i++) {
+ const RSA_additional_prime *ap =
+ sk_RSA_additional_prime_value(rsa->additional_primes, i);
+ update_buflen(ap->prime, &buf_len);
+ update_buflen(ap->exp, &buf_len);
+ update_buflen(ap->coeff, &buf_len);
+ }
+ }
}
m = (uint8_t *)OPENSSL_malloc(buf_len + 10);
if (m == NULL) {
- OPENSSL_PUT_ERROR(EVP, do_rsa_print, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -241,6 +257,28 @@ static int do_rsa_print(BIO *out, const RSA *rsa, int off,
!ASN1_bn_print(out, "coefficient:", rsa->iqmp, m, off)) {
goto err;
}
+
+ if (rsa->additional_primes != NULL &&
+ sk_RSA_additional_prime_num(rsa->additional_primes) > 0) {
+ size_t i;
+
+ if (BIO_printf(out, "otherPrimeInfos:\n") <= 0) {
+ goto err;
+ }
+ for (i = 0; i < sk_RSA_additional_prime_num(rsa->additional_primes);
+ i++) {
+ const RSA_additional_prime *ap =
+ sk_RSA_additional_prime_value(rsa->additional_primes, i);
+
+ if (BIO_printf(out, "otherPrimeInfo (prime %u):\n",
+ (unsigned)(i + 3)) <= 0 ||
+ !ASN1_bn_print(out, "prime:", ap->prime, m, off) ||
+ !ASN1_bn_print(out, "exponent:", ap->exp, m, off) ||
+ !ASN1_bn_print(out, "coeff:", ap->coeff, m, off)) {
+ goto err;
+ }
+ }
+ }
}
ret = 1;
@@ -265,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;
@@ -407,18 +445,18 @@ static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
return 1;
}
-static int old_rsa_priv_decode(EVP_PKEY *pkey, const unsigned char **pder,
+static int old_rsa_priv_decode(EVP_PKEY *pkey, const uint8_t **pder,
int derlen) {
RSA *rsa = d2i_RSAPrivateKey(NULL, pder, derlen);
if (rsa == NULL) {
- OPENSSL_PUT_ERROR(EVP, old_rsa_priv_decode, ERR_R_RSA_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_RSA_LIB);
return 0;
}
EVP_PKEY_assign_RSA(pkey, rsa);
return 1;
}
-static int old_rsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) {
+static int old_rsa_priv_encode(const EVP_PKEY *pkey, uint8_t **pder) {
return i2d_RSAPrivateKey(pkey->pkey.rsa, pder);
}
@@ -474,7 +512,7 @@ static const EVP_MD *rsa_algor_to_md(X509_ALGOR *alg) {
}
md = EVP_get_digestbyobj(alg->algorithm);
if (md == NULL) {
- OPENSSL_PUT_ERROR(EVP, rsa_algor_to_md, EVP_R_UNKNOWN_DIGEST);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_DIGEST);
}
return md;
}
@@ -487,16 +525,16 @@ static const EVP_MD *rsa_mgf1_to_md(X509_ALGOR *alg, X509_ALGOR *maskHash) {
}
/* Check mask and lookup mask hash algorithm */
if (OBJ_obj2nid(alg->algorithm) != NID_mgf1) {
- OPENSSL_PUT_ERROR(EVP, rsa_mgf1_to_md, EVP_R_UNSUPPORTED_MASK_ALGORITHM);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_MASK_ALGORITHM);
return NULL;
}
if (!maskHash) {
- OPENSSL_PUT_ERROR(EVP, rsa_mgf1_to_md, EVP_R_UNSUPPORTED_MASK_PARAMETER);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_MASK_PARAMETER);
return NULL;
}
md = EVP_get_digestbyobj(maskHash->algorithm);
if (md == NULL) {
- OPENSSL_PUT_ERROR(EVP, rsa_mgf1_to_md, EVP_R_UNKNOWN_MASK_DIGEST);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_MASK_DIGEST);
return NULL;
}
return md;
@@ -576,13 +614,13 @@ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) {
/* Sanity check: make sure it is PSS */
if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) {
- OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_UNSUPPORTED_SIGNATURE_TYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_SIGNATURE_TYPE);
return 0;
}
/* Decode PSS parameters */
pss = rsa_pss_decode(sigalg, &maskHash);
if (pss == NULL) {
- OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_INVALID_PSS_PARAMETERS);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PSS_PARAMETERS);
goto err;
}
@@ -602,7 +640,7 @@ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) {
/* Could perform more salt length sanity checks but the main
* RSA routines will trap other invalid values anyway. */
if (saltlen < 0) {
- OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_INVALID_SALT_LENGTH);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_SALT_LENGTH);
goto err;
}
}
@@ -610,7 +648,7 @@ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) {
/* low-level routines support only trailer field 0xbc (value 1)
* and PKCS#1 says we should reject any other value anyway. */
if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) {
- OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_INVALID_TRAILER);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_TRAILER);
goto err;
}
@@ -638,8 +676,7 @@ static int rsa_digest_verify_init_from_algorithm(EVP_MD_CTX *ctx,
EVP_PKEY *pkey) {
/* Sanity check: make sure it is PSS */
if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) {
- OPENSSL_PUT_ERROR(EVP, rsa_digest_verify_init_from_algorithm,
- EVP_R_UNSUPPORTED_SIGNATURE_TYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_SIGNATURE_TYPE);
return 0;
}
return rsa_pss_to_ctx(ctx, sigalg, pkey);
@@ -671,7 +708,6 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meth = {
ASN1_PKEY_SIGPARAM_NULL,
"RSA",
- "OpenSSL RSA method",
rsa_pub_decode,
rsa_pub_encode,
diff --git a/src/crypto/evp/pbkdf.c b/src/crypto/evp/pbkdf.c
index be6ed86..b06b922 100644
--- a/src/crypto/evp/pbkdf.c
+++ b/src/crypto/evp/pbkdf.c
@@ -123,6 +123,22 @@ int PKCS5_PBKDF2_HMAC(const char *password, size_t password_len,
p += cplen;
}
HMAC_CTX_cleanup(&hctx_tpl);
+
+ // RFC 2898 describes iterations (c) as being a "positive integer", so a
+ // value of 0 is an error.
+ //
+ // Unfortunatley not all consumers of PKCS5_PBKDF2_HMAC() check their return
+ // value, expecting it to succeed and unconditonally using |out_key|.
+ // As a precaution for such callsites in external code, the old behavior
+ // of iterations < 1 being treated as iterations == 1 is preserved, but
+ // additionally an error result is returned.
+ //
+ // TODO(eroman): Figure out how to remove this compatibility hack, or change
+ // the default to something more sensible like 2048.
+ if (iterations == 0) {
+ return 0;
+ }
+
return 1;
}
diff --git a/src/crypto/evp/pbkdf_test.cc b/src/crypto/evp/pbkdf_test.cc
index ae2f405..a39189f 100644
--- a/src/crypto/evp/pbkdf_test.cc
+++ b/src/crypto/evp/pbkdf_test.cc
@@ -149,6 +149,44 @@ static bool TestSHA2() {
return true;
}
+// Tests key derivation using iterations=0.
+//
+// RFC 2898 defines the iteration count (c) as a "positive integer". So doing a
+// key derivation with iterations=0 is ill-defined and should result in a
+// failure.
+static bool TestZeroIterations() {
+ static const char kPassword[] = "password";
+ const size_t password_len = strlen(kPassword);
+ static const uint8_t kSalt[] = {1, 2, 3, 4};
+ const size_t salt_len = sizeof(kSalt);
+ const EVP_MD *digest = EVP_sha1();
+
+ uint8_t key[10] = {0};
+ const size_t key_len = sizeof(key);
+
+ // Verify that calling with iterations=1 works.
+ if (!PKCS5_PBKDF2_HMAC(kPassword, password_len, kSalt, salt_len,
+ 1 /* iterations */, digest, key_len, key)) {
+ fprintf(stderr, "PBKDF2 failed with iterations=1\n");
+ return false;
+ }
+
+ // Flip the first key byte (so can later test if it got set).
+ const uint8_t expected_first_byte = key[0];
+ key[0] = ~key[0];
+
+ // However calling it with iterations=0 fails.
+ if (PKCS5_PBKDF2_HMAC(kPassword, password_len, kSalt, salt_len,
+ 0 /* iterations */, digest, key_len, key)) {
+ fprintf(stderr, "PBKDF2 returned zero with iterations=0\n");
+ return false;
+ }
+
+ // For backwards compatibility, the iterations == 0 case still fills in
+ // the out key.
+ return key[0] == expected_first_byte;
+}
+
int main(void) {
CRYPTO_library_init();
ERR_load_crypto_strings();
@@ -173,6 +211,11 @@ int main(void) {
return 1;
}
+ if (!TestZeroIterations()) {
+ fprintf(stderr, "TestZeroIterations failed\n");
+ return 1;
+ }
+
printf("PASS\n");
ERR_free_strings();
return 0;
diff --git a/src/crypto/ex_data.c b/src/crypto/ex_data.c
index 10fefc8..8fa1240 100644
--- a/src/crypto/ex_data.c
+++ b/src/crypto/ex_data.c
@@ -124,27 +124,24 @@
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;
funcs = OPENSSL_malloc(sizeof(CRYPTO_EX_DATA_FUNCS));
if (funcs == NULL) {
- OPENSSL_PUT_ERROR(CRYPTO, CRYPTO_get_ex_new_index, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE);
return 0;
}
funcs->argl = argl;
funcs->argp = argp;
- funcs->new_func = new_func;
funcs->dup_func = dup_func;
funcs->free_func = free_func;
@@ -156,12 +153,13 @@ int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class, int *out_index,
if (ex_data_class->meth == NULL ||
!sk_CRYPTO_EX_DATA_FUNCS_push(ex_data_class->meth, funcs)) {
- OPENSSL_PUT_ERROR(CRYPTO, CRYPTO_get_ex_new_index, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE);
OPENSSL_free(funcs);
goto err;
}
- *out_index = sk_CRYPTO_EX_DATA_FUNCS_num(ex_data_class->meth) - 1;
+ *out_index = sk_CRYPTO_EX_DATA_FUNCS_num(ex_data_class->meth) - 1 +
+ ex_data_class->num_reserved;
ret = 1;
err:
@@ -175,7 +173,7 @@ int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int index, void *val) {
if (ad->sk == NULL) {
ad->sk = sk_void_new_null();
if (ad->sk == NULL) {
- OPENSSL_PUT_ERROR(CRYPTO, CRYPTO_set_ex_data, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE);
return 0;
}
}
@@ -185,7 +183,7 @@ int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int index, void *val) {
/* Add NULL values until the stack is long enough. */
for (i = n; i <= index; i++) {
if (!sk_void_push(ad->sk, NULL)) {
- OPENSSL_PUT_ERROR(CRYPTO, CRYPTO_set_ex_data, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE);
return 0;
}
}
@@ -222,62 +220,40 @@ static int get_func_pointers(STACK_OF(CRYPTO_EX_DATA_FUNCS) **out,
CRYPTO_STATIC_MUTEX_unlock(&ex_data_class->lock);
if (n > 0 && *out == NULL) {
- OPENSSL_PUT_ERROR(CRYPTO, get_func_pointers, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE);
return 0;
}
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, 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);
- void *ptr = CRYPTO_get_ex_data(from, i);
+ void *ptr = CRYPTO_get_ex_data(from, i + ex_data_class->num_reserved);
if (func_pointer->dup_func) {
- func_pointer->dup_func(to, from, &ptr, i, func_pointer->argl,
- func_pointer->argp);
+ func_pointer->dup_func(to, from, &ptr, i + ex_data_class->num_reserved,
+ func_pointer->argl, func_pointer->argp);
}
- CRYPTO_set_ex_data(to, i, ptr);
+ CRYPTO_set_ex_data(to, i + ex_data_class->num_reserved, ptr);
}
sk_CRYPTO_EX_DATA_FUNCS_free(func_pointers);
@@ -287,20 +263,25 @@ 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);
if (func_pointer->free_func) {
- void *ptr = CRYPTO_get_ex_data(ad, i);
- func_pointer->free_func(obj, ptr, ad, i, func_pointer->argl,
- func_pointer->argp);
+ void *ptr = CRYPTO_get_ex_data(ad, i + ex_data_class->num_reserved);
+ func_pointer->free_func(obj, ptr, ad, i + ex_data_class->num_reserved,
+ func_pointer->argl, func_pointer->argp);
}
}
diff --git a/src/crypto/hkdf/CMakeLists.txt b/src/crypto/hkdf/CMakeLists.txt
index 66d680a..d9db933 100644
--- a/src/crypto/hkdf/CMakeLists.txt
+++ b/src/crypto/hkdf/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
hkdf
@@ -17,3 +17,4 @@ add_executable(
)
target_link_libraries(hkdf_test crypto)
+add_dependencies(all_tests hkdf_test)
diff --git a/src/crypto/hkdf/hkdf.c b/src/crypto/hkdf/hkdf.c
index bb7f5a4..f9cdcb0 100644
--- a/src/crypto/hkdf/hkdf.c
+++ b/src/crypto/hkdf/hkdf.c
@@ -40,7 +40,7 @@ int HKDF(uint8_t *out_key, size_t out_len,
/* Expand key material to desired length. */
n = (out_len + digest_len - 1) / digest_len;
if (out_len + digest_len < out_len || n > 255) {
- OPENSSL_PUT_ERROR(HKDF, HKDF, HKDF_R_OUTPUT_TOO_LARGE);
+ OPENSSL_PUT_ERROR(HKDF, HKDF_R_OUTPUT_TOO_LARGE);
return 0;
}
@@ -83,7 +83,7 @@ int HKDF(uint8_t *out_key, size_t out_len,
out:
HMAC_CTX_cleanup(&hmac);
if (ret != 1) {
- OPENSSL_PUT_ERROR(HKDF, HKDF, ERR_R_HMAC_LIB);
+ OPENSSL_PUT_ERROR(HKDF, ERR_R_HMAC_LIB);
}
return ret;
}
diff --git a/src/crypto/hmac/CMakeLists.txt b/src/crypto/hmac/CMakeLists.txt
index 11d267f..179a53b 100644
--- a/src/crypto/hmac/CMakeLists.txt
+++ b/src/crypto/hmac/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
hmac
@@ -18,3 +18,4 @@ add_executable(
)
target_link_libraries(hmac_test crypto)
+add_dependencies(all_tests hmac_test)
diff --git a/src/crypto/hmac/hmac.c b/src/crypto/hmac/hmac.c
index 556e7f9..be2dcce 100644
--- a/src/crypto/hmac/hmac.c
+++ b/src/crypto/hmac/hmac.c
@@ -97,7 +97,7 @@ void HMAC_CTX_cleanup(HMAC_CTX *ctx) {
EVP_MD_CTX_cleanup(&ctx->i_ctx);
EVP_MD_CTX_cleanup(&ctx->o_ctx);
EVP_MD_CTX_cleanup(&ctx->md_ctx);
- OPENSSL_cleanse(ctx, sizeof(ctx));
+ OPENSSL_cleanse(ctx, sizeof(HMAC_CTX));
}
int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len,
@@ -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/hmac/hmac_tests.txt b/src/crypto/hmac/hmac_tests.txt
index 012f593..53f3f8f 100644
--- a/src/crypto/hmac/hmac_tests.txt
+++ b/src/crypto/hmac/hmac_tests.txt
@@ -1,6 +1,3 @@
-# This test file is shared between evp_test and hmac_test, to test the legacy
-# EVP_PKEY_HMAC API.
-
HMAC = MD5
# Note: The empty key results in passing NULL to HMAC_Init_ex, so this tests
# that HMAC_CTX and HMAC treat NULL as the empty key initially.
diff --git a/src/crypto/internal.h b/src/crypto/internal.h
index 59eddd0..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. */
@@ -452,6 +440,7 @@ OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_unlock(
typedef enum {
OPENSSL_THREAD_LOCAL_ERR = 0,
OPENSSL_THREAD_LOCAL_RAND,
+ OPENSSL_THREAD_LOCAL_URANDOM_BUF,
OPENSSL_THREAD_LOCAL_TEST,
NUM_OPENSSL_THREAD_LOCALS,
} thread_local_data_t;
@@ -493,9 +482,14 @@ typedef struct crypto_ex_data_func_st CRYPTO_EX_DATA_FUNCS;
typedef struct {
struct CRYPTO_STATIC_MUTEX lock;
STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth;
+ /* num_reserved is one if the ex_data index zero is reserved for legacy
+ * |TYPE_get_app_data| functions. */
+ uint8_t num_reserved;
} CRYPTO_EX_DATA_CLASS;
-#define CRYPTO_EX_DATA_CLASS_INIT {CRYPTO_STATIC_MUTEX_INIT, NULL}
+#define CRYPTO_EX_DATA_CLASS_INIT {CRYPTO_STATIC_MUTEX_INIT, NULL, 0}
+#define CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA \
+ {CRYPTO_STATIC_MUTEX_INIT, NULL, 1}
/* CRYPTO_get_ex_new_index allocates a new index for |ex_data_class| and writes
* it to |*out_index|. Each class of object should provide a wrapper function
@@ -503,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
@@ -516,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/lhash/CMakeLists.txt b/src/crypto/lhash/CMakeLists.txt
index c71b8a1..4f4dea7 100644
--- a/src/crypto/lhash/CMakeLists.txt
+++ b/src/crypto/lhash/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
lhash
@@ -17,3 +17,4 @@ add_executable(
)
target_link_libraries(lhash_test crypto)
+add_dependencies(all_tests lhash_test)
diff --git a/src/crypto/lhash/lhash.c b/src/crypto/lhash/lhash.c
index c282fa8..257900e 100644
--- a/src/crypto/lhash/lhash.c
+++ b/src/crypto/lhash/lhash.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved.
+/* 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).
diff --git a/src/crypto/md4/CMakeLists.txt b/src/crypto/md4/CMakeLists.txt
index db7a187..59140a7 100644
--- a/src/crypto/md4/CMakeLists.txt
+++ b/src/crypto/md4/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
md4
diff --git a/src/crypto/md4/md4.c b/src/crypto/md4/md4.c
index 5ef9ae5..86a540b 100644
--- a/src/crypto/md4/md4.c
+++ b/src/crypto/md4/md4.c
@@ -64,18 +64,17 @@
int MD4_Init(MD4_CTX *md4) {
memset(md4, 0, sizeof(MD4_CTX));
- md4->A = 0x67452301UL;
- md4->B = 0xefcdab89UL;
- md4->C = 0x98badcfeUL;
- md4->D = 0x10325476UL;
+ md4->h[0] = 0x67452301UL;
+ md4->h[1] = 0xefcdab89UL;
+ md4->h[2] = 0x98badcfeUL;
+ md4->h[3] = 0x10325476UL;
return 1;
}
-void md4_block_data_order (MD4_CTX *md4, const void *p, size_t num);
+void md4_block_data_order(uint32_t *state, const uint8_t *data, size_t num);
#define DATA_ORDER_IS_LITTLE_ENDIAN
-#define HASH_LONG uint32_t
#define HASH_CTX MD4_CTX
#define HASH_CBLOCK 64
#define HASH_UPDATE MD4_Update
@@ -84,14 +83,14 @@ void md4_block_data_order (MD4_CTX *md4, const void *p, size_t num);
#define HASH_MAKE_STRING(c, s) \
do { \
uint32_t ll; \
- ll = (c)->A; \
- (void) HOST_l2c(ll, (s)); \
- ll = (c)->B; \
- (void) HOST_l2c(ll, (s)); \
- ll = (c)->C; \
- (void) HOST_l2c(ll, (s)); \
- ll = (c)->D; \
- (void) HOST_l2c(ll, (s)); \
+ ll = (c)->h[0]; \
+ HOST_l2c(ll, (s)); \
+ ll = (c)->h[1]; \
+ HOST_l2c(ll, (s)); \
+ ll = (c)->h[2]; \
+ HOST_l2c(ll, (s)); \
+ ll = (c)->h[3]; \
+ HOST_l2c(ll, (s)); \
} while (0)
#define HASH_BLOCK_DATA_ORDER md4_block_data_order
@@ -104,6 +103,8 @@ void md4_block_data_order (MD4_CTX *md4, const void *p, 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))); \
@@ -122,15 +123,14 @@ void md4_block_data_order (MD4_CTX *md4, const void *p, size_t num);
a = ROTATE(a, s); \
};
-void md4_block_data_order(MD4_CTX *c, const void *data_, size_t num) {
- const uint8_t *data = data_;
+void md4_block_data_order(uint32_t *state, const uint8_t *data, size_t num) {
uint32_t A, B, C, D, l;
uint32_t X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15;
- A = c->A;
- B = c->B;
- C = c->C;
- D = c->D;
+ A = state[0];
+ B = state[1];
+ C = state[2];
+ D = state[3];
for (; num--;) {
HOST_c2l(data, l);
@@ -217,9 +217,9 @@ void md4_block_data_order(MD4_CTX *c, const void *data_, size_t num) {
R2(C, D, A, B, X7, 11, 0x6ED9EBA1L);
R2(B, C, D, A, X15, 15, 0x6ED9EBA1L);
- A = c->A += A;
- B = c->B += B;
- C = c->C += C;
- D = c->D += D;
+ A = state[0] += A;
+ B = state[1] += B;
+ C = state[2] += C;
+ D = state[3] += D;
}
}
diff --git a/src/crypto/md5/CMakeLists.txt b/src/crypto/md5/CMakeLists.txt
index 6c5e80f..a37c47e 100644
--- a/src/crypto/md5/CMakeLists.txt
+++ b/src/crypto/md5/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
if (${ARCH} STREQUAL "x86_64")
set(
diff --git a/src/crypto/md5/md5.c b/src/crypto/md5/md5.c
index 5575efb..66483b8 100644
--- a/src/crypto/md5/md5.c
+++ b/src/crypto/md5/md5.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved.
+/* 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).
@@ -78,10 +79,10 @@ uint8_t *MD5(const uint8_t *data, size_t len, uint8_t *out) {
int MD5_Init(MD5_CTX *md5) {
memset(md5, 0, sizeof(MD5_CTX));
- md5->A = 0x67452301UL;
- md5->B = 0xefcdab89UL;
- md5->C = 0x98badcfeUL;
- md5->D = 0x10325476UL;
+ md5->h[0] = 0x67452301UL;
+ md5->h[1] = 0xefcdab89UL;
+ md5->h[2] = 0x98badcfeUL;
+ md5->h[3] = 0x10325476UL;
return 1;
}
@@ -92,11 +93,10 @@ int MD5_Init(MD5_CTX *md5) {
#endif
-void md5_block_data_order(MD5_CTX *md5, const void *p, size_t num);
+void md5_block_data_order(uint32_t *state, const uint8_t *data, size_t num);
#define DATA_ORDER_IS_LITTLE_ENDIAN
-#define HASH_LONG uint32_t
#define HASH_CTX MD5_CTX
#define HASH_CBLOCK 64
#define HASH_UPDATE MD5_Update
@@ -105,14 +105,14 @@ void md5_block_data_order(MD5_CTX *md5, const void *p, size_t num);
#define HASH_MAKE_STRING(c, s) \
do { \
uint32_t ll; \
- ll = (c)->A; \
- (void) HOST_l2c(ll, (s)); \
- ll = (c)->B; \
- (void) HOST_l2c(ll, (s)); \
- ll = (c)->C; \
- (void) HOST_l2c(ll, (s)); \
- ll = (c)->D; \
- (void) HOST_l2c(ll, (s)); \
+ ll = (c)->h[0]; \
+ HOST_l2c(ll, (s)); \
+ ll = (c)->h[1]; \
+ HOST_l2c(ll, (s)); \
+ ll = (c)->h[2]; \
+ HOST_l2c(ll, (s)); \
+ ll = (c)->h[3]; \
+ HOST_l2c(ll, (s)); \
} while (0)
#define HASH_BLOCK_DATA_ORDER md5_block_data_order
@@ -127,6 +127,8 @@ void md5_block_data_order(MD5_CTX *md5, const void *p, 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); \
@@ -151,17 +153,16 @@ void md5_block_data_order(MD5_CTX *md5, const void *p, size_t num);
#ifdef X
#undef X
#endif
-void md5_block_data_order(MD5_CTX *md5, const void *in_data, size_t num) {
- const uint8_t *data = in_data;
+void md5_block_data_order(uint32_t *state, const uint8_t *data, size_t num) {
uint32_t A, B, C, D, l;
uint32_t XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, XX8, XX9, XX10, XX11, XX12,
XX13, XX14, XX15;
#define X(i) XX##i
- A = md5->A;
- B = md5->B;
- C = md5->C;
- D = md5->D;
+ A = state[0];
+ B = state[1];
+ C = state[2];
+ D = state[3];
for (; num--;) {
HOST_c2l(data, l);
@@ -265,10 +266,10 @@ void md5_block_data_order(MD5_CTX *md5, const void *in_data, size_t num) {
R3(C, D, A, B, X(2), 15, 0x2ad7d2bbL);
R3(B, C, D, A, X(9), 21, 0xeb86d391L);
- A = md5->A += A;
- B = md5->B += B;
- C = md5->C += C;
- D = md5->D += D;
+ A = state[0] += A;
+ B = state[1] += B;
+ C = state[2] += C;
+ D = state[3] += D;
}
}
#endif
diff --git a/src/crypto/mem.c b/src/crypto/mem.c
index ce41440..edd14a8 100644
--- a/src/crypto/mem.c
+++ b/src/crypto/mem.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved.
+/* 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).
diff --git a/src/crypto/modes/CMakeLists.txt b/src/crypto/modes/CMakeLists.txt
index ffb29b6..41f71d7 100644
--- a/src/crypto/modes/CMakeLists.txt
+++ b/src/crypto/modes/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
if (${ARCH} STREQUAL "x86_64")
set(
@@ -63,3 +63,4 @@ add_executable(
)
target_link_libraries(gcm_test crypto)
+add_dependencies(all_tests gcm_test)
diff --git a/src/crypto/modes/asm/aesni-gcm-x86_64.pl b/src/crypto/modes/asm/aesni-gcm-x86_64.pl
index 7e4e04e..0ca89c7 100644
--- a/src/crypto/modes/asm/aesni-gcm-x86_64.pl
+++ b/src/crypto/modes/asm/aesni-gcm-x86_64.pl
@@ -41,24 +41,12 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
-if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
- =~ /GNU assembler version ([2-9]\.[0-9]+)/) {
- $avx = ($1>=2.19) + ($1>=2.22);
-}
-
-if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
- `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
- $avx = ($1>=2.09) + ($1>=2.10);
-}
-
-if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
- `ml64 2>&1` =~ /Version ([0-9]+)\./) {
- $avx = ($1>=10) + ($1>=11);
-}
-
-if (!$avx && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9]\.[0-9]+)/) {
- $avx = ($2>=3.0) + ($2>3.0);
-}
+# 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. $avx goes up to 2.
+$avx = 0;
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT=*OUT;
diff --git a/src/crypto/modes/asm/ghash-armv4.pl b/src/crypto/modes/asm/ghash-armv4.pl
index 25a4e27..d328822 100644
--- a/src/crypto/modes/asm/ghash-armv4.pl
+++ b/src/crypto/modes/asm/ghash-armv4.pl
@@ -45,7 +45,7 @@
# processes one byte in 8.45 cycles, A9 - in 10.2, A15 - in 7.63,
# Snapdragon S4 - in 9.33.
#
-# Câmara, D.; Gouvêa, C. P. L.; López, J. & Dahab, R.: Fast Software
+# Câmara, D.; Gouvêa, C. P. L.; López, J. & Dahab, R.: Fast Software
# Polynomial Multiplication on ARM Processors using the NEON Engine.
#
# http://conradoplg.cryptoland.net/files/2010/12/mocrysen13.pdf
@@ -133,15 +133,14 @@ ___
}
$code=<<___;
-#if defined(__arm__)
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
.syntax unified
.text
.code 32
-#ifdef __APPLE__
+#ifdef __clang__
#define ldrplb ldrbpl
#define ldrneb ldrbne
#endif
@@ -457,12 +456,12 @@ gcm_ghash_neon:
veor $IN,$Xl @ inp^=Xi
.Lgmult_neon:
___
- &clmul64x64 ($Xl,$Hlo,"$IN#lo"); # H.lo·Xi.lo
+ &clmul64x64 ($Xl,$Hlo,"$IN#lo"); # H.lo·Xi.lo
$code.=<<___;
veor $IN#lo,$IN#lo,$IN#hi @ Karatsuba pre-processing
___
- &clmul64x64 ($Xm,$Hhl,"$IN#lo"); # (H.lo+H.hi)·(Xi.lo+Xi.hi)
- &clmul64x64 ($Xh,$Hhi,"$IN#hi"); # H.hi·Xi.hi
+ &clmul64x64 ($Xm,$Hhl,"$IN#lo"); # (H.lo+H.hi)·(Xi.lo+Xi.hi)
+ &clmul64x64 ($Xh,$Hhi,"$IN#hi"); # H.hi·Xi.hi
$code.=<<___;
veor $Xm,$Xm,$Xl @ Karatsuba post-processing
veor $Xm,$Xm,$Xh
@@ -504,8 +503,6 @@ ___
$code.=<<___;
.asciz "GHASH for ARMv4/NEON, CRYPTOGAMS by <appro\@openssl.org>"
.align 2
-
-#endif
___
foreach (split("\n",$code)) {
diff --git a/src/crypto/modes/asm/ghash-x86.pl b/src/crypto/modes/asm/ghash-x86.pl
index 23a5527..0269169 100644
--- a/src/crypto/modes/asm/ghash-x86.pl
+++ b/src/crypto/modes/asm/ghash-x86.pl
@@ -358,7 +358,7 @@ $S=12; # shift factor for rem_4bit
# effective address calculation and finally merge of value to Z.hi.
# Reference to rem_4bit is scheduled so late that I had to >>4
# rem_4bit elements. This resulted in 20-45% procent improvement
-# on contemporary µ-archs.
+# on contemporary µ-archs.
{
my $cnt;
my $rem_4bit = "eax";
diff --git a/src/crypto/modes/asm/ghash-x86_64.pl b/src/crypto/modes/asm/ghash-x86_64.pl
index 6e656ca..e42ca32 100644
--- a/src/crypto/modes/asm/ghash-x86_64.pl
+++ b/src/crypto/modes/asm/ghash-x86_64.pl
@@ -90,24 +90,12 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
-if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
- =~ /GNU assembler version ([2-9]\.[0-9]+)/) {
- $avx = ($1>=2.19) + ($1>=2.22);
-}
-
-if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
- `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
- $avx = ($1>=2.09) + ($1>=2.10);
-}
-
-if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
- `ml64 2>&1` =~ /Version ([0-9]+)\./) {
- $avx = ($1>=10) + ($1>=11);
-}
-
-if (!$avx && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9]\.[0-9]+)/) {
- $avx = ($2>=3.0) + ($2>3.0);
-}
+# 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. $avx goes up to 2.
+$avx = 0;
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT=*OUT;
@@ -576,15 +564,15 @@ $code.=<<___ if (0 || (&reduction_alg9($Xhi,$Xi)&&0));
# experimental alternative. special thing about is that there
# no dependency between the two multiplications...
mov \$`0xE1<<1`,%eax
- mov \$0xA040608020C0E000,%r10 # ((7..0)·0xE0)&0xff
+ mov \$0xA040608020C0E000,%r10 # ((7..0)·0xE0)&0xff
mov \$0x07,%r11d
movq %rax,$T1
movq %r10,$T2
movq %r11,$T3 # borrow $T3
pand $Xi,$T3
- pshufb $T3,$T2 # ($Xi&7)·0xE0
+ pshufb $T3,$T2 # ($Xi&7)·0xE0
movq %rax,$T3
- pclmulqdq \$0x00,$Xi,$T1 # ·(0xE1<<1)
+ pclmulqdq \$0x00,$Xi,$T1 # ·(0xE1<<1)
pxor $Xi,$T2
pslldq \$15,$T2
paddd $T2,$T2 # <<(64+56+1)
@@ -657,7 +645,7 @@ $code.=<<___;
je .Lskip4x
sub \$0x30,$len
- mov \$0xA040608020C0E000,%rax # ((7..0)·0xE0)&0xff
+ mov \$0xA040608020C0E000,%rax # ((7..0)·0xE0)&0xff
movdqu 0x30($Htbl),$Hkey3
movdqu 0x40($Htbl),$Hkey4
diff --git a/src/crypto/modes/asm/ghashv8-armx.pl b/src/crypto/modes/asm/ghashv8-armx.pl
index 686951f..3a7b8d8 100644
--- a/src/crypto/modes/asm/ghashv8-armx.pl
+++ b/src/crypto/modes/asm/ghashv8-armx.pl
@@ -54,7 +54,7 @@ my ($Xl,$Xm,$Xh,$IN)=map("q$_",(0..3));
my ($t0,$t1,$t2,$xC2,$H,$Hhl,$H2)=map("q$_",(8..14));
$code=<<___;
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
.text
___
@@ -148,10 +148,10 @@ gcm_gmult_v8:
#endif
vext.8 $IN,$t1,$t1,#8
- vpmull.p64 $Xl,$H,$IN @ H.lo·Xi.lo
+ vpmull.p64 $Xl,$H,$IN @ H.lo·Xi.lo
veor $t1,$t1,$IN @ Karatsuba pre-processing
- vpmull2.p64 $Xh,$H,$IN @ H.hi·Xi.hi
- vpmull.p64 $Xm,$Hhl,$t1 @ (H.lo+H.hi)·(Xi.lo+Xi.hi)
+ vpmull2.p64 $Xh,$H,$IN @ H.hi·Xi.hi
+ vpmull.p64 $Xm,$Hhl,$t1 @ (H.lo+H.hi)·(Xi.lo+Xi.hi)
vext.8 $t1,$Xl,$Xh,#8 @ Karatsuba post-processing
veor $t2,$Xl,$Xh
@@ -239,7 +239,7 @@ $code.=<<___;
#endif
vext.8 $In,$t1,$t1,#8
veor $IN,$IN,$Xl @ I[i]^=Xi
- vpmull.p64 $Xln,$H,$In @ H·Ii+1
+ vpmull.p64 $Xln,$H,$In @ H·Ii+1
veor $t1,$t1,$In @ Karatsuba pre-processing
vpmull2.p64 $Xhn,$H,$In
b .Loop_mod2x_v8
@@ -248,14 +248,14 @@ $code.=<<___;
.Loop_mod2x_v8:
vext.8 $t2,$IN,$IN,#8
subs $len,$len,#32 @ is there more data?
- vpmull.p64 $Xl,$H2,$IN @ H^2.lo·Xi.lo
+ vpmull.p64 $Xl,$H2,$IN @ H^2.lo·Xi.lo
cclr $inc,lo @ is it time to zero $inc?
vpmull.p64 $Xmn,$Hhl,$t1
veor $t2,$t2,$IN @ Karatsuba pre-processing
- vpmull2.p64 $Xh,$H2,$IN @ H^2.hi·Xi.hi
+ vpmull2.p64 $Xh,$H2,$IN @ H^2.hi·Xi.hi
veor $Xl,$Xl,$Xln @ accumulate
- vpmull2.p64 $Xm,$Hhl,$t2 @ (H^2.lo+H^2.hi)·(Xi.lo+Xi.hi)
+ vpmull2.p64 $Xm,$Hhl,$t2 @ (H^2.lo+H^2.hi)·(Xi.lo+Xi.hi)
vld1.64 {$t0},[$inp],$inc @ load [rotated] I[i+2]
veor $Xh,$Xh,$Xhn
@@ -280,7 +280,7 @@ $code.=<<___;
vext.8 $In,$t1,$t1,#8
vext.8 $IN,$t0,$t0,#8
veor $Xl,$Xm,$t2
- vpmull.p64 $Xln,$H,$In @ H·Ii+1
+ vpmull.p64 $Xln,$H,$In @ H·Ii+1
veor $IN,$IN,$Xh @ accumulate $IN early
vext.8 $t2,$Xl,$Xl,#8 @ 2nd phase of reduction
@@ -304,10 +304,10 @@ $code.=<<___;
veor $IN,$IN,$Xl @ inp^=Xi
veor $t1,$t0,$t2 @ $t1 is rotated inp^Xi
- vpmull.p64 $Xl,$H,$IN @ H.lo·Xi.lo
+ vpmull.p64 $Xl,$H,$IN @ H.lo·Xi.lo
veor $t1,$t1,$IN @ Karatsuba pre-processing
- vpmull2.p64 $Xh,$H,$IN @ H.hi·Xi.hi
- vpmull.p64 $Xm,$Hhl,$t1 @ (H.lo+H.hi)·(Xi.lo+Xi.hi)
+ vpmull2.p64 $Xh,$H,$IN @ H.hi·Xi.hi
+ vpmull.p64 $Xm,$Hhl,$t1 @ (H.lo+H.hi)·(Xi.lo+Xi.hi)
vext.8 $t1,$Xl,$Xh,#8 @ Karatsuba post-processing
veor $t2,$Xl,$Xh
diff --git a/src/crypto/modes/cbc.c b/src/crypto/modes/cbc.c
index 931b718..e41f2b4 100644
--- a/src/crypto/modes/cbc.c
+++ b/src/crypto/modes/cbc.c
@@ -45,7 +45,6 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ==================================================================== */
-#include <openssl/modes.h>
#include <assert.h>
#include <string.h>
diff --git a/src/crypto/modes/cfb.c b/src/crypto/modes/cfb.c
index 738a438..c58614b 100644
--- a/src/crypto/modes/cfb.c
+++ b/src/crypto/modes/cfb.c
@@ -46,7 +46,7 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ==================================================================== */
-#include <openssl/modes.h>
+#include <openssl/type_check.h>
#include <assert.h>
#include <string.h>
@@ -54,6 +54,8 @@
#include "internal.h"
+OPENSSL_COMPILE_ASSERT((16 % sizeof(size_t)) == 0, bad_size_t_size);
+
void CRYPTO_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
const void *key, uint8_t ivec[16], int *num, int enc,
block128_f block) {
@@ -61,7 +63,6 @@ void CRYPTO_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
size_t l = 0;
assert(in && out && key && ivec && num);
- assert((16 % sizeof(size_t)) == 0);
n = *num;
diff --git a/src/crypto/modes/ctr.c b/src/crypto/modes/ctr.c
index 64062b2..52ff048 100644
--- a/src/crypto/modes/ctr.c
+++ b/src/crypto/modes/ctr.c
@@ -45,7 +45,8 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ==================================================================== */
-#include <openssl/modes.h>
+
+#include <openssl/type_check.h>
#include <assert.h>
#include <string.h>
@@ -72,6 +73,8 @@ static void ctr128_inc(uint8_t *counter) {
} while (n);
}
+OPENSSL_COMPILE_ASSERT((16 % sizeof(size_t)) == 0, bad_size_t_size);
+
/* The input encrypted as though 128bit counter mode is being used. The extra
* state information to record how much of the 128bit block we have used is
* contained in *num, and the encrypted counter is kept in ecount_buf. Both
@@ -91,7 +94,6 @@ void CRYPTO_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
assert(key && ecount_buf && num);
assert(len == 0 || (in && out));
assert(*num < 16);
- assert((16 % sizeof(size_t)) == 0);
n = *num;
diff --git a/src/crypto/modes/gcm.c b/src/crypto/modes/gcm.c
index b1c10b3..65451a6 100644
--- a/src/crypto/modes/gcm.c
+++ b/src/crypto/modes/gcm.c
@@ -46,7 +46,7 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ==================================================================== */
-#include <openssl/modes.h>
+#include <openssl/base.h>
#include <assert.h>
#include <string.h>
@@ -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 { \
@@ -86,6 +85,9 @@
} \
} while (0)
+// kSizeTWithoutLower4Bits is a mask that can be used to zero the lower four
+// bits of a |size_t|.
+static const size_t kSizeTWithoutLower4Bits = (size_t) -16;
static void gcm_init_4bit(u128 Htable[16], uint64_t H[2]) {
u128 V;
@@ -349,13 +351,13 @@ void gcm_ghash_4bit_x86(uint64_t Xi[2], const u128 Htable[16], const uint8_t *in
size_t len);
#endif
#elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
-#include "../arm_arch.h"
+#include <openssl/arm_arch.h>
#if __ARM_ARCH__ >= 7
#define GHASH_ASM_ARM
#define GCM_FUNCREF_4BIT
-static int pmull_capable() {
- return (OPENSSL_armcap_P & ARMV8_PMULL) != 0;
+static int pmull_capable(void) {
+ return CRYPTO_is_ARMv8_PMULL_capable();
}
void gcm_init_v8(u128 Htable[16], const uint64_t Xi[2]);
@@ -365,7 +367,7 @@ void gcm_ghash_v8(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp,
#if defined(OPENSSL_ARM)
/* 32-bit ARM also has support for doing GCM with NEON instructions. */
-static int neon_capable() {
+static int neon_capable(void) {
return CRYPTO_is_NEON_capable();
}
@@ -375,7 +377,7 @@ void gcm_ghash_neon(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp,
size_t len);
#else
/* AArch64 only has the ARMv8 versions of functions. */
-static int neon_capable() {
+static int neon_capable(void) {
return 0;
}
void gcm_init_neon(u128 Htable[16], const uint64_t Xi[2]) {
@@ -403,7 +405,7 @@ void gcm_ghash_neon(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp,
#endif
#endif
-GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block) {
+GCM128_CONTEXT *CRYPTO_gcm128_new(const void *key, block128_f block) {
GCM128_CONTEXT *ret;
ret = (GCM128_CONTEXT *)OPENSSL_malloc(sizeof(GCM128_CONTEXT));
@@ -414,7 +416,8 @@ GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block) {
return ret;
}
-void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block) {
+void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, const void *key,
+ block128_f block) {
const union {
long one;
char little;
@@ -422,7 +425,6 @@ void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block) {
memset(ctx, 0, sizeof(*ctx));
ctx->block = block;
- ctx->key = key;
(*block)(ctx->H.c, ctx->H.c, key);
@@ -488,7 +490,8 @@ void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block) {
#endif
}
-void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const uint8_t *iv, size_t len) {
+void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const void *key,
+ const uint8_t *iv, size_t len) {
const union {
long one;
char little;
@@ -556,7 +559,7 @@ void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const uint8_t *iv, size_t len) {
}
}
- (*ctx->block)(ctx->Yi.c, ctx->EK0.c, ctx->key);
+ (*ctx->block)(ctx->Yi.c, ctx->EK0.c, key);
++ctr;
if (is_endian.little) {
PUTU32(ctx->Yi.c + 12, ctr);
@@ -582,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;
@@ -629,8 +632,9 @@ int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const uint8_t *aad, size_t len) {
return 1;
}
-int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const unsigned char *in,
- unsigned char *out, size_t len) {
+int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const void *key,
+ const unsigned char *in, unsigned char *out,
+ size_t len) {
const union {
long one;
char little;
@@ -639,7 +643,6 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const unsigned char *in,
size_t i;
uint64_t mlen = ctx->len.u[1];
block128_f block = ctx->block;
- void *key = ctx->key;
#ifdef GCM_FUNCREF_4BIT
void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = ctx->gmult;
#ifdef GHASH
@@ -649,7 +652,7 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const unsigned char *in,
#endif
mlen += len;
- if (mlen > ((OPENSSL_U64(1) << 36) - 32) ||
+ if (mlen > ((UINT64_C(1) << 36) - 32) ||
(sizeof(len) == 8 && mlen < len)) {
return 0;
}
@@ -789,8 +792,9 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const unsigned char *in,
return 1;
}
-int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const unsigned char *in,
- unsigned char *out, size_t len) {
+int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const void *key,
+ const unsigned char *in, unsigned char *out,
+ size_t len) {
const union {
long one;
char little;
@@ -799,7 +803,6 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const unsigned char *in,
size_t i;
uint64_t mlen = ctx->len.u[1];
block128_f block = ctx->block;
- void *key = ctx->key;
#ifdef GCM_FUNCREF_4BIT
void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = ctx->gmult;
#ifdef GHASH
@@ -809,7 +812,7 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const unsigned char *in,
#endif
mlen += len;
- if (mlen > ((OPENSSL_U64(1) << 36) - 32) ||
+ if (mlen > ((UINT64_C(1) << 36) - 32) ||
(sizeof(len) == 8 && mlen < len)) {
return 0;
}
@@ -956,16 +959,15 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const unsigned char *in,
return 1;
}
-int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const uint8_t *in,
- uint8_t *out, size_t len, ctr128_f stream) {
+int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const void *key,
+ const uint8_t *in, uint8_t *out, size_t len,
+ ctr128_f stream) {
const union {
long one;
char little;
} is_endian = {1};
unsigned int n, ctr;
- size_t i;
uint64_t mlen = ctx->len.u[1];
- void *key = ctx->key;
#ifdef GCM_FUNCREF_4BIT
void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = ctx->gmult;
#ifdef GHASH
@@ -975,7 +977,7 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const uint8_t *in,
#endif
mlen += len;
- if (mlen > ((OPENSSL_U64(1) << 36) - 32) ||
+ if (mlen > ((UINT64_C(1) << 36) - 32) ||
(sizeof(len) == 8 && mlen < len)) {
return 0;
}
@@ -1022,7 +1024,8 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const uint8_t *in,
len -= GHASH_CHUNK;
}
#endif
- if ((i = (len & (size_t) - 16))) {
+ size_t i = len & kSizeTWithoutLower4Bits;
+ if (i != 0) {
size_t j = i / 16;
(*stream)(in, out, j, key, ctx->Yi.c);
@@ -1065,17 +1068,15 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const uint8_t *in,
return 1;
}
-int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const uint8_t *in,
- uint8_t *out, size_t len,
+int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const void *key,
+ const uint8_t *in, uint8_t *out, size_t len,
ctr128_f stream) {
const union {
long one;
char little;
} is_endian = {1};
unsigned int n, ctr;
- size_t i;
uint64_t mlen = ctx->len.u[1];
- void *key = ctx->key;
#ifdef GCM_FUNCREF_4BIT
void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = ctx->gmult;
#ifdef GHASH
@@ -1085,7 +1086,7 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const uint8_t *in,
#endif
mlen += len;
- if (mlen > ((OPENSSL_U64(1) << 36) - 32) ||
+ if (mlen > ((UINT64_C(1) << 36) - 32) ||
(sizeof(len) == 8 && mlen < len)) {
return 0;
}
@@ -1134,7 +1135,8 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const uint8_t *in,
len -= GHASH_CHUNK;
}
#endif
- if ((i = (len & (size_t) - 16))) {
+ size_t i = len & kSizeTWithoutLower4Bits;
+ if (i != 0) {
size_t j = i / 16;
#if defined(GHASH)
diff --git a/src/crypto/modes/gcm_test.c b/src/crypto/modes/gcm_test.c
index a8819ea..9414ac6 100644
--- a/src/crypto/modes/gcm_test.c
+++ b/src/crypto/modes/gcm_test.c
@@ -52,9 +52,9 @@
#include <openssl/aes.h>
#include <openssl/crypto.h>
#include <openssl/mem.h>
-#include <openssl/modes.h>
#include "internal.h"
+#include "../test/test_util.h"
struct test_case {
@@ -298,17 +298,6 @@ err:
return 0;
}
-void hexdump(const char *msg, const void *in, size_t len) {
- const uint8_t *data = in;
- size_t i;
-
- fprintf(stderr, "%s: ", msg);
- for (i = 0; i < len; i++) {
- fprintf(stderr, "%02x", data[i]);
- }
- fprintf(stderr, "\n");
-}
-
static int run_test_case(unsigned test_num, const struct test_case *test) {
size_t key_len, plaintext_len, additional_data_len, nonce_len, ciphertext_len,
tag_len;
@@ -356,29 +345,29 @@ static int run_test_case(unsigned test_num, const struct test_case *test) {
}
CRYPTO_gcm128_init(&ctx, &aes_key, (block128_f) AES_encrypt);
- CRYPTO_gcm128_setiv(&ctx, nonce, nonce_len);
+ CRYPTO_gcm128_setiv(&ctx, &aes_key, nonce, nonce_len);
memset(out, 0, plaintext_len);
if (additional_data) {
CRYPTO_gcm128_aad(&ctx, additional_data, additional_data_len);
}
if (plaintext) {
- CRYPTO_gcm128_encrypt(&ctx, plaintext, out, plaintext_len);
+ CRYPTO_gcm128_encrypt(&ctx, &aes_key, plaintext, out, plaintext_len);
}
if (!CRYPTO_gcm128_finish(&ctx, tag, tag_len) ||
(ciphertext && memcmp(out, ciphertext, plaintext_len) != 0)) {
fprintf(stderr, "%u: encrypt failed.\n", test_num);
- hexdump("got ", out, plaintext_len);
- hexdump("want", ciphertext, plaintext_len);
+ hexdump(stderr, "got :", out, plaintext_len);
+ hexdump(stderr, "want:", ciphertext, plaintext_len);
goto out;
}
- CRYPTO_gcm128_setiv(&ctx, nonce, nonce_len);
+ CRYPTO_gcm128_setiv(&ctx, &aes_key, nonce, nonce_len);
memset(out, 0, plaintext_len);
if (additional_data) {
CRYPTO_gcm128_aad(&ctx, additional_data, additional_data_len);
}
if (ciphertext) {
- CRYPTO_gcm128_decrypt(&ctx, ciphertext, out, plaintext_len);
+ CRYPTO_gcm128_decrypt(&ctx, &aes_key, ciphertext, out, plaintext_len);
}
if (!CRYPTO_gcm128_finish(&ctx, tag, tag_len)) {
fprintf(stderr, "%u: decrypt failed.\n", test_num);
diff --git a/src/crypto/modes/internal.h b/src/crypto/modes/internal.h
index d12405e..7255a7c 100644
--- a/src/crypto/modes/internal.h
+++ b/src/crypto/modes/internal.h
@@ -149,9 +149,16 @@ __inline uint32_t _bswap4(uint32_t val) {
#endif
+/* block128_f is the type of a 128-bit, block cipher. */
+typedef void (*block128_f)(const uint8_t in[16], uint8_t out[16],
+ const void *key);
+
/* GCM definitions */
typedef struct { uint64_t hi,lo; } u128;
+/* This differs from upstream's |gcm128_context| in that it does not have the
+ * |key| pointer, in order to make it |memcpy|-friendly. Rather the key is
+ * passed into each call that needs it. */
struct gcm128_context {
/* Following 6 names follow names in GCM specification */
union {
@@ -170,12 +177,6 @@ struct gcm128_context {
unsigned int mres, ares;
block128_f block;
- void *key;
-};
-
-struct xts128_context {
- void *key1, *key2;
- block128_f block1, block2;
};
struct ccm128_context {
@@ -195,6 +196,173 @@ int crypto_gcm_clmul_enabled(void);
#endif
+/* CTR. */
+
+/* ctr128_f is the type of a function that performs CTR-mode encryption. */
+typedef void (*ctr128_f)(const uint8_t *in, uint8_t *out, size_t blocks,
+ const void *key, const uint8_t ivec[16]);
+
+/* CRYPTO_ctr128_encrypt encrypts (or decrypts, it's the same in CTR mode)
+ * |len| bytes from |in| to |out| using |block| in counter mode. There's no
+ * requirement that |len| be a multiple of any value and any partial blocks are
+ * stored in |ecount_buf| and |*num|, which must be zeroed before the initial
+ * call. The counter is a 128-bit, big-endian value in |ivec| and is
+ * incremented by this function. */
+void CRYPTO_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
+ const void *key, uint8_t ivec[16],
+ uint8_t ecount_buf[16], unsigned int *num,
+ block128_f block);
+
+/* CRYPTO_ctr128_encrypt_ctr32 acts like |CRYPTO_ctr128_encrypt| but takes
+ * |ctr|, a function that performs CTR mode but only deals with the lower 32
+ * bits of the counter. This is useful when |ctr| can be an optimised
+ * function. */
+void CRYPTO_ctr128_encrypt_ctr32(const uint8_t *in, uint8_t *out, size_t len,
+ const void *key, uint8_t ivec[16],
+ uint8_t ecount_buf[16], unsigned int *num,
+ ctr128_f ctr);
+
+
+/* GCM.
+ *
+ * This API differs from the upstream API slightly. The |GCM128_CONTEXT| does
+ * not have a |key| pointer that points to the key as upstream's version does.
+ * Instead, every function takes a |key| parameter. This way |GCM128_CONTEXT|
+ * can be safely copied. */
+
+typedef struct gcm128_context GCM128_CONTEXT;
+
+/* CRYPTO_gcm128_new allocates a fresh |GCM128_CONTEXT| and calls
+ * |CRYPTO_gcm128_init|. It returns the new context, or NULL on error. */
+OPENSSL_EXPORT GCM128_CONTEXT *CRYPTO_gcm128_new(const void *key,
+ block128_f block);
+
+/* CRYPTO_gcm128_init initialises |ctx| to use |block| (typically AES) with
+ * the given key. */
+OPENSSL_EXPORT void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, const void *key,
+ block128_f block);
+
+/* CRYPTO_gcm128_setiv sets the IV (nonce) for |ctx|. The |key| must be the
+ * same key that was passed to |CRYPTO_gcm128_init|. */
+OPENSSL_EXPORT void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const void *key,
+ const uint8_t *iv, size_t iv_len);
+
+/* CRYPTO_gcm128_aad sets the authenticated data for an instance of GCM.
+ * This must be called before and data is encrypted. It returns one on success
+ * and zero otherwise. */
+OPENSSL_EXPORT int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const uint8_t *aad,
+ size_t len);
+
+/* CRYPTO_gcm128_encrypt encrypts |len| bytes from |in| to |out|. The |key|
+ * must be the same key that was passed to |CRYPTO_gcm128_init|. It returns one
+ * on success and zero otherwise. */
+OPENSSL_EXPORT int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const void *key,
+ const uint8_t *in, uint8_t *out,
+ size_t len);
+
+/* CRYPTO_gcm128_decrypt decrypts |len| bytes from |in| to |out|. The |key|
+ * must be the same key that was passed to |CRYPTO_gcm128_init|. It returns one
+ * on success and zero otherwise. */
+OPENSSL_EXPORT int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const void *key,
+ const uint8_t *in, uint8_t *out,
+ size_t len);
+
+/* CRYPTO_gcm128_encrypt_ctr32 encrypts |len| bytes from |in| to |out| using
+ * a CTR function that only handles the bottom 32 bits of the nonce, like
+ * |CRYPTO_ctr128_encrypt_ctr32|. The |key| must be the same key that was
+ * passed to |CRYPTO_gcm128_init|. It returns one on success and zero
+ * otherwise. */
+OPENSSL_EXPORT int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx,
+ const void *key,
+ const uint8_t *in, uint8_t *out,
+ size_t len, ctr128_f stream);
+
+/* CRYPTO_gcm128_decrypt_ctr32 decrypts |len| bytes from |in| to |out| using
+ * a CTR function that only handles the bottom 32 bits of the nonce, like
+ * |CRYPTO_ctr128_encrypt_ctr32|. The |key| must be the same key that was
+ * passed to |CRYPTO_gcm128_init|. It returns one on success and zero
+ * otherwise. */
+OPENSSL_EXPORT int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx,
+ const void *key,
+ const uint8_t *in, uint8_t *out,
+ size_t len, ctr128_f stream);
+
+/* CRYPTO_gcm128_finish calculates the authenticator and compares it against
+ * |len| bytes of |tag|. It returns one on success and zero otherwise. */
+OPENSSL_EXPORT int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const uint8_t *tag,
+ size_t len);
+
+/* CRYPTO_gcm128_tag calculates the authenticator and copies it into |tag|.
+ * The minimum of |len| and 16 bytes are copied into |tag|. */
+OPENSSL_EXPORT void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, uint8_t *tag,
+ size_t len);
+
+/* CRYPTO_gcm128_release clears and frees |ctx|. */
+OPENSSL_EXPORT void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx);
+
+
+/* CBC. */
+
+/* cbc128_f is the type of a function that performs CBC-mode encryption. */
+typedef void (*cbc128_f)(const uint8_t *in, uint8_t *out, size_t len,
+ const void *key, uint8_t ivec[16], int enc);
+
+/* CRYPTO_cbc128_encrypt encrypts |len| bytes from |in| to |out| using the
+ * given IV and block cipher in CBC mode. The input need not be a multiple of
+ * 128 bits long, but the output will round up to the nearest 128 bit multiple,
+ * zero padding the input if needed. The IV will be updated on return. */
+void CRYPTO_cbc128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
+ const void *key, uint8_t ivec[16], block128_f block);
+
+/* CRYPTO_cbc128_decrypt decrypts |len| bytes from |in| to |out| using the
+ * given IV and block cipher in CBC mode. If |len| is not a multiple of 128
+ * bits then only that many bytes will be written, but a multiple of 128 bits
+ * is always read from |in|. The IV will be updated on return. */
+void CRYPTO_cbc128_decrypt(const uint8_t *in, uint8_t *out, size_t len,
+ const void *key, uint8_t ivec[16], block128_f block);
+
+
+/* OFB. */
+
+/* CRYPTO_ofb128_encrypt encrypts (or decrypts, it's the same with OFB mode)
+ * |len| bytes from |in| to |out| using |block| in OFB mode. There's no
+ * requirement that |len| be a multiple of any value and any partial blocks are
+ * stored in |ivec| and |*num|, the latter must be zero before the initial
+ * call. */
+void CRYPTO_ofb128_encrypt(const uint8_t *in, uint8_t *out,
+ size_t len, const void *key, uint8_t ivec[16],
+ int *num, block128_f block);
+
+
+/* CFB. */
+
+/* CRYPTO_cfb128_encrypt encrypts (or decrypts, if |enc| is zero) |len| bytes
+ * from |in| to |out| using |block| in CFB mode. There's no requirement that
+ * |len| be a multiple of any value and any partial blocks are stored in |ivec|
+ * and |*num|, the latter must be zero before the initial call. */
+void CRYPTO_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
+ const void *key, uint8_t ivec[16], int *num, int enc,
+ block128_f block);
+
+/* CRYPTO_cfb128_8_encrypt encrypts (or decrypts, if |enc| is zero) |len| bytes
+ * from |in| to |out| using |block| in CFB-8 mode. Prior to the first call
+ * |num| should be set to zero. */
+void CRYPTO_cfb128_8_encrypt(const uint8_t *in, uint8_t *out, size_t len,
+ const void *key, uint8_t ivec[16], int *num,
+ int enc, block128_f block);
+
+/* CRYPTO_cfb128_1_encrypt encrypts (or decrypts, if |enc| is zero) |len| bytes
+ * from |in| to |out| using |block| in CFB-1 mode. Prior to the first call
+ * |num| should be set to zero. */
+void CRYPTO_cfb128_1_encrypt(const uint8_t *in, uint8_t *out, size_t bits,
+ const void *key, uint8_t ivec[16], int *num,
+ int enc, block128_f block);
+
+size_t CRYPTO_cts128_encrypt_block(const uint8_t *in, uint8_t *out, size_t len,
+ const void *key, uint8_t ivec[16],
+ block128_f block);
+
+
#if defined(__cplusplus)
} /* extern C */
#endif
diff --git a/src/crypto/modes/ofb.c b/src/crypto/modes/ofb.c
index 5836a9f..63c3165 100644
--- a/src/crypto/modes/ofb.c
+++ b/src/crypto/modes/ofb.c
@@ -46,20 +46,21 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ==================================================================== */
-#include <openssl/modes.h>
+#include <openssl/type_check.h>
#include <assert.h>
#include "internal.h"
+OPENSSL_COMPILE_ASSERT((16 % sizeof(size_t)) == 0, bad_size_t_size);
+
void CRYPTO_ofb128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
const void *key, uint8_t ivec[16], int *num,
block128_f block) {
unsigned int n;
assert(in && out && key && ivec && num);
- assert((16 % sizeof(size_t)) == 0);
n = *num;
diff --git a/src/crypto/obj/CMakeLists.txt b/src/crypto/obj/CMakeLists.txt
index a27e504..b8a4ef3 100644
--- a/src/crypto/obj/CMakeLists.txt
+++ b/src/crypto/obj/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
obj
diff --git a/src/crypto/obj/obj.c b/src/crypto/obj/obj.c
index bf16d17..94f739c 100644
--- a/src/crypto/obj/obj.c
+++ b/src/crypto/obj/obj.c
@@ -108,7 +108,7 @@ ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o) {
r = ASN1_OBJECT_new();
if (r == NULL) {
- OPENSSL_PUT_ERROR(OBJ, OBJ_dup, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(OBJ, ERR_R_ASN1_LIB);
return NULL;
}
r->ln = r->sn = NULL;
@@ -149,7 +149,7 @@ ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o) {
return r;
err:
- OPENSSL_PUT_ERROR(OBJ, OBJ_dup, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(OBJ, ERR_R_MALLOC_FAILURE);
OPENSSL_free(ln);
OPENSSL_free(sn);
OPENSSL_free(data);
@@ -337,7 +337,7 @@ const ASN1_OBJECT *OBJ_nid2obj(int nid) {
CRYPTO_STATIC_MUTEX_unlock(&global_added_lock);
err:
- OPENSSL_PUT_ERROR(OBJ, OBJ_nid2obj, OBJ_R_UNKNOWN_NID);
+ OPENSSL_PUT_ERROR(OBJ, OBJ_R_UNKNOWN_NID);
return NULL;
}
@@ -388,7 +388,7 @@ ASN1_OBJECT *OBJ_txt2obj(const char *s, int dont_search_names) {
buf = OPENSSL_malloc(total_len);
if (buf == NULL) {
- OPENSSL_PUT_ERROR(OBJ, OBJ_txt2obj, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(OBJ, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -636,7 +636,7 @@ int OBJ_create(const char *oid, const char *short_name, const char *long_name) {
buf = OPENSSL_malloc(len);
if (buf == NULL) {
- OPENSSL_PUT_ERROR(OBJ, OBJ_create, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(OBJ, ERR_R_MALLOC_FAILURE);
goto err;
}
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/CMakeLists.txt b/src/crypto/pem/CMakeLists.txt
index 720ba2f..30dd7c9 100644
--- a/src/crypto/pem/CMakeLists.txt
+++ b/src/crypto/pem/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
pem
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_info.c b/src/crypto/pem/pem_info.c
index 3f02619..2a39a5b 100644
--- a/src/crypto/pem/pem_info.c
+++ b/src/crypto/pem/pem_info.c
@@ -80,7 +80,7 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, pem_p
if ((b=BIO_new(BIO_s_file())) == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_X509_INFO_read, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,fp,BIO_NOCLOSE);
@@ -107,7 +107,7 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pe
{
if ((ret=sk_X509_INFO_new_null()) == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_X509_INFO_read_bio, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -248,13 +248,13 @@ start:
{
if (!d2i_PrivateKey(ptype, pp, &p, len))
{
- OPENSSL_PUT_ERROR(PEM, PEM_X509_INFO_read_bio, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
goto err;
}
}
else if (d2i(pp,&p,len) == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_X509_INFO_read_bio, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
goto err;
}
}
@@ -292,7 +292,7 @@ err:
if (xi != NULL) X509_INFO_free(xi);
if (!ok)
{
- for (i=0; ((int)i)<sk_X509_INFO_num(ret); i++)
+ for (i=0; i<sk_X509_INFO_num(ret); i++)
{
xi=sk_X509_INFO_value(ret,i);
X509_INFO_free(xi);
@@ -326,7 +326,7 @@ int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc,
objstr=OBJ_nid2sn(EVP_CIPHER_nid(enc));
if (objstr == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_X509_INFO_write_bio, PEM_R_UNSUPPORTED_CIPHER);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER);
goto err;
}
}
@@ -342,7 +342,7 @@ int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc,
{
if (enc == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_X509_INFO_write_bio, PEM_R_CIPHER_IS_NULL);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_CIPHER_IS_NULL);
goto err;
}
@@ -360,7 +360,7 @@ int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc,
EVP_CIPHER_nid(xi->enc_cipher.cipher));
if (objstr == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_X509_INFO_write_bio, PEM_R_UNSUPPORTED_CIPHER);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER);
goto err;
}
diff --git a/src/crypto/pem/pem_lib.c b/src/crypto/pem/pem_lib.c
index 5201467..12d9674 100644
--- a/src/crypto/pem/pem_lib.c
+++ b/src/crypto/pem/pem_lib.c
@@ -128,7 +128,7 @@ void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x,
if ((b=BIO_new(BIO_s_file())) == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_ASN1_read, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,fp,BIO_NOCLOSE);
@@ -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) &&
@@ -275,7 +271,7 @@ int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp,
if ((b=BIO_new(BIO_s_file())) == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_ASN1_write, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,fp,BIO_NOCLOSE);
@@ -302,14 +298,14 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
objstr=OBJ_nid2sn(EVP_CIPHER_nid(enc));
if (objstr == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_ASN1_write_bio, PEM_R_UNSUPPORTED_CIPHER);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER);
goto err;
}
}
if ((dsize=i2d(x,NULL)) < 0)
{
- OPENSSL_PUT_ERROR(PEM, PEM_ASN1_write_bio, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
dsize=0;
goto err;
}
@@ -318,7 +314,7 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
data=(unsigned char *)OPENSSL_malloc((unsigned int)dsize+20);
if (data == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_ASN1_write_bio, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
goto err;
}
p=data;
@@ -336,7 +332,7 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
klen=(*callback)(buf,PEM_BUFSIZE,1,u);
if (klen <= 0)
{
- OPENSSL_PUT_ERROR(PEM, PEM_ASN1_write_bio, PEM_R_READ_KEY);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_READ_KEY);
goto err;
}
kstr=(unsigned char *)buf;
@@ -408,7 +404,7 @@ int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen,
klen=callback(buf,PEM_BUFSIZE,0,u);
if (klen <= 0)
{
- OPENSSL_PUT_ERROR(PEM, PEM_do_header, PEM_R_BAD_PASSWORD_READ);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ);
return(0);
}
@@ -428,7 +424,7 @@ int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen,
OPENSSL_cleanse((char *)key,sizeof(key));
if (!o)
{
- OPENSSL_PUT_ERROR(PEM, PEM_do_header, PEM_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_DECRYPT);
return(0);
}
j+=i;
@@ -437,11 +433,18 @@ int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen,
}
static const EVP_CIPHER* cipher_by_name(const char *name) {
- if (strcmp(name, "DES-CBC") == 0) {
+ /* This is similar to the (deprecated) function |EVP_get_cipherbyname|. */
+ if (0 == strcmp(name, SN_rc4)) {
+ return EVP_rc4();
+ } else if (0 == strcmp(name, SN_des_cbc)) {
return EVP_des_cbc();
- } else if (strcmp(name, "AES-128-CBC") == 0) {
+ } else if (0 == strcmp(name, SN_des_ede3_cbc)) {
+ return EVP_des_ede3_cbc();
+ } else if (0 == strcmp(name, SN_aes_128_cbc)) {
return EVP_aes_128_cbc();
- } else if (strcmp(name, "AES-256-CBC") == 0) {
+ } else if (0 == strcmp(name, SN_aes_192_cbc)) {
+ return EVP_aes_192_cbc();
+ } else if (0 == strcmp(name, SN_aes_256_cbc)) {
return EVP_aes_256_cbc();
} else {
return NULL;
@@ -458,19 +461,19 @@ int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher)
if ((header == NULL) || (*header == '\0') || (*header == '\n'))
return(1);
if (strncmp(header,"Proc-Type: ",11) != 0)
- { OPENSSL_PUT_ERROR(PEM, PEM_get_EVP_CIPHER_INFO, PEM_R_NOT_PROC_TYPE); return(0); }
+ { OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_PROC_TYPE); return(0); }
header+=11;
if (*header != '4') return(0); header++;
if (*header != ',') return(0); header++;
if (strncmp(header,"ENCRYPTED",9) != 0)
- { OPENSSL_PUT_ERROR(PEM, PEM_get_EVP_CIPHER_INFO, PEM_R_NOT_ENCRYPTED); return(0); }
+ { OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_ENCRYPTED); return(0); }
for (; (*header != '\n') && (*header != '\0'); header++)
;
if (*header == '\0')
- { OPENSSL_PUT_ERROR(PEM, PEM_get_EVP_CIPHER_INFO, PEM_R_SHORT_HEADER); return(0); }
+ { OPENSSL_PUT_ERROR(PEM, PEM_R_SHORT_HEADER); return(0); }
header++;
if (strncmp(header,"DEK-Info: ",10) != 0)
- { OPENSSL_PUT_ERROR(PEM, PEM_get_EVP_CIPHER_INFO, PEM_R_NOT_DEK_INFO); return(0); }
+ { OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_DEK_INFO); return(0); }
header+=10;
p=header;
@@ -489,7 +492,7 @@ int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher)
if (enc == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_get_EVP_CIPHER_INFO, PEM_R_UNSUPPORTED_ENCRYPTION);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_ENCRYPTION);
return(0);
}
if (!load_iv(header_pp,&(cipher->iv[0]),EVP_CIPHER_iv_length(enc)))
@@ -516,7 +519,7 @@ static int load_iv(char **fromp, unsigned char *to, int num)
v= *from-'a'+10;
else
{
- OPENSSL_PUT_ERROR(PEM, load_iv, PEM_R_BAD_IV_CHARS);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_IV_CHARS);
return(0);
}
from++;
@@ -536,7 +539,7 @@ int PEM_write(FILE *fp, const char *name, const char *header,
if ((b=BIO_new(BIO_s_file())) == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_write, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,fp,BIO_NOCLOSE);
@@ -603,7 +606,7 @@ err:
OPENSSL_cleanse(buf, PEM_BUFSIZE*8);
OPENSSL_free(buf);
}
- OPENSSL_PUT_ERROR(PEM, PEM_write_bio, reason);
+ OPENSSL_PUT_ERROR(PEM, reason);
return(0);
}
@@ -616,7 +619,7 @@ int PEM_read(FILE *fp, char **name, char **header, unsigned char **data,
if ((b=BIO_new(BIO_s_file())) == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_read, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,fp,BIO_NOCLOSE);
@@ -644,7 +647,7 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
BUF_MEM_free(nameB);
BUF_MEM_free(headerB);
BUF_MEM_free(dataB);
- OPENSSL_PUT_ERROR(PEM, PEM_read_bio, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
return(0);
}
@@ -655,7 +658,7 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
if (i <= 0)
{
- OPENSSL_PUT_ERROR(PEM, PEM_read_bio, PEM_R_NO_START_LINE);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_NO_START_LINE);
goto err;
}
@@ -670,7 +673,7 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
continue;
if (!BUF_MEM_grow(nameB,i+9))
{
- OPENSSL_PUT_ERROR(PEM, PEM_read_bio, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
goto err;
}
memcpy(nameB->data,&(buf[11]),i-6);
@@ -680,7 +683,7 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
}
hl=0;
if (!BUF_MEM_grow(headerB,256))
- { OPENSSL_PUT_ERROR(PEM, PEM_read_bio, ERR_R_MALLOC_FAILURE); goto err; }
+ { OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); goto err; }
headerB->data[0]='\0';
for (;;)
{
@@ -692,7 +695,7 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
if (buf[0] == '\n') break;
if (!BUF_MEM_grow(headerB,hl+i+9))
- { OPENSSL_PUT_ERROR(PEM, PEM_read_bio, ERR_R_MALLOC_FAILURE); goto err; }
+ { OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); goto err; }
if (strncmp(buf,"-----END ",9) == 0)
{
nohead=1;
@@ -705,7 +708,7 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
bl=0;
if (!BUF_MEM_grow(dataB,1024))
- { OPENSSL_PUT_ERROR(PEM, PEM_read_bio, ERR_R_MALLOC_FAILURE); goto err; }
+ { OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); goto err; }
dataB->data[0]='\0';
if (!nohead)
{
@@ -723,7 +726,7 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
if (i > 65) break;
if (!BUF_MEM_grow_clean(dataB,i+bl+9))
{
- OPENSSL_PUT_ERROR(PEM, PEM_read_bio, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
goto err;
}
memcpy(&(dataB->data[bl]),buf,i);
@@ -754,7 +757,7 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
(strncmp(nameB->data,&(buf[9]),i) != 0) ||
(strncmp(&(buf[9+i]),"-----\n",6) != 0))
{
- OPENSSL_PUT_ERROR(PEM, PEM_read_bio, PEM_R_BAD_END_LINE);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_END_LINE);
goto err;
}
@@ -764,13 +767,13 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
(unsigned char *)dataB->data,bl);
if (i < 0)
{
- OPENSSL_PUT_ERROR(PEM, PEM_read_bio, PEM_R_BAD_BASE64_DECODE);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_BASE64_DECODE);
goto err;
}
i=EVP_DecodeFinal(&ctx,(unsigned char *)&(dataB->data[bl]),&k);
if (i < 0)
{
- OPENSSL_PUT_ERROR(PEM, PEM_read_bio, PEM_R_BAD_BASE64_DECODE);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_BASE64_DECODE);
goto err;
}
bl+=k;
diff --git a/src/crypto/pem/pem_oth.c b/src/crypto/pem/pem_oth.c
index 20d12b6..3e8f6bd 100644
--- a/src/crypto/pem/pem_oth.c
+++ b/src/crypto/pem/pem_oth.c
@@ -83,7 +83,7 @@ void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x,
p = data;
ret=d2i(x,&p,len);
if (ret == NULL)
- OPENSSL_PUT_ERROR(PEM, PEM_ASN1_read_bio, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
OPENSSL_free(data);
return ret;
}
diff --git a/src/crypto/pem/pem_pk8.c b/src/crypto/pem/pem_pk8.c
index 035038e..0824477 100644
--- a/src/crypto/pem/pem_pk8.c
+++ b/src/crypto/pem/pem_pk8.c
@@ -118,7 +118,7 @@ static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER
char buf[PEM_BUFSIZE];
int ret;
if(!(p8inf = EVP_PKEY2PKCS8(x))) {
- OPENSSL_PUT_ERROR(PEM, do_pk8pkey, PEM_R_ERROR_CONVERTING_PRIVATE_KEY);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_ERROR_CONVERTING_PRIVATE_KEY);
return 0;
}
if(enc || (nid != -1)) {
@@ -127,7 +127,7 @@ static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER
if (!cb) cb = PEM_def_callback;
klen = cb(buf, PEM_BUFSIZE, 1, u);
if(klen <= 0) {
- OPENSSL_PUT_ERROR(PEM, do_pk8pkey, PEM_R_READ_KEY);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_READ_KEY);
PKCS8_PRIV_KEY_INFO_free(p8inf);
return 0;
}
@@ -163,7 +163,7 @@ EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, vo
if (!cb) cb = PEM_def_callback;
klen=cb(psbuf,PEM_BUFSIZE,0,u);
if (klen <= 0) {
- OPENSSL_PUT_ERROR(PEM, d2i_PKCS8PrivateKey_bio, PEM_R_BAD_PASSWORD_READ);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ);
X509_SIG_free(p8);
return NULL;
}
@@ -216,7 +216,7 @@ static int do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid, const EVP_CI
BIO *bp;
int ret;
if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
- OPENSSL_PUT_ERROR(PEM, do_pk8pkey_fp, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
return(0);
}
ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u);
@@ -229,7 +229,7 @@ EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, vo
BIO *bp;
EVP_PKEY *ret;
if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
- OPENSSL_PUT_ERROR(PEM, d2i_PKCS8PrivateKey_fp, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
return NULL;
}
ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u);
diff --git a/src/crypto/pem/pem_pkey.c b/src/crypto/pem/pem_pkey.c
index fe58558..cd334b4 100644
--- a/src/crypto/pem/pem_pkey.c
+++ b/src/crypto/pem/pem_pkey.c
@@ -109,7 +109,7 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, vo
if (!cb) cb = PEM_def_callback;
klen=cb(psbuf,PEM_BUFSIZE,0,u);
if (klen <= 0) {
- OPENSSL_PUT_ERROR(PEM, PEM_read_bio_PrivateKey, PEM_R_BAD_PASSWORD_READ);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ);
X509_SIG_free(p8);
goto err;
}
@@ -132,7 +132,7 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, vo
}
p8err:
if (ret == NULL)
- OPENSSL_PUT_ERROR(PEM, PEM_read_bio_PrivateKey, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
err:
OPENSSL_free(nm);
@@ -210,7 +210,7 @@ EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x)
}
err:
if (ret == NULL)
- OPENSSL_PUT_ERROR(PEM, PEM_read_bio_Parameters, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
OPENSSL_free(nm);
OPENSSL_free(data);
return(ret);
@@ -236,7 +236,7 @@ EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void
if ((b=BIO_new(BIO_s_file())) == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_read_PrivateKey, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,fp,BIO_NOCLOSE);
@@ -254,7 +254,7 @@ int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
if ((b=BIO_new_fp(fp, BIO_NOCLOSE)) == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_write_PrivateKey, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
return 0;
}
ret=PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u);
@@ -280,14 +280,10 @@ 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, PEM_read_bio_DHparams, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
OPENSSL_free(nm);
OPENSSL_free(data);
return ret;
@@ -301,7 +297,7 @@ DH *PEM_read_DHparams(FILE *fp, DH **x, pem_password_cb *cb, void *u)
if ((b=BIO_new(BIO_s_file())) == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_read_DHparams, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,fp,BIO_NOCLOSE);
diff --git a/src/crypto/perlasm/arm-xlate.pl b/src/crypto/perlasm/arm-xlate.pl
index 81ceb31..706fa70 100755
--- a/src/crypto/perlasm/arm-xlate.pl
+++ b/src/crypto/perlasm/arm-xlate.pl
@@ -116,6 +116,9 @@ sub expand_line {
return $line;
}
+print "#if defined(__arm__)\n" if ($flavour eq "linux32");
+print "#if defined(__aarch64__)\n" if ($flavour eq "linux64");
+
while($line=<>) {
if ($line =~ m/^\s*(#|@|\/\/)/) { print $line; next; }
@@ -162,4 +165,6 @@ while($line=<>) {
print "\n";
}
+print "#endif" if ($flavour eq "linux32" || $flavour eq "linux64");
+
close STDOUT;
diff --git a/src/crypto/perlasm/x86_64-xlate.pl b/src/crypto/perlasm/x86_64-xlate.pl
index 8b46329..3ebb018 100755
--- a/src/crypto/perlasm/x86_64-xlate.pl
+++ b/src/crypto/perlasm/x86_64-xlate.pl
@@ -79,22 +79,17 @@ my $nasmref=2.03;
my $nasm=0;
if ($flavour eq "mingw64") { $gas=1; $elf=0; $win64=1;
+ # TODO(davidben): Before supporting the
+ # mingw64 perlasm flavour, do away with this
+ # environment variable check.
+ die "mingw64 not supported";
$prefix=`echo __USER_LABEL_PREFIX__ | $ENV{CC} -E -P -`;
chomp($prefix);
}
elsif ($flavour eq "macosx") { $gas=1; $elf=0; $prefix="_"; $decor="L\$"; }
elsif ($flavour eq "masm") { $gas=0; $elf=0; $masm=$masmref; $win64=1; $decor="\$L\$"; }
elsif ($flavour eq "nasm") { $gas=0; $elf=0; $nasm=$nasmref; $win64=1; $decor="\$L\$"; $PTR=""; }
-elsif (!$gas)
-{ if ($ENV{ASM} =~ m/nasm/ && `nasm -v` =~ m/version ([0-9]+)\.([0-9]+)/i)
- { $nasm = $1 + $2*0.01; $PTR=""; }
- elsif (`ml64 2>&1` =~ m/Version ([0-9]+)\.([0-9]+)(\.([0-9]+))?/)
- { $masm = $1 + $2*2**-16 + $4*2**-32; }
- die "no assembler found on %PATH" if (!($nasm || $masm));
- $win64=1;
- $elf=0;
- $decor="\$L\$";
-}
+elsif (!$gas) { die "unknown flavour $flavour"; }
my $current_segment;
my $current_function;
diff --git a/src/crypto/pkcs8/CMakeLists.txt b/src/crypto/pkcs8/CMakeLists.txt
index 4426f1e..9550109 100644
--- a/src/crypto/pkcs8/CMakeLists.txt
+++ b/src/crypto/pkcs8/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
pkcs8
@@ -19,4 +19,12 @@ add_executable(
$<TARGET_OBJECTS:test_support>
)
+add_executable(
+ pkcs8_test
+
+ pkcs8_test.cc
+)
+
+target_link_libraries(pkcs8_test crypto)
target_link_libraries(pkcs12_test crypto)
+add_dependencies(all_tests pkcs8_test pkcs12_test)
diff --git a/src/crypto/pkcs8/internal.h b/src/crypto/pkcs8/internal.h
index 44ca4f7..7995e78 100644
--- a/src/crypto/pkcs8/internal.h
+++ b/src/crypto/pkcs8/internal.h
@@ -66,6 +66,15 @@ extern "C" {
#define PKCS5_DEFAULT_ITERATIONS 2048
#define PKCS5_SALT_LEN 8
+/* PKCS5_v2_PBE_keyivgen intializes the supplied |ctx| for PBKDF v2, which must
+ * be specified by |param|. The password is specified by |pass_raw| and
+ * |pass_raw_len|. |cipher| and |md| are ignored.
+ *
+ * It returns one on success and zero on error. */
+int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const uint8_t *pass_raw,
+ size_t pass_raw_len, ASN1_TYPE *param,
+ const EVP_CIPHER *cipher, const EVP_MD *md, int enc);
+
#if defined(__cplusplus)
} /* extern C */
diff --git a/src/crypto/pkcs8/p5_pbe.c b/src/crypto/pkcs8/p5_pbe.c
index f30ae79..653cabf 100644
--- a/src/crypto/pkcs8/p5_pbe.c
+++ b/src/crypto/pkcs8/p5_pbe.c
@@ -86,21 +86,21 @@ int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
pbe = PBEPARAM_new();
if (!pbe)
{
- OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe_set0_algor, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
goto err;
}
if(iter <= 0)
iter = PKCS5_DEFAULT_ITERATIONS;
if (!ASN1_INTEGER_set(pbe->iter, iter))
{
- OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe_set0_algor, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!saltlen)
saltlen = PKCS5_SALT_LEN;
if (!ASN1_STRING_set(pbe->salt, NULL, saltlen))
{
- OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe_set0_algor, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
goto err;
}
sstr = ASN1_STRING_data(pbe->salt);
@@ -111,7 +111,7 @@ int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
if(!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str))
{
- OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe_set0_algor, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -138,7 +138,7 @@ X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
ret = X509_ALGOR_new();
if (!ret)
{
- OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe_set, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
return NULL;
}
diff --git a/src/crypto/pkcs8/p5_pbev2.c b/src/crypto/pkcs8/p5_pbev2.c
index 9eb9848..fec0d86 100644
--- a/src/crypto/pkcs8/p5_pbev2.c
+++ b/src/crypto/pkcs8/p5_pbev2.c
@@ -53,6 +53,8 @@
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
+#include <assert.h>
+#include <limits.h>
#include <string.h>
#include <openssl/asn1t.h>
@@ -124,7 +126,7 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
alg_nid = EVP_CIPHER_nid(cipher);
if(alg_nid == NID_undef) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe2_set_iv, PKCS8_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
goto err;
}
obj = OBJ_nid2obj(alg_nid);
@@ -152,7 +154,7 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
if (!EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0))
goto err;
if(param_to_asn1(&ctx, scheme->parameter) < 0) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe2_set_iv, PKCS8_R_ERROR_SETTING_CIPHER_PARAMS);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_ERROR_SETTING_CIPHER_PARAMS);
EVP_CIPHER_CTX_cleanup(&ctx);
goto err;
}
@@ -202,7 +204,7 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
return ret;
merr:
- OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe2_set_iv, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
err:
PBE2PARAM_free(pbe2);
@@ -295,9 +297,144 @@ X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
return keyfunc;
merr:
- OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbkdf2_set, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
PBKDF2PARAM_free(kdf);
X509_ALGOR_free(keyfunc);
return NULL;
}
+static int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx,
+ const uint8_t *pass_raw,
+ size_t pass_raw_len, const ASN1_TYPE *param,
+ const ASN1_TYPE *iv, int enc) {
+ int rv = 0;
+ PBKDF2PARAM *pbkdf2param = NULL;
+
+ if (EVP_CIPHER_CTX_cipher(ctx) == NULL) {
+ OPENSSL_PUT_ERROR(PKCS8, CIPHER_R_NO_CIPHER_SET);
+ goto err;
+ }
+
+ /* Decode parameters. */
+ if (param == NULL || param->type != V_ASN1_SEQUENCE) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR);
+ goto err;
+ }
+
+ const uint8_t *pbuf = param->value.sequence->data;
+ int plen = param->value.sequence->length;
+ pbkdf2param = d2i_PBKDF2PARAM(NULL, &pbuf, plen);
+ if (pbkdf2param == NULL || pbuf != param->value.sequence->data + plen) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR);
+ goto err;
+ }
+
+ /* Now check the parameters. */
+ uint8_t key[EVP_MAX_KEY_LENGTH];
+ const size_t key_len = EVP_CIPHER_CTX_key_length(ctx);
+ assert(key_len <= sizeof(key));
+
+ if (pbkdf2param->keylength != NULL &&
+ ASN1_INTEGER_get(pbkdf2param->keylength) != (int) key_len) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_KEYLENGTH);
+ goto err;
+ }
+
+ if (pbkdf2param->prf != NULL &&
+ OBJ_obj2nid(pbkdf2param->prf->algorithm) != NID_hmacWithSHA1) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_PRF);
+ goto err;
+ }
+
+ if (pbkdf2param->salt->type != V_ASN1_OCTET_STRING) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_SALT_TYPE);
+ goto err;
+ }
+
+ if (pbkdf2param->iter->type != V_ASN1_INTEGER) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_ITERATION_COUNT);
+ goto err;
+ }
+ long iterations = ASN1_INTEGER_get(pbkdf2param->iter);
+ if (iterations <= 0 ||
+ (sizeof(long) > sizeof(unsigned) && iterations > (long)UINT_MAX)) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_ITERATION_COUNT);
+ goto err;
+ }
+
+ if (iv->type != V_ASN1_OCTET_STRING || iv->value.octet_string == NULL) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_ERROR_SETTING_CIPHER_PARAMS);
+ goto err;
+ }
+
+ const size_t iv_len = EVP_CIPHER_CTX_iv_length(ctx);
+ if ((size_t) iv->value.octet_string->length != iv_len) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_ERROR_SETTING_CIPHER_PARAMS);
+ goto err;
+ }
+
+ if (!PKCS5_PBKDF2_HMAC_SHA1((const char *) pass_raw, pass_raw_len,
+ pbkdf2param->salt->value.octet_string->data,
+ pbkdf2param->salt->value.octet_string->length,
+ iterations, key_len, key)) {
+ goto err;
+ }
+
+ rv = EVP_CipherInit_ex(ctx, NULL /* cipher */, NULL /* engine */, key,
+ iv->value.octet_string->data, enc);
+
+ err:
+ PBKDF2PARAM_free(pbkdf2param);
+ return rv;
+}
+
+int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const uint8_t *pass_raw,
+ size_t pass_raw_len, ASN1_TYPE *param,
+ const EVP_CIPHER *unused, const EVP_MD *unused2,
+ int enc) {
+ PBE2PARAM *pbe2param = NULL;
+ int rv = 0;
+
+ if (param == NULL ||
+ param->type != V_ASN1_SEQUENCE ||
+ param->value.sequence == NULL) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR);
+ goto err;
+ }
+
+ const uint8_t *pbuf = param->value.sequence->data;
+ int plen = param->value.sequence->length;
+ pbe2param = d2i_PBE2PARAM(NULL, &pbuf, plen);
+ if (pbe2param == NULL || pbuf != param->value.sequence->data + plen) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR);
+ goto err;
+ }
+
+ /* Check that the key derivation function is PBKDF2. */
+ if (OBJ_obj2nid(pbe2param->keyfunc->algorithm) != NID_id_pbkdf2) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION);
+ goto err;
+ }
+
+ /* See if we recognise the encryption algorithm. */
+ const EVP_CIPHER *cipher =
+ EVP_get_cipherbynid(OBJ_obj2nid(pbe2param->encryption->algorithm));
+ if (cipher == NULL) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_CIPHER);
+ goto err;
+ }
+
+ /* Fixup cipher based on AlgorithmIdentifier. */
+ if (!EVP_CipherInit_ex(ctx, cipher, NULL /* engine */, NULL /* key */,
+ NULL /* iv */, enc)) {
+ goto err;
+ }
+
+ rv = PKCS5_v2_PBKDF2_keyivgen(ctx, pass_raw, pass_raw_len,
+ pbe2param->keyfunc->parameter,
+ pbe2param->encryption->parameter, enc);
+
+ err:
+ PBE2PARAM_free(pbe2param);
+ return rv;
+}
diff --git a/src/crypto/pkcs8/p8_pkey.c b/src/crypto/pkcs8/p8_pkey.c
index bd9d30c..c69d0fa 100644
--- a/src/crypto/pkcs8/p8_pkey.c
+++ b/src/crypto/pkcs8/p8_pkey.c
@@ -66,7 +66,7 @@ static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
/* Since the structure must still be valid use ASN1_OP_FREE_PRE */
if (operation == ASN1_OP_FREE_PRE) {
PKCS8_PRIV_KEY_INFO *key = (PKCS8_PRIV_KEY_INFO *)*pval;
- if (key->pkey &&
+ if (key->pkey && key->pkey->type == V_ASN1_OCTET_STRING &&
key->pkey->value.octet_string) {
OPENSSL_cleanse(key->pkey->value.octet_string->data,
key->pkey->value.octet_string->length);
diff --git a/src/crypto/pkcs8/pkcs12_test.cc b/src/crypto/pkcs8/pkcs12_test.cc
index 8b265cd..55006b4 100644
--- a/src/crypto/pkcs8/pkcs12_test.cc
+++ b/src/crypto/pkcs8/pkcs12_test.cc
@@ -681,6 +681,8 @@ static const uint8_t kWindows[] = {
0xfe, 0x3a, 0x66, 0x47, 0x40, 0x49, 0x02, 0x02, 0x07, 0xd0,
};
+static const char kPassword[] = "foo";
+
static bool Test(const char *name, const uint8_t *der, size_t der_len) {
ScopedX509Stack certs(sk_X509_new_null());
if (!certs) {
@@ -690,7 +692,7 @@ static bool Test(const char *name, const uint8_t *der, size_t der_len) {
CBS pkcs12;
EVP_PKEY *key = nullptr;
CBS_init(&pkcs12, der, der_len);
- if (!PKCS12_get_key_and_certs(&key, certs.get(), &pkcs12, "foo")) {
+ if (!PKCS12_get_key_and_certs(&key, certs.get(), &pkcs12, kPassword)) {
fprintf(stderr, "PKCS12 failed on %s data.\n", name);
ERR_print_errors_fp(stderr);
return false;
@@ -718,10 +720,20 @@ static bool TestCompat(const uint8_t *der, size_t der_len) {
return false;
}
+ if (PKCS12_verify_mac(p12.get(), "badpass", 7)) {
+ fprintf(stderr, "PKCS12_verify_mac accepted bad password.\n");
+ return false;
+ }
+
+ if (!PKCS12_verify_mac(p12.get(), kPassword, sizeof(kPassword) - 1)) {
+ fprintf(stderr, "PKCS12_verify_mac rejected good password.\n");
+ return false;
+ }
+
EVP_PKEY *key = nullptr;
X509 *cert = nullptr;
STACK_OF(X509) *ca_certs = nullptr;
- if (!PKCS12_parse(p12.get(), "foo", &key, &cert, &ca_certs)) {
+ if (!PKCS12_parse(p12.get(), kPassword, &key, &cert, &ca_certs)) {
fprintf(stderr, "PKCS12_parse failed.\n");
ERR_print_errors_fp(stderr);
return false;
diff --git a/src/crypto/pkcs8/pkcs8.c b/src/crypto/pkcs8/pkcs8.c
index 843c74d..31a34a7 100644
--- a/src/crypto/pkcs8/pkcs8.c
+++ b/src/crypto/pkcs8/pkcs8.c
@@ -69,6 +69,7 @@
#include <openssl/mem.h>
#include <openssl/x509.h>
+#include "internal.h"
#include "../bytestring/internal.h"
#include "../evp/internal.h"
@@ -200,7 +201,7 @@ static int pkcs12_key_gen_raw(const uint8_t *pass_raw, size_t pass_raw_len,
}
err:
- OPENSSL_PUT_ERROR(PKCS8, pkcs12_key_gen_raw, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
end:
OPENSSL_free(Ai);
@@ -227,14 +228,14 @@ static int pkcs12_pbe_keyivgen(EVP_CIPHER_CTX *ctx, const uint8_t *pass_raw,
/* Extract useful info from parameter */
if (param == NULL || param->type != V_ASN1_SEQUENCE ||
param->value.sequence == NULL) {
- OPENSSL_PUT_ERROR(PKCS8, pkcs12_pbe_keyivgen, PKCS8_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR);
return 0;
}
pbuf = param->value.sequence->data;
pbe = d2i_PBEPARAM(NULL, &pbuf, param->value.sequence->length);
if (pbe == NULL) {
- OPENSSL_PUT_ERROR(PKCS8, pkcs12_pbe_keyivgen, PKCS8_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR);
return 0;
}
@@ -247,13 +248,13 @@ static int pkcs12_pbe_keyivgen(EVP_CIPHER_CTX *ctx, const uint8_t *pass_raw,
salt_len = pbe->salt->length;
if (!pkcs12_key_gen_raw(pass_raw, pass_raw_len, salt, salt_len, PKCS12_KEY_ID,
iterations, EVP_CIPHER_key_length(cipher), key, md)) {
- OPENSSL_PUT_ERROR(PKCS8, pkcs12_pbe_keyivgen, PKCS8_R_KEY_GEN_ERROR);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_KEY_GEN_ERROR);
PBEPARAM_free(pbe);
return 0;
}
if (!pkcs12_key_gen_raw(pass_raw, pass_raw_len, salt, salt_len, PKCS12_IV_ID,
iterations, EVP_CIPHER_iv_length(cipher), iv, md)) {
- OPENSSL_PUT_ERROR(PKCS8, pkcs12_pbe_keyivgen, PKCS8_R_KEY_GEN_ERROR);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_KEY_GEN_ERROR);
PBEPARAM_free(pbe);
return 0;
}
@@ -274,42 +275,93 @@ struct pbe_suite {
const EVP_CIPHER* (*cipher_func)(void);
const EVP_MD* (*md_func)(void);
keygen_func keygen;
+ int flags;
};
+#define PBE_UCS2_CONVERT_PASSWORD 0x1
+
static const struct pbe_suite kBuiltinPBE[] = {
{
- NID_pbe_WithSHA1And40BitRC2_CBC, EVP_rc2_40_cbc, EVP_sha1, pkcs12_pbe_keyivgen,
+ NID_pbe_WithSHA1And40BitRC2_CBC, EVP_rc2_40_cbc, EVP_sha1,
+ pkcs12_pbe_keyivgen, PBE_UCS2_CONVERT_PASSWORD
},
{
NID_pbe_WithSHA1And128BitRC4, EVP_rc4, EVP_sha1, pkcs12_pbe_keyivgen,
+ PBE_UCS2_CONVERT_PASSWORD
},
{
NID_pbe_WithSHA1And3_Key_TripleDES_CBC, EVP_des_ede3_cbc, EVP_sha1,
- pkcs12_pbe_keyivgen,
+ pkcs12_pbe_keyivgen, PBE_UCS2_CONVERT_PASSWORD
+ },
+ {
+ NID_pbes2, NULL, NULL, PKCS5_v2_PBE_keyivgen, 0
},
};
+static const struct pbe_suite *get_pbe_suite(int pbe_nid) {
+ unsigned i;
+ for (i = 0; i < sizeof(kBuiltinPBE) / sizeof(kBuiltinPBE[0]); i++) {
+ if (kBuiltinPBE[i].pbe_nid == pbe_nid) {
+ return &kBuiltinPBE[i];
+ }
+ }
+
+ return NULL;
+}
+
+/* pass_to_pass_raw performs a password conversion (possibly a no-op)
+ * appropriate to the supplied |pbe_nid|. The input |pass| is treated as a
+ * NUL-terminated string if |pass_len| is -1, otherwise it is treated as a
+ * buffer of the specified length. If the supplied PBE NID sets the
+ * |PBE_UCS2_CONVERT_PASSWORD| flag, the supplied |pass| will be converted to
+ * UCS-2.
+ *
+ * It sets |*out_pass_raw| to a new buffer that must be freed by the caller. It
+ * returns one on success and zero on error. */
+static int pass_to_pass_raw(int pbe_nid, const char *pass, int pass_len,
+ uint8_t **out_pass_raw, size_t *out_pass_raw_len) {
+ if (pass == NULL) {
+ *out_pass_raw = NULL;
+ *out_pass_raw_len = 0;
+ return 1;
+ }
+
+ if (pass_len == -1) {
+ pass_len = strlen(pass);
+ } else if (pass_len < 0 || pass_len > 2000000000) {
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_OVERFLOW);
+ return 0;
+ }
+
+ const struct pbe_suite *suite = get_pbe_suite(pbe_nid);
+ if (suite != NULL && (suite->flags & PBE_UCS2_CONVERT_PASSWORD)) {
+ if (!ascii_to_ucs2(pass, pass_len, out_pass_raw, out_pass_raw_len)) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR);
+ return 0;
+ }
+ } else {
+ *out_pass_raw = BUF_memdup(pass, pass_len);
+ if (*out_pass_raw == NULL) {
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ *out_pass_raw_len = (size_t)pass_len;
+ }
+
+ return 1;
+}
+
static int pbe_cipher_init(ASN1_OBJECT *pbe_obj,
const uint8_t *pass_raw, size_t pass_raw_len,
ASN1_TYPE *param,
EVP_CIPHER_CTX *ctx, int is_encrypt) {
const EVP_CIPHER *cipher;
const EVP_MD *md;
- unsigned i;
-
- const struct pbe_suite *suite = NULL;
- const int pbe_nid = OBJ_obj2nid(pbe_obj);
-
- for (i = 0; i < sizeof(kBuiltinPBE) / sizeof(struct pbe_suite); i++) {
- if (kBuiltinPBE[i].pbe_nid == pbe_nid) {
- suite = &kBuiltinPBE[i];
- break;
- }
- }
+ const struct pbe_suite *suite = get_pbe_suite(OBJ_obj2nid(pbe_obj));
if (suite == NULL) {
char obj_str[80];
- OPENSSL_PUT_ERROR(PKCS8, pbe_cipher_init, PKCS8_R_UNKNOWN_ALGORITHM);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNKNOWN_ALGORITHM);
if (!pbe_obj) {
strncpy(obj_str, "NULL", sizeof(obj_str));
} else {
@@ -324,7 +376,7 @@ static int pbe_cipher_init(ASN1_OBJECT *pbe_obj,
} else {
cipher = suite->cipher_func();
if (!cipher) {
- OPENSSL_PUT_ERROR(PKCS8, pbe_cipher_init, PKCS8_R_UNKNOWN_CIPHER);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNKNOWN_CIPHER);
return 0;
}
}
@@ -334,14 +386,14 @@ static int pbe_cipher_init(ASN1_OBJECT *pbe_obj,
} else {
md = suite->md_func();
if (!md) {
- OPENSSL_PUT_ERROR(PKCS8, pbe_cipher_init, PKCS8_R_UNKNOWN_DIGEST);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNKNOWN_DIGEST);
return 0;
}
}
if (!suite->keygen(ctx, pass_raw, pass_raw_len, param, cipher, md,
is_encrypt)) {
- OPENSSL_PUT_ERROR(PKCS8, pbe_cipher_init, PKCS8_R_KEYGEN_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_KEYGEN_FAILURE);
return 0;
}
@@ -362,32 +414,32 @@ static int pbe_crypt(const X509_ALGOR *algor,
if (!pbe_cipher_init(algor->algorithm, pass_raw, pass_raw_len,
algor->parameter, &ctx, is_encrypt)) {
- OPENSSL_PUT_ERROR(PKCS8, pbe_crypt, PKCS8_R_UNKNOWN_CIPHER_ALGORITHM);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNKNOWN_CIPHER_ALGORITHM);
return 0;
}
block_size = EVP_CIPHER_CTX_block_size(&ctx);
if (in_len + block_size < in_len) {
- OPENSSL_PUT_ERROR(PKCS8, pbe_crypt, PKCS8_R_TOO_LONG);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_TOO_LONG);
goto err;
}
buf = OPENSSL_malloc(in_len + block_size);
if (buf == NULL) {
- OPENSSL_PUT_ERROR(PKCS8, pbe_crypt, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EVP_CipherUpdate(&ctx, buf, &n, in, in_len)) {
OPENSSL_free(buf);
- OPENSSL_PUT_ERROR(PKCS8, pbe_crypt, ERR_R_EVP_LIB);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_EVP_LIB);
goto err;
}
*out_len = n;
if (!EVP_CipherFinal_ex(&ctx, buf + n, &n)) {
OPENSSL_free(buf);
- OPENSSL_PUT_ERROR(PKCS8, pbe_crypt, ERR_R_EVP_LIB);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_EVP_LIB);
goto err;
}
*out_len += n;
@@ -410,14 +462,14 @@ static void *pkcs12_item_decrypt_d2i(X509_ALGOR *algor, const ASN1_ITEM *it,
if (!pbe_crypt(algor, pass_raw, pass_raw_len, oct->data, oct->length,
&out, &out_len, 0 /* decrypt */)) {
- OPENSSL_PUT_ERROR(PKCS8, pkcs12_item_decrypt_d2i, PKCS8_R_CRYPT_ERROR);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_CRYPT_ERROR);
return NULL;
}
p = out;
ret = ASN1_item_d2i(NULL, &p, out_len, it);
OPENSSL_cleanse(out, out_len);
if (!ret) {
- OPENSSL_PUT_ERROR(PKCS8, pkcs12_item_decrypt_d2i, PKCS8_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR);
}
OPENSSL_free(out);
return ret;
@@ -427,19 +479,12 @@ PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *pkcs8, const char *pass,
int pass_len) {
uint8_t *pass_raw = NULL;
size_t pass_raw_len = 0;
- PKCS8_PRIV_KEY_INFO *ret;
-
- if (pass) {
- if (pass_len == -1) {
- pass_len = strlen(pass);
- }
- if (!ascii_to_ucs2(pass, pass_len, &pass_raw, &pass_raw_len)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS8_decrypt, PKCS8_R_DECODE_ERROR);
- return NULL;
- }
+ if (!pass_to_pass_raw(OBJ_obj2nid(pkcs8->algor->algorithm), pass, pass_len,
+ &pass_raw, &pass_raw_len)) {
+ return NULL;
}
- ret = PKCS8_decrypt_pbe(pkcs8, pass_raw, pass_raw_len);
+ PKCS8_PRIV_KEY_INFO *ret = PKCS8_decrypt_pbe(pkcs8, pass_raw, pass_raw_len);
if (pass_raw) {
OPENSSL_cleanse(pass_raw, pass_raw_len);
@@ -466,17 +511,17 @@ static ASN1_OCTET_STRING *pkcs12_item_i2d_encrypt(X509_ALGOR *algor,
oct = M_ASN1_OCTET_STRING_new();
if (oct == NULL) {
- OPENSSL_PUT_ERROR(PKCS8, pkcs12_item_i2d_encrypt, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
return NULL;
}
in_len = ASN1_item_i2d(obj, &in, it);
if (!in) {
- OPENSSL_PUT_ERROR(PKCS8, pkcs12_item_i2d_encrypt, PKCS8_R_ENCODE_ERROR);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_ENCODE_ERROR);
return NULL;
}
if (!pbe_crypt(algor, pass_raw, pass_raw_len, in, in_len, &oct->data, &crypt_len,
1 /* encrypt */)) {
- OPENSSL_PUT_ERROR(PKCS8, pkcs12_item_i2d_encrypt, PKCS8_R_ENCRYPT_ERROR);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_ENCRYPT_ERROR);
OPENSSL_free(in);
return NULL;
}
@@ -491,20 +536,12 @@ X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, const char *pass,
int iterations, PKCS8_PRIV_KEY_INFO *p8inf) {
uint8_t *pass_raw = NULL;
size_t pass_raw_len = 0;
- X509_SIG *ret;
-
- if (pass) {
- if (pass_len == -1) {
- pass_len = strlen(pass);
- }
- if (!ascii_to_ucs2(pass, pass_len, &pass_raw, &pass_raw_len)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS8_encrypt, PKCS8_R_DECODE_ERROR);
- return NULL;
- }
+ if (!pass_to_pass_raw(pbe_nid, pass, pass_len, &pass_raw, &pass_raw_len)) {
+ return NULL;
}
- ret = PKCS8_encrypt_pbe(pbe_nid, pass_raw, pass_raw_len,
- salt, salt_len, iterations, p8inf);
+ X509_SIG *ret = PKCS8_encrypt_pbe(pbe_nid, cipher, pass_raw, pass_raw_len,
+ salt, salt_len, iterations, p8inf);
if (pass_raw) {
OPENSSL_cleanse(pass_raw, pass_raw_len);
@@ -513,7 +550,7 @@ X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, const char *pass,
return ret;
}
-X509_SIG *PKCS8_encrypt_pbe(int pbe_nid,
+X509_SIG *PKCS8_encrypt_pbe(int pbe_nid, const EVP_CIPHER *cipher,
const uint8_t *pass_raw, size_t pass_raw_len,
uint8_t *salt, size_t salt_len,
int iterations, PKCS8_PRIV_KEY_INFO *p8inf) {
@@ -522,13 +559,17 @@ X509_SIG *PKCS8_encrypt_pbe(int pbe_nid,
pkcs8 = X509_SIG_new();
if (pkcs8 == NULL) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS8_encrypt_pbe, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
goto err;
}
- pbe = PKCS5_pbe_set(pbe_nid, iterations, salt, salt_len);
+ if (pbe_nid == -1) {
+ pbe = PKCS5_pbe2_set(cipher, iterations, salt, salt_len);
+ } else {
+ pbe = PKCS5_pbe_set(pbe_nid, iterations, salt, salt_len);
+ }
if (!pbe) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS8_encrypt_pbe, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_ASN1_LIB);
goto err;
}
@@ -538,7 +579,7 @@ X509_SIG *PKCS8_encrypt_pbe(int pbe_nid,
pkcs8->digest = pkcs12_item_i2d_encrypt(
pbe, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), pass_raw, pass_raw_len, p8inf);
if (!pkcs8->digest) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS8_encrypt_pbe, PKCS8_R_ENCRYPT_ERROR);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_ENCRYPT_ERROR);
goto err;
}
@@ -560,13 +601,12 @@ EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) {
pkey = EVP_PKEY_new();
if (pkey == NULL) {
- OPENSSL_PUT_ERROR(PKCS8, EVP_PKCS82PKEY, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
return NULL;
}
if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid))) {
- OPENSSL_PUT_ERROR(PKCS8, EVP_PKCS82PKEY,
- PKCS8_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
i2t_ASN1_OBJECT(obj_tmp, 80, algoid);
ERR_add_error_data(2, "TYPE=", obj_tmp);
goto error;
@@ -574,11 +614,11 @@ EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) {
if (pkey->ameth->priv_decode) {
if (!pkey->ameth->priv_decode(pkey, p8)) {
- OPENSSL_PUT_ERROR(PKCS8, EVP_PKCS82PKEY, PKCS8_R_PRIVATE_KEY_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_PRIVATE_KEY_DECODE_ERROR);
goto error;
}
} else {
- OPENSSL_PUT_ERROR(PKCS8, EVP_PKCS82PKEY, PKCS8_R_METHOD_NOT_SUPPORTED);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_METHOD_NOT_SUPPORTED);
goto error;
}
@@ -594,7 +634,7 @@ PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey) {
p8 = PKCS8_PRIV_KEY_INFO_new();
if (p8 == NULL) {
- OPENSSL_PUT_ERROR(PKCS8, EVP_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
return NULL;
}
p8->broken = PKCS8_OK;
@@ -602,17 +642,15 @@ PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey) {
if (pkey->ameth) {
if (pkey->ameth->priv_encode) {
if (!pkey->ameth->priv_encode(p8, pkey)) {
- OPENSSL_PUT_ERROR(PKCS8, EVP_PKEY2PKCS8,
- PKCS8_R_PRIVATE_KEY_ENCODE_ERROR);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_PRIVATE_KEY_ENCODE_ERROR);
goto error;
}
} else {
- OPENSSL_PUT_ERROR(PKCS8, EVP_PKEY2PKCS8, PKCS8_R_METHOD_NOT_SUPPORTED);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_METHOD_NOT_SUPPORTED);
goto error;
}
} else {
- OPENSSL_PUT_ERROR(PKCS8, EVP_PKEY2PKCS8,
- PKCS8_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
goto error;
}
return p8;
@@ -646,8 +684,7 @@ static int PKCS12_handle_content_infos(CBS *content_infos,
* pkcs7-encryptedData and a pkcs7-data) and depth 1 (the various PKCS#12
* bags). */
if (depth > 3) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_infos,
- PKCS8_R_PKCS12_TOO_DEEPLY_NESTED);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_PKCS12_TOO_DEEPLY_NESTED);
return 0;
}
@@ -656,6 +693,7 @@ static int PKCS12_handle_content_infos(CBS *content_infos,
* conversion cannot see through those wrappings. So each time we step
* through one we need to convert to DER again. */
if (!CBS_asn1_ber_to_der(content_infos, &der_bytes, &der_len)) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
return 0;
}
@@ -666,16 +704,14 @@ static int PKCS12_handle_content_infos(CBS *content_infos,
}
if (!CBS_get_asn1(&in, &in, CBS_ASN1_SEQUENCE)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_infos,
- PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
while (CBS_len(&in) > 0) {
CBS content_info;
if (!CBS_get_asn1(&in, &content_info, CBS_ASN1_SEQUENCE)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_infos,
- PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
@@ -705,8 +741,7 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth,
if (!CBS_get_asn1(content_info, &content_type, CBS_ASN1_OBJECT) ||
!CBS_get_asn1(content_info, &wrapped_contents,
CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info,
- PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
@@ -734,26 +769,24 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth,
!CBS_get_asn1_element(&eci, &ai, CBS_ASN1_SEQUENCE) ||
!CBS_get_asn1(&eci, &encrypted_contents,
CBS_ASN1_CONTEXT_SPECIFIC | 0)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info,
- PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
- if (OBJ_cbs2nid(&contents_type) != NID_pkcs7_data) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info,
- PKCS8_R_BAD_PKCS12_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;
}
if (inp != CBS_data(&ai) + CBS_len(&ai)) {
X509_ALGOR_free(algor);
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info,
- PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
@@ -773,8 +806,7 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth,
if (!CBS_get_asn1(&wrapped_contents, &octet_string_contents,
CBS_ASN1_OCTETSTRING)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info,
- PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
@@ -787,22 +819,24 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth,
X509_SIG *encrypted = NULL;
if (*ctx->out_key) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info,
- PKCS8_R_MULTIPLE_PRIVATE_KEYS_IN_PKCS12);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_MULTIPLE_PRIVATE_KEYS_IN_PKCS12);
+ 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, PKCS12_handle_content_info,
- PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
if (inp != CBS_data(&wrapped_contents) + CBS_len(&wrapped_contents)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info,
- PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
X509_SIG_free(encrypted);
goto err;
}
@@ -828,22 +862,23 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth,
!CBS_get_asn1(&cert_bag, &wrapped_cert,
CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
!CBS_get_asn1(&wrapped_cert, &cert, CBS_ASN1_OCTETSTRING)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info,
- PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
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, PKCS12_handle_content_info,
- PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
if (inp != CBS_data(&cert) + CBS_len(&cert)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info,
- PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
X509_free(x509);
goto err;
}
@@ -875,6 +910,7 @@ int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs,
/* The input may be in BER format. */
if (!CBS_asn1_ber_to_der(ber_in, &der_bytes, &der_len)) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
return 0;
}
if (der_bytes != NULL) {
@@ -891,28 +927,27 @@ int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs,
if (!CBS_get_asn1(&in, &pfx, CBS_ASN1_SEQUENCE) ||
CBS_len(&in) != 0 ||
!CBS_get_asn1_uint64(&pfx, &version)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_get_key_and_certs, PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
if (version < 3) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_get_key_and_certs,
- PKCS8_R_BAD_PKCS12_VERSION);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_VERSION);
goto err;
}
if (!CBS_get_asn1(&pfx, &authsafe, CBS_ASN1_SEQUENCE)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_get_key_and_certs, PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
if (CBS_len(&pfx) == 0) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_get_key_and_certs, PKCS8_R_MISSING_MAC);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_MISSING_MAC);
goto err;
}
if (!CBS_get_asn1(&pfx, &mac_data, CBS_ASN1_SEQUENCE)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_get_key_and_certs, PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
@@ -921,7 +956,7 @@ int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs,
if (!CBS_get_asn1(&authsafe, &content_type, CBS_ASN1_OBJECT) ||
!CBS_get_asn1(&authsafe, &wrapped_authsafes,
CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_get_key_and_certs, PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
@@ -929,13 +964,12 @@ int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs,
* latter indicates that it's signed by a public key, which isn't
* supported. */
if (OBJ_cbs2nid(&content_type) != NID_pkcs7_data) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_get_key_and_certs,
- PKCS8_R_PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED);
goto err;
}
if (!CBS_get_asn1(&wrapped_authsafes, &authsafes, CBS_ASN1_OCTETSTRING)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_get_key_and_certs, PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
@@ -943,7 +977,7 @@ int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs,
ctx.out_certs = out_certs;
if (!ascii_to_ucs2(password, strlen(password), &ctx.password,
&ctx.password_len)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_get_key_and_certs, PKCS8_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR);
goto err;
}
@@ -962,7 +996,7 @@ int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs,
!CBS_get_asn1(&hash_type_seq, &hash_oid, CBS_ASN1_OBJECT) ||
!CBS_get_asn1(&mac, &expected_mac, CBS_ASN1_OCTETSTRING) ||
!CBS_get_asn1(&mac_data, &salt, CBS_ASN1_OCTETSTRING)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_get_key_and_certs, PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
@@ -971,8 +1005,7 @@ int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs,
if (CBS_len(&mac_data) > 0) {
if (!CBS_get_asn1_uint64(&mac_data, &iterations) ||
iterations > INT_MAX) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_get_key_and_certs,
- PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
}
@@ -980,7 +1013,7 @@ int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs,
hash_nid = OBJ_cbs2nid(&hash_oid);
if (hash_nid == NID_undef ||
(md = EVP_get_digestbynid(hash_nid)) == NULL) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_get_key_and_certs, PKCS8_R_UNKNOWN_HASH);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNKNOWN_HASH);
goto err;
}
@@ -996,8 +1029,7 @@ int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs,
}
if (!CBS_mem_equal(&expected_mac, hmac, hmac_len)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_get_key_and_certs,
- PKCS8_R_INCORRECT_PASSWORD);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_INCORRECT_PASSWORD);
goto err;
}
}
@@ -1126,6 +1158,7 @@ int PKCS12_parse(const PKCS12 *p12, const char *password, EVP_PKEY **out_pkey,
if (!ca_certs) {
ca_certs = sk_X509_new_null();
if (ca_certs == NULL) {
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
return 0;
}
ca_certs_alloced = 1;
@@ -1153,6 +1186,31 @@ int PKCS12_parse(const PKCS12 *p12, const char *password, EVP_PKEY **out_pkey,
return 1;
}
+int PKCS12_verify_mac(const PKCS12 *p12, const char *password,
+ int password_len) {
+ if (password == NULL) {
+ if (password_len != 0) {
+ return 0;
+ }
+ } else if (password_len != -1 &&
+ (password[password_len] != 0 ||
+ memchr(password, 0, password_len) != NULL)) {
+ return 0;
+ }
+
+ EVP_PKEY *pkey = NULL;
+ X509 *cert = NULL;
+ if (!PKCS12_parse(p12, password, &pkey, &cert, NULL)) {
+ ERR_clear_error();
+ return 0;
+ }
+
+ EVP_PKEY_free(pkey);
+ X509_free(cert);
+
+ return 1;
+}
+
void PKCS12_free(PKCS12 *p12) {
OPENSSL_free(p12->ber_bytes);
OPENSSL_free(p12);
diff --git a/src/crypto/pkcs8/pkcs8_test.cc b/src/crypto/pkcs8/pkcs8_test.cc
new file mode 100644
index 0000000..7a88ddf
--- /dev/null
+++ b/src/crypto/pkcs8/pkcs8_test.cc
@@ -0,0 +1,91 @@
+/* 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/pkcs8.h>
+#include <openssl/x509.h>
+
+#include "../test/scoped_types.h"
+
+
+/* kDER is a PKCS#8 encrypted private key. It was generated with:
+ *
+ * openssl genrsa 512 > test.key
+ * openssl pkcs8 -topk8 -in test.key -out test.key.encrypted -v2 des3 -outform der
+ * hexdump -Cv test.key.encrypted
+ *
+ * The password is "testing".
+ */
+static const uint8_t kDER[] = {
+ 0x30, 0x82, 0x01, 0x9e, 0x30, 0x40, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05,
+ 0x0d, 0x30, 0x33, 0x30, 0x1b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c,
+ 0x30, 0x0e, 0x04, 0x08, 0x06, 0xa5, 0x4b, 0x0c, 0x0c, 0x50, 0x8c, 0x19, 0x02, 0x02, 0x08, 0x00,
+ 0x30, 0x14, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x07, 0x04, 0x08, 0x3a, 0xd0,
+ 0x70, 0x4b, 0x26, 0x50, 0x13, 0x7b, 0x04, 0x82, 0x01, 0x58, 0xa6, 0xee, 0x02, 0xf2, 0xf2, 0x7c,
+ 0x19, 0x91, 0xe3, 0xce, 0x32, 0x85, 0xc5, 0x01, 0xd9, 0xe3, 0x5e, 0x14, 0xb6, 0xb8, 0x78, 0xad,
+ 0xda, 0x01, 0xec, 0x9e, 0x42, 0xe8, 0xbf, 0x0b, 0x46, 0x03, 0xbc, 0x92, 0x6f, 0xe4, 0x0f, 0x0f,
+ 0x48, 0x30, 0x10, 0x10, 0x9b, 0xfb, 0x4b, 0xb9, 0x45, 0xf8, 0xcf, 0xab, 0xa1, 0x18, 0xdd, 0x19,
+ 0xa4, 0xa4, 0xe1, 0xf0, 0xa1, 0x8d, 0xc2, 0x23, 0xe7, 0x0d, 0x7a, 0x64, 0x21, 0x6b, 0xfa, 0x48,
+ 0xb9, 0x41, 0xc1, 0x0c, 0x4b, 0xce, 0x6f, 0x1a, 0x91, 0x9b, 0x9f, 0xdd, 0xcf, 0xa9, 0x8d, 0x33,
+ 0x2c, 0x45, 0x81, 0x5c, 0x5e, 0x67, 0xc6, 0x68, 0x43, 0x62, 0xff, 0x5e, 0x9b, 0x1a, 0x15, 0x3a,
+ 0x9d, 0x71, 0x3f, 0xbe, 0x32, 0x2f, 0xe5, 0x90, 0x65, 0x65, 0x9c, 0x22, 0xf6, 0x29, 0x2e, 0xcf,
+ 0x26, 0x16, 0x7b, 0x66, 0x48, 0x55, 0xad, 0x9a, 0x8d, 0x89, 0xf4, 0x48, 0x4f, 0x1f, 0x9d, 0xb8,
+ 0xfa, 0xe1, 0xf1, 0x3b, 0x39, 0x5c, 0x72, 0xc6, 0xb8, 0x3e, 0x98, 0xe8, 0x77, 0xe8, 0xb6, 0x71,
+ 0x84, 0xa8, 0x6e, 0xca, 0xaf, 0x62, 0x96, 0x49, 0x8a, 0x21, 0x6f, 0x9e, 0x78, 0x07, 0x97, 0x38,
+ 0x40, 0x66, 0x42, 0x5a, 0x1b, 0xe0, 0x9b, 0xe9, 0x91, 0x82, 0xe4, 0xea, 0x8f, 0x2a, 0xb2, 0x80,
+ 0xce, 0xe8, 0x57, 0xd3, 0xac, 0x11, 0x9d, 0xb2, 0x39, 0x0f, 0xe1, 0xce, 0x18, 0x96, 0x38, 0xa1,
+ 0x19, 0x80, 0x88, 0x81, 0x3d, 0xda, 0xaa, 0x8e, 0x15, 0x27, 0x19, 0x73, 0x0c, 0xf3, 0xaf, 0x45,
+ 0xe9, 0x1b, 0xad, 0x6c, 0x3d, 0xbf, 0x95, 0xf7, 0xa0, 0x87, 0x0e, 0xde, 0xf1, 0xd8, 0xee, 0xaa,
+ 0x92, 0x76, 0x8d, 0x32, 0x45, 0xa1, 0xe7, 0xf5, 0x05, 0xd6, 0x2c, 0x67, 0x63, 0x10, 0xfa, 0xde,
+ 0x80, 0xc7, 0x5b, 0x96, 0x0f, 0x24, 0x50, 0x78, 0x30, 0xe5, 0x89, 0xf3, 0x73, 0xfa, 0x40, 0x11,
+ 0xd5, 0x26, 0xb8, 0x36, 0x96, 0x98, 0xe6, 0xbd, 0x73, 0x62, 0x56, 0xb9, 0xea, 0x28, 0x16, 0x93,
+ 0x5b, 0x33, 0xae, 0x83, 0xf9, 0x1f, 0xee, 0xef, 0xc8, 0xbf, 0xc7, 0xb1, 0x47, 0x43, 0xa1, 0xc6,
+ 0x1a, 0x64, 0x47, 0x02, 0x40, 0x3e, 0xbc, 0x0f, 0x80, 0x71, 0x5c, 0x44, 0x60, 0xbc, 0x78, 0x2e,
+ 0xd2, 0x77, 0xf8, 0x6e, 0x12, 0x51, 0x89, 0xdb, 0x90, 0x64, 0xcd, 0x76, 0x10, 0x29, 0x73, 0xc2,
+ 0x2f, 0x94, 0x7b, 0x98, 0xcd, 0xbb, 0x61, 0x16, 0x1d, 0x52, 0x11, 0x73, 0x48, 0xe6, 0x39, 0xfc,
+ 0xd6, 0x2d,
+};
+
+static bool test(const uint8_t *der, size_t der_len) {
+ const uint8_t *data = der;
+ ScopedX509_SIG sig(d2i_X509_SIG(NULL, &data, der_len));
+ if (sig.get() == NULL || data != der + der_len) {
+ fprintf(stderr, "d2i_X509_SIG failed or did not consume all bytes.\n");
+ return false;
+ }
+
+ static const char kPassword[] = "testing";
+ ScopedPKCS8_PRIV_KEY_INFO keypair(PKCS8_decrypt(sig.get(), kPassword, -1));
+ if (!keypair) {
+ fprintf(stderr, "PKCS8_decrypt failed.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ return true;
+}
+
+int main(int argc, char **argv) {
+ if (!test(kDER, sizeof(kDER))) {
+ return 1;
+ }
+
+ printf("PASS\n");
+ return 0;
+}
diff --git a/src/crypto/poly1305/CMakeLists.txt b/src/crypto/poly1305/CMakeLists.txt
index bb0c1e4..1b6a804 100644
--- a/src/crypto/poly1305/CMakeLists.txt
+++ b/src/crypto/poly1305/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
if (${ARCH} STREQUAL "arm")
set(
@@ -19,3 +19,13 @@ add_library(
${POLY1305_ARCH_SOURCES}
)
+
+add_executable(
+ poly1305_test
+
+ poly1305_test.cc
+ $<TARGET_OBJECTS:test_support>
+)
+
+target_link_libraries(poly1305_test crypto)
+add_dependencies(all_tests poly1305_test)
diff --git a/src/crypto/poly1305/poly1305_arm.c b/src/crypto/poly1305/poly1305_arm.c
index c06eded..5e78dc0 100644
--- a/src/crypto/poly1305/poly1305_arm.c
+++ b/src/crypto/poly1305/poly1305_arm.c
@@ -132,7 +132,7 @@ static uint32_t load32(uint8_t *t) {
static void fe1305x2_frombytearray(fe1305x2 *r, const uint8_t *x,
unsigned long long xlen) {
- int i;
+ unsigned i;
uint8_t t[17];
for (i = 0; (i < 16) && (i < xlen); i++) {
diff --git a/src/crypto/poly1305/poly1305_test.cc b/src/crypto/poly1305/poly1305_test.cc
new file mode 100644
index 0000000..3a72668
--- /dev/null
+++ b/src/crypto/poly1305/poly1305_test.cc
@@ -0,0 +1,80 @@
+/* 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 <stdio.h>
+#include <string.h>
+
+#include <vector>
+
+#include <openssl/crypto.h>
+#include <openssl/poly1305.h>
+
+#include "../test/file_test.h"
+
+
+// |CRYPTO_poly1305_finish| requires a 16-byte-aligned output.
+#if defined(OPENSSL_WINDOWS)
+// MSVC doesn't support C++11 |alignas|.
+#define ALIGNED __declspec(align(16))
+#else
+#define ALIGNED alignas(16)
+#endif
+
+static bool TestPoly1305(FileTest *t, void *arg) {
+ std::vector<uint8_t> key, in, mac;
+ if (!t->GetBytes(&key, "Key") ||
+ !t->GetBytes(&in, "Input") ||
+ !t->GetBytes(&mac, "MAC")) {
+ return false;
+ }
+ if (key.size() != 32 || mac.size() != 16) {
+ t->PrintLine("Invalid test");
+ return false;
+ }
+
+ // Test single-shot operation.
+ poly1305_state state;
+ 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, mac.data(), mac.size())) {
+ t->PrintLine("Single-shot Poly1305 failed.");
+ return false;
+ }
+
+ // Test streaming byte-by-byte.
+ 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, mac.data(), mac.size())) {
+ t->PrintLine("Streaming Poly1305 failed.");
+ return false;
+ }
+
+ return true;
+}
+
+int main(int argc, char **argv) {
+ CRYPTO_library_init();
+
+ if (argc != 2) {
+ fprintf(stderr, "%s <test file>\n", argv[0]);
+ return 1;
+ }
+
+ return FileTestMain(TestPoly1305, nullptr, argv[1]);
+}
diff --git a/src/crypto/poly1305/poly1305_test.txt b/src/crypto/poly1305/poly1305_test.txt
new file mode 100644
index 0000000..ad40699
--- /dev/null
+++ b/src/crypto/poly1305/poly1305_test.txt
@@ -0,0 +1,52 @@
+# RFC 7539, section 2.5.2.
+
+Key = 85d6be7857556d337f4452fe42d506a80103808afb0db2fd4abff6af4149f51b
+Input = "Cryptographic Forum Research Group"
+MAC = a8061dc1305136c6c22b8baf0c0127a9
+
+
+# RFC 7539, section A.3.
+
+Key = 0000000000000000000000000000000000000000000000000000000000000000
+Input = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+MAC = 00000000000000000000000000000000
+
+Key = 0000000000000000000000000000000036e5f6b5c5e06070f0efca96227a863e
+Input = 416e79207375626d697373696f6e20746f20746865204945544620696e74656e6465642062792074686520436f6e7472696275746f7220666f72207075626c69636174696f6e20617320616c6c206f722070617274206f6620616e204945544620496e7465726e65742d4472616674206f722052464320616e6420616e792073746174656d656e74206d6164652077697468696e2074686520636f6e74657874206f6620616e204945544620616374697669747920697320636f6e7369646572656420616e20224945544620436f6e747269627574696f6e222e20537563682073746174656d656e747320696e636c756465206f72616c2073746174656d656e747320696e20494554462073657373696f6e732c2061732077656c6c206173207772697474656e20616e6420656c656374726f6e696320636f6d6d756e69636174696f6e73206d61646520617420616e792074696d65206f7220706c6163652c207768696368206172652061646472657373656420746f
+MAC = 36e5f6b5c5e06070f0efca96227a863e
+
+Key = 36e5f6b5c5e06070f0efca96227a863e00000000000000000000000000000000
+Input = 416e79207375626d697373696f6e20746f20746865204945544620696e74656e6465642062792074686520436f6e7472696275746f7220666f72207075626c69636174696f6e20617320616c6c206f722070617274206f6620616e204945544620496e7465726e65742d4472616674206f722052464320616e6420616e792073746174656d656e74206d6164652077697468696e2074686520636f6e74657874206f6620616e204945544620616374697669747920697320636f6e7369646572656420616e20224945544620436f6e747269627574696f6e222e20537563682073746174656d656e747320696e636c756465206f72616c2073746174656d656e747320696e20494554462073657373696f6e732c2061732077656c6c206173207772697474656e20616e6420656c656374726f6e696320636f6d6d756e69636174696f6e73206d61646520617420616e792074696d65206f7220706c6163652c207768696368206172652061646472657373656420746f
+MAC = f3477e7cd95417af89a6b8794c310cf0
+
+Key = 1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0
+Input = 2754776173206272696c6c69672c20616e642074686520736c6974687920746f7665730a446964206779726520616e642067696d626c6520696e2074686520776162653a0a416c6c206d696d737920776572652074686520626f726f676f7665732c0a416e6420746865206d6f6d65207261746873206f757467726162652e
+MAC = 4541669a7eaaee61e708dc7cbcc5eb62
+
+Key = 0200000000000000000000000000000000000000000000000000000000000000
+Input = ffffffffffffffffffffffffffffffff
+MAC = 03000000000000000000000000000000
+
+Key = 02000000000000000000000000000000ffffffffffffffffffffffffffffffff
+Input = 02000000000000000000000000000000
+MAC = 03000000000000000000000000000000
+
+Key = 0100000000000000000000000000000000000000000000000000000000000000
+Input = fffffffffffffffffffffffffffffffff0ffffffffffffffffffffffffffffff11000000000000000000000000000000
+MAC = 05000000000000000000000000000000
+
+Key = 0100000000000000000000000000000000000000000000000000000000000000
+Input = fffffffffffffffffffffffffffffffffbfefefefefefefefefefefefefefefe01010101010101010101010101010101
+MAC = 00000000000000000000000000000000
+
+Key = 0200000000000000000000000000000000000000000000000000000000000000
+Input = fdffffffffffffffffffffffffffffff
+MAC = faffffffffffffffffffffffffffffff
+
+Key = 0100000000000000040000000000000000000000000000000000000000000000
+Input = e33594d7505e43b900000000000000003394d7505e4379cd01000000000000000000000000000000000000000000000001000000000000000000000000000000
+MAC = 14000000000000005500000000000000
+
+Key = 0100000000000000040000000000000000000000000000000000000000000000
+Input = e33594d7505e43b900000000000000003394d7505e4379cd010000000000000000000000000000000000000000000000
+MAC = 13000000000000000000000000000000
diff --git a/src/crypto/rand/CMakeLists.txt b/src/crypto/rand/CMakeLists.txt
index 374d8f1..eedf81b 100644
--- a/src/crypto/rand/CMakeLists.txt
+++ b/src/crypto/rand/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
if (${ARCH} STREQUAL "x86_64")
set(
@@ -16,7 +16,6 @@ add_library(
rand.c
urandom.c
windows.c
- hwrand.c
${RAND_ARCH_SOURCES}
)
diff --git a/src/crypto/rand/asm/rdrand-x86_64.pl b/src/crypto/rand/asm/rdrand-x86_64.pl
index a917611..c32a55c 100644
--- a/src/crypto/rand/asm/rdrand-x86_64.pl
+++ b/src/crypto/rand/asm/rdrand-x86_64.pl
@@ -1,5 +1,19 @@
#!/usr/bin/env perl
+# 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. */
+
$flavour = shift;
$output = shift;
if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
@@ -14,11 +28,47 @@ open OUT,"| \"$^X\" $xlate $flavour $output";
print<<___;
.text
+# CRYPTO_rdrand writes eight bytes of random data from the hardware RNG to
+# |out|. It returns one on success or zero on hardware failure.
+# int CRYPTO_rdrand(uint8_t out[8]);
.globl CRYPTO_rdrand
.type CRYPTO_rdrand,\@function,1
.align 16
CRYPTO_rdrand:
- .byte 0x48, 0x0f, 0xc7, 0xf0
+ xorq %rax, %rax
+ # This is rdrand %rcx. It sets rcx to a random value and sets the carry
+ # flag on success.
+ .byte 0x48, 0x0f, 0xc7, 0xf1
+ # An add-with-carry of zero effectively sets %rax to the carry flag.
+ adcq %rax, %rax
+ movq %rcx, 0(%rdi)
+ retq
+
+# CRYPTO_rdrand_multiple8_buf fills |len| bytes at |buf| with random data from
+# the hardware RNG. The |len| argument must be a multiple of eight. It returns
+# one on success and zero on hardware failure.
+# int CRYPTO_rdrand_multiple8_buf(uint8_t *buf, size_t len);
+.globl CRYPTO_rdrand_multiple8_buf
+.type CRYPTO_rdrand_multiple8_buf,\@function,2
+.align 16
+CRYPTO_rdrand_multiple8_buf:
+ test %rsi, %rsi
+ jz .Lout
+ movq \$8, %rdx
+.Lloop:
+ # This is rdrand %rcx. It sets rcx to a random value and sets the carry
+ # flag on success.
+ .byte 0x48, 0x0f, 0xc7, 0xf1
+ jnc .Lerr
+ movq %rcx, 0(%rdi)
+ addq %rdx, %rdi
+ subq %rdx, %rsi
+ jnz .Lloop
+.Lout:
+ movq \$1, %rax
+ retq
+.Lerr:
+ xorq %rax, %rax
retq
___
diff --git a/src/crypto/rand/internal.h b/src/crypto/rand/internal.h
index 1cca7f3..dcff3aa 100644
--- a/src/crypto/rand/internal.h
+++ b/src/crypto/rand/internal.h
@@ -24,14 +24,6 @@ extern "C" {
* system. */
void CRYPTO_sysrand(uint8_t *buf, size_t len);
-/* CRYPTO_have_hwrand returns one iff |CRYPTO_hwrand| can be called to generate
- * hardware entropy. */
-int CRYPTO_have_hwrand(void);
-
-/* CRYPTO_hwrand fills |len| bytes at |buf| with entropy from the hardware.
- * This function can only be called if |CRYPTO_have_hwrand| returns one. */
-void CRYPTO_hwrand(uint8_t *buf, size_t len);
-
#if defined(__cplusplus)
} /* extern C */
diff --git a/src/crypto/rand/rand.c b/src/crypto/rand/rand.c
index a647b6a..892b4ba 100644
--- a/src/crypto/rand/rand.c
+++ b/src/crypto/rand/rand.c
@@ -14,9 +14,12 @@
#include <openssl/rand.h>
+#include <assert.h>
#include <limits.h>
#include <string.h>
+#include <openssl/chacha.h>
+#include <openssl/cpu.h>
#include <openssl/mem.h>
#include "internal.h"
@@ -69,16 +72,54 @@ static void rand_thread_state_free(void *state) {
OPENSSL_free(state);
}
-extern void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len,
- const uint8_t key[32], const uint8_t nonce[8],
- size_t counter);
+#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM)
+
+/* These functions are defined in asm/rdrand-x86_64.pl */
+extern int CRYPTO_rdrand(uint8_t out[8]);
+extern int CRYPTO_rdrand_multiple8_buf(uint8_t *buf, size_t len);
+
+static int have_rdrand(void) {
+ return (OPENSSL_ia32cap_P[1] & (1u << 30)) != 0;
+}
+
+static int hwrand(uint8_t *buf, size_t len) {
+ if (!have_rdrand()) {
+ return 0;
+ }
+
+ const size_t len_multiple8 = len & ~7;
+ if (!CRYPTO_rdrand_multiple8_buf(buf, len_multiple8)) {
+ return 0;
+ }
+ len -= len_multiple8;
+
+ if (len != 0) {
+ assert(len < 8);
+
+ uint8_t rand_buf[8];
+ if (!CRYPTO_rdrand(rand_buf)) {
+ return 0;
+ }
+ memcpy(buf + len_multiple8, rand_buf, len);
+ }
+
+ return 1;
+}
+
+#else
+
+static int hwrand(uint8_t *buf, size_t len) {
+ return 0;
+}
+
+#endif
int RAND_bytes(uint8_t *buf, size_t len) {
if (len == 0) {
return 1;
}
- if (!CRYPTO_have_hwrand()) {
+ if (!hwrand(buf, len)) {
/* Without a hardware RNG to save us from address-space duplication, the OS
* entropy is used directly. */
CRYPTO_sysrand(buf, len);
@@ -108,29 +149,31 @@ int RAND_bytes(uint8_t *buf, size_t len) {
state->partial_block_used = sizeof(state->partial_block);
}
- CRYPTO_hwrand(buf, len);
-
if (len >= sizeof(state->partial_block)) {
size_t remaining = len;
while (remaining > 0) {
- // kMaxBytesPerCall is only 2GB, while ChaCha can handle 256GB. But this
- // is sufficient and easier on 32-bit.
+ /* kMaxBytesPerCall is only 2GB, while ChaCha can handle 256GB. But this
+ * is sufficient and easier on 32-bit. */
static const size_t kMaxBytesPerCall = 0x80000000;
size_t todo = remaining;
if (todo > kMaxBytesPerCall) {
todo = kMaxBytesPerCall;
}
- CRYPTO_chacha_20(buf, buf, todo, state->key,
- (uint8_t *)&state->calls_used, 0);
+ uint8_t nonce[12];
+ memset(nonce, 0, 4);
+ memcpy(nonce + 4, &state->calls_used, sizeof(state->calls_used));
+ CRYPTO_chacha_20(buf, buf, todo, state->key, nonce, 0);
buf += todo;
remaining -= todo;
state->calls_used++;
}
} else {
if (sizeof(state->partial_block) - state->partial_block_used < len) {
+ uint8_t nonce[12];
+ memset(nonce, 0, 4);
+ memcpy(nonce + 4, &state->calls_used, sizeof(state->calls_used));
CRYPTO_chacha_20(state->partial_block, state->partial_block,
- sizeof(state->partial_block), state->key,
- (uint8_t *)&state->calls_used, 0);
+ sizeof(state->partial_block), state->key, nonce, 0);
state->partial_block_used = 0;
}
@@ -149,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" */
@@ -163,6 +211,10 @@ int RAND_load_file(const char *path, long num) {
void RAND_add(const void *buf, int num, double entropy) {}
+int RAND_egd(const char *path) {
+ return 255;
+}
+
int RAND_poll(void) {
return 1;
}
@@ -170,3 +222,18 @@ int RAND_poll(void) {
int RAND_status(void) {
return 1;
}
+
+static const struct rand_meth_st kSSLeayMethod = {
+ RAND_seed,
+ RAND_bytes,
+ RAND_cleanup,
+ RAND_add,
+ RAND_pseudo_bytes,
+ RAND_status,
+};
+
+RAND_METHOD *RAND_SSLeay(void) {
+ return (RAND_METHOD*) &kSSLeayMethod;
+}
+
+void RAND_set_rand_method(const RAND_METHOD *method) {}
diff --git a/src/crypto/rand/urandom.c b/src/crypto/rand/urandom.c
index 788a979..5bf5c73 100644
--- a/src/crypto/rand/urandom.c
+++ b/src/crypto/rand/urandom.c
@@ -30,92 +30,130 @@
/* This file implements a PRNG by reading from /dev/urandom, optionally with a
- * fork-safe buffer.
- *
- * If buffering is enabled then it maintains a global, linked list of buffers.
- * Threads which need random bytes grab a buffer from the list under a lock and
- * copy out the bytes that they need. In the rare case that the buffer is
- * empty, it's refilled from /dev/urandom outside of the lock.
- *
- * Large requests are always serviced from /dev/urandom directly.
- *
- * Each buffer contains the PID of the process that created it and it's tested
- * against the current PID each time. Thus processes that fork will discard all
- * the buffers filled by the parent process. There are two problems with this:
- *
- * 1) glibc maintains a cache of the current PID+PPID and, if this cache isn't
- * correctly invalidated, the getpid() will continue to believe that
- * it's the old process. Glibc depends on the glibc wrappers for fork,
- * vfork and clone being used in order to invalidate the getpid() cache.
- *
- * 2) If a process forks, dies and then its child forks, it's possible that
- * the third process will end up with the same PID as the original process.
- * If the second process never used any random values then this will mean
- * that the third process has stale, cached values and won't notice.
- */
-
-/* BUF_SIZE is intended to be a 4K allocation with malloc overhead. struct
- * rand_buffer also fits in this space and the remainder is entropy. */
-#define BUF_SIZE (4096 - 16)
-
-/* rand_buffer contains unused, random bytes. These structures form a linked
- * list via the |next| pointer, which is NULL in the final element. */
+ * buffer, which is unsafe across |fork|. */
+
+#define BUF_SIZE 4096
+
+/* rand_buffer contains unused, random bytes, some of which may have been
+ * consumed already. */
struct rand_buffer {
- size_t used; /* used contains the number of bytes of |rand| that have
- been consumed. */
- struct rand_buffer *next;
- pid_t pid; /* pid contains the pid at the time that the buffer was
- created so that data is not duplicated after a fork. */
- pid_t ppid; /* ppid contains the parent pid in order to try and reduce
- the possibility of duplicated PID confusing the
- detection of a fork. */
- uint8_t rand[];
+ size_t used;
+ uint8_t rand[BUF_SIZE];
};
-/* rand_bytes_per_buf is the number of actual entropy bytes in a buffer. */
-static const size_t rand_bytes_per_buf = BUF_SIZE - sizeof(struct rand_buffer);
-
-static struct CRYPTO_STATIC_MUTEX global_lock = CRYPTO_STATIC_MUTEX_INIT;
+/* requested_lock is used to protect the |*_requested| variables. */
+static struct CRYPTO_STATIC_MUTEX requested_lock = CRYPTO_STATIC_MUTEX_INIT;
-/* list_head is the start of a global, linked-list of rand_buffer objects. It's
- * protected by |global_lock|. */
-static struct rand_buffer *list_head;
+/* urandom_fd_requested is set by |RAND_set_urandom_fd|. It's protected by
+ * |requested_lock|. */
+static int urandom_fd_requested = -2;
-/* urandom_fd is a file descriptor to /dev/urandom. It's protected by
- * |global_lock|. */
+/* urandom_fd is a file descriptor to /dev/urandom. It's protected by |once|. */
static int urandom_fd = -2;
+/* urandom_buffering_requested is set by |RAND_enable_fork_unsafe_buffering|.
+ * It's protected by |requested_lock|. */
+static int urandom_buffering_requested = 0;
+
/* urandom_buffering controls whether buffering is enabled (1) or not (0). This
- * is protected by |global_lock|. */
+ * is protected by |once|. */
static int urandom_buffering = 0;
-/* urandom_get_fd_locked returns a file descriptor to /dev/urandom. The caller
- * of this function must hold |global_lock|. */
-static int urandom_get_fd_locked(void) {
- if (urandom_fd != -2) {
- return urandom_fd;
+static CRYPTO_once_t once = CRYPTO_ONCE_INIT;
+
+/* init_once initializes the state of this module to values previously
+ * requested. This is the only function that modifies |urandom_fd| and
+ * |urandom_buffering|, whose values may be read safely after calling the
+ * once. */
+static void init_once(void) {
+ CRYPTO_STATIC_MUTEX_lock_read(&requested_lock);
+ urandom_buffering = urandom_buffering_requested;
+ int fd = urandom_fd_requested;
+ CRYPTO_STATIC_MUTEX_unlock(&requested_lock);
+
+ if (fd == -2) {
+ do {
+ fd = open("/dev/urandom", O_RDONLY);
+ } while (fd == -1 && errno == EINTR);
+ }
+
+ if (fd < 0) {
+ abort();
+ }
+
+ int flags = fcntl(fd, F_GETFD);
+ if (flags == -1) {
+ /* 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;
+}
+
+void RAND_cleanup(void) {}
+
+void RAND_set_urandom_fd(int fd) {
+ fd = dup(fd);
+ if (fd < 0) {
+ abort();
}
- urandom_fd = open("/dev/urandom", O_RDONLY);
- return urandom_fd;
+ CRYPTO_STATIC_MUTEX_lock_write(&requested_lock);
+ urandom_fd_requested = fd;
+ CRYPTO_STATIC_MUTEX_unlock(&requested_lock);
+
+ CRYPTO_once(&once, init_once);
+ if (urandom_fd != fd) {
+ abort(); // Already initialized.
+ }
+}
+
+void RAND_enable_fork_unsafe_buffering(int fd) {
+ if (fd >= 0) {
+ fd = dup(fd);
+ if (fd < 0) {
+ abort();
+ }
+ } else {
+ fd = -2;
+ }
+
+ CRYPTO_STATIC_MUTEX_lock_write(&requested_lock);
+ urandom_buffering_requested = 1;
+ urandom_fd_requested = fd;
+ CRYPTO_STATIC_MUTEX_unlock(&requested_lock);
+
+ CRYPTO_once(&once, init_once);
+ if (urandom_buffering != 1 || (fd >= 0 && urandom_fd != fd)) {
+ abort(); // Already initialized.
+ }
}
-/* RAND_cleanup frees all buffers, closes any cached file descriptor
- * and resets the global state. */
-void RAND_cleanup(void) {
- struct rand_buffer *cur;
+static struct rand_buffer *get_thread_local_buffer(void) {
+ struct rand_buffer *buf =
+ CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_URANDOM_BUF);
+ if (buf != NULL) {
+ return buf;
+ }
- CRYPTO_STATIC_MUTEX_lock_write(&global_lock);
- while ((cur = list_head)) {
- list_head = cur->next;
- OPENSSL_free(cur);
+ buf = OPENSSL_malloc(sizeof(struct rand_buffer));
+ if (buf == NULL) {
+ return NULL;
}
- if (urandom_fd >= 0) {
- close(urandom_fd);
+ buf->used = BUF_SIZE; /* To trigger a |read_full| on first use. */
+ if (!CRYPTO_set_thread_local(OPENSSL_THREAD_LOCAL_URANDOM_BUF, buf,
+ OPENSSL_free)) {
+ OPENSSL_free(buf);
+ return NULL;
}
- urandom_fd = -2;
- list_head = NULL;
- CRYPTO_STATIC_MUTEX_unlock(&global_lock);
+
+ return buf;
}
/* read_full reads exactly |len| bytes from |fd| into |out| and returns 1. In
@@ -138,110 +176,48 @@ static char read_full(int fd, uint8_t *out, size_t len) {
return 1;
}
-/* CRYPTO_sysrand puts |num| random bytes into |out|. */
-void CRYPTO_sysrand(uint8_t *out, size_t requested) {
- int fd;
- struct rand_buffer *buf;
- size_t todo;
- pid_t pid, ppid;
-
- if (requested == 0) {
- return;
- }
+/* read_from_buffer reads |requested| random bytes from the buffer into |out|,
+ * refilling it if necessary to satisfy the request. */
+static void read_from_buffer(struct rand_buffer *buf,
+ uint8_t *out, size_t requested) {
+ size_t remaining = BUF_SIZE - buf->used;
- CRYPTO_STATIC_MUTEX_lock_write(&global_lock);
- fd = urandom_get_fd_locked();
+ while (requested > remaining) {
+ memcpy(out, &buf->rand[buf->used], remaining);
+ buf->used += remaining;
+ out += remaining;
+ requested -= remaining;
- if (fd < 0) {
- CRYPTO_STATIC_MUTEX_unlock(&global_lock);
- abort();
- return;
- }
-
- /* If buffering is not enabled, or if the request is large, then the
- * result comes directly from urandom. */
- if (!urandom_buffering || requested > BUF_SIZE / 2) {
- CRYPTO_STATIC_MUTEX_unlock(&global_lock);
- if (!read_full(fd, out, requested)) {
+ if (!read_full(urandom_fd, buf->rand, BUF_SIZE)) {
abort();
- }
- return;
- }
-
- pid = getpid();
- ppid = getppid();
-
- for (;;) {
- buf = list_head;
- if (buf && buf->pid == pid && buf->ppid == ppid &&
- rand_bytes_per_buf - buf->used >= requested) {
- memcpy(out, &buf->rand[buf->used], requested);
- buf->used += requested;
- CRYPTO_STATIC_MUTEX_unlock(&global_lock);
return;
}
-
- /* If we don't immediately have enough entropy with the correct
- * PID, remove the buffer from the list in order to gain
- * exclusive access and unlock. */
- if (buf) {
- list_head = buf->next;
- }
- CRYPTO_STATIC_MUTEX_unlock(&global_lock);
-
- if (!buf) {
- buf = (struct rand_buffer *)OPENSSL_malloc(BUF_SIZE);
- if (!buf) {
- abort();
- return;
- }
- /* The buffer doesn't contain any random bytes yet
- * so we mark it as fully used so that it will be
- * filled below. */
- buf->used = rand_bytes_per_buf;
- buf->next = NULL;
- buf->pid = pid;
- buf->ppid = ppid;
- }
-
- if (buf->pid == pid && buf->ppid == ppid) {
- break;
- }
-
- /* We have forked and so cannot use these bytes as they
- * may have been used in another process. */
- OPENSSL_free(buf);
- CRYPTO_STATIC_MUTEX_lock_write(&global_lock);
+ buf->used = 0;
+ remaining = BUF_SIZE;
}
- while (requested > 0) {
- todo = rand_bytes_per_buf - buf->used;
- if (todo > requested) {
- todo = requested;
- }
- memcpy(out, &buf->rand[buf->used], todo);
- requested -= todo;
- out += todo;
- buf->used += todo;
+ memcpy(out, &buf->rand[buf->used], requested);
+ buf->used += requested;
+}
- if (buf->used < rand_bytes_per_buf) {
- break;
- }
+/* CRYPTO_sysrand puts |requested| random bytes into |out|. */
+void CRYPTO_sysrand(uint8_t *out, size_t requested) {
+ if (requested == 0) {
+ return;
+ }
- if (!read_full(fd, buf->rand, rand_bytes_per_buf)) {
- OPENSSL_free(buf);
- abort();
+ CRYPTO_once(&once, init_once);
+ if (urandom_buffering && requested < BUF_SIZE) {
+ struct rand_buffer *buf = get_thread_local_buffer();
+ if (buf != NULL) {
+ read_from_buffer(buf, out, requested);
return;
}
-
- buf->used = 0;
}
- CRYPTO_STATIC_MUTEX_lock_write(&global_lock);
- assert(list_head != buf);
- buf->next = list_head;
- list_head = buf;
- CRYPTO_STATIC_MUTEX_unlock(&global_lock);
+ if (!read_full(urandom_fd, out, requested)) {
+ abort();
+ }
}
#endif /* !OPENSSL_WINDOWS */
diff --git a/src/crypto/rc4/CMakeLists.txt b/src/crypto/rc4/CMakeLists.txt
index fe2d0c6..151773a 100644
--- a/src/crypto/rc4/CMakeLists.txt
+++ b/src/crypto/rc4/CMakeLists.txt
@@ -1,11 +1,10 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
if (${ARCH} STREQUAL "x86_64")
set(
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/rc4/asm/rc4-x86_64.pl b/src/crypto/rc4/asm/rc4-x86_64.pl
index db46242..cef6268 100644
--- a/src/crypto/rc4/asm/rc4-x86_64.pl
+++ b/src/crypto/rc4/asm/rc4-x86_64.pl
@@ -56,7 +56,7 @@
# achieves respectful 432MBps on 2.8GHz processor now. For reference.
# If executed on Xeon, current RC4_CHAR code-path is 2.7x faster than
# RC4_INT code-path. While if executed on Opteron, it's only 25%
-# slower than the RC4_INT one [meaning that if CPU µ-arch detection
+# slower than the RC4_INT one [meaning that if CPU µ-arch detection
# is not implemented, then this final RC4_CHAR code-path should be
# preferred, as it provides better *all-round* performance].
diff --git a/src/crypto/rc4/rc4.c b/src/crypto/rc4/rc4.c
index aa19dc2..b8e1d9f 100644
--- a/src/crypto/rc4/rc4.c
+++ b/src/crypto/rc4/rc4.c
@@ -234,23 +234,22 @@ void RC4(RC4_KEY *key, size_t len, const uint8_t *in, uint8_t *out) {
void RC4_set_key(RC4_KEY *rc4key, unsigned len, const uint8_t *key) {
uint32_t tmp;
- int id1, id2;
+ unsigned i, id1, id2;
uint32_t *d;
- unsigned int i;
d = &rc4key->data[0];
rc4key->x = 0;
rc4key->y = 0;
id1 = id2 = 0;
-#define SK_LOOP(d, n) \
- { \
- tmp = d[(n)]; \
+#define SK_LOOP(d, n) \
+ { \
+ tmp = d[(n)]; \
id2 = (key[id1] + tmp + id2) & 0xff; \
- if (++id1 == len) \
- id1 = 0; \
- d[(n)] = d[id2]; \
- d[id2] = tmp; \
+ if (++id1 == len) \
+ id1 = 0; \
+ d[(n)] = d[id2]; \
+ d[id2] = tmp; \
}
for (i = 0; i < 256; i++) {
diff --git a/src/crypto/rsa/CMakeLists.txt b/src/crypto/rsa/CMakeLists.txt
index 0ea12c8..969b753 100644
--- a/src/crypto/rsa/CMakeLists.txt
+++ b/src/crypto/rsa/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
rsa
@@ -15,9 +15,10 @@ add_library(
add_executable(
rsa_test
- rsa_test.c
+ rsa_test.cc
$<TARGET_OBJECTS:test_support>
)
target_link_libraries(rsa_test crypto)
+add_dependencies(all_tests rsa_test) \ No newline at end of file
diff --git a/src/crypto/rsa/blinding.c b/src/crypto/rsa/blinding.c
index 245142b..d21633f 100644
--- a/src/crypto/rsa/blinding.c
+++ b/src/crypto/rsa/blinding.c
@@ -127,9 +127,11 @@ struct bn_blinding_st {
BIGNUM *mod; /* just a reference */
int counter;
unsigned long flags;
- BN_MONT_CTX *m_ctx;
+ /* mont is the Montgomery context used for this |BN_BLINDING|. It is not
+ * owned and must outlive this structure. */
+ const BN_MONT_CTX *mont;
int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
- const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+ const BIGNUM *m, BN_CTX *ctx, const BN_MONT_CTX *mont);
};
BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod) {
@@ -137,7 +139,7 @@ BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod) {
ret = (BN_BLINDING*) OPENSSL_malloc(sizeof(BN_BLINDING));
if (ret == NULL) {
- OPENSSL_PUT_ERROR(RSA, BN_BLINDING_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
return NULL;
}
memset(ret, 0, sizeof(BN_BLINDING));
@@ -190,7 +192,7 @@ int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx) {
int ret = 0;
if (b->A == NULL || b->Ai == NULL) {
- OPENSSL_PUT_ERROR(RSA, BN_BLINDING_update, RSA_R_BN_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BN_NOT_INITIALIZED);
goto err;
}
@@ -230,7 +232,7 @@ int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx) {
int ret = 1;
if (b->A == NULL || b->Ai == NULL) {
- OPENSSL_PUT_ERROR(RSA, BN_BLINDING_convert_ex, RSA_R_BN_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BN_NOT_INITIALIZED);
return 0;
}
@@ -266,7 +268,7 @@ int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b,
ret = BN_mod_mul(n, n, r, b->mod, ctx);
} else {
if (b->Ai == NULL) {
- OPENSSL_PUT_ERROR(RSA, BN_BLINDING_invert_ex, RSA_R_BN_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BN_NOT_INITIALIZED);
return 0;
}
ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx);
@@ -284,8 +286,8 @@ void BN_BLINDING_set_flags(BN_BLINDING *b, unsigned long flags) {
BN_BLINDING *BN_BLINDING_create_param(
BN_BLINDING *b, const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
- const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
- BN_MONT_CTX *m_ctx) {
+ const BIGNUM *m, BN_CTX *ctx, const BN_MONT_CTX *mont),
+ const BN_MONT_CTX *mont) {
int retry_counter = 32;
BN_BLINDING *ret = NULL;
@@ -317,21 +319,21 @@ BN_BLINDING *BN_BLINDING_create_param(
if (bn_mod_exp != NULL) {
ret->bn_mod_exp = bn_mod_exp;
}
- if (m_ctx != NULL) {
- ret->m_ctx = m_ctx;
+ if (mont != NULL) {
+ ret->mont = mont;
}
do {
if (!BN_rand_range(ret->A, ret->mod)) {
goto err;
}
- if (BN_mod_inverse(ret->Ai, ret->A, ret->mod, ctx) == NULL) {
+
+ int no_inverse;
+ if (BN_mod_inverse_ex(ret->Ai, &no_inverse, ret->A, ret->mod, ctx) == NULL) {
/* this should almost never happen for good RSA keys */
- uint32_t error = ERR_peek_last_error();
- if (ERR_GET_REASON(error) == BN_R_NO_INVERSE) {
+ if (no_inverse) {
if (retry_counter-- == 0) {
- OPENSSL_PUT_ERROR(RSA, BN_BLINDING_create_param,
- RSA_R_TOO_MANY_ITERATIONS);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_MANY_ITERATIONS);
goto err;
}
ERR_clear_error();
@@ -343,8 +345,8 @@ BN_BLINDING *BN_BLINDING_create_param(
}
} while (1);
- if (ret->bn_mod_exp != NULL && ret->m_ctx != NULL) {
- if (!ret->bn_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx, ret->m_ctx)) {
+ if (ret->bn_mod_exp != NULL && ret->mont != NULL) {
+ if (!ret->bn_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx, ret->mont)) {
goto err;
}
} else {
@@ -416,14 +418,14 @@ BN_BLINDING *rsa_setup_blinding(RSA *rsa, BN_CTX *in_ctx) {
BN_CTX_start(ctx);
e = BN_CTX_get(ctx);
if (e == NULL) {
- OPENSSL_PUT_ERROR(RSA, rsa_setup_blinding, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
goto err;
}
if (rsa->e == NULL) {
e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx);
if (e == NULL) {
- OPENSSL_PUT_ERROR(RSA, rsa_setup_blinding, RSA_R_NO_PUBLIC_EXPONENT);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_NO_PUBLIC_EXPONENT);
goto err;
}
} else {
@@ -434,8 +436,7 @@ BN_BLINDING *rsa_setup_blinding(RSA *rsa, BN_CTX *in_ctx) {
BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME);
if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
- mont_ctx =
- BN_MONT_CTX_set_locked(&rsa->_method_mod_n, &rsa->lock, rsa->n, ctx);
+ mont_ctx = BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx);
if (mont_ctx == NULL) {
goto err;
}
@@ -444,7 +445,7 @@ BN_BLINDING *rsa_setup_blinding(RSA *rsa, BN_CTX *in_ctx) {
ret = BN_BLINDING_create_param(NULL, e, n, ctx, rsa->meth->bn_mod_exp,
mont_ctx);
if (ret == NULL) {
- OPENSSL_PUT_ERROR(RSA, rsa_setup_blinding, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
goto err;
}
diff --git a/src/crypto/rsa/internal.h b/src/crypto/rsa/internal.h
index d15f2a5..4e896e2 100644
--- a/src/crypto/rsa/internal.h
+++ b/src/crypto/rsa/internal.h
@@ -59,14 +59,34 @@
#include <openssl/base.h>
-#include <openssl/asn1.h>
-
#if defined(__cplusplus)
extern "C" {
#endif
+/* Default implementations of RSA operations. */
+
+extern const RSA_METHOD RSA_default_method;
+
+size_t rsa_default_size(const RSA *rsa);
+int rsa_default_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
+ const uint8_t *in, size_t in_len, int padding);
+int rsa_default_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);
+int rsa_default_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
+ const uint8_t *in, size_t in_len, int padding);
+int rsa_default_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);
+int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
+ size_t len);
+int rsa_default_multi_prime_keygen(RSA *rsa, int bits, int num_primes,
+ BIGNUM *e_value, BN_GENCB *cb);
+int rsa_default_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb);
+
+
#define RSA_PKCS1_PADDING_SIZE 11
@@ -86,8 +106,8 @@ void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
BN_BLINDING *BN_BLINDING_create_param(
BN_BLINDING *b, const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
- const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
- BN_MONT_CTX *m_ctx);
+ const BIGNUM *m, BN_CTX *ctx, const BN_MONT_CTX *mont),
+ const BN_MONT_CTX *mont);
BN_BLINDING *rsa_setup_blinding(RSA *rsa, BN_CTX *in_ctx);
@@ -109,8 +129,6 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned to_len,
const EVP_MD *md, const EVP_MD *mgf1md);
int RSA_padding_add_none(uint8_t *to, unsigned to_len, const uint8_t *from,
unsigned from_len);
-int RSA_padding_check_none(uint8_t *to, unsigned to_len, const uint8_t *from,
- unsigned from_len);
/* RSA_private_transform calls either the method-specific |private_transform|
* function (if given) or the generic one. See the comment for
@@ -118,20 +136,26 @@ int RSA_padding_check_none(uint8_t *to, unsigned to_len, const uint8_t *from,
int RSA_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
size_t len);
-typedef struct rsa_pss_params_st {
- X509_ALGOR *hashAlgorithm;
- X509_ALGOR *maskGenAlgorithm;
- ASN1_INTEGER *saltLength;
- ASN1_INTEGER *trailerField;
-} RSA_PSS_PARAMS;
-DECLARE_ASN1_FUNCTIONS(RSA_PSS_PARAMS)
+/* RSA_additional_prime contains information about the third, forth etc prime
+ * in a multi-prime RSA key. */
+typedef struct RSA_additional_prime_st {
+ BIGNUM *prime;
+ /* exp is d^{prime-1} mod prime */
+ BIGNUM *exp;
+ /* coeff is such that r×coeff ≡ 1 mod prime. */
+ BIGNUM *coeff;
+
+ /* Values below here are not in the ASN.1 serialisation. */
+
+ /* r is the product of all primes (including p and q) prior to this one. */
+ BIGNUM *r;
+ /* mont is a |BN_MONT_CTX| modulo |prime|. */
+ BN_MONT_CTX *mont;
+} RSA_additional_prime;
+
+void RSA_additional_prime_free(RSA_additional_prime *ap);
-typedef struct rsa_oaep_params_st {
- X509_ALGOR *hashFunc;
- X509_ALGOR *maskGenFunc;
- X509_ALGOR *pSourceFunc;
-} RSA_OAEP_PARAMS;
#if defined(__cplusplus)
} /* extern C */
diff --git a/src/crypto/rsa/padding.c b/src/crypto/rsa/padding.c
index 0a725f1..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,23 +66,22 @@
#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) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_type_1,
- RSA_R_KEY_SIZE_TOO_SMALL);
+ 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) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_type_1,
- RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ if (from_len > to_len - RSA_PKCS1_PADDING_SIZE) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
return 0;
}
@@ -91,34 +91,32 @@ 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) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_type_1,
- RSA_R_DATA_TOO_SMALL);
+ if (from_len < 2) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_SMALL);
return -1;
}
p = from;
if ((*(p++) != 0) || (*(p++) != 1)) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_type_1,
- RSA_R_BLOCK_TYPE_IS_NOT_01);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BLOCK_TYPE_IS_NOT_01);
return -1;
}
/* 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) {
@@ -126,8 +124,7 @@ int RSA_padding_check_PKCS1_type_1(uint8_t *to, unsigned tlen,
p++;
break;
} else {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_type_1,
- RSA_R_BAD_FIXED_HEADER_DECRYPT);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_FIXED_HEADER_DECRYPT);
return -1;
}
}
@@ -135,21 +132,18 @@ int RSA_padding_check_PKCS1_type_1(uint8_t *to, unsigned tlen,
}
if (i == j) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_type_1,
- RSA_R_NULL_BEFORE_BLOCK_MISSING);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_NULL_BEFORE_BLOCK_MISSING);
return -1;
}
if (i < 8) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_type_1,
- RSA_R_BAD_PAD_BYTE_COUNT);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_PAD_BYTE_COUNT);
return -1;
}
i++; /* Skip over the '\0' */
j -= i;
- if (j > tlen) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_type_1,
- RSA_R_DATA_TOO_LARGE);
+ if (j > to_len) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE);
return -1;
}
memcpy(to, p, j);
@@ -157,20 +151,18 @@ 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) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_type_2,
- RSA_R_KEY_SIZE_TOO_SMALL);
+ 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) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_type_2,
- RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ if (from_len > to_len - RSA_PKCS1_PADDING_SIZE) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
return 0;
}
@@ -180,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;
@@ -197,135 +189,92 @@ 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_padding_check_PKCS1_type_2,
- 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)) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_type_2,
- RSA_R_PKCS_DECODING_ERROR);
+ 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_padding_check_PKCS1_type_2,
- 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) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_none,
- RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+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) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_none,
- RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE);
+ 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;
}
-int RSA_padding_check_none(uint8_t *to, unsigned tlen, const uint8_t *from,
- unsigned flen) {
- if (flen > tlen) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_check_none, RSA_R_DATA_TOO_LARGE);
- return -1;
- }
-
- memcpy(to, from, flen);
- return flen;
-}
-
int PKCS1_MGF1(uint8_t *mask, unsigned len, const uint8_t *seed,
unsigned seedlen, const EVP_MD *dgst) {
unsigned outlen = 0;
@@ -345,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;
}
@@ -369,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;
@@ -387,22 +337,19 @@ int RSA_padding_add_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen,
mdlen = EVP_MD_size(md);
- if (tlen < 2 * mdlen + 2) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_OAEP_mgf1,
- RSA_R_KEY_SIZE_TOO_SMALL);
+ 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) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_OAEP_mgf1,
- RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ 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;
}
if (emlen < 2 * mdlen + 1) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_OAEP_mgf1,
- RSA_R_KEY_SIZE_TOO_SMALL);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
return 0;
}
@@ -410,20 +357,19 @@ 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;
}
dbmask = OPENSSL_malloc(emlen - mdlen);
if (dbmask == NULL) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_OAEP_mgf1,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -447,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();
@@ -468,17 +413,16 @@ 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, RSA_padding_check_PKCS1_OAEP_mgf1,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -499,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;
@@ -525,9 +469,8 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen,
one_index++;
mlen = dblen - one_index;
- if (tlen < mlen) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_OAEP_mgf1,
- RSA_R_DATA_TOO_LARGE);
+ if (to_len < mlen) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE);
mlen = -1;
} else {
memcpy(to, db + one_index, mlen);
@@ -539,8 +482,7 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen,
decoding_err:
/* to avoid chosen ciphertext attacks, the error message should not reveal
* which kind of decoding error happened */
- OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_OAEP_mgf1,
- RSA_R_OAEP_DECODING_ERROR);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_OAEP_DECODING_ERROR);
err:
OPENSSL_free(db);
return -1;
@@ -576,15 +518,14 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const uint8_t *mHash,
} else if (sLen == -2) {
sLen = -2;
} else if (sLen < -2) {
- OPENSSL_PUT_ERROR(RSA, RSA_verify_PKCS1_PSS_mgf1, RSA_R_SLEN_CHECK_FAILED);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED);
goto err;
}
MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
emLen = RSA_size(rsa);
if (EM[0] & (0xFF << MSBits)) {
- OPENSSL_PUT_ERROR(RSA, RSA_verify_PKCS1_PSS_mgf1,
- RSA_R_FIRST_OCTET_INVALID);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_FIRST_OCTET_INVALID);
goto err;
}
if (MSBits == 0) {
@@ -593,18 +534,18 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const uint8_t *mHash,
}
if (emLen < ((int)hLen + sLen + 2)) {
/* sLen can be small negative */
- OPENSSL_PUT_ERROR(RSA, RSA_verify_PKCS1_PSS_mgf1, RSA_R_DATA_TOO_LARGE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE);
goto err;
}
if (EM[emLen - 1] != 0xbc) {
- OPENSSL_PUT_ERROR(RSA, RSA_verify_PKCS1_PSS_mgf1, RSA_R_LAST_OCTET_INVALID);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_LAST_OCTET_INVALID);
goto err;
}
maskedDBLen = emLen - hLen - 1;
H = EM + maskedDBLen;
DB = OPENSSL_malloc(maskedDBLen);
if (!DB) {
- OPENSSL_PUT_ERROR(RSA, RSA_verify_PKCS1_PSS_mgf1, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
goto err;
}
if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash) < 0) {
@@ -620,12 +561,11 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const uint8_t *mHash,
;
}
if (DB[i++] != 0x1) {
- OPENSSL_PUT_ERROR(RSA, RSA_verify_PKCS1_PSS_mgf1,
- RSA_R_SLEN_RECOVERY_FAILED);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_RECOVERY_FAILED);
goto err;
}
if (sLen >= 0 && (maskedDBLen - i) != sLen) {
- OPENSSL_PUT_ERROR(RSA, RSA_verify_PKCS1_PSS_mgf1, RSA_R_SLEN_CHECK_FAILED);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED);
goto err;
}
if (!EVP_DigestInit_ex(&ctx, Hash, NULL) ||
@@ -642,7 +582,7 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const uint8_t *mHash,
goto err;
}
if (memcmp(H_, H, hLen)) {
- OPENSSL_PUT_ERROR(RSA, RSA_verify_PKCS1_PSS_mgf1, RSA_R_BAD_SIGNATURE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE);
ret = 0;
} else {
ret = 1;
@@ -681,14 +621,12 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
} else if (sLen == -2) {
sLen = -2;
} else if (sLen < -2) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1,
- RSA_R_SLEN_CHECK_FAILED);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED);
goto err;
}
if (BN_is_zero(rsa->n)) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1,
- RSA_R_EMPTY_PUBLIC_KEY);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY);
goto err;
}
@@ -701,21 +639,18 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
}
if (sLen == -2) {
if (emLen < hLen + 2) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1,
- RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
goto err;
}
sLen = emLen - hLen - 2;
} else if (emLen < hLen + sLen + 2) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1,
- RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
goto err;
}
if (sLen > 0) {
salt = OPENSSL_malloc(sLen);
if (!salt) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!RAND_bytes(salt, sLen)) {
diff --git a/src/crypto/rsa/rsa.c b/src/crypto/rsa/rsa.c
index 17059b0..6c28ad7 100644
--- a/src/crypto/rsa/rsa.c
+++ b/src/crypto/rsa/rsa.c
@@ -56,6 +56,7 @@
#include <openssl/rsa.h>
+#include <limits.h>
#include <string.h>
#include <openssl/bn.h>
@@ -70,8 +71,6 @@
#include "../internal.h"
-extern const RSA_METHOD RSA_default_method;
-
static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
RSA *RSA_new(void) { return RSA_new_method(NULL); }
@@ -79,7 +78,7 @@ RSA *RSA_new(void) { return RSA_new_method(NULL); }
RSA *RSA_new_method(const ENGINE *engine) {
RSA *rsa = (RSA *)OPENSSL_malloc(sizeof(RSA));
if (rsa == NULL) {
- OPENSSL_PUT_ERROR(RSA, RSA_new_method, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -97,15 +96,11 @@ 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)) {
- 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);
+ CRYPTO_MUTEX_cleanup(&rsa->lock);
METHOD_unref(rsa->meth);
OPENSSL_free(rsa);
return NULL;
@@ -114,6 +109,19 @@ RSA *RSA_new_method(const ENGINE *engine) {
return rsa;
}
+void RSA_additional_prime_free(RSA_additional_prime *ap) {
+ if (ap == NULL) {
+ return;
+ }
+
+ BN_clear_free(ap->prime);
+ BN_clear_free(ap->exp);
+ BN_clear_free(ap->coeff);
+ BN_clear_free(ap->r);
+ BN_MONT_CTX_free(ap->mont);
+ OPENSSL_free(ap);
+}
+
void RSA_free(RSA *rsa) {
unsigned u;
@@ -140,11 +148,18 @@ void RSA_free(RSA *rsa) {
BN_clear_free(rsa->dmp1);
BN_clear_free(rsa->dmq1);
BN_clear_free(rsa->iqmp);
+ BN_MONT_CTX_free(rsa->mont_n);
+ BN_MONT_CTX_free(rsa->mont_p);
+ BN_MONT_CTX_free(rsa->mont_q);
for (u = 0; u < rsa->num_blindings; u++) {
BN_BLINDING_free(rsa->blindings[u]);
}
OPENSSL_free(rsa->blindings);
OPENSSL_free(rsa->blindings_inuse);
+ if (rsa->additional_primes != NULL) {
+ sk_RSA_additional_prime_pop_free(rsa->additional_primes,
+ RSA_additional_prime_free);
+ }
CRYPTO_MUTEX_cleanup(&rsa->lock);
OPENSSL_free(rsa);
}
@@ -159,7 +174,16 @@ int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
return rsa->meth->keygen(rsa, bits, e_value, cb);
}
- return RSA_default_method.keygen(rsa, bits, e_value, cb);
+ return rsa_default_keygen(rsa, bits, e_value, cb);
+}
+
+int RSA_generate_multi_prime_key(RSA *rsa, int bits, int num_primes,
+ BIGNUM *e_value, BN_GENCB *cb) {
+ if (rsa->meth->multi_prime_keygen) {
+ return rsa->meth->multi_prime_keygen(rsa, bits, num_primes, e_value, cb);
+ }
+
+ return rsa_default_multi_prime_keygen(rsa, bits, num_primes, e_value, cb);
}
int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
@@ -168,11 +192,10 @@ int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
return rsa->meth->encrypt(rsa, out_len, out, max_out, in, in_len, padding);
}
- return RSA_default_method.encrypt(rsa, out_len, out, max_out, in, in_len,
- padding);
+ return rsa_default_encrypt(rsa, out_len, out, max_out, in, in_len, padding);
}
-int RSA_public_encrypt(int flen, const uint8_t *from, uint8_t *to, RSA *rsa,
+int RSA_public_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
int padding) {
size_t out_len;
@@ -180,6 +203,10 @@ int RSA_public_encrypt(int flen, const uint8_t *from, uint8_t *to, RSA *rsa,
return -1;
}
+ if (out_len > INT_MAX) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
+ return -1;
+ }
return out_len;
}
@@ -189,11 +216,10 @@ int RSA_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
return rsa->meth->sign_raw(rsa, out_len, out, max_out, in, in_len, padding);
}
- return RSA_default_method.sign_raw(rsa, out_len, out, max_out, in, in_len,
- padding);
+ return rsa_default_sign_raw(rsa, out_len, out, max_out, in, in_len, padding);
}
-int RSA_private_encrypt(int flen, const uint8_t *from, uint8_t *to, RSA *rsa,
+int RSA_private_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
int padding) {
size_t out_len;
@@ -201,6 +227,10 @@ int RSA_private_encrypt(int flen, const uint8_t *from, uint8_t *to, RSA *rsa,
return -1;
}
+ if (out_len > INT_MAX) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
+ return -1;
+ }
return out_len;
}
@@ -210,11 +240,10 @@ int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
return rsa->meth->decrypt(rsa, out_len, out, max_out, in, in_len, padding);
}
- return RSA_default_method.decrypt(rsa, out_len, out, max_out, in, in_len,
- padding);
+ return rsa_default_decrypt(rsa, out_len, out, max_out, in, in_len, padding);
}
-int RSA_private_decrypt(int flen, const uint8_t *from, uint8_t *to, RSA *rsa,
+int RSA_private_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
int padding) {
size_t out_len;
@@ -222,6 +251,10 @@ int RSA_private_decrypt(int flen, const uint8_t *from, uint8_t *to, RSA *rsa,
return -1;
}
+ if (out_len > INT_MAX) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
+ return -1;
+ }
return out_len;
}
@@ -231,11 +264,11 @@ int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
return rsa->meth->verify_raw(rsa, out_len, out, max_out, in, in_len, padding);
}
- return RSA_default_method.verify_raw(rsa, out_len, out, max_out, in, in_len,
- padding);
+ return rsa_default_verify_raw(rsa, out_len, out, max_out, in, in_len,
+ padding);
}
-int RSA_public_decrypt(int flen, const uint8_t *from, uint8_t *to, RSA *rsa,
+int RSA_public_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
int padding) {
size_t out_len;
@@ -243,6 +276,10 @@ int RSA_public_decrypt(int flen, const uint8_t *from, uint8_t *to, RSA *rsa,
return -1;
}
+ if (out_len > INT_MAX) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
+ return -1;
+ }
return out_len;
}
@@ -251,7 +288,7 @@ unsigned RSA_size(const RSA *rsa) {
return rsa->meth->size(rsa);
}
- return RSA_default_method.size(rsa);
+ return rsa_default_size(rsa);
}
int RSA_is_opaque(const RSA *rsa) {
@@ -265,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;
@@ -342,20 +379,15 @@ static const struct pkcs1_sig_prefix kPKCS1SigPrefixes[] = {
},
};
-/* TODO(fork): mostly new code, needs careful review. */
-
-/* pkcs1_prefixed_msg builds a PKCS#1, prefixed version of |msg| for the given
- * hash function and sets |out_msg| to point to it. On successful return,
- * |*out_msg| may be allocated memory and, if so, |*is_alloced| will be 1. */
-static int pkcs1_prefixed_msg(uint8_t **out_msg, size_t *out_msg_len,
- int *is_alloced, int hash_nid, const uint8_t *msg,
- size_t msg_len) {
+int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len,
+ int *is_alloced, int hash_nid, const uint8_t *msg,
+ size_t msg_len) {
unsigned i;
if (hash_nid == NID_md5_sha1) {
/* Special case: SSL signature, just check the length. */
if (msg_len != SSL_SIG_LENGTH) {
- OPENSSL_PUT_ERROR(RSA, pkcs1_prefixed_msg, RSA_R_INVALID_MESSAGE_LENGTH);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
return 0;
}
@@ -378,13 +410,13 @@ static int pkcs1_prefixed_msg(uint8_t **out_msg, size_t *out_msg_len,
signed_msg_len = prefix_len + msg_len;
if (signed_msg_len < prefix_len) {
- OPENSSL_PUT_ERROR(RSA, pkcs1_prefixed_msg, RSA_R_TOO_LONG);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_LONG);
return 0;
}
signed_msg = OPENSSL_malloc(signed_msg_len);
if (!signed_msg) {
- OPENSSL_PUT_ERROR(RSA, pkcs1_prefixed_msg, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -398,7 +430,7 @@ static int pkcs1_prefixed_msg(uint8_t **out_msg, size_t *out_msg_len,
return 1;
}
- OPENSSL_PUT_ERROR(RSA, pkcs1_prefixed_msg, RSA_R_UNKNOWN_ALGORITHM_TYPE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_ALGORITHM_TYPE);
return 0;
}
@@ -415,14 +447,14 @@ int RSA_sign(int hash_nid, const uint8_t *in, unsigned in_len, uint8_t *out,
return rsa->meth->sign(hash_nid, in, in_len, out, out_len, rsa);
}
- if (!pkcs1_prefixed_msg(&signed_msg, &signed_msg_len, &signed_msg_is_alloced,
- hash_nid, in, in_len)) {
+ if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len,
+ &signed_msg_is_alloced, hash_nid, in, in_len)) {
return 0;
}
if (rsa_size < RSA_PKCS1_PADDING_SIZE ||
signed_msg_len > rsa_size - RSA_PKCS1_PADDING_SIZE) {
- OPENSSL_PUT_ERROR(RSA, RSA_sign, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
goto finish;
}
@@ -453,18 +485,18 @@ int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len,
}
if (sig_len != rsa_size) {
- OPENSSL_PUT_ERROR(RSA, RSA_verify, RSA_R_WRONG_SIGNATURE_LENGTH);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_WRONG_SIGNATURE_LENGTH);
return 0;
}
if (hash_nid == NID_md5_sha1 && msg_len != SSL_SIG_LENGTH) {
- OPENSSL_PUT_ERROR(RSA, RSA_verify, RSA_R_INVALID_MESSAGE_LENGTH);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
return 0;
}
buf = OPENSSL_malloc(rsa_size);
if (!buf) {
- OPENSSL_PUT_ERROR(RSA, RSA_verify, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -473,13 +505,13 @@ int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len,
goto out;
}
- if (!pkcs1_prefixed_msg(&signed_msg, &signed_msg_len, &signed_msg_is_alloced,
- hash_nid, msg, msg_len)) {
+ if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len,
+ &signed_msg_is_alloced, hash_nid, msg, msg_len)) {
goto out;
}
if (len != signed_msg_len || CRYPTO_memcmp(buf, signed_msg, len) != 0) {
- OPENSSL_PUT_ERROR(RSA, RSA_verify, RSA_R_BAD_SIGNATURE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE);
goto out;
}
@@ -509,12 +541,12 @@ int RSA_check_key(const RSA *key) {
}
if ((key->p != NULL) != (key->q != NULL)) {
- OPENSSL_PUT_ERROR(RSA, RSA_check_key, RSA_R_ONLY_ONE_OF_P_Q_GIVEN);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_ONLY_ONE_OF_P_Q_GIVEN);
return 0;
}
if (!key->n || !key->e) {
- OPENSSL_PUT_ERROR(RSA, RSA_check_key, RSA_R_VALUE_MISSING);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
return 0;
}
@@ -526,7 +558,7 @@ int RSA_check_key(const RSA *key) {
ctx = BN_CTX_new();
if (ctx == NULL) {
- OPENSSL_PUT_ERROR(RSA, RSA_check_key, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -540,52 +572,74 @@ int RSA_check_key(const RSA *key) {
BN_init(&dmq1);
BN_init(&iqmp);
- if (/* n = pq */
- !BN_mul(&n, key->p, key->q, ctx) ||
- /* lcm = lcm(p-1, q-1) */
+ if (!BN_mul(&n, key->p, key->q, ctx) ||
+ /* lcm = lcm(prime-1, for all primes) */
!BN_sub(&pm1, key->p, BN_value_one()) ||
!BN_sub(&qm1, key->q, BN_value_one()) ||
!BN_mul(&lcm, &pm1, &qm1, ctx) ||
+ !BN_gcd(&gcd, &pm1, &qm1, ctx)) {
+ OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
+ goto out;
+ }
+
+ size_t num_additional_primes = 0;
+ if (key->additional_primes != NULL) {
+ num_additional_primes = sk_RSA_additional_prime_num(key->additional_primes);
+ }
+
+ size_t i;
+ for (i = 0; i < num_additional_primes; i++) {
+ const RSA_additional_prime *ap =
+ sk_RSA_additional_prime_value(key->additional_primes, i);
+ if (!BN_mul(&n, &n, ap->prime, ctx) ||
+ !BN_sub(&pm1, ap->prime, BN_value_one()) ||
+ !BN_mul(&lcm, &lcm, &pm1, ctx) ||
+ !BN_gcd(&gcd, &gcd, &pm1, ctx)) {
+ OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
+ goto out;
+ }
+ }
+
+ if (!BN_div(&lcm, NULL, &lcm, &gcd, ctx) ||
!BN_gcd(&gcd, &pm1, &qm1, ctx) ||
- !BN_div(&lcm, NULL, &lcm, &gcd, ctx) ||
- /* de = d*e mod lcm(p-1, q-1) */
+ /* de = d*e mod lcm(prime-1, for all primes). */
!BN_mod_mul(&de, key->d, key->e, &lcm, ctx)) {
- OPENSSL_PUT_ERROR(RSA, RSA_check_key, ERR_LIB_BN);
+ OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
goto out;
}
if (BN_cmp(&n, key->n) != 0) {
- OPENSSL_PUT_ERROR(RSA, RSA_check_key, RSA_R_N_NOT_EQUAL_P_Q);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_N_NOT_EQUAL_P_Q);
goto out;
}
if (!BN_is_one(&de)) {
- OPENSSL_PUT_ERROR(RSA, RSA_check_key, RSA_R_D_E_NOT_CONGRUENT_TO_1);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_D_E_NOT_CONGRUENT_TO_1);
goto out;
}
has_crt_values = key->dmp1 != NULL;
if (has_crt_values != (key->dmq1 != NULL) ||
has_crt_values != (key->iqmp != NULL)) {
- OPENSSL_PUT_ERROR(RSA, RSA_check_key, RSA_R_INCONSISTENT_SET_OF_CRT_VALUES);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_INCONSISTENT_SET_OF_CRT_VALUES);
goto out;
}
- if (has_crt_values) {
+ if (has_crt_values && num_additional_primes == 0) {
if (/* dmp1 = d mod (p-1) */
!BN_mod(&dmp1, key->d, &pm1, ctx) ||
/* dmq1 = d mod (q-1) */
!BN_mod(&dmq1, key->d, &qm1, ctx) ||
/* iqmp = q^-1 mod p */
!BN_mod_inverse(&iqmp, key->q, key->p, ctx)) {
- OPENSSL_PUT_ERROR(RSA, RSA_check_key, ERR_LIB_BN);
+ OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
goto out;
}
if (BN_cmp(&dmp1, key->dmp1) != 0 ||
BN_cmp(&dmq1, key->dmq1) != 0 ||
BN_cmp(&iqmp, key->iqmp) != 0) {
- OPENSSL_PUT_ERROR(RSA, RSA_check_key, RSA_R_CRT_VALUES_INCORRECT);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_VALUES_INCORRECT);
goto out;
}
}
@@ -613,13 +667,17 @@ int RSA_recover_crt_params(RSA *rsa) {
int ok = 0;
if (rsa->n == NULL || rsa->e == NULL || rsa->d == NULL) {
- OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, RSA_R_EMPTY_PUBLIC_KEY);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY);
return 0;
}
if (rsa->p || rsa->q || rsa->dmp1 || rsa->dmq1 || rsa->iqmp) {
- OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params,
- RSA_R_CRT_PARAMS_ALREADY_GIVEN);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_PARAMS_ALREADY_GIVEN);
+ return 0;
+ }
+
+ if (rsa->additional_primes != NULL) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_CANNOT_RECOVER_MULTI_PRIME_KEY);
return 0;
}
@@ -628,7 +686,7 @@ int RSA_recover_crt_params(RSA *rsa) {
ctx = BN_CTX_new();
if (ctx == NULL) {
- OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -641,7 +699,7 @@ int RSA_recover_crt_params(RSA *rsa) {
if (totient == NULL || rem == NULL || multiple == NULL || p_plus_q == NULL ||
p_minus_q == NULL) {
- OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -669,12 +727,12 @@ int RSA_recover_crt_params(RSA *rsa) {
!BN_div(multiple, NULL, totient, rsa->n, ctx) ||
!BN_add_word(multiple, 1) ||
!BN_div(totient, rem, totient, multiple, ctx)) {
- OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
goto err;
}
if (!BN_is_zero(rem)) {
- OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, RSA_R_BAD_RSA_PARAMETERS);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS);
goto err;
}
@@ -685,7 +743,7 @@ int RSA_recover_crt_params(RSA *rsa) {
rsa->iqmp = BN_new();
if (rsa->p == NULL || rsa->q == NULL || rsa->dmp1 == NULL || rsa->dmq1 ==
NULL || rsa->iqmp == NULL) {
- OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -703,12 +761,12 @@ int RSA_recover_crt_params(RSA *rsa) {
!BN_rshift1(rsa->q, rsa->q) ||
!BN_div(rsa->p, NULL, rsa->n, rsa->q, ctx) ||
!BN_mul(multiple, rsa->p, rsa->q, ctx)) {
- OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
goto err;
}
if (BN_cmp(multiple, rsa->n) != 0) {
- OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, RSA_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_INTERNAL_ERROR);
goto err;
}
@@ -717,7 +775,7 @@ int RSA_recover_crt_params(RSA *rsa) {
!BN_sub(rem, rsa->q, BN_value_one()) ||
!BN_mod(rsa->dmq1, rsa->d, rem, ctx) ||
!BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx)) {
- OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
goto err;
}
@@ -742,7 +800,7 @@ int RSA_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
return rsa->meth->private_transform(rsa, out, in, len);
}
- return RSA_default_method.private_transform(rsa, out, in, len);
+ return rsa_default_private_transform(rsa, out, in, len);
}
int RSA_blinding_on(RSA *rsa, BN_CTX *ctx) {
diff --git a/src/crypto/rsa/rsa_asn1.c b/src/crypto/rsa/rsa_asn1.c
index 924cb8a..b73a0e1 100644
--- a/src/crypto/rsa/rsa_asn1.c
+++ b/src/crypto/rsa/rsa_asn1.c
@@ -55,45 +55,399 @@
#include <openssl/rsa.h>
+#include <assert.h>
+#include <limits.h>
+#include <string.h>
+
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
+#include <openssl/bn.h>
+#include <openssl/bytestring.h>
+#include <openssl/err.h>
+#include <openssl/mem.h>
#include "internal.h"
-/* Override the default free and new methods */
-static int rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
- void *exarg) {
- if (operation == ASN1_OP_NEW_PRE) {
- *pval = (ASN1_VALUE *)RSA_new();
- if (*pval) {
- return 2;
+static int parse_integer_buggy(CBS *cbs, BIGNUM **out, int buggy) {
+ assert(*out == NULL);
+ *out = BN_new();
+ if (*out == NULL) {
+ return 0;
+ }
+ if (buggy) {
+ return BN_cbs2unsigned_buggy(cbs, *out);
+ }
+ return BN_cbs2unsigned(cbs, *out);
+}
+
+static int parse_integer(CBS *cbs, BIGNUM **out) {
+ return parse_integer_buggy(cbs, out, 0 /* not buggy */);
+}
+
+static int marshal_integer(CBB *cbb, BIGNUM *bn) {
+ if (bn == NULL) {
+ /* An RSA object may be missing some components. */
+ OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
+ return 0;
+ }
+ return BN_bn2cbb(cbb, bn);
+}
+
+static RSA *parse_public_key(CBS *cbs, int buggy) {
+ RSA *ret = RSA_new();
+ if (ret == NULL) {
+ return NULL;
+ }
+ CBS child;
+ if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
+ !parse_integer_buggy(&child, &ret->n, buggy) ||
+ !parse_integer(&child, &ret->e) ||
+ CBS_len(&child) != 0) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING);
+ 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;
+}
+
+RSA *RSA_parse_public_key(CBS *cbs) {
+ return parse_public_key(cbs, 0 /* not buggy */);
+}
+
+RSA *RSA_parse_public_key_buggy(CBS *cbs) {
+ /* Estonian IDs issued between September 2014 to September 2015 are
+ * broken. See https://crbug.com/532048 and https://crbug.com/534766.
+ *
+ * TODO(davidben): Remove this code and callers in March 2016. */
+ return parse_public_key(cbs, 1 /* buggy */);
+}
+
+RSA *RSA_public_key_from_bytes(const uint8_t *in, size_t in_len) {
+ CBS cbs;
+ CBS_init(&cbs, in, in_len);
+ RSA *ret = RSA_parse_public_key(&cbs);
+ if (ret == NULL || CBS_len(&cbs) != 0) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING);
+ RSA_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
+int RSA_marshal_public_key(CBB *cbb, const RSA *rsa) {
+ CBB child;
+ if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
+ !marshal_integer(&child, rsa->n) ||
+ !marshal_integer(&child, rsa->e) ||
+ !CBB_flush(cbb)) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR);
+ return 0;
+ }
+ return 1;
+}
+
+int RSA_public_key_to_bytes(uint8_t **out_bytes, size_t *out_len,
+ const RSA *rsa) {
+ CBB cbb;
+ CBB_zero(&cbb);
+ if (!CBB_init(&cbb, 0) ||
+ !RSA_marshal_public_key(&cbb, rsa) ||
+ !CBB_finish(&cbb, out_bytes, out_len)) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR);
+ CBB_cleanup(&cbb);
+ return 0;
+ }
+ return 1;
+}
+
+/* kVersionTwoPrime and kVersionMulti are the supported values of the version
+ * field of an RSAPrivateKey structure (RFC 3447). */
+static const uint64_t kVersionTwoPrime = 0;
+static const uint64_t kVersionMulti = 1;
+
+/* rsa_parse_additional_prime parses a DER-encoded OtherPrimeInfo from |cbs| and
+ * advances |cbs|. It returns a newly-allocated |RSA_additional_prime| on
+ * success or NULL on error. The |r| and |mont| fields of the result are set to
+ * NULL. */
+static RSA_additional_prime *rsa_parse_additional_prime(CBS *cbs) {
+ RSA_additional_prime *ret = OPENSSL_malloc(sizeof(RSA_additional_prime));
+ if (ret == NULL) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ memset(ret, 0, sizeof(RSA_additional_prime));
+
+ CBS child;
+ if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
+ !parse_integer(&child, &ret->prime) ||
+ !parse_integer(&child, &ret->exp) ||
+ !parse_integer(&child, &ret->coeff) ||
+ CBS_len(&child) != 0) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING);
+ RSA_additional_prime_free(ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+RSA *RSA_parse_private_key(CBS *cbs) {
+ BN_CTX *ctx = NULL;
+ BIGNUM *product_of_primes_so_far = NULL;
+ RSA *ret = RSA_new();
+ if (ret == NULL) {
+ return NULL;
+ }
+
+ CBS child;
+ uint64_t version;
+ if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
+ !CBS_get_asn1_uint64(&child, &version)) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING);
+ goto err;
+ }
+
+ if (version != kVersionTwoPrime && version != kVersionMulti) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_VERSION);
+ goto err;
+ }
+
+ if (!parse_integer(&child, &ret->n) ||
+ !parse_integer(&child, &ret->e) ||
+ !parse_integer(&child, &ret->d) ||
+ !parse_integer(&child, &ret->p) ||
+ !parse_integer(&child, &ret->q) ||
+ !parse_integer(&child, &ret->dmp1) ||
+ !parse_integer(&child, &ret->dmq1) ||
+ !parse_integer(&child, &ret->iqmp)) {
+ goto err;
+ }
+
+ /* Multi-prime RSA requires a newer version. */
+ if (version == kVersionMulti &&
+ CBS_peek_asn1_tag(&child, CBS_ASN1_SEQUENCE)) {
+ CBS other_prime_infos;
+ if (!CBS_get_asn1(&child, &other_prime_infos, CBS_ASN1_SEQUENCE) ||
+ CBS_len(&other_prime_infos) == 0) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING);
+ goto err;
+ }
+ ret->additional_primes = sk_RSA_additional_prime_new_null();
+ if (ret->additional_primes == NULL) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ ctx = BN_CTX_new();
+ product_of_primes_so_far = BN_new();
+ if (ctx == NULL ||
+ product_of_primes_so_far == NULL ||
+ !BN_mul(product_of_primes_so_far, ret->p, ret->q, ctx)) {
+ goto err;
+ }
+
+ while (CBS_len(&other_prime_infos) > 0) {
+ RSA_additional_prime *ap = rsa_parse_additional_prime(&other_prime_infos);
+ if (ap == NULL) {
+ goto err;
+ }
+ if (!sk_RSA_additional_prime_push(ret->additional_primes, ap)) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
+ RSA_additional_prime_free(ap);
+ goto err;
+ }
+ ap->r = BN_dup(product_of_primes_so_far);
+ if (ap->r == NULL ||
+ !BN_mul(product_of_primes_so_far, product_of_primes_so_far,
+ ap->prime, ctx)) {
+ goto err;
+ }
}
+ }
+
+ if (CBS_len(&child) != 0) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING);
+ goto err;
+ }
+
+ BN_CTX_free(ctx);
+ BN_free(product_of_primes_so_far);
+ return ret;
+
+err:
+ BN_CTX_free(ctx);
+ BN_free(product_of_primes_so_far);
+ RSA_free(ret);
+ return NULL;
+}
+
+RSA *RSA_private_key_from_bytes(const uint8_t *in, size_t in_len) {
+ CBS cbs;
+ CBS_init(&cbs, in, in_len);
+ RSA *ret = RSA_parse_private_key(&cbs);
+ if (ret == NULL || CBS_len(&cbs) != 0) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING);
+ RSA_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
+int RSA_marshal_private_key(CBB *cbb, const RSA *rsa) {
+ const int is_multiprime =
+ sk_RSA_additional_prime_num(rsa->additional_primes) > 0;
+
+ CBB child;
+ if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
+ !CBB_add_asn1_uint64(&child,
+ is_multiprime ? kVersionMulti : kVersionTwoPrime) ||
+ !marshal_integer(&child, rsa->n) ||
+ !marshal_integer(&child, rsa->e) ||
+ !marshal_integer(&child, rsa->d) ||
+ !marshal_integer(&child, rsa->p) ||
+ !marshal_integer(&child, rsa->q) ||
+ !marshal_integer(&child, rsa->dmp1) ||
+ !marshal_integer(&child, rsa->dmq1) ||
+ !marshal_integer(&child, rsa->iqmp)) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR);
+ return 0;
+ }
+
+ if (is_multiprime) {
+ CBB other_prime_infos;
+ if (!CBB_add_asn1(&child, &other_prime_infos, CBS_ASN1_SEQUENCE)) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR);
+ return 0;
+ }
+ size_t i;
+ for (i = 0; i < sk_RSA_additional_prime_num(rsa->additional_primes); i++) {
+ RSA_additional_prime *ap =
+ sk_RSA_additional_prime_value(rsa->additional_primes, i);
+ CBB other_prime_info;
+ if (!CBB_add_asn1(&other_prime_infos, &other_prime_info,
+ CBS_ASN1_SEQUENCE) ||
+ !marshal_integer(&other_prime_info, ap->prime) ||
+ !marshal_integer(&other_prime_info, ap->exp) ||
+ !marshal_integer(&other_prime_info, ap->coeff)) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR);
+ return 0;
+ }
+ }
+ }
+
+ if (!CBB_flush(cbb)) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR);
return 0;
- } else if (operation == ASN1_OP_FREE_PRE) {
- RSA_free((RSA *)*pval);
- *pval = NULL;
- return 2;
}
return 1;
}
-ASN1_SEQUENCE_cb(RSAPrivateKey, rsa_cb) = {
- ASN1_SIMPLE(RSA, version, LONG),
- ASN1_SIMPLE(RSA, n, BIGNUM),
- ASN1_SIMPLE(RSA, e, BIGNUM),
- ASN1_SIMPLE(RSA, d, BIGNUM),
- ASN1_SIMPLE(RSA, p, BIGNUM),
- ASN1_SIMPLE(RSA, q, BIGNUM),
- ASN1_SIMPLE(RSA, dmp1, BIGNUM),
- ASN1_SIMPLE(RSA, dmq1, BIGNUM),
- ASN1_SIMPLE(RSA, iqmp, BIGNUM),
-} ASN1_SEQUENCE_END_cb(RSA, RSAPrivateKey);
+int RSA_private_key_to_bytes(uint8_t **out_bytes, size_t *out_len,
+ const RSA *rsa) {
+ CBB cbb;
+ CBB_zero(&cbb);
+ if (!CBB_init(&cbb, 0) ||
+ !RSA_marshal_private_key(&cbb, rsa) ||
+ !CBB_finish(&cbb, out_bytes, out_len)) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR);
+ CBB_cleanup(&cbb);
+ return 0;
+ }
+ return 1;
+}
-ASN1_SEQUENCE_cb(RSAPublicKey, rsa_cb) = {
- ASN1_SIMPLE(RSA, n, BIGNUM),
- ASN1_SIMPLE(RSA, e, BIGNUM),
-} ASN1_SEQUENCE_END_cb(RSA, RSAPublicKey);
+RSA *d2i_RSAPublicKey(RSA **out, const uint8_t **inp, long len) {
+ if (len < 0) {
+ return NULL;
+ }
+ CBS cbs;
+ CBS_init(&cbs, *inp, (size_t)len);
+ RSA *ret = RSA_parse_public_key(&cbs);
+ if (ret == NULL) {
+ return NULL;
+ }
+ if (out != NULL) {
+ RSA_free(*out);
+ *out = ret;
+ }
+ *inp += (size_t)len - CBS_len(&cbs);
+ return ret;
+}
+
+int i2d_RSAPublicKey(const RSA *in, uint8_t **outp) {
+ uint8_t *der;
+ size_t der_len;
+ if (!RSA_public_key_to_bytes(&der, &der_len, in)) {
+ return -1;
+ }
+ if (der_len > INT_MAX) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
+ OPENSSL_free(der);
+ return -1;
+ }
+ if (outp != NULL) {
+ if (*outp == NULL) {
+ *outp = der;
+ der = NULL;
+ } else {
+ memcpy(*outp, der, der_len);
+ *outp += der_len;
+ }
+ }
+ OPENSSL_free(der);
+ return (int)der_len;
+}
+
+RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len) {
+ if (len < 0) {
+ return NULL;
+ }
+ CBS cbs;
+ CBS_init(&cbs, *inp, (size_t)len);
+ RSA *ret = RSA_parse_private_key(&cbs);
+ if (ret == NULL) {
+ return NULL;
+ }
+ if (out != NULL) {
+ RSA_free(*out);
+ *out = ret;
+ }
+ *inp += (size_t)len - CBS_len(&cbs);
+ return ret;
+}
+
+int i2d_RSAPrivateKey(const RSA *in, uint8_t **outp) {
+ uint8_t *der;
+ size_t der_len;
+ if (!RSA_private_key_to_bytes(&der, &der_len, in)) {
+ return -1;
+ }
+ if (der_len > INT_MAX) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
+ OPENSSL_free(der);
+ return -1;
+ }
+ if (outp != NULL) {
+ if (*outp == NULL) {
+ *outp = der;
+ der = NULL;
+ } else {
+ memcpy(*outp, der, der_len);
+ *outp += der_len;
+ }
+ }
+ OPENSSL_free(der);
+ return (int)der_len;
+}
ASN1_SEQUENCE(RSA_PSS_PARAMS) = {
ASN1_EXP_OPT(RSA_PSS_PARAMS, hashAlgorithm, X509_ALGOR,0),
@@ -104,22 +458,24 @@ ASN1_SEQUENCE(RSA_PSS_PARAMS) = {
IMPLEMENT_ASN1_FUNCTIONS(RSA_PSS_PARAMS);
-ASN1_SEQUENCE(RSA_OAEP_PARAMS) = {
- ASN1_EXP_OPT(RSA_OAEP_PARAMS, hashFunc, X509_ALGOR, 0),
- ASN1_EXP_OPT(RSA_OAEP_PARAMS, maskGenFunc, X509_ALGOR, 1),
- ASN1_EXP_OPT(RSA_OAEP_PARAMS, pSourceFunc, X509_ALGOR, 2),
-} ASN1_SEQUENCE_END(RSA_OAEP_PARAMS);
-
-IMPLEMENT_ASN1_FUNCTIONS(RSA_OAEP_PARAMS);
-
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPrivateKey, RSAPrivateKey);
-
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPublicKey, RSAPublicKey);
-
RSA *RSAPublicKey_dup(const RSA *rsa) {
- return ASN1_item_dup(ASN1_ITEM_rptr(RSAPublicKey), (RSA *) rsa);
+ uint8_t *der;
+ size_t der_len;
+ if (!RSA_public_key_to_bytes(&der, &der_len, rsa)) {
+ return NULL;
+ }
+ RSA *ret = RSA_public_key_from_bytes(der, der_len);
+ OPENSSL_free(der);
+ return ret;
}
RSA *RSAPrivateKey_dup(const RSA *rsa) {
- return ASN1_item_dup(ASN1_ITEM_rptr(RSAPrivateKey), (RSA *) rsa);
+ uint8_t *der;
+ size_t der_len;
+ if (!RSA_private_key_to_bytes(&der, &der_len, rsa)) {
+ return NULL;
+ }
+ RSA *ret = RSA_private_key_from_bytes(der, der_len);
+ OPENSSL_free(der);
+ return ret;
}
diff --git a/src/crypto/rsa/rsa_impl.c b/src/crypto/rsa/rsa_impl.c
index e14f0f5..b1cfaa6 100644
--- a/src/crypto/rsa/rsa_impl.c
+++ b/src/crypto/rsa/rsa_impl.c
@@ -73,20 +73,12 @@
64 /* exponent limit enforced for "large" modulus only */
-static int finish(RSA *rsa) {
- BN_MONT_CTX_free(rsa->_method_mod_n);
- BN_MONT_CTX_free(rsa->_method_mod_p);
- BN_MONT_CTX_free(rsa->_method_mod_q);
-
- return 1;
-}
-
-static size_t size(const RSA *rsa) {
+size_t rsa_default_size(const RSA *rsa) {
return BN_num_bytes(rsa->n);
}
-static int encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
- const uint8_t *in, size_t in_len, int padding) {
+int rsa_default_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
+ const uint8_t *in, size_t in_len, int padding) {
const unsigned rsa_size = RSA_size(rsa);
BIGNUM *f, *result;
uint8_t *buf = NULL;
@@ -94,24 +86,24 @@ static int encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
int i, ret = 0;
if (rsa_size > OPENSSL_RSA_MAX_MODULUS_BITS) {
- OPENSSL_PUT_ERROR(RSA, encrypt, RSA_R_MODULUS_TOO_LARGE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE);
return 0;
}
if (max_out < rsa_size) {
- OPENSSL_PUT_ERROR(RSA, encrypt, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
return 0;
}
if (BN_ucmp(rsa->n, rsa->e) <= 0) {
- OPENSSL_PUT_ERROR(RSA, encrypt, RSA_R_BAD_E_VALUE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE);
return 0;
}
/* for large moduli, enforce exponent limit */
if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS &&
BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) {
- OPENSSL_PUT_ERROR(RSA, encrypt, RSA_R_BAD_E_VALUE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE);
return 0;
}
@@ -125,7 +117,7 @@ static int encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
result = BN_CTX_get(ctx);
buf = OPENSSL_malloc(rsa_size);
if (!f || !result || !buf) {
- OPENSSL_PUT_ERROR(RSA, encrypt, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -142,7 +134,7 @@ static int encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
i = RSA_padding_add_none(buf, rsa_size, in, in_len);
break;
default:
- OPENSSL_PUT_ERROR(RSA, encrypt, RSA_R_UNKNOWN_PADDING_TYPE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE);
goto err;
}
@@ -156,26 +148,24 @@ static int encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
if (BN_ucmp(f, rsa->n) >= 0) {
/* usually the padding functions would catch this */
- OPENSSL_PUT_ERROR(RSA, encrypt, RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
goto err;
}
if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
- if (BN_MONT_CTX_set_locked(&rsa->_method_mod_n, &rsa->lock, rsa->n, ctx) ==
- NULL) {
+ if (BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) == NULL) {
goto err;
}
}
- if (!rsa->meth->bn_mod_exp(result, f, rsa->e, rsa->n, ctx,
- rsa->_method_mod_n)) {
+ if (!rsa->meth->bn_mod_exp(result, f, rsa->e, rsa->n, ctx, rsa->mont_n)) {
goto err;
}
/* put in leading 0 bytes if the number is less than the length of the
* modulus */
if (!BN_bn2bin_padded(out, rsa_size, result)) {
- OPENSSL_PUT_ERROR(RSA, encrypt, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -302,20 +292,21 @@ static void rsa_blinding_release(RSA *rsa, BN_BLINDING *blinding,
}
/* signing */
-static int 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) {
+int rsa_default_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) {
const unsigned rsa_size = RSA_size(rsa);
uint8_t *buf = NULL;
int i, ret = 0;
if (max_out < rsa_size) {
- OPENSSL_PUT_ERROR(RSA, sign_raw, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
return 0;
}
buf = OPENSSL_malloc(rsa_size);
if (buf == NULL) {
- OPENSSL_PUT_ERROR(RSA, sign_raw, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -327,7 +318,7 @@ static int sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
i = RSA_padding_add_none(buf, rsa_size, in, in_len);
break;
default:
- OPENSSL_PUT_ERROR(RSA, sign_raw, RSA_R_UNKNOWN_PADDING_TYPE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE);
goto err;
}
@@ -351,26 +342,31 @@ err:
return ret;
}
-static int decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
- const uint8_t *in, size_t in_len, int padding) {
+int rsa_default_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
+ const uint8_t *in, size_t in_len, int padding) {
const unsigned rsa_size = RSA_size(rsa);
int r = -1;
uint8_t *buf = NULL;
int ret = 0;
if (max_out < rsa_size) {
- OPENSSL_PUT_ERROR(RSA, decrypt, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
return 0;
}
- buf = OPENSSL_malloc(rsa_size);
- if (buf == NULL) {
- OPENSSL_PUT_ERROR(RSA, decrypt, ERR_R_MALLOC_FAILURE);
- goto err;
+ if (padding == RSA_NO_PADDING) {
+ buf = out;
+ } else {
+ /* Allocate a temporary buffer to hold the padded plaintext. */
+ buf = OPENSSL_malloc(rsa_size);
+ if (buf == NULL) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
}
if (in_len != rsa_size) {
- OPENSSL_PUT_ERROR(RSA, decrypt, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN);
goto err;
}
@@ -388,22 +384,22 @@ static int decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
NULL, 0, NULL, NULL);
break;
case RSA_NO_PADDING:
- r = RSA_padding_check_none(out, rsa_size, buf, rsa_size);
+ r = rsa_size;
break;
default:
- OPENSSL_PUT_ERROR(RSA, decrypt, RSA_R_UNKNOWN_PADDING_TYPE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE);
goto err;
}
if (r < 0) {
- OPENSSL_PUT_ERROR(RSA, decrypt, RSA_R_PADDING_CHECK_FAILED);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_PADDING_CHECK_FAILED);
} else {
*out_len = r;
ret = 1;
}
err:
- if (buf != NULL) {
+ if (padding != RSA_NO_PADDING && buf != NULL) {
OPENSSL_cleanse(buf, rsa_size);
OPENSSL_free(buf);
}
@@ -411,8 +407,9 @@ err:
return ret;
}
-static int 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) {
+int rsa_default_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) {
const unsigned rsa_size = RSA_size(rsa);
BIGNUM *f, *result;
int ret = 0;
@@ -421,24 +418,24 @@ static int verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
BN_CTX *ctx = NULL;
if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) {
- OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_MODULUS_TOO_LARGE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE);
return 0;
}
if (BN_ucmp(rsa->n, rsa->e) <= 0) {
- OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_BAD_E_VALUE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE);
return 0;
}
if (max_out < rsa_size) {
- OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
return 0;
}
/* for large moduli, enforce exponent limit */
if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS &&
BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) {
- OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_BAD_E_VALUE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE);
return 0;
}
@@ -450,14 +447,23 @@ static int verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
BN_CTX_start(ctx);
f = BN_CTX_get(ctx);
result = BN_CTX_get(ctx);
- buf = OPENSSL_malloc(rsa_size);
- if (!f || !result || !buf) {
- OPENSSL_PUT_ERROR(RSA, verify_raw, ERR_R_MALLOC_FAILURE);
+ if (padding == RSA_NO_PADDING) {
+ buf = out;
+ } else {
+ /* Allocate a temporary buffer to hold the padded plaintext. */
+ buf = OPENSSL_malloc(rsa_size);
+ if (buf == NULL) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+ if (!f || !result) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
goto err;
}
if (in_len != rsa_size) {
- OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN);
goto err;
}
@@ -466,24 +472,22 @@ static int verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
}
if (BN_ucmp(f, rsa->n) >= 0) {
- OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
goto err;
}
if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
- if (BN_MONT_CTX_set_locked(&rsa->_method_mod_n, &rsa->lock, rsa->n, ctx) ==
- NULL) {
+ if (BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) == NULL) {
goto err;
}
}
- if (!rsa->meth->bn_mod_exp(result, f, rsa->e, rsa->n, ctx,
- rsa->_method_mod_n)) {
+ if (!rsa->meth->bn_mod_exp(result, f, rsa->e, rsa->n, ctx, rsa->mont_n)) {
goto err;
}
if (!BN_bn2bin_padded(buf, rsa_size, result)) {
- OPENSSL_PUT_ERROR(RSA, verify_raw, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -492,15 +496,15 @@ static int verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
r = RSA_padding_check_PKCS1_type_1(out, rsa_size, buf, rsa_size);
break;
case RSA_NO_PADDING:
- r = RSA_padding_check_none(out, rsa_size, buf, rsa_size);
+ r = rsa_size;
break;
default:
- OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_UNKNOWN_PADDING_TYPE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE);
goto err;
}
if (r < 0) {
- OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_PADDING_CHECK_FAILED);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_PADDING_CHECK_FAILED);
} else {
*out_len = r;
ret = 1;
@@ -511,15 +515,15 @@ err:
BN_CTX_end(ctx);
BN_CTX_free(ctx);
}
- if (buf != NULL) {
+ if (padding != RSA_NO_PADDING && buf != NULL) {
OPENSSL_cleanse(buf, rsa_size);
OPENSSL_free(buf);
}
return ret;
}
-static int private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
- size_t len) {
+int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
+ size_t len) {
BIGNUM *f, *result;
BN_CTX *ctx = NULL;
unsigned blinding_index = 0;
@@ -535,7 +539,7 @@ static int private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
result = BN_CTX_get(ctx);
if (f == NULL || result == NULL) {
- OPENSSL_PUT_ERROR(RSA, private_transform, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -545,14 +549,14 @@ static int private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
if (BN_ucmp(f, rsa->n) >= 0) {
/* Usually the padding functions would catch this. */
- OPENSSL_PUT_ERROR(RSA, private_transform, RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
goto err;
}
if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) {
blinding = rsa_blinding_get(rsa, &blinding_index, ctx);
if (blinding == NULL) {
- OPENSSL_PUT_ERROR(RSA, private_transform, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
goto err;
}
if (!BN_BLINDING_convert_ex(f, NULL, blinding, ctx)) {
@@ -575,13 +579,13 @@ static int private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
- if (BN_MONT_CTX_set_locked(&rsa->_method_mod_n, &rsa->lock, rsa->n,
- ctx) == NULL) {
+ if (BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) ==
+ NULL) {
goto err;
}
}
- if (!rsa->meth->bn_mod_exp(result, f, d, rsa->n, ctx, rsa->_method_mod_n)) {
+ if (!rsa->meth->bn_mod_exp(result, f, d, rsa->n, ctx, rsa->mont_n)) {
goto err;
}
}
@@ -593,7 +597,7 @@ static int private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
}
if (!BN_bn2bin_padded(out, len, result)) {
- OPENSSL_PUT_ERROR(RSA, private_transform, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -616,6 +620,11 @@ static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) {
BIGNUM local_dmp1, local_dmq1, local_c, local_r1;
BIGNUM *dmp1, *dmq1, *c, *pr1;
int ret = 0;
+ size_t i, num_additional_primes = 0;
+
+ if (rsa->additional_primes != NULL) {
+ num_additional_primes = sk_RSA_additional_prime_num(rsa->additional_primes);
+ }
BN_CTX_start(ctx);
r1 = BN_CTX_get(ctx);
@@ -627,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);
@@ -637,20 +646,17 @@ static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) {
BN_with_flags(q, rsa->q, BN_FLG_CONSTTIME);
if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) {
- if (BN_MONT_CTX_set_locked(&rsa->_method_mod_p, &rsa->lock, p, ctx) ==
- NULL) {
+ if (BN_MONT_CTX_set_locked(&rsa->mont_p, &rsa->lock, p, ctx) == NULL) {
goto err;
}
- if (BN_MONT_CTX_set_locked(&rsa->_method_mod_q, &rsa->lock, q, ctx) ==
- NULL) {
+ if (BN_MONT_CTX_set_locked(&rsa->mont_q, &rsa->lock, q, ctx) == NULL) {
goto err;
}
}
}
if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
- if (BN_MONT_CTX_set_locked(&rsa->_method_mod_n, &rsa->lock, rsa->n, ctx) ==
- NULL) {
+ if (BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) == NULL) {
goto err;
}
}
@@ -665,7 +671,7 @@ static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) {
/* compute r1^dmq1 mod q */
dmq1 = &local_dmq1;
BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME);
- if (!rsa->meth->bn_mod_exp(m1, r1, dmq1, rsa->q, ctx, rsa->_method_mod_q)) {
+ if (!rsa->meth->bn_mod_exp(m1, r1, dmq1, rsa->q, ctx, rsa->mont_q)) {
goto err;
}
@@ -679,7 +685,7 @@ static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) {
/* compute r1^dmp1 mod p */
dmp1 = &local_dmp1;
BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME);
- if (!rsa->meth->bn_mod_exp(r0, r1, dmp1, rsa->p, ctx, rsa->_method_mod_p)) {
+ if (!rsa->meth->bn_mod_exp(r0, r1, dmp1, rsa->p, ctx, rsa->mont_p)) {
goto err;
}
@@ -724,9 +730,44 @@ static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) {
goto err;
}
+ for (i = 0; i < num_additional_primes; i++) {
+ /* multi-prime RSA. */
+ BIGNUM local_exp, local_prime;
+ BIGNUM *exp = &local_exp, *prime = &local_prime;
+ RSA_additional_prime *ap =
+ sk_RSA_additional_prime_value(rsa->additional_primes, i);
+
+ BN_with_flags(exp, ap->exp, BN_FLG_CONSTTIME);
+ BN_with_flags(prime, ap->prime, BN_FLG_CONSTTIME);
+
+ /* c will already point to a BIGNUM with the correct flags. */
+ if (!BN_mod(r1, c, prime, ctx)) {
+ goto err;
+ }
+
+ if ((rsa->flags & RSA_FLAG_CACHE_PRIVATE) &&
+ !BN_MONT_CTX_set_locked(&ap->mont, &rsa->lock, prime, ctx)) {
+ goto err;
+ }
+
+ if (!rsa->meth->bn_mod_exp(m1, r1, exp, prime, ctx, ap->mont)) {
+ goto err;
+ }
+
+ BN_set_flags(m1, BN_FLG_CONSTTIME);
+
+ if (!BN_sub(m1, m1, r0) ||
+ !BN_mul(m1, m1, ap->coeff, ctx) ||
+ !BN_mod(m1, m1, prime, ctx) ||
+ (BN_is_negative(m1) && !BN_add(m1, m1, prime)) ||
+ !BN_mul(m1, m1, ap->r, ctx) ||
+ !BN_add(r0, r0, m1)) {
+ goto err;
+ }
+ }
+
if (rsa->e && rsa->n) {
- if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx,
- rsa->_method_mod_n)) {
+ if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx, rsa->mont_n)) {
goto err;
}
/* If 'I' was greater than (or equal to) rsa->n, the operation
@@ -754,7 +795,7 @@ static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) {
d = &local_d;
BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
- if (!rsa->meth->bn_mod_exp(r0, I, d, rsa->n, ctx, rsa->_method_mod_n)) {
+ if (!rsa->meth->bn_mod_exp(r0, I, d, rsa->n, ctx, rsa->mont_n)) {
goto err;
}
}
@@ -766,12 +807,20 @@ err:
return ret;
}
-static int keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
+int rsa_default_multi_prime_keygen(RSA *rsa, int bits, int num_primes,
+ BIGNUM *e_value, BN_GENCB *cb) {
BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *tmp;
BIGNUM local_r0, local_d, local_p;
BIGNUM *pr0, *d, *p;
- int bitsp, bitsq, ok = -1, n = 0;
+ int prime_bits, ok = -1, n = 0, i, j;
BN_CTX *ctx = NULL;
+ STACK_OF(RSA_additional_prime) *additional_primes = NULL;
+
+ if (num_primes < 2) {
+ ok = 0; /* we set our own err */
+ OPENSSL_PUT_ERROR(RSA, RSA_R_MUST_HAVE_AT_LEAST_TWO_PRIMES);
+ goto err;
+ }
ctx = BN_CTX_new();
if (ctx == NULL) {
@@ -782,12 +831,36 @@ static int keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
r1 = BN_CTX_get(ctx);
r2 = BN_CTX_get(ctx);
r3 = BN_CTX_get(ctx);
- if (r3 == NULL) {
+ if (r0 == NULL || r1 == NULL || r2 == NULL || r3 == NULL) {
goto err;
}
- bitsp = (bits + 1) / 2;
- bitsq = bits - bitsp;
+ if (num_primes > 2) {
+ additional_primes = sk_RSA_additional_prime_new_null();
+ if (additional_primes == NULL) {
+ goto err;
+ }
+ }
+
+ for (i = 2; i < num_primes; i++) {
+ RSA_additional_prime *ap = OPENSSL_malloc(sizeof(RSA_additional_prime));
+ if (ap == NULL) {
+ goto err;
+ }
+ memset(ap, 0, sizeof(RSA_additional_prime));
+ ap->prime = BN_new();
+ ap->exp = BN_new();
+ ap->coeff = BN_new();
+ ap->r = BN_new();
+ if (ap->prime == NULL ||
+ ap->exp == NULL ||
+ ap->coeff == NULL ||
+ ap->r == NULL ||
+ !sk_RSA_additional_prime_push(additional_primes, ap)) {
+ RSA_additional_prime_free(ap);
+ goto err;
+ }
+ }
/* We need the RSA components non-NULL */
if (!rsa->n && ((rsa->n = BN_new()) == NULL)) {
@@ -815,11 +888,14 @@ static int keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
goto err;
}
- BN_copy(rsa->e, e_value);
+ if (!BN_copy(rsa->e, e_value)) {
+ goto err;
+ }
/* generate p and q */
+ prime_bits = (bits + (num_primes - 1)) / num_primes;
for (;;) {
- if (!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb) ||
+ if (!BN_generate_prime_ex(rsa->p, prime_bits, 0, NULL, NULL, cb) ||
!BN_sub(r2, rsa->p, BN_value_one()) ||
!BN_gcd(r1, r2, rsa->e, ctx)) {
goto err;
@@ -834,19 +910,20 @@ static int keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
if (!BN_GENCB_call(cb, 3, 0)) {
goto err;
}
+ prime_bits = ((bits - prime_bits) + (num_primes - 2)) / (num_primes - 1);
for (;;) {
/* When generating ridiculously small keys, we can get stuck
* continually regenerating the same prime values. Check for
* this and bail if it happens 3 times. */
unsigned int degenerate = 0;
do {
- if (!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb)) {
+ if (!BN_generate_prime_ex(rsa->q, prime_bits, 0, NULL, NULL, cb)) {
goto err;
}
} while ((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3));
if (degenerate == 3) {
ok = 0; /* we set our own err */
- OPENSSL_PUT_ERROR(RSA, keygen, RSA_R_KEY_SIZE_TOO_SMALL);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
goto err;
}
if (!BN_sub(r2, rsa->q, BN_value_one()) ||
@@ -860,20 +937,91 @@ static int keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
goto err;
}
}
- if (!BN_GENCB_call(cb, 3, 1)) {
+
+ if (!BN_GENCB_call(cb, 3, 1) ||
+ !BN_mul(rsa->n, rsa->p, rsa->q, ctx)) {
goto err;
}
+
+ for (i = 2; i < num_primes; i++) {
+ RSA_additional_prime *ap =
+ sk_RSA_additional_prime_value(additional_primes, i - 2);
+ prime_bits = ((bits - BN_num_bits(rsa->n)) + (num_primes - (i + 1))) /
+ (num_primes - i);
+
+ for (;;) {
+ if (!BN_generate_prime_ex(ap->prime, prime_bits, 0, NULL, NULL, cb)) {
+ goto err;
+ }
+ if (BN_cmp(rsa->p, ap->prime) == 0 ||
+ BN_cmp(rsa->q, ap->prime) == 0) {
+ continue;
+ }
+
+ for (j = 0; j < i - 2; j++) {
+ if (BN_cmp(sk_RSA_additional_prime_value(additional_primes, j)->prime,
+ ap->prime) == 0) {
+ break;
+ }
+ }
+ if (j != i - 2) {
+ continue;
+ }
+
+ if (!BN_sub(r2, ap->prime, BN_value_one()) ||
+ !BN_gcd(r1, r2, rsa->e, ctx)) {
+ goto err;
+ }
+
+ if (!BN_is_one(r1)) {
+ continue;
+ }
+ if (i != num_primes - 1) {
+ break;
+ }
+
+ /* For the last prime we'll check that it makes n large enough. In the
+ * two prime case this isn't a problem because we generate primes with
+ * the top two bits set and so the product is always of the expected
+ * size. In the multi prime case, this doesn't follow. */
+ if (!BN_mul(r1, rsa->n, ap->prime, ctx)) {
+ goto err;
+ }
+ if (BN_num_bits(r1) == (unsigned) bits) {
+ break;
+ }
+
+ if (!BN_GENCB_call(cb, 2, n++)) {
+ goto err;
+ }
+ }
+
+ /* ap->r is is the product of all the primes prior to the current one
+ * (including p and q). */
+ if (!BN_copy(ap->r, rsa->n)) {
+ goto err;
+ }
+ if (i == num_primes - 1) {
+ /* In the case of the last prime, we calculated n as |r1| in the loop
+ * above. */
+ if (!BN_copy(rsa->n, r1)) {
+ goto err;
+ }
+ } else if (!BN_mul(rsa->n, rsa->n, ap->prime, ctx)) {
+ goto err;
+ }
+
+ if (!BN_GENCB_call(cb, 3, 1)) {
+ goto err;
+ }
+ }
+
if (BN_cmp(rsa->p, rsa->q) < 0) {
tmp = rsa->p;
rsa->p = rsa->q;
rsa->q = tmp;
}
- /* calculate n */
- if (!BN_mul(rsa->n, rsa->p, rsa->q, ctx)) {
- goto err;
- }
-
/* calculate d */
if (!BN_sub(r1, rsa->p, BN_value_one())) {
goto err; /* p-1 */
@@ -884,6 +1032,14 @@ static int keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
if (!BN_mul(r0, r1, r2, ctx)) {
goto err; /* (p-1)(q-1) */
}
+ for (i = 2; i < num_primes; i++) {
+ RSA_additional_prime *ap =
+ sk_RSA_additional_prime_value(additional_primes, i - 2);
+ if (!BN_sub(r3, ap->prime, BN_value_one()) ||
+ !BN_mul(r0, r0, r3, ctx)) {
+ goto err;
+ }
+ }
pr0 = &local_r0;
BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
if (!BN_mod_inverse(rsa->d, rsa->e, pr0, ctx)) {
@@ -912,22 +1068,43 @@ static int keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
goto err;
}
+ for (i = 2; i < num_primes; i++) {
+ RSA_additional_prime *ap =
+ sk_RSA_additional_prime_value(additional_primes, i - 2);
+ if (!BN_sub(ap->exp, ap->prime, BN_value_one()) ||
+ !BN_mod(ap->exp, rsa->d, ap->exp, ctx) ||
+ !BN_mod_inverse(ap->coeff, ap->r, ap->prime, ctx)) {
+ goto err;
+ }
+ }
+
ok = 1;
+ rsa->additional_primes = additional_primes;
+ additional_primes = NULL;
err:
if (ok == -1) {
- OPENSSL_PUT_ERROR(RSA, keygen, ERR_LIB_BN);
+ OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
ok = 0;
}
if (ctx != NULL) {
BN_CTX_end(ctx);
BN_CTX_free(ctx);
}
-
+ sk_RSA_additional_prime_pop_free(additional_primes,
+ RSA_additional_prime_free);
return ok;
}
-const struct rsa_meth_st RSA_default_method = {
+int rsa_default_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
+ return rsa_default_multi_prime_keygen(rsa, bits, 2 /* num primes */, e_value,
+ cb);
+}
+
+/* Many of these methods are NULL to more easily drop unused functions. The
+ * wrapper functions will select the appropriate |rsa_default_*| for all
+ * methods. */
+const RSA_METHOD RSA_default_method = {
{
0 /* references */,
1 /* is_static */,
@@ -935,24 +1112,27 @@ const struct rsa_meth_st RSA_default_method = {
NULL /* app_data */,
NULL /* init */,
- finish,
+ NULL /* finish (defaults to rsa_default_finish) */,
- size,
+ NULL /* size (defaults to rsa_default_size) */,
NULL /* sign */,
NULL /* verify */,
- encrypt,
- sign_raw,
- decrypt,
- verify_raw,
+ NULL /* encrypt (defaults to rsa_default_encrypt) */,
+ NULL /* sign_raw (defaults to rsa_default_sign_raw) */,
+ NULL /* decrypt (defaults to rsa_default_decrypt) */,
+ NULL /* verify_raw (defaults to rsa_default_verify_raw) */,
- private_transform,
+ NULL /* private_transform (defaults to rsa_default_private_transform) */,
- mod_exp /* mod_exp */,
+ mod_exp,
BN_mod_exp_mont /* bn_mod_exp */,
RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE,
- keygen,
+ NULL /* keygen (defaults to rsa_default_keygen) */,
+ NULL /* multi_prime_keygen (defaults to rsa_default_multi_prime_keygen) */,
+
+ NULL /* supports_digest */,
};
diff --git a/src/crypto/rsa/rsa_test.c b/src/crypto/rsa/rsa_test.c
deleted file mode 100644
index 318cf3f..0000000
--- a/src/crypto/rsa/rsa_test.c
+++ /dev/null
@@ -1,511 +0,0 @@
-/* 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.] */
-
-#include <openssl/rsa.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <openssl/bn.h>
-#include <openssl/crypto.h>
-#include <openssl/err.h>
-#include <openssl/obj.h>
-
-
-#define SetKey \
- key->n = BN_bin2bn(n, sizeof(n) - 1, key->n); \
- key->e = BN_bin2bn(e, sizeof(e) - 1, key->e); \
- key->d = BN_bin2bn(d, sizeof(d) - 1, key->d); \
- key->p = BN_bin2bn(p, sizeof(p) - 1, key->p); \
- key->q = BN_bin2bn(q, sizeof(q) - 1, key->q); \
- key->dmp1 = BN_bin2bn(dmp1, sizeof(dmp1) - 1, key->dmp1); \
- key->dmq1 = BN_bin2bn(dmq1, sizeof(dmq1) - 1, key->dmq1); \
- key->iqmp = BN_bin2bn(iqmp, sizeof(iqmp) - 1, key->iqmp); \
- memcpy(c, ctext_ex, sizeof(ctext_ex) - 1); \
- return (sizeof(ctext_ex) - 1);
-
-static int key1(RSA *key, unsigned char *c) {
- static unsigned char n[] =
- "\x00\xAA\x36\xAB\xCE\x88\xAC\xFD\xFF\x55\x52\x3C\x7F\xC4\x52\x3F"
- "\x90\xEF\xA0\x0D\xF3\x77\x4A\x25\x9F\x2E\x62\xB4\xC5\xD9\x9C\xB5"
- "\xAD\xB3\x00\xA0\x28\x5E\x53\x01\x93\x0E\x0C\x70\xFB\x68\x76\x93"
- "\x9C\xE6\x16\xCE\x62\x4A\x11\xE0\x08\x6D\x34\x1E\xBC\xAC\xA0\xA1"
- "\xF5";
-
- static unsigned char e[] = "\x11";
-
- static unsigned char d[] =
- "\x0A\x03\x37\x48\x62\x64\x87\x69\x5F\x5F\x30\xBC\x38\xB9\x8B\x44"
- "\xC2\xCD\x2D\xFF\x43\x40\x98\xCD\x20\xD8\xA1\x38\xD0\x90\xBF\x64"
- "\x79\x7C\x3F\xA7\xA2\xCD\xCB\x3C\xD1\xE0\xBD\xBA\x26\x54\xB4\xF9"
- "\xDF\x8E\x8A\xE5\x9D\x73\x3D\x9F\x33\xB3\x01\x62\x4A\xFD\x1D\x51";
-
- static unsigned char p[] =
- "\x00\xD8\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5"
- "\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x12"
- "\x0D";
-
- static unsigned char q[] =
- "\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9"
- "\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D"
- "\x89";
-
- static unsigned char dmp1[] =
- "\x59\x0B\x95\x72\xA2\xC2\xA9\xC4\x06\x05\x9D\xC2\xAB\x2F\x1D\xAF"
- "\xEB\x7E\x8B\x4F\x10\xA7\x54\x9E\x8E\xED\xF5\xB4\xFC\xE0\x9E\x05";
-
- static unsigned char dmq1[] =
- "\x00\x8E\x3C\x05\x21\xFE\x15\xE0\xEA\x06\xA3\x6F\xF0\xF1\x0C\x99"
- "\x52\xC3\x5B\x7A\x75\x14\xFD\x32\x38\xB8\x0A\xAD\x52\x98\x62\x8D"
- "\x51";
-
- static unsigned char iqmp[] =
- "\x36\x3F\xF7\x18\x9D\xA8\xE9\x0B\x1D\x34\x1F\x71\xD0\x9B\x76\xA8"
- "\xA9\x43\xE1\x1D\x10\xB2\x4D\x24\x9F\x2D\xEA\xFE\xF8\x0C\x18\x26";
-
- static unsigned char ctext_ex[] =
- "\x1b\x8f\x05\xf9\xca\x1a\x79\x52\x6e\x53\xf3\xcc\x51\x4f\xdb\x89"
- "\x2b\xfb\x91\x93\x23\x1e\x78\xb9\x92\xe6\x8d\x50\xa4\x80\xcb\x52"
- "\x33\x89\x5c\x74\x95\x8d\x5d\x02\xab\x8c\x0f\xd0\x40\xeb\x58\x44"
- "\xb0\x05\xc3\x9e\xd8\x27\x4a\x9d\xbf\xa8\x06\x71\x40\x94\x39\xd2";
-
- SetKey;
-}
-
-static int key2(RSA *key, unsigned char *c) {
- static unsigned char n[] =
- "\x00\xA3\x07\x9A\x90\xDF\x0D\xFD\x72\xAC\x09\x0C\xCC\x2A\x78\xB8"
- "\x74\x13\x13\x3E\x40\x75\x9C\x98\xFA\xF8\x20\x4F\x35\x8A\x0B\x26"
- "\x3C\x67\x70\xE7\x83\xA9\x3B\x69\x71\xB7\x37\x79\xD2\x71\x7B\xE8"
- "\x34\x77\xCF";
-
- static unsigned char e[] = "\x3";
-
- static unsigned char d[] =
- "\x6C\xAF\xBC\x60\x94\xB3\xFE\x4C\x72\xB0\xB3\x32\xC6\xFB\x25\xA2"
- "\xB7\x62\x29\x80\x4E\x68\x65\xFC\xA4\x5A\x74\xDF\x0F\x8F\xB8\x41"
- "\x3B\x52\xC0\xD0\xE5\x3D\x9B\x59\x0F\xF1\x9B\xE7\x9F\x49\xDD\x21"
- "\xE5\xEB";
-
- static unsigned char p[] =
- "\x00\xCF\x20\x35\x02\x8B\x9D\x86\x98\x40\xB4\x16\x66\xB4\x2E\x92"
- "\xEA\x0D\xA3\xB4\x32\x04\xB5\xCF\xCE\x91";
-
- static unsigned char q[] =
- "\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9"
- "\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5F";
-
- static unsigned char dmp1[] =
- "\x00\x8A\x15\x78\xAC\x5D\x13\xAF\x10\x2B\x22\xB9\x99\xCD\x74\x61"
- "\xF1\x5E\x6D\x22\xCC\x03\x23\xDF\xDF\x0B";
-
- static unsigned char dmq1[] =
- "\x00\x86\x55\x21\x4A\xC5\x4D\x8D\x4E\xCD\x61\x77\xF1\xC7\x36\x90"
- "\xCE\x2A\x48\x2C\x8B\x05\x99\xCB\xE0\x3F";
-
- static unsigned char iqmp[] =
- "\x00\x83\xEF\xEF\xB8\xA9\xA4\x0D\x1D\xB6\xED\x98\xAD\x84\xED\x13"
- "\x35\xDC\xC1\x08\xF3\x22\xD0\x57\xCF\x8D";
-
- static unsigned char ctext_ex[] =
- "\x14\xbd\xdd\x28\xc9\x83\x35\x19\x23\x80\xe8\xe5\x49\xb1\x58\x2a"
- "\x8b\x40\xb4\x48\x6d\x03\xa6\xa5\x31\x1f\x1f\xd5\xf0\xa1\x80\xe4"
- "\x17\x53\x03\x29\xa9\x34\x90\x74\xb1\x52\x13\x54\x29\x08\x24\x52"
- "\x62\x51";
-
- SetKey;
-}
-
-static int key3(RSA *key, unsigned char *c) {
- static unsigned char n[] =
- "\x00\xBB\xF8\x2F\x09\x06\x82\xCE\x9C\x23\x38\xAC\x2B\x9D\xA8\x71"
- "\xF7\x36\x8D\x07\xEE\xD4\x10\x43\xA4\x40\xD6\xB6\xF0\x74\x54\xF5"
- "\x1F\xB8\xDF\xBA\xAF\x03\x5C\x02\xAB\x61\xEA\x48\xCE\xEB\x6F\xCD"
- "\x48\x76\xED\x52\x0D\x60\xE1\xEC\x46\x19\x71\x9D\x8A\x5B\x8B\x80"
- "\x7F\xAF\xB8\xE0\xA3\xDF\xC7\x37\x72\x3E\xE6\xB4\xB7\xD9\x3A\x25"
- "\x84\xEE\x6A\x64\x9D\x06\x09\x53\x74\x88\x34\xB2\x45\x45\x98\x39"
- "\x4E\xE0\xAA\xB1\x2D\x7B\x61\xA5\x1F\x52\x7A\x9A\x41\xF6\xC1\x68"
- "\x7F\xE2\x53\x72\x98\xCA\x2A\x8F\x59\x46\xF8\xE5\xFD\x09\x1D\xBD"
- "\xCB";
-
- static unsigned char e[] = "\x11";
-
- static unsigned char d[] =
- "\x00\xA5\xDA\xFC\x53\x41\xFA\xF2\x89\xC4\xB9\x88\xDB\x30\xC1\xCD"
- "\xF8\x3F\x31\x25\x1E\x06\x68\xB4\x27\x84\x81\x38\x01\x57\x96\x41"
- "\xB2\x94\x10\xB3\xC7\x99\x8D\x6B\xC4\x65\x74\x5E\x5C\x39\x26\x69"
- "\xD6\x87\x0D\xA2\xC0\x82\xA9\x39\xE3\x7F\xDC\xB8\x2E\xC9\x3E\xDA"
- "\xC9\x7F\xF3\xAD\x59\x50\xAC\xCF\xBC\x11\x1C\x76\xF1\xA9\x52\x94"
- "\x44\xE5\x6A\xAF\x68\xC5\x6C\x09\x2C\xD3\x8D\xC3\xBE\xF5\xD2\x0A"
- "\x93\x99\x26\xED\x4F\x74\xA1\x3E\xDD\xFB\xE1\xA1\xCE\xCC\x48\x94"
- "\xAF\x94\x28\xC2\xB7\xB8\x88\x3F\xE4\x46\x3A\x4B\xC8\x5B\x1C\xB3"
- "\xC1";
-
- static unsigned char p[] =
- "\x00\xEE\xCF\xAE\x81\xB1\xB9\xB3\xC9\x08\x81\x0B\x10\xA1\xB5\x60"
- "\x01\x99\xEB\x9F\x44\xAE\xF4\xFD\xA4\x93\xB8\x1A\x9E\x3D\x84\xF6"
- "\x32\x12\x4E\xF0\x23\x6E\x5D\x1E\x3B\x7E\x28\xFA\xE7\xAA\x04\x0A"
- "\x2D\x5B\x25\x21\x76\x45\x9D\x1F\x39\x75\x41\xBA\x2A\x58\xFB\x65"
- "\x99";
-
- static unsigned char q[] =
- "\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9"
- "\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D"
- "\x86\x98\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5"
- "\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x15"
- "\x03";
-
- static unsigned char dmp1[] =
- "\x54\x49\x4C\xA6\x3E\xBA\x03\x37\xE4\xE2\x40\x23\xFC\xD6\x9A\x5A"
- "\xEB\x07\xDD\xDC\x01\x83\xA4\xD0\xAC\x9B\x54\xB0\x51\xF2\xB1\x3E"
- "\xD9\x49\x09\x75\xEA\xB7\x74\x14\xFF\x59\xC1\xF7\x69\x2E\x9A\x2E"
- "\x20\x2B\x38\xFC\x91\x0A\x47\x41\x74\xAD\xC9\x3C\x1F\x67\xC9\x81";
-
- static unsigned char dmq1[] =
- "\x47\x1E\x02\x90\xFF\x0A\xF0\x75\x03\x51\xB7\xF8\x78\x86\x4C\xA9"
- "\x61\xAD\xBD\x3A\x8A\x7E\x99\x1C\x5C\x05\x56\xA9\x4C\x31\x46\xA7"
- "\xF9\x80\x3F\x8F\x6F\x8A\xE3\x42\xE9\x31\xFD\x8A\xE4\x7A\x22\x0D"
- "\x1B\x99\xA4\x95\x84\x98\x07\xFE\x39\xF9\x24\x5A\x98\x36\xDA\x3D";
-
- static unsigned char iqmp[] =
- "\x00\xB0\x6C\x4F\xDA\xBB\x63\x01\x19\x8D\x26\x5B\xDB\xAE\x94\x23"
- "\xB3\x80\xF2\x71\xF7\x34\x53\x88\x50\x93\x07\x7F\xCD\x39\xE2\x11"
- "\x9F\xC9\x86\x32\x15\x4F\x58\x83\xB1\x67\xA9\x67\xBF\x40\x2B\x4E"
- "\x9E\x2E\x0F\x96\x56\xE6\x98\xEA\x36\x66\xED\xFB\x25\x79\x80\x39"
- "\xF7";
-
- static unsigned char ctext_ex[] =
- "\xb8\x24\x6b\x56\xa6\xed\x58\x81\xae\xb5\x85\xd9\xa2\x5b\x2a\xd7"
- "\x90\xc4\x17\xe0\x80\x68\x1b\xf1\xac\x2b\xc3\xde\xb6\x9d\x8b\xce"
- "\xf0\xc4\x36\x6f\xec\x40\x0a\xf0\x52\xa7\x2e\x9b\x0e\xff\xb5\xb3"
- "\xf2\xf1\x92\xdb\xea\xca\x03\xc1\x27\x40\x05\x71\x13\xbf\x1f\x06"
- "\x69\xac\x22\xe9\xf3\xa7\x85\x2e\x3c\x15\xd9\x13\xca\xb0\xb8\x86"
- "\x3a\x95\xc9\x92\x94\xce\x86\x74\x21\x49\x54\x61\x03\x46\xf4\xd4"
- "\x74\xb2\x6f\x7c\x48\xb4\x2e\xe6\x8e\x1f\x57\x2a\x1f\xc4\x02\x6a"
- "\xc4\x56\xb4\xf5\x9f\x7b\x62\x1e\xa1\xb9\xd8\x8f\x64\x20\x2f\xb1";
-
- SetKey;
-}
-
-static int test_bad_key(void) {
- RSA *key = RSA_new();
- BIGNUM e;
-
- BN_init(&e);
- BN_set_word(&e, RSA_F4);
-
- if (!RSA_generate_key_ex(key, 512, &e, NULL)) {
- fprintf(stderr, "RSA_generate_key_ex failed.\n");
- ERR_print_errors_fp(stderr);
- return 0;
- }
-
- if (!BN_add(key->p, key->p, BN_value_one())) {
- fprintf(stderr, "BN error.\n");
- ERR_print_errors_fp(stderr);
- return 0;
- }
-
- if (RSA_check_key(key)) {
- fprintf(stderr, "RSA_check_key passed with invalid key!\n");
- return 0;
- }
-
- ERR_clear_error();
- BN_free(&e);
- RSA_free(key);
- return 1;
-}
-
-static int test_only_d_given(void) {
- RSA *key = RSA_new();
- uint8_t buf[64];
- unsigned buf_len = sizeof(buf);
- const uint8_t kDummyHash[16] = {0};
- int ret = 0;
-
- if (!BN_hex2bn(&key->n,
- "00e77bbf3889d4ef36a9a25d4d69f3f632eb4362214c74517da6d6aeaa9bd"
- "09ac42b26621cd88f3a6eb013772fc3bf9f83914b6467231c630202c35b3e"
- "5808c659") ||
- !BN_hex2bn(&key->e, "010001") ||
- !BN_hex2bn(&key->d,
- "0365db9eb6d73b53b015c40cd8db4de7dd7035c68b5ac1bf786d7a4ee2cea"
- "316eaeca21a73ac365e58713195f2ae9849348525ca855386b6d028e437a9"
- "495a01") ||
- RSA_size(key) > sizeof(buf)) {
- goto err;
- }
-
- if (!RSA_check_key(key)) {
- fprintf(stderr, "RSA_check_key failed with only d given.\n");
- ERR_print_errors_fp(stderr);
- goto err;
- }
-
- if (!RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, &buf_len,
- key)) {
- fprintf(stderr, "RSA_sign failed with only d given.\n");
- ERR_print_errors_fp(stderr);
- goto err;
- }
-
- if (!RSA_verify(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, buf_len,
- key)) {
- fprintf(stderr, "RSA_verify failed with only d given.\n");
- ERR_print_errors_fp(stderr);
- goto err;
- }
-
- ret = 1;
-
-err:
- RSA_free(key);
- return ret;
-}
-
-static int test_recover_crt_params(void) {
- RSA *key1, *key2;
- BIGNUM *e = BN_new();
- uint8_t buf[128];
- unsigned buf_len = sizeof(buf);
- const uint8_t kDummyHash[16] = {0};
- unsigned i;
-
- BN_set_word(e, RSA_F4);
-
- ERR_clear_error();
-
- for (i = 0; i < 1; i++) {
- key1 = RSA_new();
- if (!RSA_generate_key_ex(key1, 512, e, NULL)) {
- fprintf(stderr, "RSA_generate_key_ex failed.\n");
- ERR_print_errors_fp(stderr);
- return 0;
- }
-
- if (!RSA_check_key(key1)) {
- fprintf(stderr, "RSA_check_key failed with original key.\n");
- ERR_print_errors_fp(stderr);
- return 0;
- }
-
- key2 = RSA_new();
- key2->n = BN_dup(key1->n);
- key2->e = BN_dup(key1->e);
- key2->d = BN_dup(key1->d);
- RSA_free(key1);
-
- if (!RSA_recover_crt_params(key2)) {
- fprintf(stderr, "RSA_recover_crt_params failed.\n");
- ERR_print_errors_fp(stderr);
- return 0;
- }
-
- if (RSA_size(key2) > buf_len) {
- return 0;
- }
-
- if (!RSA_check_key(key2)) {
- fprintf(stderr, "RSA_check_key failed with recovered key.\n");
- ERR_print_errors_fp(stderr);
- return 0;
- }
-
- if (!RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, &buf_len,
- key2)) {
- fprintf(stderr, "RSA_sign failed with recovered key.\n");
- ERR_print_errors_fp(stderr);
- return 0;
- }
-
- if (!RSA_verify(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, buf_len,
- key2)) {
- fprintf(stderr, "RSA_verify failed with recovered key.\n");
- ERR_print_errors_fp(stderr);
- return 0;
- }
-
- RSA_free(key2);
- }
-
- BN_free(e);
- return 1;
-}
-
-int main(int argc, char *argv[]) {
- int err = 0;
- int v;
- RSA *key;
- unsigned char ptext[256];
- unsigned char ctext[256];
- static unsigned char ptext_ex[] = "\x54\x85\x9b\x34\x2c\x49\xea\x2a";
- unsigned char ctext_ex[256];
- int plen;
- int clen = 0;
- int num;
- int n;
-
- CRYPTO_library_init();
-
- plen = sizeof(ptext_ex) - 1;
-
- for (v = 0; v < 3; v++) {
- key = RSA_new();
- switch (v) {
- case 0:
- clen = key1(key, ctext_ex);
- break;
- case 1:
- clen = key2(key, ctext_ex);
- break;
- case 2:
- clen = key3(key, ctext_ex);
- break;
- default:
- abort();
- }
-
- if (!RSA_check_key(key)) {
- printf("%d: RSA_check_key failed\n", v);
- err = 1;
- goto oaep;
- }
-
- num = RSA_public_encrypt(plen, ptext_ex, ctext, key, RSA_PKCS1_PADDING);
- if (num != clen) {
- printf("PKCS#1 v1.5 encryption failed!\n");
- err = 1;
- goto oaep;
- }
-
- num = RSA_private_decrypt(num, ctext, ptext, key, RSA_PKCS1_PADDING);
- if (num != plen || memcmp(ptext, ptext_ex, num) != 0) {
- printf("PKCS#1 v1.5 decryption failed!\n");
- err = 1;
- } else {
- printf("PKCS #1 v1.5 encryption/decryption ok\n");
- }
-
- oaep:
- ERR_clear_error();
- num =
- RSA_public_encrypt(plen, ptext_ex, ctext, key, RSA_PKCS1_OAEP_PADDING);
- if (num == -1) {
- printf("No OAEP support\n");
- goto next;
- }
- if (num != clen) {
- printf("OAEP encryption failed!\n");
- err = 1;
- goto next;
- }
-
- num = RSA_private_decrypt(num, ctext, ptext, key, RSA_PKCS1_OAEP_PADDING);
- if (num != plen || memcmp(ptext, ptext_ex, num) != 0) {
- printf("OAEP decryption (encrypted data) failed!\n");
- err = 1;
- } else if (memcmp(ctext, ctext_ex, num) == 0) {
- printf("OAEP test vector %d passed!\n", v);
- }
-
- /* Different ciphertexts (rsa_oaep.c without -DPKCS_TESTVECT).
- Try decrypting ctext_ex */
-
- num =
- RSA_private_decrypt(clen, ctext_ex, ptext, key, RSA_PKCS1_OAEP_PADDING);
-
- if (num != plen || memcmp(ptext, ptext_ex, num) != 0) {
- printf("OAEP decryption (test vector data) failed!\n");
- err = 1;
- } else {
- printf("OAEP encryption/decryption ok\n");
- }
-
- /* Try decrypting corrupted ciphertexts */
- for (n = 0; n < clen; ++n) {
- int b;
- unsigned char saved = ctext[n];
- for (b = 0; b < 256; ++b) {
- if (b == saved) {
- continue;
- }
- ctext[n] = b;
- num =
- RSA_private_decrypt(num, ctext, ptext, key, RSA_PKCS1_OAEP_PADDING);
- if (num > 0) {
- printf("Corrupt data decrypted!\n");
- err = 1;
- }
- }
- }
-
- next:
- RSA_free(key);
- }
-
- if (err != 0 ||
- !test_only_d_given() ||
- !test_recover_crt_params() ||
- !test_bad_key()) {
- err = 1;
- }
-
- if (err == 0) {
- printf("PASS\n");
- }
- return err;
-}
diff --git a/src/crypto/rsa/rsa_test.cc b/src/crypto/rsa/rsa_test.cc
new file mode 100644
index 0000000..5545161
--- /dev/null
+++ b/src/crypto/rsa/rsa_test.cc
@@ -0,0 +1,918 @@
+/* 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.] */
+
+#include <openssl/rsa.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/bn.h>
+#include <openssl/bytestring.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/obj.h>
+
+#include "../test/scoped_types.h"
+
+
+// kPlaintext is a sample plaintext.
+static const uint8_t kPlaintext[] = "\x54\x85\x9b\x34\x2c\x49\xea\x2a";
+static const size_t kPlaintextLen = sizeof(kPlaintext) - 1;
+
+// kKey1 is a DER-encoded RSAPrivateKey.
+static const uint8_t kKey1[] =
+ "\x30\x82\x01\x38\x02\x01\x00\x02\x41\x00\xaa\x36\xab\xce\x88\xac\xfd\xff"
+ "\x55\x52\x3c\x7f\xc4\x52\x3f\x90\xef\xa0\x0d\xf3\x77\x4a\x25\x9f\x2e\x62"
+ "\xb4\xc5\xd9\x9c\xb5\xad\xb3\x00\xa0\x28\x5e\x53\x01\x93\x0e\x0c\x70\xfb"
+ "\x68\x76\x93\x9c\xe6\x16\xce\x62\x4a\x11\xe0\x08\x6d\x34\x1e\xbc\xac\xa0"
+ "\xa1\xf5\x02\x01\x11\x02\x40\x0a\x03\x37\x48\x62\x64\x87\x69\x5f\x5f\x30"
+ "\xbc\x38\xb9\x8b\x44\xc2\xcd\x2d\xff\x43\x40\x98\xcd\x20\xd8\xa1\x38\xd0"
+ "\x90\xbf\x64\x79\x7c\x3f\xa7\xa2\xcd\xcb\x3c\xd1\xe0\xbd\xba\x26\x54\xb4"
+ "\xf9\xdf\x8e\x8a\xe5\x9d\x73\x3d\x9f\x33\xb3\x01\x62\x4a\xfd\x1d\x51\x02"
+ "\x21\x00\xd8\x40\xb4\x16\x66\xb4\x2e\x92\xea\x0d\xa3\xb4\x32\x04\xb5\xcf"
+ "\xce\x33\x52\x52\x4d\x04\x16\xa5\xa4\x41\xe7\x00\xaf\x46\x12\x0d\x02\x21"
+ "\x00\xc9\x7f\xb1\xf0\x27\xf4\x53\xf6\x34\x12\x33\xea\xaa\xd1\xd9\x35\x3f"
+ "\x6c\x42\xd0\x88\x66\xb1\xd0\x5a\x0f\x20\x35\x02\x8b\x9d\x89\x02\x20\x59"
+ "\x0b\x95\x72\xa2\xc2\xa9\xc4\x06\x05\x9d\xc2\xab\x2f\x1d\xaf\xeb\x7e\x8b"
+ "\x4f\x10\xa7\x54\x9e\x8e\xed\xf5\xb4\xfc\xe0\x9e\x05\x02\x21\x00\x8e\x3c"
+ "\x05\x21\xfe\x15\xe0\xea\x06\xa3\x6f\xf0\xf1\x0c\x99\x52\xc3\x5b\x7a\x75"
+ "\x14\xfd\x32\x38\xb8\x0a\xad\x52\x98\x62\x8d\x51\x02\x20\x36\x3f\xf7\x18"
+ "\x9d\xa8\xe9\x0b\x1d\x34\x1f\x71\xd0\x9b\x76\xa8\xa9\x43\xe1\x1d\x10\xb2"
+ "\x4d\x24\x9f\x2d\xea\xfe\xf8\x0c\x18\x26";
+
+// kOAEPCiphertext1 is a sample encryption of |kPlaintext| with |kKey1| using
+// RSA OAEP.
+static const uint8_t kOAEPCiphertext1[] =
+ "\x1b\x8f\x05\xf9\xca\x1a\x79\x52\x6e\x53\xf3\xcc\x51\x4f\xdb\x89\x2b\xfb"
+ "\x91\x93\x23\x1e\x78\xb9\x92\xe6\x8d\x50\xa4\x80\xcb\x52\x33\x89\x5c\x74"
+ "\x95\x8d\x5d\x02\xab\x8c\x0f\xd0\x40\xeb\x58\x44\xb0\x05\xc3\x9e\xd8\x27"
+ "\x4a\x9d\xbf\xa8\x06\x71\x40\x94\x39\xd2";
+
+// kKey2 is a DER-encoded RSAPrivateKey.
+static const uint8_t kKey2[] =
+ "\x30\x81\xfb\x02\x01\x00\x02\x33\x00\xa3\x07\x9a\x90\xdf\x0d\xfd\x72\xac"
+ "\x09\x0c\xcc\x2a\x78\xb8\x74\x13\x13\x3e\x40\x75\x9c\x98\xfa\xf8\x20\x4f"
+ "\x35\x8a\x0b\x26\x3c\x67\x70\xe7\x83\xa9\x3b\x69\x71\xb7\x37\x79\xd2\x71"
+ "\x7b\xe8\x34\x77\xcf\x02\x01\x03\x02\x32\x6c\xaf\xbc\x60\x94\xb3\xfe\x4c"
+ "\x72\xb0\xb3\x32\xc6\xfb\x25\xa2\xb7\x62\x29\x80\x4e\x68\x65\xfc\xa4\x5a"
+ "\x74\xdf\x0f\x8f\xb8\x41\x3b\x52\xc0\xd0\xe5\x3d\x9b\x59\x0f\xf1\x9b\xe7"
+ "\x9f\x49\xdd\x21\xe5\xeb\x02\x1a\x00\xcf\x20\x35\x02\x8b\x9d\x86\x98\x40"
+ "\xb4\x16\x66\xb4\x2e\x92\xea\x0d\xa3\xb4\x32\x04\xb5\xcf\xce\x91\x02\x1a"
+ "\x00\xc9\x7f\xb1\xf0\x27\xf4\x53\xf6\x34\x12\x33\xea\xaa\xd1\xd9\x35\x3f"
+ "\x6c\x42\xd0\x88\x66\xb1\xd0\x5f\x02\x1a\x00\x8a\x15\x78\xac\x5d\x13\xaf"
+ "\x10\x2b\x22\xb9\x99\xcd\x74\x61\xf1\x5e\x6d\x22\xcc\x03\x23\xdf\xdf\x0b"
+ "\x02\x1a\x00\x86\x55\x21\x4a\xc5\x4d\x8d\x4e\xcd\x61\x77\xf1\xc7\x36\x90"
+ "\xce\x2a\x48\x2c\x8b\x05\x99\xcb\xe0\x3f\x02\x1a\x00\x83\xef\xef\xb8\xa9"
+ "\xa4\x0d\x1d\xb6\xed\x98\xad\x84\xed\x13\x35\xdc\xc1\x08\xf3\x22\xd0\x57"
+ "\xcf\x8d";
+
+// kOAEPCiphertext2 is a sample encryption of |kPlaintext| with |kKey2| using
+// RSA OAEP.
+static const uint8_t kOAEPCiphertext2[] =
+ "\x14\xbd\xdd\x28\xc9\x83\x35\x19\x23\x80\xe8\xe5\x49\xb1\x58\x2a\x8b\x40"
+ "\xb4\x48\x6d\x03\xa6\xa5\x31\x1f\x1f\xd5\xf0\xa1\x80\xe4\x17\x53\x03\x29"
+ "\xa9\x34\x90\x74\xb1\x52\x13\x54\x29\x08\x24\x52\x62\x51";
+
+// kKey3 is a DER-encoded RSAPrivateKey.
+static const uint8_t kKey3[] =
+ "\x30\x82\x02\x5b\x02\x01\x00\x02\x81\x81\x00\xbb\xf8\x2f\x09\x06\x82\xce"
+ "\x9c\x23\x38\xac\x2b\x9d\xa8\x71\xf7\x36\x8d\x07\xee\xd4\x10\x43\xa4\x40"
+ "\xd6\xb6\xf0\x74\x54\xf5\x1f\xb8\xdf\xba\xaf\x03\x5c\x02\xab\x61\xea\x48"
+ "\xce\xeb\x6f\xcd\x48\x76\xed\x52\x0d\x60\xe1\xec\x46\x19\x71\x9d\x8a\x5b"
+ "\x8b\x80\x7f\xaf\xb8\xe0\xa3\xdf\xc7\x37\x72\x3e\xe6\xb4\xb7\xd9\x3a\x25"
+ "\x84\xee\x6a\x64\x9d\x06\x09\x53\x74\x88\x34\xb2\x45\x45\x98\x39\x4e\xe0"
+ "\xaa\xb1\x2d\x7b\x61\xa5\x1f\x52\x7a\x9a\x41\xf6\xc1\x68\x7f\xe2\x53\x72"
+ "\x98\xca\x2a\x8f\x59\x46\xf8\xe5\xfd\x09\x1d\xbd\xcb\x02\x01\x11\x02\x81"
+ "\x81\x00\xa5\xda\xfc\x53\x41\xfa\xf2\x89\xc4\xb9\x88\xdb\x30\xc1\xcd\xf8"
+ "\x3f\x31\x25\x1e\x06\x68\xb4\x27\x84\x81\x38\x01\x57\x96\x41\xb2\x94\x10"
+ "\xb3\xc7\x99\x8d\x6b\xc4\x65\x74\x5e\x5c\x39\x26\x69\xd6\x87\x0d\xa2\xc0"
+ "\x82\xa9\x39\xe3\x7f\xdc\xb8\x2e\xc9\x3e\xda\xc9\x7f\xf3\xad\x59\x50\xac"
+ "\xcf\xbc\x11\x1c\x76\xf1\xa9\x52\x94\x44\xe5\x6a\xaf\x68\xc5\x6c\x09\x2c"
+ "\xd3\x8d\xc3\xbe\xf5\xd2\x0a\x93\x99\x26\xed\x4f\x74\xa1\x3e\xdd\xfb\xe1"
+ "\xa1\xce\xcc\x48\x94\xaf\x94\x28\xc2\xb7\xb8\x88\x3f\xe4\x46\x3a\x4b\xc8"
+ "\x5b\x1c\xb3\xc1\x02\x41\x00\xee\xcf\xae\x81\xb1\xb9\xb3\xc9\x08\x81\x0b"
+ "\x10\xa1\xb5\x60\x01\x99\xeb\x9f\x44\xae\xf4\xfd\xa4\x93\xb8\x1a\x9e\x3d"
+ "\x84\xf6\x32\x12\x4e\xf0\x23\x6e\x5d\x1e\x3b\x7e\x28\xfa\xe7\xaa\x04\x0a"
+ "\x2d\x5b\x25\x21\x76\x45\x9d\x1f\x39\x75\x41\xba\x2a\x58\xfb\x65\x99\x02"
+ "\x41\x00\xc9\x7f\xb1\xf0\x27\xf4\x53\xf6\x34\x12\x33\xea\xaa\xd1\xd9\x35"
+ "\x3f\x6c\x42\xd0\x88\x66\xb1\xd0\x5a\x0f\x20\x35\x02\x8b\x9d\x86\x98\x40"
+ "\xb4\x16\x66\xb4\x2e\x92\xea\x0d\xa3\xb4\x32\x04\xb5\xcf\xce\x33\x52\x52"
+ "\x4d\x04\x16\xa5\xa4\x41\xe7\x00\xaf\x46\x15\x03\x02\x40\x54\x49\x4c\xa6"
+ "\x3e\xba\x03\x37\xe4\xe2\x40\x23\xfc\xd6\x9a\x5a\xeb\x07\xdd\xdc\x01\x83"
+ "\xa4\xd0\xac\x9b\x54\xb0\x51\xf2\xb1\x3e\xd9\x49\x09\x75\xea\xb7\x74\x14"
+ "\xff\x59\xc1\xf7\x69\x2e\x9a\x2e\x20\x2b\x38\xfc\x91\x0a\x47\x41\x74\xad"
+ "\xc9\x3c\x1f\x67\xc9\x81\x02\x40\x47\x1e\x02\x90\xff\x0a\xf0\x75\x03\x51"
+ "\xb7\xf8\x78\x86\x4c\xa9\x61\xad\xbd\x3a\x8a\x7e\x99\x1c\x5c\x05\x56\xa9"
+ "\x4c\x31\x46\xa7\xf9\x80\x3f\x8f\x6f\x8a\xe3\x42\xe9\x31\xfd\x8a\xe4\x7a"
+ "\x22\x0d\x1b\x99\xa4\x95\x84\x98\x07\xfe\x39\xf9\x24\x5a\x98\x36\xda\x3d"
+ "\x02\x41\x00\xb0\x6c\x4f\xda\xbb\x63\x01\x19\x8d\x26\x5b\xdb\xae\x94\x23"
+ "\xb3\x80\xf2\x71\xf7\x34\x53\x88\x50\x93\x07\x7f\xcd\x39\xe2\x11\x9f\xc9"
+ "\x86\x32\x15\x4f\x58\x83\xb1\x67\xa9\x67\xbf\x40\x2b\x4e\x9e\x2e\x0f\x96"
+ "\x56\xe6\x98\xea\x36\x66\xed\xfb\x25\x79\x80\x39\xf7";
+
+// kOAEPCiphertext3 is a sample encryption of |kPlaintext| with |kKey3| using
+// RSA OAEP.
+static const uint8_t kOAEPCiphertext3[] =
+ "\xb8\x24\x6b\x56\xa6\xed\x58\x81\xae\xb5\x85\xd9\xa2\x5b\x2a\xd7\x90\xc4"
+ "\x17\xe0\x80\x68\x1b\xf1\xac\x2b\xc3\xde\xb6\x9d\x8b\xce\xf0\xc4\x36\x6f"
+ "\xec\x40\x0a\xf0\x52\xa7\x2e\x9b\x0e\xff\xb5\xb3\xf2\xf1\x92\xdb\xea\xca"
+ "\x03\xc1\x27\x40\x05\x71\x13\xbf\x1f\x06\x69\xac\x22\xe9\xf3\xa7\x85\x2e"
+ "\x3c\x15\xd9\x13\xca\xb0\xb8\x86\x3a\x95\xc9\x92\x94\xce\x86\x74\x21\x49"
+ "\x54\x61\x03\x46\xf4\xd4\x74\xb2\x6f\x7c\x48\xb4\x2e\xe6\x8e\x1f\x57\x2a"
+ "\x1f\xc4\x02\x6a\xc4\x56\xb4\xf5\x9f\x7b\x62\x1e\xa1\xb9\xd8\x8f\x64\x20"
+ "\x2f\xb1";
+
+static const uint8_t kTwoPrimeKey[] =
+ "\x30\x82\x04\xa1\x02\x01\x00\x02\x82\x01\x01\x00\x93\x3a\x4f\xc9\x6a\x0a"
+ "\x6b\x28\x04\xfa\xb7\x05\x56\xdf\xa0\xaa\x4f\xaa\xab\x94\xa0\xa9\x25\xef"
+ "\xc5\x96\xd2\xd4\x66\x16\x62\x2c\x13\x7b\x91\xd0\x36\x0a\x10\x11\x6d\x7a"
+ "\x91\xb6\xe4\x74\x57\xc1\x3d\x7a\xbe\x24\x05\x3a\x04\x0b\x73\x91\x53\xb1"
+ "\x74\x10\xe1\x87\xdc\x91\x28\x9c\x1e\xe5\xf2\xb9\xfc\xa2\x48\x34\xb6\x78"
+ "\xed\x6d\x95\xfb\xf2\xc0\x4e\x1c\xa4\x15\x00\x3c\x8a\x68\x2b\xd6\xce\xd5"
+ "\xb3\x9f\x66\x02\xa7\x0d\x08\xa3\x23\x9b\xe5\x36\x96\x13\x22\xf9\x69\xa6"
+ "\x87\x88\x9b\x85\x3f\x83\x9c\xab\x1a\x1b\x6d\x8d\x16\xf4\x5e\xbd\xee\x4b"
+ "\x59\x56\xf8\x9d\x58\xcd\xd2\x83\x85\x59\x43\x84\x63\x4f\xe6\x1a\x86\x66"
+ "\x0d\xb5\xa0\x87\x89\xb6\x13\x82\x43\xda\x34\x92\x3b\x68\xc4\x95\x71\x2f"
+ "\x15\xc2\xe0\x43\x67\x3c\x08\x00\x36\x10\xc3\xb4\x46\x4c\x4e\x6e\xf5\x44"
+ "\xa9\x04\x44\x9d\xce\xc7\x05\x79\xee\x11\xcf\xaf\x2c\xd7\x9a\x32\xd3\xa5"
+ "\x30\xd4\x3a\x78\x43\x37\x74\x22\x90\x24\x04\x11\xd7\x95\x08\x52\xa4\x71"
+ "\x41\x68\x94\xb0\xa0\xc3\xec\x4e\xd2\xc4\x30\x71\x98\x64\x9c\xe3\x7c\x76"
+ "\xef\x33\xa3\x2b\xb1\x87\x63\xd2\x5c\x09\xfc\x90\x2d\x92\xf4\x57\x02\x01"
+ "\x03\x02\x82\x01\x00\x62\x26\xdf\xdb\x9c\x06\xf2\x1a\xad\xfc\x7a\x03\x8f"
+ "\x3f\xc0\x71\x8a\x71\xc7\xb8\x6b\x1b\x6e\x9f\xd9\x0f\x37\x38\x44\x0e\xec"
+ "\x1d\x62\x52\x61\x35\x79\x5c\x0a\xb6\x48\xfc\x61\x24\x98\x4d\x8f\xd6\x28"
+ "\xfc\x7e\xc2\xae\x26\xad\x5c\xf7\xb6\x37\xcb\xa2\xb5\xeb\xaf\xe8\x60\xc5"
+ "\xbd\x69\xee\xa1\xd1\x53\x16\xda\xcd\xce\xfb\x48\xf3\xb9\x52\xa1\xd5\x89"
+ "\x68\x6d\x63\x55\x7d\xb1\x9a\xc7\xe4\x89\xe3\xcd\x14\xee\xac\x6f\x5e\x05"
+ "\xc2\x17\xbd\x43\x79\xb9\x62\x17\x50\xf1\x19\xaf\xb0\x67\xae\x2a\x57\xbd"
+ "\xc7\x66\xbc\xf3\xb3\x64\xa1\xe3\x16\x74\x9e\xea\x02\x5c\xab\x94\xd8\x97"
+ "\x02\x42\x0c\x2c\xba\x54\xb9\xaf\xe0\x45\x93\xad\x7f\xb3\x10\x6a\x96\x50"
+ "\x4b\xaf\xcf\xc8\x27\x62\x2d\x83\xe9\x26\xc6\x94\xc1\xef\x5c\x8e\x06\x42"
+ "\x53\xe5\x56\xaf\xc2\x99\x01\xaa\x9a\x71\xbc\xe8\x21\x33\x2a\x2d\xa3\x36"
+ "\xac\x1b\x86\x19\xf8\xcd\x1f\x80\xa4\x26\x98\xb8\x9f\x62\x62\xd5\x1a\x7f"
+ "\xee\xdb\xdf\x81\xd3\x21\xdb\x33\x92\xee\xff\xe2\x2f\x32\x77\x73\x6a\x58"
+ "\xab\x21\xf3\xe3\xe1\xbc\x4f\x12\x72\xa6\xb5\xc2\xfb\x27\x9e\xc8\xca\xab"
+ "\x64\xa0\x87\x07\x9d\xef\xca\x0f\xdb\x02\x81\x81\x00\xe6\xd3\x4d\xc0\xa1"
+ "\x91\x0e\x62\xfd\xb0\xdd\xc6\x30\xb8\x8c\xcb\x14\xc1\x4b\x69\x30\xdd\xcd"
+ "\x86\x67\xcb\x37\x14\xc5\x03\xd2\xb4\x69\xab\x3d\xe5\x16\x81\x0f\xe5\x50"
+ "\xf4\x18\xb1\xec\xbc\x71\xe9\x80\x99\x06\xe4\xa3\xfe\x44\x84\x4a\x2d\x1e"
+ "\x07\x7f\x22\x70\x6d\x4f\xd4\x93\x0b\x8b\x99\xce\x1e\xab\xcd\x4c\xd2\xd3"
+ "\x10\x47\x5c\x09\x9f\x6d\x82\xc0\x08\x75\xe3\x3d\x83\xc2\x19\x50\x29\xec"
+ "\x1f\x84\x29\xcc\xf1\x56\xee\xbd\x54\x5d\xe6\x19\xdf\x0d\x1c\xa4\xbb\x0a"
+ "\xfe\x84\x44\x29\x1d\xf9\x5c\x80\x96\x5b\x24\xb4\xf7\x02\x1b\x02\x81\x81"
+ "\x00\xa3\x48\xf1\x9c\x58\xc2\x5f\x38\xfb\xd8\x12\x39\xf1\x8e\x73\xa1\xcf"
+ "\x78\x12\xe0\xed\x2a\xbb\xef\xac\x23\xb2\xbf\xd6\x0c\xe9\x6e\x1e\xab\xea"
+ "\x3f\x68\x36\xa7\x1f\xe5\xab\xe0\x86\xa5\x76\x32\x98\xdd\x75\xb5\x2b\xbc"
+ "\xcb\x8a\x03\x00\x7c\x2e\xca\xf8\xbc\x19\xe4\xe3\xa3\x31\xbd\x1d\x20\x2b"
+ "\x09\xad\x6f\x4c\xed\x48\xd4\xdf\x87\xf9\xf0\x46\xb9\x86\x4c\x4b\x71\xe7"
+ "\x48\x78\xdc\xed\xc7\x82\x02\x44\xd3\xa6\xb3\x10\x5f\x62\x81\xfc\xb8\xe4"
+ "\x0e\xf4\x1a\xdd\xab\x3f\xbc\x63\x79\x5b\x39\x69\x5e\xea\xa9\x15\xfe\x90"
+ "\xec\xda\x75\x02\x81\x81\x00\x99\xe2\x33\xd5\xc1\x0b\x5e\xec\xa9\x20\x93"
+ "\xd9\x75\xd0\x5d\xdc\xb8\x80\xdc\xf0\xcb\x3e\x89\x04\x45\x32\x24\xb8\x83"
+ "\x57\xe1\xcd\x9b\xc7\x7e\x98\xb9\xab\x5f\xee\x35\xf8\x10\x76\x9d\xd2\xf6"
+ "\x9b\xab\x10\xaf\x43\x17\xfe\xd8\x58\x31\x73\x69\x5a\x54\xc1\xa0\x48\xdf"
+ "\xe3\x0c\xb2\x5d\x11\x34\x14\x72\x88\xdd\xe1\xe2\x0a\xda\x3d\x5b\xbf\x9e"
+ "\x57\x2a\xb0\x4e\x97\x7e\x57\xd6\xbb\x8a\xc6\x9d\x6a\x58\x1b\xdd\xf6\x39"
+ "\xf4\x7e\x38\x3e\x99\x66\x94\xb3\x68\x6d\xd2\x07\x54\x58\x2d\x70\xbe\xa6"
+ "\x3d\xab\x0e\xe7\x6d\xcd\xfa\x01\x67\x02\x81\x80\x6c\xdb\x4b\xbd\x90\x81"
+ "\x94\xd0\xa7\xe5\x61\x7b\xf6\x5e\xf7\xc1\x34\xfa\xb7\x40\x9e\x1c\x7d\x4a"
+ "\x72\xc2\x77\x2a\x8e\xb3\x46\x49\x69\xc7\xf1\x7f\x9a\xcf\x1a\x15\x43\xc7"
+ "\xeb\x04\x6e\x4e\xcc\x65\xe8\xf9\x23\x72\x7d\xdd\x06\xac\xaa\xfd\x74\x87"
+ "\x50\x7d\x66\x98\x97\xc2\x21\x28\xbe\x15\x72\x06\x73\x9f\x88\x9e\x30\x8d"
+ "\xea\x5a\xa6\xa0\x2f\x26\x59\x88\x32\x4b\xef\x85\xa5\xe8\x9e\x85\x01\x56"
+ "\xd8\x8d\x19\xcc\xb5\x94\xec\x56\xa8\x7b\x42\xb4\xa2\xbc\x93\xc7\x7f\xd2"
+ "\xec\xfb\x92\x26\x46\x3f\x47\x1b\x63\xff\x0b\x48\x91\xa3\x02\x81\x80\x2c"
+ "\x4a\xb9\xa4\x46\x7b\xff\x50\x7e\xbf\x60\x47\x3b\x2b\x66\x82\xdc\x0e\x53"
+ "\x65\x71\xe9\xda\x2a\xb8\x32\x93\x42\xb7\xff\xea\x67\x66\xf1\xbc\x87\x28"
+ "\x65\x29\x79\xca\xab\x93\x56\xda\x95\xc1\x26\x44\x3d\x27\xc1\x91\xc6\x9b"
+ "\xd9\xec\x9d\xb7\x49\xe7\x16\xee\x99\x87\x50\x95\x81\xd4\x5c\x5b\x5a\x5d"
+ "\x0a\x43\xa5\xa7\x8f\x5a\x80\x49\xa0\xb7\x10\x85\xc7\xf4\x42\x34\x86\xb6"
+ "\x5f\x3f\x88\x9e\xc7\xf5\x59\x29\x39\x68\x48\xf2\xd7\x08\x5b\x92\x8e\x6b"
+ "\xea\xa5\x63\x5f\xc0\xfb\xe4\xe1\xb2\x7d\xb7\x40\xe9\x55\x06\xbf\x58\x25"
+ "\x6f";
+
+static const uint8_t kTwoPrimeEncryptedMessage[] = {
+ 0x63, 0x0a, 0x30, 0x45, 0x43, 0x11, 0x45, 0xb7, 0x99, 0x67, 0x90, 0x35,
+ 0x37, 0x27, 0xff, 0xbc, 0xe0, 0xbf, 0xa6, 0xd1, 0x47, 0x50, 0xbb, 0x6c,
+ 0x1c, 0xaa, 0x66, 0xf2, 0xff, 0x9d, 0x9a, 0xa6, 0xb4, 0x16, 0x63, 0xb0,
+ 0xa1, 0x7c, 0x7c, 0x0c, 0xef, 0xb3, 0x66, 0x52, 0x42, 0xd7, 0x5e, 0xf3,
+ 0xa4, 0x15, 0x33, 0x40, 0x43, 0xe8, 0xb1, 0xfc, 0xe0, 0x42, 0x83, 0x46,
+ 0x28, 0xce, 0xde, 0x7b, 0x01, 0xeb, 0x28, 0x92, 0x70, 0xdf, 0x8d, 0x54,
+ 0x9e, 0xed, 0x23, 0xb4, 0x78, 0xc3, 0xca, 0x85, 0x53, 0x48, 0xd6, 0x8a,
+ 0x87, 0xf7, 0x69, 0xcd, 0x82, 0x8c, 0x4f, 0x5c, 0x05, 0x55, 0xa6, 0x78,
+ 0x89, 0xab, 0x4c, 0xd8, 0xa9, 0xd6, 0xa5, 0xf4, 0x29, 0x4c, 0x23, 0xc8,
+ 0xcf, 0xf0, 0x4c, 0x64, 0x6b, 0x4e, 0x02, 0x17, 0x69, 0xd6, 0x47, 0x83,
+ 0x30, 0x43, 0x02, 0x29, 0xda, 0xda, 0x75, 0x3b, 0xd7, 0xa7, 0x2b, 0x31,
+ 0xb3, 0xe9, 0x71, 0xa4, 0x41, 0xf7, 0x26, 0x9b, 0xcd, 0x23, 0xfa, 0x45,
+ 0x3c, 0x9b, 0x7d, 0x28, 0xf7, 0xf9, 0x67, 0x04, 0xba, 0xfc, 0x46, 0x75,
+ 0x11, 0x3c, 0xd5, 0x27, 0x43, 0x53, 0xb1, 0xb6, 0x9e, 0x18, 0xeb, 0x11,
+ 0xb4, 0x25, 0x20, 0x30, 0x0b, 0xe0, 0x1c, 0x17, 0x36, 0x22, 0x10, 0x0f,
+ 0x99, 0xb5, 0x50, 0x14, 0x73, 0x07, 0xf0, 0x2f, 0x5d, 0x4c, 0xe3, 0xf2,
+ 0x86, 0xc2, 0x05, 0xc8, 0x38, 0xed, 0xeb, 0x2a, 0x4a, 0xab, 0x76, 0xe3,
+ 0x1a, 0x75, 0x44, 0xf7, 0x6e, 0x94, 0xdc, 0x25, 0x62, 0x7e, 0x31, 0xca,
+ 0xc2, 0x73, 0x51, 0xb5, 0x03, 0xfb, 0xf9, 0xf6, 0xb5, 0x8d, 0x4e, 0x6c,
+ 0x21, 0x0e, 0xf9, 0x97, 0x26, 0x57, 0xf3, 0x52, 0x72, 0x07, 0xf8, 0xb4,
+ 0xcd, 0xb4, 0x39, 0xcf, 0xbf, 0x78, 0xcc, 0xb6, 0x87, 0xf9, 0xb7, 0x8b,
+ 0x6a, 0xce, 0x9f, 0xc8,
+};
+
+static const uint8_t kThreePrimeKey[] =
+ "\x30\x82\x04\xd7\x02\x01\x01\x02\x82\x01\x00\x62\x91\xe9\xea\xb3\x5d\x6c"
+ "\x29\xae\x21\x83\xbb\xb5\x82\xb1\x9e\xea\xe0\x64\x5b\x1e\x2f\x5e\x2c\x0a"
+ "\x80\x3d\x29\xd4\xfa\x9a\xe7\x44\xe6\x21\xbd\x98\xc0\x3d\xe0\x53\x59\xae"
+ "\xd3\x3e\xfe\xc4\xc2\xc4\x5a\x5a\x89\x07\xf4\x4f\xdc\xb0\x6a\xd4\x3e\x99"
+ "\x7d\x7a\x97\x26\x4e\xe1\x93\xca\x6e\xed\x07\xfc\xb4\xfa\x95\x1e\x73\x7b"
+ "\x86\x08\x6a\xb9\xd4\x29\xb0\x7e\x59\xb7\x9d\x7b\xeb\x67\x6e\xf0\xbb\x5e"
+ "\xcf\xb9\xcd\x58\x93\xf0\xe7\x88\x17\x6c\x0d\x76\x1e\xb9\x27\x9a\x4d\x02"
+ "\x16\xb6\x49\x6d\xa7\x83\x23\x4d\x02\x48\x0c\x0c\x1f\x0e\x85\x21\xe3\x06"
+ "\x76\x0a\x73\xe6\xc1\x21\xfa\x30\x18\x78\x29\x5c\x31\xd0\x29\xae\x6f\x7d"
+ "\x87\xd8\x2f\x16\xfa\xbc\x67\x8a\x94\x71\x59\x9b\xec\x22\x40\x55\x9f\xc2"
+ "\x94\xb5\xbd\x78\x01\xc9\xef\x18\xc8\x6d\x0d\xdc\x53\x42\xb2\x5c\xab\x65"
+ "\x05\xbd\x35\x08\x85\x1b\xf8\xe9\x47\xbc\xfe\xc5\xae\x47\x29\x63\x44\x8e"
+ "\x4d\xb7\x47\xab\x0d\xd8\x76\x68\x4f\xc7\x07\x02\xe4\x86\xb0\xcf\xd8\x19"
+ "\xad\xf4\x85\x76\x8b\x3b\x4e\x40\x8d\x29\x7a\x8a\x07\x36\xf3\x78\xae\x17"
+ "\xa6\x8f\x53\x58\x65\x4c\x86\x9e\xd7\x8b\xec\x38\x4f\x99\xc7\x02\x01\x03"
+ "\x02\x82\x01\x00\x41\xb6\x9b\xf1\xcc\xe8\xf2\xc6\x74\x16\x57\xd2\x79\x01"
+ "\xcb\xbf\x47\x40\x42\xe7\x69\x74\xe9\x72\xb1\xaa\xd3\x71\x38\xa7\x11\xef"
+ "\x83\x44\x16\x7e\x65\xd5\x7e\x95\x8c\xe6\x74\x8c\xd4\xa9\xd8\x81\xd8\x3c"
+ "\x3c\x5b\x5a\xa2\xdf\xe8\x75\x9c\x8d\x7f\x10\xfe\x51\xba\x19\x89\xeb\xb7"
+ "\xdc\x49\xf3\x5a\xa8\x78\xa7\x0e\x14\x4c\xfd\x04\x05\x9c\x7b\xe2\xc5\xa3"
+ "\x04\xee\xd9\x4c\xfd\x7d\x47\xb0\x0d\x9b\x3d\x70\x91\x81\x2c\xab\x2b\x87"
+ "\xad\x11\x68\x24\xfc\x2b\xd4\xee\x5e\x28\xeb\x6d\xab\xde\x0f\x77\x15\x58"
+ "\x76\x39\xc9\x59\x3a\x7f\x19\x9d\xc6\x7e\x86\xe4\xd5\x38\x70\x9e\xae\xb9"
+ "\xfb\x33\x33\xd1\x0c\x2d\xab\x01\x20\xe1\x8b\x29\x99\xd3\xeb\x87\x05\x72"
+ "\xaa\x43\x58\x64\x8e\x9e\x31\xdb\x45\x9b\x2b\xac\x58\x80\x5d\x33\xa2\x43"
+ "\x05\x96\xcc\xca\x2d\x04\x5f\xd6\xb7\x3d\x8b\x8f\x2d\xa3\xa5\xf8\x73\xf5"
+ "\xd7\xc0\x19\xff\x10\xe6\xee\x3a\x26\x2f\xe1\x64\x3d\x11\xcd\x2d\xe4\x0a"
+ "\x84\x27\xe3\xcb\x16\x62\x19\xe7\xe3\x0d\x13\xe8\x09\x5a\x53\xd0\x20\x56"
+ "\x15\xf5\xb3\x67\xac\xa1\xb5\x94\x6b\xab\xdc\x71\xc7\xbf\x0a\xde\x76\xf5"
+ "\x03\xa0\x30\xd8\x27\x9d\x00\x2b\x02\x57\x00\xf1\x4f\xc2\x86\x13\x06\x17"
+ "\xf7\x69\x7e\x37\xdf\x67\xc5\x32\xa0\x74\x1c\x32\x69\x0f\x9f\x08\x88\x24"
+ "\xb1\x51\xbc\xbc\x92\xba\x73\x1f\x9c\x75\xc2\x14\x6d\x4f\xc4\x5a\xcf\xda"
+ "\x44\x35\x00\x6b\x42\x3b\x9f\x14\xf1\x05\xb3\x51\x22\xb6\xbe\x9c\xe0\xc1"
+ "\x5c\x48\x61\xdf\x4e\x4c\x72\xb8\x05\x35\x7c\xac\xf1\xbb\xa0\x3b\x2a\xea"
+ "\xf7\x86\xe9\xd2\xff\x1e\x1d\x02\x56\x00\xca\xb1\x39\xf6\xa2\xc6\x3b\x65"
+ "\x45\x2f\x39\x00\xcd\x6e\xd6\x55\xf7\x71\x37\x89\xc2\xe7\x7a\xc0\x1a\xa6"
+ "\x2f\xea\x17\x7c\xaa\x2a\x91\x8f\xd4\xc7\x50\x8b\xab\x8e\x99\x3b\x33\x91"
+ "\xbc\x02\x10\x58\x4b\x58\x40\x9b\xc4\x8f\x48\x2b\xa7\x44\xfd\x07\x04\xf0"
+ "\x98\x67\x56\xea\x25\x92\x8b\x2e\x4b\x4a\xa1\xd3\xc2\xa4\xb4\x9b\x59\x70"
+ "\x32\xa6\xd8\x8b\xd9\x02\x57\x00\xa0\xdf\xd7\x04\x0c\xae\xba\xa4\xf0\xfe"
+ "\xcf\xea\x45\x2e\x21\xc0\x4d\x68\x21\x9b\x5f\xbf\x5b\x05\x6d\xcb\x8b\xd3"
+ "\x28\x61\xd1\xa2\x15\x12\xf9\x2c\x0d\x9e\x35\x2d\x91\xdf\xe6\xd8\x23\x55"
+ "\x9c\xd6\xd2\x6a\x0d\xf6\x03\xcc\xe0\xc1\xcf\x29\xbd\xeb\x2b\x92\xda\xeb"
+ "\xea\x34\x32\xf7\x25\x58\xce\x53\x1d\xf6\x7d\x15\x7c\xc7\x47\x4f\xaf\x46"
+ "\x8c\xaa\x14\x13\x02\x56\x00\x87\x20\xd1\x4f\x17\x2e\xd2\x43\x83\x74\xd0"
+ "\xab\x33\x9f\x39\x8e\xa4\xf6\x25\x06\x81\xef\xa7\x2a\xbc\x6e\xca\x9c\x0f"
+ "\xa8\x71\x71\xb6\x5f\xe3\x2f\x8b\x07\xc7\xb4\x66\x27\x77\xb6\x7d\x56\xb5"
+ "\x90\x32\x3a\xd5\xbd\x2d\xb4\xda\xc7\xc4\xd8\xa8\xaf\x58\xa0\x65\x9a\x39"
+ "\xf1\x6e\x61\xb2\x1e\xdc\xdc\x6b\xe2\x81\xc3\x23\x12\x3b\xa0\x21\xc4\x90"
+ "\x5d\x3b\x02\x57\x00\xe6\x8a\xaa\xb8\x6d\x2c\x81\x43\xb5\xd6\xa0\x2b\x42"
+ "\x49\xa9\x0a\x51\xfa\x18\xc8\x32\xea\x54\x18\xf3\x60\xc2\xb5\x4a\x43\x05"
+ "\x93\x9c\x01\xd9\x28\xed\x73\xfa\x82\xbc\x12\x64\xcb\xc4\x24\xa9\x3e\xae"
+ "\x7c\x4b\x8f\x94\x57\x7b\x14\x10\x41\xdc\x62\x12\x8c\xb2\x4a\x7c\xf6\x53"
+ "\xd4\xc6\xe4\xda\xd1\xa2\x00\x0e\x3d\x30\xf7\x05\x4f\x1d\x82\xbc\x52\xd9"
+ "\xb1\x30\x82\x01\x0a\x30\x82\x01\x06\x02\x56\x00\x84\x12\x4f\xf7\x3b\x65"
+ "\x53\x34\x6c\x6c\x4d\x77\xdf\xfd\x1f\xb6\x16\xe2\x25\x15\xca\xc9\xc1\x41"
+ "\x9a\x50\xda\xeb\x88\x4f\x3d\xb3\x01\x00\x44\xc4\xac\xe7\x14\x62\xa6\x56"
+ "\xde\xc5\xb7\xc3\x1d\x07\xbd\x7d\x64\xc5\x7e\x45\x25\x56\xed\x7a\xd2\x14"
+ "\xdb\x4e\x27\xd4\x1f\xf8\x94\xa7\xef\x07\xce\xdb\x24\xb7\xdd\x71\x5c\x63"
+ "\xc9\x33\xfe\xde\x40\x52\xeb\x02\x55\x58\x0c\x35\x4f\x7c\xee\x37\x78\x48"
+ "\x48\x33\xa5\x3f\xfe\x15\x24\x0f\x41\x6e\x0e\x87\x31\x2b\x81\x11\x8b\x3c"
+ "\x9d\x05\x8a\x29\x22\x00\xaa\xd8\x83\x1d\xef\x62\xec\x6e\xe4\x94\x83\xcf"
+ "\xd7\x68\xaf\xd3\xa8\xed\xd8\xfe\xd8\xc3\x8f\x48\xfc\x8c\x0d\xe7\x89\x6f"
+ "\xe2\xbf\xfb\x0d\xc5\x4a\x05\x34\x92\x18\x7a\x93\xa0\xe8\x42\x86\x22\xa9"
+ "\xe9\x80\x37\x47\x02\x55\x60\x76\xab\xde\x2b\xf5\xa2\x2c\xaa\x0c\x99\x81"
+ "\xee\x72\x2c\x7d\x22\x59\x2a\x35\xea\x50\x4e\x47\x6b\x92\x2d\x30\xa1\x01"
+ "\xa5\x9e\x26\x6e\x27\xca\xf5\xf2\x87\x5d\x31\xaf\xe9\x32\xcd\x10\xfd\x4d"
+ "\xdb\xf9\x86\x05\x12\x1b\x01\x84\x55\x97\x5f\xe2\x78\x27\xd9\xe4\x26\x7d"
+ "\xab\x0e\xe0\x1b\x6f\xcb\x4b\x14\xdd\xdc\xdc\x8b\xe8\x9f\xd0\x62\x96\xca"
+ "\xcf";
+
+static const uint8_t kThreePrimeEncryptedMessage[] = {
+ 0x58, 0xd9, 0xea, 0x8a, 0xf6, 0x3d, 0xb4, 0xd9, 0xf7, 0xbb, 0x02, 0xc5,
+ 0x58, 0xd2, 0xa9, 0x46, 0x80, 0x70, 0x70, 0x16, 0x07, 0x64, 0x32, 0x4c,
+ 0x4e, 0x92, 0x61, 0xb7, 0xff, 0x92, 0xdc, 0xfc, 0xf8, 0xf0, 0x2c, 0x84,
+ 0x56, 0xbc, 0xe5, 0x93, 0x76, 0xe5, 0xa3, 0x72, 0x98, 0xf2, 0xdf, 0xef,
+ 0x99, 0x53, 0xf6, 0xd8, 0x4b, 0x09, 0xac, 0xa9, 0xa3, 0xdb, 0x63, 0xa1,
+ 0xb5, 0x09, 0x8e, 0x40, 0x84, 0x8f, 0x4d, 0xd5, 0x1d, 0xac, 0x6c, 0xaa,
+ 0x6b, 0x15, 0xe7, 0xb1, 0x0c, 0x67, 0xd2, 0xb2, 0x81, 0x58, 0x30, 0x0e,
+ 0x18, 0x27, 0xa1, 0x9b, 0x96, 0xad, 0xae, 0x76, 0x1a, 0x32, 0xf7, 0x10,
+ 0x0b, 0x53, 0x85, 0x31, 0xd6, 0x2a, 0xf6, 0x1c, 0x9f, 0xc2, 0xc7, 0xb1,
+ 0x05, 0x63, 0x0b, 0xa5, 0x07, 0x1f, 0x1c, 0x01, 0xf0, 0xe0, 0x06, 0xea,
+ 0x20, 0x69, 0x41, 0x19, 0x57, 0x92, 0x17, 0xf7, 0x0c, 0x5c, 0x66, 0x75,
+ 0x0e, 0xe5, 0xb3, 0xf1, 0x67, 0x3b, 0x27, 0x47, 0xb2, 0x8e, 0x1c, 0xb6,
+ 0x3f, 0xdd, 0x76, 0x42, 0x31, 0x13, 0x68, 0x96, 0xdf, 0x3b, 0xd4, 0x87,
+ 0xd9, 0x16, 0x44, 0x71, 0x52, 0x2e, 0x54, 0x3e, 0x09, 0xcd, 0x71, 0xc1,
+ 0x1e, 0x5e, 0x96, 0x13, 0xc9, 0x1e, 0xa4, 0xe6, 0xe6, 0x97, 0x2c, 0x6b,
+ 0xf2, 0xa9, 0x5c, 0xc6, 0x60, 0x2a, 0xbc, 0x82, 0xf8, 0xcb, 0xd4, 0xd7,
+ 0xea, 0x8a, 0xa1, 0x8a, 0xd9, 0xa5, 0x14, 0x8b, 0x9e, 0xf9, 0x25, 0x02,
+ 0xd2, 0xab, 0x0c, 0x42, 0xca, 0x2d, 0x45, 0xa3, 0x56, 0x5e, 0xa2, 0x2a,
+ 0xc8, 0x60, 0xa5, 0x87, 0x5d, 0x85, 0x5c, 0xde, 0xc7, 0xa2, 0x47, 0xc3,
+ 0x99, 0x29, 0x23, 0x79, 0x36, 0x88, 0xad, 0x40, 0x3e, 0x27, 0x7d, 0xf0,
+ 0xb6, 0xfa, 0x95, 0x20, 0x3c, 0xec, 0xfc, 0x56, 0x3b, 0x20, 0x91, 0xee,
+ 0x98, 0x10, 0x2c, 0x82,
+};
+
+static const uint8_t kSixPrimeKey[] =
+ "\x30\x82\x05\x20\x02\x01\x01\x02\x82\x01\x00\x1c\x04\x39\x44\xb9\xb8\x71"
+ "\x1c\x1c\xf7\xdc\x11\x1b\x85\x3b\x2b\xe8\xa6\xeb\xeb\xe9\xb6\x86\x97\x73"
+ "\x5d\x75\x46\xd1\x35\x25\xf8\x30\x9a\xc3\x57\x44\x89\xa6\x44\x59\xe3\x3a"
+ "\x60\xb5\x33\x84\x72\xa4\x03\xc5\x1a\x20\x98\x70\xbd\xe8\x3b\xc1\x9b\x8a"
+ "\x3a\x24\x45\xb6\x6a\x73\xb4\xd0\x6c\x18\xc6\xa7\x94\xd3\x24\x70\xf0\x2d"
+ "\x0c\xa5\xb2\x3b\xc5\x33\x90\x9d\x56\x8d\x33\xf6\x93\x7d\xa7\x95\x88\x05"
+ "\xdf\xf5\x65\x58\xb9\x5b\xd3\x07\x9c\x16\x8e\x74\xfc\xb8\x76\xaf\x62\x99"
+ "\x6c\xd4\xc5\xb3\x69\xe5\x64\xdf\x38\x00\x25\x24\xe9\xb1\x4a\x85\xa6\xf4"
+ "\xb6\x23\x68\x67\x4a\x2c\xbd\x9d\x01\x3b\x04\x8c\x70\x94\x82\x76\x45\x0c"
+ "\x8b\x95\x8a\x07\x1c\x32\xe7\x09\x97\x3a\xfd\xca\x57\xe9\x57\x0c\xae\x2b"
+ "\xa3\x25\xd1\xf2\x0d\x34\xa1\xe6\x2f\x7b\x1b\x36\x53\x83\x95\xb9\x26\x6e"
+ "\x4f\x36\x26\xf8\x47\xae\xdf\xe8\x4d\xf6\xb2\xff\x03\x23\x74\xfa\xa5\x6d"
+ "\xcb\xcb\x80\x12\xc3\x77\xf0\x19\xb7\xf2\x6b\x19\x5c\xde\x0a\xd7\xee\x8c"
+ "\x48\x2f\x50\x24\xa5\x2e\xcc\x2a\xed\xc2\x35\xe0\x3d\x29\x31\x17\xd6\x8f"
+ "\x44\xaa\x5b\x33\xbd\xb4\x88\x87\xd9\x29\x3f\x94\xe7\x75\xe3\x02\x01\x03"
+ "\x02\x82\x01\x00\x12\xad\x7b\x83\x26\x7a\xf6\x12\xbd\xfa\x92\xb6\x12\x58"
+ "\xd2\x1d\x45\xc4\x9d\x47\xf1\x24\x59\xba\x4c\xe8\xf8\xd9\xe0\xce\x19\x50"
+ "\x20\x67\x2c\xe4\xd8\x5b\xc4\x2d\x91\x41\xeb\x05\x4f\xf4\xb4\x20\xc7\xbc"
+ "\xd6\xe2\x5c\xa0\x27\xcf\xb8\xb3\x3b\x5c\xeb\x5e\x96\xb7\x99\x4b\x8a\xc3"
+ "\x70\xaf\x7f\xd8\x5f\xeb\xcb\x1a\x79\x44\x68\x97\x84\xd8\x29\x87\x64\xba"
+ "\x18\x2e\x95\x66\x1a\x7d\xd9\x35\x3a\x5c\x92\x7a\x81\x1b\x6c\xa9\xf8\xfa"
+ "\x05\x23\x18\x5b\xb2\xf8\x77\x1c\xc5\x1b\x7d\x26\x5f\x48\x69\x1b\xc4\x34"
+ "\xef\x6e\xa1\x15\xd2\xb2\xac\xb8\xa8\xed\x1e\xee\xdc\xb5\xb9\x5c\x79\x25"
+ "\x48\xbb\xe5\x9d\xd8\xe5\xe2\x94\xdf\xd5\x32\x22\x84\xbf\xc2\xaa\xa4\x54"
+ "\xbb\x29\xdb\x13\x4a\x28\x3d\x83\x3a\xff\xa3\xae\x38\x08\xfc\x36\x84\x91"
+ "\x30\xd1\xfd\x82\x64\xf1\x0f\xae\xba\xd7\x9a\x43\x58\x03\x5e\x5f\x01\xcb"
+ "\x8b\x90\x8d\x77\x34\x6f\x37\x40\xb6\x6d\x22\x23\x90\xb2\xfd\x32\xb5\x96"
+ "\x45\xbf\xae\x8c\xc4\x62\x03\x6c\x68\x90\x59\x31\x1a\xcb\xfb\xa4\x0b\x94"
+ "\x15\x13\xda\x1a\x8d\xa7\x0b\x34\x62\x93\xea\xbe\x6e\x71\xc2\x1d\xc8\x9d"
+ "\xac\x66\xcc\x31\x87\xff\x99\xab\x02\x2c\x00\xa5\x57\x41\x66\x87\x68\x02"
+ "\x6a\xdf\x97\xb0\xfe\x6b\x34\xc4\x33\x88\x2b\xce\x82\xaf\x2d\x33\x5a\xad"
+ "\x75\x2d\xac\xa5\xd6\x3a\x2d\x65\x43\x68\xfb\x44\x9e\xb8\x25\x05\xed\x97"
+ "\x02\x2c\x00\xd2\x77\x34\x24\xac\x60\x9a\xc4\x68\x34\xe5\x6a\xa3\xdc\xe2"
+ "\xb0\x58\x5c\x35\x83\x5a\xc7\xa7\xc1\x0b\x7e\x9e\xa5\x85\x32\x47\x93\x22"
+ "\xee\xb6\x59\xe9\xe3\x61\x94\xd0\x0e\xcb\x02\x2b\x6e\x3a\x2b\x99\xaf\x9a"
+ "\xac\x47\x3f\xba\x75\xfe\xf2\x23\x2d\x77\xb0\x1d\x34\x57\x1f\x73\x77\x91"
+ "\xc8\xf8\xc9\x1d\xc3\xe4\x26\xc8\xee\x2c\xf0\xa7\x83\x14\x7a\xc3\x59\x49"
+ "\x0f\x02\x2c\x00\x8c\x4f\x78\x18\x72\xeb\x11\xd8\x45\x78\x98\xf1\xc2\x93"
+ "\x41\xca\xe5\x92\xce\x57\x91\xda\x6f\xd6\x07\xa9\xbf\x19\x03\x76\xda\x62"
+ "\x17\x49\xce\xe6\x9b\xec\xeb\xb8\x8a\xb4\x87\x02\x2c\x00\xa3\xc2\x29\xa6"
+ "\xa7\xe1\x3c\xe9\xcf\x0f\x50\x51\x1c\xcc\xc8\x5b\x08\x9c\x97\x24\x3a\x86"
+ "\x23\xa8\x0b\xbb\x54\xa6\xb9\x70\x3d\x1d\xd0\x1b\xa3\xac\xd9\xb2\x03\x80"
+ "\xd7\x67\xec\x30\x82\x02\x29\x30\x81\x88\x02\x2c\x00\x97\x5d\x3b\xf2\xcc"
+ "\xba\xd9\x77\x67\xaa\xd2\x22\xa7\xa3\x49\x08\xc7\xb8\x27\xa1\x59\x4b\xa7"
+ "\xa5\xd2\x74\x05\xe7\x5a\x35\xd7\x25\x79\x18\x20\x8a\x25\xec\x3b\x52\xaf"
+ "\xcb\xdb\x02\x2b\x64\xe8\xd2\xa1\xdd\xd1\xe6\x4f\x9a\x71\xe1\x6c\x6f\xc2"
+ "\x30\xb0\x85\x25\x6f\xc0\xe6\x32\x6f\xc3\xe1\xa2\xae\x9a\x3c\x23\xe4\xc3"
+ "\xa6\x10\x15\xb1\x6e\x9d\x7c\xe1\xca\x87\xe7\x02\x2b\x5e\xef\x25\x29\xed"
+ "\xf6\x52\x15\xd3\x60\xb6\x88\xcf\x0f\xe2\x24\xa4\x04\x97\x9c\x9d\x58\x13"
+ "\xbb\x00\x6d\x39\xf6\xad\x21\x7e\x56\x2c\x2e\x06\x06\xc4\x6d\x44\xac\x79"
+ "\x1f\xe5\x30\x81\x89\x02\x2c\x00\xdb\xf1\x78\xf9\xa4\x94\xea\x39\x8a\x3f"
+ "\x23\x48\x2a\x23\x8f\xd2\x18\x97\xd2\xdf\x0f\xb8\x2b\x33\xa0\xe8\x8f\xbc"
+ "\x4e\x42\xfd\x54\xc7\x0f\xde\xba\x6d\xba\x96\xa7\xce\x67\x3d\x02\x2c\x00"
+ "\x92\xa0\xfb\x51\x18\x63\x46\xd1\x06\xd4\xc2\x30\x1c\x17\xb5\x36\xbb\x0f"
+ "\xe1\xea\x0a\x7a\xc7\x77\xc0\x9b\x0a\x7d\x89\x81\xfe\x38\x84\xb5\x3f\x26"
+ "\xf3\xd1\xb9\xc5\x34\x44\xd3\x02\x2b\x4c\xbd\x1d\x44\xc8\x19\x23\xd8\xb3"
+ "\x96\x66\x4b\x62\xcb\x3e\xe6\x6c\x11\xdf\xb2\x92\xd3\xc8\x34\xb9\xa6\x5a"
+ "\x2f\x19\xf4\x0b\xb2\xe6\x8e\xa6\xaf\xa3\xae\xa4\xb3\x92\xc4\x79\x30\x81"
+ "\x85\x02\x2b\x00\x89\xab\x30\xfc\x7b\x37\x94\x11\x9f\x4d\x31\x3b\xac\x09"
+ "\x57\xe6\x64\xec\xa0\xc8\xf8\x04\x1a\xf9\x2a\xa4\x4b\x36\x18\xbb\x5f\xdc"
+ "\xcd\xf0\xc8\xcb\x97\xd1\xdf\x13\x12\x3f\x02\x2a\x5b\xc7\x75\xfd\xa7\x7a"
+ "\x62\xb6\x6a\x33\x76\x27\xc8\x06\x3a\x99\x98\x9d\xc0\x85\xfa\xad\x67\x50"
+ "\xc7\x18\x32\x24\x10\x7c\xea\x93\x33\xf5\xdb\x32\x65\x36\x94\xb7\x61\x7f"
+ "\x02\x2a\x16\x6c\x96\xa1\x50\x6f\x3a\x92\xc0\x75\x43\xb5\x6b\x9c\x17\x09"
+ "\xd3\xf0\x67\x69\x45\x92\xfb\x7b\x50\xa8\x42\x9b\x33\x92\xab\xd5\xe6\x49"
+ "\xb3\x26\x99\x55\x16\x3a\x39\x63\x30\x81\x87\x02\x2b\x00\xc1\x25\x19\x1d"
+ "\x6e\x18\xcb\x2d\x64\xe2\xe6\xb6\x1c\xe4\xaa\x9c\xb9\xee\x18\xd4\xf7\x5f"
+ "\x66\x40\xf0\xe1\x31\x38\xf2\x53\x00\x8b\xcc\xe4\x0d\xb7\x81\xb4\xe6\x1c"
+ "\x19\xaf\x02\x2b\x00\x80\xc3\x66\x13\x9e\xbb\x32\x1e\x43\x41\xef\x24\x13"
+ "\x43\x1c\x68\x7b\xf4\x10\x8d\xfa\x3f\x99\x80\xa0\x96\x20\xd0\xa1\x8c\xab"
+ "\x07\xdd\xed\x5e\x7a\x56\x78\x99\x68\x11\x1f\x02\x2b\x00\xb0\x59\xea\x67"
+ "\x93\x42\xbf\x07\x54\x38\x41\xcb\x73\xa4\x0e\xc2\xae\x56\x19\x41\xc9\x8a"
+ "\xb2\x2f\xa8\x0a\xb1\x4e\x12\x39\x2e\xc0\x94\x9a\xc6\xa3\xe4\xaf\x8a\x16"
+ "\x06\xb8";
+
+static const uint8_t kSixPrimeEncryptedMessage[] = {
+ 0x0a, 0xcb, 0x6c, 0x02, 0x9d, 0x1a, 0x7c, 0xf3, 0x4e, 0xff, 0x16, 0x88,
+ 0xee, 0x22, 0x1d, 0x8d, 0xd2, 0xfd, 0xde, 0x83, 0xb3, 0xd9, 0x35, 0x2c,
+ 0x82, 0xe0, 0xff, 0xe6, 0x79, 0x6d, 0x06, 0x21, 0x74, 0xa8, 0x04, 0x0c,
+ 0xe2, 0xd3, 0x98, 0x3f, 0xbf, 0xd0, 0xe9, 0x88, 0x24, 0xe2, 0x05, 0xa4,
+ 0x45, 0x51, 0x87, 0x6b, 0x1c, 0xef, 0x5f, 0x2d, 0x61, 0xb6, 0xf1, 0x4c,
+ 0x1f, 0x3d, 0xbf, 0x4b, 0xf2, 0xda, 0x09, 0x97, 0x81, 0xde, 0x91, 0xb7,
+ 0x0d, 0xb4, 0xc2, 0xab, 0x41, 0x64, 0x9d, 0xd9, 0x39, 0x46, 0x79, 0x66,
+ 0x43, 0xf1, 0x34, 0x21, 0x56, 0x2f, 0xc6, 0x68, 0x40, 0x4a, 0x2d, 0x73,
+ 0x96, 0x50, 0xe1, 0xb0, 0xaf, 0x49, 0x39, 0xb4, 0xf0, 0x3a, 0x78, 0x38,
+ 0x70, 0xa9, 0x91, 0x5d, 0x5e, 0x07, 0xf4, 0xec, 0xbb, 0xc4, 0xe5, 0x8a,
+ 0xb8, 0x06, 0xba, 0xdf, 0xc6, 0x48, 0x78, 0x4b, 0xca, 0x2a, 0x8a, 0x92,
+ 0x64, 0xe3, 0xa6, 0xae, 0x87, 0x97, 0x12, 0x16, 0x46, 0x67, 0x59, 0xdf,
+ 0xf2, 0xf3, 0x89, 0x6f, 0xe8, 0xa9, 0x13, 0x57, 0x63, 0x4e, 0x07, 0x98,
+ 0xcc, 0x73, 0xa0, 0x84, 0x9d, 0xe8, 0xb3, 0x50, 0x59, 0xb5, 0x51, 0xb3,
+ 0x41, 0x7d, 0x55, 0xfe, 0xd9, 0xf0, 0xc6, 0xff, 0x6e, 0x96, 0x4f, 0x22,
+ 0xb2, 0x0d, 0x6b, 0xc9, 0x83, 0x2d, 0x98, 0x98, 0xb2, 0xd1, 0xb7, 0xe4,
+ 0x50, 0x83, 0x1a, 0xa9, 0x02, 0x9f, 0xaf, 0x54, 0x74, 0x2a, 0x2c, 0x63,
+ 0x10, 0x79, 0x45, 0x5c, 0x95, 0x0d, 0xa1, 0x9b, 0x55, 0xf3, 0x1e, 0xb7,
+ 0x56, 0x59, 0xf1, 0x59, 0x8d, 0xd6, 0x15, 0x89, 0xf6, 0xfe, 0xc0, 0x00,
+ 0xdd, 0x1f, 0x2b, 0xf0, 0xf7, 0x5d, 0x64, 0x84, 0x76, 0xd3, 0xc2, 0x92,
+ 0x35, 0xac, 0xb5, 0xf9, 0xf6, 0xa8, 0x05, 0x89, 0x4c, 0x95, 0x41, 0x4e,
+ 0x34, 0x25, 0x11, 0x14,
+};
+
+// kEstonianRSAKey is an RSAPublicKey encoded with a negative modulus. See
+// https://crbug.com/532048.
+static const uint8_t kEstonianRSAKey[] = {
+ 0x30, 0x82, 0x01, 0x09, 0x02, 0x82, 0x01, 0x00, 0x96, 0xa6, 0x2e, 0x9c,
+ 0x4e, 0x6a, 0xc3, 0xcc, 0xcd, 0x8f, 0x70, 0xc3, 0x55, 0xbf, 0x5e, 0x9c,
+ 0xd4, 0xf3, 0x17, 0xc3, 0x97, 0x70, 0xae, 0xdf, 0x12, 0x5c, 0x15, 0x80,
+ 0x03, 0xef, 0x2b, 0x18, 0x9d, 0x6a, 0xcb, 0x52, 0x22, 0xc1, 0x81, 0xb8,
+ 0x7e, 0x61, 0xe8, 0x0f, 0x79, 0x24, 0x0f, 0x82, 0x70, 0x24, 0x4e, 0x29,
+ 0x20, 0x05, 0x54, 0xeb, 0xd4, 0xa9, 0x65, 0x59, 0xb6, 0x3c, 0x75, 0x95,
+ 0x2f, 0x4c, 0xf6, 0x9d, 0xd1, 0xaf, 0x5f, 0x14, 0x14, 0xe7, 0x25, 0xea,
+ 0xa5, 0x47, 0x5d, 0xc6, 0x3e, 0x28, 0x8d, 0xdc, 0x54, 0x87, 0x2a, 0x7c,
+ 0x10, 0xe9, 0xc6, 0x76, 0x2d, 0xe7, 0x79, 0xd8, 0x0e, 0xbb, 0xa9, 0xac,
+ 0xb5, 0x18, 0x98, 0xd6, 0x47, 0x6e, 0x06, 0x70, 0xbf, 0x9e, 0x82, 0x25,
+ 0x95, 0x4e, 0xfd, 0x70, 0xd7, 0x73, 0x45, 0x2e, 0xc1, 0x1f, 0x7a, 0x9a,
+ 0x9d, 0x60, 0xc0, 0x1f, 0x67, 0x06, 0x2a, 0x4e, 0x87, 0x3f, 0x19, 0x88,
+ 0x69, 0x64, 0x4d, 0x9f, 0x75, 0xf5, 0xd3, 0x1a, 0x41, 0x3d, 0x35, 0x17,
+ 0xb6, 0xd1, 0x44, 0x0d, 0x25, 0x8b, 0xe7, 0x94, 0x39, 0xb0, 0x7c, 0xaf,
+ 0x3e, 0x6a, 0xfa, 0x8d, 0x90, 0x21, 0x0f, 0x8a, 0x43, 0x94, 0x37, 0x7c,
+ 0x2a, 0x15, 0x4c, 0xa0, 0xfa, 0xa9, 0x2f, 0x21, 0xa6, 0x6f, 0x8e, 0x2f,
+ 0x89, 0xbc, 0xbb, 0x33, 0xf8, 0x31, 0xfc, 0xdf, 0xcd, 0x68, 0x9a, 0xbc,
+ 0x75, 0x06, 0x95, 0xf1, 0x3d, 0xef, 0xca, 0x76, 0x27, 0xd2, 0xba, 0x8e,
+ 0x0e, 0x1c, 0x43, 0xd7, 0x70, 0xb9, 0xc6, 0x15, 0xca, 0xd5, 0x4d, 0x87,
+ 0xb9, 0xd1, 0xae, 0xde, 0x69, 0x73, 0x00, 0x2a, 0x97, 0x51, 0x4b, 0x30,
+ 0x01, 0xc2, 0x85, 0xd0, 0x05, 0xcc, 0x2e, 0xe8, 0xc7, 0x42, 0xe7, 0x94,
+ 0x51, 0xe3, 0xf5, 0x19, 0x35, 0xdc, 0x57, 0x96, 0xe7, 0xd9, 0xb4, 0x49,
+ 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) {
+ ScopedRSA key(RSA_private_key_from_bytes(der, der_len));
+ if (!key) {
+ return false;
+ }
+
+ if (!RSA_check_key(key.get())) {
+ fprintf(stderr, "RSA_check_key failed\n");
+ return false;
+ }
+
+ uint8_t ciphertext[256];
+
+ size_t ciphertext_len = 0;
+ if (!RSA_encrypt(key.get(), &ciphertext_len, ciphertext, sizeof(ciphertext),
+ kPlaintext, kPlaintextLen, RSA_PKCS1_PADDING) ||
+ ciphertext_len != RSA_size(key.get())) {
+ fprintf(stderr, "PKCS#1 v1.5 encryption failed!\n");
+ return false;
+ }
+
+ uint8_t plaintext[256];
+ size_t plaintext_len = 0;
+ if (!RSA_decrypt(key.get(), &plaintext_len, plaintext, sizeof(plaintext),
+ ciphertext, ciphertext_len, RSA_PKCS1_PADDING) ||
+ plaintext_len != kPlaintextLen ||
+ memcmp(plaintext, kPlaintext, plaintext_len) != 0) {
+ fprintf(stderr, "PKCS#1 v1.5 decryption failed!\n");
+ return false;
+ }
+
+ ciphertext_len = 0;
+ if (!RSA_encrypt(key.get(), &ciphertext_len, ciphertext, sizeof(ciphertext),
+ kPlaintext, kPlaintextLen, RSA_PKCS1_OAEP_PADDING) ||
+ ciphertext_len != RSA_size(key.get())) {
+ fprintf(stderr, "OAEP encryption failed!\n");
+ return false;
+ }
+
+ plaintext_len = 0;
+ if (!RSA_decrypt(key.get(), &plaintext_len, plaintext, sizeof(plaintext),
+ ciphertext, ciphertext_len, RSA_PKCS1_OAEP_PADDING) ||
+ plaintext_len != kPlaintextLen ||
+ memcmp(plaintext, kPlaintext, plaintext_len) != 0) {
+ fprintf(stderr, "OAEP decryption (encrypted data) failed!\n");
+ return false;
+ }
+
+ // |oaep_ciphertext| should decrypt to |kPlaintext|.
+ plaintext_len = 0;
+ if (!RSA_decrypt(key.get(), &plaintext_len, plaintext, sizeof(plaintext),
+ oaep_ciphertext, oaep_ciphertext_len,
+ RSA_PKCS1_OAEP_PADDING) ||
+ plaintext_len != kPlaintextLen ||
+ memcmp(plaintext, kPlaintext, plaintext_len) != 0) {
+ fprintf(stderr, "OAEP decryption (test vector data) failed!\n");
+ return false;
+ }
+
+ // Try decrypting corrupted ciphertexts.
+ memcpy(ciphertext, oaep_ciphertext, oaep_ciphertext_len);
+ for (size_t i = 0; i < oaep_ciphertext_len; i++) {
+ ciphertext[i] ^= 1;
+ if (RSA_decrypt(key.get(), &plaintext_len, plaintext, sizeof(plaintext),
+ ciphertext, oaep_ciphertext_len, RSA_PKCS1_OAEP_PADDING)) {
+ fprintf(stderr, "Corrupt data decrypted!\n");
+ return false;
+ }
+ ciphertext[i] ^= 1;
+ }
+
+ // Test truncated ciphertexts.
+ for (size_t len = 0; len < oaep_ciphertext_len; len++) {
+ if (RSA_decrypt(key.get(), &plaintext_len, plaintext, sizeof(plaintext),
+ ciphertext, len, RSA_PKCS1_OAEP_PADDING)) {
+ fprintf(stderr, "Corrupt data decrypted!\n");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static bool TestMultiPrimeKey(int nprimes, const uint8_t *der, size_t der_size,
+ const uint8_t *enc, size_t enc_size) {
+ ScopedRSA rsa(d2i_RSAPrivateKey(nullptr, &der, der_size));
+ if (!rsa) {
+ fprintf(stderr, "%d-prime key failed to parse.\n", nprimes);
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ if (!RSA_check_key(rsa.get())) {
+ fprintf(stderr, "RSA_check_key failed for %d-prime key.\n", nprimes);
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ uint8_t out[256];
+ size_t out_len;
+ if (!RSA_decrypt(rsa.get(), &out_len, out, sizeof(out), enc, enc_size,
+ RSA_PKCS1_PADDING) ||
+ out_len != 11 ||
+ memcmp(out, "hello world", 11) != 0) {
+ fprintf(stderr, "%d-prime key failed to decrypt.\n", nprimes);
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ return true;
+}
+
+static bool TestMultiPrimeKeygen() {
+ static const char kMessage[] = "Hello world.";
+ static const size_t kBits = 1024;
+ uint8_t encrypted[kBits / 8], decrypted[kBits / 8];
+ size_t encrypted_len, decrypted_len;
+
+ ScopedRSA rsa(RSA_new());
+ ScopedBIGNUM e(BN_new());
+ if (!rsa || !e ||
+ !BN_set_word(e.get(), RSA_F4) ||
+ !RSA_generate_multi_prime_key(rsa.get(), kBits, 3, e.get(), nullptr) ||
+ !RSA_check_key(rsa.get()) ||
+ !RSA_encrypt(rsa.get(), &encrypted_len, encrypted, sizeof(encrypted),
+ (const uint8_t *)kMessage, sizeof(kMessage),
+ RSA_PKCS1_PADDING) ||
+ !RSA_decrypt(rsa.get(), &decrypted_len, decrypted, sizeof(decrypted),
+ encrypted, encrypted_len, RSA_PKCS1_PADDING) ||
+ decrypted_len != sizeof(kMessage) ||
+ memcmp(decrypted, kMessage, sizeof(kMessage)) != 0) {
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ return true;
+}
+
+static bool TestBadKey() {
+ ScopedRSA key(RSA_new());
+ ScopedBIGNUM e(BN_new());
+
+ if (!key || !e || !BN_set_word(e.get(), RSA_F4)) {
+ return false;
+ }
+
+ if (!RSA_generate_key_ex(key.get(), 512, e.get(), nullptr)) {
+ fprintf(stderr, "RSA_generate_key_ex failed.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ if (!BN_add(key->p, key->p, BN_value_one())) {
+ fprintf(stderr, "BN error.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ if (RSA_check_key(key.get())) {
+ fprintf(stderr, "RSA_check_key passed with invalid key!\n");
+ return false;
+ }
+
+ ERR_clear_error();
+ return true;
+}
+
+static bool TestOnlyDGiven() {
+ uint8_t buf[64];
+ unsigned buf_len = sizeof(buf);
+ ScopedRSA key(RSA_new());
+ if (!key ||
+ !BN_hex2bn(&key->n,
+ "00e77bbf3889d4ef36a9a25d4d69f3f632eb4362214c74517da6d6aeaa9bd"
+ "09ac42b26621cd88f3a6eb013772fc3bf9f83914b6467231c630202c35b3e"
+ "5808c659") ||
+ !BN_hex2bn(&key->e, "010001") ||
+ !BN_hex2bn(&key->d,
+ "0365db9eb6d73b53b015c40cd8db4de7dd7035c68b5ac1bf786d7a4ee2cea"
+ "316eaeca21a73ac365e58713195f2ae9849348525ca855386b6d028e437a9"
+ "495a01") ||
+ RSA_size(key.get()) > sizeof(buf)) {
+ return false;
+ }
+
+ if (!RSA_check_key(key.get())) {
+ fprintf(stderr, "RSA_check_key failed with only d given.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ const uint8_t kDummyHash[16] = {0};
+
+ if (!RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, &buf_len,
+ key.get())) {
+ fprintf(stderr, "RSA_sign failed with only d given.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ if (!RSA_verify(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, buf_len,
+ key.get())) {
+ fprintf(stderr, "RSA_verify failed with only d given.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ return true;
+}
+
+static bool TestRecoverCRTParams() {
+ ScopedBIGNUM e(BN_new());
+ if (!e || !BN_set_word(e.get(), RSA_F4)) {
+ return false;
+ }
+
+ ERR_clear_error();
+
+ for (unsigned i = 0; i < 1; i++) {
+ ScopedRSA key1(RSA_new());
+ if (!key1 ||
+ !RSA_generate_key_ex(key1.get(), 512, e.get(), nullptr)) {
+ fprintf(stderr, "RSA_generate_key_ex failed.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ if (!RSA_check_key(key1.get())) {
+ fprintf(stderr, "RSA_check_key failed with original key.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ ScopedRSA key2(RSA_new());
+ if (!key2) {
+ return false;
+ }
+ key2->n = BN_dup(key1->n);
+ key2->e = BN_dup(key1->e);
+ key2->d = BN_dup(key1->d);
+ if (key2->n == nullptr || key2->e == nullptr || key2->d == nullptr) {
+ return false;
+ }
+
+ if (!RSA_recover_crt_params(key2.get())) {
+ fprintf(stderr, "RSA_recover_crt_params failed.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ uint8_t buf[128];
+ unsigned buf_len = sizeof(buf);
+ if (RSA_size(key2.get()) > buf_len) {
+ return false;
+ }
+
+ if (!RSA_check_key(key2.get())) {
+ fprintf(stderr, "RSA_check_key failed with recovered key.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ const uint8_t kDummyHash[16] = {0};
+ if (!RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, &buf_len,
+ key2.get())) {
+ fprintf(stderr, "RSA_sign failed with recovered key.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ if (!RSA_verify(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, buf_len,
+ key2.get())) {
+ fprintf(stderr, "RSA_verify failed with recovered key.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static bool TestASN1() {
+ // Test that private keys may be decoded.
+ ScopedRSA rsa(RSA_private_key_from_bytes(kKey1, sizeof(kKey1) - 1));
+ if (!rsa) {
+ return false;
+ }
+
+ // Test that the serialization round-trips.
+ uint8_t *der;
+ size_t der_len;
+ if (!RSA_private_key_to_bytes(&der, &der_len, rsa.get())) {
+ return false;
+ }
+ ScopedOpenSSLBytes delete_der(der);
+ if (der_len != sizeof(kKey1) - 1 || memcmp(der, kKey1, der_len) != 0) {
+ return false;
+ }
+
+ // Test that serializing public keys works.
+ if (!RSA_public_key_to_bytes(&der, &der_len, rsa.get())) {
+ return false;
+ }
+ delete_der.reset(der);
+
+ // Public keys may be parsed back out.
+ rsa.reset(RSA_public_key_from_bytes(der, der_len));
+ if (!rsa || rsa->p != NULL || rsa->q != NULL) {
+ return false;
+ }
+
+ // Serializing the result round-trips.
+ uint8_t *der2;
+ size_t der2_len;
+ if (!RSA_public_key_to_bytes(&der2, &der2_len, rsa.get())) {
+ return false;
+ }
+ ScopedOpenSSLBytes delete_der2(der2);
+ if (der_len != der2_len || memcmp(der, der2, der_len) != 0) {
+ return false;
+ }
+
+ // Public keys cannot be serialized as private keys.
+ if (RSA_private_key_to_bytes(&der, &der_len, rsa.get())) {
+ OPENSSL_free(der);
+ return false;
+ }
+ ERR_clear_error();
+
+ // Public keys with negative moduli are invalid.
+ rsa.reset(RSA_public_key_from_bytes(kEstonianRSAKey,
+ sizeof(kEstonianRSAKey)));
+ if (rsa) {
+ return false;
+ }
+ ERR_clear_error();
+
+ // But |RSA_parse_public_key_buggy| will accept it.
+ CBS cbs;
+ CBS_init(&cbs, kEstonianRSAKey, sizeof(kEstonianRSAKey));
+ rsa.reset(RSA_parse_public_key_buggy(&cbs));
+ if (!rsa || CBS_len(&cbs) != 0) {
+ return false;
+ }
+
+ 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();
+
+ if (!TestRSA(kKey1, sizeof(kKey1) - 1, kOAEPCiphertext1,
+ sizeof(kOAEPCiphertext1) - 1) ||
+ !TestRSA(kKey2, sizeof(kKey2) - 1, kOAEPCiphertext2,
+ sizeof(kOAEPCiphertext2) - 1) ||
+ !TestRSA(kKey3, sizeof(kKey3) - 1, kOAEPCiphertext3,
+ sizeof(kOAEPCiphertext3) - 1) ||
+ !TestOnlyDGiven() ||
+ !TestRecoverCRTParams() ||
+ !TestBadKey() ||
+ !TestMultiPrimeKey(2, kTwoPrimeKey, sizeof(kTwoPrimeKey) - 1,
+ kTwoPrimeEncryptedMessage,
+ sizeof(kTwoPrimeEncryptedMessage)) ||
+ !TestMultiPrimeKey(3, kThreePrimeKey, sizeof(kThreePrimeKey) - 1,
+ kThreePrimeEncryptedMessage,
+ sizeof(kThreePrimeEncryptedMessage)) ||
+ !TestMultiPrimeKey(6, kSixPrimeKey, sizeof(kSixPrimeKey) - 1,
+ kSixPrimeEncryptedMessage,
+ sizeof(kSixPrimeEncryptedMessage)) ||
+ !TestMultiPrimeKeygen() ||
+ !TestASN1() ||
+ !TestBadExponent()) {
+ return 1;
+ }
+
+ printf("PASS\n");
+ return 0;
+}
diff --git a/src/crypto/sha/CMakeLists.txt b/src/crypto/sha/CMakeLists.txt
index 5a10c85..ecff09b 100644
--- a/src/crypto/sha/CMakeLists.txt
+++ b/src/crypto/sha/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
if (${ARCH} STREQUAL "x86_64")
set(
diff --git a/src/crypto/sha/asm/sha1-586.pl b/src/crypto/sha/asm/sha1-586.pl
index 4895eb3..3514273 100644
--- a/src/crypto/sha/asm/sha1-586.pl
+++ b/src/crypto/sha/asm/sha1-586.pl
@@ -66,9 +66,9 @@
# switch to AVX alone improves performance by as little as 4% in
# comparison to SSSE3 code path. But below result doesn't look like
# 4% improvement... Trouble is that Sandy Bridge decodes 'ro[rl]' as
-# pair of µ-ops, and it's the additional µ-ops, two per round, that
+# pair of µ-ops, and it's the additional µ-ops, two per round, that
# make it run slower than Core2 and Westmere. But 'sh[rl]d' is decoded
-# as single µ-op by Sandy Bridge and it's replacing 'ro[rl]' with
+# as single µ-op by Sandy Bridge and it's replacing 'ro[rl]' with
# equivalent 'sh[rl]d' that is responsible for the impressive 5.1
# cycles per processed byte. But 'sh[rl]d' is not something that used
# to be fast, nor does it appear to be fast in upcoming Bulldozer
@@ -118,24 +118,19 @@ require "x86asm.pl";
$xmm=$ymm=0;
for (@ARGV) { $xmm=1 if (/-DOPENSSL_IA32_SSE2/); }
-$ymm=1 if ($xmm &&
- `$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
- =~ /GNU assembler version ([2-9]\.[0-9]+)/ &&
- $1>=2.19); # first version supporting AVX
+# 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.
+$ymm = 1;
-$ymm=1 if ($xmm && !$ymm && $ARGV[0] eq "win32n" &&
- `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/ &&
- $1>=2.03); # first version supporting AVX
-
-$ymm=1 if ($xmm && !$ymm && $ARGV[0] eq "win32" &&
- `ml 2>&1` =~ /Version ([0-9]+)\./ &&
- $1>=10); # first version supporting AVX
-
-$ymm=1 if ($xmm && !$ymm && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9]\.[0-9]+)/ &&
- $2>=3.0); # first version supporting AVX
+$ymm = 0 unless ($xmm);
$shaext=$xmm; ### set to zero if compiling for 1.0.1
+# TODO(davidben): Consider enabling the Intel SHA Extensions code once it's
+# been tested.
+$shaext = 0;
+
&external_label("OPENSSL_ia32cap_P") if ($xmm);
diff --git a/src/crypto/sha/asm/sha1-armv4-large.pl b/src/crypto/sha/asm/sha1-armv4-large.pl
index a20d336..64e2ed6 100644
--- a/src/crypto/sha/asm/sha1-armv4-large.pl
+++ b/src/crypto/sha/asm/sha1-armv4-large.pl
@@ -178,7 +178,7 @@ ___
}
$code=<<___;
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
.text
.code 32
diff --git a/src/crypto/sha/asm/sha1-armv8.pl b/src/crypto/sha/asm/sha1-armv8.pl
index a8c08c2..1c4fe4a 100644
--- a/src/crypto/sha/asm/sha1-armv8.pl
+++ b/src/crypto/sha/asm/sha1-armv8.pl
@@ -162,7 +162,7 @@ ___
}
$code.=<<___;
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
.text
diff --git a/src/crypto/sha/asm/sha1-x86_64.pl b/src/crypto/sha/asm/sha1-x86_64.pl
index 124034d..4895f92 100644
--- a/src/crypto/sha/asm/sha1-x86_64.pl
+++ b/src/crypto/sha/asm/sha1-x86_64.pl
@@ -92,25 +92,17 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
-if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
- =~ /GNU assembler version ([2-9]\.[0-9]+)/) {
- $avx = ($1>=2.19) + ($1>=2.22);
-}
-
-if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
- `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
- $avx = ($1>=2.09) + ($1>=2.10);
-}
-
-if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
- `ml64 2>&1` =~ /Version ([0-9]+)\./) {
- $avx = ($1>=10) + ($1>=11);
-}
-
-if (!$avx && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([2-9]\.[0-9]+)/) {
- $avx = ($2>=3.0) + ($2>3.0);
-}
+# 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 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.
$shaext=0; ### set to zero if compiling for 1.0.1
$avx=1 if (!$shaext && $avx);
diff --git a/src/crypto/sha/asm/sha256-586.pl b/src/crypto/sha/asm/sha256-586.pl
index 6462e45..fa8f264 100644
--- a/src/crypto/sha/asm/sha256-586.pl
+++ b/src/crypto/sha/asm/sha256-586.pl
@@ -10,7 +10,7 @@
# SHA256 block transform for x86. September 2007.
#
# Performance improvement over compiler generated code varies from
-# 10% to 40% [see below]. Not very impressive on some µ-archs, but
+# 10% to 40% [see below]. Not very impressive on some µ-archs, but
# it's 5 times smaller and optimizies amount of writes.
#
# May 2012.
@@ -68,27 +68,21 @@ require "x86asm.pl";
$xmm=$avx=0;
for (@ARGV) { $xmm=1 if (/-DOPENSSL_IA32_SSE2/); }
-if ($xmm && `$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
- =~ /GNU assembler version ([2-9]\.[0-9]+)/) {
- $avx = ($1>=2.19) + ($1>=2.22);
-}
-
-if ($xmm && !$avx && $ARGV[0] eq "win32n" &&
- `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
- $avx = ($1>=2.03) + ($1>=2.10);
-}
-
-if ($xmm && !$avx && $ARGV[0] eq "win32" &&
- `ml 2>&1` =~ /Version ([0-9]+)\./) {
- $avx = ($1>=10) + ($1>=11);
-}
+# 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 AVX2 code after testing by setting $avx to 2.
+$avx = 1;
-if ($xmm && !$avx && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9]\.[0-9]+)/) {
- $avx = ($2>=3.0) + ($2>3.0);
-}
+$avx = 0 unless ($xmm);
$shaext=$xmm; ### set to zero if compiling for 1.0.1
+# TODO(davidben): Consider enabling the Intel SHA Extensions code once it's
+# been tested.
+$shaext = 0;
+
$unroll_after = 64*4; # If pre-evicted from L1P cache first spin of
# fully unrolled loop was measured to run about
# 3-4x slower. If slowdown coefficient is N and
diff --git a/src/crypto/sha/asm/sha256-armv4.pl b/src/crypto/sha/asm/sha256-armv4.pl
index df71676..7e07147 100644
--- a/src/crypto/sha/asm/sha256-armv4.pl
+++ b/src/crypto/sha/asm/sha256-armv4.pl
@@ -168,7 +168,7 @@ ___
$code=<<___;
#ifndef __KERNEL__
-# include "arm_arch.h"
+# include <openssl/arm_arch.h>
#else
# define __ARM_ARCH__ __LINUX_ARM_ARCH__
# define __ARM_MAX_ARCH__ 7
diff --git a/src/crypto/sha/asm/sha512-586.pl b/src/crypto/sha/asm/sha512-586.pl
index e96ec00..2f6a202 100644
--- a/src/crypto/sha/asm/sha512-586.pl
+++ b/src/crypto/sha/asm/sha512-586.pl
@@ -37,7 +37,7 @@
#
# IALU code-path is optimized for elder Pentiums. On vanilla Pentium
# performance improvement over compiler generated code reaches ~60%,
-# while on PIII - ~35%. On newer µ-archs improvement varies from 15%
+# while on PIII - ~35%. On newer µ-archs improvement varies from 15%
# to 50%, but it's less important as they are expected to execute SSE2
# code-path, which is commonly ~2-3x faster [than compiler generated
# code]. SSE2 code-path is as fast as original sha512-sse2.pl, even
diff --git a/src/crypto/sha/asm/sha512-armv4.pl b/src/crypto/sha/asm/sha512-armv4.pl
index 2964a39..cd3662a 100644
--- a/src/crypto/sha/asm/sha512-armv4.pl
+++ b/src/crypto/sha/asm/sha512-armv4.pl
@@ -191,7 +191,7 @@ ___
}
$code=<<___;
#ifndef __KERNEL__
-# include "arm_arch.h"
+# include <openssl/arm_arch.h>
# define VFP_ABI_PUSH vstmdb sp!,{d8-d15}
# define VFP_ABI_POP vldmia sp!,{d8-d15}
#else
diff --git a/src/crypto/sha/asm/sha512-armv8.pl b/src/crypto/sha/asm/sha512-armv8.pl
index 43e7293..40eb17a 100644
--- a/src/crypto/sha/asm/sha512-armv8.pl
+++ b/src/crypto/sha/asm/sha512-armv8.pl
@@ -164,7 +164,7 @@ ___
}
$code.=<<___;
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
.text
diff --git a/src/crypto/sha/asm/sha512-x86_64.pl b/src/crypto/sha/asm/sha512-x86_64.pl
index 6660a88..2bc33c6 100644
--- a/src/crypto/sha/asm/sha512-x86_64.pl
+++ b/src/crypto/sha/asm/sha512-x86_64.pl
@@ -109,25 +109,17 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
-if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
- =~ /GNU assembler version ([2-9]\.[0-9]+)/) {
- $avx = ($1>=2.19) + ($1>=2.22);
-}
-
-if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
- `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
- $avx = ($1>=2.09) + ($1>=2.10);
-}
-
-if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
- `ml64 2>&1` =~ /Version ([0-9]+)\./) {
- $avx = ($1>=10) + ($1>=11);
-}
-
-if (!$avx && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9]\.[0-9]+)/) {
- $avx = ($2>=3.0) + ($2>3.0);
-}
+# 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 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.
$shaext=0; ### set to zero if compiling for 1.0.1
$avx=1 if (!$shaext && $avx);
@@ -2264,7 +2256,8 @@ $code.=<<___;
ret
.size se_handler,.-se_handler
___
-$code.=<<___ if ($SZ == 4 && $shaext);
+
+$code.=<<___ if ($SZ==4 && $shaext);
.type shaext_handler,\@abi-omnipotent
.align 16
shaext_handler:
@@ -2298,6 +2291,7 @@ shaext_handler:
jmp .Lin_prologue
.size shaext_handler,.-shaext_handler
___
+
$code.=<<___;
.section .pdata
.align 4
@@ -2305,7 +2299,7 @@ $code.=<<___;
.rva .LSEH_end_$func
.rva .LSEH_info_$func
___
-$code.=<<___ if ($SZ==4 && $shext);
+$code.=<<___ if ($SZ==4 && $shaext);
.rva .LSEH_begin_${func}_shaext
.rva .LSEH_end_${func}_shaext
.rva .LSEH_info_${func}_shaext
diff --git a/src/crypto/sha/sha1.c b/src/crypto/sha/sha1.c
index c03e608..74e841c 100644
--- a/src/crypto/sha/sha1.c
+++ b/src/crypto/sha/sha1.c
@@ -69,11 +69,11 @@
int SHA1_Init(SHA_CTX *sha) {
memset(sha, 0, sizeof(SHA_CTX));
- sha->h0 = 0x67452301UL;
- sha->h1 = 0xefcdab89UL;
- sha->h2 = 0x98badcfeUL;
- sha->h3 = 0x10325476UL;
- sha->h4 = 0xc3d2e1f0UL;
+ sha->h[0] = 0x67452301UL;
+ sha->h[1] = 0xefcdab89UL;
+ sha->h[2] = 0x98badcfeUL;
+ sha->h[3] = 0x10325476UL;
+ sha->h[4] = 0xc3d2e1f0UL;
return 1;
}
@@ -96,35 +96,35 @@ uint8_t *SHA1(const uint8_t *data, size_t len, uint8_t *out) {
#define DATA_ORDER_IS_BIG_ENDIAN
-#define HASH_LONG uint32_t
#define HASH_CTX SHA_CTX
#define HASH_CBLOCK 64
#define HASH_MAKE_STRING(c, s) \
do { \
uint32_t ll; \
- ll = (c)->h0; \
- (void) HOST_l2c(ll, (s)); \
- ll = (c)->h1; \
- (void) HOST_l2c(ll, (s)); \
- ll = (c)->h2; \
- (void) HOST_l2c(ll, (s)); \
- ll = (c)->h3; \
- (void) HOST_l2c(ll, (s)); \
- ll = (c)->h4; \
- (void) HOST_l2c(ll, (s)); \
+ ll = (c)->h[0]; \
+ HOST_l2c(ll, (s)); \
+ ll = (c)->h[1]; \
+ HOST_l2c(ll, (s)); \
+ ll = (c)->h[2]; \
+ HOST_l2c(ll, (s)); \
+ ll = (c)->h[3]; \
+ HOST_l2c(ll, (s)); \
+ ll = (c)->h[4]; \
+ 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))
#ifndef SHA1_ASM
static
#endif
-void sha1_block_data_order(SHA_CTX *c, const void *p, size_t num);
+void sha1_block_data_order(uint32_t *state, const uint8_t *data, size_t num);
#include "../digest/md32_common.h"
@@ -186,111 +186,67 @@ void sha1_block_data_order(SHA_CTX *c, const void *p, size_t num);
#define X(i) XX##i
#if !defined(SHA1_ASM)
-static void HASH_BLOCK_DATA_ORDER(SHA_CTX *c, const void *p, size_t num) {
- const uint8_t *data = p;
+static void sha1_block_data_order(uint32_t *state, const uint8_t *data,
+ size_t num) {
register uint32_t A, B, C, D, E, T, l;
uint32_t XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, XX8, XX9, XX10,
XX11, XX12, XX13, XX14, XX15;
- A = c->h0;
- B = c->h1;
- C = c->h2;
- D = c->h3;
- E = c->h4;
+ A = state[0];
+ B = state[1];
+ C = state[2];
+ D = state[3];
+ E = state[4];
for (;;) {
- const union {
- long one;
- char little;
- } is_endian = {1};
-
- if (!is_endian.little && ((size_t)p % 4) == 0) {
- const uint32_t *W = (const uint32_t *)data;
-
- X(0) = W[0];
- X(1) = W[1];
- BODY_00_15(0, A, B, C, D, E, T, X(0));
- X(2) = W[2];
- BODY_00_15(1, T, A, B, C, D, E, X(1));
- X(3) = W[3];
- BODY_00_15(2, E, T, A, B, C, D, X(2));
- X(4) = W[4];
- BODY_00_15(3, D, E, T, A, B, C, X(3));
- X(5) = W[5];
- BODY_00_15(4, C, D, E, T, A, B, X(4));
- X(6) = W[6];
- BODY_00_15(5, B, C, D, E, T, A, X(5));
- X(7) = W[7];
- BODY_00_15(6, A, B, C, D, E, T, X(6));
- X(8) = W[8];
- BODY_00_15(7, T, A, B, C, D, E, X(7));
- X(9) = W[9];
- BODY_00_15(8, E, T, A, B, C, D, X(8));
- X(10) = W[10];
- BODY_00_15(9, D, E, T, A, B, C, X(9));
- X(11) = W[11];
- BODY_00_15(10, C, D, E, T, A, B, X(10));
- X(12) = W[12];
- BODY_00_15(11, B, C, D, E, T, A, X(11));
- X(13) = W[13];
- BODY_00_15(12, A, B, C, D, E, T, X(12));
- X(14) = W[14];
- BODY_00_15(13, T, A, B, C, D, E, X(13));
- X(15) = W[15];
- BODY_00_15(14, E, T, A, B, C, D, X(14));
- BODY_00_15(15, D, E, T, A, B, C, X(15));
-
- data += HASH_CBLOCK;
- } else {
- (void)HOST_c2l(data, l);
- X(0) = l;
- (void)HOST_c2l(data, l);
- X(1) = l;
- BODY_00_15(0, A, B, C, D, E, T, X(0));
- (void)HOST_c2l(data, l);
- X(2) = l;
- BODY_00_15(1, T, A, B, C, D, E, X(1));
- (void)HOST_c2l(data, l);
- X(3) = l;
- BODY_00_15(2, E, T, A, B, C, D, X(2));
- (void)HOST_c2l(data, l);
- X(4) = l;
- BODY_00_15(3, D, E, T, A, B, C, X(3));
- (void)HOST_c2l(data, l);
- X(5) = l;
- BODY_00_15(4, C, D, E, T, A, B, X(4));
- (void)HOST_c2l(data, l);
- X(6) = l;
- BODY_00_15(5, B, C, D, E, T, A, X(5));
- (void)HOST_c2l(data, l);
- X(7) = l;
- BODY_00_15(6, A, B, C, D, E, T, X(6));
- (void)HOST_c2l(data, l);
- X(8) = l;
- BODY_00_15(7, T, A, B, C, D, E, X(7));
- (void)HOST_c2l(data, l);
- X(9) = l;
- BODY_00_15(8, E, T, A, B, C, D, X(8));
- (void)HOST_c2l(data, l);
- X(10) = l;
- BODY_00_15(9, D, E, T, A, B, C, X(9));
- (void)HOST_c2l(data, l);
- X(11) = l;
- BODY_00_15(10, C, D, E, T, A, B, X(10));
- (void)HOST_c2l(data, l);
- X(12) = l;
- BODY_00_15(11, B, C, D, E, T, A, X(11));
- (void)HOST_c2l(data, l);
- X(13) = l;
- BODY_00_15(12, A, B, C, D, E, T, X(12));
- (void)HOST_c2l(data, l);
- X(14) = l;
- BODY_00_15(13, T, A, B, C, D, E, X(13));
- (void)HOST_c2l(data, l);
- X(15) = l;
- BODY_00_15(14, E, T, A, B, C, D, X(14));
- BODY_00_15(15, D, E, T, A, B, C, X(15));
- }
+ (void)HOST_c2l(data, l);
+ X(0) = l;
+ (void)HOST_c2l(data, l);
+ X(1) = l;
+ BODY_00_15(0, A, B, C, D, E, T, X(0));
+ (void)HOST_c2l(data, l);
+ X(2) = l;
+ BODY_00_15(1, T, A, B, C, D, E, X(1));
+ (void)HOST_c2l(data, l);
+ X(3) = l;
+ BODY_00_15(2, E, T, A, B, C, D, X(2));
+ (void)HOST_c2l(data, l);
+ X(4) = l;
+ BODY_00_15(3, D, E, T, A, B, C, X(3));
+ (void)HOST_c2l(data, l);
+ X(5) = l;
+ BODY_00_15(4, C, D, E, T, A, B, X(4));
+ (void)HOST_c2l(data, l);
+ X(6) = l;
+ BODY_00_15(5, B, C, D, E, T, A, X(5));
+ (void)HOST_c2l(data, l);
+ X(7) = l;
+ BODY_00_15(6, A, B, C, D, E, T, X(6));
+ (void)HOST_c2l(data, l);
+ X(8) = l;
+ BODY_00_15(7, T, A, B, C, D, E, X(7));
+ (void)HOST_c2l(data, l);
+ X(9) = l;
+ BODY_00_15(8, E, T, A, B, C, D, X(8));
+ (void)HOST_c2l(data, l);
+ X(10) = l;
+ BODY_00_15(9, D, E, T, A, B, C, X(9));
+ (void)HOST_c2l(data, l);
+ X(11) = l;
+ BODY_00_15(10, C, D, E, T, A, B, X(10));
+ (void)HOST_c2l(data, l);
+ X(12) = l;
+ BODY_00_15(11, B, C, D, E, T, A, X(11));
+ (void)HOST_c2l(data, l);
+ X(13) = l;
+ BODY_00_15(12, A, B, C, D, E, T, X(12));
+ (void)HOST_c2l(data, l);
+ X(14) = l;
+ BODY_00_15(13, T, A, B, C, D, E, X(13));
+ (void)HOST_c2l(data, l);
+ X(15) = l;
+ BODY_00_15(14, E, T, A, B, C, D, X(14));
+ BODY_00_15(15, D, E, T, A, B, C, X(15));
BODY_16_19(16, C, D, E, T, A, B, X(0), X(0), X(2), X(8), X(13));
BODY_16_19(17, B, C, D, E, T, A, X(1), X(1), X(3), X(9), X(14));
@@ -361,21 +317,21 @@ static void HASH_BLOCK_DATA_ORDER(SHA_CTX *c, const void *p, size_t num) {
BODY_60_79(78, A, B, C, D, E, T, X(14), X(0), X(6), X(11));
BODY_60_79(79, T, A, B, C, D, E, X(15), X(1), X(7), X(12));
- c->h0 = (c->h0 + E) & 0xffffffffL;
- c->h1 = (c->h1 + T) & 0xffffffffL;
- c->h2 = (c->h2 + A) & 0xffffffffL;
- c->h3 = (c->h3 + B) & 0xffffffffL;
- c->h4 = (c->h4 + C) & 0xffffffffL;
+ state[0] = (state[0] + E) & 0xffffffffL;
+ state[1] = (state[1] + T) & 0xffffffffL;
+ state[2] = (state[2] + A) & 0xffffffffL;
+ state[3] = (state[3] + B) & 0xffffffffL;
+ state[4] = (state[4] + C) & 0xffffffffL;
if (--num == 0) {
break;
}
- A = c->h0;
- B = c->h1;
- C = c->h2;
- D = c->h3;
- E = c->h4;
+ A = state[0];
+ B = state[1];
+ C = state[2];
+ D = state[3];
+ E = state[4];
}
}
#endif
diff --git a/src/crypto/sha/sha256.c b/src/crypto/sha/sha256.c
index 8276bbb..0ddacba 100644
--- a/src/crypto/sha/sha256.c
+++ b/src/crypto/sha/sha256.c
@@ -135,7 +135,6 @@ int SHA224_Final(uint8_t *md, SHA256_CTX *ctx) {
#define DATA_ORDER_IS_BIG_ENDIAN
-#define HASH_LONG uint32_t
#define HASH_CTX SHA256_CTX
#define HASH_CBLOCK 64
@@ -156,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: \
@@ -171,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; \
} \
@@ -185,12 +184,12 @@ int SHA224_Final(uint8_t *md, SHA256_CTX *ctx) {
#ifndef SHA256_ASM
static
#endif
-void sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num);
+void sha256_block_data_order(uint32_t *state, const uint8_t *in, size_t num);
#include "../digest/md32_common.h"
#ifndef SHA256_ASM
-static const HASH_LONG K256[64] = {
+static const uint32_t K256[64] = {
0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
@@ -205,6 +204,8 @@ static const HASH_LONG 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... */
@@ -234,116 +235,72 @@ static const HASH_LONG K256[64] = {
ROUND_00_15(i, a, b, c, d, e, f, g, h); \
} while (0)
-static void sha256_block_data_order(SHA256_CTX *ctx, const void *in,
+static void sha256_block_data_order(uint32_t *state, const uint8_t *data,
size_t num) {
uint32_t a, b, c, d, e, f, g, h, s0, s1, T1;
- HASH_LONG X[16];
+ uint32_t X[16];
int i;
- const uint8_t *data = in;
- const union {
- long one;
- char little;
- } is_endian = {1};
while (num--) {
- a = ctx->h[0];
- b = ctx->h[1];
- c = ctx->h[2];
- d = ctx->h[3];
- e = ctx->h[4];
- f = ctx->h[5];
- g = ctx->h[6];
- h = ctx->h[7];
-
- if (!is_endian.little && sizeof(HASH_LONG) == 4 && ((size_t)in % 4) == 0) {
- const HASH_LONG *W = (const HASH_LONG *)data;
-
- T1 = X[0] = W[0];
- ROUND_00_15(0, a, b, c, d, e, f, g, h);
- T1 = X[1] = W[1];
- ROUND_00_15(1, h, a, b, c, d, e, f, g);
- T1 = X[2] = W[2];
- ROUND_00_15(2, g, h, a, b, c, d, e, f);
- T1 = X[3] = W[3];
- ROUND_00_15(3, f, g, h, a, b, c, d, e);
- T1 = X[4] = W[4];
- ROUND_00_15(4, e, f, g, h, a, b, c, d);
- T1 = X[5] = W[5];
- ROUND_00_15(5, d, e, f, g, h, a, b, c);
- T1 = X[6] = W[6];
- ROUND_00_15(6, c, d, e, f, g, h, a, b);
- T1 = X[7] = W[7];
- ROUND_00_15(7, b, c, d, e, f, g, h, a);
- T1 = X[8] = W[8];
- ROUND_00_15(8, a, b, c, d, e, f, g, h);
- T1 = X[9] = W[9];
- ROUND_00_15(9, h, a, b, c, d, e, f, g);
- T1 = X[10] = W[10];
- ROUND_00_15(10, g, h, a, b, c, d, e, f);
- T1 = X[11] = W[11];
- ROUND_00_15(11, f, g, h, a, b, c, d, e);
- T1 = X[12] = W[12];
- ROUND_00_15(12, e, f, g, h, a, b, c, d);
- T1 = X[13] = W[13];
- ROUND_00_15(13, d, e, f, g, h, a, b, c);
- T1 = X[14] = W[14];
- ROUND_00_15(14, c, d, e, f, g, h, a, b);
- T1 = X[15] = W[15];
- ROUND_00_15(15, b, c, d, e, f, g, h, a);
-
- data += HASH_CBLOCK;
- } else {
- HASH_LONG l;
-
- HOST_c2l(data, l);
- T1 = X[0] = l;
- ROUND_00_15(0, a, b, c, d, e, f, g, h);
- HOST_c2l(data, l);
- T1 = X[1] = l;
- ROUND_00_15(1, h, a, b, c, d, e, f, g);
- HOST_c2l(data, l);
- T1 = X[2] = l;
- ROUND_00_15(2, g, h, a, b, c, d, e, f);
- HOST_c2l(data, l);
- T1 = X[3] = l;
- ROUND_00_15(3, f, g, h, a, b, c, d, e);
- HOST_c2l(data, l);
- T1 = X[4] = l;
- ROUND_00_15(4, e, f, g, h, a, b, c, d);
- HOST_c2l(data, l);
- T1 = X[5] = l;
- ROUND_00_15(5, d, e, f, g, h, a, b, c);
- HOST_c2l(data, l);
- T1 = X[6] = l;
- ROUND_00_15(6, c, d, e, f, g, h, a, b);
- HOST_c2l(data, l);
- T1 = X[7] = l;
- ROUND_00_15(7, b, c, d, e, f, g, h, a);
- HOST_c2l(data, l);
- T1 = X[8] = l;
- ROUND_00_15(8, a, b, c, d, e, f, g, h);
- HOST_c2l(data, l);
- T1 = X[9] = l;
- ROUND_00_15(9, h, a, b, c, d, e, f, g);
- HOST_c2l(data, l);
- T1 = X[10] = l;
- ROUND_00_15(10, g, h, a, b, c, d, e, f);
- HOST_c2l(data, l);
- T1 = X[11] = l;
- ROUND_00_15(11, f, g, h, a, b, c, d, e);
- HOST_c2l(data, l);
- T1 = X[12] = l;
- ROUND_00_15(12, e, f, g, h, a, b, c, d);
- HOST_c2l(data, l);
- T1 = X[13] = l;
- ROUND_00_15(13, d, e, f, g, h, a, b, c);
- HOST_c2l(data, l);
- T1 = X[14] = l;
- ROUND_00_15(14, c, d, e, f, g, h, a, b);
- HOST_c2l(data, l);
- T1 = X[15] = l;
- ROUND_00_15(15, b, c, d, e, f, g, h, a);
- }
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+ f = state[5];
+ g = state[6];
+ h = state[7];
+
+ uint32_t l;
+
+ HOST_c2l(data, l);
+ T1 = X[0] = l;
+ ROUND_00_15(0, a, b, c, d, e, f, g, h);
+ HOST_c2l(data, l);
+ T1 = X[1] = l;
+ ROUND_00_15(1, h, a, b, c, d, e, f, g);
+ HOST_c2l(data, l);
+ T1 = X[2] = l;
+ ROUND_00_15(2, g, h, a, b, c, d, e, f);
+ HOST_c2l(data, l);
+ T1 = X[3] = l;
+ ROUND_00_15(3, f, g, h, a, b, c, d, e);
+ HOST_c2l(data, l);
+ T1 = X[4] = l;
+ ROUND_00_15(4, e, f, g, h, a, b, c, d);
+ HOST_c2l(data, l);
+ T1 = X[5] = l;
+ ROUND_00_15(5, d, e, f, g, h, a, b, c);
+ HOST_c2l(data, l);
+ T1 = X[6] = l;
+ ROUND_00_15(6, c, d, e, f, g, h, a, b);
+ HOST_c2l(data, l);
+ T1 = X[7] = l;
+ ROUND_00_15(7, b, c, d, e, f, g, h, a);
+ HOST_c2l(data, l);
+ T1 = X[8] = l;
+ ROUND_00_15(8, a, b, c, d, e, f, g, h);
+ HOST_c2l(data, l);
+ T1 = X[9] = l;
+ ROUND_00_15(9, h, a, b, c, d, e, f, g);
+ HOST_c2l(data, l);
+ T1 = X[10] = l;
+ ROUND_00_15(10, g, h, a, b, c, d, e, f);
+ HOST_c2l(data, l);
+ T1 = X[11] = l;
+ ROUND_00_15(11, f, g, h, a, b, c, d, e);
+ HOST_c2l(data, l);
+ T1 = X[12] = l;
+ ROUND_00_15(12, e, f, g, h, a, b, c, d);
+ HOST_c2l(data, l);
+ T1 = X[13] = l;
+ ROUND_00_15(13, d, e, f, g, h, a, b, c);
+ HOST_c2l(data, l);
+ T1 = X[14] = l;
+ ROUND_00_15(14, c, d, e, f, g, h, a, b);
+ HOST_c2l(data, l);
+ T1 = X[15] = l;
+ ROUND_00_15(15, b, c, d, e, f, g, h, a);
for (i = 16; i < 64; i += 8) {
ROUND_16_63(i + 0, a, b, c, d, e, f, g, h, X);
@@ -356,14 +313,14 @@ static void sha256_block_data_order(SHA256_CTX *ctx, const void *in,
ROUND_16_63(i + 7, b, c, d, e, f, g, h, a, X);
}
- ctx->h[0] += a;
- ctx->h[1] += b;
- ctx->h[2] += c;
- ctx->h[3] += d;
- ctx->h[4] += e;
- ctx->h[5] += f;
- ctx->h[6] += g;
- ctx->h[7] += h;
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+ state[5] += f;
+ state[6] += g;
+ state[7] += h;
}
}
diff --git a/src/crypto/sha/sha512.c b/src/crypto/sha/sha512.c
index 57c96ab..6ad8d40 100644
--- a/src/crypto/sha/sha512.c
+++ b/src/crypto/sha/sha512.c
@@ -60,49 +60,39 @@
#include <openssl/mem.h>
-#include "../internal.h"
-
/* IMPLEMENTATION NOTES.
*
- * As you might have noticed 32-bit hash algorithms:
- *
- * - permit SHA_LONG to be wider than 32-bit (case on CRAY);
- * - optimized versions implement two transform functions: one operating
- * on [aligned] data in host byte order and one - on data in input
- * stream byte order;
- * - share common byte-order neutral collector and padding function
- * implementations, ../md32_common.h;
- *
- * Neither of the above applies to this SHA-512 implementations. Reasons
+ * The 32-bit hash algorithms share a common byte-order neutral collector and
+ * padding function implementations that operate on unaligned data,
+ * ../md32_common.h. This SHA-512 implementation does not. Reasons
* [in reverse order] are:
*
- * - it's the only 64-bit hash algorithm for the moment of this writing,
+ * - It's the only 64-bit hash algorithm for the moment of this writing,
* there is no need for common collector/padding implementation [yet];
- * - by supporting only one transform function [which operates on
- * *aligned* data in input stream byte order, big-endian in this case]
- * we minimize burden of maintenance in two ways: a) collector/padding
- * function is simpler; b) only one transform function to stare at;
- * - SHA_LONG64 is required to be exactly 64-bit in order to be able to
- * apply a number of optimizations to mitigate potential performance
- * penalties caused by previous design decision; */
+ * - By supporting only a transform function that operates on *aligned* data
+ * the collector/padding function is simpler and easier to optimize. */
#if !defined(OPENSSL_NO_ASM) && \
(defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \
defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))
-#define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
#define SHA512_ASM
#endif
+#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \
+ defined(__ARM_FEATURE_UNALIGNED)
+#define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
+#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;
@@ -113,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;
@@ -163,7 +153,7 @@ uint8_t *SHA512(const uint8_t *data, size_t len, uint8_t *out) {
#if !defined(SHA512_ASM)
static
#endif
-void sha512_block_data_order(SHA512_CTX *ctx, const void *in, size_t num);
+void sha512_block_data_order(uint64_t *state, const uint64_t *W, size_t num);
int SHA384_Final(uint8_t *md, SHA512_CTX *sha) {
@@ -181,7 +171,7 @@ void SHA512_Transform(SHA512_CTX *c, const uint8_t *data) {
data = c->u.p;
}
#endif
- sha512_block_data_order(c, data, 1);
+ sha512_block_data_order(c->h, (uint64_t *)data, 1);
}
int SHA512_Update(SHA512_CTX *c, const void *in_data, size_t len) {
@@ -193,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++;
}
@@ -213,7 +203,7 @@ int SHA512_Update(SHA512_CTX *c, const void *in_data, size_t len) {
memcpy(p + c->num, data, n), c->num = 0;
len -= n;
data += n;
- sha512_block_data_order(c, p, 1);
+ sha512_block_data_order(c->h, (uint64_t *)p, 1);
}
}
@@ -222,14 +212,14 @@ int SHA512_Update(SHA512_CTX *c, const void *in_data, size_t len) {
if ((size_t)data % sizeof(c->u.d[0]) != 0) {
while (len >= sizeof(c->u)) {
memcpy(p, data, sizeof(c->u));
- sha512_block_data_order(c, p, 1);
+ sha512_block_data_order(c->h, (uint64_t *)p, 1);
len -= sizeof(c->u);
data += sizeof(c->u);
}
} else
#endif
{
- sha512_block_data_order(c, data, len / sizeof(c->u));
+ sha512_block_data_order(c->h, (uint64_t *)data, len / sizeof(c->u));
data += len;
len %= sizeof(c->u);
data -= len;
@@ -253,7 +243,7 @@ int SHA512_Final(uint8_t *md, SHA512_CTX *sha) {
if (n > (sizeof(sha->u) - 16)) {
memset(p + n, 0, sizeof(sha->u) - n);
n = 0;
- sha512_block_data_order(sha, p, 1);
+ sha512_block_data_order(sha->h, (uint64_t *)p, 1);
}
memset(p + n, 0, sizeof(sha->u) - 16 - n);
@@ -274,7 +264,7 @@ int SHA512_Final(uint8_t *md, SHA512_CTX *sha) {
p[sizeof(sha->u) - 15] = (uint8_t)(sha->Nh >> 48);
p[sizeof(sha->u) - 16] = (uint8_t)(sha->Nh >> 56);
- sha512_block_data_order(sha, p, 1);
+ sha512_block_data_order(sha->h, (uint64_t *)p, 1);
if (md == NULL) {
/* TODO(davidben): This NULL check is absent in other low-level hash 'final'
@@ -324,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
@@ -443,23 +447,22 @@ static uint64_t __fastcall __pull64be(const void *x) {
* This code should give better results on 32-bit CPU with less than
* ~24 registers, both size and performance wise...
*/
-static void sha512_block_data_order(SHA512_CTX *ctx, const void *in,
+static void sha512_block_data_order(uint64_t *state, const uint64_t *W,
size_t num) {
- const uint64_t *W = in;
uint64_t A, E, T;
uint64_t X[9 + 80], *F;
int i;
while (num--) {
F = X + 80;
- A = ctx->h[0];
- F[1] = ctx->h[1];
- F[2] = ctx->h[2];
- F[3] = ctx->h[3];
- E = ctx->h[4];
- F[5] = ctx->h[5];
- F[6] = ctx->h[6];
- F[7] = ctx->h[7];
+ A = state[0];
+ F[1] = state[1];
+ F[2] = state[2];
+ F[3] = state[3];
+ E = state[4];
+ F[5] = state[5];
+ F[6] = state[6];
+ F[7] = state[7];
for (i = 0; i < 16; i++, F--) {
T = PULL64(W[i]);
@@ -484,14 +487,14 @@ static void sha512_block_data_order(SHA512_CTX *ctx, const void *in,
A = T + Sigma0(A) + Maj(A, F[1], F[2]);
}
- ctx->h[0] += A;
- ctx->h[1] += F[1];
- ctx->h[2] += F[2];
- ctx->h[3] += F[3];
- ctx->h[4] += E;
- ctx->h[5] += F[5];
- ctx->h[6] += F[6];
- ctx->h[7] += F[7];
+ state[0] += A;
+ state[1] += F[1];
+ state[2] += F[2];
+ state[3] += F[3];
+ state[4] += E;
+ state[5] += F[5];
+ state[6] += F[6];
+ state[7] += F[7];
W += 16;
}
@@ -517,23 +520,22 @@ static void sha512_block_data_order(SHA512_CTX *ctx, const void *in,
ROUND_00_15(i + j, a, b, c, d, e, f, g, h); \
} while (0)
-static void sha512_block_data_order(SHA512_CTX *ctx, const void *in,
+static void sha512_block_data_order(uint64_t *state, const uint64_t *W,
size_t num) {
- const uint64_t *W = in;
uint64_t a, b, c, d, e, f, g, h, s0, s1, T1;
uint64_t X[16];
int i;
while (num--) {
- a = ctx->h[0];
- b = ctx->h[1];
- c = ctx->h[2];
- d = ctx->h[3];
- e = ctx->h[4];
- f = ctx->h[5];
- g = ctx->h[6];
- h = ctx->h[7];
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+ f = state[5];
+ g = state[6];
+ h = state[7];
T1 = X[0] = PULL64(W[0]);
ROUND_00_15(0, a, b, c, d, e, f, g, h);
@@ -587,14 +589,14 @@ static void sha512_block_data_order(SHA512_CTX *ctx, const void *in,
ROUND_16_80(i, 15, b, c, d, e, f, g, h, a, X);
}
- ctx->h[0] += a;
- ctx->h[1] += b;
- ctx->h[2] += c;
- ctx->h[3] += d;
- ctx->h[4] += e;
- ctx->h[5] += f;
- ctx->h[6] += g;
- ctx->h[7] += h;
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+ state[5] += f;
+ state[6] += g;
+ state[7] += h;
W += 16;
}
diff --git a/src/crypto/stack/CMakeLists.txt b/src/crypto/stack/CMakeLists.txt
index bdb0599..dcd8ef4 100644
--- a/src/crypto/stack/CMakeLists.txt
+++ b/src/crypto/stack/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
stack
diff --git a/src/crypto/test/CMakeLists.txt b/src/crypto/test/CMakeLists.txt
index 84a6174..8c75314 100644
--- a/src/crypto/test/CMakeLists.txt
+++ b/src/crypto/test/CMakeLists.txt
@@ -5,4 +5,5 @@ add_library(
file_test.cc
malloc.cc
+ test_util.cc
)
diff --git a/src/crypto/test/file_test.cc b/src/crypto/test/file_test.cc
index 8df6f9a..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");
@@ -128,6 +126,7 @@ FileTest::ReadResult FileTest::ReadNext() {
const char *delimiter = FindDelimiter(buf);
if (delimiter == nullptr) {
fprintf(stderr, "Line %u: Could not parse attribute.\n", line_);
+ return kReadError;
}
std::string key = StripSpace(buf, delimiter - buf);
std::string value = StripSpace(delimiter + 1,
diff --git a/src/crypto/test/file_test.h b/src/crypto/test/file_test.h
index 7303d8a..24651ab 100644
--- a/src/crypto/test/file_test.h
+++ b/src/crypto/test/file_test.h
@@ -18,11 +18,19 @@
#include <stdint.h>
#include <stdio.h>
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable: 4702)
+#endif
+
#include <string>
#include <map>
#include <set>
#include <vector>
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
// File-based test framework.
//
diff --git a/src/crypto/test/malloc.cc b/src/crypto/test/malloc.cc
index 9ffdf01..898f2a7 100644
--- a/src/crypto/test/malloc.cc
+++ b/src/crypto/test/malloc.cc
@@ -34,6 +34,8 @@
#if defined(__linux__) && defined(OPENSSL_GLIBC) && !defined(OPENSSL_ARM) && \
!defined(OPENSSL_AARCH64) && !defined(OPENSSL_ASAN)
+#include <errno.h>
+#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -45,14 +47,14 @@
/* This file defines overrides for the standard allocation functions that allow
* a given allocation to be made to fail for testing. If the program is run
* with MALLOC_NUMBER_TO_FAIL set to a base-10 number then that allocation will
- * return NULL. If MALLOC_ABORT_ON_FAIL is also defined then the allocation
- * will abort() rather than return NULL.
+ * return NULL. If MALLOC_BREAK_ON_FAIL is also defined then the allocation
+ * will signal SIGTRAP rather than return NULL.
*
* This code is not thread safe. */
static uint64_t current_malloc_count = 0;
static uint64_t malloc_number_to_fail = 0;
-static char failure_enabled = 0, abort_on_fail = 0;
+static char failure_enabled = 0, break_on_fail = 0;
static int in_call = 0;
extern "C" {
@@ -95,7 +97,7 @@ static int should_fail_allocation() {
std::set_new_handler(cpp_new_handler);
}
}
- abort_on_fail = (NULL != getenv("MALLOC_ABORT_ON_FAIL"));
+ break_on_fail = (NULL != getenv("MALLOC_BREAK_ON_FAIL"));
init = 1;
}
@@ -108,8 +110,8 @@ static int should_fail_allocation() {
should_fail = (current_malloc_count == malloc_number_to_fail);
current_malloc_count++;
- if (should_fail && abort_on_fail) {
- abort();
+ if (should_fail && break_on_fail) {
+ raise(SIGTRAP);
}
return should_fail;
}
@@ -118,6 +120,7 @@ extern "C" {
void *malloc(size_t size) {
if (should_fail_allocation()) {
+ errno = ENOMEM;
return NULL;
}
@@ -126,6 +129,7 @@ void *malloc(size_t size) {
void *calloc(size_t num_elems, size_t size) {
if (should_fail_allocation()) {
+ errno = ENOMEM;
return NULL;
}
@@ -134,6 +138,7 @@ void *calloc(size_t num_elems, size_t size) {
void *realloc(void *ptr, size_t size) {
if (should_fail_allocation()) {
+ errno = ENOMEM;
return NULL;
}
diff --git a/src/crypto/test/scoped_types.h b/src/crypto/test/scoped_types.h
index c5c8cfe..590f926 100644
--- a/src/crypto/test/scoped_types.h
+++ b/src/crypto/test/scoped_types.h
@@ -18,6 +18,9 @@
#include <stdint.h>
#include <stdio.h>
+#include <memory>
+
+#include <openssl/aead.h>
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/cmac.h>
@@ -33,8 +36,6 @@
#include <openssl/stack.h>
#include <openssl/x509.h>
-#include "stl_compat.h"
-
template<typename T, void (*func)(T*)>
struct OpenSSLDeleter {
@@ -65,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*)>
@@ -112,9 +113,14 @@ using ScopedPKCS12 = ScopedOpenSSLType<PKCS12, PKCS12_free>;
using ScopedRSA = ScopedOpenSSLType<RSA, RSA_free>;
using ScopedX509 = ScopedOpenSSLType<X509, X509_free>;
using ScopedX509_ALGOR = ScopedOpenSSLType<X509_ALGOR, X509_ALGOR_free>;
+using ScopedX509_SIG = ScopedOpenSSLType<X509_SIG, X509_SIG_free>;
using ScopedX509Stack = ScopedOpenSSLStack<STACK_OF(X509), X509, X509_free>;
+using ScopedCBB = ScopedOpenSSLContext<CBB, void, CBB_zero, CBB_cleanup>;
+using ScopedEVP_AEAD_CTX = ScopedOpenSSLContext<EVP_AEAD_CTX, void,
+ EVP_AEAD_CTX_zero,
+ EVP_AEAD_CTX_cleanup>;
using ScopedEVP_CIPHER_CTX = ScopedOpenSSLContext<EVP_CIPHER_CTX, int,
EVP_CIPHER_CTX_init,
EVP_CIPHER_CTX_cleanup>;
@@ -123,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/header_removed.h b/src/crypto/test/test_util.cc
index 49ee31a..8021aaa 100644
--- a/src/crypto/header_removed.h
+++ b/src/crypto/test/test_util.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, Google Inc.
+/* 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
@@ -12,6 +12,19 @@
* 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. */
+#include <stdint.h>
+#include <stdio.h>
+
+#include "test_util.h"
+
+
+void hexdump(FILE *fp, const char *msg, const void *in, size_t len) {
+ const uint8_t *data = reinterpret_cast<const uint8_t*>(in);
+ size_t i;
+
+ fputs(msg, fp);
+ for (i = 0; i < len; i++) {
+ fprintf(fp, "%02x", data[i]);
+ }
+ fputs("\n", fp);
+}
diff --git a/src/crypto/rand/hwrand.c b/src/crypto/test/test_util.h
index 73d3de7..972e206 100644
--- a/src/crypto/rand/hwrand.c
+++ b/src/crypto/test/test_util.h
@@ -12,45 +12,24 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
-#include <openssl/rand.h>
+#ifndef OPENSSL_HEADER_CRYPTO_TEST_TEST_UTIL_H
+#define OPENSSL_HEADER_CRYPTO_TEST_TEST_UTIL_H
-#include <stdlib.h>
-#include <string.h>
-
-#include <openssl/cpu.h>
+#include <stddef.h>
+#include <stdio.h>
+#if defined(__cplusplus)
+extern "C" {
+#endif
-#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM)
-int CRYPTO_have_hwrand(void) {
- return (OPENSSL_ia32cap_P[1] & (1u << 30)) != 0;
-}
-
-/* CRYPTO_rdrand is defined in asm/rdrand-x86_64.pl */
-extern uint64_t CRYPTO_rdrand(void);
-
-void CRYPTO_hwrand(uint8_t *buf, size_t len) {
- while (len >= 8) {
- uint64_t rand = CRYPTO_rdrand();
- memcpy(buf, &rand, sizeof(rand));
- len -= sizeof(rand);
- buf += sizeof(rand);
- }
-
- if (len > 0) {
- uint64_t rand = CRYPTO_rdrand();
- memcpy(buf, &rand, len);
- }
-}
+/* hexdump writes |msg| to |fp| followed by the hex encoding of |len| bytes
+ * from |in|. */
+void hexdump(FILE *fp, const char *msg, const void *in, size_t len);
-#else
-int CRYPTO_have_hwrand(void) {
- return 0;
+#if defined(__cplusplus)
}
-
-void CRYPTO_hwrand(uint8_t *buf, size_t len) {
- abort();
-}
-
#endif
+
+#endif /* OPENSSL_HEADER_CRYPTO_TEST_TEST_UTIL_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/time_support.c b/src/crypto/time_support.c
index bf9daed..ae0f496 100644
--- a/src/crypto/time_support.c
+++ b/src/crypto/time_support.c
@@ -59,12 +59,6 @@
#define _POSIX_C_SOURCE 201410L /* for gmtime_r */
#endif
-#if defined(__MINGW32__)
-#define MINGW_HAS_SECURE_API 1 /* supplied by libmingwex */
-#include <sec_api/time_s.h> /* for correct definition of gmtime_s */
-#undef MINGW_HAS_SECURE_API
-#endif
-
#include <openssl/time_support.h>
#include <time.h>
diff --git a/src/crypto/x509/CMakeLists.txt b/src/crypto/x509/CMakeLists.txt
index 3bb5704..8ffeaa0 100644
--- a/src/crypto/x509/CMakeLists.txt
+++ b/src/crypto/x509/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
x509
@@ -15,6 +15,7 @@ add_library(
i2d_pr.c
pkcs7.c
t_crl.c
+ t_req.c
t_x509.c
t_x509a.c
x509.c
@@ -64,3 +65,4 @@ add_executable(
)
target_link_libraries(pkcs7_test crypto)
+add_dependencies(all_tests pkcs7_test)
diff --git a/src/crypto/x509/a_digest.c b/src/crypto/x509/a_digest.c
index 6060bbd..430e2e6 100644
--- a/src/crypto/x509/a_digest.c
+++ b/src/crypto/x509/a_digest.c
@@ -71,7 +71,7 @@ int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
i=i2d(data,NULL);
if ((str=(unsigned char *)OPENSSL_malloc(i)) == NULL)
{
- OPENSSL_PUT_ERROR(X509, ASN1_digest, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return(0);
}
p=str;
diff --git a/src/crypto/x509/a_sign.c b/src/crypto/x509/a_sign.c
index f219c23..4e9be8a 100644
--- a/src/crypto/x509/a_sign.c
+++ b/src/crypto/x509/a_sign.c
@@ -106,7 +106,7 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it,
if ((buf_in == NULL) || (buf_out == NULL))
{
outl=0;
- OPENSSL_PUT_ERROR(X509, ASN1_item_sign_ctx, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -114,7 +114,7 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it,
|| !EVP_DigestSignFinal(ctx, buf_out, &outl))
{
outl=0;
- OPENSSL_PUT_ERROR(X509, ASN1_item_sign_ctx, ERR_R_EVP_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB);
goto err;
}
if (signature->data != NULL) OPENSSL_free(signature->data);
diff --git a/src/crypto/x509/a_verify.c b/src/crypto/x509/a_verify.c
index 72e0a62..572a139 100644
--- a/src/crypto/x509/a_verify.c
+++ b/src/crypto/x509/a_verify.c
@@ -80,13 +80,13 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
if (!pkey)
{
- OPENSSL_PUT_ERROR(X509, ASN1_item_verify, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7)
{
- OPENSSL_PUT_ERROR(X509, ASN1_item_verify, X509_R_INVALID_BIT_STRING_BITS_LEFT);
+ OPENSSL_PUT_ERROR(X509, X509_R_INVALID_BIT_STRING_BITS_LEFT);
return 0;
}
@@ -101,7 +101,7 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
if (buf_in == NULL)
{
- OPENSSL_PUT_ERROR(X509, ASN1_item_verify, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -109,7 +109,7 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
{
OPENSSL_cleanse(buf_in,(unsigned int)inl);
OPENSSL_free(buf_in);
- OPENSSL_PUT_ERROR(X509, ASN1_item_verify, ERR_R_EVP_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB);
goto err;
}
@@ -119,7 +119,7 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
if (EVP_DigestVerifyFinal(&ctx,signature->data,
(size_t)signature->length) <= 0)
{
- OPENSSL_PUT_ERROR(X509, ASN1_item_verify, ERR_R_EVP_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB);
goto err;
}
/* we don't need to zero the 'ctx' because we just checked
diff --git a/src/crypto/x509/asn1_gen.c b/src/crypto/x509/asn1_gen.c
index d4d1ee6..850a816 100644
--- a/src/crypto/x509/asn1_gen.c
+++ b/src/crypto/x509/asn1_gen.c
@@ -171,7 +171,7 @@ ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
{
if (!cnf)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_generate_v3, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG);
return NULL;
}
ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf);
@@ -314,7 +314,7 @@ static int asn1_cb(const char *elem, int len, void *bitstr)
if (utype == -1)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_cb, ASN1_R_UNKNOWN_TAG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_TAG);
ERR_add_error_data(2, "tag=", elem);
return -1;
}
@@ -327,7 +327,7 @@ static int asn1_cb(const char *elem, int len, void *bitstr)
/* If no value and not end of string, error */
if (!vstart && elem[len])
{
- OPENSSL_PUT_ERROR(ASN1, asn1_cb, ASN1_R_MISSING_VALUE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE);
return -1;
}
return 0;
@@ -340,7 +340,7 @@ static int asn1_cb(const char *elem, int len, void *bitstr)
/* Check for illegal multiple IMPLICIT tagging */
if (arg->imp_tag != -1)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_cb, ASN1_R_ILLEGAL_NESTED_TAGGING);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING);
return -1;
}
if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class))
@@ -378,7 +378,7 @@ static int asn1_cb(const char *elem, int len, void *bitstr)
case ASN1_GEN_FLAG_FORMAT:
if (!vstart)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_cb, ASN1_R_UNKNOWN_FORMAT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
return -1;
}
if (!strncmp(vstart, "ASCII", 5))
@@ -391,7 +391,7 @@ static int asn1_cb(const char *elem, int len, void *bitstr)
arg->format = ASN1_GEN_FORMAT_BITLIST;
else
{
- OPENSSL_PUT_ERROR(ASN1, asn1_cb, ASN1_R_UNKNOWN_FORMAT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
return -1;
}
break;
@@ -415,7 +415,7 @@ static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass)
return 0;
if (tag_num < 0)
{
- OPENSSL_PUT_ERROR(ASN1, parse_tagging, ASN1_R_INVALID_NUMBER);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER);
return 0;
}
*ptag = tag_num;
@@ -448,7 +448,7 @@ static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass)
default:
erch[0] = *eptr;
erch[1] = 0;
- OPENSSL_PUT_ERROR(ASN1, parse_tagging, ASN1_R_INVALID_MODIFIER);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_MODIFIER);
ERR_add_error_data(2, "Char=", erch);
return 0;
break;
@@ -534,13 +534,13 @@ static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_cons
/* Can only have IMPLICIT if permitted */
if ((arg->imp_tag != -1) && !imp_ok)
{
- OPENSSL_PUT_ERROR(ASN1, append_exp, ASN1_R_ILLEGAL_IMPLICIT_TAG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_IMPLICIT_TAG);
return 0;
}
if (arg->exp_count == ASN1_FLAG_EXP_MAX)
{
- OPENSSL_PUT_ERROR(ASN1, append_exp, ASN1_R_DEPTH_EXCEEDED);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_DEPTH_EXCEEDED);
return 0;
}
@@ -658,7 +658,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
if (!(atmp = ASN1_TYPE_new()))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -671,7 +671,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
case V_ASN1_NULL:
if (str && *str)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_ILLEGAL_NULL_VALUE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL_VALUE);
goto bad_form;
}
break;
@@ -679,7 +679,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
case V_ASN1_BOOLEAN:
if (format != ASN1_GEN_FORMAT_ASCII)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_NOT_ASCII_FORMAT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ASCII_FORMAT);
goto bad_form;
}
vtmp.name = NULL;
@@ -687,7 +687,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
vtmp.value = (char *)str;
if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_ILLEGAL_BOOLEAN);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BOOLEAN);
goto bad_str;
}
break;
@@ -696,12 +696,12 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
case V_ASN1_ENUMERATED:
if (format != ASN1_GEN_FORMAT_ASCII)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_INTEGER_NOT_ASCII_FORMAT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_NOT_ASCII_FORMAT);
goto bad_form;
}
if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str)))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_ILLEGAL_INTEGER);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_INTEGER);
goto bad_str;
}
break;
@@ -709,12 +709,12 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
case V_ASN1_OBJECT:
if (format != ASN1_GEN_FORMAT_ASCII)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_OBJECT_NOT_ASCII_FORMAT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_OBJECT_NOT_ASCII_FORMAT);
goto bad_form;
}
if (!(atmp->value.object = OBJ_txt2obj(str, 0)))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_ILLEGAL_OBJECT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OBJECT);
goto bad_str;
}
break;
@@ -723,23 +723,23 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
case V_ASN1_GENERALIZEDTIME:
if (format != ASN1_GEN_FORMAT_ASCII)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_TIME_NOT_ASCII_FORMAT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_TIME_NOT_ASCII_FORMAT);
goto bad_form;
}
if (!(atmp->value.asn1_string = ASN1_STRING_new()))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto bad_str;
}
if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto bad_str;
}
atmp->value.asn1_string->type = utype;
if (!ASN1_TIME_check(atmp->value.asn1_string))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_ILLEGAL_TIME_VALUE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TIME_VALUE);
goto bad_str;
}
@@ -761,7 +761,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
format = MBSTRING_UTF8;
else
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_ILLEGAL_FORMAT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_FORMAT);
goto bad_form;
}
@@ -769,7 +769,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str,
-1, format, ASN1_tag2bit(utype)) <= 0)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto bad_str;
}
@@ -782,7 +782,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
if (!(atmp->value.asn1_string = ASN1_STRING_new()))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto bad_form;
}
@@ -791,7 +791,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
if (!(rdata = string_to_hex((char *)str, &rdlen)))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_ILLEGAL_HEX);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_HEX);
goto bad_str;
}
@@ -806,7 +806,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
{
if (!CONF_parse_list(str, ',', 1, bitstr_cb, atmp->value.bit_string))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_LIST_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_LIST_ERROR);
goto bad_str;
}
no_unused = 0;
@@ -814,7 +814,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
}
else
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_ILLEGAL_BITSTRING_FORMAT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BITSTRING_FORMAT);
goto bad_form;
}
@@ -830,7 +830,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
break;
default:
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_UNSUPPORTED_TYPE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_TYPE);
goto bad_str;
break;
}
@@ -860,12 +860,12 @@ static int bitstr_cb(const char *elem, int len, void *bitstr)
return 0;
if (bitnum < 0)
{
- OPENSSL_PUT_ERROR(ASN1, bitstr_cb, ASN1_R_INVALID_NUMBER);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER);
return 0;
}
if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1))
{
- OPENSSL_PUT_ERROR(ASN1, bitstr_cb, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return 0;
}
return 1;
diff --git a/src/crypto/x509/by_dir.c b/src/crypto/x509/by_dir.c
index 34bb1e4..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 */
@@ -139,7 +139,7 @@ static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
X509_FILETYPE_PEM);
if (!ret)
{
- OPENSSL_PUT_ERROR(X509, dir_ctrl, X509_R_LOADING_CERT_DIR);
+ OPENSSL_PUT_ERROR(X509, X509_R_LOADING_CERT_DIR);
}
}
else
@@ -208,7 +208,7 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type)
if (dir == NULL || !*dir)
{
- OPENSSL_PUT_ERROR(X509, add_cert_dir, X509_R_INVALID_DIRECTORY);
+ OPENSSL_PUT_ERROR(X509, X509_R_INVALID_DIRECTORY);
return 0;
}
@@ -237,7 +237,7 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type)
ctx->dirs = sk_BY_DIR_ENTRY_new_null();
if (!ctx->dirs)
{
- OPENSSL_PUT_ERROR(X509, add_cert_dir, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return 0;
}
}
@@ -311,13 +311,13 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
}
else
{
- OPENSSL_PUT_ERROR(X509, get_cert_by_subject, X509_R_WRONG_LOOKUP_TYPE);
+ OPENSSL_PUT_ERROR(X509, X509_R_WRONG_LOOKUP_TYPE);
goto finish;
}
if ((b=BUF_MEM_new()) == NULL)
{
- OPENSSL_PUT_ERROR(X509, get_cert_by_subject, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
goto finish;
}
@@ -337,7 +337,7 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
j=strlen(ent->dir)+1+8+6+1+1;
if (!BUF_MEM_grow(b,j))
{
- OPENSSL_PUT_ERROR(X509, get_cert_by_subject, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
goto finish;
}
if (type == X509_LU_CRL && ent->hashes)
diff --git a/src/crypto/x509/by_file.c b/src/crypto/x509/by_file.c
index 2fdbce4..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 */
@@ -109,7 +109,7 @@ static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
if (!ok)
{
- OPENSSL_PUT_ERROR(X509, by_file_ctrl, X509_R_LOADING_DEFAULTS);
+ OPENSSL_PUT_ERROR(X509, X509_R_LOADING_DEFAULTS);
}
}
else
@@ -137,7 +137,7 @@ int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type)
if ((in == NULL) || (BIO_read_filename(in,file) <= 0))
{
- OPENSSL_PUT_ERROR(X509, X509_load_cert_file, ERR_R_SYS_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB);
goto err;
}
@@ -156,7 +156,7 @@ int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type)
}
else
{
- OPENSSL_PUT_ERROR(X509, X509_load_cert_file, ERR_R_PEM_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_PEM_LIB);
goto err;
}
}
@@ -173,7 +173,7 @@ int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type)
x=d2i_X509_bio(in,NULL);
if (x == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_load_cert_file, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB);
goto err;
}
i=X509_STORE_add_cert(ctx->store_ctx,x);
@@ -182,7 +182,7 @@ int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type)
}
else
{
- OPENSSL_PUT_ERROR(X509, X509_load_cert_file, X509_R_BAD_X509_FILETYPE);
+ OPENSSL_PUT_ERROR(X509, X509_R_BAD_X509_FILETYPE);
goto err;
}
err:
@@ -203,7 +203,7 @@ int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type)
if ((in == NULL) || (BIO_read_filename(in,file) <= 0))
{
- OPENSSL_PUT_ERROR(X509, X509_load_crl_file, ERR_R_SYS_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB);
goto err;
}
@@ -222,7 +222,7 @@ int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type)
}
else
{
- OPENSSL_PUT_ERROR(X509, X509_load_crl_file, ERR_R_PEM_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_PEM_LIB);
goto err;
}
}
@@ -239,7 +239,7 @@ int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type)
x=d2i_X509_CRL_bio(in,NULL);
if (x == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_load_crl_file, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB);
goto err;
}
i=X509_STORE_add_crl(ctx->store_ctx,x);
@@ -248,7 +248,7 @@ int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type)
}
else
{
- OPENSSL_PUT_ERROR(X509, X509_load_crl_file, X509_R_BAD_X509_FILETYPE);
+ OPENSSL_PUT_ERROR(X509, X509_R_BAD_X509_FILETYPE);
goto err;
}
err:
@@ -268,13 +268,13 @@ int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type)
return X509_load_cert_file(ctx, file, type);
in = BIO_new_file(file, "r");
if(!in) {
- OPENSSL_PUT_ERROR(X509, X509_load_cert_crl_file, ERR_R_SYS_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB);
return 0;
}
inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
BIO_free(in);
if(!inf) {
- OPENSSL_PUT_ERROR(X509, X509_load_cert_crl_file, ERR_R_PEM_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_PEM_LIB);
return 0;
}
for(i = 0; i < sk_X509_INFO_num(inf); i++) {
diff --git a/src/crypto/x509/i2d_pr.c b/src/crypto/x509/i2d_pr.c
index 443ca53..e7f4269 100644
--- a/src/crypto/x509/i2d_pr.c
+++ b/src/crypto/x509/i2d_pr.c
@@ -78,7 +78,7 @@ int i2d_PrivateKey(const EVP_PKEY *a, unsigned char **pp)
}
/* Although this file is in crypto/x509 for layering reasons, it emits
* an error code from ASN1 for OpenSSL compatibility. */
- OPENSSL_PUT_ERROR(ASN1, i2d_PrivateKey, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
return -1;
}
diff --git a/src/crypto/x509/pkcs7.c b/src/crypto/x509/pkcs7.c
index 99ee3da..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>
@@ -57,8 +58,7 @@ static int pkcs7_parse_header(uint8_t **der_bytes, CBS *out, CBS *cbs) {
}
if (OBJ_cbs2nid(&content_type) != NID_pkcs7_signed) {
- OPENSSL_PUT_ERROR(X509, pkcs7_parse_header,
- X509_R_NOT_PKCS7_SIGNED_DATA);
+ OPENSSL_PUT_ERROR(X509, X509_R_NOT_PKCS7_SIGNED_DATA);
goto err;
}
@@ -73,8 +73,7 @@ static int pkcs7_parse_header(uint8_t **der_bytes, CBS *out, CBS *cbs) {
}
if (version < 1) {
- OPENSSL_PUT_ERROR(X509, pkcs7_parse_header,
- X509_R_BAD_PKCS7_VERSION);
+ OPENSSL_PUT_ERROR(X509, X509_R_BAD_PKCS7_VERSION);
goto err;
}
@@ -103,8 +102,7 @@ int PKCS7_get_certificates(STACK_OF(X509) *out_certs, CBS *cbs) {
/* See https://tools.ietf.org/html/rfc2315#section-9.1 */
if (!CBS_get_asn1(&signed_data, &certificates,
CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) {
- OPENSSL_PUT_ERROR(X509, PKCS7_get_certificates,
- X509_R_NO_CERTIFICATES_INCLUDED);
+ OPENSSL_PUT_ERROR(X509, X509_R_NO_CERTIFICATES_INCLUDED);
goto err;
}
@@ -117,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;
}
@@ -171,8 +172,7 @@ int PKCS7_get_CRLs(STACK_OF(X509_CRL) *out_crls, CBS *cbs) {
if (!CBS_get_asn1(&signed_data, &crls,
CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1)) {
- OPENSSL_PUT_ERROR(X509, PKCS7_get_CRLs,
- X509_R_NO_CRLS_INCLUDED);
+ OPENSSL_PUT_ERROR(X509, X509_R_NO_CRLS_INCLUDED);
goto err;
}
@@ -185,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/t_crl.c b/src/crypto/x509/t_crl.c
index 93a7afb..a2d8bc7 100644
--- a/src/crypto/x509/t_crl.c
+++ b/src/crypto/x509/t_crl.c
@@ -70,7 +70,7 @@ int X509_CRL_print_fp(FILE *fp, X509_CRL *x)
if ((b=BIO_new(BIO_s_file())) == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_CRL_print_fp, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,fp,BIO_NOCLOSE);
diff --git a/src/crypto/x509/t_req.c b/src/crypto/x509/t_req.c
new file mode 100644
index 0000000..39c836c
--- /dev/null
+++ b/src/crypto/x509/t_req.c
@@ -0,0 +1,246 @@
+/* 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.] */
+
+#include <stdio.h>
+
+#include <openssl/bn.h>
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+
+int X509_REQ_print_fp(FILE *fp, X509_REQ *x) {
+ BIO *bio = BIO_new(BIO_s_file());
+ if (bio == NULL) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
+ return 0;
+ }
+
+ BIO_set_fp(bio, fp, BIO_NOCLOSE);
+ int ret = X509_REQ_print(bio, x);
+ BIO_free(bio);
+ return ret;
+}
+
+int X509_REQ_print_ex(BIO *bio, X509_REQ *x, unsigned long nmflags,
+ unsigned long cflag) {
+ long l;
+ EVP_PKEY *pkey;
+ STACK_OF(X509_ATTRIBUTE) * sk;
+ char mlch = ' ';
+
+ int nmindent = 0;
+
+ if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
+ mlch = '\n';
+ nmindent = 12;
+ }
+
+ if (nmflags == X509_FLAG_COMPAT) {
+ nmindent = 16;
+ }
+
+ X509_REQ_INFO *ri = x->req_info;
+ if (!(cflag & X509_FLAG_NO_HEADER)) {
+ if (BIO_write(bio, "Certificate Request:\n", 21) <= 0 ||
+ BIO_write(bio, " Data:\n", 10) <= 0) {
+ goto err;
+ }
+ }
+ if (!(cflag & X509_FLAG_NO_VERSION)) {
+ l = X509_REQ_get_version(x);
+ if (BIO_printf(bio, "%8sVersion: %ld (0x%lx)\n", "", l + 1, l) <= 0) {
+ goto err;
+ }
+ }
+ if (!(cflag & X509_FLAG_NO_SUBJECT)) {
+ if (BIO_printf(bio, " Subject:%c", mlch) <= 0 ||
+ X509_NAME_print_ex(bio, ri->subject, nmindent, nmflags) < 0 ||
+ BIO_write(bio, "\n", 1) <= 0) {
+ goto err;
+ }
+ }
+ if (!(cflag & X509_FLAG_NO_PUBKEY)) {
+ if (BIO_write(bio, " Subject Public Key Info:\n", 33) <= 0 ||
+ BIO_printf(bio, "%12sPublic Key Algorithm: ", "") <= 0 ||
+ i2a_ASN1_OBJECT(bio, ri->pubkey->algor->algorithm) <= 0 ||
+ BIO_puts(bio, "\n") <= 0) {
+ goto err;
+ }
+
+ pkey = X509_REQ_get_pubkey(x);
+ if (pkey == NULL) {
+ BIO_printf(bio, "%12sUnable to load Public Key\n", "");
+ ERR_print_errors(bio);
+ } else {
+ EVP_PKEY_print_public(bio, pkey, 16, NULL);
+ EVP_PKEY_free(pkey);
+ }
+ }
+
+ if (!(cflag & X509_FLAG_NO_ATTRIBUTES)) {
+ if (BIO_printf(bio, "%8sAttributes:\n", "") <= 0) {
+ goto err;
+ }
+
+ sk = x->req_info->attributes;
+ if (sk_X509_ATTRIBUTE_num(sk) == 0) {
+ if (BIO_printf(bio, "%12sa0:00\n", "") <= 0) {
+ goto err;
+ }
+ } else {
+ size_t i;
+ for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
+ X509_ATTRIBUTE *a = sk_X509_ATTRIBUTE_value(sk, i);
+ ASN1_OBJECT *aobj = X509_ATTRIBUTE_get0_object(a);
+
+ if (X509_REQ_extension_nid(OBJ_obj2nid(aobj))) {
+ continue;
+ }
+
+ if (BIO_printf(bio, "%12s", "") <= 0) {
+ goto err;
+ }
+
+ const int num_attrs = X509_ATTRIBUTE_count(a);
+ const int obj_str_len = i2a_ASN1_OBJECT(bio, aobj);
+ if (obj_str_len <= 0) {
+ if (BIO_puts(bio, "(Unable to print attribute ID.)\n") < 0) {
+ goto err;
+ } else {
+ continue;
+ }
+ }
+
+ int j;
+ for (j = 0; j < num_attrs; j++) {
+ const ASN1_TYPE *at = X509_ATTRIBUTE_get0_type(a, j);
+ const int type = at->type;
+ ASN1_BIT_STRING *bs = at->value.asn1_string;
+
+ int k;
+ for (k = 25 - obj_str_len; k > 0; k--) {
+ if (BIO_write(bio, " ", 1) != 1) {
+ goto err;
+ }
+ }
+
+ if (BIO_puts(bio, ":") <= 0) {
+ goto err;
+ }
+
+ if (type == V_ASN1_PRINTABLESTRING ||
+ type == V_ASN1_UTF8STRING ||
+ type == V_ASN1_IA5STRING ||
+ type == V_ASN1_T61STRING) {
+ if (BIO_write(bio, (char *)bs->data, bs->length) != bs->length) {
+ goto err;
+ }
+ BIO_puts(bio, "\n");
+ } else {
+ BIO_puts(bio, "unable to print attribute\n");
+ }
+ }
+ }
+ }
+ }
+
+ if (!(cflag & X509_FLAG_NO_EXTENSIONS)) {
+ STACK_OF(X509_EXTENSION) *exts = X509_REQ_get_extensions(x);
+ if (exts) {
+ BIO_printf(bio, "%8sRequested Extensions:\n", "");
+
+ size_t i;
+ for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
+ X509_EXTENSION *ex = sk_X509_EXTENSION_value(exts, i);
+ if (BIO_printf(bio, "%12s", "") <= 0) {
+ goto err;
+ }
+ ASN1_OBJECT *obj = X509_EXTENSION_get_object(ex);
+ i2a_ASN1_OBJECT(bio, obj);
+ const int is_critical = X509_EXTENSION_get_critical(ex);
+ if (BIO_printf(bio, ": %s\n", is_critical ? "critical" : "") <= 0) {
+ goto err;
+ }
+ if (!X509V3_EXT_print(bio, ex, cflag, 16)) {
+ BIO_printf(bio, "%16s", "");
+ ASN1_STRING_print(bio, X509_EXTENSION_get_data(ex));
+ }
+ if (BIO_write(bio, "\n", 1) <= 0) {
+ goto err;
+ }
+ }
+ sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
+ }
+ }
+
+ if (!(cflag & X509_FLAG_NO_SIGDUMP) &&
+ !X509_signature_print(bio, x->sig_alg, x->signature)) {
+ goto err;
+ }
+
+ return 1;
+
+err:
+ OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
+ return 0;
+}
+
+int X509_REQ_print(BIO *bio, X509_REQ *req) {
+ return X509_REQ_print_ex(bio, req, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
+}
diff --git a/src/crypto/x509/t_x509.c b/src/crypto/x509/t_x509.c
index 2b9a421..7785ebf 100644
--- a/src/crypto/x509/t_x509.c
+++ b/src/crypto/x509/t_x509.c
@@ -74,7 +74,7 @@ int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag, unsigned long cfla
if ((b=BIO_new(BIO_s_file())) == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_print_ex_fp, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,fp,BIO_NOCLOSE);
@@ -493,7 +493,7 @@ int X509_NAME_print(BIO *bp, X509_NAME *name, int obase)
if (0)
{
err:
- OPENSSL_PUT_ERROR(X509, X509_NAME_print, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
}
OPENSSL_free(b);
return(ret);
diff --git a/src/crypto/x509/x509_att.c b/src/crypto/x509/x509_att.c
index 90e7810..1491484 100644
--- a/src/crypto/x509/x509_att.c
+++ b/src/crypto/x509/x509_att.c
@@ -124,7 +124,7 @@ STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
if (x == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509at_add1_attr, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
goto err2;
}
@@ -144,7 +144,7 @@ STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
*x=sk;
return(sk);
err:
- OPENSSL_PUT_ERROR(X509, X509at_add1_attr, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
err2:
if (new_attr != NULL) X509_ATTRIBUTE_free(new_attr);
if (sk != NULL) sk_X509_ATTRIBUTE_free(sk);
@@ -214,7 +214,7 @@ X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
obj=OBJ_nid2obj(nid);
if (obj == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_ATTRIBUTE_create_by_NID, X509_R_UNKNOWN_NID);
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID);
return(NULL);
}
return X509_ATTRIBUTE_create_by_OBJ(attr,obj,atrtype,data,len);
@@ -229,7 +229,7 @@ X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
{
if ((ret=X509_ATTRIBUTE_new()) == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_ATTRIBUTE_create_by_OBJ, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return(NULL);
}
}
@@ -258,7 +258,7 @@ X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
obj=OBJ_txt2obj(atrname, 0);
if (obj == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_ATTRIBUTE_create_by_txt, X509_R_INVALID_FIELD_NAME);
+ OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_NAME);
ERR_add_error_data(2, "name=", atrname);
return(NULL);
}
@@ -286,7 +286,7 @@ int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *dat
stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype,
OBJ_obj2nid(attr->object));
if(!stmp) {
- OPENSSL_PUT_ERROR(X509, X509_ATTRIBUTE_set1_data, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB);
return 0;
}
atype = stmp->type;
@@ -314,7 +314,7 @@ int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *dat
if(!sk_ASN1_TYPE_push(attr->value.set, ttmp)) goto err;
return 1;
err:
- OPENSSL_PUT_ERROR(X509, X509_ATTRIBUTE_set1_data, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -338,7 +338,7 @@ void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx,
ttmp = X509_ATTRIBUTE_get0_type(attr, idx);
if(!ttmp) return NULL;
if(atrtype != ASN1_TYPE_get(ttmp)){
- OPENSSL_PUT_ERROR(X509, X509_ATTRIBUTE_get0_data, X509_R_WRONG_TYPE);
+ OPENSSL_PUT_ERROR(X509, X509_R_WRONG_TYPE);
return NULL;
}
return ttmp->value.ptr;
diff --git a/src/crypto/x509/x509_cmp.c b/src/crypto/x509/x509_cmp.c
index 712e36b..0e35f3e 100644
--- a/src/crypto/x509/x509_cmp.c
+++ b/src/crypto/x509/x509_cmp.c
@@ -333,13 +333,13 @@ int X509_check_private_key(X509 *x, EVP_PKEY *k)
case 1:
break;
case 0:
- OPENSSL_PUT_ERROR(X509, X509_check_private_key, X509_R_KEY_VALUES_MISMATCH);
+ OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH);
break;
case -1:
- OPENSSL_PUT_ERROR(X509, X509_check_private_key, X509_R_KEY_TYPE_MISMATCH);
+ OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH);
break;
case -2:
- OPENSSL_PUT_ERROR(X509, X509_check_private_key, X509_R_UNKNOWN_KEY_TYPE);
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
}
if (xk)
EVP_PKEY_free(xk);
diff --git a/src/crypto/x509/x509_lu.c b/src/crypto/x509/x509_lu.c
index a662305..5751f75 100644
--- a/src/crypto/x509/x509_lu.c
+++ b/src/crypto/x509/x509_lu.c
@@ -187,12 +187,16 @@ X509_STORE *X509_STORE_new(void)
if ((ret=(X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL)
return NULL;
memset(ret, 0, sizeof(*ret));
- ret->objs = sk_X509_OBJECT_new(x509_object_cmp);
CRYPTO_MUTEX_init(&ret->objs_lock);
+ ret->objs = sk_X509_OBJECT_new(x509_object_cmp);
+ if (ret->objs == NULL)
+ goto err;
ret->cache = 1;
ret->get_cert_methods = sk_X509_LOOKUP_new_null();
-
- if ((ret->param = X509_VERIFY_PARAM_new()) == NULL)
+ if (ret->get_cert_methods == NULL)
+ goto err;
+ ret->param = X509_VERIFY_PARAM_new();
+ if (ret->param == NULL)
goto err;
ret->references = 1;
@@ -200,6 +204,7 @@ X509_STORE *X509_STORE_new(void)
err:
if (ret)
{
+ CRYPTO_MUTEX_cleanup(&ret->objs_lock);
if (ret->param)
X509_VERIFY_PARAM_free(ret->param);
if (ret->get_cert_methods)
@@ -345,7 +350,7 @@ int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
if (obj == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_STORE_add_cert, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return 0;
}
obj->type=X509_LU_X509;
@@ -359,7 +364,7 @@ int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
{
X509_OBJECT_free_contents(obj);
OPENSSL_free(obj);
- OPENSSL_PUT_ERROR(X509, X509_STORE_add_cert, X509_R_CERT_ALREADY_IN_HASH_TABLE);
+ OPENSSL_PUT_ERROR(X509, X509_R_CERT_ALREADY_IN_HASH_TABLE);
ret=0;
}
else sk_X509_OBJECT_push(ctx->objs, obj);
@@ -378,7 +383,7 @@ int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
if (obj == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_STORE_add_crl, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return 0;
}
obj->type=X509_LU_CRL;
@@ -392,7 +397,7 @@ int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
{
X509_OBJECT_free_contents(obj);
OPENSSL_free(obj);
- OPENSSL_PUT_ERROR(X509, X509_STORE_add_crl, X509_R_CERT_ALREADY_IN_HASH_TABLE);
+ OPENSSL_PUT_ERROR(X509, X509_R_CERT_ALREADY_IN_HASH_TABLE);
ret=0;
}
else sk_X509_OBJECT_push(ctx->objs, obj);
@@ -410,7 +415,7 @@ void X509_OBJECT_up_ref_count(X509_OBJECT *a)
X509_up_ref(a->data.x509);
break;
case X509_LU_CRL:
- CRYPTO_refcount_inc(&a->data.crl->references);
+ X509_CRL_up_ref(a->data.crl);
break;
}
}
@@ -436,7 +441,6 @@ static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type,
X509_CINF cinf_s;
X509_CRL crl_s;
X509_CRL_INFO crl_info_s;
- size_t idx;
stmp.type=type;
switch (type)
@@ -456,8 +460,11 @@ static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type,
return -1;
}
- idx = -1;
- if (sk_X509_OBJECT_find(h, &idx, &stmp) && pnmatch)
+ size_t idx;
+ if (!sk_X509_OBJECT_find(h, &idx, &stmp))
+ return -1;
+
+ if (pnmatch != NULL)
{
int tidx;
const X509_OBJECT *tobj, *pstmp;
@@ -498,6 +505,8 @@ STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
X509 *x;
X509_OBJECT *obj;
sk = sk_X509_new_null();
+ if (sk == NULL)
+ return NULL;
CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
if (idx < 0)
@@ -546,13 +555,10 @@ STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
X509_CRL *x;
X509_OBJECT *obj, xobj;
sk = sk_X509_CRL_new_null();
- CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
- /* Check cache first */
- idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
+ if (sk == NULL)
+ return NULL;
- /* Always do lookup to possibly add new CRLs to cache
- */
- CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
+ /* Always do lookup to possibly add new CRLs to cache. */
if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj))
{
sk_X509_CRL_free(sk);
@@ -572,7 +578,7 @@ STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
{
obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
x = obj->data.crl;
- CRYPTO_refcount_inc(&x->references);
+ X509_CRL_up_ref(x);
if (!sk_X509_CRL_push(sk, x))
{
CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
@@ -641,7 +647,7 @@ int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
if (ok == X509_LU_RETRY)
{
X509_OBJECT_free_contents(&obj);
- OPENSSL_PUT_ERROR(X509, X509_STORE_CTX_get1_issuer, X509_R_SHOULD_RETRY);
+ OPENSSL_PUT_ERROR(X509, X509_R_SHOULD_RETRY);
return -1;
}
else if (ok != X509_LU_FAIL)
diff --git a/src/crypto/x509/x509_obj.c b/src/crypto/x509/x509_obj.c
index 914e0de..b6f0816 100644
--- a/src/crypto/x509/x509_obj.c
+++ b/src/crypto/x509/x509_obj.c
@@ -184,7 +184,7 @@ char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
*p = '\0';
return(p);
err:
- OPENSSL_PUT_ERROR(X509, X509_NAME_oneline, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
if (b != NULL) BUF_MEM_free(b);
return(NULL);
}
diff --git a/src/crypto/x509/x509_r2x.c b/src/crypto/x509/x509_r2x.c
index 3c8e9c0..85979ac 100644
--- a/src/crypto/x509/x509_r2x.c
+++ b/src/crypto/x509/x509_r2x.c
@@ -72,7 +72,7 @@ X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey)
if ((ret=X509_new()) == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_REQ_to_X509, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
goto err;
}
diff --git a/src/crypto/x509/x509_req.c b/src/crypto/x509/x509_req.c
index 2732d6e..01c5113 100644
--- a/src/crypto/x509/x509_req.c
+++ b/src/crypto/x509/x509_req.c
@@ -77,7 +77,7 @@ X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
ret=X509_REQ_new();
if (ret == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_to_X509_REQ, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -128,24 +128,24 @@ int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k)
ok=1;
break;
case 0:
- OPENSSL_PUT_ERROR(X509, X509_REQ_check_private_key, X509_R_KEY_VALUES_MISMATCH);
+ OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH);
break;
case -1:
- OPENSSL_PUT_ERROR(X509, X509_REQ_check_private_key, X509_R_KEY_TYPE_MISMATCH);
+ OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH);
break;
case -2:
if (k->type == EVP_PKEY_EC)
{
- OPENSSL_PUT_ERROR(X509, X509_REQ_check_private_key, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_EC_LIB);
break;
}
if (k->type == EVP_PKEY_DH)
{
/* No idea */
- OPENSSL_PUT_ERROR(X509, X509_REQ_check_private_key, X509_R_CANT_CHECK_DH_KEY);
+ OPENSSL_PUT_ERROR(X509, X509_R_CANT_CHECK_DH_KEY);
break;
}
- OPENSSL_PUT_ERROR(X509, X509_REQ_check_private_key, X509_R_UNKNOWN_KEY_TYPE);
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
}
EVP_PKEY_free(xk);
diff --git a/src/crypto/x509/x509_trs.c b/src/crypto/x509/x509_trs.c
index 9b7cc9c..820e605 100644
--- a/src/crypto/x509/x509_trs.c
+++ b/src/crypto/x509/x509_trs.c
@@ -156,7 +156,7 @@ int X509_TRUST_get_by_id(int id)
int X509_TRUST_set(int *t, int trust)
{
if(X509_TRUST_get_by_id(trust) == -1) {
- OPENSSL_PUT_ERROR(X509, X509_TRUST_set, X509_R_INVALID_TRUST);
+ OPENSSL_PUT_ERROR(X509, X509_R_INVALID_TRUST);
return 0;
}
*t = trust;
@@ -179,7 +179,7 @@ int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int),
/* Need a new entry */
if(idx == -1) {
if(!(trtmp = OPENSSL_malloc(sizeof(X509_TRUST)))) {
- OPENSSL_PUT_ERROR(X509, X509_TRUST_add, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return 0;
}
trtmp->flags = X509_TRUST_DYNAMIC;
@@ -188,7 +188,7 @@ int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int),
/* Duplicate the supplied name. */
name_dup = BUF_strdup(name);
if (name_dup == NULL) {
- OPENSSL_PUT_ERROR(X509, X509_TRUST_add, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
if (idx == -1)
OPENSSL_free(trtmp);
return 0;
@@ -210,12 +210,12 @@ int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int),
/* If its a new entry manage the dynamic table */
if(idx == -1) {
if(!trtable && !(trtable = sk_X509_TRUST_new(tr_cmp))) {
- OPENSSL_PUT_ERROR(X509, X509_TRUST_add, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
trtable_free(trtmp);
return 0;
}
if (!sk_X509_TRUST_push(trtable, trtmp)) {
- OPENSSL_PUT_ERROR(X509, X509_TRUST_add, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
trtable_free(trtmp);
return 0;
}
diff --git a/src/crypto/x509/x509_v3.c b/src/crypto/x509/x509_v3.c
index 0fc9a9a..b042985 100644
--- a/src/crypto/x509/x509_v3.c
+++ b/src/crypto/x509/x509_v3.c
@@ -147,7 +147,7 @@ STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
if (x == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509v3_add_ext, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
goto err2;
}
@@ -171,7 +171,7 @@ STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
*x=sk;
return(sk);
err:
- OPENSSL_PUT_ERROR(X509, X509v3_add_ext, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
err2:
if (new_ex != NULL) X509_EXTENSION_free(new_ex);
if (sk != NULL) sk_X509_EXTENSION_free(sk);
@@ -187,7 +187,7 @@ X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid,
obj=OBJ_nid2obj(nid);
if (obj == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_EXTENSION_create_by_NID, X509_R_UNKNOWN_NID);
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID);
return(NULL);
}
ret=X509_EXTENSION_create_by_OBJ(ex,obj,crit,data);
@@ -203,7 +203,7 @@ X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
{
if ((ret=X509_EXTENSION_new()) == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_EXTENSION_create_by_OBJ, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return(NULL);
}
}
diff --git a/src/crypto/x509/x509_vfy.c b/src/crypto/x509/x509_vfy.c
index 2ba9c84..c62a6f5 100644
--- a/src/crypto/x509/x509_vfy.c
+++ b/src/crypto/x509/x509_vfy.c
@@ -72,7 +72,8 @@
#include "../internal.h"
-static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
+static CRYPTO_EX_DATA_CLASS g_ex_data_class =
+ CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;
/* CRL score values */
@@ -140,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)
@@ -201,7 +201,14 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
STACK_OF(X509) *sktmp=NULL;
if (ctx->cert == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_verify_cert, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
+ 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;
}
@@ -209,23 +216,20 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
/* 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, X509_verify_cert, 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
&& (sktmp=sk_X509_dup(ctx->untrusted)) == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_verify_cert, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
goto end;
}
@@ -251,7 +255,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
{
ok = ctx->get_issuer(&xtmp, ctx, x);
if (ok < 0)
- return ok;
+ goto end;
/* If successful for now free up cert so it
* will be picked up again later.
*/
@@ -270,10 +274,10 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
{
if (!sk_X509_push(ctx->chain,xtmp))
{
- OPENSSL_PUT_ERROR(X509, X509_verify_cert, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
goto end;
}
- CRYPTO_refcount_inc(&xtmp->references);
+ X509_up_ref(xtmp);
(void)sk_X509_delete_ptr(sktmp,xtmp);
ctx->last_untrusted++;
x=xtmp;
@@ -349,15 +353,16 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
ok = ctx->get_issuer(&xtmp, ctx, x);
- if (ok < 0) return ok;
+ if (ok < 0) goto end;
if (ok == 0) break;
x = xtmp;
if (!sk_X509_push(ctx->chain,x))
{
X509_free(xtmp);
- OPENSSL_PUT_ERROR(X509, X509_verify_cert, ERR_R_MALLOC_FAILURE);
- return 0;
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ ok = 0;
+ goto end;
}
num++;
}
@@ -990,7 +995,7 @@ static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
*pissuer = best_crl_issuer;
*pscore = best_score;
*preasons = best_reasons;
- CRYPTO_refcount_inc(&best_crl->references);
+ X509_CRL_up_ref(best_crl);
if (*pdcrl)
{
X509_CRL_free(*pdcrl);
@@ -1097,7 +1102,7 @@ static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore,
{
if (check_crl_time(ctx, delta, 0))
*pscore |= CRL_SCORE_TIME_DELTA;
- CRYPTO_refcount_inc(&delta->references);
+ X509_CRL_up_ref(delta);
*dcrl = delta;
return;
}
@@ -1189,7 +1194,7 @@ static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
int cidx = ctx->error_depth;
size_t i;
- if (cidx != sk_X509_num(ctx->chain) - 1)
+ if ((size_t) cidx != sk_X509_num(ctx->chain) - 1)
cidx++;
crl_issuer = sk_X509_value(ctx->chain, cidx);
@@ -1634,7 +1639,7 @@ static int check_policy(X509_STORE_CTX *ctx)
ctx->param->policies, ctx->param->flags);
if (ret == 0)
{
- OPENSSL_PUT_ERROR(X509, check_policy, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return 0;
}
/* Invalid or inconsistent extensions */
@@ -1829,49 +1834,89 @@ int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
ASN1_TIME atm;
long offset;
char buff1[24],buff2[24],*p;
- int i,j;
+ int i, j, remaining;
p=buff1;
- i=ctm->length;
+ remaining = ctm->length;
str=(char *)ctm->data;
+ /* Note that the following (historical) code allows much more slack in
+ * the time format than RFC5280. In RFC5280, the representation is
+ * fixed:
+ * UTCTime: YYMMDDHHMMSSZ
+ * GeneralizedTime: YYYYMMDDHHMMSSZ */
if (ctm->type == V_ASN1_UTCTIME)
{
- if ((i < 11) || (i > 17)) return 0;
+ /* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */
+ int min_length = sizeof("YYMMDDHHMMZ") - 1;
+ int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1;
+ if (remaining < min_length || remaining > max_length)
+ return 0;
memcpy(p,str,10);
p+=10;
str+=10;
+ remaining -= 10;
}
else
{
- if (i < 13) return 0;
+ /* YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm */
+ int min_length = sizeof("YYYYMMDDHHMMZ") - 1;
+ int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1;
+ if (remaining < min_length || remaining > max_length)
+ return 0;
memcpy(p,str,12);
p+=12;
str+=12;
+ remaining -= 12;
}
if ((*str == 'Z') || (*str == '-') || (*str == '+'))
{ *(p++)='0'; *(p++)='0'; }
else
{
+ /* SS (seconds) */
+ if (remaining < 2)
+ return 0;
*(p++)= *(str++);
*(p++)= *(str++);
- /* Skip any fractional seconds... */
- if (*str == '.')
+ remaining -= 2;
+ /* Skip any (up to three) fractional seconds...
+ * TODO(emilia): in RFC5280, fractional seconds are forbidden.
+ * Can we just kill them altogether? */
+ if (remaining && *str == '.')
{
str++;
- while ((*str >= '0') && (*str <= '9')) str++;
+ remaining--;
+ for (i = 0; i < 3 && remaining; i++, str++, remaining--)
+ {
+ if (*str < '0' || *str > '9')
+ break;
+ }
}
}
*(p++)='Z';
*(p++)='\0';
+ /* We now need either a terminating 'Z' or an offset. */
+ if (!remaining)
+ return 0;
if (*str == 'Z')
+ {
+ if (remaining != 1)
+ return 0;
offset=0;
+ }
else
{
+ /* (+-)HHMM */
if ((*str != '+') && (*str != '-'))
return 0;
+ /* Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280. */
+ if (remaining != 5)
+ return 0;
+ if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' ||
+ str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9')
+ return 0;
offset=((str[1]-'0')*10+(str[2]-'0'))*60;
offset+=(str[3]-'0')*10+(str[4]-'0');
if (*str == '-')
@@ -1943,44 +1988,44 @@ X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
/* CRLs can't be delta already */
if (base->base_crl_number || newer->base_crl_number)
{
- OPENSSL_PUT_ERROR(X509, X509_CRL_diff, X509_R_CRL_ALREADY_DELTA);
+ OPENSSL_PUT_ERROR(X509, X509_R_CRL_ALREADY_DELTA);
return NULL;
}
/* Base and new CRL must have a CRL number */
if (!base->crl_number || !newer->crl_number)
{
- OPENSSL_PUT_ERROR(X509, X509_CRL_diff, X509_R_NO_CRL_NUMBER);
+ OPENSSL_PUT_ERROR(X509, X509_R_NO_CRL_NUMBER);
return NULL;
}
/* Issuer names must match */
if (X509_NAME_cmp(X509_CRL_get_issuer(base),
X509_CRL_get_issuer(newer)))
{
- OPENSSL_PUT_ERROR(X509, X509_CRL_diff, X509_R_ISSUER_MISMATCH);
+ OPENSSL_PUT_ERROR(X509, X509_R_ISSUER_MISMATCH);
return NULL;
}
/* AKID and IDP must match */
if (!crl_extension_match(base, newer, NID_authority_key_identifier))
{
- OPENSSL_PUT_ERROR(X509, X509_CRL_diff, X509_R_AKID_MISMATCH);
+ OPENSSL_PUT_ERROR(X509, X509_R_AKID_MISMATCH);
return NULL;
}
if (!crl_extension_match(base, newer, NID_issuing_distribution_point))
{
- OPENSSL_PUT_ERROR(X509, X509_CRL_diff, X509_R_IDP_MISMATCH);
+ OPENSSL_PUT_ERROR(X509, X509_R_IDP_MISMATCH);
return NULL;
}
/* Newer CRL number must exceed full CRL number */
if (ASN1_INTEGER_cmp(newer->crl_number, base->crl_number) <= 0)
{
- OPENSSL_PUT_ERROR(X509, X509_CRL_diff, X509_R_NEWER_CRL_NOT_NEWER);
+ OPENSSL_PUT_ERROR(X509, X509_R_NEWER_CRL_NOT_NEWER);
return NULL;
}
/* CRLs must verify */
if (skey && (X509_CRL_verify(base, skey) <= 0 ||
X509_CRL_verify(newer, skey) <= 0))
{
- OPENSSL_PUT_ERROR(X509, X509_CRL_diff, X509_R_CRL_VERIFY_FAILURE);
+ OPENSSL_PUT_ERROR(X509, X509_R_CRL_VERIFY_FAILURE);
return NULL;
}
/* Create new CRL */
@@ -2045,20 +2090,20 @@ X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
return crl;
memerr:
- OPENSSL_PUT_ERROR(X509, X509_CRL_diff, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
if (crl)
X509_CRL_free(crl);
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;
}
@@ -2170,7 +2215,7 @@ int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
idx = X509_PURPOSE_get_by_id(purpose);
if (idx == -1)
{
- OPENSSL_PUT_ERROR(X509, X509_STORE_CTX_purpose_inherit, X509_R_UNKNOWN_PURPOSE_ID);
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID);
return 0;
}
ptmp = X509_PURPOSE_get0(idx);
@@ -2179,7 +2224,7 @@ int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
idx = X509_PURPOSE_get_by_id(def_purpose);
if (idx == -1)
{
- OPENSSL_PUT_ERROR(X509, X509_STORE_CTX_purpose_inherit, X509_R_UNKNOWN_PURPOSE_ID);
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID);
return 0;
}
ptmp = X509_PURPOSE_get0(idx);
@@ -2192,7 +2237,7 @@ int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
idx = X509_TRUST_get_by_id(trust);
if (idx == -1)
{
- OPENSSL_PUT_ERROR(X509, X509_STORE_CTX_purpose_inherit, X509_R_UNKNOWN_TRUST_ID);
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_TRUST_ID);
return 0;
}
}
@@ -2208,7 +2253,7 @@ X509_STORE_CTX *X509_STORE_CTX_new(void)
ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX));
if (!ctx)
{
- OPENSSL_PUT_ERROR(X509, X509_STORE_CTX_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return NULL;
}
memset(ctx, 0, sizeof(X509_STORE_CTX));
@@ -2225,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)
@@ -2321,17 +2360,14 @@ 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);
}
memset(ctx, 0, sizeof(X509_STORE_CTX));
- OPENSSL_PUT_ERROR(X509, X509_STORE_CTX_init, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return 0;
}
diff --git a/src/crypto/x509/x509cset.c b/src/crypto/x509/x509cset.c
index b526c69..82d61d0 100644
--- a/src/crypto/x509/x509cset.c
+++ b/src/crypto/x509/x509cset.c
@@ -57,6 +57,8 @@
#include <openssl/obj.h>
#include <openssl/x509.h>
+#include "../internal.h"
+
int X509_CRL_set_version(X509_CRL *x, long version)
{
@@ -128,6 +130,11 @@ int X509_CRL_sort(X509_CRL *c)
return 1;
}
+void X509_CRL_up_ref(X509_CRL *crl)
+ {
+ CRYPTO_refcount_inc(&crl->references);
+ }
+
int X509_REVOKED_set_revocationDate(X509_REVOKED *x, ASN1_TIME *tm)
{
ASN1_TIME *in;
diff --git a/src/crypto/x509/x509name.c b/src/crypto/x509/x509name.c
index 042d18b..8b10fa2 100644
--- a/src/crypto/x509/x509name.c
+++ b/src/crypto/x509/x509name.c
@@ -254,7 +254,7 @@ int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, int loc,
new_name->set=set;
if (!sk_X509_NAME_ENTRY_insert(sk,new_name,loc))
{
- OPENSSL_PUT_ERROR(X509, X509_NAME_add_entry, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
goto err;
}
if (inc)
@@ -279,7 +279,7 @@ X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
obj=OBJ_txt2obj(field, 0);
if (obj == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_NAME_ENTRY_create_by_txt, X509_R_INVALID_FIELD_NAME);
+ OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_NAME);
ERR_add_error_data(2, "name=", field);
return(NULL);
}
@@ -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_NAME_ENTRY_create_by_NID, X509_R_UNKNOWN_NID);
- return(NULL);
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID);
+ 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,
@@ -336,7 +330,7 @@ int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj)
{
if ((ne == NULL) || (obj == NULL))
{
- OPENSSL_PUT_ERROR(X509, X509_NAME_ENTRY_set_object, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
return(0);
}
ASN1_OBJECT_free(ne->object);
diff --git a/src/crypto/x509/x509spki.c b/src/crypto/x509/x509spki.c
index 9bab957..ccf93e0 100644
--- a/src/crypto/x509/x509spki.c
+++ b/src/crypto/x509/x509spki.c
@@ -84,15 +84,15 @@ NETSCAPE_SPKI * NETSCAPE_SPKI_b64_decode(const char *str, int len)
if (len <= 0)
len = strlen(str);
if (!EVP_DecodedLength(&spki_len, len)) {
- OPENSSL_PUT_ERROR(X509, NETSCAPE_SPKI_b64_decode, X509_R_BASE64_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(X509, X509_R_BASE64_DECODE_ERROR);
return NULL;
}
if (!(spki_der = OPENSSL_malloc(spki_len))) {
- OPENSSL_PUT_ERROR(X509, NETSCAPE_SPKI_b64_decode, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return NULL;
}
if (!EVP_DecodeBase64(spki_der, &spki_len, spki_len, (const uint8_t *)str, len)) {
- OPENSSL_PUT_ERROR(X509, NETSCAPE_SPKI_b64_decode, X509_R_BASE64_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(X509, X509_R_BASE64_DECODE_ERROR);
OPENSSL_free(spki_der);
return NULL;
}
@@ -113,18 +113,18 @@ char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki)
der_len = i2d_NETSCAPE_SPKI(spki, NULL);
if (!EVP_EncodedLength(&b64_len, der_len))
{
- OPENSSL_PUT_ERROR(X509, NETSCAPE_SPKI_b64_encode, ERR_R_OVERFLOW);
+ OPENSSL_PUT_ERROR(X509, ERR_R_OVERFLOW);
return NULL;
}
der_spki = OPENSSL_malloc(der_len);
if (der_spki == NULL) {
- OPENSSL_PUT_ERROR(X509, NETSCAPE_SPKI_b64_encode, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return NULL;
}
b64_str = OPENSSL_malloc(b64_len);
if (b64_str == NULL) {
OPENSSL_free(der_spki);
- OPENSSL_PUT_ERROR(X509, NETSCAPE_SPKI_b64_encode, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return NULL;
}
p = der_spki;
diff --git a/src/crypto/x509/x_all.c b/src/crypto/x509/x_all.c
index 785fd1e..62b3f40 100644
--- a/src/crypto/x509/x_all.c
+++ b/src/crypto/x509/x_all.c
@@ -64,9 +64,6 @@
#include <openssl/x509.h>
-extern const ASN1_ITEM RSAPrivateKey_it;
-extern const ASN1_ITEM RSAPublicKey_it;
-
int X509_verify(X509 *a, EVP_PKEY *r)
{
if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature))
@@ -96,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,
@@ -130,20 +119,18 @@ 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,
x->signature, x->spkac,pkey,md));
}
+int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *x, EVP_PKEY *pkey)
+ {
+ return (ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor,
+ x->signature, x->spkac, pkey));
+ }
+
#ifndef OPENSSL_NO_FP_API
X509 *d2i_X509_fp(FILE *fp, X509 **x509)
{
@@ -188,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)
{
@@ -239,17 +201,17 @@ int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req)
#ifndef OPENSSL_NO_FP_API
RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa)
{
- return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa);
+ return ASN1_d2i_fp_of(RSA, RSA_new, d2i_RSAPrivateKey, fp, rsa);
}
int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa)
{
- return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa);
+ return ASN1_i2d_fp_of_const(RSA, i2d_RSAPrivateKey, fp, rsa);
}
RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa)
{
- return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa);
+ return ASN1_d2i_fp_of(RSA, RSA_new, d2i_RSAPublicKey, fp, rsa);
}
RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa)
@@ -261,7 +223,7 @@ RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa)
int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa)
{
- return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa);
+ return ASN1_i2d_fp_of_const(RSA, i2d_RSAPublicKey, fp, rsa);
}
int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa)
@@ -272,17 +234,17 @@ int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa)
RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa)
{
- return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa);
+ return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSAPrivateKey, bp, rsa);
}
int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa)
{
- return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa);
+ return ASN1_i2d_bio_of_const(RSA, i2d_RSAPrivateKey, bp, rsa);
}
RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa)
{
- return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa);
+ return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSAPublicKey, bp, rsa);
}
@@ -293,7 +255,7 @@ RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa)
int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa)
{
- return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa);
+ return ASN1_i2d_bio_of_const(RSA, i2d_RSAPublicKey, bp, rsa);
}
int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa)
@@ -422,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_crl.c b/src/crypto/x509/x_crl.c
index 2f41bb1..d516872 100644
--- a/src/crypto/x509/x_crl.c
+++ b/src/crypto/x509/x_crl.c
@@ -400,7 +400,7 @@ int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev)
if(!inf->revoked)
inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp);
if(!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) {
- OPENSSL_PUT_ERROR(X509, X509_CRL_add0_revoked, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return 0;
}
inf->enc.modified = 1;
diff --git a/src/crypto/x509/x_info.c b/src/crypto/x509/x_info.c
index f9e9ab8..be579d7 100644
--- a/src/crypto/x509/x_info.c
+++ b/src/crypto/x509/x_info.c
@@ -69,7 +69,7 @@ X509_INFO *X509_INFO_new(void)
ret=(X509_INFO *)OPENSSL_malloc(sizeof(X509_INFO));
if (ret == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_INFO_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return(NULL);
}
diff --git a/src/crypto/x509/x_name.c b/src/crypto/x509/x_name.c
index 5cfb3ae..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,
@@ -150,7 +150,7 @@ static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
return 1;
memerr:
- OPENSSL_PUT_ERROR(X509, x509_name_ex_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
if (ret)
{
if (ret->entries)
@@ -239,7 +239,7 @@ static int x509_name_ex_d2i(ASN1_VALUE **val,
err:
if (nm.x != NULL)
X509_NAME_free(nm.x);
- OPENSSL_PUT_ERROR(X509, x509_name_ex_d2i, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB);
return 0;
}
@@ -300,7 +300,7 @@ static int x509_name_encode(X509_NAME *a)
memerr:
sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
local_sk_X509_NAME_ENTRY_free);
- OPENSSL_PUT_ERROR(X509, x509_name_encode, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return -1;
}
diff --git a/src/crypto/x509/x_pkey.c b/src/crypto/x509/x_pkey.c
index 5bc6415..f5e98b8 100644
--- a/src/crypto/x509/x_pkey.c
+++ b/src/crypto/x509/x_pkey.c
@@ -69,7 +69,7 @@ X509_PKEY *X509_PKEY_new(void)
X509_PKEY *ret = OPENSSL_malloc(sizeof(X509_PKEY));
if (ret == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_PKEY_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
goto err;
}
memset(ret, 0, sizeof(X509_PKEY));
diff --git a/src/crypto/x509/x_pubkey.c b/src/crypto/x509/x_pubkey.c
index c2e0863..a16edca 100644
--- a/src/crypto/x509/x_pubkey.c
+++ b/src/crypto/x509/x_pubkey.c
@@ -100,19 +100,19 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
{
if (!pkey->ameth->pub_encode(pk, pkey))
{
- OPENSSL_PUT_ERROR(X509, X509_PUBKEY_set, X509_R_PUBLIC_KEY_ENCODE_ERROR);
+ OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_ENCODE_ERROR);
goto error;
}
}
else
{
- OPENSSL_PUT_ERROR(X509, X509_PUBKEY_set, X509_R_METHOD_NOT_SUPPORTED);
+ OPENSSL_PUT_ERROR(X509, X509_R_METHOD_NOT_SUPPORTED);
goto error;
}
}
else
{
- OPENSSL_PUT_ERROR(X509, X509_PUBKEY_set, X509_R_UNSUPPORTED_ALGORITHM);
+ OPENSSL_PUT_ERROR(X509, X509_R_UNSUPPORTED_ALGORITHM);
goto error;
}
@@ -151,13 +151,13 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
if ((ret = EVP_PKEY_new()) == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_PUBKEY_get, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
goto error;
}
if (!EVP_PKEY_set_type(ret, OBJ_obj2nid(key->algor->algorithm)))
{
- OPENSSL_PUT_ERROR(X509, X509_PUBKEY_get, X509_R_UNSUPPORTED_ALGORITHM);
+ OPENSSL_PUT_ERROR(X509, X509_R_UNSUPPORTED_ALGORITHM);
goto error;
}
@@ -165,13 +165,13 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
{
if (!ret->ameth->pub_decode(ret, key))
{
- OPENSSL_PUT_ERROR(X509, X509_PUBKEY_get, X509_R_PUBLIC_KEY_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_DECODE_ERROR);
goto error;
}
}
else
{
- OPENSSL_PUT_ERROR(X509, X509_PUBKEY_get, X509_R_METHOD_NOT_SUPPORTED);
+ OPENSSL_PUT_ERROR(X509, X509_R_METHOD_NOT_SUPPORTED);
goto error;
}
@@ -262,7 +262,7 @@ int i2d_RSA_PUBKEY(const RSA *a, unsigned char **pp)
pktmp = EVP_PKEY_new();
if (!pktmp)
{
- OPENSSL_PUT_ERROR(X509, i2d_RSA_PUBKEY, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return 0;
}
EVP_PKEY_set1_RSA(pktmp, (RSA*) a);
@@ -301,7 +301,7 @@ int i2d_DSA_PUBKEY(const DSA *a, unsigned char **pp)
pktmp = EVP_PKEY_new();
if(!pktmp)
{
- OPENSSL_PUT_ERROR(X509, i2d_DSA_PUBKEY, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return 0;
}
EVP_PKEY_set1_DSA(pktmp, (DSA*) a);
@@ -338,7 +338,7 @@ int i2d_EC_PUBKEY(const EC_KEY *a, unsigned char **pp)
if (!a) return(0);
if ((pktmp = EVP_PKEY_new()) == NULL)
{
- OPENSSL_PUT_ERROR(X509, i2d_EC_PUBKEY, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return(0);
}
EVP_PKEY_set1_EC_KEY(pktmp, (EC_KEY*) a);
diff --git a/src/crypto/x509/x_x509.c b/src/crypto/x509/x_x509.c
index c975dd3..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;
}
@@ -178,22 +178,21 @@ void *X509_get_ex_data(X509 *r, int idx)
X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length)
{
- const unsigned char *q;
+ const unsigned char *q = *pp;
X509 *ret;
int freeret = 0;
- /* Save start position */
- q = *pp;
-
if (!a || *a == NULL)
freeret = 1;
- ret = d2i_X509(a, pp, length);
+ ret = d2i_X509(a, &q, length);
/* If certificate unreadable then forget it */
if(!ret) return NULL;
/* update length */
- length -= *pp - q;
- if(!length) return ret;
- if(!d2i_X509_CERT_AUX(&ret->aux, pp, length)) goto err;
+ length -= q - *pp;
+ /* Parse auxiliary information if there is any. */
+ if (length > 0 && !d2i_X509_CERT_AUX(&ret->aux, &q, length))
+ goto err;
+ *pp = q;
return ret;
err:
if (freeret)
diff --git a/src/crypto/x509/x_x509a.c b/src/crypto/x509/x_x509a.c
index e13204b..fb7172b 100644
--- a/src/crypto/x509/x_x509a.c
+++ b/src/crypto/x509/x_x509a.c
@@ -133,24 +133,44 @@ unsigned char *X509_keyid_get0(X509 *x, int *len)
int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj)
{
- X509_CERT_AUX *aux;
- ASN1_OBJECT *objtmp;
- if(!(objtmp = OBJ_dup(obj))) return 0;
- if(!(aux = aux_get(x))) return 0;
- if(!aux->trust
- && !(aux->trust = sk_ASN1_OBJECT_new_null())) return 0;
- return sk_ASN1_OBJECT_push(aux->trust, objtmp);
+ ASN1_OBJECT *objtmp = OBJ_dup(obj);
+ if (objtmp == NULL)
+ goto err;
+ X509_CERT_AUX *aux = aux_get(x);
+ if (aux->trust == NULL)
+ {
+ aux->trust = sk_ASN1_OBJECT_new_null();
+ if (aux->trust == NULL)
+ goto err;
+ }
+ if (!sk_ASN1_OBJECT_push(aux->trust, objtmp))
+ goto err;
+ return 1;
+
+err:
+ ASN1_OBJECT_free(objtmp);
+ return 0;
}
int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj)
{
- X509_CERT_AUX *aux;
- ASN1_OBJECT *objtmp;
- if(!(objtmp = OBJ_dup(obj))) return 0;
- if(!(aux = aux_get(x))) return 0;
- if(!aux->reject
- && !(aux->reject = sk_ASN1_OBJECT_new_null())) return 0;
- return sk_ASN1_OBJECT_push(aux->reject, objtmp);
+ ASN1_OBJECT *objtmp = OBJ_dup(obj);
+ if (objtmp == NULL)
+ goto err;
+ X509_CERT_AUX *aux = aux_get(x);
+ if (aux->reject == NULL)
+ {
+ aux->reject = sk_ASN1_OBJECT_new_null();
+ if (aux->reject == NULL)
+ goto err;
+ }
+ if (!sk_ASN1_OBJECT_push(aux->reject, objtmp))
+ goto err;
+ return 1;
+
+err:
+ ASN1_OBJECT_free(objtmp);
+ return 0;
}
void X509_trust_clear(X509 *x)
diff --git a/src/crypto/x509v3/CMakeLists.txt b/src/crypto/x509v3/CMakeLists.txt
index c7e6054..cf2474a 100644
--- a/src/crypto/x509v3/CMakeLists.txt
+++ b/src/crypto/x509v3/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
x509v3
@@ -46,19 +46,21 @@ add_library(
add_executable(
v3name_test
- v3nametest.c
+ v3name_test.c
$<TARGET_OBJECTS:test_support>
)
target_link_libraries(v3name_test crypto)
+add_dependencies(all_tests v3name_test)
add_executable(
tab_test
- tabtest.c
+ tab_test.c
$<TARGET_OBJECTS:test_support>
)
target_link_libraries(tab_test crypto)
+add_dependencies(all_tests tab_test)
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/crypto/x509v3/pcy_tree.c b/src/crypto/x509v3/pcy_tree.c
index 682474d..8e9ef25 100644
--- a/src/crypto/x509v3/pcy_tree.c
+++ b/src/crypto/x509v3/pcy_tree.c
@@ -426,7 +426,7 @@ static int tree_link_unmatched(X509_POLICY_LEVEL *curr,
{
/* If mapping: matched if one child per expected policy set */
STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set;
- if (node->nchild == sk_ASN1_OBJECT_num(expset))
+ if ((size_t) node->nchild == sk_ASN1_OBJECT_num(expset))
return 1;
/* Locate unmatched nodes */
for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++)
diff --git a/src/crypto/x509v3/tabtest.c b/src/crypto/x509v3/tab_test.c
index 6b97e91..c0e0cb6 100644
--- a/src/crypto/x509v3/tabtest.c
+++ b/src/crypto/x509v3/tab_test.c
@@ -73,7 +73,8 @@
int main(void)
{
#if !defined(BORINGSSL_SHARED_LIBRARY)
- int i, prev = -1, bad = 0;
+ unsigned i;
+ int prev = -1, bad = 0;
const X509V3_EXT_METHOD *const *tmp;
CRYPTO_library_init();
i = sizeof(standard_exts) / sizeof(X509V3_EXT_METHOD *);
@@ -89,7 +90,7 @@ int main(void)
tmp = standard_exts;
fprintf(stderr, "Extensions out of order!\n");
for(i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++)
- printf("%d : %s\n", (*tmp)->ext_nid, OBJ_nid2sn((*tmp)->ext_nid));
+ printf("%d : %s\n", (*tmp)->ext_nid, OBJ_nid2sn((*tmp)->ext_nid));
return 1;
} else {
printf("PASS\n");
diff --git a/src/crypto/x509v3/v3_akey.c b/src/crypto/x509v3/v3_akey.c
index f6e6b69..9578a57 100644
--- a/src/crypto/x509v3/v3_akey.c
+++ b/src/crypto/x509v3/v3_akey.c
@@ -144,7 +144,7 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
}
else
{
- OPENSSL_PUT_ERROR(X509V3, v2i_AUTHORITY_KEYID, X509V3_R_UNKNOWN_OPTION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_OPTION);
ERR_add_error_data(2, "name=", cnf->name);
return NULL;
}
@@ -154,7 +154,7 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
{
if(ctx && (ctx->flags==CTX_TEST))
return AUTHORITY_KEYID_new();
- OPENSSL_PUT_ERROR(X509V3, v2i_AUTHORITY_KEYID, X509V3_R_NO_ISSUER_CERTIFICATE);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_ISSUER_CERTIFICATE);
return NULL;
}
@@ -167,7 +167,7 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
ikeyid = X509V3_EXT_d2i(ext);
if(keyid==2 && !ikeyid)
{
- OPENSSL_PUT_ERROR(X509V3, v2i_AUTHORITY_KEYID, X509V3_R_UNABLE_TO_GET_ISSUER_KEYID);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_KEYID);
return NULL;
}
}
@@ -178,7 +178,7 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(cert));
if(!isname || !serial)
{
- OPENSSL_PUT_ERROR(X509V3, v2i_AUTHORITY_KEYID, X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS);
goto err;
}
}
@@ -191,7 +191,7 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
|| !(gen = GENERAL_NAME_new())
|| !sk_GENERAL_NAME_push(gens, gen))
{
- OPENSSL_PUT_ERROR(X509V3, v2i_AUTHORITY_KEYID, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
gen->type = GEN_DIRNAME;
diff --git a/src/crypto/x509v3/v3_alt.c b/src/crypto/x509v3/v3_alt.c
index f547316..cfc1348 100644
--- a/src/crypto/x509v3/v3_alt.c
+++ b/src/crypto/x509v3/v3_alt.c
@@ -250,7 +250,7 @@ static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
CONF_VALUE *cnf;
size_t i;
if(!(gens = sk_GENERAL_NAME_new_null())) {
- OPENSSL_PUT_ERROR(X509V3, v2i_issuer_alt, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
@@ -282,21 +282,21 @@ static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens)
size_t j;
if(ctx && (ctx->flags == CTX_TEST)) return 1;
if(!ctx || !ctx->issuer_cert) {
- OPENSSL_PUT_ERROR(X509V3, copy_issuer, X509V3_R_NO_ISSUER_DETAILS);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_ISSUER_DETAILS);
goto err;
}
i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1);
if(i < 0) return 1;
if(!(ext = X509_get_ext(ctx->issuer_cert, i)) ||
!(ialt = X509V3_EXT_d2i(ext)) ) {
- OPENSSL_PUT_ERROR(X509V3, copy_issuer, X509V3_R_ISSUER_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_ISSUER_DECODE_ERROR);
goto err;
}
for(j = 0; j < sk_GENERAL_NAME_num(ialt); j++) {
gen = sk_GENERAL_NAME_value(ialt, j);
if(!sk_GENERAL_NAME_push(gens, gen)) {
- OPENSSL_PUT_ERROR(X509V3, copy_issuer, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -316,7 +316,7 @@ static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
CONF_VALUE *cnf;
size_t i;
if(!(gens = sk_GENERAL_NAME_new_null())) {
- OPENSSL_PUT_ERROR(X509V3, v2i_subject_alt, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
@@ -354,7 +354,7 @@ static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
if(ctx != NULL && ctx->flags == CTX_TEST)
return 1;
if(!ctx || (!ctx->subject_cert && !ctx->subject_req)) {
- OPENSSL_PUT_ERROR(X509V3, copy_email, X509V3_R_NO_SUBJECT_DETAILS);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_SUBJECT_DETAILS);
goto err;
}
/* Find the subject name */
@@ -374,14 +374,14 @@ static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
i--;
}
if(!email || !(gen = GENERAL_NAME_new())) {
- OPENSSL_PUT_ERROR(X509V3, copy_email, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
gen->d.ia5 = email;
email = NULL;
gen->type = GEN_EMAIL;
if(!sk_GENERAL_NAME_push(gens, gen)) {
- OPENSSL_PUT_ERROR(X509V3, copy_email, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
gen = NULL;
@@ -405,7 +405,7 @@ GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
CONF_VALUE *cnf;
size_t i;
if(!(gens = sk_GENERAL_NAME_new_null())) {
- OPENSSL_PUT_ERROR(X509V3, v2i_GENERAL_NAMES, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
@@ -434,7 +434,7 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
if(!value)
{
- OPENSSL_PUT_ERROR(X509V3, a2i_GENERAL_NAME, X509V3_R_MISSING_VALUE);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE);
return NULL;
}
@@ -445,7 +445,7 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
gen = GENERAL_NAME_new();
if(gen == NULL)
{
- OPENSSL_PUT_ERROR(X509V3, a2i_GENERAL_NAME, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
}
@@ -463,7 +463,7 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
ASN1_OBJECT *obj;
if(!(obj = OBJ_txt2obj(value,0)))
{
- OPENSSL_PUT_ERROR(X509V3, a2i_GENERAL_NAME, X509V3_R_BAD_OBJECT);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_OBJECT);
ERR_add_error_data(2, "value=", value);
goto err;
}
@@ -478,7 +478,7 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
gen->d.ip = a2i_IPADDRESS(value);
if(gen->d.ip == NULL)
{
- OPENSSL_PUT_ERROR(X509V3, a2i_GENERAL_NAME, X509V3_R_BAD_IP_ADDRESS);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_IP_ADDRESS);
ERR_add_error_data(2, "value=", value);
goto err;
}
@@ -487,7 +487,7 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
case GEN_DIRNAME:
if (!do_dirname(gen, value, ctx))
{
- OPENSSL_PUT_ERROR(X509V3, a2i_GENERAL_NAME, X509V3_R_DIRNAME_ERROR);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_DIRNAME_ERROR);
goto err;
}
break;
@@ -495,12 +495,12 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
case GEN_OTHERNAME:
if (!do_othername(gen, value, ctx))
{
- OPENSSL_PUT_ERROR(X509V3, a2i_GENERAL_NAME, X509V3_R_OTHERNAME_ERROR);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_OTHERNAME_ERROR);
goto err;
}
break;
default:
- OPENSSL_PUT_ERROR(X509V3, a2i_GENERAL_NAME, X509V3_R_UNSUPPORTED_TYPE);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_TYPE);
goto err;
}
@@ -510,7 +510,7 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
!ASN1_STRING_set(gen->d.ia5, (unsigned char*)value,
strlen(value)))
{
- OPENSSL_PUT_ERROR(X509V3, a2i_GENERAL_NAME, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -538,7 +538,7 @@ GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
if(!value)
{
- OPENSSL_PUT_ERROR(X509V3, v2i_GENERAL_NAME_ex, X509V3_R_MISSING_VALUE);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE);
return NULL;
}
@@ -558,7 +558,7 @@ GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
type = GEN_OTHERNAME;
else
{
- OPENSSL_PUT_ERROR(X509V3, v2i_GENERAL_NAME_ex, X509V3_R_UNSUPPORTED_OPTION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_OPTION);
ERR_add_error_data(2, "name=", name);
return NULL;
}
@@ -596,25 +596,27 @@ static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
{
- int ret;
- STACK_OF(CONF_VALUE) *sk;
- X509_NAME *nm;
- if (!(nm = X509_NAME_new()))
- return 0;
+ int ret = 0;
+ STACK_OF(CONF_VALUE) *sk = NULL;
+ X509_NAME *nm = X509_NAME_new();
+ if (nm == NULL)
+ goto err;
sk = X509V3_get_section(ctx, value);
- if (!sk)
+ if (sk == NULL)
{
- OPENSSL_PUT_ERROR(X509V3, do_dirname, X509V3_R_SECTION_NOT_FOUND);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND);
ERR_add_error_data(2, "section=", value);
- X509_NAME_free(nm);
- return 0;
+ goto err;
}
/* FIXME: should allow other character types... */
- ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC);
+ if (!X509V3_NAME_from_section(nm, sk, MBSTRING_ASC))
+ goto err;
+ gen->d.dirn = nm;
+ ret = 1;
+
+err:
if (!ret)
X509_NAME_free(nm);
- gen->d.dirn = nm;
X509V3_section_free(ctx, sk);
-
return ret;
}
diff --git a/src/crypto/x509v3/v3_bcons.c b/src/crypto/x509v3/v3_bcons.c
index a1381b4..73ef21e 100644
--- a/src/crypto/x509v3/v3_bcons.c
+++ b/src/crypto/x509v3/v3_bcons.c
@@ -103,7 +103,7 @@ static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
CONF_VALUE *val;
size_t i;
if(!(bcons = BASIC_CONSTRAINTS_new())) {
- OPENSSL_PUT_ERROR(X509V3, v2i_BASIC_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
for(i = 0; i < sk_CONF_VALUE_num(values); i++) {
@@ -113,7 +113,7 @@ static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
} else if(!strcmp(val->name, "pathlen")) {
if(!X509V3_get_value_int(val, &bcons->pathlen)) goto err;
} else {
- OPENSSL_PUT_ERROR(X509V3, v2i_BASIC_CONSTRAINTS, X509V3_R_INVALID_NAME);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME);
X509V3_conf_err(val);
goto err;
}
diff --git a/src/crypto/x509v3/v3_bitst.c b/src/crypto/x509v3/v3_bitst.c
index 15e9859..e1e2087 100644
--- a/src/crypto/x509v3/v3_bitst.c
+++ b/src/crypto/x509v3/v3_bitst.c
@@ -112,7 +112,7 @@ ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
size_t i;
const BIT_STRING_BITNAME *bnam;
if(!(bs = M_ASN1_BIT_STRING_new())) {
- OPENSSL_PUT_ERROR(X509V3, v2i_ASN1_BIT_STRING, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
@@ -121,7 +121,7 @@ ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
if(!strcmp(bnam->sname, val->name) ||
!strcmp(bnam->lname, val->name) ) {
if(!ASN1_BIT_STRING_set_bit(bs, bnam->bitnum, 1)) {
- OPENSSL_PUT_ERROR(X509V3, v2i_ASN1_BIT_STRING, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
M_ASN1_BIT_STRING_free(bs);
return NULL;
}
@@ -129,7 +129,7 @@ ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
}
}
if(!bnam->lname) {
- OPENSSL_PUT_ERROR(X509V3, v2i_ASN1_BIT_STRING, X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT);
X509V3_conf_err(val);
M_ASN1_BIT_STRING_free(bs);
return NULL;
diff --git a/src/crypto/x509v3/v3_conf.c b/src/crypto/x509v3/v3_conf.c
index cb6569f..fe71566 100644
--- a/src/crypto/x509v3/v3_conf.c
+++ b/src/crypto/x509v3/v3_conf.c
@@ -92,7 +92,7 @@ X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name,
ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value);
if (!ret)
{
- OPENSSL_PUT_ERROR(X509V3, X509V3_EXT_nconf, X509V3_R_ERROR_IN_EXTENSION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_IN_EXTENSION);
ERR_add_error_data(4,"name=", name, ", value=", value);
}
return ret;
@@ -123,12 +123,12 @@ static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
void *ext_struc;
if (ext_nid == NID_undef)
{
- OPENSSL_PUT_ERROR(X509V3, do_ext_nconf, X509V3_R_UNKNOWN_EXTENSION_NAME);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION_NAME);
return NULL;
}
if (!(method = X509V3_EXT_get_nid(ext_nid)))
{
- OPENSSL_PUT_ERROR(X509V3, do_ext_nconf, X509V3_R_UNKNOWN_EXTENSION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION);
return NULL;
}
/* Now get internal extension representation based on type */
@@ -138,7 +138,7 @@ static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
else nval = X509V3_parse_list(value);
if(sk_CONF_VALUE_num(nval) <= 0)
{
- OPENSSL_PUT_ERROR(X509V3, do_ext_nconf, X509V3_R_INVALID_EXTENSION_STRING);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_EXTENSION_STRING);
ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=", value);
return NULL;
}
@@ -155,14 +155,14 @@ static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
{
if(!ctx->db || !ctx->db_meth)
{
- OPENSSL_PUT_ERROR(X509V3, do_ext_nconf, X509V3_R_NO_CONFIG_DATABASE);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_CONFIG_DATABASE);
return NULL;
}
if(!(ext_struc = method->r2i(method, ctx, value))) return NULL;
}
else
{
- OPENSSL_PUT_ERROR(X509V3, do_ext_nconf, X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);
ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid));
return NULL;
}
@@ -207,7 +207,7 @@ static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid,
return ext;
merr:
- OPENSSL_PUT_ERROR(X509V3, do_ext_i2d, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -218,7 +218,7 @@ X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc)
{
const X509V3_EXT_METHOD *method;
if (!(method = X509V3_EXT_get_nid(ext_nid))) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_EXT_i2d, X509V3_R_UNKNOWN_EXTENSION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION);
return NULL;
}
return do_ext_i2d(method, ext_nid, crit, ext_struc);
@@ -271,7 +271,7 @@ static X509_EXTENSION *v3_generic_extension(const char *ext, char *value,
X509_EXTENSION *extension=NULL;
if (!(obj = OBJ_txt2obj(ext, 0)))
{
- OPENSSL_PUT_ERROR(X509V3, v3_generic_extension, X509V3_R_EXTENSION_NAME_ERROR);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_NAME_ERROR);
ERR_add_error_data(2, "name=", ext);
goto err;
}
@@ -283,14 +283,14 @@ static X509_EXTENSION *v3_generic_extension(const char *ext, char *value,
if (ext_der == NULL)
{
- OPENSSL_PUT_ERROR(X509V3, v3_generic_extension, X509V3_R_EXTENSION_VALUE_ERROR);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_VALUE_ERROR);
ERR_add_error_data(2, "value=", value);
goto err;
}
if (!(oct = M_ASN1_OCTET_STRING_new()))
{
- OPENSSL_PUT_ERROR(X509V3, v3_generic_extension, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -389,7 +389,7 @@ char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section)
{
if(!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string)
{
- OPENSSL_PUT_ERROR(X509V3, X509V3_get_string, X509V3_R_OPERATION_NOT_DEFINED);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_OPERATION_NOT_DEFINED);
return NULL;
}
if (ctx->db_meth->get_string)
@@ -401,7 +401,7 @@ STACK_OF(CONF_VALUE) * X509V3_get_section(X509V3_CTX *ctx, char *section)
{
if(!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section)
{
- OPENSSL_PUT_ERROR(X509V3, X509V3_get_section, X509V3_R_OPERATION_NOT_DEFINED);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_OPERATION_NOT_DEFINED);
return NULL;
}
if (ctx->db_meth->get_section)
diff --git a/src/crypto/x509v3/v3_cpols.c b/src/crypto/x509v3/v3_cpols.c
index cbe596b..0b58676 100644
--- a/src/crypto/x509v3/v3_cpols.c
+++ b/src/crypto/x509v3/v3_cpols.c
@@ -146,19 +146,19 @@ static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
int ia5org;
pols = sk_POLICYINFO_new_null();
if (pols == NULL) {
- OPENSSL_PUT_ERROR(X509V3, r2i_certpol, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
vals = X509V3_parse_list(value);
if (vals == NULL) {
- OPENSSL_PUT_ERROR(X509V3, r2i_certpol, ERR_R_X509V3_LIB);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_X509V3_LIB);
goto err;
}
ia5org = 0;
for(i = 0; i < sk_CONF_VALUE_num(vals); i++) {
cnf = sk_CONF_VALUE_value(vals, i);
if(cnf->value || !cnf->name ) {
- OPENSSL_PUT_ERROR(X509V3, r2i_certpol, X509V3_R_INVALID_POLICY_IDENTIFIER);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_POLICY_IDENTIFIER);
X509V3_conf_err(cnf);
goto err;
}
@@ -170,7 +170,7 @@ static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
STACK_OF(CONF_VALUE) *polsect;
polsect = X509V3_get_section(ctx, pstr + 1);
if(!polsect) {
- OPENSSL_PUT_ERROR(X509V3, r2i_certpol, X509V3_R_INVALID_SECTION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION);
X509V3_conf_err(cnf);
goto err;
@@ -180,7 +180,7 @@ static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
if(!pol) goto err;
} else {
if(!(pobj = OBJ_txt2obj(cnf->name, 0))) {
- OPENSSL_PUT_ERROR(X509V3, r2i_certpol, X509V3_R_INVALID_OBJECT_IDENTIFIER);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
X509V3_conf_err(cnf);
goto err;
}
@@ -189,7 +189,7 @@ static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
}
if (!sk_POLICYINFO_push(pols, pol)){
POLICYINFO_free(pol);
- OPENSSL_PUT_ERROR(X509V3, r2i_certpol, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -214,7 +214,7 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx,
if(!strcmp(cnf->name, "policyIdentifier")) {
ASN1_OBJECT *pobj;
if(!(pobj = OBJ_txt2obj(cnf->value, 0))) {
- OPENSSL_PUT_ERROR(X509V3, policy_section, X509V3_R_INVALID_OBJECT_IDENTIFIER);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
X509V3_conf_err(cnf);
goto err;
}
@@ -229,7 +229,7 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx,
/* TODO(fork): const correctness */
qual->pqualid = (ASN1_OBJECT*) OBJ_nid2obj(NID_id_qt_cps);
if (qual->pqualid == NULL) {
- OPENSSL_PUT_ERROR(X509V3, policy_section, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_INTERNAL_ERROR);
goto err;
}
qual->d.cpsuri = M_ASN1_IA5STRING_new();
@@ -241,13 +241,13 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx,
} else if(!name_cmp(cnf->name, "userNotice")) {
STACK_OF(CONF_VALUE) *unot;
if(*cnf->value != '@') {
- OPENSSL_PUT_ERROR(X509V3, policy_section, X509V3_R_EXPECTED_A_SECTION_NAME);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXPECTED_A_SECTION_NAME);
X509V3_conf_err(cnf);
goto err;
}
unot = X509V3_get_section(ctx, cnf->value + 1);
if(!unot) {
- OPENSSL_PUT_ERROR(X509V3, policy_section, X509V3_R_INVALID_SECTION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION);
X509V3_conf_err(cnf);
goto err;
@@ -260,21 +260,21 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx,
if(!sk_POLICYQUALINFO_push(pol->qualifiers, qual))
goto merr;
} else {
- OPENSSL_PUT_ERROR(X509V3, policy_section, X509V3_R_INVALID_OPTION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OPTION);
X509V3_conf_err(cnf);
goto err;
}
}
if(!pol->policyid) {
- OPENSSL_PUT_ERROR(X509V3, policy_section, X509V3_R_NO_POLICY_IDENTIFIER);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_POLICY_IDENTIFIER);
goto err;
}
return pol;
merr:
- OPENSSL_PUT_ERROR(X509V3, policy_section, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
err:
POLICYINFO_free(pol);
@@ -296,7 +296,7 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
qual->pqualid = (ASN1_OBJECT *) OBJ_nid2obj(NID_id_qt_unotice);
if (qual->pqualid == NULL)
{
- OPENSSL_PUT_ERROR(X509V3, notice_section, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_INTERNAL_ERROR);
goto err;
}
if(!(not = USERNOTICE_new())) goto merr;
@@ -328,7 +328,7 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
} else nref = not->noticeref;
nos = X509V3_parse_list(cnf->value);
if(!nos || !sk_CONF_VALUE_num(nos)) {
- OPENSSL_PUT_ERROR(X509V3, notice_section, X509V3_R_INVALID_NUMBERS);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NUMBERS);
X509V3_conf_err(cnf);
goto err;
}
@@ -337,7 +337,7 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
if (!ret)
goto err;
} else {
- OPENSSL_PUT_ERROR(X509V3, notice_section, X509V3_R_INVALID_OPTION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OPTION);
X509V3_conf_err(cnf);
goto err;
}
@@ -345,14 +345,14 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
if(not->noticeref &&
(!not->noticeref->noticenos || !not->noticeref->organization)) {
- OPENSSL_PUT_ERROR(X509V3, notice_section, X509V3_R_NEED_ORGANIZATION_AND_NUMBERS);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_NEED_ORGANIZATION_AND_NUMBERS);
goto err;
}
return qual;
merr:
- OPENSSL_PUT_ERROR(X509V3, notice_section, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
err:
POLICYQUALINFO_free(qual);
@@ -369,7 +369,7 @@ static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos)
for(i = 0; i < sk_CONF_VALUE_num(nos); i++) {
cnf = sk_CONF_VALUE_value(nos, i);
if(!(aint = s2i_ASN1_INTEGER(NULL, cnf->name))) {
- OPENSSL_PUT_ERROR(X509V3, nref_nos, X509V3_R_INVALID_NUMBER);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NUMBER);
goto err;
}
if(!sk_ASN1_INTEGER_push(nnums, aint)) goto merr;
@@ -377,7 +377,7 @@ static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos)
return 1;
merr:
- OPENSSL_PUT_ERROR(X509V3, nref_nos, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
err:
sk_ASN1_INTEGER_pop_free(nnums, ASN1_STRING_free);
diff --git a/src/crypto/x509v3/v3_crld.c b/src/crypto/x509v3/v3_crld.c
index e41dd65..3984c31 100644
--- a/src/crypto/x509v3/v3_crld.c
+++ b/src/crypto/x509v3/v3_crld.c
@@ -103,7 +103,7 @@ static STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx, char *sect)
gnsect = X509V3_parse_list(sect);
if (!gnsect)
{
- OPENSSL_PUT_ERROR(X509V3, gnames_from_sectname, X509V3_R_SECTION_NOT_FOUND);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND);
return NULL;
}
gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect);
@@ -136,7 +136,7 @@ static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx,
dnsect = X509V3_get_section(ctx, cnf->value);
if (!dnsect)
{
- OPENSSL_PUT_ERROR(X509V3, set_dist_point_name, X509V3_R_SECTION_NOT_FOUND);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND);
return -1;
}
ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC);
@@ -152,7 +152,7 @@ static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx,
if (sk_X509_NAME_ENTRY_value(rnm,
sk_X509_NAME_ENTRY_num(rnm) - 1)->set)
{
- OPENSSL_PUT_ERROR(X509V3, set_dist_point_name, X509V3_R_INVALID_MULTIPLE_RDNS);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_MULTIPLE_RDNS);
goto err;
}
}
@@ -161,7 +161,7 @@ static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx,
if (*pdp)
{
- OPENSSL_PUT_ERROR(X509V3, set_dist_point_name, X509V3_R_DISTPOINT_ALREADY_SET);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_DISTPOINT_ALREADY_SET);
goto err;
}
@@ -362,7 +362,7 @@ static void *v2i_crld(const X509V3_EXT_METHOD *method,
return crld;
merr:
- OPENSSL_PUT_ERROR(X509V3, v2i_crld, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
err:
GENERAL_NAME_free(gen);
GENERAL_NAMES_free(gens);
@@ -490,7 +490,7 @@ static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
}
else
{
- OPENSSL_PUT_ERROR(X509V3, v2i_idp, X509V3_R_INVALID_NAME);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME);
X509V3_conf_err(cnf);
goto err;
}
@@ -498,7 +498,7 @@ static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
return idp;
merr:
- OPENSSL_PUT_ERROR(X509V3, v2i_idp, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
err:
ISSUING_DIST_POINT_free(idp);
return NULL;
diff --git a/src/crypto/x509v3/v3_extku.c b/src/crypto/x509v3/v3_extku.c
index f4b8af8..d64eb9c 100644
--- a/src/crypto/x509v3/v3_extku.c
+++ b/src/crypto/x509v3/v3_extku.c
@@ -125,7 +125,7 @@ static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
size_t i;
if(!(extku = sk_ASN1_OBJECT_new_null())) {
- OPENSSL_PUT_ERROR(X509V3, v2i_EXTENDED_KEY_USAGE, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -135,7 +135,7 @@ static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
else extval = val->name;
if(!(objtmp = OBJ_txt2obj(extval, 0))) {
sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free);
- OPENSSL_PUT_ERROR(X509V3, v2i_EXTENDED_KEY_USAGE, X509V3_R_INVALID_OBJECT_IDENTIFIER);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
X509V3_conf_err(val);
return NULL;
}
diff --git a/src/crypto/x509v3/v3_ia5.c b/src/crypto/x509v3/v3_ia5.c
index ec57e9b..5a27233 100644
--- a/src/crypto/x509v3/v3_ia5.c
+++ b/src/crypto/x509v3/v3_ia5.c
@@ -87,7 +87,7 @@ static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
char *tmp;
if(!ia5 || !ia5->length) return NULL;
if(!(tmp = OPENSSL_malloc(ia5->length + 1))) {
- OPENSSL_PUT_ERROR(X509V3, i2s_ASN1_IA5STRING, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
memcpy(tmp, ia5->data, ia5->length);
@@ -100,7 +100,7 @@ static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
{
ASN1_IA5STRING *ia5;
if(!str) {
- OPENSSL_PUT_ERROR(X509V3, s2i_ASN1_IA5STRING, X509V3_R_INVALID_NULL_ARGUMENT);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT);
return NULL;
}
if(!(ia5 = M_ASN1_IA5STRING_new())) goto err;
@@ -111,7 +111,7 @@ static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
}
return ia5;
err:
- OPENSSL_PUT_ERROR(X509V3, s2i_ASN1_IA5STRING, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
diff --git a/src/crypto/x509v3/v3_info.c b/src/crypto/x509v3/v3_info.c
index 7558b2d..475c56f 100644
--- a/src/crypto/x509v3/v3_info.c
+++ b/src/crypto/x509v3/v3_info.c
@@ -124,7 +124,7 @@ static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method
nlen = strlen(objtmp) + strlen(vtmp->name) + 5;
ntmp = OPENSSL_malloc(nlen);
if(!ntmp) {
- OPENSSL_PUT_ERROR(X509V3, i2v_AUTHORITY_INFO_ACCESS, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
BUF_strlcpy(ntmp, objtmp, nlen);
@@ -148,19 +148,19 @@ static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *metho
int objlen;
char *objtmp, *ptmp;
if(!(ainfo = sk_ACCESS_DESCRIPTION_new_null())) {
- OPENSSL_PUT_ERROR(X509V3, v2i_AUTHORITY_INFO_ACCESS, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
cnf = sk_CONF_VALUE_value(nval, i);
if(!(acc = ACCESS_DESCRIPTION_new())
|| !sk_ACCESS_DESCRIPTION_push(ainfo, acc)) {
- OPENSSL_PUT_ERROR(X509V3, v2i_AUTHORITY_INFO_ACCESS, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
ptmp = strchr(cnf->name, ';');
if(!ptmp) {
- OPENSSL_PUT_ERROR(X509V3, v2i_AUTHORITY_INFO_ACCESS, X509V3_R_INVALID_SYNTAX);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SYNTAX);
goto err;
}
objlen = ptmp - cnf->name;
@@ -169,14 +169,14 @@ static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *metho
if(!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0))
goto err;
if(!(objtmp = OPENSSL_malloc(objlen + 1))) {
- OPENSSL_PUT_ERROR(X509V3, v2i_AUTHORITY_INFO_ACCESS, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
strncpy(objtmp, cnf->name, objlen);
objtmp[objlen] = 0;
acc->method = OBJ_txt2obj(objtmp, 0);
if(!acc->method) {
- OPENSSL_PUT_ERROR(X509V3, v2i_AUTHORITY_INFO_ACCESS, X509V3_R_BAD_OBJECT);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_OBJECT);
ERR_add_error_data(2, "value=", objtmp);
OPENSSL_free(objtmp);
goto err;
diff --git a/src/crypto/x509v3/v3_lib.c b/src/crypto/x509v3/v3_lib.c
index d4e4e78..f8e5531 100644
--- a/src/crypto/x509v3/v3_lib.c
+++ b/src/crypto/x509v3/v3_lib.c
@@ -78,12 +78,12 @@ static int ext_stack_cmp(const X509V3_EXT_METHOD **a, const X509V3_EXT_METHOD **
int X509V3_EXT_add(X509V3_EXT_METHOD *ext)
{
if(!ext_list && !(ext_list = sk_X509V3_EXT_METHOD_new(ext_stack_cmp))) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_EXT_add, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
ext_list_free(ext);
return 0;
}
if(!sk_X509V3_EXT_METHOD_push(ext_list, ext)) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_EXT_add, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
ext_list_free(ext);
return 0;
}
@@ -127,7 +127,7 @@ int X509V3_EXT_free(int nid, void *ext_data)
const X509V3_EXT_METHOD *ext_method = X509V3_EXT_get_nid(nid);
if (ext_method == NULL)
{
- OPENSSL_PUT_ERROR(X509V3, X509V3_EXT_free, X509V3_R_CANNOT_FIND_FREE_FUNCTION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_CANNOT_FIND_FREE_FUNCTION);
return 0;
}
@@ -137,7 +137,7 @@ int X509V3_EXT_free(int nid, void *ext_data)
ext_method->ext_free(ext_data);
else
{
- OPENSSL_PUT_ERROR(X509V3, X509V3_EXT_free, X509V3_R_CANNOT_FIND_FREE_FUNCTION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_CANNOT_FIND_FREE_FUNCTION);
return 0;
}
@@ -157,11 +157,11 @@ int X509V3_EXT_add_alias(int nid_to, int nid_from)
X509V3_EXT_METHOD *tmpext;
if(!(ext = X509V3_EXT_get_nid(nid_from))) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_EXT_add_alias, X509V3_R_EXTENSION_NOT_FOUND);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_NOT_FOUND);
return 0;
}
if(!(tmpext = (X509V3_EXT_METHOD *)OPENSSL_malloc(sizeof(X509V3_EXT_METHOD)))) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_EXT_add_alias, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return 0;
}
*tmpext = *ext;
@@ -311,7 +311,7 @@ int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value,
ext = X509V3_EXT_i2d(nid, crit, value);
if(!ext) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_add1_i2d, X509V3_R_ERROR_CREATING_EXTENSION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_CREATING_EXTENSION);
return 0;
}
@@ -330,6 +330,6 @@ int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value,
err:
if(!(flags & X509V3_ADD_SILENT))
- OPENSSL_PUT_ERROR(X509V3, X509V3_add1_i2d, errcode);
+ OPENSSL_PUT_ERROR(X509V3, errcode);
return 0;
}
diff --git a/src/crypto/x509v3/v3_ncons.c b/src/crypto/x509v3/v3_ncons.c
index c42a665..19f5e94 100644
--- a/src/crypto/x509v3/v3_ncons.c
+++ b/src/crypto/x509v3/v3_ncons.c
@@ -135,7 +135,7 @@ static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
}
else
{
- OPENSSL_PUT_ERROR(X509V3, v2i_NAME_CONSTRAINTS, X509V3_R_INVALID_SYNTAX);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SYNTAX);
goto err;
}
tval.value = val->value;
@@ -152,7 +152,7 @@ static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
return ncons;
memerr:
- OPENSSL_PUT_ERROR(X509V3, v2i_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
err:
if (ncons)
NAME_CONSTRAINTS_free(ncons);
diff --git a/src/crypto/x509v3/v3_pci.c b/src/crypto/x509v3/v3_pci.c
index aa93891..f19a37a 100644
--- a/src/crypto/x509v3/v3_pci.c
+++ b/src/crypto/x509v3/v3_pci.c
@@ -87,13 +87,13 @@ static int process_pci_value(CONF_VALUE *val,
{
if (*language)
{
- OPENSSL_PUT_ERROR(X509V3, process_pci_value, X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED);
X509V3_conf_err(val);
return 0;
}
if (!(*language = OBJ_txt2obj(val->value, 0)))
{
- OPENSSL_PUT_ERROR(X509V3, process_pci_value, X509V3_R_INVALID_OBJECT_IDENTIFIER);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
X509V3_conf_err(val);
return 0;
}
@@ -102,13 +102,13 @@ static int process_pci_value(CONF_VALUE *val,
{
if (*pathlen)
{
- OPENSSL_PUT_ERROR(X509V3, process_pci_value, X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED);
X509V3_conf_err(val);
return 0;
}
if (!X509V3_get_value_int(val, pathlen))
{
- OPENSSL_PUT_ERROR(X509V3, process_pci_value, X509V3_R_POLICY_PATH_LENGTH);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_POLICY_PATH_LENGTH);
X509V3_conf_err(val);
return 0;
}
@@ -122,7 +122,7 @@ static int process_pci_value(CONF_VALUE *val,
*policy = ASN1_OCTET_STRING_new();
if (!*policy)
{
- OPENSSL_PUT_ERROR(X509V3, process_pci_value, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
X509V3_conf_err(val);
return 0;
}
@@ -135,7 +135,7 @@ static int process_pci_value(CONF_VALUE *val,
if (!tmp_data2)
{
- OPENSSL_PUT_ERROR(X509V3, process_pci_value, X509V3_R_ILLEGAL_HEX_DIGIT);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_HEX_DIGIT);
X509V3_conf_err(val);
goto err;
}
@@ -156,7 +156,7 @@ static int process_pci_value(CONF_VALUE *val,
/* realloc failure implies the original data space is b0rked too! */
(*policy)->data = NULL;
(*policy)->length = 0;
- OPENSSL_PUT_ERROR(X509V3, process_pci_value, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
X509V3_conf_err(val);
goto err;
}
@@ -169,7 +169,7 @@ static int process_pci_value(CONF_VALUE *val,
BIO *b = BIO_new_file(val->value + 5, "r");
if (!b)
{
- OPENSSL_PUT_ERROR(X509V3, process_pci_value, ERR_R_BIO_LIB);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_BIO_LIB);
X509V3_conf_err(val);
goto err;
}
@@ -194,7 +194,7 @@ static int process_pci_value(CONF_VALUE *val,
if (n < 0)
{
- OPENSSL_PUT_ERROR(X509V3, process_pci_value, ERR_R_BIO_LIB);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_BIO_LIB);
X509V3_conf_err(val);
goto err;
}
@@ -217,20 +217,20 @@ static int process_pci_value(CONF_VALUE *val,
/* realloc failure implies the original data space is b0rked too! */
(*policy)->data = NULL;
(*policy)->length = 0;
- OPENSSL_PUT_ERROR(X509V3, process_pci_value, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
X509V3_conf_err(val);
goto err;
}
}
else
{
- OPENSSL_PUT_ERROR(X509V3, process_pci_value, X509V3_R_INCORRECT_POLICY_SYNTAX_TAG);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INCORRECT_POLICY_SYNTAX_TAG);
X509V3_conf_err(val);
goto err;
}
if (!tmp_data)
{
- OPENSSL_PUT_ERROR(X509V3, process_pci_value, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
X509V3_conf_err(val);
goto err;
}
@@ -262,7 +262,7 @@ static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i);
if (!cnf->name || (*cnf->name != '@' && !cnf->value))
{
- OPENSSL_PUT_ERROR(X509V3, r2i_pci, X509V3_R_INVALID_PROXY_POLICY_SETTING);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_PROXY_POLICY_SETTING);
X509V3_conf_err(cnf);
goto err;
}
@@ -274,7 +274,7 @@ static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
sect = X509V3_get_section(ctx, cnf->name + 1);
if (!sect)
{
- OPENSSL_PUT_ERROR(X509V3, r2i_pci, X509V3_R_INVALID_SECTION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION);
X509V3_conf_err(cnf);
goto err;
}
@@ -302,20 +302,21 @@ static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
/* Language is mandatory */
if (!language)
{
- OPENSSL_PUT_ERROR(X509V3, r2i_pci, X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED);
goto err;
}
nid = OBJ_obj2nid(language);
if ((nid == NID_Independent || nid == NID_id_ppl_inheritAll) && policy)
{
- OPENSSL_PUT_ERROR(X509V3, r2i_pci, X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY);
+ OPENSSL_PUT_ERROR(X509V3,
+ X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY);
goto err;
}
pci = PROXY_CERT_INFO_EXTENSION_new();
if (!pci)
{
- OPENSSL_PUT_ERROR(X509V3, r2i_pci, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
diff --git a/src/crypto/x509v3/v3_pcons.c b/src/crypto/x509v3/v3_pcons.c
index f87c6a0..b752290 100644
--- a/src/crypto/x509v3/v3_pcons.c
+++ b/src/crypto/x509v3/v3_pcons.c
@@ -112,7 +112,7 @@ static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method,
CONF_VALUE *val;
size_t i;
if(!(pcons = POLICY_CONSTRAINTS_new())) {
- OPENSSL_PUT_ERROR(X509V3, v2i_POLICY_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
for(i = 0; i < sk_CONF_VALUE_num(values); i++) {
@@ -124,13 +124,13 @@ static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method,
if(!X509V3_get_value_int(val,
&pcons->inhibitPolicyMapping)) goto err;
} else {
- OPENSSL_PUT_ERROR(X509V3, v2i_POLICY_CONSTRAINTS, X509V3_R_INVALID_NAME);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME);
X509V3_conf_err(val);
goto err;
}
}
if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) {
- OPENSSL_PUT_ERROR(X509V3, v2i_POLICY_CONSTRAINTS, X509V3_R_ILLEGAL_EMPTY_EXTENSION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_EMPTY_EXTENSION);
goto err;
}
diff --git a/src/crypto/x509v3/v3_pmaps.c b/src/crypto/x509v3/v3_pmaps.c
index fbc169d..5b90977 100644
--- a/src/crypto/x509v3/v3_pmaps.c
+++ b/src/crypto/x509v3/v3_pmaps.c
@@ -122,7 +122,7 @@ static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
size_t i;
if(!(pmaps = sk_POLICY_MAPPING_new_null())) {
- OPENSSL_PUT_ERROR(X509V3, v2i_POLICY_MAPPINGS, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -130,7 +130,7 @@ static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
val = sk_CONF_VALUE_value(nval, i);
if(!val->value || !val->name) {
sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
- OPENSSL_PUT_ERROR(X509V3, v2i_POLICY_MAPPINGS, X509V3_R_INVALID_OBJECT_IDENTIFIER);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
X509V3_conf_err(val);
return NULL;
}
@@ -138,14 +138,14 @@ static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
obj2 = OBJ_txt2obj(val->value, 0);
if(!obj1 || !obj2) {
sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
- OPENSSL_PUT_ERROR(X509V3, v2i_POLICY_MAPPINGS, X509V3_R_INVALID_OBJECT_IDENTIFIER);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
X509V3_conf_err(val);
return NULL;
}
pmap = POLICY_MAPPING_new();
if (!pmap) {
sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
- OPENSSL_PUT_ERROR(X509V3, v2i_POLICY_MAPPINGS, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
pmap->issuerDomainPolicy = obj1;
diff --git a/src/crypto/x509v3/v3_purp.c b/src/crypto/x509v3/v3_purp.c
index 8ae8a06..9a0a7bc 100644
--- a/src/crypto/x509v3/v3_purp.c
+++ b/src/crypto/x509v3/v3_purp.c
@@ -70,6 +70,14 @@
#include "../internal.h"
+#define V1_ROOT (EXFLAG_V1|EXFLAG_SS)
+#define ku_reject(x, usage) \
+ (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
+#define xku_reject(x, usage) \
+ (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage)))
+#define ns_reject(x, usage) \
+ (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage)))
+
static void x509v3_cache_extensions(X509 *x);
static int check_ssl_ca(const X509 *x);
@@ -128,7 +136,7 @@ int X509_check_purpose(X509 *x, int id, int ca)
int X509_PURPOSE_set(int *p, int purpose)
{
if(X509_PURPOSE_get_by_id(purpose) == -1) {
- OPENSSL_PUT_ERROR(X509V3, X509_PURPOSE_set, X509V3_R_INVALID_PURPOSE);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_PURPOSE);
return 0;
}
*p = purpose;
@@ -191,7 +199,7 @@ int X509_PURPOSE_add(int id, int trust, int flags,
/* Need a new entry */
if(idx == -1) {
if(!(ptmp = OPENSSL_malloc(sizeof(X509_PURPOSE)))) {
- OPENSSL_PUT_ERROR(X509V3, X509_PURPOSE_add, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return 0;
}
ptmp->flags = X509_PURPOSE_DYNAMIC;
@@ -201,7 +209,7 @@ int X509_PURPOSE_add(int id, int trust, int flags,
name_dup = BUF_strdup(name);
sname_dup = BUF_strdup(sname);
if (name_dup == NULL || sname_dup == NULL) {
- OPENSSL_PUT_ERROR(X509V3, X509_PURPOSE_add, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
if (name_dup != NULL)
OPENSSL_free(name_dup);
if (sname_dup != NULL)
@@ -232,12 +240,12 @@ int X509_PURPOSE_add(int id, int trust, int flags,
/* If its a new entry manage the dynamic table */
if(idx == -1) {
if(!xptable && !(xptable = sk_X509_PURPOSE_new(xp_cmp))) {
- OPENSSL_PUT_ERROR(X509V3, X509_PURPOSE_add, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
xptable_free(ptmp);
return 0;
}
if (!sk_X509_PURPOSE_push(xptable, ptmp)) {
- OPENSSL_PUT_ERROR(X509V3, X509_PURPOSE_add, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
xptable_free(ptmp);
return 0;
}
@@ -494,7 +502,8 @@ static void x509v3_cache_extensions(X509 *x)
{
x->ex_flags |= EXFLAG_SI;
/* If SKID matches AKID also indicate self signed */
- if (X509_check_akid(x, x->akid) == X509_V_OK)
+ if (X509_check_akid(x, x->akid) == X509_V_OK &&
+ !ku_reject(x, KU_KEY_CERT_SIGN))
x->ex_flags |= EXFLAG_SS;
}
x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
@@ -531,14 +540,6 @@ static void x509v3_cache_extensions(X509 *x)
* 4 basicConstraints absent but keyUsage present and keyCertSign asserted.
*/
-#define V1_ROOT (EXFLAG_V1|EXFLAG_SS)
-#define ku_reject(x, usage) \
- (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
-#define xku_reject(x, usage) \
- (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage)))
-#define ns_reject(x, usage) \
- (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage)))
-
static int check_ca(const X509 *x)
{
/* keyUsage if present should allow cert signing */
diff --git a/src/crypto/x509v3/v3_skey.c b/src/crypto/x509v3/v3_skey.c
index 471a1ab..e396f05 100644
--- a/src/crypto/x509v3/v3_skey.c
+++ b/src/crypto/x509v3/v3_skey.c
@@ -86,7 +86,7 @@ ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
long length;
if(!(oct = M_ASN1_OCTET_STRING_new())) {
- OPENSSL_PUT_ERROR(X509V3, s2i_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -112,14 +112,14 @@ static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method,
if(strcmp(str, "hash")) return s2i_ASN1_OCTET_STRING(method, ctx, str);
if(!(oct = M_ASN1_OCTET_STRING_new())) {
- OPENSSL_PUT_ERROR(X509V3, s2i_skey_id, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
if(ctx && (ctx->flags == CTX_TEST)) return oct;
if(!ctx || (!ctx->subject_req && !ctx->subject_cert)) {
- OPENSSL_PUT_ERROR(X509V3, s2i_skey_id, X509V3_R_NO_PUBLIC_KEY);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_PUBLIC_KEY);
goto err;
}
@@ -128,7 +128,7 @@ static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method,
else pk = ctx->subject_cert->cert_info->key->public_key;
if(!pk) {
- OPENSSL_PUT_ERROR(X509V3, s2i_skey_id, X509V3_R_NO_PUBLIC_KEY);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_PUBLIC_KEY);
goto err;
}
@@ -136,7 +136,7 @@ static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method,
goto err;
if(!M_ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) {
- OPENSSL_PUT_ERROR(X509V3, s2i_skey_id, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
diff --git a/src/crypto/x509v3/v3_sxnet.c b/src/crypto/x509v3/v3_sxnet.c
index bb5e214..4dd5bfc 100644
--- a/src/crypto/x509v3/v3_sxnet.c
+++ b/src/crypto/x509v3/v3_sxnet.c
@@ -159,7 +159,7 @@ int SXNET_add_id_asc(SXNET **psx, char *zone, char *user,
{
ASN1_INTEGER *izone = NULL;
if(!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
- OPENSSL_PUT_ERROR(X509V3, SXNET_add_id_asc, X509V3_R_ERROR_CONVERTING_ZONE);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_CONVERTING_ZONE);
return 0;
}
return SXNET_add_id_INTEGER(psx, izone, user, userlen);
@@ -172,7 +172,7 @@ int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user,
{
ASN1_INTEGER *izone = NULL;
if(!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
- OPENSSL_PUT_ERROR(X509V3, SXNET_add_id_ulong, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
M_ASN1_INTEGER_free(izone);
return 0;
}
@@ -191,12 +191,12 @@ int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, char *user,
SXNET *sx = NULL;
SXNETID *id = NULL;
if(!psx || !zone || !user) {
- OPENSSL_PUT_ERROR(X509V3, SXNET_add_id_INTEGER, X509V3_R_INVALID_NULL_ARGUMENT);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT);
return 0;
}
if(userlen == -1) userlen = strlen(user);
if(userlen > 64) {
- OPENSSL_PUT_ERROR(X509V3, SXNET_add_id_INTEGER, X509V3_R_USER_TOO_LONG);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_USER_TOO_LONG);
return 0;
}
if(!*psx) {
@@ -205,7 +205,7 @@ int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, char *user,
*psx = sx;
} else sx = *psx;
if(SXNET_get_id_INTEGER(sx, zone)) {
- OPENSSL_PUT_ERROR(X509V3, SXNET_add_id_INTEGER, X509V3_R_DUPLICATE_ZONE_ID);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_DUPLICATE_ZONE_ID);
return 0;
}
@@ -218,7 +218,7 @@ int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, char *user,
return 1;
err:
- OPENSSL_PUT_ERROR(X509V3, SXNET_add_id_INTEGER, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
SXNETID_free(id);
SXNET_free(sx);
*psx = NULL;
@@ -230,7 +230,7 @@ ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone)
ASN1_INTEGER *izone = NULL;
ASN1_OCTET_STRING *oct;
if(!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
- OPENSSL_PUT_ERROR(X509V3, SXNET_get_id_asc, X509V3_R_ERROR_CONVERTING_ZONE);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_CONVERTING_ZONE);
return NULL;
}
oct = SXNET_get_id_INTEGER(sx, izone);
@@ -243,7 +243,7 @@ ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone)
ASN1_INTEGER *izone = NULL;
ASN1_OCTET_STRING *oct;
if(!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
- OPENSSL_PUT_ERROR(X509V3, SXNET_get_id_ulong, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
M_ASN1_INTEGER_free(izone);
return NULL;
}
diff --git a/src/crypto/x509v3/v3_utl.c b/src/crypto/x509v3/v3_utl.c
index 14a2f3b..6bcb6da 100644
--- a/src/crypto/x509v3/v3_utl.c
+++ b/src/crypto/x509v3/v3_utl.c
@@ -70,6 +70,8 @@
#include <openssl/obj.h>
#include <openssl/x509v3.h>
+#include "../conf/internal.h"
+
static char *strip_spaces(char *name);
static int sk_strcmp(const OPENSSL_STRING *a, const OPENSSL_STRING *b);
@@ -91,7 +93,7 @@ int X509V3_add_value(const char *name, const char *value,
char *tname = NULL, *tvalue = NULL;
if(name && !(tname = BUF_strdup(name))) goto err;
if(value && !(tvalue = BUF_strdup(value))) goto err;
- if(!(vtmp = (CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE)))) goto err;
+ if(!(vtmp = CONF_VALUE_new())) goto err;
if(!*extlist && !(*extlist = sk_CONF_VALUE_new_null())) goto err;
vtmp->section = NULL;
vtmp->name = tname;
@@ -99,7 +101,7 @@ int X509V3_add_value(const char *name, const char *value,
if(!sk_CONF_VALUE_push(*extlist, vtmp)) goto err;
return 1;
err:
- OPENSSL_PUT_ERROR(X509V3, X509V3_add_value, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
if(vtmp) OPENSSL_free(vtmp);
if(tname) OPENSSL_free(tname);
if(tvalue) OPENSSL_free(tvalue);
@@ -145,7 +147,7 @@ char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *a)
if(!a) return NULL;
if(!(bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) ||
!(strtmp = BN_bn2dec(bntmp)) )
- OPENSSL_PUT_ERROR(X509V3, i2s_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
BN_free(bntmp);
return strtmp;
}
@@ -157,7 +159,7 @@ char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, ASN1_INTEGER *a)
if(!a) return NULL;
if(!(bntmp = ASN1_INTEGER_to_BN(a, NULL)) ||
!(strtmp = BN_bn2dec(bntmp)) )
- OPENSSL_PUT_ERROR(X509V3, i2s_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
BN_free(bntmp);
return strtmp;
}
@@ -169,7 +171,7 @@ ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, char *value)
int isneg, ishex;
int ret;
if (!value) {
- OPENSSL_PUT_ERROR(X509V3, s2i_ASN1_INTEGER, X509V3_R_INVALID_NULL_VALUE);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE);
return 0;
}
bn = BN_new();
@@ -188,7 +190,7 @@ ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, char *value)
if (!ret || value[ret]) {
BN_free(bn);
- OPENSSL_PUT_ERROR(X509V3, s2i_ASN1_INTEGER, X509V3_R_BN_DEC2BN_ERROR);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_BN_DEC2BN_ERROR);
return 0;
}
@@ -197,7 +199,7 @@ ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, char *value)
aint = BN_to_ASN1_INTEGER(bn, NULL);
BN_free(bn);
if (!aint) {
- OPENSSL_PUT_ERROR(X509V3, s2i_ASN1_INTEGER, X509V3_R_BN_TO_ASN1_INTEGER_ERROR);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_BN_TO_ASN1_INTEGER_ERROR);
return 0;
}
if (isneg) aint->type |= V_ASN1_NEG;
@@ -232,7 +234,7 @@ int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool)
return 1;
}
err:
- OPENSSL_PUT_ERROR(X509V3, X509V3_get_value_bool, X509V3_R_INVALID_BOOLEAN_STRING);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_BOOLEAN_STRING);
X509V3_conf_err(value);
return 0;
}
@@ -264,7 +266,7 @@ STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
linebuf = BUF_strdup(line);
if (linebuf == NULL)
{
- OPENSSL_PUT_ERROR(X509V3, X509V3_parse_list, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
state = HDR_NAME;
@@ -279,7 +281,7 @@ STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
*p = 0;
ntmp = strip_spaces(q);
if(!ntmp) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_parse_list, X509V3_R_INVALID_NULL_NAME);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME);
goto err;
}
q = p + 1;
@@ -291,7 +293,7 @@ STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
printf("%s\n", ntmp);
#endif
if(!ntmp) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_parse_list, X509V3_R_INVALID_NULL_NAME);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME);
goto err;
}
X509V3_add_value(ntmp, NULL, &values);
@@ -307,7 +309,7 @@ STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
printf("%s\n", ntmp);
#endif
if(!vtmp) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_parse_list, X509V3_R_INVALID_NULL_VALUE);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE);
goto err;
}
X509V3_add_value(ntmp, vtmp, &values);
@@ -324,7 +326,7 @@ STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
printf("%s=%s\n", ntmp, vtmp);
#endif
if(!vtmp) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_parse_list, X509V3_R_INVALID_NULL_VALUE);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE);
goto err;
}
X509V3_add_value(ntmp, vtmp, &values);
@@ -334,7 +336,7 @@ STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
printf("%s\n", ntmp);
#endif
if(!ntmp) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_parse_list, X509V3_R_INVALID_NULL_NAME);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME);
goto err;
}
X509V3_add_value(ntmp, NULL, &values);
@@ -379,7 +381,7 @@ char *hex_to_string(const unsigned char *buffer, long len)
static const char hexdig[] = "0123456789ABCDEF";
if(!buffer || !len) return NULL;
if(!(tmp = OPENSSL_malloc(len * 3 + 1))) {
- OPENSSL_PUT_ERROR(X509V3, hex_to_string, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
q = tmp;
@@ -402,7 +404,7 @@ unsigned char *string_to_hex(const char *str, long *len)
unsigned char *hexbuf, *q;
unsigned char ch, cl, *p;
if(!str) {
- OPENSSL_PUT_ERROR(X509V3, string_to_hex, X509V3_R_INVALID_NULL_ARGUMENT);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT);
return NULL;
}
if(!(hexbuf = OPENSSL_malloc(strlen(str) >> 1))) goto err;
@@ -411,7 +413,7 @@ unsigned char *string_to_hex(const char *str, long *len)
if(ch == ':') continue;
cl = *p++;
if(!cl) {
- OPENSSL_PUT_ERROR(X509V3, string_to_hex, X509V3_R_ODD_NUMBER_OF_DIGITS);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_ODD_NUMBER_OF_DIGITS);
OPENSSL_free(hexbuf);
return NULL;
}
@@ -435,12 +437,12 @@ unsigned char *string_to_hex(const char *str, long *len)
err:
if(hexbuf) OPENSSL_free(hexbuf);
- OPENSSL_PUT_ERROR(X509V3, string_to_hex, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
badhex:
OPENSSL_free(hexbuf);
- OPENSSL_PUT_ERROR(X509V3, string_to_hex, X509V3_R_ILLEGAL_HEX_DIGIT);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_HEX_DIGIT);
return NULL;
}
@@ -882,9 +884,9 @@ static int do_check_string(ASN1_STRING *a, int cmp_type, equal_fn equal,
if (astrlen < 0)
return -1;
rv = equal(astr, astrlen, (unsigned char *)b, blen, flags);
- OPENSSL_free(astr);
if (rv > 0 && peername)
*peername = BUF_strndup((char *)astr, astrlen);
+ OPENSSL_free(astr);
}
return rv;
}
@@ -897,7 +899,7 @@ static int do_x509_check(X509 *x, const char *chk, size_t chklen,
X509_NAME *name = NULL;
size_t i;
int j;
- int cnid;
+ int cnid = NID_undef;
int alt_type;
int san_present = 0;
int rv = 0;
@@ -925,7 +927,6 @@ static int do_x509_check(X509 *x, const char *chk, size_t chklen,
}
else
{
- cnid = 0;
alt_type = V_ASN1_OCTET_STRING;
equal = equal_case;
}
@@ -955,11 +956,16 @@ static int do_x509_check(X509 *x, const char *chk, size_t chklen,
GENERAL_NAMES_free(gens);
if (rv != 0)
return rv;
- if (!cnid
+ if (cnid == NID_undef
|| (san_present
&& !(flags & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT)))
return 0;
}
+
+ /* We're done if CN-ID is not pertinent */
+ if (cnid == NID_undef)
+ return 0;
+
j = -1;
name = X509_get_subject_name(x);
while((j = X509_NAME_get_index_by_NID(name, cnid, j)) >= 0)
diff --git a/src/crypto/x509v3/v3nametest.c b/src/crypto/x509v3/v3name_test.c
index a3197e6..f9f7087 100644
--- a/src/crypto/x509v3/v3nametest.c
+++ b/src/crypto/x509v3/v3name_test.c
@@ -284,7 +284,7 @@ static const struct set_name_fn name_fns[] =
{set_email_and_cn, "set emailAddress", 0, 1},
{set_altname_dns, "set dnsName", 1, 0},
{set_altname_email, "set rfc822Name", 0, 1},
- {NULL, NULL, 0}
+ {NULL, NULL, 0, 0},
};
static X509 *make_cert(void)
diff --git a/src/decrepit/CMakeLists.txt b/src/decrepit/CMakeLists.txt
index b43fea7..0773f9a 100644
--- a/src/decrepit/CMakeLists.txt
+++ b/src/decrepit/CMakeLists.txt
@@ -1,9 +1,19 @@
-add_subdirectory(cast)
+add_subdirectory(bio)
add_subdirectory(blowfish)
+add_subdirectory(cast)
+add_subdirectory(des)
+add_subdirectory(rsa)
+add_subdirectory(xts)
add_library(
decrepit
- $<TARGET_OBJECTS:cast>
+ $<TARGET_OBJECTS:bio_decrepit>
$<TARGET_OBJECTS:blowfish>
+ $<TARGET_OBJECTS:cast>
+ $<TARGET_OBJECTS:des_decrepit>
+ $<TARGET_OBJECTS:rsa_decrepit>
+ $<TARGET_OBJECTS:xts>
)
+
+target_link_libraries(decrepit crypto)
diff --git a/src/decrepit/bio/CMakeLists.txt b/src/decrepit/bio/CMakeLists.txt
new file mode 100644
index 0000000..95d9231
--- /dev/null
+++ b/src/decrepit/bio/CMakeLists.txt
@@ -0,0 +1,9 @@
+include_directories(../../include)
+
+add_library(
+ bio_decrepit
+
+ OBJECT
+
+ base64_bio.c
+)
diff --git a/src/decrepit/bio/base64_bio.c b/src/decrepit/bio/base64_bio.c
new file mode 100644
index 0000000..2056138
--- /dev/null
+++ b/src/decrepit/bio/base64_bio.c
@@ -0,0 +1,536 @@
+/* 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.] */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <openssl/base64.h>
+#include <openssl/bio.h>
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+#include <openssl/mem.h>
+
+
+#define B64_BLOCK_SIZE 1024
+#define B64_BLOCK_SIZE2 768
+#define B64_NONE 0
+#define B64_ENCODE 1
+#define B64_DECODE 2
+#define EVP_ENCODE_LENGTH(l) (((l+2)/3*4)+(l/48+1)*2+80)
+
+typedef struct b64_struct {
+ int buf_len;
+ int buf_off;
+ int tmp_len; /* used to find the start when decoding */
+ int tmp_nl; /* If true, scan until '\n' */
+ int encode;
+ int start; /* have we started decoding yet? */
+ int cont; /* <= 0 when finished */
+ EVP_ENCODE_CTX base64;
+ char buf[EVP_ENCODE_LENGTH(B64_BLOCK_SIZE) + 10];
+ char tmp[B64_BLOCK_SIZE];
+} BIO_B64_CTX;
+
+static int b64_new(BIO *bio) {
+ BIO_B64_CTX *ctx;
+
+ ctx = OPENSSL_malloc(sizeof(*ctx));
+ if (ctx == NULL) {
+ return 0;
+ }
+
+ memset(ctx, 0, sizeof(*ctx));
+
+ ctx->cont = 1;
+ ctx->start = 1;
+
+ bio->init = 1;
+ bio->ptr = (char *)ctx;
+ return 1;
+}
+
+static int b64_free(BIO *bio) {
+ if (bio == NULL) {
+ return 0;
+ }
+ OPENSSL_free(bio->ptr);
+ bio->ptr = NULL;
+ bio->init = 0;
+ bio->flags = 0;
+ return 1;
+}
+
+static int b64_read(BIO *b, char *out, int outl) {
+ int ret = 0, i, ii, j, k, x, n, num, ret_code = 0;
+ BIO_B64_CTX *ctx;
+ uint8_t *p, *q;
+
+ if (out == NULL) {
+ return 0;
+ }
+ ctx = (BIO_B64_CTX *) b->ptr;
+
+ if (ctx == NULL || b->next_bio == NULL) {
+ return 0;
+ }
+
+ BIO_clear_retry_flags(b);
+
+ if (ctx->encode != B64_DECODE) {
+ ctx->encode = B64_DECODE;
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ ctx->tmp_len = 0;
+ EVP_DecodeInit(&ctx->base64);
+ }
+
+ /* First check if there are bytes decoded/encoded */
+ if (ctx->buf_len > 0) {
+ assert(ctx->buf_len >= ctx->buf_off);
+ i = ctx->buf_len - ctx->buf_off;
+ if (i > outl) {
+ i = outl;
+ }
+ assert(ctx->buf_off + i < (int)sizeof(ctx->buf));
+ memcpy(out, &ctx->buf[ctx->buf_off], i);
+ ret = i;
+ out += i;
+ outl -= i;
+ ctx->buf_off += i;
+ if (ctx->buf_len == ctx->buf_off) {
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ }
+ }
+
+ /* At this point, we have room of outl bytes and an empty buffer, so we
+ * should read in some more. */
+
+ ret_code = 0;
+ while (outl > 0) {
+ if (ctx->cont <= 0) {
+ break;
+ }
+
+ i = BIO_read(b->next_bio, &(ctx->tmp[ctx->tmp_len]),
+ B64_BLOCK_SIZE - ctx->tmp_len);
+
+ if (i <= 0) {
+ ret_code = i;
+
+ /* Should we continue next time we are called? */
+ if (!BIO_should_retry(b->next_bio)) {
+ ctx->cont = i;
+ /* If buffer empty break */
+ if (ctx->tmp_len == 0) {
+ break;
+ } else {
+ /* Fall through and process what we have */
+ i = 0;
+ }
+ } else {
+ /* else we retry and add more data to buffer */
+ break;
+ }
+ }
+ i += ctx->tmp_len;
+ ctx->tmp_len = i;
+
+ /* We need to scan, a line at a time until we have a valid line if we are
+ * starting. */
+ if (ctx->start && (BIO_test_flags(b, BIO_FLAGS_BASE64_NO_NL))) {
+ /* ctx->start = 1; */
+ ctx->tmp_len = 0;
+ } else if (ctx->start) {
+ q = p = (uint8_t *)ctx->tmp;
+ num = 0;
+ for (j = 0; j < i; j++) {
+ if (*(q++) != '\n') {
+ continue;
+ }
+
+ /* due to a previous very long line, we need to keep on scanning for a
+ * '\n' before we even start looking for base64 encoded stuff. */
+ if (ctx->tmp_nl) {
+ p = q;
+ ctx->tmp_nl = 0;
+ continue;
+ }
+
+ k = EVP_DecodeUpdate(&(ctx->base64), (uint8_t *)ctx->buf, &num, p,
+ q - p);
+
+ if (k <= 0 && num == 0 && ctx->start) {
+ EVP_DecodeInit(&ctx->base64);
+ } else {
+ if (p != (uint8_t *)&(ctx->tmp[0])) {
+ i -= (p - (uint8_t *)&(ctx->tmp[0]));
+ for (x = 0; x < i; x++) {
+ ctx->tmp[x] = p[x];
+ }
+ }
+ EVP_DecodeInit(&ctx->base64);
+ ctx->start = 0;
+ break;
+ }
+ p = q;
+ }
+
+ /* we fell off the end without starting */
+ if (j == i && num == 0) {
+ /* Is this is one long chunk?, if so, keep on reading until a new
+ * line. */
+ if (p == (uint8_t *)&(ctx->tmp[0])) {
+ /* Check buffer full */
+ if (i == B64_BLOCK_SIZE) {
+ ctx->tmp_nl = 1;
+ ctx->tmp_len = 0;
+ }
+ } else if (p != q) { /* finished on a '\n' */
+ n = q - p;
+ for (ii = 0; ii < n; ii++) {
+ ctx->tmp[ii] = p[ii];
+ }
+ ctx->tmp_len = n;
+ }
+ /* else finished on a '\n' */
+ continue;
+ } else {
+ ctx->tmp_len = 0;
+ }
+ } else if (i < B64_BLOCK_SIZE && ctx->cont > 0) {
+ /* If buffer isn't full and we can retry then restart to read in more
+ * data. */
+ continue;
+ }
+
+ if (BIO_test_flags(b, BIO_FLAGS_BASE64_NO_NL)) {
+ int z, jj;
+
+ jj = i & ~3; /* process per 4 */
+ z = EVP_DecodeBlock((uint8_t *)ctx->buf, (uint8_t *)ctx->tmp, jj);
+ if (jj > 2) {
+ if (ctx->tmp[jj - 1] == '=') {
+ z--;
+ if (ctx->tmp[jj - 2] == '=') {
+ z--;
+ }
+ }
+ }
+ /* z is now number of output bytes and jj is the number consumed. */
+ if (jj != i) {
+ memmove(ctx->tmp, &ctx->tmp[jj], i - jj);
+ ctx->tmp_len = i - jj;
+ }
+ ctx->buf_len = 0;
+ if (z > 0) {
+ ctx->buf_len = z;
+ }
+ i = z;
+ } else {
+ i = EVP_DecodeUpdate(&(ctx->base64), (uint8_t *)ctx->buf,
+ &ctx->buf_len, (uint8_t *)ctx->tmp, i);
+ ctx->tmp_len = 0;
+ }
+ ctx->buf_off = 0;
+ if (i < 0) {
+ ret_code = 0;
+ ctx->buf_len = 0;
+ break;
+ }
+
+ if (ctx->buf_len <= outl) {
+ i = ctx->buf_len;
+ } else {
+ i = outl;
+ }
+
+ memcpy(out, ctx->buf, i);
+ ret += i;
+ ctx->buf_off = i;
+ if (ctx->buf_off == ctx->buf_len) {
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ }
+ outl -= i;
+ out += i;
+ }
+
+ BIO_copy_next_retry(b);
+ return ret == 0 ? ret_code : ret;
+}
+
+static int b64_write(BIO *b, const char *in, int inl) {
+ int ret = 0, n, i;
+ BIO_B64_CTX *ctx;
+
+ ctx = (BIO_B64_CTX *)b->ptr;
+ BIO_clear_retry_flags(b);
+
+ if (ctx->encode != B64_ENCODE) {
+ ctx->encode = B64_ENCODE;
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ ctx->tmp_len = 0;
+ EVP_EncodeInit(&(ctx->base64));
+ }
+
+ assert(ctx->buf_off < (int)sizeof(ctx->buf));
+ assert(ctx->buf_len <= (int)sizeof(ctx->buf));
+ assert(ctx->buf_len >= ctx->buf_off);
+
+ n = ctx->buf_len - ctx->buf_off;
+ while (n > 0) {
+ i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
+ if (i <= 0) {
+ BIO_copy_next_retry(b);
+ return i;
+ }
+ assert(i <= n);
+ ctx->buf_off += i;
+ assert(ctx->buf_off <= (int)sizeof(ctx->buf));
+ assert(ctx->buf_len >= ctx->buf_off);
+ n -= i;
+ }
+
+ /* at this point all pending data has been written. */
+ ctx->buf_off = 0;
+ ctx->buf_len = 0;
+
+ if (in == NULL || inl <= 0) {
+ return 0;
+ }
+
+ while (inl > 0) {
+ n = (inl > B64_BLOCK_SIZE) ? B64_BLOCK_SIZE : inl;
+
+ if (BIO_test_flags(b, BIO_FLAGS_BASE64_NO_NL)) {
+ if (ctx->tmp_len > 0) {
+ assert(ctx->tmp_len <= 3);
+ n = 3 - ctx->tmp_len;
+ /* There's a theoretical possibility of this. */
+ if (n > inl) {
+ n = inl;
+ }
+ memcpy(&(ctx->tmp[ctx->tmp_len]), in, n);
+ ctx->tmp_len += n;
+ ret += n;
+ if (ctx->tmp_len < 3) {
+ break;
+ }
+ ctx->buf_len = EVP_EncodeBlock((uint8_t *)ctx->buf, (uint8_t *)ctx->tmp,
+ ctx->tmp_len);
+ assert(ctx->buf_len <= (int)sizeof(ctx->buf));
+ assert(ctx->buf_len >= ctx->buf_off);
+
+ /* Since we're now done using the temporary buffer, the length should
+ * be zeroed. */
+ ctx->tmp_len = 0;
+ } else {
+ if (n < 3) {
+ memcpy(ctx->tmp, in, n);
+ ctx->tmp_len = n;
+ ret += n;
+ break;
+ }
+ n -= n % 3;
+ ctx->buf_len =
+ EVP_EncodeBlock((uint8_t *)ctx->buf, (const uint8_t *)in, n);
+ assert(ctx->buf_len <= (int)sizeof(ctx->buf));
+ assert(ctx->buf_len >= ctx->buf_off);
+ ret += n;
+ }
+ } else {
+ EVP_EncodeUpdate(&(ctx->base64), (uint8_t *)ctx->buf, &ctx->buf_len,
+ (uint8_t *)in, n);
+ assert(ctx->buf_len <= (int)sizeof(ctx->buf));
+ assert(ctx->buf_len >= ctx->buf_off);
+ ret += n;
+ }
+ inl -= n;
+ in += n;
+
+ ctx->buf_off = 0;
+ n = ctx->buf_len;
+
+ while (n > 0) {
+ i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
+ if (i <= 0) {
+ BIO_copy_next_retry(b);
+ return ret == 0 ? i : ret;
+ }
+ assert(i <= n);
+ n -= i;
+ ctx->buf_off += i;
+ assert(ctx->buf_off <= (int)sizeof(ctx->buf));
+ assert(ctx->buf_len >= ctx->buf_off);
+ }
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ }
+ return ret;
+}
+
+static long b64_ctrl(BIO *b, int cmd, long num, void *ptr) {
+ BIO_B64_CTX *ctx;
+ long ret = 1;
+ int i;
+
+ ctx = (BIO_B64_CTX *)b->ptr;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ ctx->cont = 1;
+ ctx->start = 1;
+ ctx->encode = B64_NONE;
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+
+ case BIO_CTRL_EOF: /* More to read */
+ if (ctx->cont <= 0) {
+ ret = 1;
+ } else {
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ }
+ break;
+
+ case BIO_CTRL_WPENDING: /* More to write in buffer */
+ assert(ctx->buf_len >= ctx->buf_off);
+ ret = ctx->buf_len - ctx->buf_off;
+ if ((ret == 0) && (ctx->encode != B64_NONE) && (ctx->base64.num != 0)) {
+ ret = 1;
+ } else if (ret <= 0) {
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ }
+ break;
+
+ case BIO_CTRL_PENDING: /* More to read in buffer */
+ assert(ctx->buf_len >= ctx->buf_off);
+ ret = ctx->buf_len - ctx->buf_off;
+ if (ret <= 0) {
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ }
+ break;
+
+ case BIO_CTRL_FLUSH:
+ /* do a final write */
+ again:
+ while (ctx->buf_len != ctx->buf_off) {
+ i = b64_write(b, NULL, 0);
+ if (i < 0) {
+ return i;
+ }
+ }
+ if (BIO_test_flags(b, BIO_FLAGS_BASE64_NO_NL)) {
+ if (ctx->tmp_len != 0) {
+ ctx->buf_len = EVP_EncodeBlock((uint8_t *)ctx->buf,
+ (uint8_t *)ctx->tmp, ctx->tmp_len);
+ ctx->buf_off = 0;
+ ctx->tmp_len = 0;
+ goto again;
+ }
+ } else if (ctx->encode != B64_NONE && ctx->base64.num != 0) {
+ ctx->buf_off = 0;
+ EVP_EncodeFinal(&(ctx->base64), (uint8_t *)ctx->buf, &(ctx->buf_len));
+ /* push out the bytes */
+ goto again;
+ }
+ /* Finally flush the underlying BIO */
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+
+ case BIO_C_DO_STATE_MACHINE:
+ BIO_clear_retry_flags(b);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ BIO_copy_next_retry(b);
+ break;
+
+ case BIO_CTRL_INFO:
+ case BIO_CTRL_GET:
+ case BIO_CTRL_SET:
+ default:
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ }
+ return ret;
+}
+
+static long b64_callback_ctrl(BIO *b, int cmd, bio_info_cb fp) {
+ long ret = 1;
+
+ if (b->next_bio == NULL) {
+ return 0;
+ }
+ switch (cmd) {
+ default:
+ ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+ break;
+ }
+ return ret;
+}
+
+static int b64_puts(BIO *b, const char *str) {
+ return b64_write(b, str, strlen(str));
+}
+
+static const BIO_METHOD b64_method = {
+ BIO_TYPE_BASE64, "base64 encoding", b64_write, b64_read, b64_puts,
+ NULL /* gets */, b64_ctrl, b64_new, b64_free, b64_callback_ctrl,
+};
+
+const BIO_METHOD *BIO_f_base64(void) { return &b64_method; }
diff --git a/src/decrepit/blowfish/CMakeLists.txt b/src/decrepit/blowfish/CMakeLists.txt
index afaf641..29729c4 100644
--- a/src/decrepit/blowfish/CMakeLists.txt
+++ b/src/decrepit/blowfish/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. ../../include)
+include_directories(../../include)
add_library(
blowfish
diff --git a/src/decrepit/cast/CMakeLists.txt b/src/decrepit/cast/CMakeLists.txt
index ada99e4..2830381 100644
--- a/src/decrepit/cast/CMakeLists.txt
+++ b/src/decrepit/cast/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. ../../include)
+include_directories(../../include)
add_library(
cast
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/include/openssl/ssl23.h b/src/decrepit/cast/internal.h
index df395a8..15e2222 100644
--- a/src/include/openssl/ssl23.h
+++ b/src/decrepit/cast/internal.h
@@ -1,4 +1,3 @@
-/* ssl/ssl23.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -53,33 +52,30 @@
* 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.]
- */
+ * [including the GNU Public Licence.] */
-#ifndef HEADER_SSL23_H
-#define HEADER_SSL23_H
+#ifndef OPENSSL_HEADER_CAST_INTERNAL_H
+#define OPENSSL_HEADER_CAST_INTERNAL_H
-#ifdef __cplusplus
+#include <openssl/base.h>
+
+#if defined(__cplusplus)
extern "C" {
#endif
-/*client */
-/* write to server */
-#define SSL23_ST_CW_CLNT_HELLO_A (0x210 | SSL_ST_CONNECT)
-#define SSL23_ST_CW_CLNT_HELLO_B (0x211 | SSL_ST_CONNECT)
-/* read from server */
-#define SSL23_ST_CR_SRVR_HELLO_A (0x220 | SSL_ST_CONNECT)
-#define SSL23_ST_CR_SRVR_HELLO_B (0x221 | SSL_ST_CONNECT)
-
-/* server */
-/* read from client */
-#define SSL23_ST_SR_CLNT_HELLO (0x210 | SSL_ST_ACCEPT)
-#define SSL23_ST_SR_V2_CLNT_HELLO (0x220 | SSL_ST_ACCEPT)
-#define SSL23_ST_SR_SWITCH_VERSION (0x230 | SSL_ST_ACCEPT)
+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];
-#ifdef __cplusplus
-}
-#endif
+#if defined(__cplusplus)
+} /* extern C */
#endif
+
+#endif /* OPENSSL_HEADER_CAST_INTERNAL_H */
diff --git a/src/decrepit/des/CMakeLists.txt b/src/decrepit/des/CMakeLists.txt
new file mode 100644
index 0000000..0ee5c2e
--- /dev/null
+++ b/src/decrepit/des/CMakeLists.txt
@@ -0,0 +1,9 @@
+include_directories(../../include)
+
+add_library(
+ des_decrepit
+
+ OBJECT
+
+ cfb64ede.c
+)
diff --git a/src/decrepit/des/cfb64ede.c b/src/decrepit/des/cfb64ede.c
new file mode 100644
index 0000000..f7e81d4
--- /dev/null
+++ b/src/decrepit/des/cfb64ede.c
@@ -0,0 +1,236 @@
+/* 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.] */
+
+#include <string.h>
+
+#include <openssl/des.h>
+
+#include "../crypto/des/internal.h"
+
+
+/* The input and output encrypted as though 64bit cfb mode is being used. The
+ * extra state information to record how much of the 64bit block we have used
+ * is contained in *num; */
+void DES_ede3_cfb64_encrypt(const uint8_t *in, uint8_t *out,
+ long length, DES_key_schedule *ks1,
+ DES_key_schedule *ks2, DES_key_schedule *ks3,
+ DES_cblock *ivec, int *num, int enc) {
+ uint32_t v0, v1;
+ long l = length;
+ int n = *num;
+ uint32_t ti[2];
+ uint8_t *iv, c, cc;
+
+ iv = ivec->bytes;
+ if (enc) {
+ while (l--) {
+ if (n == 0) {
+ c2l(iv, v0);
+ c2l(iv, v1);
+
+ ti[0] = v0;
+ ti[1] = v1;
+ DES_encrypt3(ti, ks1, ks2, ks3);
+ v0 = ti[0];
+ v1 = ti[1];
+
+ iv = ivec->bytes;
+ l2c(v0, iv);
+ l2c(v1, iv);
+ iv = ivec->bytes;
+ }
+ c = *(in++) ^ iv[n];
+ *(out++) = c;
+ iv[n] = c;
+ n = (n + 1) & 0x07;
+ }
+ } else {
+ while (l--) {
+ if (n == 0) {
+ c2l(iv, v0);
+ c2l(iv, v1);
+
+ ti[0] = v0;
+ ti[1] = v1;
+ DES_encrypt3(ti, ks1, ks2, ks3);
+ v0 = ti[0];
+ v1 = ti[1];
+
+ iv = ivec->bytes;
+ l2c(v0, iv);
+ l2c(v1, iv);
+ iv = ivec->bytes;
+ }
+ cc = *(in++);
+ c = iv[n];
+ iv[n] = cc;
+ *(out++) = c ^ cc;
+ n = (n + 1) & 0x07;
+ }
+ }
+ v0 = v1 = ti[0] = ti[1] = c = cc = 0;
+ *num = n;
+}
+
+/* This is compatible with the single key CFB-r for DES, even thought that's
+ * not what EVP needs. */
+
+void DES_ede3_cfb_encrypt(const uint8_t *in, uint8_t *out, int numbits,
+ long length, DES_key_schedule *ks1,
+ DES_key_schedule *ks2, DES_key_schedule *ks3,
+ DES_cblock *ivec, int enc) {
+ uint32_t d0, d1, v0, v1;
+ unsigned long l = length, n = ((unsigned int)numbits + 7) / 8;
+ int num = numbits, i;
+ uint32_t ti[2];
+ uint8_t *iv;
+ uint8_t ovec[16];
+
+ if (num > 64) {
+ return;
+ };
+
+ iv = ivec->bytes;
+ c2l(iv, v0);
+ c2l(iv, v1);
+
+ if (enc) {
+ while (l >= n) {
+ l -= n;
+ ti[0] = v0;
+ ti[1] = v1;
+ DES_encrypt3(ti, ks1, ks2, ks3);
+ c2ln(in, d0, d1, n);
+ in += n;
+ d0 ^= ti[0];
+ d1 ^= ti[1];
+ l2cn(d0, d1, out, n);
+ out += n;
+ /* 30-08-94 - eay - changed because l>>32 and l<<32 are bad under
+ * gcc :-( */
+ if (num == 32) {
+ v0 = v1;
+ v1 = d0;
+ } else if (num == 64) {
+ v0 = d0;
+ v1 = d1;
+ } else {
+ iv = &ovec[0];
+ l2c(v0, iv);
+ l2c(v1, iv);
+ l2c(d0, iv);
+ l2c(d1, iv);
+ /* shift ovec left most of the bits... */
+ memmove(ovec, ovec + num / 8, 8 + (num % 8 ? 1 : 0));
+ /* now the remaining bits */
+ if (num % 8 != 0) {
+ for (i = 0; i < 8; ++i) {
+ ovec[i] <<= num % 8;
+ ovec[i] |= ovec[i + 1] >> (8 - num % 8);
+ }
+ }
+ iv = &ovec[0];
+ c2l(iv, v0);
+ c2l(iv, v1);
+ }
+ }
+ } else {
+ while (l >= n) {
+ l -= n;
+ ti[0] = v0;
+ ti[1] = v1;
+ DES_encrypt3(ti, ks1, ks2, ks3);
+ c2ln(in, d0, d1, n);
+ in += n;
+ /* 30-08-94 - eay - changed because l>>32 and l<<32 are bad under
+ * gcc :-( */
+ if (num == 32) {
+ v0 = v1;
+ v1 = d0;
+ } else if (num == 64) {
+ v0 = d0;
+ v1 = d1;
+ } else {
+ iv = &ovec[0];
+ l2c(v0, iv);
+ l2c(v1, iv);
+ l2c(d0, iv);
+ l2c(d1, iv);
+ /* shift ovec left most of the bits... */
+ memmove(ovec, ovec + num / 8, 8 + (num % 8 ? 1 : 0));
+ /* now the remaining bits */
+ if (num % 8 != 0) {
+ for (i = 0; i < 8; ++i) {
+ ovec[i] <<= num % 8;
+ ovec[i] |= ovec[i + 1] >> (8 - num % 8);
+ }
+ }
+ iv = &ovec[0];
+ c2l(iv, v0);
+ c2l(iv, v1);
+ }
+ d0 ^= ti[0];
+ d1 ^= ti[1];
+ l2cn(d0, d1, out, n);
+ out += n;
+ }
+ }
+
+ iv = ivec->bytes;
+ l2c(v0, iv);
+ l2c(v1, iv);
+ v0 = v1 = d0 = d1 = ti[0] = ti[1] = 0;
+}
diff --git a/src/decrepit/rsa/CMakeLists.txt b/src/decrepit/rsa/CMakeLists.txt
new file mode 100644
index 0000000..66d836b
--- /dev/null
+++ b/src/decrepit/rsa/CMakeLists.txt
@@ -0,0 +1,9 @@
+include_directories(../../include)
+
+add_library(
+ rsa_decrepit
+
+ OBJECT
+
+ rsa_decrepit.c
+)
diff --git a/src/ssl/ssl_algs.c b/src/decrepit/rsa/rsa_decrepit.c
index fda39a5..c238f46 100644
--- a/src/ssl/ssl_algs.c
+++ b/src/decrepit/rsa/rsa_decrepit.c
@@ -54,13 +54,33 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
-#include "internal.h"
+#include <openssl/rsa.h>
-#include <openssl/crypto.h>
+#include <assert.h>
-int SSL_library_init(void) {
- CRYPTO_library_init();
- return 1;
-}
+#include <openssl/bn.h>
+
+
+RSA *RSA_generate_key(int bits, unsigned long e_value, void *callback,
+ void *cb_arg) {
+ assert(callback == NULL);
+ assert(cb_arg == NULL);
+
+ RSA *rsa = RSA_new();
+ BIGNUM *e = BN_new();
-void SSL_load_error_strings(void) {}
+ if (rsa == NULL ||
+ e == NULL ||
+ !BN_set_word(e, e_value) ||
+ !RSA_generate_key_ex(rsa, bits, e, NULL)) {
+ goto err;
+ }
+
+ BN_free(e);
+ return rsa;
+
+err:
+ BN_free(e);
+ RSA_free(rsa);
+ return NULL;
+}
diff --git a/src/decrepit/xts/CMakeLists.txt b/src/decrepit/xts/CMakeLists.txt
new file mode 100644
index 0000000..7dccde0
--- /dev/null
+++ b/src/decrepit/xts/CMakeLists.txt
@@ -0,0 +1,9 @@
+include_directories(../../include)
+
+add_library(
+ xts
+
+ OBJECT
+
+ xts.c
+)
diff --git a/src/decrepit/xts/xts.c b/src/decrepit/xts/xts.c
new file mode 100644
index 0000000..10a696d
--- /dev/null
+++ b/src/decrepit/xts/xts.c
@@ -0,0 +1,258 @@
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ==================================================================== */
+
+#include <openssl/evp.h>
+
+#include <string.h>
+
+#include <openssl/aes.h>
+#include <openssl/cipher.h>
+
+#include "../crypto/modes/internal.h"
+
+
+typedef struct xts128_context {
+ void *key1, *key2;
+ block128_f block1, block2;
+} 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) {
+ union {
+ uint64_t u[2];
+ uint32_t d[4];
+ uint8_t c[16];
+ } tweak, scratch;
+ unsigned int i;
+
+ if (len < 16) return 0;
+
+ memcpy(tweak.c, iv, 16);
+
+ (*ctx->block2)(tweak.c, tweak.c, ctx->key2);
+
+ if (!enc && (len % 16)) len -= 16;
+
+ while (len >= 16) {
+#if STRICT_ALIGNMENT
+ memcpy(scratch.c, inp, 16);
+ scratch.u[0] ^= tweak.u[0];
+ scratch.u[1] ^= tweak.u[1];
+#else
+ 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 STRICT_ALIGNMENT
+ scratch.u[0] ^= tweak.u[0];
+ scratch.u[1] ^= tweak.u[1];
+ memcpy(out, scratch.c, 16);
+#else
+ ((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;
+ len -= 16;
+
+ if (len == 0) return 1;
+
+ 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;
+ }
+ if (enc) {
+ for (i = 0; i < len; ++i) {
+ uint8_t c = inp[i];
+ out[i] = scratch.c[i];
+ scratch.c[i] = c;
+ }
+ scratch.u[0] ^= tweak.u[0];
+ scratch.u[1] ^= tweak.u[1];
+ (*ctx->block1)(scratch.c, scratch.c, ctx->key1);
+ scratch.u[0] ^= tweak.u[0];
+ scratch.u[1] ^= tweak.u[1];
+ memcpy(out - 16, scratch.c, 16);
+ } else {
+ union {
+ uint64_t u[2];
+ uint8_t c[16];
+ } tweak1;
+
+ 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;
+#if STRICT_ALIGNMENT
+ memcpy(scratch.c, inp, 16);
+ scratch.u[0] ^= tweak1.u[0];
+ scratch.u[1] ^= tweak1.u[1];
+#else
+ 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];
+ scratch.u[1] ^= tweak1.u[1];
+
+ for (i = 0; i < len; ++i) {
+ uint8_t c = inp[16 + i];
+ out[16 + i] = scratch.c[i];
+ scratch.c[i] = c;
+ }
+ scratch.u[0] ^= tweak.u[0];
+ scratch.u[1] ^= tweak.u[1];
+ (*ctx->block1)(scratch.c, scratch.c, ctx->key1);
+#if STRICT_ALIGNMENT
+ scratch.u[0] ^= tweak.u[0];
+ scratch.u[1] ^= tweak.u[1];
+ memcpy(out, scratch.c, 16);
+#else
+ ((uint64_t *)out)[0] = scratch.u[0] ^ tweak.u[0];
+ ((uint64_t *)out)[1] = scratch.u[1] ^ tweak.u[1];
+#endif
+ }
+
+ return 1;
+}
+
+typedef struct {
+ union {
+ double align;
+ AES_KEY ks;
+ } ks1, ks2; /* AES key schedules to use */
+ XTS128_CONTEXT xts;
+} EVP_AES_XTS_CTX;
+
+static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
+ const uint8_t *iv, int enc) {
+ EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
+ if (!iv && !key) {
+ return 1;
+ }
+
+ if (key) {
+ /* key_len is two AES keys */
+ if (enc) {
+ AES_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
+ xctx->xts.block1 = (block128_f) AES_encrypt;
+ } else {
+ AES_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
+ xctx->xts.block1 = (block128_f) AES_decrypt;
+ }
+
+ AES_set_encrypt_key(key + ctx->key_len / 2,
+ ctx->key_len * 4, &xctx->ks2.ks);
+ xctx->xts.block2 = (block128_f) AES_encrypt;
+ xctx->xts.key1 = &xctx->ks1;
+ }
+
+ if (iv) {
+ xctx->xts.key2 = &xctx->ks2;
+ memcpy(ctx->iv, iv, 16);
+ }
+
+ return 1;
+}
+
+static int aes_xts_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out,
+ const uint8_t *in, size_t len) {
+ EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
+ if (!xctx->xts.key1 ||
+ !xctx->xts.key2 ||
+ !out ||
+ !in ||
+ len < AES_BLOCK_SIZE ||
+ !CRYPTO_xts128_encrypt(&xctx->xts, ctx->iv, in, out, len, ctx->encrypt)) {
+ return 0;
+ }
+ return 1;
+}
+
+static int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) {
+ EVP_AES_XTS_CTX *xctx = c->cipher_data;
+ if (type == EVP_CTRL_COPY) {
+ EVP_CIPHER_CTX *out = ptr;
+ EVP_AES_XTS_CTX *xctx_out = out->cipher_data;
+ if (xctx->xts.key1) {
+ if (xctx->xts.key1 != &xctx->ks1) {
+ return 0;
+ }
+ xctx_out->xts.key1 = &xctx_out->ks1;
+ }
+ if (xctx->xts.key2) {
+ if (xctx->xts.key2 != &xctx->ks2) {
+ return 0;
+ }
+ xctx_out->xts.key2 = &xctx_out->ks2;
+ }
+ return 1;
+ } else if (type != EVP_CTRL_INIT) {
+ return -1;
+ }
+ /* key1 and key2 are used as an indicator both key and IV are set */
+ xctx->xts.key1 = NULL;
+ xctx->xts.key2 = NULL;
+ return 1;
+}
+
+static const EVP_CIPHER aes_256_xts = {
+ 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,
+ NULL /* app_data */, aes_xts_init_key, aes_xts_cipher,
+ NULL /* cleanup */, aes_xts_ctrl};
+
+const EVP_CIPHER *EVP_aes_256_xts(void) { return &aes_256_xts; }
diff --git a/src/doc/doc.css b/src/doc/doc.css
deleted file mode 120000
index d7c5102..0000000
--- a/src/doc/doc.css
+++ /dev/null
@@ -1 +0,0 @@
-../util/doc.css \ No newline at end of file
diff --git a/src/include/openssl/aead.h b/src/include/openssl/aead.h
index dc453e3..092d2f6 100644
--- a/src/include/openssl/aead.h
+++ b/src/include/openssl/aead.h
@@ -24,7 +24,7 @@ extern "C" {
/* Authenticated Encryption with Additional Data.
*
- * AEAD couples confidentiality and integrity in a single primtive. AEAD
+ * AEAD couples confidentiality and integrity in a single primitive. AEAD
* algorithms take a key and then can seal and open individual messages. Each
* message has a unique, per-message nonce and, optionally, additional data
* which is authenticated but not included in the ciphertext.
@@ -98,9 +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 an AEAD built from ChaCha20 and Poly1305. */
+/* 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_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.
*
@@ -120,7 +126,7 @@ OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_key_wrap(void);
* block counter, thus the maximum plaintext size is 64GB. */
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_ctr_hmac_sha256(void);
-/* EVP_aead_aes_128_ctr_hmac_sha256 is AES-256 in CTR mode with HMAC-SHA256 for
+/* EVP_aead_aes_256_ctr_hmac_sha256 is AES-256 in CTR mode with HMAC-SHA256 for
* authentication. See |EVP_aead_aes_128_ctr_hmac_sha256| for details. */
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_ctr_hmac_sha256(void);
@@ -153,6 +159,8 @@ OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha384_tls(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv(void);
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_null_sha1_tls(void);
+
/* SSLv3-specific AEAD algorithms.
*
@@ -167,6 +175,7 @@ OPENSSL_EXPORT const EVP_AEAD *EVP_aead_rc4_sha1_ssl3(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_ssl3(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_ssl3(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_ssl3(void);
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_null_sha1_ssl3(void);
/* Utility functions. */
@@ -223,11 +232,17 @@ enum evp_aead_direction_t {
evp_aead_seal,
};
-/* EVP_AEAD_CTX_init initializes |ctx| for the given AEAD algorithm from |impl|.
- * The |impl| argument may be NULL to choose the default implementation.
- * Authentication tags may be truncated by passing a size as |tag_len|. A
- * |tag_len| of zero indicates the default tag length and this is defined as
- * EVP_AEAD_DEFAULT_TAG_LENGTH for readability.
+/* EVP_AEAD_CTX_zero sets an uninitialized |ctx| to the zero state. It must be
+ * initialized with |EVP_AEAD_CTX_init| before use. It is safe, but not
+ * necessary, to call |EVP_AEAD_CTX_cleanup| in this state. This may be used for
+ * more uniform cleanup of |EVP_AEAD_CTX|. */
+OPENSSL_EXPORT void EVP_AEAD_CTX_zero(EVP_AEAD_CTX *ctx);
+
+/* EVP_AEAD_CTX_init initializes |ctx| for the given AEAD algorithm. The |impl|
+ * argument is ignored and should be NULL. Authentication tags may be truncated
+ * by passing a size as |tag_len|. A |tag_len| of zero indicates the default
+ * tag length and this is defined as EVP_AEAD_DEFAULT_TAG_LENGTH for
+ * readability.
*
* Returns 1 on success. Otherwise returns 0 and pushes to the error stack. In
* the error case, you do not need to call |EVP_AEAD_CTX_cleanup|, but it's
@@ -307,6 +322,22 @@ OPENSSL_EXPORT int EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
OPENSSL_EXPORT int EVP_AEAD_CTX_get_rc4_state(const EVP_AEAD_CTX *ctx,
const RC4_KEY **out_key);
+/* EVP_AEAD_CTX_get_iv sets |*out_len| to the length of the IV for |ctx| and
+ * sets |*out_iv| to point to that many bytes of the current IV. This is only
+ * meaningful for AEADs with implicit IVs (i.e. CBC mode in SSLv3 and TLS 1.0).
+ *
+ * It returns one on success or zero on error. */
+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 */
diff --git a/src/include/openssl/aes.h b/src/include/openssl/aes.h
index 84cde41..ed060ff 100644
--- a/src/include/openssl/aes.h
+++ b/src/include/openssl/aes.h
@@ -124,7 +124,7 @@ OPENSSL_EXPORT void AES_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
const AES_KEY *key, uint8_t *ivec,
const int enc);
-/* AES_ofb128_encrypt encrypts (or decrypts, it's the same in CTR mode) |len|
+/* AES_ofb128_encrypt encrypts (or decrypts, it's the same in OFB mode) |len|
* bytes from |in| to |out|. The |num| parameter must be set to zero on the
* first call. */
OPENSSL_EXPORT void AES_ofb128_encrypt(const uint8_t *in, uint8_t *out,
diff --git a/src/crypto/arm_arch.h b/src/include/openssl/arm_arch.h
index 0600fbb..1471db9 100644
--- a/src/crypto/arm_arch.h
+++ b/src/include/openssl/arm_arch.h
@@ -102,15 +102,6 @@
* will be included. */
#define __ARM_MAX_ARCH__ 8
-#if !__ASSEMBLER__
-
-/* OPENSSL_armcap_P contains flags describing the capabilities of the CPU and
- * is easy for assembly code to acesss. For C code, see the functions in
- * |cpu.h|. */
-extern uint32_t OPENSSL_armcap_P;
-
-#endif /* !__ASSEMBLER__ */
-
/* ARMV7_NEON is true when a NEON unit is present in the current CPU. */
#define ARMV7_NEON (1 << 0)
@@ -133,4 +124,4 @@ extern uint32_t OPENSSL_armcap_P;
#define ARMV8_PMULL (1 << 5)
-#endif /* OPENSSL_HEADER_THREAD_H */
+#endif /* OPENSSL_HEADER_ARM_ARCH_H */
diff --git a/src/include/openssl/asn1.h b/src/include/openssl/asn1.h
index 4baf81c..63bde18 100644
--- a/src/include/openssl/asn1.h
+++ b/src/include/openssl/asn1.h
@@ -1,4 +1,3 @@
-/* crypto/asn1/asn1.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -515,7 +514,6 @@ struct X509_algor_st
ASN1_OBJECT *algorithm;
ASN1_TYPE *parameter;
} /* X509_ALGOR */;
-DEFINE_STACK_OF(X509_ALGOR);
DECLARE_ASN1_FUNCTIONS(X509_ALGOR)
@@ -950,7 +948,7 @@ OPENSSL_EXPORT void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in
CHECKED_PPTR_OF(type, x)))
OPENSSL_EXPORT void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x);
-OPENSSL_EXPORT int ASN1_i2d_bio(i2d_of_void *i2d,BIO *out, unsigned char *x);
+OPENSSL_EXPORT int ASN1_i2d_bio(i2d_of_void *i2d,BIO *out, void *x);
#define ASN1_i2d_bio_of(type,i2d,out,x) \
(ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \
@@ -1078,70 +1076,6 @@ OPENSSL_EXPORT int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, asn1_ps_f
}
#endif
-#define ASN1_F_ASN1_BIT_STRING_set_bit 100
-#define ASN1_F_ASN1_ENUMERATED_set 101
-#define ASN1_F_ASN1_ENUMERATED_to_BN 102
-#define ASN1_F_ASN1_GENERALIZEDTIME_adj 103
-#define ASN1_F_ASN1_INTEGER_set 104
-#define ASN1_F_ASN1_INTEGER_to_BN 105
-#define ASN1_F_ASN1_OBJECT_new 106
-#define ASN1_F_ASN1_PCTX_new 107
-#define ASN1_F_ASN1_STRING_TABLE_add 108
-#define ASN1_F_ASN1_STRING_set 109
-#define ASN1_F_ASN1_STRING_type_new 110
-#define ASN1_F_ASN1_TIME_adj 111
-#define ASN1_F_ASN1_UTCTIME_adj 112
-#define ASN1_F_ASN1_d2i_fp 113
-#define ASN1_F_ASN1_dup 114
-#define ASN1_F_ASN1_generate_v3 115
-#define ASN1_F_ASN1_get_object 116
-#define ASN1_F_ASN1_i2d_bio 117
-#define ASN1_F_ASN1_i2d_fp 118
-#define ASN1_F_ASN1_item_d2i_fp 119
-#define ASN1_F_ASN1_item_dup 120
-#define ASN1_F_ASN1_item_ex_d2i 121
-#define ASN1_F_ASN1_item_i2d_bio 122
-#define ASN1_F_ASN1_item_i2d_fp 123
-#define ASN1_F_ASN1_item_pack 124
-#define ASN1_F_ASN1_item_unpack 125
-#define ASN1_F_ASN1_mbstring_ncopy 126
-#define ASN1_F_ASN1_template_new 127
-#define ASN1_F_BIO_new_NDEF 128
-#define ASN1_F_BN_to_ASN1_ENUMERATED 129
-#define ASN1_F_BN_to_ASN1_INTEGER 130
-#define ASN1_F_a2d_ASN1_OBJECT 131
-#define ASN1_F_a2i_ASN1_ENUMERATED 132
-#define ASN1_F_a2i_ASN1_INTEGER 133
-#define ASN1_F_a2i_ASN1_STRING 134
-#define ASN1_F_append_exp 135
-#define ASN1_F_asn1_cb 136
-#define ASN1_F_asn1_check_tlen 137
-#define ASN1_F_asn1_collate_primitive 138
-#define ASN1_F_asn1_collect 139
-#define ASN1_F_asn1_d2i_ex_primitive 140
-#define ASN1_F_asn1_d2i_read_bio 141
-#define ASN1_F_asn1_do_adb 142
-#define ASN1_F_asn1_ex_c2i 143
-#define ASN1_F_asn1_find_end 144
-#define ASN1_F_asn1_item_ex_combine_new 145
-#define ASN1_F_asn1_str2type 146
-#define ASN1_F_asn1_template_ex_d2i 147
-#define ASN1_F_asn1_template_noexp_d2i 148
-#define ASN1_F_bitstr_cb 149
-#define ASN1_F_c2i_ASN1_BIT_STRING 150
-#define ASN1_F_c2i_ASN1_INTEGER 151
-#define ASN1_F_c2i_ASN1_OBJECT 152
-#define ASN1_F_collect_data 153
-#define ASN1_F_d2i_ASN1_BOOLEAN 154
-#define ASN1_F_d2i_ASN1_OBJECT 155
-#define ASN1_F_d2i_ASN1_UINTEGER 156
-#define ASN1_F_d2i_ASN1_UTCTIME 157
-#define ASN1_F_d2i_ASN1_bytes 158
-#define ASN1_F_d2i_ASN1_type_bytes 159
-#define ASN1_F_i2d_ASN1_TIME 160
-#define ASN1_F_i2d_PrivateKey 161
-#define ASN1_F_long_c2i 162
-#define ASN1_F_parse_tagging 163
#define ASN1_R_ASN1_LENGTH_MISMATCH 100
#define ASN1_R_AUX_ERROR 101
#define ASN1_R_BAD_GET_ASN1_OBJECT_CALL 102
@@ -1192,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/asn1_mac.h b/src/include/openssl/asn1_mac.h
index 49b2a28..f319bee 100644
--- a/src/include/openssl/asn1_mac.h
+++ b/src/include/openssl/asn1_mac.h
@@ -1,4 +1,3 @@
-/* crypto/asn1/asn1_mac.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
diff --git a/src/include/openssl/asn1t.h b/src/include/openssl/asn1t.h
index 0f2560b..b43c332 100644
--- a/src/include/openssl/asn1t.h
+++ b/src/include/openssl/asn1t.h
@@ -1,4 +1,3 @@
-/* asn1t.h */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
diff --git a/src/include/openssl/base.h b/src/include/openssl/base.h
index b769ad5..47b3ccb 100644
--- a/src/include/openssl/base.h
+++ b/src/include/openssl/base.h
@@ -79,9 +79,8 @@ extern "C" {
#elif defined(__arm) || defined(__arm__) || defined(_M_ARM)
#define OPENSSL_32_BIT
#define OPENSSL_ARM
-#elif defined(__aarch64__)
+#elif defined(__PPC64__) || defined(__powerpc64__)
#define OPENSSL_64_BIT
-#define OPENSSL_AARCH64
#elif defined(__mips__) && !defined(__LP64__)
#define OPENSSL_32_BIT
#define OPENSSL_MIPS
@@ -99,7 +98,7 @@ extern "C" {
#define OPENSSL_APPLE
#endif
-#if defined(WIN32) || defined(_WIN32)
+#if defined(_WIN32)
#define OPENSSL_WINDOWS
#endif
@@ -109,7 +108,9 @@ extern "C" {
#endif
#define OPENSSL_IS_BORINGSSL
+#define BORINGSSL_201510
#define OPENSSL_VERSION_NUMBER 0x10002000
+#define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER
#if defined(BORINGSSL_SHARED_LIBRARY)
@@ -166,13 +167,29 @@ typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID;
typedef struct DIST_POINT_st DIST_POINT;
typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT;
typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS;
+typedef struct Netscape_certificate_sequence NETSCAPE_CERT_SEQUENCE;
+typedef struct Netscape_spkac_st NETSCAPE_SPKAC;
+typedef struct Netscape_spki_st NETSCAPE_SPKI;
+typedef struct PBE2PARAM_st PBE2PARAM;
+typedef struct PBEPARAM_st PBEPARAM;
+typedef struct PBKDF2PARAM_st PBKDF2PARAM;
typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE;
typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL;
typedef struct X509_POLICY_NODE_st X509_POLICY_NODE;
typedef struct X509_POLICY_TREE_st X509_POLICY_TREE;
typedef struct X509_algor_st X509_ALGOR;
+typedef struct X509_crl_info_st X509_CRL_INFO;
typedef struct X509_crl_st X509_CRL;
+typedef struct X509_extension_st X509_EXTENSION;
+typedef struct X509_info_st X509_INFO;
+typedef struct X509_name_entry_st X509_NAME_ENTRY;
+typedef struct X509_name_st X509_NAME;
+typedef struct X509_objects_st X509_OBJECTS;
typedef struct X509_pubkey_st X509_PUBKEY;
+typedef struct X509_req_info_st X509_REQ_INFO;
+typedef struct X509_req_st X509_REQ;
+typedef struct X509_sig_st X509_SIG;
+typedef struct X509_val_st X509_VAL;
typedef struct bignum_ctx BN_CTX;
typedef struct bignum_st BIGNUM;
typedef struct bio_method_st BIO_METHOD;
@@ -185,9 +202,7 @@ typedef struct cbs_st CBS;
typedef struct cmac_ctx_st CMAC_CTX;
typedef struct conf_st CONF;
typedef struct conf_value_st CONF_VALUE;
-typedef struct dh_method DH_METHOD;
typedef struct dh_st DH;
-typedef struct dsa_method DSA_METHOD;
typedef struct dsa_st DSA;
typedef struct ec_key_st EC_KEY;
typedef struct ecdsa_method_st ECDSA_METHOD;
@@ -198,6 +213,7 @@ typedef struct env_md_st EVP_MD;
typedef struct evp_aead_st EVP_AEAD;
typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;
typedef struct evp_cipher_st EVP_CIPHER;
+typedef struct evp_encode_ctx_st EVP_ENCODE_CTX;
typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD;
typedef struct evp_pkey_ctx_st EVP_PKEY_CTX;
typedef struct evp_pkey_method_st EVP_PKEY_METHOD;
@@ -205,8 +221,9 @@ typedef struct evp_pkey_st EVP_PKEY;
typedef struct hmac_ctx_st HMAC_CTX;
typedef struct md4_state_st MD4_CTX;
typedef struct md5_state_st MD5_CTX;
-typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO;
typedef struct pkcs12_st PKCS12;
+typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO;
+typedef struct private_key_st X509_PKEY;
typedef struct rand_meth_st RAND_METHOD;
typedef struct rc4_key_st RC4_KEY;
typedef struct rsa_meth_st RSA_METHOD;
@@ -214,15 +231,26 @@ typedef struct rsa_st RSA;
typedef struct sha256_state_st SHA256_CTX;
typedef struct sha512_state_st SHA512_CTX;
typedef struct sha_state_st SHA_CTX;
+typedef struct srtp_protection_profile_st SRTP_PROTECTION_PROFILE;
+typedef struct ssl_cipher_st SSL_CIPHER;
typedef struct ssl_ctx_st SSL_CTX;
+typedef struct ssl_custom_extension SSL_CUSTOM_EXTENSION;
+typedef struct ssl_method_st SSL_METHOD;
+typedef struct ssl_session_st SSL_SESSION;
typedef struct ssl_st SSL;
typedef struct st_ERR_FNS ERR_FNS;
typedef struct v3_ext_ctx X509V3_CTX;
+typedef struct x509_attributes_st X509_ATTRIBUTE;
+typedef struct x509_cert_aux_st X509_CERT_AUX;
+typedef struct x509_cert_pair_st X509_CERT_PAIR;
+typedef struct x509_cinf_st X509_CINF;
typedef struct x509_crl_method_st X509_CRL_METHOD;
typedef struct x509_revoked_st X509_REVOKED;
typedef struct x509_st X509;
typedef struct x509_store_ctx_st X509_STORE_CTX;
typedef struct x509_store_st X509_STORE;
+typedef struct x509_trust_st X509_TRUST;
+
typedef void *OPENSSL_BLOCK;
diff --git a/src/include/openssl/base64.h b/src/include/openssl/base64.h
index 7aee990..f28e7dd 100644
--- a/src/include/openssl/base64.h
+++ b/src/include/openssl/base64.h
@@ -70,32 +70,8 @@ extern "C" {
* base64 encoding and decoding. */
-typedef struct evp_encode_ctx_st EVP_ENCODE_CTX;
-
-
/* Encoding */
-/* EVP_EncodeInit initialises |*ctx|, which is typically stack
- * allocated, for an encoding operation.
- *
- * NOTE: The encoding operation breaks its output with newlines every
- * 64 characters of output (48 characters of input). Use
- * EVP_EncodeBlock to encode raw base64. */
-OPENSSL_EXPORT void EVP_EncodeInit(EVP_ENCODE_CTX *ctx);
-
-/* EVP_EncodeUpdate encodes |in_len| bytes from |in| and writes an encoded
- * version of them to |out| and sets |*out_len| to the number of bytes written.
- * Some state may be contained in |ctx| so |EVP_EncodeFinal| must be used to
- * flush it before using the encoded data. */
-OPENSSL_EXPORT void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out,
- int *out_len, const uint8_t *in,
- size_t in_len);
-
-/* EVP_EncodeFinal flushes any remaining output bytes from |ctx| to |out| and
- * sets |*out_len| to the number of bytes written. */
-OPENSSL_EXPORT void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out,
- int *out_len);
-
/* EVP_EncodeBlock encodes |src_len| bytes from |src| and writes the
* result to |dst| with a trailing NUL. It returns the number of bytes
* written, not including this trailing NUL. */
@@ -124,6 +100,36 @@ OPENSSL_EXPORT int EVP_DecodeBase64(uint8_t *out, size_t *out_len,
size_t max_out, const uint8_t *in,
size_t in_len);
+
+/* Deprecated functions.
+ *
+ * OpenSSL provides a streaming base64 implementation, however its behavior is
+ * very specific to PEM. It is also very lenient of invalid input. Use of any of
+ * these functions is thus deprecated.
+ *
+ * TODO(davidben): Import upstream's rewrite that rejects the invalid input. */
+
+/* EVP_EncodeInit initialises |*ctx|, which is typically stack
+ * allocated, for an encoding operation.
+ *
+ * NOTE: The encoding operation breaks its output with newlines every
+ * 64 characters of output (48 characters of input). Use
+ * EVP_EncodeBlock to encode raw base64. */
+OPENSSL_EXPORT void EVP_EncodeInit(EVP_ENCODE_CTX *ctx);
+
+/* EVP_EncodeUpdate encodes |in_len| bytes from |in| and writes an encoded
+ * version of them to |out| and sets |*out_len| to the number of bytes written.
+ * Some state may be contained in |ctx| so |EVP_EncodeFinal| must be used to
+ * flush it before using the encoded data. */
+OPENSSL_EXPORT void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out,
+ int *out_len, const uint8_t *in,
+ size_t in_len);
+
+/* EVP_EncodeFinal flushes any remaining output bytes from |ctx| to |out| and
+ * sets |*out_len| to the number of bytes written. */
+OPENSSL_EXPORT void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out,
+ int *out_len);
+
/* EVP_DecodeInit initialises |*ctx|, which is typically stack allocated, for
* a decoding operation.
*
@@ -148,9 +154,8 @@ OPENSSL_EXPORT int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out,
OPENSSL_EXPORT int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out,
int *out_len);
-/* Deprecated: EVP_DecodeBlock encodes |src_len| bytes from |src| and
- * writes the result to |dst|. It returns the number of bytes written
- * or -1 on error.
+/* EVP_DecodeBlock encodes |src_len| bytes from |src| and writes the result to
+ * |dst|. It returns the number of bytes written or -1 on error.
*
* WARNING: EVP_DecodeBlock's return value does not take padding into
* account. It also strips leading whitespace and trailing
diff --git a/src/include/openssl/bio.h b/src/include/openssl/bio.h
index 8724657..c88a3e1 100644
--- a/src/include/openssl/bio.h
+++ b/src/include/openssl/bio.h
@@ -76,8 +76,6 @@ extern "C" {
/* Allocation and freeing. */
-DEFINE_STACK_OF(BIO);
-
/* BIO_new creates a new BIO with the given type and a reference count of one.
* It returns the fresh |BIO|, or NULL on error. */
OPENSSL_EXPORT BIO *BIO_new(const BIO_METHOD *type);
@@ -207,7 +205,7 @@ OPENSSL_EXPORT void BIO_clear_flags(BIO *bio, int flags);
* flags on |bio|. */
OPENSSL_EXPORT void BIO_set_retry_read(BIO *bio);
-/* BIO_set_retry_read sets the |BIO_FLAGS_WRITE| and |BIO_FLAGS_SHOULD_RETRY|
+/* BIO_set_retry_write sets the |BIO_FLAGS_WRITE| and |BIO_FLAGS_SHOULD_RETRY|
* flags on |bio|. */
OPENSSL_EXPORT void BIO_set_retry_write(BIO *bio);
@@ -446,8 +444,9 @@ OPENSSL_EXPORT BIO *BIO_new_fd(int fd, int close_flag);
* or zero on error. */
OPENSSL_EXPORT int BIO_set_fd(BIO *bio, int fd, int close_flag);
-/* BIO_get_fd sets |*out_fd| to the file descriptor currently in use by |bio|.
- * It returns one on success and zero on error. */
+/* BIO_get_fd returns the file descriptor currently in use by |bio| or -1 if
+ * |bio| does not wrap a file descriptor. If there is a file descriptor and
+ * |out_fd| is not NULL, it also sets |*out_fd| to the file descriptor. */
OPENSSL_EXPORT int BIO_get_fd(BIO *bio, int *out_fd);
@@ -656,7 +655,7 @@ OPENSSL_EXPORT int BIO_zero_copy_get_read_buf(BIO* bio,
* error stack. */
OPENSSL_EXPORT int BIO_zero_copy_get_read_buf_done(BIO* bio, size_t bytes_read);
-/* BIO_zero_copy_get_write_buf_done initiates a zero copy write operation.
+/* BIO_zero_copy_get_write_buf initiates a zero copy write operation.
* |out_write_buf| is set to to the internal write buffer, and |out_buf_offset|
* is set to the current write position of |out_write_buf|.
* The number of bytes available for write from |out_write_buf| +
@@ -667,7 +666,7 @@ OPENSSL_EXPORT int BIO_zero_copy_get_read_buf_done(BIO* bio, size_t bytes_read);
* stack.
*
* The zero copy write operation is completed by calling
- * |BIO_zero_copy_write_buf_done|. Neither |BIO_zero_copy_get_write_buf|
+ * |BIO_zero_copy_get_write_buf_done|. Neither |BIO_zero_copy_get_write_buf|
* nor any other I/O write operation may be called while a zero copy write
* operation is active. */
OPENSSL_EXPORT int BIO_zero_copy_get_write_buf(BIO* bio,
@@ -675,8 +674,8 @@ OPENSSL_EXPORT int BIO_zero_copy_get_write_buf(BIO* bio,
size_t* out_buf_offset,
size_t* out_available_bytes);
-/* BIO_zero_copy_write_buf_done must be called after writing to a BIO using
- * |BIO_zero_copy_get_write_buf_done| to finish the write operation. The
+/* BIO_zero_copy_get_write_buf_done must be called after writing to a BIO using
+ * |BIO_zero_copy_get_write_buf| to finish the write operation. The
* |bytes_written| argument gives the number of bytes written.
*
* It returns one on success. In case of error it returns zero and pushes to the
@@ -727,6 +726,19 @@ OPENSSL_EXPORT int BIO_zero_copy_get_write_buf_done(BIO* bio,
#define BIO_print_errors_fp ERR_print_errors_fp
+/* Deprecated functions. */
+
+/* BIO_f_base64 returns a filter |BIO| that base64-encodes data written into
+ * it, and decodes data read from it. |BIO_gets| is not supported. Call
+ * |BIO_flush| when done writing, to signal that no more data are to be
+ * encoded. The flag |BIO_FLAGS_BASE64_NO_NL| may be set to encode all the data
+ * on one line. */
+OPENSSL_EXPORT const BIO_METHOD *BIO_f_base64(void);
+
+/* ERR_print_errors is an alias for |BIO_print_errors|. */
+OPENSSL_EXPORT void ERR_print_errors(BIO *bio);
+
+
/* Private functions */
#define BIO_FLAGS_READ 0x01
@@ -785,7 +797,7 @@ struct bio_method_st {
struct bio_st {
const BIO_METHOD *method;
/* bio, mode, argp, argi, argl, ret */
- long (*callback)(struct bio_st *, int, const char *, int, long, long);
+ long (*callback)(BIO *, int, const char *, int, long, long);
char *cb_arg; /* first argument for the callback */
/* init is non-zero if this |BIO| has been initialised. */
@@ -804,7 +816,7 @@ struct bio_st {
void *ptr;
/* next_bio points to the next |BIO| in a chain. This |BIO| owns a reference
* to |next_bio|. */
- struct bio_st *next_bio; /* used by filter BIOs */
+ BIO *next_bio; /* used by filter BIOs */
size_t num_read, num_write;
};
@@ -831,7 +843,6 @@ struct bio_st {
#define BIO_C_GET_MD_CTX 120
#define BIO_C_GET_PROXY_PARAM 121
#define BIO_C_SET_BUFF_READ_DATA 122 /* data to read first */
-#define BIO_C_GET_CONNECT 123
#define BIO_C_GET_ACCEPT 124
#define BIO_C_SET_SSL_RENEGOTIATE_BYTES 125
#define BIO_C_GET_SSL_NUM_RENEGOTIATES 126
@@ -870,25 +881,6 @@ struct bio_st {
} /* extern C */
#endif
-#define BIO_F_BIO_callback_ctrl 100
-#define BIO_F_BIO_ctrl 101
-#define BIO_F_BIO_new 102
-#define BIO_F_BIO_new_file 103
-#define BIO_F_BIO_new_mem_buf 104
-#define BIO_F_BIO_zero_copy_get_read_buf 105
-#define BIO_F_BIO_zero_copy_get_read_buf_done 106
-#define BIO_F_BIO_zero_copy_get_write_buf 107
-#define BIO_F_BIO_zero_copy_get_write_buf_done 108
-#define BIO_F_bio_io 109
-#define BIO_F_bio_make_pair 110
-#define BIO_F_bio_write 111
-#define BIO_F_buffer_ctrl 112
-#define BIO_F_conn_ctrl 113
-#define BIO_F_conn_state 114
-#define BIO_F_file_ctrl 115
-#define BIO_F_file_read 116
-#define BIO_F_mem_write 117
-#define BIO_F_BIO_printf 118
#define BIO_R_BAD_FOPEN_MODE 100
#define BIO_R_BROKEN_PIPE 101
#define BIO_R_CONNECT_ERROR 102
diff --git a/src/include/openssl/bn.h b/src/include/openssl/bn.h
index ec1c8ff..6e971e4 100644
--- a/src/include/openssl/bn.h
+++ b/src/include/openssl/bn.h
@@ -182,7 +182,8 @@ OPENSSL_EXPORT void BN_clear_free(BIGNUM *bn);
* allocated BIGNUM on success or NULL otherwise. */
OPENSSL_EXPORT BIGNUM *BN_dup(const BIGNUM *src);
-/* BN_copy sets |dest| equal to |src| and returns |dest|. */
+/* BN_copy sets |dest| equal to |src| and returns |dest| or NULL on allocation
+ * failure. */
OPENSSL_EXPORT BIGNUM *BN_copy(BIGNUM *dest, const BIGNUM *src);
/* BN_clear sets |bn| to zero and erases the old data. */
@@ -252,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. */
@@ -297,6 +301,21 @@ OPENSSL_EXPORT int BN_print_fp(FILE *fp, const BIGNUM *a);
OPENSSL_EXPORT BN_ULONG BN_get_word(const BIGNUM *bn);
+/* ASN.1 functions. */
+
+/* BN_cbs2unsigned parses a non-negative DER INTEGER from |cbs| writes the
+ * result to |ret|. It returns one on success and zero on failure. */
+OPENSSL_EXPORT int BN_cbs2unsigned(CBS *cbs, BIGNUM *ret);
+
+/* BN_cbs2unsigned_buggy acts like |BN_cbs2unsigned| but tolerates some invalid
+ * encodings. Do not use this function. */
+OPENSSL_EXPORT int BN_cbs2unsigned_buggy(CBS *cbs, BIGNUM *ret);
+
+/* BN_bn2cbb marshals |bn| as a non-negative DER INTEGER and appends the result
+ * to |cbb|. It returns one on success and zero on failure. */
+OPENSSL_EXPORT int BN_bn2cbb(CBB *cbb, const BIGNUM *bn);
+
+
/* Internal functions.
*
* These functions are useful for code that is doing low-level manipulations of
@@ -310,7 +329,7 @@ OPENSSL_EXPORT void bn_correct_top(BIGNUM *bn);
/* bn_wexpand ensures that |bn| has at least |words| works of space without
* altering its value. It returns one on success or zero on allocation
* failure. */
-OPENSSL_EXPORT BIGNUM *bn_wexpand(BIGNUM *bn, unsigned words);
+OPENSSL_EXPORT BIGNUM *bn_wexpand(BIGNUM *bn, size_t words);
/* BIGNUM pools.
@@ -516,7 +535,7 @@ OPENSSL_EXPORT int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
OPENSSL_EXPORT int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
const BIGNUM *m, BN_CTX *ctx);
-/* BN_mod_mul sets |r| = |a|^2 mod |m|. It returns one on success and zero
+/* BN_mod_sqr sets |r| = |a|^2 mod |m|. It returns one on success and zero
* on error. */
OPENSSL_EXPORT int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m,
BN_CTX *ctx);
@@ -694,6 +713,14 @@ OPENSSL_EXPORT int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
OPENSSL_EXPORT BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a,
const BIGNUM *n, BN_CTX *ctx);
+/* BN_mod_inverse_ex acts like |BN_mod_inverse| except that, when it returns
+ * zero, it will set |*out_no_inverse| to one if the failure was caused because
+ * |a| has no inverse mod |n|. Otherwise it will set |*out_no_inverse| to
+ * zero. */
+OPENSSL_EXPORT BIGNUM *BN_mod_inverse_ex(BIGNUM *out, int *out_no_inverse,
+ const BIGNUM *a, const BIGNUM *n,
+ BN_CTX *ctx);
+
/* BN_kronecker returns the Kronecker symbol of |a| and |b| (which is -1, 0 or
* 1), or -2 on error. */
OPENSSL_EXPORT int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
@@ -707,17 +734,13 @@ OPENSSL_EXPORT int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
/* BN_MONT_CTX_new returns a fresh BN_MONT_CTX or NULL on allocation failure. */
OPENSSL_EXPORT BN_MONT_CTX *BN_MONT_CTX_new(void);
-/* BN_MONT_CTX_init initialises a stack allocated |BN_MONT_CTX|. */
-OPENSSL_EXPORT void BN_MONT_CTX_init(BN_MONT_CTX *mont);
-
-/* BN_MONT_CTX_free frees the contexts of |mont| and, if it was originally
- * allocated with |BN_MONT_CTX_new|, |mont| itself. */
+/* BN_MONT_CTX_free frees memory associated with |mont|. */
OPENSSL_EXPORT void BN_MONT_CTX_free(BN_MONT_CTX *mont);
/* BN_MONT_CTX_copy sets |to| equal to |from|. It returns |to| on success or
* NULL on error. */
OPENSSL_EXPORT BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to,
- BN_MONT_CTX *from);
+ const BN_MONT_CTX *from);
/* BN_MONT_CTX_set sets up a Montgomery context given the modulus, |mod|. It
* returns one on success and zero on error. */
@@ -767,19 +790,39 @@ OPENSSL_EXPORT int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
OPENSSL_EXPORT int BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx,
- BN_MONT_CTX *m_ctx);
+ const BN_MONT_CTX *mont);
OPENSSL_EXPORT int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a,
const BIGNUM *p, const BIGNUM *m,
- BN_CTX *ctx, BN_MONT_CTX *in_mont);
+ BN_CTX *ctx,
+ const BN_MONT_CTX *mont);
OPENSSL_EXPORT int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx,
- BN_MONT_CTX *m_ctx);
+ const BN_MONT_CTX *mont);
OPENSSL_EXPORT int BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1,
const BIGNUM *p1, const BIGNUM *a2,
const BIGNUM *p2, const BIGNUM *m,
- BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+ BN_CTX *ctx, const BN_MONT_CTX *mont);
+
+
+/* Deprecated functions */
+
+/* BN_bn2mpi serialises the value of |in| to |out|, using a format that consists
+ * of the number's length in bytes represented as a 4-byte big-endian number,
+ * and the number itself in big-endian format, where the most significant bit
+ * signals a negative number. (The representation of numbers with the MSB set is
+ * prefixed with null byte). |out| must have sufficient space available; to
+ * find the needed amount of space, call the function with |out| set to NULL. */
+OPENSSL_EXPORT size_t BN_bn2mpi(const BIGNUM *in, uint8_t *out);
+
+/* BN_mpi2bn parses |len| bytes from |in| and returns the resulting value. The
+ * bytes at |in| are expected to be in the format emitted by |BN_bn2mpi|.
+ *
+ * If |out| is NULL then a fresh |BIGNUM| is allocated and returned, otherwise
+ * |out| is reused and returned. On error, NULL is returned and the error queue
+ * is updated. */
+OPENSSL_EXPORT BIGNUM *BN_mpi2bn(const uint8_t *in, size_t len, BIGNUM *out);
/* Private functions */
@@ -796,12 +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 flags;
- 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);
@@ -827,33 +865,6 @@ OPENSSL_EXPORT BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn);
} /* extern C */
#endif
-#define BN_F_BN_CTX_get 100
-#define BN_F_BN_CTX_new 101
-#define BN_F_BN_CTX_start 102
-#define BN_F_BN_bn2dec 103
-#define BN_F_BN_bn2hex 104
-#define BN_F_BN_div 105
-#define BN_F_BN_div_recp 106
-#define BN_F_BN_exp 107
-#define BN_F_BN_generate_dsa_nonce 108
-#define BN_F_BN_generate_prime_ex 109
-#define BN_F_BN_mod_exp2_mont 110
-#define BN_F_BN_mod_exp_mont 111
-#define BN_F_BN_mod_exp_mont_consttime 112
-#define BN_F_BN_mod_exp_mont_word 113
-#define BN_F_BN_mod_inverse 114
-#define BN_F_BN_mod_inverse_no_branch 115
-#define BN_F_BN_mod_lshift_quick 116
-#define BN_F_BN_mod_sqrt 117
-#define BN_F_BN_new 118
-#define BN_F_BN_rand 119
-#define BN_F_BN_rand_range 120
-#define BN_F_BN_sqrt 121
-#define BN_F_BN_usub 122
-#define BN_F_bn_wexpand 123
-#define BN_F_mod_exp_recp 124
-#define BN_F_BN_lshift 125
-#define BN_F_BN_rshift 126
#define BN_R_ARG2_LT_ARG3 100
#define BN_R_BAD_RECIPROCAL 101
#define BN_R_BIGNUM_TOO_LONG 102
@@ -871,5 +882,7 @@ OPENSSL_EXPORT BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn);
#define BN_R_P_IS_NOT_PRIME 114
#define BN_R_TOO_MANY_ITERATIONS 115
#define BN_R_TOO_MANY_TEMPORARY_VARIABLES 116
+#define BN_R_BAD_ENCODING 117
+#define BN_R_ENCODE_ERROR 118
#endif /* OPENSSL_HEADER_BN_H */
diff --git a/src/include/openssl/buf.h b/src/include/openssl/buf.h
index 2b36ce4..76e3795 100644
--- a/src/include/openssl/buf.h
+++ b/src/include/openssl/buf.h
@@ -115,9 +115,4 @@ OPENSSL_EXPORT size_t BUF_strlcat(char *dst, const char *src, size_t size);
} /* extern C */
#endif
-#define BUF_F_BUF_MEM_new 100
-#define BUF_F_BUF_memdup 101
-#define BUF_F_BUF_strndup 102
-#define BUF_F_buf_mem_grow 103
-
#endif /* OPENSSL_HEADER_BUFFER_H */
diff --git a/src/include/openssl/bytestring.h b/src/include/openssl/bytestring.h
index 9963426..9193e11 100644
--- a/src/include/openssl/bytestring.h
+++ b/src/include/openssl/bytestring.h
@@ -99,6 +99,10 @@ OPENSSL_EXPORT int CBS_get_u32(CBS *cbs, uint32_t *out);
* |cbs|. It returns one on success and zero on error. */
OPENSSL_EXPORT int CBS_get_bytes(CBS *cbs, CBS *out, size_t len);
+/* CBS_copy_bytes copies the next |len| bytes from |cbs| to |out| and advances
+ * |cbs|. It returns one on success and zero on error. */
+OPENSSL_EXPORT int CBS_copy_bytes(CBS *cbs, uint8_t *out, size_t len);
+
/* CBS_get_u8_length_prefixed sets |*out| to the contents of an 8-bit,
* length-prefixed value from |cbs| and advances |cbs| over it. It returns one
* on success and zero on error. */
@@ -121,10 +125,12 @@ OPENSSL_EXPORT int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out);
#define CBS_ASN1_INTEGER 0x2
#define CBS_ASN1_BITSTRING 0x3
#define CBS_ASN1_OCTETSTRING 0x4
+#define CBS_ASN1_NULL 0x5
#define CBS_ASN1_OBJECT 0x6
#define CBS_ASN1_ENUMERATED 0xa
#define CBS_ASN1_SEQUENCE (0x10 | CBS_ASN1_CONSTRUCTED)
#define CBS_ASN1_SET (0x11 | CBS_ASN1_CONSTRUCTED)
+#define CBS_ASN1_GENERALIZEDTIME 0x18
#define CBS_ASN1_CONSTRUCTED 0x20
#define CBS_ASN1_CONTEXT_SPECIFIC 0x80
@@ -158,16 +164,24 @@ OPENSSL_EXPORT int CBS_get_any_asn1_element(CBS *cbs, CBS *out,
unsigned *out_tag,
size_t *out_header_len);
+/* CBS_get_any_ber_asn1_element acts the same as |CBS_get_any_asn1_element| but
+ * also allows indefinite-length elements to be returned. In that case,
+ * |*out_header_len| and |CBS_len(out)| will both be two as only the header is
+ * returned, otherwise it behaves the same as the previous function. */
+OPENSSL_EXPORT int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out,
+ unsigned *out_tag,
+ size_t *out_header_len);
+
/* CBS_get_asn1_uint64 gets an ASN.1 INTEGER from |cbs| using |CBS_get_asn1|
* and sets |*out| to its value. It returns one on success and zero on error,
* where error includes the integer being negative, or too large to represent
* in 64 bits. */
OPENSSL_EXPORT int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out);
-/* CBS_get_optional_asn1 gets an optional explicitly-tagged element
- * from |cbs| tagged with |tag| and sets |*out| to its contents. If
- * present, it sets |*out_present| to one, otherwise zero. It returns
- * one on success, whether or not the element was present, and zero on
+/* CBS_get_optional_asn1 gets an optional explicitly-tagged element from |cbs|
+ * tagged with |tag| and sets |*out| to its contents. If present and if
+ * |out_present| is not NULL, it sets |*out_present| to one, otherwise zero. It
+ * returns one on success, whether or not the element was present, and zero on
* decode failure. */
OPENSSL_EXPORT int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present,
unsigned tag);
@@ -224,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. */
- struct cbb_st *child;
- /* pending_len_len contains the number of bytes in a pending length-prefix,
- * or zero if no length-prefix is pending. */
+ CBB *child;
+ /* 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
@@ -238,6 +252,12 @@ struct cbb_st {
char is_top_level;
};
+/* CBB_zero sets an uninitialised |cbb| to the zero state. It must be
+ * initialised with |CBB_init| or |CBB_init_fixed| before use, but it is safe to
+ * call |CBB_cleanup| without a successful |CBB_init|. This may be used for more
+ * uniform cleanup of a |CBB|. */
+OPENSSL_EXPORT void CBB_zero(CBB *cbb);
+
/* CBB_init initialises |cbb| with |initial_capacity|. Since a |CBB| grows as
* needed, the |initial_capacity| is just a hint. It returns one on success or
* zero on error. */
@@ -250,7 +270,11 @@ OPENSSL_EXPORT int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len);
/* CBB_cleanup frees all resources owned by |cbb| and other |CBB| objects
* writing to the same buffer. This should be used in an error case where a
- * serialisation is abandoned. */
+ * serialisation is abandoned.
+ *
+ * This function can only be called on a "top level" |CBB|, i.e. one initialised
+ * with |CBB_init| or |CBB_init_fixed|, or a |CBB| set to the zero state with
+ * |CBB_zero|. */
OPENSSL_EXPORT void CBB_cleanup(CBB *cbb);
/* CBB_finish completes any pending length prefix and sets |*out_data| to a
@@ -268,6 +292,20 @@ 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_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|.
+ *
+ * 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
* data written to |*out_contents| will be prefixed in |cbb| with an 8-bit
* length. It returns one on success or zero on error. */
@@ -283,7 +321,7 @@ OPENSSL_EXPORT int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents);
* big-endian length. It returns one on success or zero on error. */
OPENSSL_EXPORT int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents);
-/* CBB_add_asn sets |*out_contents| to a |CBB| into which the contents of an
+/* CBB_add_asn1 sets |*out_contents| to a |CBB| into which the contents of an
* ASN.1 object can be written. The |tag| argument will be used as the tag for
* the object. Passing in |tag| number 31 will return in an error since only
* single octet identifiers are supported. It returns one on success or zero
@@ -300,11 +338,22 @@ 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);
-/* CBB_add_u8 appends a 16-bit, big-endian number from |value| to |cbb|. It
+/* CBB_add_u16 appends a 16-bit, big-endian number from |value| to |cbb|. It
* returns one on success and zero otherwise. */
OPENSSL_EXPORT int CBB_add_u16(CBB *cbb, uint16_t value);
@@ -312,6 +361,10 @@ OPENSSL_EXPORT int CBB_add_u16(CBB *cbb, uint16_t value);
* returns one on success and zero otherwise. */
OPENSSL_EXPORT int CBB_add_u24(CBB *cbb, uint32_t value);
+/* CBB_discard_child discards the current unflushed child of |cbb|. Neither the
+ * child's contents nor the length prefix will be included in the output. */
+OPENSSL_EXPORT void CBB_discard_child(CBB *cbb);
+
/* CBB_add_asn1_uint64 writes an ASN.1 INTEGER into |cbb| using |CBB_add_asn1|
* and writes |value| in its contents. It returns one on success and zero on
* error. */
diff --git a/src/include/openssl/chacha.h b/src/include/openssl/chacha.h
index ce53d49..64713c2 100644
--- a/src/include/openssl/chacha.h
+++ b/src/include/openssl/chacha.h
@@ -25,9 +25,9 @@ extern "C" {
/* CRYPTO_chacha_20 encrypts |in_len| bytes from |in| with the given key and
* nonce and writes the result to |out|, which may be equal to |in|. The
* initial block counter is specified by |counter|. */
-void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in,
- size_t in_len, const uint8_t key[32],
- const uint8_t nonce[8], size_t counter);
+OPENSSL_EXPORT void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in,
+ size_t in_len, const uint8_t key[32],
+ const uint8_t nonce[12], uint32_t counter);
#if defined(__cplusplus)
diff --git a/src/include/openssl/cipher.h b/src/include/openssl/cipher.h
index 7f5fe04..fb7171f 100644
--- a/src/include/openssl/cipher.h
+++ b/src/include/openssl/cipher.h
@@ -75,6 +75,9 @@ extern "C" {
OPENSSL_EXPORT const EVP_CIPHER *EVP_rc4(void);
OPENSSL_EXPORT const EVP_CIPHER *EVP_des_cbc(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ecb(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ede(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ede_cbc(void);
OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ede3_cbc(void);
OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_ecb(void);
@@ -86,22 +89,15 @@ OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_ecb(void);
OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_cbc(void);
OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_ctr(void);
OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_ofb(void);
-
-/* Deprecated AES-GCM implementations that set |EVP_CIPH_FLAG_CUSTOM_CIPHER|.
- * Use |EVP_aead_aes_128_gcm| and |EVP_aead_aes_256_gcm| instead. */
-OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_gcm(void);
-OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_gcm(void);
-
-/* Deprecated 192-bit version of AES. */
-OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_ecb(void);
-OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_cbc(void);
-OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_ctr(void);
-OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_gcm(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_xts(void);
/* EVP_enc_null returns a 'cipher' that passes plaintext through as
* ciphertext. */
OPENSSL_EXPORT const EVP_CIPHER *EVP_enc_null(void);
+/* EVP_rc2_cbc returns a cipher that implements 128-bit RC2 in CBC mode. */
+OPENSSL_EXPORT const EVP_CIPHER *EVP_rc2_cbc(void);
+
/* EVP_rc2_40_cbc returns a cipher that implements 40-bit RC2 in CBC mode. This
* is obviously very, very weak and is included only in order to read PKCS#12
* files, which often encrypt the certificate chain using this cipher. It is
@@ -338,6 +334,7 @@ OPENSSL_EXPORT int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
#define EVP_CIPH_OFB_MODE 0x4
#define EVP_CIPH_CTR_MODE 0x5
#define EVP_CIPH_GCM_MODE 0x6
+#define EVP_CIPH_XTS_MODE 0x7
/* Cipher flags (for |EVP_CIPHER_flags|). */
@@ -399,6 +396,18 @@ OPENSSL_EXPORT int EVP_add_cipher_alias(const char *a, const char *b);
* |name|, or NULL if the name is unknown. */
OPENSSL_EXPORT const EVP_CIPHER *EVP_get_cipherbyname(const char *name);
+/* These AEADs are deprecated AES-GCM implementations that set
+ * |EVP_CIPH_FLAG_CUSTOM_CIPHER|. Use |EVP_aead_aes_128_gcm| and
+ * |EVP_aead_aes_256_gcm| instead. */
+OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_gcm(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_gcm(void);
+
+/* These are deprecated, 192-bit version of AES. */
+OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_ecb(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_cbc(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_ctr(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_gcm(void);
+
/* Private functions. */
@@ -533,41 +542,6 @@ struct evp_cipher_st {
} /* extern C */
#endif
-#define CIPHER_F_EVP_AEAD_CTX_init 100
-#define CIPHER_F_EVP_AEAD_CTX_open 101
-#define CIPHER_F_EVP_AEAD_CTX_seal 102
-#define CIPHER_F_EVP_CIPHER_CTX_copy 103
-#define CIPHER_F_EVP_CIPHER_CTX_ctrl 104
-#define CIPHER_F_EVP_CIPHER_CTX_set_key_length 105
-#define CIPHER_F_EVP_CipherInit_ex 106
-#define CIPHER_F_EVP_DecryptFinal_ex 107
-#define CIPHER_F_EVP_EncryptFinal_ex 108
-#define CIPHER_F_aead_aes_gcm_init 109
-#define CIPHER_F_aead_aes_gcm_open 110
-#define CIPHER_F_aead_aes_gcm_seal 111
-#define CIPHER_F_aead_aes_key_wrap_init 112
-#define CIPHER_F_aead_aes_key_wrap_open 113
-#define CIPHER_F_aead_aes_key_wrap_seal 114
-#define CIPHER_F_aead_chacha20_poly1305_init 115
-#define CIPHER_F_aead_chacha20_poly1305_open 116
-#define CIPHER_F_aead_chacha20_poly1305_seal 117
-#define CIPHER_F_aead_rc4_md5_tls_init 118
-#define CIPHER_F_aead_rc4_md5_tls_open 119
-#define CIPHER_F_aead_rc4_md5_tls_seal 120
-#define CIPHER_F_aead_ssl3_ensure_cipher_init 121
-#define CIPHER_F_aead_ssl3_init 122
-#define CIPHER_F_aead_ssl3_open 123
-#define CIPHER_F_aead_ssl3_seal 124
-#define CIPHER_F_aead_tls_ensure_cipher_init 125
-#define CIPHER_F_aead_tls_init 126
-#define CIPHER_F_aead_tls_open 127
-#define CIPHER_F_aead_tls_seal 128
-#define CIPHER_F_aes_init_key 129
-#define CIPHER_F_aesni_init_key 130
-#define CIPHER_F_EVP_AEAD_CTX_init_with_direction 131
-#define CIPHER_F_aead_aes_ctr_hmac_sha256_init 132
-#define CIPHER_F_aead_aes_ctr_hmac_sha256_open 133
-#define CIPHER_F_aead_aes_ctr_hmac_sha256_seal 134
#define CIPHER_R_AES_KEY_SETUP_FAILED 100
#define CIPHER_R_BAD_DECRYPT 101
#define CIPHER_R_BAD_KEY_LENGTH 102
diff --git a/src/include/openssl/cmac.h b/src/include/openssl/cmac.h
index 183f41b..0bb44b9 100644
--- a/src/include/openssl/cmac.h
+++ b/src/include/openssl/cmac.h
@@ -73,4 +73,4 @@ OPENSSL_EXPORT int CMAC_Final(CMAC_CTX *ctx, uint8_t *out, size_t *out_len);
} /* extern C */
#endif
-#endif /* OPENSSL_HEADER_CBC_H */
+#endif /* OPENSSL_HEADER_CMAC_H */
diff --git a/src/include/openssl/conf.h b/src/include/openssl/conf.h
index 84fc94f..a2741a8 100644
--- a/src/include/openssl/conf.h
+++ b/src/include/openssl/conf.h
@@ -135,10 +135,6 @@ int CONF_parse_list(const char *list, char sep, int remove_whitespace,
} /* extern C */
#endif
-#define CONF_F_CONF_parse_list 100
-#define CONF_F_NCONF_load 101
-#define CONF_F_def_load_bio 102
-#define CONF_F_str_copy 103
#define CONF_R_LIST_CANNOT_BE_NULL 100
#define CONF_R_MISSING_CLOSE_SQUARE_BRACKET 101
#define CONF_R_MISSING_EQUAL_SIGN 102
diff --git a/src/include/openssl/cpu.h b/src/include/openssl/cpu.h
index 83ec473..e946304 100644
--- a/src/include/openssl/cpu.h
+++ b/src/include/openssl/cpu.h
@@ -77,11 +77,16 @@ extern "C" {
*
* Index 0:
* EDX for CPUID where EAX = 1
+ * Bit 20 is always zero
+ * Bit 28 is adjusted to reflect whether the data cache is shared between
+ * multiple logical cores
* Bit 30 is used to indicate an Intel CPU
* Index 1:
* ECX for CPUID where EAX = 1
+ * Bit 11 is used to indicate AMD XOP support, not SDBG
* Index 2:
* EBX for CPUID where EAX = 7
+ * Index 3 is set to zero.
*
* Note: the CPUID bits are pre-adjusted for the OSXSAVE bit and the YMM and XMM
* bits in XCR0, so it is not necessary to check those. */
@@ -89,10 +94,28 @@ extern uint32_t OPENSSL_ia32cap_P[4];
#endif
#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
-/* 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);
+
+#if defined(OPENSSL_APPLE)
+/* iOS builds use the static ARM configuration. */
+#define OPENSSL_STATIC_ARMCAP
+#endif
+
+#if !defined(OPENSSL_STATIC_ARMCAP)
+
+/* 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
@@ -111,6 +134,46 @@ OPENSSL_EXPORT char CRYPTO_is_NEON_functional(void);
* compiled with |-mfpu=neon| or if |CRYPTO_set_NEON_capable| has been called
* with a non-zero argument. */
OPENSSL_EXPORT void CRYPTO_set_NEON_functional(char neon_functional);
+
+/* CRYPTO_is_ARMv8_AES_capable returns true if the current CPU supports the
+ * ARMv8 AES instruction. */
+int CRYPTO_is_ARMv8_AES_capable(void);
+
+/* CRYPTO_is_ARMv8_PMULL_capable returns true if the current CPU supports the
+ * ARMv8 PMULL instruction. */
+int CRYPTO_is_ARMv8_PMULL_capable(void);
+
+#else
+
+static inline int CRYPTO_is_NEON_capable(void) {
+#if defined(OPENSSL_STATIC_ARMCAP_NEON) || defined(__ARM_NEON__)
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+static inline int CRYPTO_is_NEON_functional(void) {
+ return CRYPTO_is_NEON_capable();
+}
+
+static inline int CRYPTO_is_ARMv8_AES_capable(void) {
+#if defined(OPENSSL_STATIC_ARMCAP_AES)
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+static inline int CRYPTO_is_ARMv8_PMULL_capable(void) {
+#if defined(OPENSSL_STATIC_ARMCAP_PMULL)
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+#endif /* OPENSSL_STATIC_ARMCAP */
#endif /* OPENSSL_ARM */
diff --git a/src/include/openssl/crypto.h b/src/include/openssl/crypto.h
index 3af1547..b421884 100644
--- a/src/include/openssl/crypto.h
+++ b/src/include/openssl/crypto.h
@@ -21,6 +21,10 @@
* mem.h. */
#include <openssl/mem.h>
+/* Upstream OpenSSL defines |CRYPTO_LOCK|, etc., in crypto.h rather than
+ * thread.h. */
+#include <openssl/thread.h>
+
#if defined(__cplusplus)
extern "C" {
@@ -50,14 +54,15 @@ OPENSSL_EXPORT const char *SSLeay_version(int unused);
* base.h. */
OPENSSL_EXPORT unsigned long SSLeay(void);
+/* CRYPTO_malloc_init returns one. */
+OPENSSL_EXPORT int CRYPTO_malloc_init(void);
+
+/* ENGINE_load_builtin_engines does nothing. */
+OPENSSL_EXPORT void ENGINE_load_builtin_engines(void);
+
#if defined(__cplusplus)
} /* extern C */
#endif
-#define CRYPTO_F_CRYPTO_get_ex_new_index 100
-#define CRYPTO_F_CRYPTO_set_ex_data 101
-#define CRYPTO_F_get_class 102
-#define CRYPTO_F_get_func_pointers 103
-
#endif /* OPENSSL_HEADER_CRYPTO_H */
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/des.h b/src/include/openssl/des.h
index 6e1b0cf..2b8dd0f 100644
--- a/src/include/openssl/des.h
+++ b/src/include/openssl/des.h
@@ -72,12 +72,7 @@ typedef struct DES_cblock_st {
} DES_cblock;
typedef struct DES_ks {
- union {
- DES_cblock cblock;
- /* make sure things are correct size on machines with
- * 8 byte longs */
- uint32_t deslong[2];
- } ks[16];
+ uint32_t subkeys[16][2];
} DES_key_schedule;
@@ -142,6 +137,39 @@ OPENSSL_EXPORT void DES_ede2_cbc_encrypt(const uint8_t *in, uint8_t *out,
DES_cblock *ivec, int enc);
+/* Deprecated functions. */
+
+/* DES_set_key_unchecked calls |DES_set_key|. */
+OPENSSL_EXPORT void DES_set_key_unchecked(const DES_cblock *key,
+ DES_key_schedule *schedule);
+
+OPENSSL_EXPORT void DES_ede3_cfb64_encrypt(const uint8_t *in, uint8_t *out,
+ long length, DES_key_schedule *ks1,
+ DES_key_schedule *ks2,
+ DES_key_schedule *ks3,
+ DES_cblock *ivec, int *num, int enc);
+
+OPENSSL_EXPORT void DES_ede3_cfb_encrypt(const uint8_t *in, uint8_t *out,
+ int numbits, long length,
+ DES_key_schedule *ks1,
+ DES_key_schedule *ks2,
+ DES_key_schedule *ks3,
+ DES_cblock *ivec, int enc);
+
+
+/* Private functions.
+ *
+ * These functions are only exported for use in |decrepit|. */
+
+OPENSSL_EXPORT void DES_decrypt3(uint32_t *data, const DES_key_schedule *ks1,
+ const DES_key_schedule *ks2,
+ const DES_key_schedule *ks3);
+
+OPENSSL_EXPORT void DES_encrypt3(uint32_t *data, const DES_key_schedule *ks1,
+ const DES_key_schedule *ks2,
+ const DES_key_schedule *ks3);
+
+
#if defined(__cplusplus)
} /* extern C */
#endif
diff --git a/src/include/openssl/dh.h b/src/include/openssl/dh.h
index 17574d5..2c49fc8 100644
--- a/src/include/openssl/dh.h
+++ b/src/include/openssl/dh.h
@@ -77,9 +77,6 @@ extern "C" {
/* DH_new returns a new, empty DH object or NULL on error. */
OPENSSL_EXPORT DH *DH_new(void);
-/* DH_new_method acts the same as |DH_new| but takes an explicit |ENGINE|. */
-OPENSSL_EXPORT DH *DH_new_method(const ENGINE *engine);
-
/* DH_free decrements the reference count of |dh| and frees it if the reference
* count drops to zero. */
OPENSSL_EXPORT void DH_free(DH *dh);
@@ -90,9 +87,8 @@ OPENSSL_EXPORT int DH_up_ref(DH *dh);
/* Standard parameters.
*
- * These functions return new DH objects with standard parameters configured
- * that use the given ENGINE, which may be NULL. They return NULL on allocation
- * failure. */
+ * These functions return new DH objects with standard parameters. They return
+ * NULL on allocation failure. The |engine| parameter is ignored. */
/* These parameters are taken from RFC 5114. */
@@ -197,45 +193,17 @@ 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);
OPENSSL_EXPORT void *DH_get_ex_data(DH *d, int idx);
-/* dh_method contains function pointers to override the implementation of DH.
- * See |engine.h| for details. */
-struct dh_method {
- struct openssl_method_common_st common;
-
- /* app_data is an opaque pointer for the method to use. */
- void *app_data;
-
- /* init is called just before the return of |DH_new_method|. It returns one
- * on success or zero on error. */
- int (*init)(DH *dh);
-
- /* finish is called before |dh| is destructed. */
- void (*finish)(DH *dh);
-
- /* generate_parameters is called by |DH_generate_parameters_ex|. */
- int (*generate_parameters)(DH *dh, int prime_bits, int generator,
- BN_GENCB *cb);
-
- /* generate_parameters is called by |DH_generate_key|. */
- int (*generate_key)(DH *dh);
-
- /* compute_key is called by |DH_compute_key|. */
- int (*compute_key)(DH *dh, uint8_t *out, const BIGNUM *pub_key);
-};
-
struct dh_st {
- DH_METHOD *meth;
-
BIGNUM *p;
BIGNUM *g;
- BIGNUM *pub_key; /* g^x */
+ BIGNUM *pub_key; /* g^x mod p */
BIGNUM *priv_key; /* x */
/* priv_length contains the length, in bits, of the private value. If zero,
@@ -262,10 +230,6 @@ struct dh_st {
} /* extern C */
#endif
-#define DH_F_DH_new_method 100
-#define DH_F_compute_key 101
-#define DH_F_generate_key 102
-#define DH_F_generate_parameters 103
#define DH_R_BAD_GENERATOR 100
#define DH_R_INVALID_PUBKEY 101
#define DH_R_MODULUS_TOO_LARGE 102
diff --git a/src/include/openssl/digest.h b/src/include/openssl/digest.h
index 2ea4ec4..80028ef 100644
--- a/src/include/openssl/digest.h
+++ b/src/include/openssl/digest.h
@@ -138,8 +138,9 @@ OPENSSL_EXPORT int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
OPENSSL_EXPORT int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data,
size_t len);
-/* EVP_MAX_MD_SIZE is the largest digest size supported. Functions that output
- * a digest generally require the buffer have at least this much space. */
+/* EVP_MAX_MD_SIZE is the largest digest size supported, in bytes.
+ * Functions that output a digest generally require the buffer have
+ * at least this much space. */
#define EVP_MAX_MD_SIZE 64 /* SHA-512 is the longest so far. */
/* EVP_DigestFinal_ex finishes the digest in |ctx| and writes the output to
@@ -180,7 +181,7 @@ OPENSSL_EXPORT uint32_t EVP_MD_flags(const EVP_MD *md);
/* EVP_MD_size returns the digest size of |md|, in bytes. */
OPENSSL_EXPORT size_t EVP_MD_size(const EVP_MD *md);
-/* EVP_MD_block_size returns the native block-size of |md|. */
+/* EVP_MD_block_size returns the native block-size of |md|, in bytes. */
OPENSSL_EXPORT size_t EVP_MD_block_size(const EVP_MD *md);
/* EVP_MD_FLAG_PKEY_DIGEST indicates the the digest function is used with a
@@ -204,7 +205,7 @@ OPENSSL_EXPORT int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in);
* compatibility with OpenSSL. */
OPENSSL_EXPORT int EVP_add_digest(const EVP_MD *digest);
-/* EVP_get_cipherbyname returns an |EVP_MD| given a human readable name in
+/* EVP_get_digestbyname returns an |EVP_MD| given a human readable name in
* |name|, or NULL if the name is unknown. */
OPENSSL_EXPORT const EVP_MD *EVP_get_digestbyname(const char *);
@@ -215,12 +216,12 @@ OPENSSL_EXPORT const EVP_MD *EVP_get_digestbyname(const char *);
* been set. */
OPENSSL_EXPORT const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx);
-/* EVP_MD_CTX_size returns the digest size of |ctx|. It will crash if a digest
- * hasn't been set on |ctx|. */
+/* EVP_MD_CTX_size returns the digest size of |ctx|, in bytes. It
+ * will crash if a digest hasn't been set on |ctx|. */
OPENSSL_EXPORT unsigned EVP_MD_CTX_size(const EVP_MD_CTX *ctx);
/* EVP_MD_CTX_block_size returns the block size of the digest function used by
- * |ctx|. It will crash if a digest hasn't been set on |ctx|. */
+ * |ctx|, in bytes. It will crash if a digest hasn't been set on |ctx|. */
OPENSSL_EXPORT unsigned EVP_MD_CTX_block_size(const EVP_MD_CTX *ctx);
/* EVP_MD_CTX_type returns a NID describing the digest function used by |ctx|.
@@ -234,15 +235,9 @@ struct evp_md_pctx_ops;
struct env_md_ctx_st {
/* digest is the underlying digest function, or NULL if not set. */
const EVP_MD *digest;
- /* flags is the OR of a number of |EVP_MD_CTX_FLAG_*| values. */
- uint32_t flags;
/* md_data points to a block of memory that contains the hash-specific
* context. */
void *md_data;
- /* update is usually copied from |digest->update| but can differ in some
- * cases, i.e. HMAC.
- * TODO(davidben): Remove this hook once |EVP_PKEY_HMAC| is gone. */
- void (*update)(EVP_MD_CTX *ctx, const void *data, size_t count);
/* pctx is an opaque (at this layer) pointer to additional context that
* EVP_PKEY functions may store in this object. */
@@ -258,8 +253,6 @@ struct env_md_ctx_st {
} /* extern C */
#endif
-#define DIGEST_F_EVP_DigestInit_ex 100
-#define DIGEST_F_EVP_MD_CTX_copy_ex 101
#define DIGEST_R_INPUT_NOT_INITIALIZED 100
#endif /* OPENSSL_HEADER_DIGEST_H */
diff --git a/src/include/openssl/dsa.h b/src/include/openssl/dsa.h
index 7274e4c..2045fe7 100644
--- a/src/include/openssl/dsa.h
+++ b/src/include/openssl/dsa.h
@@ -80,9 +80,6 @@ extern "C" {
/* DSA_new returns a new, empty DSA object or NULL on error. */
OPENSSL_EXPORT DSA *DSA_new(void);
-/* DSA_new_method acts the same as |DH_new| but takes an explicit |ENGINE|. */
-OPENSSL_EXPORT DSA *DSA_new_method(const ENGINE *engine);
-
/* DSA_free decrements the reference count of |dsa| and frees it if the
* reference count drops to zero. */
OPENSSL_EXPORT void DSA_free(DSA *dsa);
@@ -305,38 +302,13 @@ 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);
OPENSSL_EXPORT void *DSA_get_ex_data(const DSA *d, int idx);
-struct dsa_method {
- struct openssl_method_common_st common;
-
- void *app_data;
-
- int (*init)(DSA *dsa);
- int (*finish)(DSA *dsa);
-
- DSA_SIG *(*sign)(const uint8_t *digest, size_t digest_len, DSA *dsa);
-
- int (*sign_setup)(const DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp,
- const uint8_t *digest, size_t digest_len);
-
- int (*verify)(int *out_valid, const uint8_t *digest, size_t digest_len,
- DSA_SIG *sig, const DSA *dsa);
-
- /* generate_parameters, if non-NULL, is used to generate DSA parameters. */
- int (*generate_parameters)(DSA *dsa, unsigned bits, const uint8_t *seed,
- size_t seed_len, int *counter_ret,
- unsigned long *h_ret, BN_GENCB *cb);
-
- /* keygen, if non-NULL, is used to generate DSA keys. */
- int (*keygen)(DSA *dsa);
-};
-
struct dsa_st {
long version;
int write_params;
@@ -356,9 +328,6 @@ struct dsa_st {
BN_MONT_CTX *method_mont_p;
CRYPTO_refcount_t references;
CRYPTO_EX_DATA ex_data;
- DSA_METHOD *meth;
- /* functional reference if 'meth' is ENGINE-provided */
- ENGINE *engine;
};
@@ -366,11 +335,6 @@ struct dsa_st {
} /* extern C */
#endif
-#define DSA_F_DSA_new_method 100
-#define DSA_F_dsa_sig_cb 101
-#define DSA_F_sign 102
-#define DSA_F_sign_setup 103
-#define DSA_F_verify 104
#define DSA_R_BAD_Q_VALUE 100
#define DSA_R_MISSING_PARAMETERS 101
#define DSA_R_MODULUS_TOO_LARGE 102
diff --git a/src/include/openssl/ec.h b/src/include/openssl/ec.h
index 25b4551..667be3b 100644
--- a/src/include/openssl/ec.h
+++ b/src/include/openssl/ec.h
@@ -87,7 +87,7 @@ typedef enum {
/** the point is encoded as z||x, where the octet z specifies
* which solution of the quadratic equation y is */
POINT_CONVERSION_COMPRESSED = 2,
- /** the point is encoded as z||x||y, where z is the octet 0x02 */
+ /** the point is encoded as z||x||y, where z is the octet 0x04 */
POINT_CONVERSION_UNCOMPRESSED = 4
} point_conversion_form_t;
@@ -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. */
@@ -144,16 +143,7 @@ OPENSSL_EXPORT int EC_GROUP_get_curve_name(const EC_GROUP *group);
/* EC_GROUP_get_degree returns the number of bits needed to represent an
* element of the field underlying |group|. */
-OPENSSL_EXPORT int 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);
+OPENSSL_EXPORT unsigned EC_GROUP_get_degree(const EC_GROUP *group);
/* Points on elliptic curves. */
@@ -220,8 +210,10 @@ OPENSSL_EXPORT int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
BIGNUM *x, BIGNUM *y,
BN_CTX *ctx);
-/* EC_POINT_set_affine_coordinates sets the value of |p| to be (|x|, |y|). The
- * |ctx| argument may be used if not NULL. */
+/* EC_POINT_set_affine_coordinates_GFp sets the value of |p| to be (|x|, |y|).
+ * The |ctx| argument may be used if not NULL. It returns one on success or
+ * zero on error. Note that, unlike with OpenSSL, it's considered an error if
+ * the point is not on the curve. */
OPENSSL_EXPORT int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group,
EC_POINT *point,
const BIGNUM *x,
@@ -265,7 +257,7 @@ OPENSSL_EXPORT int EC_POINT_add(const EC_GROUP *group, EC_POINT *r,
OPENSSL_EXPORT int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r,
const EC_POINT *a, BN_CTX *ctx);
-/* EC_POINT_dbl sets |a| equal to minus |a|. It returns one on success and zero
+/* EC_POINT_invert sets |a| equal to minus |a|. It returns one on success and zero
* otherwise. If |ctx| is not NULL, it may be used. */
OPENSSL_EXPORT int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a,
BN_CTX *ctx);
@@ -276,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. */
@@ -297,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|. */
@@ -325,82 +316,13 @@ OPENSSL_EXPORT void EC_GROUP_set_point_conversion_form(
/* Old code expects to get EC_KEY from ec.h. */
-#if !defined(OPENSSL_HEADER_EC_KEY_H)
#include <openssl/ec_key.h>
-#endif
#if defined(__cplusplus)
} /* extern C */
#endif
-#define EC_F_EC_GROUP_copy 100
-#define EC_F_EC_GROUP_get_curve_GFp 101
-#define EC_F_EC_GROUP_get_degree 102
-#define EC_F_EC_GROUP_new_by_curve_name 103
-#define EC_F_EC_KEY_check_key 104
-#define EC_F_EC_KEY_copy 105
-#define EC_F_EC_KEY_generate_key 106
-#define EC_F_EC_KEY_new_method 107
-#define EC_F_EC_KEY_set_public_key_affine_coordinates 108
-#define EC_F_EC_POINT_add 109
-#define EC_F_EC_POINT_cmp 110
-#define EC_F_EC_POINT_copy 111
-#define EC_F_EC_POINT_dbl 112
-#define EC_F_EC_POINT_dup 113
-#define EC_F_EC_POINT_get_affine_coordinates_GFp 114
-#define EC_F_EC_POINT_invert 115
-#define EC_F_EC_POINT_is_at_infinity 116
-#define EC_F_EC_POINT_is_on_curve 117
-#define EC_F_EC_POINT_make_affine 118
-#define EC_F_EC_POINT_new 119
-#define EC_F_EC_POINT_oct2point 120
-#define EC_F_EC_POINT_point2oct 121
-#define EC_F_EC_POINT_set_affine_coordinates_GFp 122
-#define EC_F_EC_POINT_set_compressed_coordinates_GFp 123
-#define EC_F_EC_POINT_set_to_infinity 124
-#define EC_F_EC_POINTs_make_affine 125
-#define EC_F_compute_wNAF 126
-#define EC_F_d2i_ECPKParameters 127
-#define EC_F_d2i_ECParameters 128
-#define EC_F_d2i_ECPrivateKey 129
-#define EC_F_ec_GFp_mont_field_decode 130
-#define EC_F_ec_GFp_mont_field_encode 131
-#define EC_F_ec_GFp_mont_field_mul 132
-#define EC_F_ec_GFp_mont_field_set_to_one 133
-#define EC_F_ec_GFp_mont_field_sqr 134
-#define EC_F_ec_GFp_mont_group_set_curve 135
-#define EC_F_ec_GFp_simple_group_check_discriminant 136
-#define EC_F_ec_GFp_simple_group_set_curve 137
-#define EC_F_ec_GFp_simple_make_affine 138
-#define EC_F_ec_GFp_simple_oct2point 139
-#define EC_F_ec_GFp_simple_point2oct 140
-#define EC_F_ec_GFp_simple_point_get_affine_coordinates 141
-#define EC_F_ec_GFp_simple_point_set_affine_coordinates 142
-#define EC_F_ec_GFp_simple_points_make_affine 143
-#define EC_F_ec_GFp_simple_set_compressed_coordinates 144
-#define EC_F_ec_asn1_group2pkparameters 145
-#define EC_F_ec_asn1_pkparameters2group 146
-#define EC_F_ec_group_new 147
-#define EC_F_ec_group_new_curve_GFp 148
-#define EC_F_ec_group_new_from_data 149
-#define EC_F_ec_point_set_Jprojective_coordinates_GFp 150
-#define EC_F_ec_pre_comp_new 151
-#define EC_F_ec_wNAF_mul 152
-#define EC_F_ec_wNAF_precompute_mult 153
-#define EC_F_i2d_ECPKParameters 154
-#define EC_F_i2d_ECParameters 155
-#define EC_F_i2d_ECPrivateKey 156
-#define EC_F_i2o_ECPublicKey 157
-#define EC_F_o2i_ECPublicKey 158
-#define EC_F_BN_to_felem 159
-#define EC_F_ec_GFp_nistp256_group_set_curve 160
-#define EC_F_ec_GFp_nistp256_point_get_affine_coordinates 161
-#define EC_F_ec_GFp_nistp256_points_mul 162
-#define EC_F_ec_group_copy 163
-#define EC_F_nistp256_pre_comp_new 164
-#define EC_F_EC_KEY_new_by_curve_name 165
-#define EC_F_EC_GROUP_new_curve_GFp 166
#define EC_R_BUFFER_TOO_SMALL 100
#define EC_R_COORDINATES_OUT_OF_RANGE 101
#define EC_R_D2I_ECPKPARAMETERS_FAILURE 102
diff --git a/src/include/openssl/ec_key.h b/src/include/openssl/ec_key.h
index ee64030..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
@@ -192,7 +186,7 @@ OPENSSL_EXPORT int EC_KEY_generate_key(EC_KEY *key);
OPENSSL_EXPORT EC_KEY *d2i_ECPrivateKey(EC_KEY **out_key, const uint8_t **inp,
long len);
-/* i2d_ECParameters marshals an EC private key from |key| to an ASN.1, DER
+/* i2d_ECPrivateKey marshals an EC private key from |key| to an ASN.1, DER
* structure. If |outp| is not NULL then the result is written to |*outp| and
* |*outp| is advanced just past the output. It returns the number of bytes in
* the result, whether written or not, or a negative value on error. */
@@ -215,8 +209,8 @@ OPENSSL_EXPORT int i2d_ECParameters(const EC_KEY *key, uint8_t **outp);
/* o2i_ECPublicKey parses an EC point from |len| bytes at |*inp| into
* |*out_key|. Note that this differs from the d2i format in that |*out_key|
- * must be non-NULL. On successful exit, |*inp| is advanced past the DER
- * structure. It returns |*out_key| or NULL on error. */
+ * must be non-NULL with a group set. On successful exit, |*inp| is advanced by
+ * |len| bytes. It returns |*out_key| or NULL on error. */
OPENSSL_EXPORT EC_KEY *o2i_ECPublicKey(EC_KEY **out_key, const uint8_t **inp,
long len);
@@ -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/ecdh.h b/src/include/openssl/ecdh.h
index 27a8578..5fe3ae9 100644
--- a/src/include/openssl/ecdh.h
+++ b/src/include/openssl/ecdh.h
@@ -80,14 +80,14 @@ extern "C" {
/* ECDH_compute_key calculates the shared key between |pub_key| and |priv_key|.
- * If |KDF| is not NULL, then it is called with the bytes of the shared key and
- * the parameter |out|. When |KDF| returns, the value of |*outlen| becomes the
+ * If |kdf| is not NULL, then it is called with the bytes of the shared key and
+ * the parameter |out|. When |kdf| returns, the value of |*outlen| becomes the
* return value. Otherwise, as many bytes of the shared key as will fit are
* copied directly to, at most, |outlen| bytes at |out|. It returns the number
* of bytes written to |out|, or -1 on error. */
OPENSSL_EXPORT int ECDH_compute_key(void *out, size_t outlen,
const EC_POINT *pub_key, EC_KEY *priv_key,
- void *(*KDF)(const void *in, size_t inlen,
+ void *(*kdf)(const void *in, size_t inlen,
void *out, size_t *outlen));
@@ -95,7 +95,6 @@ OPENSSL_EXPORT int ECDH_compute_key(void *out, size_t outlen,
} /* extern C */
#endif
-#define ECDH_F_ECDH_compute_key 100
#define ECDH_R_KDF_FAILED 100
#define ECDH_R_NO_PRIVATE_VALUE 101
#define ECDH_R_POINT_ARITHMETIC_FAILURE 102
diff --git a/src/include/openssl/ecdsa.h b/src/include/openssl/ecdsa.h
index e045463..f3f68eb 100644
--- a/src/include/openssl/ecdsa.h
+++ b/src/include/openssl/ecdsa.h
@@ -106,14 +106,14 @@ OPENSSL_EXPORT ECDSA_SIG *ECDSA_SIG_new(void);
/* ECDSA_SIG_free frees |sig| its member |BIGNUM|s. */
OPENSSL_EXPORT void ECDSA_SIG_free(ECDSA_SIG *sig);
-/* ECDSA_sign signs |digest_len| bytes from |digest| with |key| and returns the
- * resulting signature structure, or NULL on error. */
+/* ECDSA_do_sign signs |digest_len| bytes from |digest| with |key| and returns
+ * the resulting signature structure, or NULL on error. */
OPENSSL_EXPORT ECDSA_SIG *ECDSA_do_sign(const uint8_t *digest,
size_t digest_len, EC_KEY *key);
-/* ECDSA_verify verifies that |sig| constitutes a valid signature by |key| of
- * |digest|. It returns one on success or zero if the signature is invalid or
- * on error. */
+/* ECDSA_do_verify verifies that |sig| constitutes a valid signature by |key|
+ * of |digest|. It returns one on success or zero if the signature is invalid
+ * or on error. */
OPENSSL_EXPORT int ECDSA_do_verify(const uint8_t *digest, size_t digest_len,
const ECDSA_SIG *sig, EC_KEY *key);
@@ -148,6 +148,34 @@ OPENSSL_EXPORT int ECDSA_sign_ex(int type, const uint8_t *digest,
/* ASN.1 functions. */
+/* ECDSA_SIG_parse parses a DER-encoded ECDSA-Sig-Value structure from |cbs| and
+ * advances |cbs|. It returns a newly-allocated |ECDSA_SIG| or NULL on error. */
+OPENSSL_EXPORT ECDSA_SIG *ECDSA_SIG_parse(CBS *cbs);
+
+/* ECDSA_SIG_from_bytes parses |in| as a DER-encoded ECDSA-Sig-Value structure.
+ * It returns a newly-allocated |ECDSA_SIG| structure or NULL on error. */
+OPENSSL_EXPORT ECDSA_SIG *ECDSA_SIG_from_bytes(const uint8_t *in,
+ size_t in_len);
+
+/* ECDSA_SIG_marshal marshals |sig| as a DER-encoded ECDSA-Sig-Value and appends
+ * the result to |cbb|. It returns one on success and zero on error. */
+OPENSSL_EXPORT int ECDSA_SIG_marshal(CBB *cbb, const ECDSA_SIG *sig);
+
+/* ECDSA_SIG_to_bytes marshals |sig| as a DER-encoded ECDSA-Sig-Value and, on
+ * success, sets |*out_bytes| to a newly allocated buffer containing the result
+ * and returns one. Otherwise, it returns zero. The result should be freed with
+ * |OPENSSL_free|. */
+OPENSSL_EXPORT int ECDSA_SIG_to_bytes(uint8_t **out_bytes, size_t *out_len,
+ const ECDSA_SIG *sig);
+
+/* ECDSA_SIG_max_len returns the maximum length of a DER-encoded ECDSA-Sig-Value
+ * structure for a group whose order is represented in |order_len| bytes, or
+ * zero on overflow. */
+OPENSSL_EXPORT size_t ECDSA_SIG_max_len(size_t order_len);
+
+
+/* Deprecated functions. */
+
/* d2i_ECDSA_SIG parses an ASN.1, DER-encoded, signature from |len| bytes at
* |*inp|. If |out| is not NULL then, on exit, a pointer to the result is in
* |*out|. If |*out| is already non-NULL on entry then the result is written
@@ -168,15 +196,11 @@ OPENSSL_EXPORT int i2d_ECDSA_SIG(const ECDSA_SIG *sig, uint8_t **outp);
} /* extern C */
#endif
-#define ECDSA_F_ECDSA_do_sign_ex 100
-#define ECDSA_F_ECDSA_do_verify 101
-#define ECDSA_F_ECDSA_sign_ex 102
-#define ECDSA_F_digest_to_bn 103
-#define ECDSA_F_ecdsa_sign_setup 104
#define ECDSA_R_BAD_SIGNATURE 100
#define ECDSA_R_MISSING_PARAMETERS 101
#define ECDSA_R_NEED_NEW_SETUP_VALUES 102
#define ECDSA_R_NOT_IMPLEMENTED 103
#define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED 104
+#define ECDSA_R_ENCODE_ERROR 105
#endif /* OPENSSL_HEADER_ECDSA_H */
diff --git a/src/include/openssl/engine.h b/src/include/openssl/engine.h
index d3d278a..128a2ae 100644
--- a/src/include/openssl/engine.h
+++ b/src/include/openssl/engine.h
@@ -53,15 +53,6 @@ OPENSSL_EXPORT void ENGINE_free(ENGINE *engine);
*
* Set functions return one on success and zero on allocation failure. */
-OPENSSL_EXPORT int ENGINE_set_DH_method(ENGINE *engine, const DH_METHOD *method,
- size_t method_size);
-OPENSSL_EXPORT DH_METHOD *ENGINE_get_DH_method(const ENGINE *engine);
-
-OPENSSL_EXPORT int ENGINE_set_DSA_method(ENGINE *engine,
- const DSA_METHOD *method,
- size_t method_size);
-OPENSSL_EXPORT DSA_METHOD *ENGINE_get_DSA_method(const ENGINE *engine);
-
OPENSSL_EXPORT int ENGINE_set_RSA_method(ENGINE *engine,
const RSA_METHOD *method,
size_t method_size);
diff --git a/src/include/openssl/err.h b/src/include/openssl/err.h
index 30dc4af..40361d7 100644
--- a/src/include/openssl/err.h
+++ b/src/include/openssl/err.h
@@ -126,12 +126,11 @@ extern "C" {
*
* Each error contains:
* 1) The library (i.e. ec, pem, rsa) which created it.
- * 2) A function identifier and reason code.
- * 3) The file and line number of the call that added the error.
- * 4) A pointer to some error specific data, which may be NULL.
+ * 2) The file and line number of the call that added the error.
+ * 3) A pointer to some error specific data, which may be NULL.
*
- * The library identifier, function identifier and reason code are packed in a
- * uint32_t and there exist various functions for unpacking it.
+ * The library identifier and reason code are packed in a uint32_t and there
+ * exist various functions for unpacking it.
*
* The typical behaviour is that an error will occur deep in a call queue and
* that code will push an error onto the error queue. As the error queue
@@ -202,10 +201,10 @@ OPENSSL_EXPORT uint32_t ERR_peek_last_error_line_data(const char **file,
*
* The string will have the following format:
*
- * error:[error code]:[library name]:[function name]:[reason string]
+ * error:[error code]:[library name]:OPENSSL_internal:[reason string]
*
- * error code is an 8 digit hexadecimal number; library name, function name
- * and reason string are ASCII text.
+ * error code is an 8 digit hexadecimal number; library name and reason string
+ * are ASCII text.
*
* TODO(fork): remove in favour of |ERR_error_string_n|. */
OPENSSL_EXPORT char *ERR_error_string(uint32_t packed_error, char *buf);
@@ -222,10 +221,6 @@ OPENSSL_EXPORT void ERR_error_string_n(uint32_t packed_error, char *buf,
* generated |packed_error|. */
OPENSSL_EXPORT const char *ERR_lib_error_string(uint32_t packed_error);
-/* ERR_func_error_string returns a string representation of the function that
- * generated |packed_error|. */
-OPENSSL_EXPORT const char *ERR_func_error_string(uint32_t packed_error);
-
/* ERR_reason_error_string returns a string representation of the reason for
* |packed_error|. */
OPENSSL_EXPORT const char *ERR_reason_error_string(uint32_t packed_error);
@@ -247,7 +242,7 @@ typedef int (*ERR_print_errors_callback_t)(const char *str, size_t len,
* The string will have the following format (which differs from
* |ERR_error_string|):
*
- * [thread id]:error:[error code]:[library name]:[function name]:
+ * [thread id]:error:[error code]:[library name]:OPENSSL_internal:
* [reason string]:[file]:[line number]:[optional string data]
*
* (All in one line.)
@@ -258,11 +253,11 @@ typedef int (*ERR_print_errors_callback_t)(const char *str, size_t len,
OPENSSL_EXPORT void ERR_print_errors_cb(ERR_print_errors_callback_t callback,
void *ctx);
-
/* ERR_print_errors_fp prints the current contents of the error stack to |file|
* using human readable strings where possible. */
OPENSSL_EXPORT void ERR_print_errors_fp(FILE *file);
+
/* Clearing errors. */
/* ERR_clear_error clears the error queue for the current thread. */
@@ -287,9 +282,12 @@ OPENSSL_EXPORT int ERR_get_next_error_library(void);
/* Deprecated functions. */
-/* |ERR_remove_state| calls |ERR_clear_error|. */
+/* ERR_remove_state calls |ERR_clear_error|. */
OPENSSL_EXPORT void ERR_remove_state(unsigned long pid);
+/* ERR_func_error_string returns the string "OPENSSL_internal". */
+OPENSSL_EXPORT const char *ERR_func_error_string(uint32_t packed_error);
+
/* Private functions. */
@@ -298,19 +296,18 @@ OPENSSL_EXPORT void ERR_clear_system_error(void);
/* OPENSSL_PUT_ERROR is used by OpenSSL code to add an error to the error
* queue. */
-#define OPENSSL_PUT_ERROR(library, func, reason) \
- ERR_put_error(ERR_LIB_##library, library##_F_##func, reason, __FILE__, \
- __LINE__)
+#define OPENSSL_PUT_ERROR(library, reason) \
+ ERR_put_error(ERR_LIB_##library, 0, reason, __FILE__, __LINE__)
/* OPENSSL_PUT_SYSTEM_ERROR is used by OpenSSL code to add an error from the
- * operating system to the error queue. */
-/* TODO(fork): include errno. */
-#define OPENSSL_PUT_SYSTEM_ERROR(func) \
- ERR_put_error(ERR_LIB_SYS, SYS_F_##func, 0, __FILE__, __LINE__);
+ * operating system to the error queue.
+ * TODO(fork): include errno. */
+#define OPENSSL_PUT_SYSTEM_ERROR() \
+ ERR_put_error(ERR_LIB_SYS, 0, 0, __FILE__, __LINE__);
/* ERR_put_error adds an error to the error queue, dropping the least recent
* error if neccessary for space reasons. */
-OPENSSL_EXPORT void ERR_put_error(int library, int func, int reason,
+OPENSSL_EXPORT void ERR_put_error(int library, int unused, int reason,
const char *file, unsigned line);
/* ERR_add_error_data takes a variable number (|count|) of const char*
@@ -338,8 +335,7 @@ struct err_error_st {
/* data contains optional data. It must be freed with |OPENSSL_free| if
* |flags&ERR_FLAG_MALLOCED|. */
char *data;
- /* packed contains the error library, function and reason, as packed by
- * ERR_PACK. */
+ /* packed contains the error library and reason, as packed by ERR_PACK. */
uint32_t packed;
/* line contains the line number where the error occured. */
uint16_t line;
@@ -418,8 +414,8 @@ enum {
ERR_LIB_HMAC,
ERR_LIB_DIGEST,
ERR_LIB_CIPHER,
- ERR_LIB_USER,
ERR_LIB_HKDF,
+ ERR_LIB_USER,
ERR_NUM_LIBS
};
@@ -469,22 +465,11 @@ enum {
#define ERR_R_INTERNAL_ERROR (4 | ERR_R_FATAL)
#define ERR_R_OVERFLOW (5 | ERR_R_FATAL)
-/* System error functions */
-#define SYS_F_fopen 100
-#define SYS_F_fclose 101
-#define SYS_F_fread 102
-#define SYS_F_fwrite 103
-#define SYS_F_socket 104
-#define SYS_F_setsockopt 105
-#define SYS_F_connect 106
-#define SYS_F_getaddrinfo 107
-
-#define ERR_PACK(lib, func, reason) \
- (((((uint32_t)lib) & 0xff) << 24) | ((((uint32_t)func) & 0xfff) << 12) | \
- ((((uint32_t)reason) & 0xfff)))
+#define ERR_PACK(lib, reason) \
+ (((((uint32_t)lib) & 0xff) << 24) | ((((uint32_t)reason) & 0xfff)))
#define ERR_GET_LIB(packed_error) ((int)(((packed_error) >> 24) & 0xff))
-#define ERR_GET_FUNC(packed_error) ((int)(((packed_error) >> 12) & 0xfff))
+#define ERR_GET_FUNC(packed_error) 0
#define ERR_GET_REASON(packed_error) ((int)((packed_error) & 0xfff))
/* OPENSSL_DECLARE_ERROR_REASON is used by util/make_errors.h (which generates
@@ -494,13 +479,6 @@ enum {
* ${lib}_R_${reason}. */
#define OPENSSL_DECLARE_ERROR_REASON(lib, reason)
-/* OPENSSL_DECLARE_ERROR_FUNCTION is used by util/make_errors.h (which
- * generates the error * defines to recognise that an additional function value
- * is needed. This is * needed when the function value is used outside of an
- * |OPENSSL_PUT_ERROR| * macro. The resulting define will be
- * ${lib}_F_${reason}. */
-#define OPENSSL_DECLARE_ERROR_FUNCTION(lib, function_name)
-
#if defined(__cplusplus)
} /* extern C */
diff --git a/src/include/openssl/evp.h b/src/include/openssl/evp.h
index 490a951..be2ea33 100644
--- a/src/include/openssl/evp.h
+++ b/src/include/openssl/evp.h
@@ -66,6 +66,7 @@
*
* TODO(fork): clean up callers so that they include what they use. */
#include <openssl/aead.h>
+#include <openssl/base64.h>
#include <openssl/cipher.h>
#include <openssl/digest.h>
#include <openssl/obj.h>
@@ -136,50 +137,38 @@ OPENSSL_EXPORT int EVP_PKEY_id(const EVP_PKEY *pkey);
* |EVP_PKEY_RSA2| will be turned into |EVP_PKEY_RSA|. */
OPENSSL_EXPORT int EVP_PKEY_type(int nid);
-/* Deprecated: EVP_PKEY_new_mac_key allocates a fresh |EVP_PKEY| of the given
- * type (e.g. |EVP_PKEY_HMAC|), sets |mac_key| as the MAC key and "generates" a
- * new key, suitable for signing. It returns the fresh |EVP_PKEY|, or NULL on
- * error. Use |HMAC_CTX| directly instead. */
-OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *engine,
- const uint8_t *mac_key,
- size_t mac_key_len);
-
/* Getting and setting concrete public key types.
*
* 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, struct dsa_st *key);
+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 struct dsa_st *EVP_PKEY_get1_DSA(EVP_PKEY *pkey);
+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, struct ec_key_st *key);
+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 struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey);
-
-OPENSSL_EXPORT int EVP_PKEY_set1_DH(EVP_PKEY *pkey, struct dh_st *key);
-OPENSSL_EXPORT int EVP_PKEY_assign_DH(EVP_PKEY *pkey, DH *key);
-OPENSSL_EXPORT struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey);
+OPENSSL_EXPORT EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey);
+OPENSSL_EXPORT EC_KEY *EVP_PKEY_get1_EC_KEY(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
-/* Deprecated: Use |HMAC_CTX| directly instead. */
-#define EVP_PKEY_HMAC NID_hmac
-
/* EVP_PKEY_assign sets the underlying key of |pkey| to |key|, which must be of
* the given type. The |type| argument should be one of the |EVP_PKEY_*|
* values. */
@@ -220,10 +209,13 @@ OPENSSL_EXPORT EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp,
* the result, whether written or not, or a negative value on error. */
OPENSSL_EXPORT int i2d_PrivateKey(const EVP_PKEY *key, uint8_t **outp);
-/* i2d_PublicKey marshals a public key from |key| to an ASN.1, DER
- * structure. If |outp| is not NULL then the result is written to |*outp| and
+/* i2d_PublicKey marshals a public key from |key| to a type-specific format.
+ * If |outp| is not NULL then the result is written to |*outp| and
* |*outp| is advanced just past the output. It returns the number of bytes in
- * the result, whether written or not, or a negative value on error. */
+ * the result, whether written or not, or a negative value on error.
+ *
+ * RSA keys are serialized as a DER-encoded RSAPublicKey (RFC 3447) structure.
+ * EC keys are serialized as an EC point per SEC 1. */
OPENSSL_EXPORT int i2d_PublicKey(EVP_PKEY *key, uint8_t **outp);
@@ -377,12 +369,12 @@ OPENSSL_EXPORT int EVP_VerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig,
OPENSSL_EXPORT int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
int indent, ASN1_PCTX *pctx);
-/* EVP_PKEY_print_public prints a textual representation of the private key in
+/* EVP_PKEY_print_private prints a textual representation of the private key in
* |pkey| to |out|. Returns one on success or zero otherwise. */
OPENSSL_EXPORT int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
int indent, ASN1_PCTX *pctx);
-/* EVP_PKEY_print_public prints a textual representation of the parameters in
+/* EVP_PKEY_print_params prints a textual representation of the parameters in
* |pkey| to |out|. Returns one on success or zero otherwise. */
OPENSSL_EXPORT int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
int indent, ASN1_PCTX *pctx);
@@ -419,13 +411,13 @@ OPENSSL_EXPORT int PKCS5_PBKDF2_HMAC_SHA1(const char *password,
* returns the context or NULL on error. */
OPENSSL_EXPORT EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
-/* EVP_PKEY_CTX_new allocates a fresh |EVP_PKEY_CTX| for a key of type |id|
+/* EVP_PKEY_CTX_new_id allocates a fresh |EVP_PKEY_CTX| for a key of type |id|
* (e.g. |EVP_PKEY_HMAC|). This can be used for key generation where
* |EVP_PKEY_CTX_new| can't be used because there isn't an |EVP_PKEY| to pass
* it. It returns the context or NULL on error. */
OPENSSL_EXPORT EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
-/* EVP_KEY_CTX_free frees |ctx| and the data it owns. */
+/* EVP_PKEY_CTX_free frees |ctx| and the data it owns. */
OPENSSL_EXPORT void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
/* EVP_PKEY_CTX_dup allocates a fresh |EVP_PKEY_CTX| and sets it equal to the
@@ -650,16 +642,9 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx,
/* Deprecated functions. */
-/* EVP_PKEY_dup adds one to the reference count of |pkey| and returns
- * |pkey|.
- *
- * WARNING: this is a |_dup| function that doesn't actually duplicate! Use
- * |EVP_PKEY_up_ref| if you want to increment the reference count without
- * confusion. */
-OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_dup(EVP_PKEY *pkey);
-
-
-/* Private 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);
@@ -673,13 +658,20 @@ OPENSSL_EXPORT void OpenSSL_add_all_digests(void);
/* EVP_cleanup does nothing. */
OPENSSL_EXPORT void EVP_cleanup(void);
+
+/* Private functions */
+
/* EVP_PKEY_asn1_find returns the ASN.1 method table for the given |nid|, which
* should be one of the |EVP_PKEY_*| values. It returns NULL if |nid| is
* unknown. */
OPENSSL_EXPORT const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pengine,
int nid);
-/* TODO(fork): move to PEM? */
+/* EVP_PKEY_asn1_find_str returns an |EVP_PKEY_ASN1_METHOD| by matching values
+ * of the |len| bytes at |name|. For example, if name equals "EC" then it will
+ * return an ECC method. The |pengine| argument is ignored.
+ *
+ * TODO(fork): move to PEM? */
OPENSSL_EXPORT const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(
ENGINE **pengine, const char *name, size_t len);
@@ -692,10 +684,10 @@ struct evp_pkey_st {
union {
char *ptr;
- struct rsa_st *rsa; /* RSA */
- struct dsa_st *dsa; /* DSA */
- struct dh_st *dh; /* DH */
- struct ec_key_st *ec; /* ECC */
+ RSA *rsa;
+ DSA *dsa;
+ DH *dh;
+ EC_KEY *ec;
} pkey;
/* ameth contains a pointer to a method table that contains many ASN.1
@@ -708,74 +700,6 @@ struct evp_pkey_st {
} /* extern C */
#endif
-#define EVP_F_EVP_PKEY_derive_init 108
-#define EVP_F_EVP_PKEY_encrypt 110
-#define EVP_F_EVP_PKEY_encrypt_init 111
-#define EVP_F_EVP_PKEY_get1_DH 112
-#define EVP_F_EVP_PKEY_get1_EC_KEY 114
-#define EVP_F_EVP_PKEY_get1_RSA 115
-#define EVP_F_EVP_PKEY_keygen 116
-#define EVP_F_EVP_PKEY_sign 120
-#define EVP_F_EVP_PKEY_sign_init 121
-#define EVP_F_EVP_PKEY_verify 122
-#define EVP_F_EVP_PKEY_verify_init 123
-#define EVP_F_d2i_AutoPrivateKey 125
-#define EVP_F_d2i_PrivateKey 126
-#define EVP_F_do_EC_KEY_print 127
-#define EVP_F_do_sigver_init 129
-#define EVP_F_eckey_param2type 130
-#define EVP_F_eckey_param_decode 131
-#define EVP_F_eckey_priv_decode 132
-#define EVP_F_eckey_priv_encode 133
-#define EVP_F_eckey_pub_decode 134
-#define EVP_F_eckey_pub_encode 135
-#define EVP_F_eckey_type2param 136
-#define EVP_F_evp_pkey_ctx_new 137
-#define EVP_F_hmac_signctx 138
-#define EVP_F_i2d_PublicKey 139
-#define EVP_F_old_ec_priv_decode 140
-#define EVP_F_old_rsa_priv_decode 141
-#define EVP_F_pkey_ec_ctrl 142
-#define EVP_F_pkey_ec_derive 143
-#define EVP_F_pkey_ec_keygen 144
-#define EVP_F_pkey_ec_paramgen 145
-#define EVP_F_pkey_ec_sign 146
-#define EVP_F_pkey_rsa_ctrl 147
-#define EVP_F_pkey_rsa_decrypt 148
-#define EVP_F_pkey_rsa_encrypt 149
-#define EVP_F_pkey_rsa_sign 150
-#define EVP_F_rsa_algor_to_md 151
-#define EVP_F_rsa_digest_verify_init_from_algorithm 152
-#define EVP_F_rsa_mgf1_to_md 153
-#define EVP_F_rsa_priv_decode 154
-#define EVP_F_rsa_priv_encode 155
-#define EVP_F_rsa_pss_to_ctx 156
-#define EVP_F_rsa_pub_decode 157
-#define EVP_F_pkey_hmac_ctrl 158
-#define EVP_F_EVP_PKEY_CTX_get0_rsa_oaep_label 159
-#define EVP_F_EVP_DigestSignAlgorithm 160
-#define EVP_F_EVP_DigestVerifyInitFromAlgorithm 161
-#define EVP_F_EVP_PKEY_CTX_ctrl 162
-#define EVP_F_EVP_PKEY_CTX_dup 163
-#define EVP_F_EVP_PKEY_copy_parameters 164
-#define EVP_F_EVP_PKEY_decrypt 165
-#define EVP_F_EVP_PKEY_decrypt_init 166
-#define EVP_F_EVP_PKEY_derive 167
-#define EVP_F_EVP_PKEY_derive_set_peer 168
-#define EVP_F_EVP_PKEY_get1_DSA 169
-#define EVP_F_EVP_PKEY_keygen_init 170
-#define EVP_F_EVP_PKEY_new 171
-#define EVP_F_EVP_PKEY_set_type 172
-#define EVP_F_check_padding_md 173
-#define EVP_F_do_dsa_print 174
-#define EVP_F_do_rsa_print 175
-#define EVP_F_dsa_param_decode 176
-#define EVP_F_dsa_priv_decode 177
-#define EVP_F_dsa_priv_encode 178
-#define EVP_F_dsa_pub_decode 179
-#define EVP_F_dsa_pub_encode 180
-#define EVP_F_dsa_sig_print 181
-#define EVP_F_old_dsa_priv_decode 182
#define EVP_R_BUFFER_TOO_SMALL 100
#define EVP_R_COMMAND_NOT_SUPPORTED 101
#define EVP_R_DIFFERENT_KEY_TYPES 104
diff --git a/src/include/openssl/ex_data.h b/src/include/openssl/ex_data.h
index 2303eb4..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;
@@ -134,7 +134,7 @@ typedef struct crypto_ex_data_st CRYPTO_EX_DATA;
#if 0 /* Sample */
-/* |TYPE_get_ex_new_index| allocates a new index for |TYPE|. See the
+/* TYPE_get_ex_new_index allocates a new index for |TYPE|. See the
* descriptions of the callback typedefs for details of when they are
* called. Any of the callback arguments may be NULL. The |argl| and |argp|
* arguments are opaque values that are passed to the callbacks. It returns the
@@ -142,15 +142,15 @@ 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);
-/* |TYPE_set_ex_data| sets an extra data pointer on |t|. The |index| argument
+/* TYPE_set_ex_data sets an extra data pointer on |t|. The |index| argument
* should have been returned from a previous call to |TYPE_get_ex_new_index|. */
OPENSSL_EXPORT int TYPE_set_ex_data(TYPE *t, int index, void *arg);
-/* |TYPE_get_ex_data| returns an extra data pointer for |t|, or NULL if no such
+/* TYPE_get_ex_data returns an extra data pointer for |t|, or NULL if no such
* pointer exists. The |index| argument should have been returned from a
* previous call to |TYPE_get_ex_new_index|. */
OPENSSL_EXPORT void *TYPE_get_ex_data(const TYPE *t, int index);
@@ -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/hkdf.h b/src/include/openssl/hkdf.h
index 4091b84..b7a0dc2 100644
--- a/src/include/openssl/hkdf.h
+++ b/src/include/openssl/hkdf.h
@@ -39,7 +39,6 @@ OPENSSL_EXPORT int HKDF(uint8_t *out_key, size_t out_len, const EVP_MD *digest,
} /* extern C */
#endif
-#define HKDF_F_HKDF 100
#define HKDF_R_OUTPUT_TOO_LARGE 100
#endif /* OPENSSL_HEADER_HKDF_H */
diff --git a/src/include/openssl/lhash.h b/src/include/openssl/lhash.h
index d2ee982..0d6d3ae 100644
--- a/src/include/openssl/lhash.h
+++ b/src/include/openssl/lhash.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved.
+/* 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).
@@ -188,4 +189,4 @@ OPENSSL_EXPORT uint32_t lh_strhash(const char *c);
} /* extern C */
#endif
-#endif /* OPENSSL_HEADER_STACK_H */
+#endif /* OPENSSL_HEADER_LHASH_H */
diff --git a/src/include/openssl/md4.h b/src/include/openssl/md4.h
index ce4fa99..93c7af8 100644
--- a/src/include/openssl/md4.h
+++ b/src/include/openssl/md4.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved.
+/* 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).
@@ -71,7 +72,7 @@ extern "C" {
/* MD4_DIGEST_LENGTH is the length of an MD4 digest. */
#define MD4_DIGEST_LENGTH 16
-/* MD41_Init initialises |md4| and returns one. */
+/* MD4_Init initialises |md4| and returns one. */
OPENSSL_EXPORT int MD4_Init(MD4_CTX *md4);
/* MD4_Update adds |len| bytes from |data| to |md4| and returns one. */
@@ -87,10 +88,10 @@ OPENSSL_EXPORT int MD4_Final(uint8_t *md, MD4_CTX *md4);
OPENSSL_EXPORT void MD4_Transform(MD4_CTX *md4, const uint8_t *block);
struct md4_state_st {
- uint32_t A, B, C, D;
+ 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 efedc98..55162f0 100644
--- a/src/include/openssl/md5.h
+++ b/src/include/openssl/md5.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved.
+/* 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).
@@ -72,7 +73,7 @@ extern "C" {
/* MD5_DIGEST_LENGTH is the length of an MD5 digest. */
#define MD5_DIGEST_LENGTH 16
-/* MD51_Init initialises |md5| and returns one. */
+/* MD5_Init initialises |md5| and returns one. */
OPENSSL_EXPORT int MD5_Init(MD5_CTX *md5);
/* MD5_Update adds |len| bytes from |data| to |md5| and returns one. */
@@ -92,10 +93,10 @@ OPENSSL_EXPORT uint8_t *MD5(const uint8_t *data, size_t len, uint8_t *out);
OPENSSL_EXPORT void MD5_Transform(MD5_CTX *md5, const uint8_t *block);
struct md5_state_st {
- uint32_t A, B, C, D;
+ 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/mem.h b/src/include/openssl/mem.h
index 42ec46a..c8e2b3e 100644
--- a/src/include/openssl/mem.h
+++ b/src/include/openssl/mem.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved.
+/* 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).
diff --git a/src/include/openssl/modes.h b/src/include/openssl/modes.h
deleted file mode 100644
index 220adec..0000000
--- a/src/include/openssl/modes.h
+++ /dev/null
@@ -1,223 +0,0 @@
-/* ====================================================================
- * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ==================================================================== */
-
-#ifndef OPENSSL_HEADER_MODES_H
-#define OPENSSL_HEADER_MODES_H
-
-#include <openssl/base.h>
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-
-/* modes.h contains functions that implement various block-cipher modes. */
-
-
-/* block128_f is the type of a 128-bit, block cipher. */
-typedef void (*block128_f)(const uint8_t in[16], uint8_t out[16],
- const void *key);
-
-
-/* CTR. */
-
-/* ctr128_f is the type of a function that performs CTR-mode encryption. */
-typedef void (*ctr128_f)(const uint8_t *in, uint8_t *out, size_t blocks,
- const void *key, const uint8_t ivec[16]);
-
-/* CRYPTO_ctr128_encrypt encrypts (or decrypts, it's the same in CTR mode)
- * |len| bytes from |in| to |out| using |block| in counter mode. There's no
- * requirement that |len| be a multiple of any value and any partial blocks are
- * stored in |ecount_buf| and |*num|, which must be zeroed before the initial
- * call. The counter is a 128-bit, big-endian value in |ivec| and is
- * incremented by this function. */
-OPENSSL_EXPORT void CRYPTO_ctr128_encrypt(const uint8_t *in, uint8_t *out,
- size_t len, const void *key,
- uint8_t ivec[16],
- uint8_t ecount_buf[16],
- unsigned int *num, block128_f block);
-
-/* CRYPTO_ctr128_encrypt_ctr32 acts like |CRYPTO_ctr128_encrypt| but takes
- * |ctr|, a function that performs CTR mode but only deals with the lower 32
- * bits of the counter. This is useful when |ctr| can be an optimised
- * function. */
-OPENSSL_EXPORT void CRYPTO_ctr128_encrypt_ctr32(
- const uint8_t *in, uint8_t *out, size_t len, const void *key,
- uint8_t ivec[16], uint8_t ecount_buf[16], unsigned int *num, ctr128_f ctr);
-
-
-/* GCM. */
-
-typedef struct gcm128_context GCM128_CONTEXT;
-
-/* CRYPTO_gcm128_new allocates a fresh |GCM128_CONTEXT| and calls
- * |CRYPTO_gcm128_init|. It returns the new context, or NULL on error. */
-OPENSSL_EXPORT GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block);
-
-/* CRYPTO_gcm128_init initialises |ctx| to use |block| (typically AES) with the
- * given key. */
-OPENSSL_EXPORT void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key,
- block128_f block);
-
-/* CRYPTO_gcm128_setiv sets the IV (nonce) for |ctx|. */
-OPENSSL_EXPORT void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const uint8_t *iv,
- size_t len);
-
-/* CRYPTO_gcm128_aad sets the authenticated data for an instance of GCM. This
- * must be called before and data is encrypted. It returns one on success and
- * zero otherwise. */
-OPENSSL_EXPORT int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const uint8_t *aad,
- size_t len);
-
-/* CRYPTO_gcm128_encrypt encrypts |len| bytes from |in| to |out|. It returns
- * one on success and zero otherwise. */
-OPENSSL_EXPORT int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const uint8_t *in,
- uint8_t *out, size_t len);
-
-/* CRYPTO_gcm128_decrypt decrypts |len| bytes from |in| to |out|. It returns
- * one on success and zero otherwise. */
-OPENSSL_EXPORT int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const uint8_t *in,
- uint8_t *out, size_t len);
-
-/* CRYPTO_gcm128_encrypt_ctr32 encrypts |len| bytes from |in| to |out| using a
- * CTR function that only handles the bottom 32 bits of the nonce, like
- * |CRYPTO_ctr128_encrypt_ctr32|. It returns one on success and zero
- * otherwise. */
-OPENSSL_EXPORT int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx,
- const uint8_t *in, uint8_t *out,
- size_t len, ctr128_f stream);
-
-/* CRYPTO_gcm128_decrypt_ctr32 decrypts |len| bytes from |in| to |out| using a
- * CTR function that only handles the bottom 32 bits of the nonce, like
- * |CRYPTO_ctr128_encrypt_ctr32|. It returns one on success and zero
- * otherwise. */
-OPENSSL_EXPORT int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx,
- const uint8_t *in, uint8_t *out,
- size_t len, ctr128_f stream);
-
-/* CRYPTO_gcm128_finish calculates the authenticator and compares it against
- * |len| bytes of |tag|. It returns one on success and zero otherwise. */
-OPENSSL_EXPORT int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const uint8_t *tag,
- size_t len);
-
-/* CRYPTO_gcm128_tag calculates the authenticator and copies it into |tag|. The
- * minimum of |len| and 16 bytes are copied into |tag|. */
-OPENSSL_EXPORT void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, uint8_t *tag,
- size_t len);
-
-/* CRYPTO_gcm128_release clears and frees |ctx|. */
-OPENSSL_EXPORT void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx);
-
-
-/* CBC. */
-
-/* cbc128_f is the type of a function that performs CBC-mode encryption. */
-typedef void (*cbc128_f)(const uint8_t *in, uint8_t *out, size_t len,
- const void *key, uint8_t ivec[16], int enc);
-
-/* CRYPTO_cbc128_encrypt encrypts |len| bytes from |in| to |out| using the
- * given IV and block cipher in CBC mode. The input need not be a multiple of
- * 128 bits long, but the output will round up to the nearest 128 bit multiple,
- * zero padding the input if needed. The IV will be updated on return. */
-void CRYPTO_cbc128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
- const void *key, uint8_t ivec[16], block128_f block);
-
-/* CRYPTO_cbc128_decrypt decrypts |len| bytes from |in| to |out| using the
- * given IV and block cipher in CBC mode. If |len| is not a multiple of 128
- * bits then only that many bytes will be written, but a multiple of 128 bits
- * is always read from |in|. The IV will be updated on return. */
-void CRYPTO_cbc128_decrypt(const uint8_t *in, uint8_t *out, size_t len,
- const void *key, uint8_t ivec[16], block128_f block);
-
-
-/* OFB. */
-
-/* CRYPTO_ofb128_encrypt encrypts (or decrypts, it's the same with OFB mode)
- * |len| bytes from |in| to |out| using |block| in OFB mode. There's no
- * requirement that |len| be a multiple of any value and any partial blocks are
- * stored in |ivec| and |*num|, the latter must be zero before the initial
- * call. */
-void CRYPTO_ofb128_encrypt(const uint8_t *in, uint8_t *out,
- size_t len, const void *key, uint8_t ivec[16],
- int *num, block128_f block);
-
-
-/* CFB. */
-
-/* CRYPTO_cfb128_encrypt encrypts (or decrypts, if |enc| is zero) |len| bytes
- * from |in| to |out| using |block| in CFB mode. There's no requirement that
- * |len| be a multiple of any value and any partial blocks are stored in |ivec|
- * and |*num|, the latter must be zero before the initial call. */
-void CRYPTO_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
- const void *key, uint8_t ivec[16], int *num, int enc,
- block128_f block);
-
-/* CRYPTO_cfb128_8_encrypt encrypts (or decrypts, if |enc| is zero) |len| bytes
- * from |in| to |out| using |block| in CFB-8 mode. Prior to the first call
- * |num| should be set to zero. */
-void CRYPTO_cfb128_8_encrypt(const uint8_t *in, uint8_t *out, size_t len,
- const void *key, uint8_t ivec[16], int *num,
- int enc, block128_f block);
-
-/* CRYPTO_cfb128_1_encrypt encrypts (or decrypts, if |enc| is zero) |len| bytes
- * from |in| to |out| using |block| in CFB-1 mode. Prior to the first call
- * |num| should be set to zero. */
-void CRYPTO_cfb128_1_encrypt(const uint8_t *in, uint8_t *out, size_t bits,
- const void *key, uint8_t ivec[16], int *num,
- int enc, block128_f block);
-
-size_t CRYPTO_cts128_encrypt_block(const uint8_t *in, uint8_t *out, size_t len,
- const void *key, uint8_t ivec[16],
- block128_f block);
-
-
-#if defined(__cplusplus)
-} /* extern C */
-#endif
-
-#endif /* OPENSSL_HEADER_MODES_H */
diff --git a/src/include/openssl/obj.h b/src/include/openssl/obj.h
index f476617..32a4894 100644
--- a/src/include/openssl/obj.h
+++ b/src/include/openssl/obj.h
@@ -54,8 +54,8 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
-#ifndef OPENSSL_HEADER_OBJECTS_H
-#define OPENSSL_HEADER_OBJECTS_H
+#ifndef OPENSSL_HEADER_OBJ_H
+#define OPENSSL_HEADER_OBJ_H
#include <openssl/base.h>
@@ -125,10 +125,10 @@ OPENSSL_EXPORT const ASN1_OBJECT *OBJ_nid2obj(int nid);
/* OBJ_nid2sn returns the short name for |nid|, or NULL if |nid| is unknown. */
OPENSSL_EXPORT const char *OBJ_nid2sn(int nid);
-/* OBJ_nid2sn returns the long name for |nid|, or NULL if |nid| is unknown. */
+/* OBJ_nid2ln returns the long name for |nid|, or NULL if |nid| is unknown. */
OPENSSL_EXPORT const char *OBJ_nid2ln(int nid);
-/* OBJ_nid2cbs writes |nid| as an ASN.1 OBJECT IDENTIFIER to |out|. It returns
+/* OBJ_nid2cbb writes |nid| as an ASN.1 OBJECT IDENTIFIER to |out|. It returns
* one on success or zero otherwise. */
OPENSSL_EXPORT int OBJ_nid2cbb(CBB *out, int nid);
@@ -193,10 +193,6 @@ OPENSSL_EXPORT int OBJ_find_sigid_by_algs(int *out_sign_nid, int digest_nid,
} /* extern C */
#endif
-#define OBJ_F_OBJ_create 100
-#define OBJ_F_OBJ_dup 101
-#define OBJ_F_OBJ_nid2obj 102
-#define OBJ_F_OBJ_txt2obj 103
#define OBJ_R_UNKNOWN_NID 100
-#endif /* OPENSSL_HEADER_OBJECTS_H */
+#endif /* OPENSSL_HEADER_OBJ_H */
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 7756e45..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"
@@ -410,7 +408,7 @@ OPENSSL_EXPORT void PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type);
OPENSSL_EXPORT void PEM_SignUpdate(EVP_MD_CTX *ctx,unsigned char *d,unsigned int cnt);
OPENSSL_EXPORT int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen, EVP_PKEY *pkey);
-/* |PEM_def_callback| treats |userdata| as a string and copies it into |buf|,
+/* PEM_def_callback treats |userdata| as a string and copies it into |buf|,
* assuming its |size| is sufficient. Returns the length of the string, or 0
* if there is not enough room. If either |buf| or |userdata| is NULL, 0 is
* returned. Note that this is different from OpenSSL, which prompts for a
@@ -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)
@@ -502,30 +498,6 @@ void ERR_load_PEM_strings(void);
}
#endif
-#define PEM_F_PEM_ASN1_read 100
-#define PEM_F_PEM_ASN1_read_bio 101
-#define PEM_F_PEM_ASN1_write 102
-#define PEM_F_PEM_ASN1_write_bio 103
-#define PEM_F_PEM_X509_INFO_read 104
-#define PEM_F_PEM_X509_INFO_read_bio 105
-#define PEM_F_PEM_X509_INFO_write_bio 106
-#define PEM_F_PEM_do_header 107
-#define PEM_F_PEM_get_EVP_CIPHER_INFO 108
-#define PEM_F_PEM_read 109
-#define PEM_F_PEM_read_DHparams 110
-#define PEM_F_PEM_read_PrivateKey 111
-#define PEM_F_PEM_read_bio 112
-#define PEM_F_PEM_read_bio_DHparams 113
-#define PEM_F_PEM_read_bio_Parameters 114
-#define PEM_F_PEM_read_bio_PrivateKey 115
-#define PEM_F_PEM_write 116
-#define PEM_F_PEM_write_PrivateKey 117
-#define PEM_F_PEM_write_bio 118
-#define PEM_F_d2i_PKCS8PrivateKey_bio 119
-#define PEM_F_d2i_PKCS8PrivateKey_fp 120
-#define PEM_F_do_pk8pkey 121
-#define PEM_F_do_pk8pkey_fp 122
-#define PEM_F_load_iv 123
#define PEM_R_BAD_BASE64_DECODE 100
#define PEM_R_BAD_DECRYPT 101
#define PEM_R_BAD_END_LINE 102
diff --git a/src/include/openssl/pkcs8.h b/src/include/openssl/pkcs8.h
index 8dc7731..6b51f85 100644
--- a/src/include/openssl/pkcs8.h
+++ b/src/include/openssl/pkcs8.h
@@ -66,13 +66,15 @@ extern "C" {
#endif
-/* PKCS8_encrypt_pbe serializes and encrypts a PKCS8_PRIV_KEY_INFO with PBES1 as
- * defined in PKCS #5. Only pbeWithSHAAnd128BitRC4,
+/* PKCS8_encrypt_pbe serializes and encrypts a PKCS8_PRIV_KEY_INFO with PBES1 or
+ * PBES2 as defined in PKCS #5. Only pbeWithSHAAnd128BitRC4,
* pbeWithSHAAnd3-KeyTripleDES-CBC and pbeWithSHA1And40BitRC2, defined in PKCS
- * #12, are supported. The |pass_raw_len| bytes pointed to by |pass_raw| are
- * used as the password. Note that any conversions from the password as
- * supplied in a text string (such as those specified in B.1 of PKCS #12) must
- * be performed by the caller.
+ * #12, and PBES2, are supported. PBES2 is selected by setting |cipher| and
+ * passing -1 for |pbe_nid|. Otherwise, PBES1 is used and |cipher| is ignored.
+ *
+ * The |pass_raw_len| bytes pointed to by |pass_raw| are used as the password.
+ * Note that any conversions from the password as supplied in a text string
+ * (such as those specified in B.1 of PKCS #12) must be performed by the caller.
*
* If |salt| is NULL, a random salt of |salt_len| bytes is generated. If
* |salt_len| is zero, a default salt length is used instead.
@@ -83,55 +85,56 @@ extern "C" {
* TODO(davidben): Really? An X509_SIG? OpenSSL probably did that because it has
* the same structure as EncryptedPrivateKeyInfo. */
OPENSSL_EXPORT X509_SIG *PKCS8_encrypt_pbe(int pbe_nid,
+ const EVP_CIPHER *cipher,
const uint8_t *pass_raw,
size_t pass_raw_len,
uint8_t *salt, size_t salt_len,
int iterations,
PKCS8_PRIV_KEY_INFO *p8inf);
-/* PKCS8_decrypt_pbe decrypts and decodes a PKCS8_PRIV_KEY_INFO with PBES1 as
- * defined in PKCS #5. Only pbeWithSHAAnd128BitRC4,
- * pbeWithSHAAnd3-KeyTripleDES-CBC and pbeWithSHA1And40BitRC2, defined in PKCS
- * #12, are supported. The |pass_raw_len| bytes pointed to by |pass_raw| are
- * used as the password. Note that any conversions from the password as
- * supplied in a text string (such as those specified in B.1 of PKCS #12) must
- * be performed by the caller.
+/* PKCS8_decrypt_pbe decrypts and decodes a PKCS8_PRIV_KEY_INFO with PBES1 or
+ * PBES2 as defined in PKCS #5. Only pbeWithSHAAnd128BitRC4,
+ * pbeWithSHAAnd3-KeyTripleDES-CBC and pbeWithSHA1And40BitRC2, and PBES2,
+ * defined in PKCS #12, are supported.
+ *
+ * The |pass_raw_len| bytes pointed to by |pass_raw| are used as the password.
+ * Note that any conversions from the password as supplied in a text string
+ * (such as those specified in B.1 of PKCS #12) must be performed by the caller.
*
* The resulting structure must be freed by the caller. */
OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *PKCS8_decrypt_pbe(X509_SIG *pkcs8,
const uint8_t *pass_raw,
size_t pass_raw_len);
+/* PKCS12_get_key_and_certs parses a PKCS#12 structure from |in|, authenticates
+ * and decrypts it using |password|, sets |*out_key| to the included private
+ * key and appends the included certificates to |out_certs|. It returns one on
+ * success and zero on error. The caller takes ownership of the outputs. */
+OPENSSL_EXPORT int PKCS12_get_key_and_certs(EVP_PKEY **out_key,
+ STACK_OF(X509) *out_certs,
+ CBS *in, const char *password);
+
/* Deprecated functions. */
-/* PKCS8_encrypt calls PKCS8_encrypt_pbe after treating |pass| as an ASCII
- * string, appending U+0000, and converting to UCS-2. (So the empty password
- * encodes as two NUL bytes.) The |cipher| argument is ignored. */
+/* PKCS8_encrypt calls |PKCS8_encrypt_pbe| after (in the PKCS#12 case) treating
+ * |pass| as an ASCII string, appending U+0000, and converting to UCS-2. (So the
+ * empty password encodes as two NUL bytes.) In the PBES2 case, the password is
+ * unchanged. */
OPENSSL_EXPORT X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
const char *pass, int pass_len,
uint8_t *salt, size_t salt_len,
int iterations,
PKCS8_PRIV_KEY_INFO *p8inf);
-/* PKCS8_decrypt calls PKCS8_decrypt_pbe after treating |pass| as an ASCII
- * string, appending U+0000, and converting to UCS-2. (So the empty password
- * encodes as two NUL bytes.) */
+/* PKCS8_decrypt calls PKCS8_decrypt_pbe after (in the PKCS#12 case) treating
+ * |pass| as an ASCII string, appending U+0000, and converting to UCS-2. (So the
+ * empty password encodes as two NUL bytes.) In the PBES2 case, the password is
+ * unchanged. */
OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *pkcs8,
const char *pass,
int pass_len);
-/* PKCS12_get_key_and_certs parses a PKCS#12 structure from |in|, authenticates
- * and decrypts it using |password|, sets |*out_key| to the included private
- * key and appends the included certificates to |out_certs|. It returns one on
- * success and zero on error. The caller takes ownership of the outputs. */
-OPENSSL_EXPORT int PKCS12_get_key_and_certs(EVP_PKEY **out_key,
- STACK_OF(X509) *out_certs,
- CBS *in, const char *password);
-
-
-/* Deprecated functions. */
-
/* PKCS12_PBE_add does nothing. It exists for compatibility with OpenSSL. */
OPENSSL_EXPORT void PKCS12_PBE_add(void);
@@ -163,31 +166,25 @@ OPENSSL_EXPORT int PKCS12_parse(const PKCS12 *p12, const char *password,
EVP_PKEY **out_pkey, X509 **out_cert,
STACK_OF(X509) **out_ca_certs);
+/* PKCS12_verify_mac returns one if |password| is a valid password for |p12|
+ * and zero otherwise. Since |PKCS12_parse| doesn't take a length parameter,
+ * it's not actually possible to use a non-NUL-terminated password to actually
+ * get anything from a |PKCS12|. Thus |password| and |password_len| may be
+ * |NULL| and zero, respectively, or else |password_len| may be -1, or else
+ * |password[password_len]| must be zero and no other NUL bytes may appear in
+ * |password|. If the |password_len| checks fail, zero is returned
+ * immediately. */
+OPENSSL_EXPORT int PKCS12_verify_mac(const PKCS12 *p12, const char *password,
+ int password_len);
+
/* PKCS12_free frees |p12| and its contents. */
OPENSSL_EXPORT void PKCS12_free(PKCS12 *p12);
+
#if defined(__cplusplus)
} /* extern C */
#endif
-#define PKCS8_F_EVP_PKCS82PKEY 100
-#define PKCS8_F_EVP_PKEY2PKCS8 101
-#define PKCS8_F_PKCS12_get_key_and_certs 102
-#define PKCS8_F_PKCS12_handle_content_info 103
-#define PKCS8_F_PKCS12_handle_content_infos 104
-#define PKCS8_F_PKCS5_pbe2_set_iv 105
-#define PKCS8_F_PKCS5_pbe_set 106
-#define PKCS8_F_PKCS5_pbe_set0_algor 107
-#define PKCS8_F_PKCS5_pbkdf2_set 108
-#define PKCS8_F_PKCS8_decrypt 109
-#define PKCS8_F_PKCS8_encrypt 110
-#define PKCS8_F_PKCS8_encrypt_pbe 111
-#define PKCS8_F_pbe_cipher_init 112
-#define PKCS8_F_pbe_crypt 113
-#define PKCS8_F_pkcs12_item_decrypt_d2i 114
-#define PKCS8_F_pkcs12_item_i2d_encrypt 115
-#define PKCS8_F_pkcs12_key_gen_raw 116
-#define PKCS8_F_pkcs12_pbe_keyivgen 117
#define PKCS8_R_BAD_PKCS12_DATA 100
#define PKCS8_R_BAD_PKCS12_VERSION 101
#define PKCS8_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 102
@@ -213,5 +210,11 @@ OPENSSL_EXPORT void PKCS12_free(PKCS12 *p12);
#define PKCS8_R_UNKNOWN_DIGEST 122
#define PKCS8_R_UNKNOWN_HASH 123
#define PKCS8_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM 124
+#define PKCS8_R_UNSUPPORTED_KEYLENGTH 125
+#define PKCS8_R_UNSUPPORTED_SALT_TYPE 126
+#define PKCS8_R_UNSUPPORTED_CIPHER 127
+#define PKCS8_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION 128
+#define PKCS8_R_BAD_ITERATION_COUNT 129
+#define PKCS8_R_UNSUPPORTED_PRF 130
#endif /* OPENSSL_HEADER_PKCS8_H */
diff --git a/src/include/openssl/poly1305.h b/src/include/openssl/poly1305.h
index aa90486..b4e23e2 100644
--- a/src/include/openssl/poly1305.h
+++ b/src/include/openssl/poly1305.h
@@ -22,22 +22,26 @@ extern "C" {
#endif
-typedef unsigned char poly1305_state[512];
+typedef uint8_t poly1305_state[512];
-/* poly1305_init sets up |state| so that it can be used to calculate an
+/* CRYPTO_poly1305_init sets up |state| so that it can be used to calculate an
* authentication tag with the one-time key |key|. Note that |key| is a
* one-time key and therefore there is no `reset' method because that would
* enable several messages to be authenticated with the same key. */
-extern void CRYPTO_poly1305_init(poly1305_state* state, const uint8_t key[32]);
-
-/* poly1305_update processes |in_len| bytes from |in|. It can be called zero or
- * more times after poly1305_init. */
-extern void CRYPTO_poly1305_update(poly1305_state* state, const uint8_t* in,
- size_t in_len);
-
-/* poly1305_finish completes the poly1305 calculation and writes a 16 byte
- * authentication tag to |mac|. The |mac| address must be 16-byte aligned. */
-extern void CRYPTO_poly1305_finish(poly1305_state* state, uint8_t mac[16]);
+OPENSSL_EXPORT void CRYPTO_poly1305_init(poly1305_state* state,
+ const uint8_t key[32]);
+
+/* CRYPTO_poly1305_update processes |in_len| bytes from |in|. It can be called
+ * zero or more times after poly1305_init. */
+OPENSSL_EXPORT void CRYPTO_poly1305_update(poly1305_state* state,
+ const uint8_t* in,
+ size_t in_len);
+
+/* CRYPTO_poly1305_finish completes the poly1305 calculation and writes a 16
+ * byte authentication tag to |mac|. The |mac| address must be 16-byte
+ * aligned. */
+OPENSSL_EXPORT void CRYPTO_poly1305_finish(poly1305_state* state,
+ uint8_t mac[16]);
#if defined(__cplusplus)
diff --git a/src/include/openssl/rand.h b/src/include/openssl/rand.h
index 300bf42..3a8e357 100644
--- a/src/include/openssl/rand.h
+++ b/src/include/openssl/rand.h
@@ -33,12 +33,43 @@ OPENSSL_EXPORT int RAND_bytes(uint8_t *buf, size_t len);
OPENSSL_EXPORT void RAND_cleanup(void);
+/* Obscure functions. */
+
+#if !defined(OPENSSL_WINDOWS)
+/* RAND_set_urandom_fd causes the module to use a copy of |fd| for system
+ * randomness rather opening /dev/urandom internally. The caller retains
+ * ownership of |fd| and is at liberty to close it at any time. This is useful
+ * if, due to a sandbox, /dev/urandom isn't available. If used, it must be
+ * called before the first call to |RAND_bytes|, and it is mutually exclusive
+ * with |RAND_enable_fork_unsafe_buffering|.
+ *
+ * |RAND_set_urandom_fd| does not buffer any entropy, so it is safe to call
+ * |fork| at any time after calling |RAND_set_urandom_fd|. */
+OPENSSL_EXPORT void RAND_set_urandom_fd(int fd);
+
+/* RAND_enable_fork_unsafe_buffering enables efficient buffered reading of
+ * /dev/urandom. It adds an overhead of a few KB of memory per thread. It must
+ * be called before the first call to |RAND_bytes| and it is mutually exclusive
+ * with calls to |RAND_set_urandom_fd|.
+ *
+ * If |fd| is non-negative then a copy of |fd| will be used rather than opening
+ * /dev/urandom internally. Like |RAND_set_urandom_fd|, the caller retains
+ * ownership of |fd|. If |fd| is negative then /dev/urandom will be opened and
+ * any error from open(2) crashes the address space.
+ *
+ * It has an unusual name because the buffer is unsafe across calls to |fork|.
+ * Hence, this function should never be called by libraries. */
+OPENSSL_EXPORT void RAND_enable_fork_unsafe_buffering(int fd);
+#endif
+
+
/* Deprecated functions */
/* 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. */
@@ -47,12 +78,33 @@ OPENSSL_EXPORT int RAND_load_file(const char *path, long num);
/* RAND_add does nothing. */
OPENSSL_EXPORT void RAND_add(const void *buf, int num, double entropy);
+/* RAND_egd returns 255. */
+OPENSSL_EXPORT int RAND_egd(const char *);
+
/* RAND_poll returns one. */
OPENSSL_EXPORT int RAND_poll(void);
/* RAND_status returns one. */
OPENSSL_EXPORT int RAND_status(void);
+/* rand_meth_st is typedefed to |RAND_METHOD| in base.h. It isn't used; it
+ * exists only to be the return type of |RAND_SSLeay|. It's
+ * external so that variables of this type can be initialized. */
+struct rand_meth_st {
+ void (*seed) (const void *buf, int num);
+ int (*bytes) (uint8_t *buf, size_t num);
+ void (*cleanup) (void);
+ void (*add) (const void *buf, int num, double entropy);
+ int (*pseudorand) (uint8_t *buf, size_t num);
+ int (*status) (void);
+};
+
+/* RAND_SSLeay returns a pointer to a dummy |RAND_METHOD|. */
+OPENSSL_EXPORT RAND_METHOD *RAND_SSLeay(void);
+
+/* RAND_set_rand_method does nothing. */
+OPENSSL_EXPORT void RAND_set_rand_method(const RAND_METHOD *);
+
#if defined(__cplusplus)
} /* extern C */
diff --git a/src/include/openssl/rsa.h b/src/include/openssl/rsa.h
index 9b415d7..304c555 100644
--- a/src/include/openssl/rsa.h
+++ b/src/include/openssl/rsa.h
@@ -59,6 +59,7 @@
#include <openssl/base.h>
+#include <openssl/asn1.h>
#include <openssl/engine.h>
#include <openssl/ex_data.h>
#include <openssl/thread.h>
@@ -100,6 +101,12 @@ OPENSSL_EXPORT int RSA_up_ref(RSA *rsa);
OPENSSL_EXPORT int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e,
BN_GENCB *cb);
+/* RSA_generate_multi_prime_key acts like |RSA_generate_key_ex| but can
+ * generate an RSA private key with more than two primes. */
+OPENSSL_EXPORT int RSA_generate_multi_prime_key(RSA *rsa, int bits,
+ int num_primes, BIGNUM *e,
+ BN_GENCB *cb);
+
/* Encryption / Decryption */
@@ -117,8 +124,8 @@ OPENSSL_EXPORT int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e,
* 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);
@@ -130,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);
@@ -140,46 +153,34 @@ 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. */
-OPENSSL_EXPORT int RSA_public_encrypt(int flen, const uint8_t *from,
+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(int flen, const uint8_t *from,
+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
@@ -197,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
@@ -224,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);
@@ -233,22 +236,26 @@ 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. */
-OPENSSL_EXPORT int RSA_private_encrypt(int flen, const uint8_t *from,
+OPENSSL_EXPORT int RSA_private_encrypt(size_t flen, const uint8_t *from,
uint8_t *to, RSA *rsa, int padding);
-/* RSA_private_encrypt verifies |flen| bytes of signature from |from| using the
+/* RSA_public_decrypt verifies |flen| bytes of signature from |from| using 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.
+ * |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. */
-OPENSSL_EXPORT int RSA_public_decrypt(int flen, const uint8_t *from,
+OPENSSL_EXPORT int RSA_public_decrypt(size_t flen, const uint8_t *from,
uint8_t *to, RSA *rsa, int padding);
@@ -266,7 +273,7 @@ OPENSSL_EXPORT int RSA_is_opaque(const RSA *rsa);
* of type |md|. Otherwise it returns zero. */
OPENSSL_EXPORT int RSA_supports_digest(const RSA *rsa, const EVP_MD *md);
-/* RSAPublicKey_dup allocates a fresh |RSA| and copies the private key from
+/* RSAPublicKey_dup allocates a fresh |RSA| and copies the public key from
* |rsa| into it. It returns the fresh |RSA| object, or NULL on error. */
OPENSSL_EXPORT RSA *RSAPublicKey_dup(const RSA *rsa);
@@ -315,36 +322,63 @@ OPENSSL_EXPORT int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, uint8_t *EM,
const EVP_MD *mgf1Hash,
int sLen);
+/* RSA_add_pkcs1_prefix builds a version of |msg| prefixed with the DigestInfo
+ * header for the given hash function and sets |out_msg| to point to it. On
+ * successful return, |*out_msg| may be allocated memory and, if so,
+ * |*is_alloced| will be 1. */
+OPENSSL_EXPORT int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len,
+ int *is_alloced, int hash_nid,
+ const uint8_t *msg, size_t msg_len);
-/* ASN.1 functions. */
-/* d2i_RSAPublicKey parses an ASN.1, DER-encoded, RSA public key from |len|
- * bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result
- * is in |*out|. If |*out| is already non-NULL on entry then the result is
- * written directly into |*out|, otherwise a fresh |RSA| is allocated. On
- * successful exit, |*inp| is advanced past the DER structure. It returns the
- * result or NULL on error. */
-OPENSSL_EXPORT RSA *d2i_RSAPublicKey(RSA **out, const uint8_t **inp, long len);
-
-/* i2d_RSAPublicKey marshals |in| to an ASN.1, DER structure. If |outp| is not
- * NULL then the result is written to |*outp| and |*outp| is advanced just past
- * the output. It returns the number of bytes in the result, whether written or
- * not, or a negative value on error. */
-OPENSSL_EXPORT int i2d_RSAPublicKey(const RSA *in, uint8_t **outp);
-
-/* d2i_RSAPrivateKey parses an ASN.1, DER-encoded, RSA private key from |len|
- * bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result
- * is in |*out|. If |*out| is already non-NULL on entry then the result is
- * written directly into |*out|, otherwise a fresh |RSA| is allocated. On
- * successful exit, |*inp| is advanced past the DER structure. It returns the
- * result or NULL on error. */
-OPENSSL_EXPORT RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len);
+/* ASN.1 functions. */
-/* i2d_RSAPrivateKey marshals |in| to an ASN.1, DER structure. If |outp| is not
- * NULL then the result is written to |*outp| and |*outp| is advanced just past
- * the output. It returns the number of bytes in the result, whether written or
- * not, or a negative value on error. */
-OPENSSL_EXPORT int i2d_RSAPrivateKey(const RSA *in, uint8_t **outp);
+/* RSA_parse_public_key parses a DER-encoded RSAPublicKey structure (RFC 3447)
+ * from |cbs| and advances |cbs|. It returns a newly-allocated |RSA| or NULL on
+ * error. */
+OPENSSL_EXPORT RSA *RSA_parse_public_key(CBS *cbs);
+
+/* RSA_parse_public_key_buggy behaves like |RSA_parse_public_key|, but it
+ * tolerates some invalid encodings. Do not use this function. */
+OPENSSL_EXPORT RSA *RSA_parse_public_key_buggy(CBS *cbs);
+
+/* RSA_public_key_from_bytes parses |in| as a DER-encoded RSAPublicKey structure
+ * (RFC 3447). It returns a newly-allocated |RSA| or NULL on error. */
+OPENSSL_EXPORT RSA *RSA_public_key_from_bytes(const uint8_t *in, size_t in_len);
+
+/* RSA_marshal_public_key marshals |rsa| as a DER-encoded RSAPublicKey structure
+ * (RFC 3447) and appends the result to |cbb|. It returns one on success and
+ * zero on failure. */
+OPENSSL_EXPORT int RSA_marshal_public_key(CBB *cbb, const RSA *rsa);
+
+/* RSA_public_key_to_bytes marshals |rsa| as a DER-encoded RSAPublicKey
+ * structure (RFC 3447) and, on success, sets |*out_bytes| to a newly allocated
+ * buffer containing the result and returns one. Otherwise, it returns zero. The
+ * result should be freed with |OPENSSL_free|. */
+OPENSSL_EXPORT int RSA_public_key_to_bytes(uint8_t **out_bytes, size_t *out_len,
+ const RSA *rsa);
+
+/* RSA_parse_private_key parses a DER-encoded RSAPrivateKey structure (RFC 3447)
+ * from |cbs| and advances |cbs|. It returns a newly-allocated |RSA| or NULL on
+ * error. */
+OPENSSL_EXPORT RSA *RSA_parse_private_key(CBS *cbs);
+
+/* RSA_private_key_from_bytes parses |in| as a DER-encoded RSAPrivateKey
+ * structure (RFC 3447). It returns a newly-allocated |RSA| or NULL on error. */
+OPENSSL_EXPORT RSA *RSA_private_key_from_bytes(const uint8_t *in,
+ size_t in_len);
+
+/* RSA_marshal_private_key marshals |rsa| as a DER-encoded RSAPrivateKey
+ * structure (RFC 3447) and appends the result to |cbb|. It returns one on
+ * success and zero on failure. */
+OPENSSL_EXPORT int RSA_marshal_private_key(CBB *cbb, const RSA *rsa);
+
+/* RSA_private_key_to_bytes marshals |rsa| as a DER-encoded RSAPrivateKey
+ * structure (RFC 3447) and, on success, sets |*out_bytes| to a newly allocated
+ * buffer containing the result and returns one. Otherwise, it returns zero. The
+ * result should be freed with |OPENSSL_free|. */
+OPENSSL_EXPORT int RSA_private_key_to_bytes(uint8_t **out_bytes,
+ size_t *out_len, const RSA *rsa);
/* ex_data functions.
@@ -352,12 +386,15 @@ OPENSSL_EXPORT int i2d_RSAPrivateKey(const RSA *in, uint8_t **outp);
* 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);
OPENSSL_EXPORT void *RSA_get_ex_data(const RSA *r, int idx);
+
+/* Flags. */
+
/* RSA_FLAG_OPAQUE specifies that this RSA_METHOD does not expose its key
* material. This may be set if, for instance, it is wrapping some other crypto
* API, like a platform key store. */
@@ -395,6 +432,50 @@ OPENSSL_EXPORT void *RSA_get_ex_data(const RSA *r, int idx);
/* RSA_blinding_on returns one. */
OPENSSL_EXPORT int RSA_blinding_on(RSA *rsa, BN_CTX *ctx);
+/* RSA_generate_key behaves like |RSA_generate_key_ex|, which is what you
+ * should use instead. It returns NULL on error, or a newly-allocated |RSA| on
+ * success. This function is provided for compatibility only. The |callback|
+ * and |cb_arg| parameters must be NULL. */
+OPENSSL_EXPORT RSA *RSA_generate_key(int bits, unsigned long e, void *callback,
+ void *cb_arg);
+
+/* d2i_RSAPublicKey parses an ASN.1, DER-encoded, RSA public key from |len|
+ * bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result
+ * is in |*out|. If |*out| is already non-NULL on entry then the result is
+ * written directly into |*out|, otherwise a fresh |RSA| is allocated. On
+ * successful exit, |*inp| is advanced past the DER structure. It returns the
+ * result or NULL on error. */
+OPENSSL_EXPORT RSA *d2i_RSAPublicKey(RSA **out, const uint8_t **inp, long len);
+
+/* i2d_RSAPublicKey marshals |in| to an ASN.1, DER structure. If |outp| is not
+ * NULL then the result is written to |*outp| and |*outp| is advanced just past
+ * the output. It returns the number of bytes in the result, whether written or
+ * not, or a negative value on error. */
+OPENSSL_EXPORT int i2d_RSAPublicKey(const RSA *in, uint8_t **outp);
+
+/* d2i_RSAPrivateKey parses an ASN.1, DER-encoded, RSA private key from |len|
+ * bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result
+ * is in |*out|. If |*out| is already non-NULL on entry then the result is
+ * written directly into |*out|, otherwise a fresh |RSA| is allocated. On
+ * successful exit, |*inp| is advanced past the DER structure. It returns the
+ * result or NULL on error. */
+OPENSSL_EXPORT RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len);
+
+/* i2d_RSAPrivateKey marshals |in| to an ASN.1, DER structure. If |outp| is not
+ * NULL then the result is written to |*outp| and |*outp| is advanced just past
+ * the output. It returns the number of bytes in the result, whether written or
+ * not, or a negative value on error. */
+OPENSSL_EXPORT int i2d_RSAPrivateKey(const RSA *in, uint8_t **outp);
+
+typedef struct rsa_pss_params_st {
+ X509_ALGOR *hashAlgorithm;
+ X509_ALGOR *maskGenAlgorithm;
+ ASN1_INTEGER *saltLength;
+ ASN1_INTEGER *trailerField;
+} RSA_PSS_PARAMS;
+
+DECLARE_ASN1_FUNCTIONS(RSA_PSS_PARAMS)
+
struct rsa_meth_st {
struct openssl_method_common_st common;
@@ -444,12 +525,15 @@ struct rsa_meth_st {
BN_CTX *ctx); /* Can be null */
int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx,
- BN_MONT_CTX *m_ctx);
+ const BN_MONT_CTX *mont);
int flags;
int (*keygen)(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
+ int (*multi_prime_keygen)(RSA *rsa, int bits, int num_primes, BIGNUM *e,
+ BN_GENCB *cb);
+
/* supports_digest returns one if |rsa| supports digests of type
* |md|. If null, it is assumed that all digests are supported. */
int (*supports_digest)(const RSA *rsa, const EVP_MD *md);
@@ -461,8 +545,6 @@ struct rsa_meth_st {
typedef struct bn_blinding_st BN_BLINDING;
struct rsa_st {
- /* version is only used during ASN.1 (de)serialisation. */
- long version;
RSA_METHOD *meth;
BIGNUM *n;
@@ -473,6 +555,9 @@ struct rsa_st {
BIGNUM *dmp1;
BIGNUM *dmq1;
BIGNUM *iqmp;
+
+ STACK_OF(RSA_additional_prime) *additional_primes;
+
/* be careful using this if the RSA structure is shared */
CRYPTO_EX_DATA ex_data;
CRYPTO_refcount_t references;
@@ -482,9 +567,9 @@ struct rsa_st {
/* Used to cache montgomery values. The creation of these values is protected
* by |lock|. */
- BN_MONT_CTX *_method_mod_n;
- BN_MONT_CTX *_method_mod_p;
- BN_MONT_CTX *_method_mod_q;
+ BN_MONT_CTX *mont_n;
+ BN_MONT_CTX *mont_p;
+ BN_MONT_CTX *mont_q;
/* num_blindings contains the size of the |blindings| and |blindings_inuse|
* arrays. This member and the |blindings_inuse| array are protected by
@@ -502,34 +587,6 @@ struct rsa_st {
} /* extern C */
#endif
-#define RSA_F_BN_BLINDING_convert_ex 100
-#define RSA_F_BN_BLINDING_create_param 101
-#define RSA_F_BN_BLINDING_invert_ex 102
-#define RSA_F_BN_BLINDING_new 103
-#define RSA_F_BN_BLINDING_update 104
-#define RSA_F_RSA_check_key 105
-#define RSA_F_RSA_new_method 106
-#define RSA_F_RSA_padding_add_PKCS1_OAEP_mgf1 107
-#define RSA_F_RSA_padding_add_PKCS1_PSS_mgf1 108
-#define RSA_F_RSA_padding_add_PKCS1_type_1 109
-#define RSA_F_RSA_padding_add_PKCS1_type_2 110
-#define RSA_F_RSA_padding_add_none 111
-#define RSA_F_RSA_padding_check_PKCS1_OAEP_mgf1 112
-#define RSA_F_RSA_padding_check_PKCS1_type_1 113
-#define RSA_F_RSA_padding_check_PKCS1_type_2 114
-#define RSA_F_RSA_padding_check_none 115
-#define RSA_F_RSA_recover_crt_params 116
-#define RSA_F_RSA_sign 117
-#define RSA_F_RSA_verify 118
-#define RSA_F_RSA_verify_PKCS1_PSS_mgf1 119
-#define RSA_F_decrypt 120
-#define RSA_F_encrypt 121
-#define RSA_F_keygen 122
-#define RSA_F_pkcs1_prefixed_msg 123
-#define RSA_F_private_transform 124
-#define RSA_F_rsa_setup_blinding 125
-#define RSA_F_sign_raw 126
-#define RSA_F_verify_raw 127
#define RSA_R_BAD_E_VALUE 100
#define RSA_R_BAD_FIXED_HEADER_DECRYPT 101
#define RSA_R_BAD_PAD_BYTE_COUNT 102
@@ -571,5 +628,10 @@ struct rsa_st {
#define RSA_R_UNKNOWN_PADDING_TYPE 138
#define RSA_R_VALUE_MISSING 139
#define RSA_R_WRONG_SIGNATURE_LENGTH 140
+#define RSA_R_MUST_HAVE_AT_LEAST_TWO_PRIMES 141
+#define RSA_R_CANNOT_RECOVER_MULTI_PRIME_KEY 142
+#define RSA_R_BAD_ENCODING 143
+#define RSA_R_ENCODE_ERROR 144
+#define RSA_R_BAD_VERSION 145
#endif /* OPENSSL_HEADER_RSA_H */
diff --git a/src/include/openssl/sha.h b/src/include/openssl/sha.h
index ac2ab75..48a52e8f 100644
--- a/src/include/openssl/sha.h
+++ b/src/include/openssl/sha.h
@@ -98,10 +98,25 @@ 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 {
- uint32_t h0, h1, h2, h3, h4;
+#if defined(OPENSSL_WINDOWS)
+ uint32_t h[5];
+#else
+ /* wpa_supplicant accesses |h0|..|h4| so we must support those names
+ * for compatibility with it until it can be updated. */
+ union {
+ uint32_t h[5];
+ struct {
+ uint32_t h0;
+ uint32_t h1;
+ uint32_t h2;
+ uint32_t h3;
+ uint32_t h4;
+ };
+ };
+#endif
uint32_t Nl, Nh;
- uint32_t data[16];
- unsigned int num;
+ uint8_t data[SHA_CBLOCK];
+ unsigned num;
};
@@ -161,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;
};
@@ -230,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/srtp.h b/src/include/openssl/srtp.h
index 3f5a53e..39f6a85 100644
--- a/src/include/openssl/srtp.h
+++ b/src/include/openssl/srtp.h
@@ -1,178 +1,18 @@
-/* ssl/tls1.h */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
+/* Copyright (c) 2015, Google Inc.
*
- * 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.]
- */
-/* ====================================================================
- * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
+ * 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.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-/*
- DTLS code by Eric Rescorla <ekr@rtfm.com>
-
- Copyright (C) 2006, Network Resonance, Inc.
- Copyright (C) 2011, RTFM, Inc.
-*/
-
-#ifndef OPENSSL_HEADER_SRTP_H
-#define OPENSSL_HEADER_SRTP_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/* Constants for SRTP profiles */
-#define SRTP_AES128_CM_SHA1_80 0x0001
-#define SRTP_AES128_CM_SHA1_32 0x0002
-#define SRTP_AES128_F8_SHA1_80 0x0003
-#define SRTP_AES128_F8_SHA1_32 0x0004
-#define SRTP_NULL_SHA1_80 0x0005
-#define SRTP_NULL_SHA1_32 0x0006
-
-/* 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
- * one on success and zero on failure. */
-OPENSSL_EXPORT int SSL_CTX_set_srtp_profiles(SSL_CTX *ctx,
- const char *profiles);
-
-/* SSL_set_srtp_profiles enables SRTP for |ssl|. |profile| contains a
- * colon-separated list of profile names. It returns one on success and zero on
- * failure. */
-OPENSSL_EXPORT int SSL_set_srtp_profiles(SSL *ctx, const char *profiles);
-
-/* SSL_get_srtp_profiles returns the SRTP profiles supported by |ssl|. */
-OPENSSL_EXPORT STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(
- SSL *ssl);
-
-/* SSL_get_selected_srtp_profile returns the selected SRTP profile, or NULL if
- * SRTP was not negotiated. */
-OPENSSL_EXPORT const SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(
- SSL *s);
-
-
-/* Deprecated functions */
-
-/* SSL_CTX_set_tlsext_use_srtp calls SSL_CTX_set_srtp_profiles. It returns zero
- * on success and one on failure.
- *
- * WARNING: this function is dangerous because it breaks the usual return value
- * convention. Use SSL_CTX_set_srtp_profiles instead. */
-OPENSSL_EXPORT int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx,
- const char *profiles);
-
-/* SSL_set_tlsext_use_srtp calls SSL_set_srtp_profiles. It returns zero on
- * success and one on failure.
- *
- * WARNING: this function is dangerous because it breaks the usual return value
- * convention. Use SSL_set_srtp_profiles instead. */
-OPENSSL_EXPORT int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles);
-
-
-#ifdef __cplusplus
-} /* extern C */
-#endif
+ * 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. */
-#endif /* OPENSSL_HEADER_SRTP_H */
+/* This header is provided in order to make compiling against code that expects
+ OpenSSL easier. */
+#include "ssl.h"
diff --git a/src/include/openssl/ssl.h b/src/include/openssl/ssl.h
index 217dbaf..dcfee91 100644
--- a/src/include/openssl/ssl.h
+++ b/src/include/openssl/ssl.h
@@ -1,4 +1,3 @@
-/* ssl/ssl.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -150,7 +149,9 @@
#include <openssl/hmac.h>
#include <openssl/lhash.h>
#include <openssl/pem.h>
+#include <openssl/ssl3.h>
#include <openssl/thread.h>
+#include <openssl/tls1.h>
#include <openssl/x509.h>
#if !defined(OPENSSL_WINDOWS)
@@ -173,127 +174,338 @@ extern "C" {
/* SSL implementation. */
-/* Initialization. */
+/* SSL contexts.
+ *
+ * |SSL_CTX| objects manage shared state and configuration between multiple TLS
+ * or DTLS connections. Whether the connections are TLS or DTLS is selected by
+ * an |SSL_METHOD| on creation.
+ *
+ * |SSL_CTX| are reference-counted and may be shared by connections across
+ * multiple threads. Once shared, functions which change the |SSL_CTX|'s
+ * configuration may not be used. */
-/* SSL_library_init initializes the crypto and SSL libraries and returns one. */
-OPENSSL_EXPORT int SSL_library_init(void);
+/* TLS_method is the |SSL_METHOD| used for TLS (and SSLv3) connections. */
+OPENSSL_EXPORT const SSL_METHOD *TLS_method(void);
+/* DTLS_method is the |SSL_METHOD| used for DTLS connections. */
+OPENSSL_EXPORT const SSL_METHOD *DTLS_method(void);
-/* Cipher suites. */
+/* SSL_CTX_new returns a newly-allocated |SSL_CTX| with default settings or NULL
+ * on error. */
+OPENSSL_EXPORT SSL_CTX *SSL_CTX_new(const SSL_METHOD *method);
-/* An SSL_CIPHER represents a cipher suite. */
-typedef struct ssl_cipher_st {
- /* name is the OpenSSL name for the cipher. */
- const char *name;
- /* id is the cipher suite value bitwise OR-d with 0x03000000. */
- uint32_t id;
+/* SSL_CTX_free releases memory associated with |ctx|. */
+OPENSSL_EXPORT void SSL_CTX_free(SSL_CTX *ctx);
- /* The following 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;
+/* SSL connections.
+ *
+ * An |SSL| object represents a single TLS or DTLS connection. Although the
+ * shared |SSL_CTX| is thread-safe, an |SSL| is not thread-safe and may only be
+ * used on one thread at a time. */
- /* algorithm2 contains extra flags. See ssl/internal.h. */
- uint32_t algorithm2;
+/* SSL_new returns a newly-allocated |SSL| using |ctx| or NULL on error. The new
+ * connection inherits settings from |ctx| at the time of creation. Settings may
+ * also be individually configured on the connection.
+ *
+ * On creation, an |SSL| is not configured to be either a client or server. Call
+ * |SSL_set_connect_state| or |SSL_set_accept_state| to set this. */
+OPENSSL_EXPORT SSL *SSL_new(SSL_CTX *ctx);
- /* 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;
-} SSL_CIPHER;
+/* SSL_free releases memory associated with |ssl|. */
+OPENSSL_EXPORT void SSL_free(SSL *ssl);
-DECLARE_STACK_OF(SSL_CIPHER)
+/* SSL_get_SSL_CTX returns the |SSL_CTX| associated with |ssl|. If
+ * |SSL_set_SSL_CTX| is called, it returns the new |SSL_CTX|, not the initial
+ * one. */
+OPENSSL_EXPORT SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl);
-/* SSL_get_cipher_by_value returns the structure representing a TLS cipher
- * suite based on its assigned number, or NULL if unknown. See
- * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4. */
-OPENSSL_EXPORT const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value);
+/* SSL_set_connect_state configures |ssl| to be a client. */
+OPENSSL_EXPORT void SSL_set_connect_state(SSL *ssl);
-/* SSL_CIPHER_get_id returns |cipher|'s id. It may be cast to a |uint16_t| to
- * get the cipher suite value. */
-OPENSSL_EXPORT uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *cipher);
+/* SSL_set_accept_state configures |ssl| to be a server. */
+OPENSSL_EXPORT void SSL_set_accept_state(SSL *ssl);
-/* SSL_CIPHER_is_AES returns one if |cipher| uses AES (either GCM or CBC
- * mode). */
-OPENSSL_EXPORT int SSL_CIPHER_is_AES(const SSL_CIPHER *cipher);
+/* SSL_is_server returns one if |ssl| is configured as a server and zero
+ * otherwise. */
+OPENSSL_EXPORT int SSL_is_server(SSL *ssl);
-/* SSL_CIPHER_has_MD5_HMAC returns one if |cipher| uses HMAC-MD5. */
-OPENSSL_EXPORT int SSL_CIPHER_has_MD5_HMAC(const SSL_CIPHER *cipher);
+/* SSL_set_bio configures |ssl| to read from |rbio| and write to |wbio|. |ssl|
+ * takes ownership of the two |BIO|s. If |rbio| and |wbio| are the same, |ssl|
+ * only takes ownership of one reference.
+ *
+ * In DTLS, if |rbio| is blocking, it must handle
+ * |BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT| control requests to set read timeouts.
+ *
+ * Calling this function on an already-configured |ssl| is deprecated. */
+OPENSSL_EXPORT void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio);
-/* SSL_CIPHER_is_AESGCM returns one if |cipher| uses AES-GCM. */
-OPENSSL_EXPORT int SSL_CIPHER_is_AESGCM(const SSL_CIPHER *cipher);
+/* SSL_get_rbio returns the |BIO| that |ssl| reads from. */
+OPENSSL_EXPORT BIO *SSL_get_rbio(const SSL *ssl);
-/* SSL_CIPHER_is_CHACHA20POLY1305 returns one if |cipher| uses
- * CHACHA20_POLY1305. */
-OPENSSL_EXPORT int SSL_CIPHER_is_CHACHA20POLY1305(const SSL_CIPHER *cipher);
+/* SSL_get_wbio returns the |BIO| that |ssl| writes to. */
+OPENSSL_EXPORT BIO *SSL_get_wbio(const SSL *ssl);
-/* SSL_CIPHER_get_name returns the OpenSSL name of |cipher|. */
-OPENSSL_EXPORT const char *SSL_CIPHER_get_name(const SSL_CIPHER *cipher);
+/* SSL_get_fd calls |SSL_get_rfd|. */
+OPENSSL_EXPORT int SSL_get_fd(const SSL *ssl);
-/* SSL_CIPHER_get_kx_name returns a string that describes the key-exchange
- * method used by |cipher|. For example, "ECDHE_ECDSA". */
-OPENSSL_EXPORT const char *SSL_CIPHER_get_kx_name(const SSL_CIPHER *cipher);
+/* SSL_get_rfd returns the file descriptor that |ssl| is configured to read
+ * from. If |ssl|'s read |BIO| is not configured or doesn't wrap a file
+ * descriptor then it returns -1. */
+OPENSSL_EXPORT int SSL_get_rfd(const SSL *ssl);
-/* SSL_CIPHER_get_rfc_name returns a newly-allocated string with the standard
- * name for |cipher| or NULL on error. For example,
- * "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256". The caller is responsible for
- * calling |OPENSSL_free| on the result. */
-OPENSSL_EXPORT char *SSL_CIPHER_get_rfc_name(const SSL_CIPHER *cipher);
+/* SSL_get_wfd returns the file descriptor that |ssl| is configured to write
+ * to. If |ssl|'s write |BIO| is not configured or doesn't wrap a file
+ * descriptor then it returns -1. */
+OPENSSL_EXPORT int SSL_get_wfd(const SSL *ssl);
-/* SSL_CIPHER_get_bits returns the strength, in bits, of |cipher|. If
- * |out_alg_bits| is not NULL, it writes the number of bits consumed by the
- * symmetric algorithm to |*out_alg_bits|. */
-OPENSSL_EXPORT int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher,
- int *out_alg_bits);
+/* SSL_set_fd configures |ssl| to read from and write to |fd|. It returns one
+ * on success and zero on allocation error. The caller retains ownership of
+ * |fd|. */
+OPENSSL_EXPORT int SSL_set_fd(SSL *ssl, int fd);
+/* SSL_set_rfd configures |ssl| to read from |fd|. It returns one on success and
+ * zero on allocation error. The caller retains ownership of |fd|. */
+OPENSSL_EXPORT int SSL_set_rfd(SSL *ssl, int fd);
-/* SSL contexts. */
+/* SSL_set_wfd configures |ssl| to write to |fd|. It returns one on success and
+ * zero on allocation error. The caller retains ownership of |fd|. */
+OPENSSL_EXPORT int SSL_set_wfd(SSL *ssl, int fd);
-/* An SSL_METHOD selects whether to use TLS or DTLS. */
-typedef struct ssl_method_st SSL_METHOD;
+/* SSL_do_handshake continues the current handshake. If there is none or the
+ * handshake has completed or False Started, it returns one. Otherwise, it
+ * returns <= 0. The caller should pass the value into |SSL_get_error| to
+ * determine how to proceed.
+ *
+ * In DTLS, if the read |BIO| is non-blocking, the caller must drive
+ * retransmissions. Whenever |SSL_get_error| signals |SSL_ERROR_WANT_READ|, use
+ * |DTLSv1_get_timeout| to determine the current timeout. If it expires before
+ * the next retry, call |DTLSv1_handle_timeout|. Note that DTLS handshake
+ * retransmissions use fresh sequence numbers, so it is not sufficient to replay
+ * packets at the transport.
+ *
+ * TODO(davidben): Ensure 0 is only returned on transport EOF.
+ * https://crbug.com/466303. */
+OPENSSL_EXPORT int SSL_do_handshake(SSL *ssl);
-/* TLS_method is the |SSL_METHOD| used for TLS (and SSLv3) connections. */
-OPENSSL_EXPORT const SSL_METHOD *TLS_method(void);
+/* SSL_connect configures |ssl| as a client, if unconfigured, and calls
+ * |SSL_do_handshake|. */
+OPENSSL_EXPORT int SSL_connect(SSL *ssl);
-/* DTLS_method is the |SSL_METHOD| used for DTLS connections. */
-OPENSSL_EXPORT const SSL_METHOD *DTLS_method(void);
+/* SSL_accept configures |ssl| as a server, if unconfigured, and calls
+ * |SSL_do_handshake|. */
+OPENSSL_EXPORT int SSL_accept(SSL *ssl);
-/* SSL_CTX_new returns a newly-allocated |SSL_CTX| with default settings or NULL
- * on error. An |SSL_CTX| manages shared state and configuration between
- * multiple TLS or DTLS connections. */
-OPENSSL_EXPORT SSL_CTX *SSL_CTX_new(const SSL_METHOD *method);
+/* SSL_read reads up to |num| bytes from |ssl| into |buf|. It implicitly runs
+ * any pending handshakes, including renegotiations when enabled. On success, it
+ * returns the number of bytes read. Otherwise, it returns <= 0. The caller
+ * should pass the value into |SSL_get_error| to determine how to proceed.
+ *
+ * TODO(davidben): Ensure 0 is only returned on transport EOF.
+ * https://crbug.com/466303. */
+OPENSSL_EXPORT int SSL_read(SSL *ssl, void *buf, int num);
-/* SSL_CTX_free releases memory associated with |ctx|. */
-OPENSSL_EXPORT void SSL_CTX_free(SSL_CTX *ctx);
+/* SSL_peek behaves like |SSL_read| but does not consume any bytes returned. */
+OPENSSL_EXPORT int SSL_peek(SSL *ssl, void *buf, int num);
+/* SSL_pending returns the number of bytes available in |ssl|. It does not read
+ * from the transport. */
+OPENSSL_EXPORT int SSL_pending(const SSL *ssl);
-/* SSL connections. */
+/* SSL_write writes up to |num| bytes from |buf| into |ssl|. It implicitly runs
+ * any pending handshakes, including renegotiations when enabled. On success, it
+ * returns the number of bytes read. Otherwise, it returns <= 0. The caller
+ * should pass the value into |SSL_get_error| to determine how to proceed.
+ *
+ * In TLS, a non-blocking |SSL_write| differs from non-blocking |write| in that
+ * a failed |SSL_write| still commits to the data passed in. When retrying, the
+ * caller must supply the original write buffer (or a larger one containing the
+ * original as a prefix). By default, retries will fail if they also do not
+ * reuse the same |buf| pointer. This may be relaxed with
+ * |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, but the buffer contents still must be
+ * unchanged.
+ *
+ * By default, in TLS, |SSL_write| will not return success until all |num| bytes
+ * are written. This may be relaxed with |SSL_MODE_ENABLE_PARTIAL_WRITE|. It
+ * allows |SSL_write| to complete with a partial result when only part of the
+ * input was written in a single record.
+ *
+ * In DTLS, neither |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| and
+ * |SSL_MODE_ENABLE_PARTIAL_WRITE| do anything. The caller may retry with a
+ * different buffer freely. A single call to |SSL_write| only ever writes a
+ * single record in a single packet, so |num| must be at most
+ * |SSL3_RT_MAX_PLAIN_LENGTH|.
+ *
+ * TODO(davidben): Ensure 0 is only returned on transport EOF.
+ * https://crbug.com/466303. */
+OPENSSL_EXPORT int SSL_write(SSL *ssl, const void *buf, int num);
-/* SSL_new returns a newly-allocated |SSL| using |ctx| or NULL on error. An
- * |SSL| object represents a single TLS or DTLS connection. It inherits settings
- * from |ctx| at the time of creation. Settings may also be individually
- * configured on the connection.
+/* SSL_shutdown shuts down |ssl|. On success, it completes in two stages. First,
+ * it returns 0 if |ssl| completed uni-directional shutdown; close_notify has
+ * been sent, but the peer's close_notify has not been received. Most callers
+ * may stop at this point. For bi-directional shutdown, call |SSL_shutdown|
+ * again. It returns 1 if close_notify has been both sent and received.
*
- * On creation, an |SSL| is not configured to be either a client or server. Call
- * |SSL_set_connect_state| or |SSL_set_accept_state| to set this. */
-OPENSSL_EXPORT SSL *SSL_new(SSL_CTX *ctx);
+ * If the peer's close_notify arrived first, the first stage is skipped.
+ * |SSL_shutdown| will return 1 once close_notify is sent and skip 0. Callers
+ * only interested in uni-directional shutdown must therefore allow for the
+ * first stage returning either 0 or 1.
+ *
+ * |SSL_shutdown| returns -1 on failure. The caller should pass the return value
+ * into |SSL_get_error| to determine how to proceed. If the underlying |BIO| is
+ * non-blocking, both stages may require retry.
+ *
+ * |SSL_shutdown| must be called to retain |ssl|'s session in the session
+ * cache. Use |SSL_CTX_set_quiet_shutdown| to configure |SSL_shutdown| to
+ * neither send nor wait for close_notify but still retain the session.
+ *
+ * TODO(davidben): Is there any point in the session cache interaction? Remove
+ * it? */
+OPENSSL_EXPORT int SSL_shutdown(SSL *ssl);
-/* SSL_free releases memory associated with |ssl|. */
-OPENSSL_EXPORT void SSL_free(SSL *ssl);
+/* SSL_CTX_set_quiet_shutdown sets quiet shutdown on |ctx| to |mode|. If
+ * enabled, |SSL_shutdown| will not send a close_notify alert or wait for one
+ * from the peer. It will instead synchronously return one. */
+OPENSSL_EXPORT void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode);
-/* SSL_set_connect_state configures |ssl| to be a client. */
-OPENSSL_EXPORT void SSL_set_connect_state(SSL *ssl);
+/* SSL_CTX_get_quiet_shutdown returns whether quiet shutdown is enabled for
+ * |ctx|. */
+OPENSSL_EXPORT int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx);
-/* SSL_set_accept_state configures |ssl| to be a server. */
-OPENSSL_EXPORT void SSL_set_accept_state(SSL *ssl);
+/* SSL_set_quiet_shutdown sets quiet shutdown on |ssl| to |mode|. If enabled,
+ * |SSL_shutdown| will not send a close_notify alert or wait for one from the
+ * peer. It will instead synchronously return one. */
+OPENSSL_EXPORT void SSL_set_quiet_shutdown(SSL *ssl, int mode);
+
+/* SSL_get_quiet_shutdown returns whether quiet shutdown is enabled for
+ * |ssl|. */
+OPENSSL_EXPORT int SSL_get_quiet_shutdown(const SSL *ssl);
+
+/* SSL_get_error returns a |SSL_ERROR_*| value for the most recent operation on
+ * |ssl|. It should be called after an operation failed to determine whether the
+ * error was fatal and, if not, when to retry. */
+OPENSSL_EXPORT int SSL_get_error(const SSL *ssl, int ret_code);
+
+/* SSL_ERROR_NONE indicates the operation succeeded. */
+#define SSL_ERROR_NONE 0
+
+/* SSL_ERROR_SSL indicates the operation failed within the library. The caller
+ * may inspect the error queue for more information. */
+#define SSL_ERROR_SSL 1
+
+/* SSL_ERROR_WANT_READ indicates the operation failed attempting to read from
+ * the transport. The caller may retry the operation when the transport is ready
+ * for reading.
+ *
+ * If signaled by a DTLS handshake, the caller must also call
+ * |DTLSv1_get_timeout| and |DTLSv1_handle_timeout| as appropriate. See
+ * |SSL_do_handshake|. */
+#define SSL_ERROR_WANT_READ 2
+
+/* SSL_ERROR_WANT_WRITE indicates the operation failed attempting to write to
+ * the transport. The caller may retry the operation when the transport is ready
+ * for writing. */
+#define SSL_ERROR_WANT_WRITE 3
+
+/* SSL_ERROR_WANT_X509_LOOKUP indicates the operation failed in calling the
+ * |cert_cb| or |client_cert_cb|. The caller may retry the operation when the
+ * callback is ready to return a certificate or one has been configured
+ * externally.
+ *
+ * See also |SSL_CTX_set_cert_cb| and |SSL_CTX_set_client_cert_cb|. */
+#define SSL_ERROR_WANT_X509_LOOKUP 4
+
+/* SSL_ERROR_WANT_SYSCALL indicates the operation failed externally to the
+ * library. The caller should consult the system-specific error mechanism. This
+ * is typically |errno| but may be something custom if using a custom |BIO|. It
+ * may also be signaled if the transport returned EOF, in which case the
+ * operation's return value will be zero. */
+#define SSL_ERROR_SYSCALL 5
+
+/* SSL_ERROR_ZERO_RETURN indicates the operation failed because the connection
+ * was cleanly shut down with a close_notify alert. */
+#define SSL_ERROR_ZERO_RETURN 6
+
+/* SSL_ERROR_WANT_CONNECT indicates the operation failed attempting to connect
+ * the transport (the |BIO| signaled |BIO_RR_CONNECT|). The caller may retry the
+ * operation when the transport is ready. */
+#define SSL_ERROR_WANT_CONNECT 7
+
+/* SSL_ERROR_WANT_ACCEPT indicates the operation failed attempting to accept a
+ * connection from the transport (the |BIO| signaled |BIO_RR_ACCEPT|). The
+ * caller may retry the operation when the transport is ready.
+ *
+ * TODO(davidben): Remove this. It's used by accept BIOs which are bizarre. */
+#define SSL_ERROR_WANT_ACCEPT 8
+
+/* SSL_ERROR_WANT_CHANNEL_ID_LOOKUP indicates the operation failed looking up
+ * the Channel ID key. The caller may retry the operation when |channel_id_cb|
+ * is ready to return a key or one has been configured with
+ * |SSL_set1_tls_channel_id|.
+ *
+ * See also |SSL_CTX_set_channel_id_cb|. */
+#define SSL_ERROR_WANT_CHANNEL_ID_LOOKUP 9
+
+/* SSL_ERROR_PENDING_SESSION indicates the operation failed because the session
+ * lookup callback indicated the session was unavailable. The caller may retry
+ * the operation when lookup has completed.
+ *
+ * See also |SSL_CTX_sess_set_get_cb| and |SSL_magic_pending_session_ptr|. */
+#define SSL_ERROR_PENDING_SESSION 11
+
+/* SSL_ERROR_PENDING_CERTIFICATE indicates the operation failed because the
+ * early callback indicated certificate lookup was incomplete. The caller may
+ * retry the operation when lookup has completed. Note: when the operation is
+ * retried, the early callback will not be called a second time.
+ *
+ * See also |SSL_CTX_set_select_certificate_cb|. */
+#define SSL_ERROR_PENDING_CERTIFICATE 12
+
+/* SSL_ERROR_WANT_PRIVATE_KEY_OPERATION indicates the operation failed because
+ * a private key operation was unfinished. The caller may retry the operation
+ * when the private key operation is complete.
+ *
+ * See also |SSL_set_private_key_method|. */
+#define SSL_ERROR_WANT_PRIVATE_KEY_OPERATION 13
+
+/* SSL_set_mtu sets the |ssl|'s MTU in DTLS to |mtu|. It returns one on success
+ * and zero on failure. */
+OPENSSL_EXPORT int SSL_set_mtu(SSL *ssl, unsigned mtu);
+
+/* DTLSv1_get_timeout queries the next DTLS handshake timeout. If there is a
+ * timeout in progress, it sets |*out| to the time remaining and returns one.
+ * Otherwise, it returns zero.
+ *
+ * When the timeout expires, call |DTLSv1_handle_timeout| to handle the
+ * retransmit behavior.
+ *
+ * NOTE: This function must be queried again whenever the handshake state
+ * machine changes, including when |DTLSv1_handle_timeout| is called. */
+OPENSSL_EXPORT int DTLSv1_get_timeout(const SSL *ssl, struct timeval *out);
+
+/* DTLSv1_handle_timeout is called when a DTLS handshake timeout expires. If no
+ * timeout had expired, it returns 0. Otherwise, it retransmits the previous
+ * flight of handshake messages and returns 1. If too many timeouts had expired
+ * without progress or an error occurs, it returns -1.
+ *
+ * The caller's external timer should be compatible with the one |ssl| queries
+ * within some fudge factor. Otherwise, the call will be a no-op, but
+ * |DTLSv1_get_timeout| will return an updated timeout.
+ *
+ * If the function returns -1, checking if |SSL_get_error| returns
+ * |SSL_ERROR_WANT_WRITE| may be used to determine if the retransmit failed due
+ * to a non-fatal error at the write |BIO|. However, the operation may not be
+ * retried until the next timeout fires.
+ *
+ * WARNING: This function breaks the usual return value convention.
+ *
+ * TODO(davidben): This |SSL_ERROR_WANT_WRITE| behavior is kind of bizarre. */
+OPENSSL_EXPORT int DTLSv1_handle_timeout(SSL *ssl);
/* Protocol versions. */
+#define DTLS1_VERSION_MAJOR 0xfe
#define SSL3_VERSION_MAJOR 0x03
#define SSL3_VERSION 0x0300
@@ -320,66 +532,32 @@ OPENSSL_EXPORT void SSL_set_min_version(SSL *ssl, uint16_t version);
* |version|. */
OPENSSL_EXPORT void SSL_set_max_version(SSL *ssl, uint16_t version);
+/* SSL_version returns the TLS or DTLS protocol version used by |ssl|, which is
+ * one of the |*_VERSION| values. (E.g. |TLS1_2_VERSION|.) Before the version
+ * is negotiated, the result is undefined. */
+OPENSSL_EXPORT int SSL_version(const SSL *ssl);
+
/* Options.
*
* 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
-/* SSL_OP_NO_TICKET disables session ticket support (RFC 4507). */
+/* SSL_OP_NO_TICKET disables session ticket support (RFC 5077). */
#define SSL_OP_NO_TICKET 0x00004000L
-/* SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION permits unsafe legacy renegotiation
- * without renegotiation_info (RFC 5746) support. */
-#define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x00040000L
-
/* SSL_OP_CIPHER_SERVER_PREFERENCE configures servers to select ciphers and
* ECDHE curves according to the server's preferences instead of the
* client's. */
#define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000L
-/* The following flags toggle individual protocol versions. This is deprecated.
- * Use |SSL_CTX_set_min_version| and |SSL_CTX_set_max_version| instead. */
-#define SSL_OP_NO_SSLv3 0x02000000L
-#define SSL_OP_NO_TLSv1 0x04000000L
-#define SSL_OP_NO_TLSv1_2 0x08000000L
-#define SSL_OP_NO_TLSv1_1 0x10000000L
-#define SSL_OP_NO_DTLSv1 SSL_OP_NO_TLSv1
-#define SSL_OP_NO_DTLSv1_2 SSL_OP_NO_TLSv1_2
-
-/* The following flags do nothing and are included only to make it easier to
- * compile code with BoringSSL. */
-#define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0
-#define SSL_OP_MICROSOFT_SESS_ID_BUG 0
-#define SSL_OP_NETSCAPE_CHALLENGE_BUG 0
-#define SSL_OP_NO_COMPRESSION 0
-#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
-#define SSL_OP_NO_SSLv2 0
-#define SSL_OP_SINGLE_DH_USE 0
-#define SSL_OP_SINGLE_ECDH_USE 0
-#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0
-#define SSL_OP_TLS_BLOCK_PADDING_BUG 0
-#define SSL_OP_TLS_ROLLBACK_BUG 0
+/* SSL_OP_DISABLE_NPN configures an individual |SSL| to not advertise NPN,
+ * despite |SSL_CTX_set_next_proto_select_cb| being configured on the
+ * |SSL_CTX|. */
+#define SSL_OP_DISABLE_NPN 0x00800000L
/* SSL_CTX_set_options enables all options set in |options| (which should be one
* or more of the |SSL_OP_*| values, ORed together) in |ctx|. It returns a
@@ -414,14 +592,16 @@ OPENSSL_EXPORT uint32_t SSL_get_options(const SSL *ssl);
*
* Modes configure API behavior. */
-/* SSL_MODE_ENABLE_PARTIAL_WRITE allows |SSL_write| to complete with a partial
- * result when the only part of the input was written in a single record. */
+/* SSL_MODE_ENABLE_PARTIAL_WRITE, in TLS, allows |SSL_write| to complete with a
+ * partial result when the only part of the input was written in a single
+ * record. In DTLS, it does nothing. */
#define SSL_MODE_ENABLE_PARTIAL_WRITE 0x00000001L
-/* SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER allows retrying an incomplete |SSL_write|
- * with a different buffer. However, |SSL_write| still assumes the buffer
- * contents are unchanged. This is not the default to avoid the misconception
- * that non-blocking |SSL_write| behaves like non-blocking |write|. */
+/* SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, in TLS, allows retrying an incomplete
+ * |SSL_write| with a different buffer. However, |SSL_write| still assumes the
+ * buffer contents are unchanged. This is not the default to avoid the
+ * misconception that non-blocking |SSL_write| behaves like non-blocking
+ * |write|. In DTLS, it does nothing. */
#define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002L
/* SSL_MODE_NO_AUTO_CHAIN disables automatically building a certificate chain
@@ -430,14 +610,17 @@ OPENSSL_EXPORT uint32_t SSL_get_options(const SSL *ssl);
#define SSL_MODE_NO_AUTO_CHAIN 0x00000008L
/* SSL_MODE_ENABLE_FALSE_START allows clients to send application data before
- * receipt of CCS and Finished. This mode enables full-handshakes to 'complete'
- * in one RTT. See draft-bmoeller-tls-falsestart-01. */
+ * receipt of ChangeCipherSpec and Finished. This mode enables full-handshakes
+ * to 'complete' in one RTT. See draft-bmoeller-tls-falsestart-01.
+ *
+ * When False Start is enabled, |SSL_do_handshake| may succeed before the
+ * handshake has completely finished. |SSL_write| will function at this point,
+ * and |SSL_read| will transparently wait for the final handshake leg before
+ * returning application data. To determine if False Start occurred or when the
+ * handshake is completely finished, see |SSL_in_false_start|, |SSL_in_init|,
+ * and |SSL_CB_HANDSHAKE_DONE| from |SSL_CTX_set_info_callback|. */
#define SSL_MODE_ENABLE_FALSE_START 0x00000080L
-/* Deprecated: SSL_MODE_HANDSHAKE_CUTTHROUGH is the same as
- * SSL_MODE_ENABLE_FALSE_START. */
-#define SSL_MODE_HANDSHAKE_CUTTHROUGH SSL_MODE_ENABLE_FALSE_START
-
/* SSL_MODE_CBC_RECORD_SPLITTING causes multi-byte CBC records in SSL 3.0 and
* TLS 1.0 to be split in two: the first record will contain a single byte and
* the second will contain the remainder. This effectively randomises the IV and
@@ -451,21 +634,12 @@ OPENSSL_EXPORT uint32_t SSL_get_options(const SSL *ssl);
/* SSL_MODE_SEND_FALLBACK_SCSV sends TLS_FALLBACK_SCSV in the ClientHello.
* To be set only by applications that reconnect with a downgraded protocol
- * version; see https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-05
- * for details.
+ * version; see RFC 7507 for details.
*
* DO NOT ENABLE THIS if your application attempts a normal handshake. Only use
- * this in explicit fallback retries, following the guidance in
- * draft-ietf-tls-downgrade-scsv-05. */
+ * this in explicit fallback retries, following the guidance in RFC 7507. */
#define SSL_MODE_SEND_FALLBACK_SCSV 0x00000400L
-/* The following flags do nothing and are included only to make it easier to
- * compile code with BoringSSL. */
-#define SSL_MODE_AUTO_RETRY 0
-#define SSL_MODE_RELEASE_BUFFERS 0
-#define SSL_MODE_SEND_CLIENTHELLO_TIME 0
-#define SSL_MODE_SEND_SERVERHELLO_TIME 0
-
/* SSL_CTX_set_mode enables all modes set in |mode| (which should be one or more
* of the |SSL_MODE_*| values, ORed together) in |ctx|. It returns a bitmask
* representing the resulting enabled modes. */
@@ -495,8 +669,604 @@ OPENSSL_EXPORT uint32_t SSL_clear_mode(SSL *ssl, uint32_t mode);
OPENSSL_EXPORT uint32_t SSL_get_mode(const SSL *ssl);
+/* Configuring certificates and private keys.
+ *
+ * These functions configure the connection's leaf certificate, private key, and
+ * certificate chain. The certificate chain is ordered leaf to root (as sent on
+ * the wire) but does not include the leaf. Both client and server certificates
+ * use these functions.
+ *
+ * Certificates and keys may be configured before the handshake or dynamically
+ * in the early callback and certificate callback. */
+
+/* SSL_CTX_use_certificate sets |ctx|'s leaf certificate to |x509|. It returns
+ * one on success and zero on failure. */
+OPENSSL_EXPORT int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x509);
+
+/* SSL_use_certificate sets |ssl|'s leaf certificate to |x509|. It returns one
+ * on success and zero on failure. */
+OPENSSL_EXPORT int SSL_use_certificate(SSL *ssl, X509 *x509);
+
+/* SSL_CTX_use_PrivateKey sets |ctx|'s private key to |pkey|. It returns one on
+ * success and zero on failure. */
+OPENSSL_EXPORT int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey);
+
+/* SSL_use_PrivateKey sets |ssl|'s private key to |pkey|. It returns one on
+ * success and zero on failure. */
+OPENSSL_EXPORT int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey);
+
+/* SSL_CTX_set0_chain sets |ctx|'s certificate chain, excluding the leaf, to
+ * |chain|. On success, it returns one and takes ownership of |chain|.
+ * Otherwise, it returns zero. */
+OPENSSL_EXPORT int SSL_CTX_set0_chain(SSL_CTX *ctx, STACK_OF(X509) *chain);
+
+/* SSL_CTX_set1_chain sets |ctx|'s certificate chain, excluding the leaf, to
+ * |chain|. It returns one on success and zero on failure. The caller retains
+ * ownership of |chain| and may release it freely. */
+OPENSSL_EXPORT int SSL_CTX_set1_chain(SSL_CTX *ctx, STACK_OF(X509) *chain);
+
+/* SSL_set0_chain sets |ssl|'s certificate chain, excluding the leaf, to
+ * |chain|. On success, it returns one and takes ownership of |chain|.
+ * Otherwise, it returns zero. */
+OPENSSL_EXPORT int SSL_set0_chain(SSL *ssl, STACK_OF(X509) *chain);
+
+/* SSL_set1_chain sets |ssl|'s certificate chain, excluding the leaf, to
+ * |chain|. It returns one on success and zero on failure. The caller retains
+ * ownership of |chain| and may release it freely. */
+OPENSSL_EXPORT int SSL_set1_chain(SSL *ssl, STACK_OF(X509) *chain);
+
+/* SSL_CTX_add0_chain_cert appends |x509| to |ctx|'s certificate chain. On
+ * success, it returns one and takes ownership of |x509|. Otherwise, it returns
+ * zero. */
+OPENSSL_EXPORT int SSL_CTX_add0_chain_cert(SSL_CTX *ctx, X509 *x509);
+
+/* SSL_CTX_add1_chain_cert appends |x509| to |ctx|'s certificate chain. It
+ * returns one on success and zero on failure. The caller retains ownership of
+ * |x509| and may release it freely. */
+OPENSSL_EXPORT int SSL_CTX_add1_chain_cert(SSL_CTX *ctx, X509 *x509);
+
+/* SSL_add0_chain_cert appends |x509| to |ctx|'s certificate chain. On success,
+ * it returns one and takes ownership of |x509|. Otherwise, it returns zero. */
+OPENSSL_EXPORT int SSL_add0_chain_cert(SSL *ssl, X509 *x509);
+
+/* SSL_CTX_add_extra_chain_cert calls |SSL_CTX_add0_chain_cert|. */
+OPENSSL_EXPORT int SSL_CTX_add_extra_chain_cert(SSL_CTX *ctx, X509 *x509);
+
+/* SSL_add1_chain_cert appends |x509| to |ctx|'s certificate chain. It returns
+ * one on success and zero on failure. The caller retains ownership of |x509|
+ * and may release it freely. */
+OPENSSL_EXPORT int SSL_add1_chain_cert(SSL *ssl, X509 *x509);
+
+/* SSL_CTX_clear_chain_certs clears |ctx|'s certificate chain and returns
+ * one. */
+OPENSSL_EXPORT int SSL_CTX_clear_chain_certs(SSL_CTX *ctx);
+
+/* SSL_CTX_clear_extra_chain_certs calls |SSL_CTX_clear_chain_certs|. */
+OPENSSL_EXPORT int SSL_CTX_clear_extra_chain_certs(SSL_CTX *ctx);
+
+/* SSL_clear_chain_certs clears |ssl|'s certificate chain and returns one. */
+OPENSSL_EXPORT int SSL_clear_chain_certs(SSL *ssl);
+
+/* SSL_CTX_set_cert_cb sets a callback that is called to select a certificate.
+ * The callback returns one on success, zero on internal error, and a negative
+ * number on failure or to pause the handshake. If the handshake is paused,
+ * |SSL_get_error| will return |SSL_ERROR_WANT_X509_LOOKUP|.
+ *
+ * On the client, the callback may call |SSL_get0_certificate_types| and
+ * |SSL_get_client_CA_list| for information on the server's certificate
+ * request. */
+OPENSSL_EXPORT void SSL_CTX_set_cert_cb(SSL_CTX *ctx,
+ int (*cb)(SSL *ssl, void *arg),
+ void *arg);
+
+/* SSL_set_cert_cb sets a callback that is called to select a certificate. The
+ * callback returns one on success, zero on internal error, and a negative
+ * number on failure or to pause the handshake. If the handshake is paused,
+ * |SSL_get_error| will return |SSL_ERROR_WANT_X509_LOOKUP|.
+ *
+ * On the client, the callback may call |SSL_get0_certificate_types| and
+ * |SSL_get_client_CA_list| for information on the server's certificate
+ * request. */
+OPENSSL_EXPORT void SSL_set_cert_cb(SSL *ssl, int (*cb)(SSL *ssl, void *arg),
+ void *arg);
+
+/* SSL_get0_certificate_types, for a client, sets |*out_types| to an array
+ * containing the client certificate types requested by a server. It returns the
+ * length of the array.
+ *
+ * The behavior of this function is undefined except during the callbacks set by
+ * by |SSL_CTX_set_cert_cb| and |SSL_CTX_set_client_cert_cb| or when the
+ * handshake is paused because of them. */
+OPENSSL_EXPORT size_t SSL_get0_certificate_types(SSL *ssl,
+ const uint8_t **out_types);
+
+/* SSL_certs_clear resets the private key, leaf certificate, and certificate
+ * chain of |ssl|. */
+OPENSSL_EXPORT void SSL_certs_clear(SSL *ssl);
+
+/* SSL_CTX_check_private_key returns one if the certificate and private key
+ * configured in |ctx| are consistent and zero otherwise. */
+OPENSSL_EXPORT int SSL_CTX_check_private_key(const SSL_CTX *ctx);
+
+/* SSL_check_private_key returns one if the certificate and private key
+ * configured in |ssl| are consistent and zero otherwise. */
+OPENSSL_EXPORT int SSL_check_private_key(const SSL *ssl);
+
+/* SSL_CTX_get0_certificate returns |ctx|'s leaf certificate. */
+OPENSSL_EXPORT X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx);
+
+/* SSL_get_certificate returns |ssl|'s leaf certificate. */
+OPENSSL_EXPORT X509 *SSL_get_certificate(const SSL *ssl);
+
+/* SSL_CTX_get0_privatekey returns |ctx|'s private key. */
+OPENSSL_EXPORT EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx);
+
+/* SSL_get_privatekey returns |ssl|'s private key. */
+OPENSSL_EXPORT EVP_PKEY *SSL_get_privatekey(const SSL *ssl);
+
+/* SSL_CTX_get0_chain_certs sets |*out_chain| to |ctx|'s certificate chain and
+ * returns one. */
+OPENSSL_EXPORT int SSL_CTX_get0_chain_certs(const SSL_CTX *ctx,
+ STACK_OF(X509) **out_chain);
+
+/* SSL_CTX_get_extra_chain_certs calls |SSL_CTX_get0_chain_certs|. */
+OPENSSL_EXPORT int SSL_CTX_get_extra_chain_certs(const SSL_CTX *ctx,
+ STACK_OF(X509) **out_chain);
+
+/* SSL_get0_chain_certs sets |*out_chain| to |ssl|'s certificate chain and
+ * returns one. */
+OPENSSL_EXPORT int SSL_get0_chain_certs(const SSL *ssl,
+ STACK_OF(X509) **out_chain);
+
+/* SSL_CTX_set_signed_cert_timestamp_list sets the list of signed certificate
+ * timestamps that is sent to clients that request it. The |list| argument must
+ * contain one or more SCT structures serialised as a SignedCertificateTimestamp
+ * List (see https://tools.ietf.org/html/rfc6962#section-3.3) – i.e. each SCT
+ * is prefixed by a big-endian, uint16 length and the concatenation of one or
+ * more such prefixed SCTs are themselves also prefixed by a uint16 length. It
+ * returns one on success and zero on error. The caller retains ownership of
+ * |list|. */
+OPENSSL_EXPORT int SSL_CTX_set_signed_cert_timestamp_list(SSL_CTX *ctx,
+ const uint8_t *list,
+ size_t list_len);
+
+/* SSL_CTX_set_ocsp_response sets the OCSP reponse that is sent to clients
+ * which request it. It returns one on success and zero on error. The caller
+ * retains ownership of |response|. */
+OPENSSL_EXPORT int SSL_CTX_set_ocsp_response(SSL_CTX *ctx,
+ const uint8_t *response,
+ size_t response_len);
+
+/* SSL_set_private_key_digest_prefs copies |num_digests| NIDs from |digest_nids|
+ * into |ssl|. These digests will be used, in decreasing order of preference,
+ * when signing with |ssl|'s private key. It returns one on success and zero on
+ * error. */
+OPENSSL_EXPORT int SSL_set_private_key_digest_prefs(SSL *ssl,
+ const int *digest_nids,
+ size_t num_digests);
+
+
+/* Certificate and private key convenience functions. */
+
+/* SSL_CTX_use_RSAPrivateKey sets |ctx|'s private key to |rsa|. It returns one
+ * on success and zero on failure. */
+OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa);
+
+/* SSL_use_RSAPrivateKey sets |ctx|'s private key to |rsa|. It returns one on
+ * success and zero on failure. */
+OPENSSL_EXPORT int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa);
+
+/* The following functions configure certificates or private keys but take as
+ * input DER-encoded structures. They return one on success and zero on
+ * failure. */
+
+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,
+ size_t der_len);
+
+OPENSSL_EXPORT int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx,
+ const uint8_t *der,
+ size_t der_len);
+OPENSSL_EXPORT int SSL_use_PrivateKey_ASN1(int type, SSL *ssl,
+ const uint8_t *der, size_t der_len);
+
+OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx,
+ const uint8_t *der,
+ size_t der_len);
+OPENSSL_EXPORT int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const uint8_t *der,
+ size_t der_len);
+
+/* The following functions configure certificates or private keys but take as
+ * input files to read from. They return one on success and zero on failure. The
+ * |type| parameter is one of the |SSL_FILETYPE_*| values and determines whether
+ * the file's contents are read as PEM or DER. */
+
+#define SSL_FILETYPE_ASN1 X509_FILETYPE_ASN1
+#define SSL_FILETYPE_PEM X509_FILETYPE_PEM
+
+OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx,
+ const char *file,
+ int type);
+OPENSSL_EXPORT int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file,
+ int type);
+
+OPENSSL_EXPORT int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file,
+ int type);
+OPENSSL_EXPORT int SSL_use_certificate_file(SSL *ssl, const char *file,
+ int type);
+
+OPENSSL_EXPORT int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file,
+ int type);
+OPENSSL_EXPORT int SSL_use_PrivateKey_file(SSL *ssl, const char *file,
+ int type);
+
+/* SSL_CTX_use_certificate_chain_file configures certificates for |ctx|. It
+ * reads the contents of |file| as a PEM-encoded leaf certificate followed
+ * optionally by the certificate chain to send to the peer. It returns one on
+ * success and zero on failure. */
+OPENSSL_EXPORT int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx,
+ const char *file);
+
+/* SSL_CTX_set_default_passwd_cb sets the password callback for PEM-based
+ * convenience functions called on |ctx|. */
+OPENSSL_EXPORT void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx,
+ pem_password_cb *cb);
+
+/* SSL_CTX_set_default_passwd_cb_userdata sets the userdata parameter for
+ * |ctx|'s password callback. */
+OPENSSL_EXPORT void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx,
+ void *data);
+
+
+/* Custom private keys. */
+
+enum ssl_private_key_result_t {
+ ssl_private_key_success,
+ ssl_private_key_retry,
+ ssl_private_key_failure,
+};
+
+/* SSL_PRIVATE_KEY_METHOD describes private key hooks. This is used to off-load
+ * signing operations to a custom, potentially asynchronous, backend. */
+typedef struct ssl_private_key_method_st {
+ /* type returns either |EVP_PKEY_RSA| or |EVP_PKEY_EC| to denote the type of
+ * key used by |ssl|. */
+ int (*type)(SSL *ssl);
+
+ /* max_signature_len returns the maximum length of a signature signed by the
+ * key used by |ssl|. This must be a constant value for a given |ssl|. */
+ size_t (*max_signature_len)(SSL *ssl);
+
+ /* sign signs |in_len| bytes of digest from |in|. |md| is the hash function
+ * used to calculate |in|. On success, it returns |ssl_private_key_success|
+ * and writes at most |max_out| bytes of signature data to |out|. On failure,
+ * it returns |ssl_private_key_failure|. If the operation has not completed,
+ * it returns |ssl_private_key_retry|. |sign| should arrange for the
+ * high-level operation on |ssl| to be retried when the operation is
+ * completed. This will result in a call to |sign_complete|.
+ *
+ * If the key is an RSA key, implementations must use PKCS#1 padding. |in| is
+ * the digest itself, so the DigestInfo prefix, if any, must be prepended by
+ * |sign|. If |md| is |EVP_md5_sha1|, there is no prefix.
+ *
+ * It is an error to call |sign| while another private key operation is in
+ * progress on |ssl|. */
+ enum ssl_private_key_result_t (*sign)(SSL *ssl, uint8_t *out, size_t *out_len,
+ size_t max_out, const EVP_MD *md,
+ const uint8_t *in, size_t in_len);
+
+ /* sign_complete completes a pending |sign| operation. If the operation has
+ * completed, it returns |ssl_private_key_success| and writes the result to
+ * |out| as in |sign|. Otherwise, it returns |ssl_private_key_failure| on
+ * failure and |ssl_private_key_retry| if the operation is still in progress.
+ *
+ * |sign_complete| may be called arbitrarily many times before completion, but
+ * it is an error to call |sign_complete| if there is no pending |sign|
+ * operation in progress on |ssl|. */
+ enum ssl_private_key_result_t (*sign_complete)(SSL *ssl, uint8_t *out,
+ size_t *out_len,
+ size_t max_out);
+
+ /* decrypt decrypts |in_len| bytes of encrypted data from |in|. On success it
+ * returns |ssl_private_key_success|, writes at most |max_out| bytes of
+ * decrypted data to |out| and sets |*out_len| to the actual number of bytes
+ * written. On failure it returns |ssl_private_key_failure|. If the operation
+ * has not completed, it returns |ssl_private_key_retry|. The caller should
+ * arrange for the high-level operation on |ssl| to be retried when the
+ * operation is completed, which will result in a call to |decrypt_complete|.
+ * This function only works with RSA keys and should perform a raw RSA
+ * decryption operation with no padding.
+ *
+ * It is an error to call |decrypt| while another private key operation is in
+ * progress on |ssl|. */
+ enum ssl_private_key_result_t (*decrypt)(SSL *ssl, uint8_t *out,
+ size_t *out_len, size_t max_out,
+ const uint8_t *in, size_t in_len);
+
+ /* decrypt_complete completes a pending |decrypt| operation. If the operation
+ * has completed, it returns |ssl_private_key_success| and writes the result
+ * to |out| as in |decrypt|. Otherwise, it returns |ssl_private_key_failure|
+ * on failure and |ssl_private_key_retry| if the operation is still in
+ * progress.
+ *
+ * |decrypt_complete| may be called arbitrarily many times before completion,
+ * but it is an error to call |decrypt_complete| if there is no pending
+ * |decrypt| operation in progress on |ssl|. */
+ enum ssl_private_key_result_t (*decrypt_complete)(SSL *ssl, uint8_t *out,
+ size_t *out_len,
+ size_t max_out);
+} SSL_PRIVATE_KEY_METHOD;
+
+/* SSL_set_private_key_method configures a custom private key on |ssl|.
+ * |key_method| must remain valid for the lifetime of |ssl|. */
+OPENSSL_EXPORT void SSL_set_private_key_method(
+ SSL *ssl, const SSL_PRIVATE_KEY_METHOD *key_method);
+
+
+/* Cipher suites.
+ *
+ * |SSL_CIPHER| objects represent cipher suites. */
+
+DECLARE_STACK_OF(SSL_CIPHER)
+
+/* SSL_get_cipher_by_value returns the structure representing a TLS cipher
+ * suite based on its assigned number, or NULL if unknown. See
+ * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4. */
+OPENSSL_EXPORT const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value);
+
+/* SSL_CIPHER_get_id returns |cipher|'s id. It may be cast to a |uint16_t| to
+ * get the cipher suite value. */
+OPENSSL_EXPORT uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_is_AES returns one if |cipher| uses AES (either GCM or CBC
+ * mode). */
+OPENSSL_EXPORT int SSL_CIPHER_is_AES(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_has_MD5_HMAC returns one if |cipher| uses HMAC-MD5. */
+OPENSSL_EXPORT int SSL_CIPHER_has_MD5_HMAC(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_has_SHA1_HMAC returns one if |cipher| uses HMAC-SHA1. */
+OPENSSL_EXPORT int SSL_CIPHER_has_SHA1_HMAC(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_is_AESGCM returns one if |cipher| uses AES-GCM. */
+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. 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. */
+OPENSSL_EXPORT int SSL_CIPHER_is_NULL(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_is_RC4 returns one if |cipher| uses RC4. */
+OPENSSL_EXPORT int SSL_CIPHER_is_RC4(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_is_block_cipher returns one if |cipher| is a block cipher. */
+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);
+
+/* SSL_CIPHER_get_name returns the OpenSSL name of |cipher|. */
+OPENSSL_EXPORT const char *SSL_CIPHER_get_name(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_get_kx_name returns a string that describes the key-exchange
+ * method used by |cipher|. For example, "ECDHE_ECDSA". */
+OPENSSL_EXPORT const char *SSL_CIPHER_get_kx_name(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_get_rfc_name returns a newly-allocated string with the standard
+ * name for |cipher| or NULL on error. For example,
+ * "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256". The caller is responsible for
+ * calling |OPENSSL_free| on the result. */
+OPENSSL_EXPORT char *SSL_CIPHER_get_rfc_name(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_get_bits returns the strength, in bits, of |cipher|. If
+ * |out_alg_bits| is not NULL, it writes the number of bits consumed by the
+ * symmetric algorithm to |*out_alg_bits|. */
+OPENSSL_EXPORT int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher,
+ int *out_alg_bits);
+
+
+/* Cipher suite configuration.
+ *
+ * OpenSSL uses a mini-language to configure cipher suites. The language
+ * maintains an ordered list of enabled ciphers, along with an ordered list of
+ * disabled but available ciphers. Initially, all ciphers are disabled with a
+ * default ordering. The cipher string is then interpreted as a sequence of
+ * directives, separated by colons, each of which modifies this state.
+ *
+ * Most directives consist of a one character or empty opcode followed by a
+ * selector which matches a subset of available ciphers.
+ *
+ * Available opcodes are:
+ *
+ * The empty opcode enables and appends all matching disabled ciphers to the
+ * end of the enabled list. The newly appended ciphers are ordered relative to
+ * each other matching their order in the disabled list.
+ *
+ * |-| disables all matching enabled ciphers and prepends them to the disabled
+ * list, with relative order from the enabled list preserved. This means the
+ * most recently disabled ciphers get highest preference relative to other
+ * disabled ciphers if re-enabled.
+ *
+ * |+| moves all matching enabled ciphers to the end of the enabled list, with
+ * relative order preserved.
+ *
+ * |!| deletes all matching ciphers, enabled or not, from either list. Deleted
+ * ciphers will not matched by future operations.
+ *
+ * A selector may be a specific cipher (using the OpenSSL name for the cipher)
+ * or one or more rules separated by |+|. The final selector matches the
+ * intersection of each rule. For instance, |AESGCM+aECDSA| matches
+ * ECDSA-authenticated AES-GCM ciphers.
+ *
+ * Available cipher rules are:
+ *
+ * |ALL| matches all ciphers.
+ *
+ * |kRSA|, |kDHE|, |kECDHE|, and |kPSK| match ciphers using plain RSA, DHE,
+ * ECDHE, and plain PSK key exchanges, respectively. Note that ECDHE_PSK is
+ * matched by |kECDHE| and not |kPSK|.
+ *
+ * |aRSA|, |aECDSA|, and |aPSK| match ciphers authenticated by RSA, ECDSA, and
+ * a pre-shared key, respectively.
+ *
+ * |RSA|, |DHE|, |ECDHE|, |PSK|, |ECDSA|, and |PSK| are aliases for the
+ * corresponding |k*| or |a*| cipher rule. |RSA| is an alias for |kRSA|, not
+ * |aRSA|.
+ *
+ * |3DES|, |RC4|, |AES128|, |AES256|, |AES|, |AESGCM|, |CHACHA20| match
+ * ciphers whose bulk cipher use the corresponding encryption scheme. Note
+ * that |AES|, |AES128|, and |AES256| match both CBC and GCM ciphers.
+ *
+ * |MD5|, |SHA1|, |SHA256|, and |SHA384| match legacy cipher suites using the
+ * corresponding hash function in their MAC. AEADs are matched by none of
+ * these.
+ *
+ * |SHA| is an alias for |SHA1|.
+ *
+ * Although implemented, authentication-only ciphers match no rules and must be
+ * explicitly selected by name.
+ *
+ * Deprecated cipher rules:
+ *
+ * |kEDH|, |EDH|, |kEECDH|, and |EECDH| are legacy aliases for |kDHE|, |DHE|,
+ * |kECDHE|, and |ECDHE|, respectively.
+ *
+ * |MEDIUM| and |HIGH| match RC4-based ciphers and all others, respectively.
+ *
+ * |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
+ * be used.
+ *
+ * Unknown rules silently match nothing.
+ *
+ * The special |@STRENGTH| directive will sort all enabled ciphers by strength.
+ *
+ * The |DEFAULT| directive, when appearing at the front of the string, expands
+ * to the default ordering of available ciphers.
+ *
+ * If configuring a server, one may also configure equal-preference groups to
+ * partially respect the client's preferences when
+ * |SSL_OP_CIPHER_SERVER_PREFERENCE| is enabled. Ciphers in an equal-preference
+ * group have equal priority and use the client order. This may be used to
+ * enforce that AEADs are preferred but select AES-GCM vs. ChaCha20-Poly1305
+ * based on client preferences. An equal-preference is specified with square
+ * brackets, combining multiple selectors separated by |. For example:
+ *
+ * [ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]
+ *
+ * Once an equal-preference group is used, future directives must be
+ * opcode-less. */
+
+/* SSL_DEFAULT_CIPHER_LIST is the default cipher suite configuration. It is
+ * substituted when a cipher string starts with 'DEFAULT'. */
+#define SSL_DEFAULT_CIPHER_LIST "ALL"
+
+/* SSL_CTX_set_cipher_list configures the cipher list for |ctx|, evaluating
+ * |str| as a cipher string. It returns one on success and zero on failure. */
+OPENSSL_EXPORT int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str);
+
+/* SSL_CTX_set_cipher_list_tls10 configures the TLS 1.0+ cipher list for |ctx|,
+ * evaluating |str| as a cipher string. It returns one on success and zero on
+ * failure. If set, servers will use this cipher suite list for TLS 1.0 or
+ * higher. */
+OPENSSL_EXPORT int SSL_CTX_set_cipher_list_tls10(SSL_CTX *ctx, const char *str);
+
+/* SSL_CTX_set_cipher_list_tls11 configures the TLS 1.1+ cipher list for |ctx|,
+ * evaluating |str| as a cipher string. It returns one on success and zero on
+ * failure. If set, servers will use this cipher suite list for TLS 1.1 or
+ * higher. */
+OPENSSL_EXPORT int SSL_CTX_set_cipher_list_tls11(SSL_CTX *ctx, const char *str);
+
+/* SSL_set_cipher_list configures the cipher list for |ssl|, evaluating |str| as
+ * a cipher string. It returns one on success and zero on failure. */
+OPENSSL_EXPORT int SSL_set_cipher_list(SSL *ssl, const char *str);
+
+/* SSL_get_ciphers returns the cipher list for |ssl|, in order of preference. If
+ * |SSL_CTX_set_cipher_list_tls10| or |SSL_CTX_set_cipher_list_tls11| has been
+ * used, the corresponding list for the current version is returned. */
+OPENSSL_EXPORT STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *ssl);
+
+
/* Connection information. */
+/* SSL_is_init_finished returns one if |ssl| has completed its initial handshake
+ * and has no pending handshake. It returns zero otherwise. */
+OPENSSL_EXPORT int SSL_is_init_finished(const SSL *ssl);
+
+/* SSL_in_init returns one if |ssl| has a pending handshake and zero
+ * otherwise. */
+OPENSSL_EXPORT int SSL_in_init(const SSL *ssl);
+
+/* SSL_in_false_start returns one if |ssl| has a pending handshake that is in
+ * False Start. |SSL_write| may be called at this point without waiting for the
+ * peer, but |SSL_read| will complete the handshake before accepting application
+ * data.
+ *
+ * See also |SSL_MODE_ENABLE_FALSE_START|. */
+OPENSSL_EXPORT int SSL_in_false_start(const SSL *ssl);
+
+/* SSL_get_peer_certificate returns the peer's leaf certificate or NULL if the
+ * peer did not use certificates. The caller must call |X509_free| on the
+ * result to release it. */
+OPENSSL_EXPORT X509 *SSL_get_peer_certificate(const SSL *ssl);
+
+/* SSL_get_peer_cert_chain returns the peer's certificate chain or NULL if
+ * unavailable or the peer did not use certificates. This is the unverified
+ * list of certificates as sent by the peer, not the final chain built during
+ * verification. For historical reasons, this value may not be available if
+ * resuming a serialized |SSL_SESSION|. The caller does not take ownership of
+ * the result.
+ *
+ * WARNING: This function behaves differently between client and server. If
+ * |ssl| is a server, the returned chain does not include the leaf certificate.
+ * If a client, it does. */
+OPENSSL_EXPORT STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *ssl);
+
+/* SSL_get0_signed_cert_timestamp_list sets |*out| and |*out_len| to point to
+ * |*out_len| bytes of SCT information from the server. This is only valid if
+ * |ssl| is a client. The SCT information is a SignedCertificateTimestampList
+ * (including the two leading length bytes).
+ * See https://tools.ietf.org/html/rfc6962#section-3.3
+ * If no SCT was received then |*out_len| will be zero on return.
+ *
+ * WARNING: the returned data is not guaranteed to be well formed. */
+OPENSSL_EXPORT void SSL_get0_signed_cert_timestamp_list(const SSL *ssl,
+ const uint8_t **out,
+ size_t *out_len);
+
+/* SSL_get0_ocsp_response sets |*out| and |*out_len| to point to |*out_len|
+ * bytes of an OCSP response from the server. This is the DER encoding of an
+ * OCSPResponse type as defined in RFC 2560.
+ *
+ * WARNING: the returned data is not guaranteed to be well formed. */
+OPENSSL_EXPORT void SSL_get0_ocsp_response(const SSL *ssl, const uint8_t **out,
+ size_t *out_len);
+
/* SSL_get_tls_unique writes at most |max_out| bytes of the tls-unique value
* for |ssl| to |out| and sets |*out_len| to the number of bytes written. It
* returns one on success or zero on error. In general |max_out| should be at
@@ -517,211 +1287,1317 @@ OPENSSL_EXPORT uint32_t SSL_get_mode(const SSL *ssl);
OPENSSL_EXPORT int SSL_get_tls_unique(const SSL *ssl, uint8_t *out,
size_t *out_len, size_t max_out);
+/* SSL_get_extms_support returns one if the Extended Master Secret
+ * extension was negotiated. Otherwise, it returns zero. */
+OPENSSL_EXPORT int SSL_get_extms_support(const SSL *ssl);
-/* Underdocumented functions.
+/* SSL_get_current_cipher returns the cipher used in the current outgoing
+ * connection state, or NULL if the null cipher is active. */
+OPENSSL_EXPORT const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl);
+
+/* SSL_session_reused returns one if |ssl| performed an abbreviated handshake
+ * and zero otherwise.
*
- * Functions below here haven't been touched up and may be underdocumented. */
+ * TODO(davidben): Hammer down the semantics of this API while a handshake,
+ * initial or renego, is in progress. */
+OPENSSL_EXPORT int SSL_session_reused(const SSL *ssl);
-/* SSLeay version number for ASN.1 encoding of the session information */
-/* Version 0 - initial version
- * Version 1 - added the optional peer certificate. */
-#define SSL_SESSION_ASN1_VERSION 0x0001
+/* SSL_get_secure_renegotiation_support returns one if the peer supports secure
+ * renegotiation (RFC 5746) and zero otherwise. */
+OPENSSL_EXPORT int SSL_get_secure_renegotiation_support(const SSL *ssl);
-#define SSL_MAX_SSL_SESSION_ID_LENGTH 32
-#define SSL_MAX_SID_CTX_LENGTH 32
-#define SSL_MAX_MASTER_KEY_LENGTH 48
+/* SSL_export_keying_material exports a value derived from the master secret, as
+ * specified in RFC 5705. It writes |out_len| bytes to |out| given a label and
+ * optional context. (Since a zero length context is allowed, the |use_context|
+ * flag controls whether a context is included.)
+ *
+ * It returns one on success and zero otherwise. */
+OPENSSL_EXPORT int SSL_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);
-/* These are used to specify which ciphers to use and not to use */
-#define SSL_TXT_MEDIUM "MEDIUM"
-#define SSL_TXT_HIGH "HIGH"
-#define SSL_TXT_FIPS "FIPS"
+/* Custom extensions.
+ *
+ * The custom extension functions allow TLS extensions to be added to
+ * ClientHello and ServerHello messages. */
+
+/* SSL_custom_ext_add_cb is a callback function that is called when the
+ * ClientHello (for clients) or ServerHello (for servers) is constructed. In
+ * the case of a server, this callback will only be called for a given
+ * extension if the ClientHello contained that extension – it's not possible to
+ * inject extensions into a ServerHello that the client didn't request.
+ *
+ * When called, |extension_value| will contain the extension number that is
+ * being considered for addition (so that a single callback can handle multiple
+ * extensions). If the callback wishes to include the extension, it must set
+ * |*out| to point to |*out_len| bytes of extension contents and return one. In
+ * this case, the corresponding |SSL_custom_ext_free_cb| callback will later be
+ * called with the value of |*out| once that data has been copied.
+ *
+ * If the callback does not wish to add an extension it must return zero.
+ *
+ * Alternatively, the callback can abort the connection by setting
+ * |*out_alert_value| to a TLS alert number and returning -1. */
+typedef int (*SSL_custom_ext_add_cb)(SSL *ssl, unsigned extension_value,
+ const uint8_t **out, size_t *out_len,
+ int *out_alert_value, void *add_arg);
+
+/* SSL_custom_ext_free_cb is a callback function that is called by OpenSSL iff
+ * an |SSL_custom_ext_add_cb| callback previously returned one. In that case,
+ * this callback is called and passed the |out| pointer that was returned by
+ * the add callback. This is to free any dynamically allocated data created by
+ * the add callback. */
+typedef void (*SSL_custom_ext_free_cb)(SSL *ssl, unsigned extension_value,
+ const uint8_t *out, void *add_arg);
+
+/* SSL_custom_ext_parse_cb is a callback function that is called by OpenSSL to
+ * parse an extension from the peer: that is from the ServerHello for a client
+ * and from the ClientHello for a server.
+ *
+ * When called, |extension_value| will contain the extension number and the
+ * contents of the extension are |contents_len| bytes at |contents|.
+ *
+ * The callback must return one to continue the handshake. Otherwise, if it
+ * returns zero, a fatal alert with value |*out_alert_value| is sent and the
+ * handshake is aborted. */
+typedef int (*SSL_custom_ext_parse_cb)(SSL *ssl, unsigned extension_value,
+ const uint8_t *contents,
+ size_t contents_len,
+ int *out_alert_value, void *parse_arg);
+
+/* SSL_extension_supported returns one iff OpenSSL internally handles
+ * extensions of type |extension_value|. This can be used to avoid registering
+ * custom extension handlers for extensions that a future version of OpenSSL
+ * may handle internally. */
+OPENSSL_EXPORT int SSL_extension_supported(unsigned extension_value);
+
+/* SSL_CTX_add_client_custom_ext registers callback functions for handling
+ * custom TLS extensions for client connections.
+ *
+ * If |add_cb| is NULL then an empty extension will be added in each
+ * ClientHello. Otherwise, see the comment for |SSL_custom_ext_add_cb| about
+ * this callback.
+ *
+ * The |free_cb| may be NULL if |add_cb| doesn't dynamically allocate data that
+ * needs to be freed.
+ *
+ * It returns one on success or zero on error. It's always an error to register
+ * callbacks for the same extension twice, or to register callbacks for an
+ * extension that OpenSSL handles internally. See |SSL_extension_supported| to
+ * discover, at runtime, which extensions OpenSSL handles internally. */
+OPENSSL_EXPORT int SSL_CTX_add_client_custom_ext(
+ SSL_CTX *ctx, unsigned extension_value, SSL_custom_ext_add_cb add_cb,
+ SSL_custom_ext_free_cb free_cb, void *add_arg,
+ SSL_custom_ext_parse_cb parse_cb, void *parse_arg);
+
+/* SSL_CTX_add_server_custom_ext is the same as
+ * |SSL_CTX_add_client_custom_ext|, but for server connections.
+ *
+ * Unlike on the client side, if |add_cb| is NULL no extension will be added.
+ * The |add_cb|, if any, will only be called if the ClientHello contained a
+ * matching extension. */
+OPENSSL_EXPORT int SSL_CTX_add_server_custom_ext(
+ SSL_CTX *ctx, unsigned extension_value, SSL_custom_ext_add_cb add_cb,
+ SSL_custom_ext_free_cb free_cb, void *add_arg,
+ SSL_custom_ext_parse_cb parse_cb, void *parse_arg);
-#define SSL_TXT_kRSA "kRSA"
-#define SSL_TXT_kDHE "kDHE"
-#define SSL_TXT_kEDH "kEDH" /* same as "kDHE" */
-#define SSL_TXT_kECDHE "kECDHE"
-#define SSL_TXT_kEECDH "kEECDH" /* same as "kECDHE" */
-#define SSL_TXT_kPSK "kPSK"
-#define SSL_TXT_aRSA "aRSA"
-#define SSL_TXT_aECDSA "aECDSA"
-#define SSL_TXT_aPSK "aPSK"
+/* Sessions.
+ *
+ * An |SSL_SESSION| represents an SSL session that may be resumed in an
+ * abbreviated handshake. It is reference-counted and immutable. Once
+ * established, an |SSL_SESSION| may be shared by multiple |SSL| objects on
+ * different threads and must not be modified. */
-#define SSL_TXT_DH "DH"
-#define SSL_TXT_DHE "DHE" /* same as "kDHE" */
-#define SSL_TXT_EDH "EDH" /* same as "DHE" */
-#define SSL_TXT_RSA "RSA"
-#define SSL_TXT_ECDH "ECDH"
-#define SSL_TXT_ECDHE "ECDHE" /* same as "kECDHE" */
-#define SSL_TXT_EECDH "EECDH" /* same as "ECDHE" */
-#define SSL_TXT_ECDSA "ECDSA"
-#define SSL_TXT_PSK "PSK"
+DECLARE_LHASH_OF(SSL_SESSION)
+DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
-#define SSL_TXT_3DES "3DES"
-#define SSL_TXT_RC4 "RC4"
-#define SSL_TXT_AES128 "AES128"
-#define SSL_TXT_AES256 "AES256"
-#define SSL_TXT_AES "AES"
-#define SSL_TXT_AES_GCM "AESGCM"
-#define SSL_TXT_CHACHA20 "CHACHA20"
+/* SSL_SESSION_new returns a newly-allocated blank |SSL_SESSION| or NULL on
+ * error. This may be useful in writing tests but otherwise should not be
+ * used outside the library. */
+OPENSSL_EXPORT SSL_SESSION *SSL_SESSION_new(void);
-#define SSL_TXT_MD5 "MD5"
-#define SSL_TXT_SHA1 "SHA1"
-#define SSL_TXT_SHA "SHA" /* same as "SHA1" */
-#define SSL_TXT_SHA256 "SHA256"
-#define SSL_TXT_SHA384 "SHA384"
+/* SSL_SESSION_up_ref, if |session| is not NULL, increments the reference count
+ * of |session|. It then returns |session|. */
+OPENSSL_EXPORT SSL_SESSION *SSL_SESSION_up_ref(SSL_SESSION *session);
-#define SSL_TXT_SSLV3 "SSLv3"
-#define SSL_TXT_TLSV1 "TLSv1"
-#define SSL_TXT_TLSV1_1 "TLSv1.1"
-#define SSL_TXT_TLSV1_2 "TLSv1.2"
+/* SSL_SESSION_free decrements the reference count of |session|. If it reaches
+ * zero, all data referenced by |session| and |session| itself are released. */
+OPENSSL_EXPORT void SSL_SESSION_free(SSL_SESSION *session);
-#define SSL_TXT_ALL "ALL"
+/* SSL_SESSION_to_bytes serializes |in| into a newly allocated buffer and sets
+ * |*out_data| to that buffer and |*out_len| to its length. The caller takes
+ * ownership of the buffer and must call |OPENSSL_free| when done. It returns
+ * one on success and zero on error. */
+OPENSSL_EXPORT int SSL_SESSION_to_bytes(const SSL_SESSION *in,
+ uint8_t **out_data, size_t *out_len);
+
+/* SSL_SESSION_to_bytes_for_ticket serializes |in|, but excludes the session
+ * identification information, namely the session ID and ticket. */
+OPENSSL_EXPORT int SSL_SESSION_to_bytes_for_ticket(const SSL_SESSION *in,
+ uint8_t **out_data,
+ size_t *out_len);
+
+/* SSL_SESSION_from_bytes parses |in_len| bytes from |in| as an SSL_SESSION. It
+ * returns a newly-allocated |SSL_SESSION| on success or NULL on error. */
+OPENSSL_EXPORT SSL_SESSION *SSL_SESSION_from_bytes(const uint8_t *in,
+ size_t in_len);
-/* COMPLEMENTOF* definitions. These identifiers are used to (de-select) ciphers
- * normally not being used.
+/* SSL_SESSION_get_version returns a string describing the TLS version |session|
+ * was established at. For example, "TLSv1.2" or "SSLv3". */
+OPENSSL_EXPORT const char *SSL_SESSION_get_version(const SSL_SESSION *session);
+
+/* SSL_SESSION_get_id returns a pointer to a buffer containg |session|'s session
+ * ID and sets |*out_len| to its length. */
+OPENSSL_EXPORT const uint8_t *SSL_SESSION_get_id(const SSL_SESSION *session,
+ unsigned *out_len);
+
+/* SSL_SESSION_get_time returns the time at which |session| was established in
+ * seconds since the UNIX epoch. */
+OPENSSL_EXPORT long SSL_SESSION_get_time(const SSL_SESSION *session);
+
+/* SSL_SESSION_get_timeout returns the lifetime of |session| in seconds. */
+OPENSSL_EXPORT long SSL_SESSION_get_timeout(const SSL_SESSION *session);
+
+/* SSL_SESSION_get_key_exchange_info returns a value that describes the
+ * strength of the asymmetric operation that provides confidentiality to
+ * |session|. Its interpretation depends on the operation used. See the
+ * documentation for this value in the |SSL_SESSION| structure. */
+OPENSSL_EXPORT uint32_t SSL_SESSION_get_key_exchange_info(
+ const SSL_SESSION *session);
+
+/* SSL_SESSION_get0_peer return's the peer leaf certificate stored in
+ * |session|.
*
- * Example: "RC4" will activate all ciphers using RC4 including ciphers without
- * authentication, which would normally disabled by DEFAULT (due the "!ADH"
- * being part of default). Therefore "RC4:!COMPLEMENTOFDEFAULT" will make sure
- * that it is also disabled in the specific selection. COMPLEMENTOF*
- * identifiers are portable between version, as adjustments to the default
- * cipher setup will also be included here.
+ * TODO(davidben): This should return a const X509 *. */
+OPENSSL_EXPORT X509 *SSL_SESSION_get0_peer(const SSL_SESSION *session);
+
+/* SSL_SESSION_set_time sets |session|'s creation time to |time| and returns
+ * |time|. This function may be useful in writing tests but otherwise should not
+ * be used. */
+OPENSSL_EXPORT long SSL_SESSION_set_time(SSL_SESSION *session, long time);
+
+/* SSL_SESSION_set_timeout sets |session|'s timeout to |timeout| and returns
+ * one. This function may be useful in writing tests but otherwise should not
+ * be used. */
+OPENSSL_EXPORT long SSL_SESSION_set_timeout(SSL_SESSION *session, long timeout);
+
+/* SSL_SESSION_set1_id_context sets |session|'s session ID context (see
+ * |SSL_CTX_set_session_id_context|) to |sid_ctx|. It returns one on success and
+ * zero on error. This function may be useful in writing tests but otherwise
+ * should not be used. */
+OPENSSL_EXPORT int SSL_SESSION_set1_id_context(SSL_SESSION *session,
+ const uint8_t *sid_ctx,
+ unsigned sid_ctx_len);
+
+
+/* Session caching.
*
- * COMPLEMENTOFDEFAULT does not experience the same special treatment that
- * DEFAULT gets, as only selection is being done and no sorting as needed for
- * DEFAULT. */
-#define SSL_TXT_CMPDEF "COMPLEMENTOFDEFAULT"
+ * Session caching allows clients to reconnect to a server based on saved
+ * parameters from a previous connection.
+ *
+ * For a server, the library implements a built-in internal session cache as an
+ * in-memory hash table. One may also register callbacks to implement a custom
+ * external session cache. An external cache may be used in addition to or
+ * instead of the internal one. Use |SSL_CTX_set_session_cache_mode| to toggle
+ * the internal cache.
+ *
+ * For a client, the only option is an external session cache. Prior to
+ * handshaking, the consumer should look up a session externally (keyed, for
+ * instance, by hostname) and use |SSL_set_session| to configure which session
+ * to offer. The callbacks may be used to determine when new sessions are
+ * available.
+ *
+ * Note that offering or accepting a session short-circuits most parameter
+ * negotiation. Resuming sessions across different configurations may result in
+ * surprising behavor. So, for instance, a client implementing a version
+ * fallback should shard its session cache by maximum protocol version. */
-/* The following cipher list is used by default. It also is substituted when an
- * application-defined cipher list string starts with 'DEFAULT'. */
-#define SSL_DEFAULT_CIPHER_LIST "ALL"
+/* SSL_SESS_CACHE_OFF disables all session caching. */
+#define SSL_SESS_CACHE_OFF 0x0000
-/* As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always
- * starts with a reasonable order, and all we have to do for DEFAULT is
- * throwing out anonymous and unencrypted ciphersuites! (The latter are not
- * actually enabled by ALL, but "ALL:RSA" would enable some of them.) */
+/* SSL_SESS_CACHE_CLIENT enables session caching for a client. The internal
+ * cache is never used on a client, so this only enables the callbacks. */
+#define SSL_SESS_CACHE_CLIENT 0x0001
-/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */
-#define SSL_SENT_SHUTDOWN 1
-#define SSL_RECEIVED_SHUTDOWN 2
+/* SSL_SESS_CACHE_SERVER enables session caching for a server. */
+#define SSL_SESS_CACHE_SERVER 0x0002
-#define SSL_FILETYPE_ASN1 X509_FILETYPE_ASN1
-#define SSL_FILETYPE_PEM X509_FILETYPE_PEM
+/* SSL_SESS_CACHE_SERVER enables session caching for both client and server. */
+#define SSL_SESS_CACHE_BOTH (SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_SERVER)
-typedef struct ssl_protocol_method_st SSL_PROTOCOL_METHOD;
-typedef struct ssl_session_st SSL_SESSION;
-typedef struct tls_sigalgs_st TLS_SIGALGS;
-typedef struct ssl_conf_ctx_st SSL_CONF_CTX;
-typedef struct ssl3_enc_method SSL3_ENC_METHOD;
+/* SSL_SESS_CACHE_NO_AUTO_CLEAR disables automatically calling
+ * |SSL_CTX_flush_sessions| every 255 connections. */
+#define SSL_SESS_CACHE_NO_AUTO_CLEAR 0x0080
+
+/* SSL_SESS_CACHE_NO_INTERNAL_LOOKUP, on a server, disables looking up a session
+ * from the internal session cache. */
+#define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP 0x0100
+
+/* SSL_SESS_CACHE_NO_INTERNAL_STORE, on a server, disables storing sessions in
+ * the internal session cache. */
+#define SSL_SESS_CACHE_NO_INTERNAL_STORE 0x0200
-/* SRTP protection profiles for use with the use_srtp extension (RFC 5764). */
-typedef struct srtp_protection_profile_st {
+/* SSL_SESS_CACHE_NO_INTERNAL, on a server, disables the internal session
+ * cache. */
+#define SSL_SESS_CACHE_NO_INTERNAL \
+ (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP | SSL_SESS_CACHE_NO_INTERNAL_STORE)
+
+/* SSL_CTX_set_session_cache_mode sets the session cache mode bits for |ctx| to
+ * |mode|. It returns the previous value. */
+OPENSSL_EXPORT int SSL_CTX_set_session_cache_mode(SSL_CTX *ctx, int mode);
+
+/* SSL_CTX_get_session_cache_mode returns the session cache mode bits for
+ * |ctx| */
+OPENSSL_EXPORT int SSL_CTX_get_session_cache_mode(const SSL_CTX *ctx);
+
+/* SSL_set_session, for a client, configures |ssl| to offer to resume |session|
+ * in the initial handshake and returns one. The caller retains ownership of
+ * |session|. */
+OPENSSL_EXPORT int SSL_set_session(SSL *ssl, SSL_SESSION *session);
+
+/* SSL_get_session returns a non-owning pointer to |ssl|'s session. Prior to the
+ * initial handshake beginning, this is the session to be offered, set by
+ * |SSL_set_session|. After a handshake has finished, this is the currently
+ * active session. Its behavior is undefined while a handshake is progress. */
+OPENSSL_EXPORT SSL_SESSION *SSL_get_session(const SSL *ssl);
+
+/* SSL_get0_session is an alias for |SSL_get_session|. */
+#define SSL_get0_session SSL_get_session
+
+/* SSL_get1_session acts like |SSL_get_session| but returns a new reference to
+ * the session. */
+OPENSSL_EXPORT SSL_SESSION *SSL_get1_session(SSL *ssl);
+
+/* SSL_DEFAULT_SESSION_TIMEOUT is the default lifetime, in seconds, of a
+ * session. */
+#define SSL_DEFAULT_SESSION_TIMEOUT (2 * 60 * 60)
+
+/* SSL_CTX_set_timeout sets the lifetime, in seconds, of sessions created in
+ * |ctx| to |timeout|. */
+OPENSSL_EXPORT long SSL_CTX_set_timeout(SSL_CTX *ctx, long timeout);
+
+/* SSL_CTX_get_timeout returns the lifetime, in seconds, of sessions created in
+ * |ctx|. */
+OPENSSL_EXPORT long SSL_CTX_get_timeout(const SSL_CTX *ctx);
+
+/* SSL_CTX_set_session_id_context sets |ctx|'s session ID context to |sid_ctx|.
+ * It returns one on success and zero on error. The session ID context is an
+ * application-defined opaque byte string. A session will not be used in a
+ * connection without a matching session ID context.
+ *
+ * For a server, if |SSL_VERIFY_PEER| is enabled, it is an error to not set a
+ * session ID context.
+ *
+ * TODO(davidben): Is that check needed? That seems a special case of taking
+ * care not to cross-resume across configuration changes, and this is only
+ * relevant if a server requires client auth. */
+OPENSSL_EXPORT int SSL_CTX_set_session_id_context(SSL_CTX *ctx,
+ const uint8_t *sid_ctx,
+ unsigned sid_ctx_len);
+
+/* SSL_set_session_id_context sets |ssl|'s session ID context to |sid_ctx|. It
+ * returns one on success and zero on error. See also
+ * |SSL_CTX_set_session_id_context|. */
+OPENSSL_EXPORT int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx,
+ unsigned sid_ctx_len);
+
+/* SSL_SESSION_CACHE_MAX_SIZE_DEFAULT is the default maximum size of a session
+ * cache. */
+#define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT (1024 * 20)
+
+/* SSL_CTX_sess_set_cache_size sets the maximum size of |ctx|'s internal session
+ * cache to |size|. It returns the previous value. */
+OPENSSL_EXPORT unsigned long SSL_CTX_sess_set_cache_size(SSL_CTX *ctx,
+ unsigned long size);
+
+/* SSL_CTX_sess_get_cache_size returns the maximum size of |ctx|'s internal
+ * session cache. */
+OPENSSL_EXPORT unsigned long SSL_CTX_sess_get_cache_size(const SSL_CTX *ctx);
+
+/* SSL_CTX_sessions returns |ctx|'s internal session cache. */
+OPENSSL_EXPORT LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx);
+
+/* SSL_CTX_sess_number returns the number of sessions in |ctx|'s internal
+ * session cache. */
+OPENSSL_EXPORT size_t SSL_CTX_sess_number(const SSL_CTX *ctx);
+
+/* SSL_CTX_add_session inserts |session| into |ctx|'s internal session cache. It
+ * returns one on success and zero on error or if |session| is already in the
+ * cache. The caller retains its reference to |session|. */
+OPENSSL_EXPORT int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *session);
+
+/* SSL_CTX_remove_session removes |session| from |ctx|'s internal session cache.
+ * It returns one on success and zero if |session| was not in the cache. */
+OPENSSL_EXPORT int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *session);
+
+/* SSL_CTX_flush_sessions removes all sessions from |ctx| which have expired as
+ * of time |time|. If |time| is zero, all sessions are removed. */
+OPENSSL_EXPORT void SSL_CTX_flush_sessions(SSL_CTX *ctx, long time);
+
+/* SSL_CTX_sess_set_new_cb sets the callback to be called when a new session is
+ * established and ready to be cached. If the session cache is disabled (the
+ * appropriate one of |SSL_SESS_CACHE_CLIENT| or |SSL_SESS_CACHE_SERVER| is
+ * unset), the callback is not called.
+ *
+ * The callback is passed a reference to |session|. It returns one if it takes
+ * ownership and zero otherwise.
+ *
+ * Note: For a client, the callback may be called on abbreviated handshakes if a
+ * ticket is renewed. Further, it may not be called until some time after
+ * |SSL_do_handshake| or |SSL_connect| completes if False Start is enabled. Thus
+ * it's recommended to use this callback over checking |SSL_session_reused| on
+ * handshake completion.
+ *
+ * TODO(davidben): Conditioning callbacks on |SSL_SESS_CACHE_CLIENT| or
+ * |SSL_SESS_CACHE_SERVER| doesn't make any sense when one could just as easily
+ * not supply the callbacks. Removing that condition and the client internal
+ * cache would simplify things. */
+OPENSSL_EXPORT void SSL_CTX_sess_set_new_cb(
+ SSL_CTX *ctx, int (*new_session_cb)(SSL *ssl, SSL_SESSION *session));
+
+/* SSL_CTX_sess_get_new_cb returns the callback set by
+ * |SSL_CTX_sess_set_new_cb|. */
+OPENSSL_EXPORT int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(
+ SSL *ssl, SSL_SESSION *session);
+
+/* SSL_CTX_sess_set_remove_cb sets a callback which is called when a session is
+ * removed from the internal session cache.
+ *
+ * TODO(davidben): What is the point of this callback? It seems useless since it
+ * only fires on sessions in the internal cache. */
+OPENSSL_EXPORT void SSL_CTX_sess_set_remove_cb(
+ SSL_CTX *ctx,
+ void (*remove_session_cb)(SSL_CTX *ctx, SSL_SESSION *session));
+
+/* SSL_CTX_sess_get_remove_cb returns the callback set by
+ * |SSL_CTX_sess_set_remove_cb|. */
+OPENSSL_EXPORT void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(
+ SSL_CTX *ctx, SSL_SESSION *session);
+
+/* SSL_CTX_sess_set_get_cb sets a callback to look up a session by ID for a
+ * server. The callback is passed the session ID and should return a matching
+ * |SSL_SESSION| or NULL if not found. It should set |*out_copy| to zero and
+ * return a new reference to the session. This callback is not used for a
+ * client.
+ *
+ * For historical reasons, if |*out_copy| is set to one (default), the SSL
+ * library will take a new reference to the returned |SSL_SESSION|, expecting
+ * the callback to return a non-owning pointer. This is not recommended. If
+ * |ctx| and thus the callback is used on multiple threads, the session may be
+ * removed and invalidated before the SSL library calls |SSL_SESSION_up_ref|,
+ * whereas the callback may synchronize internally.
+ *
+ * To look up a session asynchronously, the callback may return
+ * |SSL_magic_pending_session_ptr|. See the documentation for that function and
+ * |SSL_ERROR_PENDING_SESSION|.
+ *
+ * If the internal session cache is enabled, the callback is only consulted if
+ * the internal cache does not return a match.
+ *
+ * The callback's |id| parameter is not const for historical reasons, but the
+ * contents may not be modified. */
+OPENSSL_EXPORT void SSL_CTX_sess_set_get_cb(
+ SSL_CTX *ctx,
+ SSL_SESSION *(*get_session_cb)(SSL *ssl, uint8_t *id, int id_len,
+ int *out_copy));
+
+/* SSL_CTX_sess_get_get_cb returns the callback set by
+ * |SSL_CTX_sess_set_get_cb|. */
+OPENSSL_EXPORT SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(
+ SSL *ssl, uint8_t *id, int id_len, int *out_copy);
+
+/* SSL_magic_pending_session_ptr returns a magic |SSL_SESSION|* which indicates
+ * that the session isn't currently unavailable. |SSL_get_error| will then
+ * return |SSL_ERROR_PENDING_SESSION| and the handshake can be retried later
+ * when the lookup has completed. */
+OPENSSL_EXPORT SSL_SESSION *SSL_magic_pending_session_ptr(void);
+
+
+/* Session tickets.
+ *
+ * Session tickets, from RFC 5077, allow session resumption without server-side
+ * state. Session tickets are supported in by default but may be disabled with
+ * |SSL_OP_NO_TICKET|.
+ *
+ * On the client, ticket-based sessions use the same APIs as ID-based tickets.
+ * Callers do not need to handle them differently.
+ *
+ * On the server, tickets are encrypted and authenticated with a secret key. By
+ * default, an |SSL_CTX| generates a key on creation. Tickets are minted and
+ * processed transparently. The following functions may be used to configure a
+ * persistent key or implement more custom behavior. */
+
+/* SSL_CTX_get_tlsext_ticket_keys writes |ctx|'s session ticket key material to
+ * |len| bytes of |out|. It returns one on success and zero if |len| is not
+ * 48. If |out| is NULL, it returns 48 instead. */
+OPENSSL_EXPORT int SSL_CTX_get_tlsext_ticket_keys(SSL_CTX *ctx, void *out,
+ size_t len);
+
+/* SSL_CTX_set_tlsext_ticket_keys sets |ctx|'s session ticket key material to
+ * |len| bytes of |in|. It returns one on success and zero if |len| is not
+ * 48. If |in| is NULL, it returns 48 instead. */
+OPENSSL_EXPORT int SSL_CTX_set_tlsext_ticket_keys(SSL_CTX *ctx, const void *in,
+ size_t len);
+
+/* SSL_TICKET_KEY_NAME_LEN is the length of the key name prefix of a session
+ * ticket. */
+#define SSL_TICKET_KEY_NAME_LEN 16
+
+/* SSL_CTX_set_tlsext_ticket_key_cb sets the ticket callback to |callback| and
+ * returns one. |callback| will be called when encrypting a new ticket and when
+ * decrypting a ticket from the client.
+ *
+ * In both modes, |ctx| and |hmac_ctx| will already have been initialized with
+ * |EVP_CIPHER_CTX_init| and |HMAC_CTX_init|, respectively. |callback|
+ * configures |hmac_ctx| with an HMAC digest and key, and configures |ctx|
+ * for encryption or decryption, based on the mode.
+ *
+ * When encrypting a new ticket, |encrypt| will be one. It writes a public
+ * 16-byte key name to |key_name| and a fresh IV to |iv|. The output IV length
+ * must match |EVP_CIPHER_CTX_iv_length| of the cipher selected. In this mode,
+ * |callback| returns 1 on success and -1 on error.
+ *
+ * When decrypting a ticket, |encrypt| will be zero. |key_name| will point to a
+ * 16-byte key name and |iv| points to an IV. The length of the IV consumed must
+ * match |EVP_CIPHER_CTX_iv_length| of the cipher selected. In this mode,
+ * |callback| returns -1 to abort the handshake, 0 if decrypting the ticket
+ * failed, and 1 or 2 on success. If it returns 2, the ticket will be renewed.
+ * This may be used to re-key the ticket.
+ *
+ * WARNING: |callback| wildly breaks the usual return value convention and is
+ * called in two different modes. */
+OPENSSL_EXPORT int SSL_CTX_set_tlsext_ticket_key_cb(
+ SSL_CTX *ctx, int (*callback)(SSL *ssl, uint8_t *key_name, uint8_t *iv,
+ EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
+ int encrypt));
+
+
+/* Elliptic curve Diffie-Hellman.
+ *
+ * Cipher suites using an ECDHE key exchange perform Diffie-Hellman over an
+ * elliptic curve negotiated by both endpoints. See RFC 4492. Only named curves
+ * are supported. ECDHE is always enabled, but the curve preferences may be
+ * configured with these functions.
+ *
+ * A client may use |SSL_SESSION_get_key_exchange_info| to determine the curve
+ * selected. */
+
+/* SSL_CTX_set1_curves sets the preferred curves for |ctx| to be |curves|. Each
+ * element of |curves| should be a curve nid. It returns one on success and
+ * zero on failure. */
+OPENSSL_EXPORT int SSL_CTX_set1_curves(SSL_CTX *ctx, const int *curves,
+ size_t curves_len);
+
+/* SSL_set1_curves sets the preferred curves for |ssl| to be |curves|. Each
+ * element of |curves| should be a curve nid. It returns one on success and
+ * zero on failure. */
+OPENSSL_EXPORT int SSL_set1_curves(SSL *ssl, const int *curves,
+ size_t curves_len);
+
+/* 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);
+
+
+/* Multiplicative Diffie-Hellman.
+ *
+ * Cipher suites using a DHE key exchange perform Diffie-Hellman over a
+ * multiplicative group selected by the server. These ciphers are disabled for a
+ * server unless a group is chosen with one of these functions.
+ *
+ * A client may use |SSL_SESSION_get_key_exchange_info| to determine the size of
+ * the selected group's prime, but note that servers may select degenerate
+ * groups. */
+
+/* SSL_CTX_set_tmp_dh configures |ctx| to use the group from |dh| as the group
+ * for DHE. Only the group is used, so |dh| needn't have a keypair. It returns
+ * one on success and zero on error. */
+OPENSSL_EXPORT int SSL_CTX_set_tmp_dh(SSL_CTX *ctx, const DH *dh);
+
+/* SSL_set_tmp_dh configures |ssl| to use the group from |dh| as the group for
+ * DHE. Only the group is used, so |dh| needn't have a keypair. It returns one
+ * on success and zero on error. */
+OPENSSL_EXPORT int SSL_set_tmp_dh(SSL *ssl, const DH *dh);
+
+/* SSL_CTX_set_tmp_dh_callback configures |ctx| to use |callback| to determine
+ * the group for DHE ciphers. |callback| should ignore |is_export| and
+ * |keylength| and return a |DH| of the selected group or NULL on error. Only
+ * the parameters are used, so the |DH| needn't have a generated keypair.
+ *
+ * WARNING: The caller does not take ownership of the resulting |DH|, so
+ * |callback| must save and release the object elsewhere. */
+OPENSSL_EXPORT void SSL_CTX_set_tmp_dh_callback(
+ SSL_CTX *ctx, DH *(*callback)(SSL *ssl, int is_export, int keylength));
+
+/* SSL_set_tmp_dh_callback configures |ssl| to use |callback| to determine the
+ * group for DHE ciphers. |callback| should ignore |is_export| and |keylength|
+ * and return a |DH| of the selected group or NULL on error. Only the
+ * parameters are used, so the |DH| needn't have a generated keypair.
+ *
+ * WARNING: The caller does not take ownership of the resulting |DH|, so
+ * |callback| must save and release the object elsewhere. */
+OPENSSL_EXPORT void SSL_set_tmp_dh_callback(SSL *ssl,
+ DH *(*dh)(SSL *ssl, int is_export,
+ int keylength));
+
+
+/* Certificate verification.
+ *
+ * SSL may authenticate either endpoint with an X.509 certificate. Typically
+ * this is used to authenticate the server to the client. These functions
+ * configure certificate verification.
+ *
+ * WARNING: By default, certificate verification errors on a client are not
+ * fatal. See |SSL_VERIFY_NONE| This may be configured with
+ * |SSL_CTX_set_verify|.
+ *
+ * By default clients are anonymous but a server may request a certificate from
+ * the client by setting |SSL_VERIFY_PEER|.
+ *
+ * Many of these functions use OpenSSL's legacy X.509 stack which is
+ * underdocumented and deprecated, but the replacement isn't ready yet. For
+ * now, consumers may use the existing stack or bypass it by performing
+ * certificate verification externally. This may be done with
+ * |SSL_CTX_set_cert_verify_callback| or by extracting the chain with
+ * |SSL_get_peer_cert_chain| after the handshake. In the future, functions will
+ * be added to use the SSL stack without dependency on any part of the legacy
+ * X.509 and ASN.1 stack.
+ *
+ * To augment certificate verification, a client may also enable OCSP stapling
+ * (RFC 6066) and Certificate Transparency (RFC 6962) extensions. */
+
+/* SSL_VERIFY_NONE, on a client, verifies the server certificate but does not
+ * make errors fatal. The result may be checked with |SSL_get_verify_result|. On
+ * a server it does not request a client certificate. This is the default. */
+#define SSL_VERIFY_NONE 0x00
+
+/* SSL_VERIFY_PEER, on a client, makes server certificate errors fatal. On a
+ * server it requests a client certificate and makes errors fatal. However,
+ * anonymous clients are still allowed. See
+ * |SSL_VERIFY_FAIL_IF_NO_PEER_CERT|. */
+#define SSL_VERIFY_PEER 0x01
+
+/* SSL_VERIFY_FAIL_IF_NO_PEER_CERT configures a server to reject connections if
+ * the client declines to send a certificate. Otherwise |SSL_VERIFY_PEER| still
+ * allows anonymous clients. */
+#define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02
+
+/* SSL_VERIFY_PEER_IF_NO_OBC configures a server to request a client certificate
+ * if and only if Channel ID is not negotiated. */
+#define SSL_VERIFY_PEER_IF_NO_OBC 0x04
+
+/* SSL_CTX_set_verify configures certificate verification behavior. |mode| is
+ * one of the |SSL_VERIFY_*| values defined above. |callback|, if not NULL, is
+ * used to customize certificate verification. See the behavior of
+ * |X509_STORE_CTX_set_verify_cb|.
+ *
+ * The callback may use |SSL_get_ex_data_X509_STORE_CTX_idx| with
+ * |X509_STORE_CTX_get_ex_data| to look up the |SSL| from |store_ctx|. */
+OPENSSL_EXPORT void SSL_CTX_set_verify(
+ SSL_CTX *ctx, int mode, int (*callback)(int ok, X509_STORE_CTX *store_ctx));
+
+/* SSL_set_verify configures certificate verification behavior. |mode| is one of
+ * the |SSL_VERIFY_*| values defined above. |callback|, if not NULL, is used to
+ * customize certificate verification. See the behavior of
+ * |X509_STORE_CTX_set_verify_cb|.
+ *
+ * The callback may use |SSL_get_ex_data_X509_STORE_CTX_idx| with
+ * |X509_STORE_CTX_get_ex_data| to look up the |SSL| from |store_ctx|. */
+OPENSSL_EXPORT void SSL_set_verify(SSL *ssl, int mode,
+ int (*callback)(int ok,
+ X509_STORE_CTX *store_ctx));
+
+/* SSL_CTX_get_verify_mode returns |ctx|'s verify mode, set by
+ * |SSL_CTX_set_verify|. */
+OPENSSL_EXPORT int SSL_CTX_get_verify_mode(const SSL_CTX *ctx);
+
+/* SSL_get_verify_mode returns |ssl|'s verify mode, set by |SSL_CTX_set_verify|
+ * or |SSL_set_verify|. */
+OPENSSL_EXPORT int SSL_get_verify_mode(const SSL *ssl);
+
+/* SSL_CTX_get_verify_callback returns the callback set by
+ * |SSL_CTX_set_verify|. */
+OPENSSL_EXPORT int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(
+ int ok, X509_STORE_CTX *store_ctx);
+
+/* SSL_get_verify_callback returns the callback set by |SSL_CTX_set_verify| or
+ * |SSL_set_verify|. */
+OPENSSL_EXPORT int (*SSL_get_verify_callback(const SSL *ssl))(
+ int ok, X509_STORE_CTX *store_ctx);
+
+/* SSL_CTX_set_verify_depth sets the maximum depth of a certificate chain
+ * accepted in verification. This number does not include the leaf, so a depth
+ * of 1 allows the leaf and one CA certificate. */
+OPENSSL_EXPORT void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth);
+
+/* SSL_set_verify_depth sets the maximum depth of a certificate chain accepted
+ * in verification. This number does not include the leaf, so a depth of 1
+ * allows the leaf and one CA certificate. */
+OPENSSL_EXPORT void SSL_set_verify_depth(SSL *ssl, int depth);
+
+/* SSL_CTX_get_verify_depth returns the maximum depth of a certificate accepted
+ * in verification. */
+OPENSSL_EXPORT int SSL_CTX_get_verify_depth(const SSL_CTX *ctx);
+
+/* SSL_get_verify_depth returns the maximum depth of a certificate accepted in
+ * verification. */
+OPENSSL_EXPORT int SSL_get_verify_depth(const SSL *ssl);
+
+/* SSL_CTX_set1_param sets verification parameters from |param|. It returns one
+ * on success and zero on failure. The caller retains ownership of |param|. */
+OPENSSL_EXPORT int SSL_CTX_set1_param(SSL_CTX *ctx,
+ const X509_VERIFY_PARAM *param);
+
+/* SSL_set1_param sets verification parameters from |param|. It returns one on
+ * success and zero on failure. The caller retains ownership of |param|. */
+OPENSSL_EXPORT int SSL_set1_param(SSL *ssl,
+ const X509_VERIFY_PARAM *param);
+
+/* SSL_CTX_get0_param returns |ctx|'s |X509_VERIFY_PARAM| for certificate
+ * verification. The caller must not release the returned pointer but may call
+ * functions on it to configure it. */
+OPENSSL_EXPORT X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx);
+
+/* SSL_get0_param returns |ssl|'s |X509_VERIFY_PARAM| for certificate
+ * verification. The caller must not release the returned pointer but may call
+ * functions on it to configure it. */
+OPENSSL_EXPORT X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl);
+
+/* SSL_CTX_set_purpose sets |ctx|'s |X509_VERIFY_PARAM|'s 'purpose' parameter to
+ * |purpose|. It returns one on success and zero on error. */
+OPENSSL_EXPORT int SSL_CTX_set_purpose(SSL_CTX *ctx, int purpose);
+
+/* SSL_set_purpose sets |ssl|'s |X509_VERIFY_PARAM|'s 'purpose' parameter to
+ * |purpose|. It returns one on success and zero on error. */
+OPENSSL_EXPORT int SSL_set_purpose(SSL *ssl, int purpose);
+
+/* SSL_CTX_set_trust sets |ctx|'s |X509_VERIFY_PARAM|'s 'trust' parameter to
+ * |trust|. It returns one on success and zero on error. */
+OPENSSL_EXPORT int SSL_CTX_set_trust(SSL_CTX *ctx, int trust);
+
+/* SSL_set_trust sets |ssl|'s |X509_VERIFY_PARAM|'s 'trust' parameter to
+ * |trust|. It returns one on success and zero on error. */
+OPENSSL_EXPORT int SSL_set_trust(SSL *ssl, int trust);
+
+/* SSL_CTX_set_cert_store sets |ctx|'s certificate store to |store|. It takes
+ * ownership of |store|. The store is used for certificate verification.
+ *
+ * The store is also used for the auto-chaining feature, but this is deprecated.
+ * See also |SSL_MODE_NO_AUTO_CHAIN|. */
+OPENSSL_EXPORT void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store);
+
+/* SSL_CTX_get_cert_store returns |ctx|'s certificate store. */
+OPENSSL_EXPORT X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx);
+
+/* SSL_CTX_set_default_verify_paths loads the OpenSSL system-default trust
+ * anchors into |ctx|'s store. It returns one on success and zero on failure. */
+OPENSSL_EXPORT int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx);
+
+/* SSL_CTX_load_verify_locations loads trust anchors into |ctx|'s store from
+ * |ca_file| and |ca_dir|, either of which may be NULL. If |ca_file| is passed,
+ * it is opened and PEM-encoded CA certificates are read. If |ca_dir| is passed,
+ * it is treated as a directory in OpenSSL's hashed directory format. It returns
+ * one on success and zero on failure.
+ *
+ * See
+ * https://www.openssl.org/docs/manmaster/ssl/SSL_CTX_load_verify_locations.html
+ * for documentation on the directory format. */
+OPENSSL_EXPORT int SSL_CTX_load_verify_locations(SSL_CTX *ctx,
+ const char *ca_file,
+ const char *ca_dir);
+
+/* SSL_get_verify_result returns the result of certificate verification. It is
+ * either |X509_V_OK| or a |X509_V_ERR_*| value. */
+OPENSSL_EXPORT long SSL_get_verify_result(const SSL *ssl);
+
+/* SSL_set_verify_result overrides the result of certificate verification. */
+OPENSSL_EXPORT void SSL_set_verify_result(SSL *ssl, long result);
+
+/* SSL_get_ex_data_X509_STORE_CTX_idx returns the ex_data index used to look up
+ * the |SSL| associated with an |X509_STORE_CTX| in the verify callback. */
+OPENSSL_EXPORT int SSL_get_ex_data_X509_STORE_CTX_idx(void);
+
+/* SSL_CTX_set_cert_verify_callback sets a custom callback to be called on
+ * certificate verification rather than |X509_verify_cert|. |store_ctx| contains
+ * the verification parameters. The callback should return one on success and
+ * zero on fatal error. It may use |X509_STORE_CTX_set_error| to set a
+ * verification result.
+ *
+ * The callback may use either the |arg| parameter or
+ * |SSL_get_ex_data_X509_STORE_CTX_idx| to recover the associated |SSL|
+ * object. */
+OPENSSL_EXPORT void SSL_CTX_set_cert_verify_callback(
+ SSL_CTX *ctx, int (*callback)(X509_STORE_CTX *store_ctx, void *arg),
+ void *arg);
+
+/* SSL_enable_signed_cert_timestamps causes |ssl| (which must be the client end
+ * of a connection) to request SCTs from the server. See
+ * https://tools.ietf.org/html/rfc6962. It returns one.
+ *
+ * Call |SSL_get0_signed_cert_timestamp_list| to recover the SCT after the
+ * handshake. */
+OPENSSL_EXPORT int SSL_enable_signed_cert_timestamps(SSL *ssl);
+
+/* SSL_CTX_enable_signed_cert_timestamps enables SCT requests on all client SSL
+ * objects created from |ctx|.
+ *
+ * Call |SSL_get0_signed_cert_timestamp_list| to recover the SCT after the
+ * handshake. */
+OPENSSL_EXPORT void SSL_CTX_enable_signed_cert_timestamps(SSL_CTX *ctx);
+
+/* SSL_enable_ocsp_stapling causes |ssl| (which must be the client end of a
+ * connection) to request a stapled OCSP response from the server. It returns
+ * one.
+ *
+ * Call |SSL_get0_ocsp_response| to recover the OCSP response after the
+ * handshake. */
+OPENSSL_EXPORT int SSL_enable_ocsp_stapling(SSL *ssl);
+
+/* SSL_CTX_enable_ocsp_stapling enables OCSP stapling on all client SSL objects
+ * created from |ctx|.
+ *
+ * Call |SSL_get0_ocsp_response| to recover the OCSP response after the
+ * handshake. */
+OPENSSL_EXPORT void SSL_CTX_enable_ocsp_stapling(SSL_CTX *ctx);
+
+
+/* Client certificate CA list.
+ *
+ * When requesting a client certificate, a server may advertise a list of
+ * certificate authorities which are accepted. These functions may be used to
+ * configure this list. */
+
+/* SSL_set_client_CA_list sets |ssl|'s client certificate CA list to
+ * |name_list|. It takes ownership of |name_list|. */
+OPENSSL_EXPORT void SSL_set_client_CA_list(SSL *ssl,
+ STACK_OF(X509_NAME) *name_list);
+
+/* SSL_CTX_set_client_CA_list sets |ctx|'s client certificate CA list to
+ * |name_list|. It takes ownership of |name_list|. */
+OPENSSL_EXPORT void SSL_CTX_set_client_CA_list(SSL_CTX *ctx,
+ STACK_OF(X509_NAME) *name_list);
+
+/* SSL_get_client_CA_list returns |ssl|'s client certificate CA list. If |ssl|
+ * has not been configured as a client, this is the list configured by
+ * |SSL_CTX_set_client_CA_list|.
+ *
+ * If configured as a client, it returns the client certificate CA list sent by
+ * the server. In this mode, the behavior is undefined except during the
+ * callbacks set by |SSL_CTX_set_cert_cb| and |SSL_CTX_set_client_cert_cb| or
+ * when the handshake is paused because of them. */
+OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl);
+
+/* SSL_CTX_get_client_CA_list returns |ctx|'s client certificate CA list. */
+OPENSSL_EXPORT STACK_OF(X509_NAME) *
+ SSL_CTX_get_client_CA_list(const SSL_CTX *ctx);
+
+/* SSL_add_client_CA appends |x509|'s subject to the client certificate CA list.
+ * It returns one on success or zero on error. The caller retains ownership of
+ * |x509|. */
+OPENSSL_EXPORT int SSL_add_client_CA(SSL *ssl, X509 *x509);
+
+/* SSL_CTX_add_client_CA appends |x509|'s subject to the client certificate CA
+ * list. It returns one on success or zero on error. The caller retains
+ * ownership of |x509|. */
+OPENSSL_EXPORT int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x509);
+
+/* SSL_load_client_CA_file opens |file| and reads PEM-encoded certificates from
+ * it. It returns a newly-allocated stack of the certificate subjects or NULL
+ * on error. */
+OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file);
+
+/* SSL_dup_CA_list makes a deep copy of |list|. It returns the new list on
+ * success or NULL on allocation error. */
+OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *list);
+
+/* SSL_add_file_cert_subjects_to_stack behaves like |SSL_load_client_CA_file|
+ * but appends the result to |out|. It returns one on success or zero on
+ * error. */
+OPENSSL_EXPORT int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *out,
+ const char *file);
+
+/* SSL_add_dir_cert_subjects_to_stack lists files in directory |dir|. It calls
+ * |SSL_add_file_cert_subjects_to_stack| on each file and returns one on success
+ * or zero on error. */
+OPENSSL_EXPORT int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *out,
+ const char *dir);
+
+
+/* Server name indication.
+ *
+ * The server_name extension (RFC 3546) allows the client to advertise the name
+ * of the server it is connecting to. This is used in virtual hosting
+ * deployments to select one of a several certificates on a single IP. Only the
+ * host_name name type is supported. */
+
+#define TLSEXT_NAMETYPE_host_name 0
+
+/* SSL_set_tlsext_host_name, for a client, configures |ssl| to advertise |name|
+ * in the server_name extension. It returns one on success and zero on error. */
+OPENSSL_EXPORT int SSL_set_tlsext_host_name(SSL *ssl, const char *name);
+
+/* SSL_get_servername, for a server, returns the hostname supplied by the
+ * client or NULL if there was none. The |type| argument must be
+ * |TLSEXT_NAMETYPE_host_name|. */
+OPENSSL_EXPORT const char *SSL_get_servername(const SSL *ssl, const int type);
+
+/* SSL_get_servername_type, for a server, returns |TLSEXT_NAMETYPE_host_name|
+ * if the client sent a hostname and -1 otherwise. */
+OPENSSL_EXPORT int SSL_get_servername_type(const SSL *ssl);
+
+/* SSL_CTX_set_tlsext_servername_callback configures |callback| to be called on
+ * the server after ClientHello extensions have been parsed and returns one.
+ * The callback may use |SSL_get_servername| to examine the server_name extension
+ * and returns a |SSL_TLSEXT_ERR_*| value. The value of |arg| may be set by
+ * calling |SSL_CTX_set_tlsext_servername_arg|.
+ *
+ * If the callback returns |SSL_TLSEXT_ERR_NOACK|, the server_name extension is
+ * not acknowledged in the ServerHello. If the return value is
+ * |SSL_TLSEXT_ERR_ALERT_FATAL| or |SSL_TLSEXT_ERR_ALERT_WARNING| then
+ * |*out_alert| must be set to the alert value to send. */
+OPENSSL_EXPORT int SSL_CTX_set_tlsext_servername_callback(
+ SSL_CTX *ctx, int (*callback)(SSL *ssl, int *out_alert, void *arg));
+
+/* SSL_CTX_set_tlsext_servername_arg sets the argument to the servername
+ * callback and returns one. See |SSL_CTX_set_tlsext_servername_callback|. */
+OPENSSL_EXPORT int SSL_CTX_set_tlsext_servername_arg(SSL_CTX *ctx, void *arg);
+
+/* SSL_TLSEXT_ERR_* are values returned by some extension-related callbacks. */
+#define SSL_TLSEXT_ERR_OK 0
+#define SSL_TLSEXT_ERR_ALERT_WARNING 1
+#define SSL_TLSEXT_ERR_ALERT_FATAL 2
+#define SSL_TLSEXT_ERR_NOACK 3
+
+
+/* Application-layer protocol negotation.
+ *
+ * The ALPN extension (RFC 7301) allows negotiating different application-layer
+ * protocols over a single port. This is used, for example, to negotiate
+ * HTTP/2. */
+
+/* SSL_CTX_set_alpn_protos sets the client ALPN protocol list on |ctx| to
+ * |protos|. |protos| must be in wire-format (i.e. a series of non-empty, 8-bit
+ * length-prefixed strings). It returns zero on success and one on failure.
+ * Configuring this list enables ALPN on a client.
+ *
+ * WARNING: this function is dangerous because it breaks the usual return value
+ * convention. */
+OPENSSL_EXPORT int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const uint8_t *protos,
+ unsigned protos_len);
+
+/* SSL_set_alpn_protos sets the client ALPN protocol list on |ssl| to |protos|.
+ * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit
+ * length-prefixed strings). It returns zero on success and one on failure.
+ * Configuring this list enables ALPN on a client.
+ *
+ * WARNING: this function is dangerous because it breaks the usual return value
+ * convention. */
+OPENSSL_EXPORT int SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos,
+ unsigned protos_len);
+
+/* SSL_CTX_set_alpn_select_cb sets a callback function on |ctx| that is called
+ * during ClientHello processing in order to select an ALPN protocol from the
+ * client's list of offered protocols. Configuring this callback enables ALPN on
+ * a server.
+ *
+ * The callback is passed a wire-format (i.e. a series of non-empty, 8-bit
+ * length-prefixed strings) ALPN protocol list in |in|. It should set |*out| and
+ * |*out_len| to the selected protocol and return |SSL_TLSEXT_ERR_OK| on
+ * success. It does not pass ownership of the buffer. Otherwise, it should
+ * return |SSL_TLSEXT_ERR_NOACK|. Other |SSL_TLSEXT_ERR_*| values are
+ * unimplemented and will be treated as |SSL_TLSEXT_ERR_NOACK|. */
+OPENSSL_EXPORT void SSL_CTX_set_alpn_select_cb(
+ SSL_CTX *ctx, int (*cb)(SSL *ssl, const uint8_t **out, uint8_t *out_len,
+ const uint8_t *in, unsigned in_len, void *arg),
+ void *arg);
+
+/* SSL_get0_alpn_selected gets the selected ALPN protocol (if any) from |ssl|.
+ * On return it sets |*out_data| to point to |*out_len| bytes of protocol name
+ * (not including the leading length-prefix byte). If the server didn't respond
+ * with a negotiated protocol then |*out_len| will be zero. */
+OPENSSL_EXPORT void SSL_get0_alpn_selected(const SSL *ssl,
+ const uint8_t **out_data,
+ unsigned *out_len);
+
+
+/* Next protocol negotiation.
+ *
+ * The NPN extension (draft-agl-tls-nextprotoneg-03) is the predecessor to ALPN
+ * and deprecated in favor of it. */
+
+/* SSL_CTX_set_next_protos_advertised_cb sets a callback that is called when a
+ * TLS server needs a list of supported protocols for Next Protocol
+ * Negotiation. The returned list must be in wire format. The list is returned
+ * by setting |*out| to point to it and |*out_len| to its length. This memory
+ * will not be modified, but one should assume that |ssl| keeps a reference to
+ * it.
+ *
+ * The callback should return |SSL_TLSEXT_ERR_OK| if it wishes to advertise.
+ * Otherwise, no such extension will be included in the ServerHello. */
+OPENSSL_EXPORT void SSL_CTX_set_next_protos_advertised_cb(
+ SSL_CTX *ctx,
+ int (*cb)(SSL *ssl, const uint8_t **out, unsigned *out_len, void *arg),
+ void *arg);
+
+/* SSL_CTX_set_next_proto_select_cb sets a callback that is called when a client
+ * needs to select a protocol from the server's provided list. |*out| must be
+ * set to point to the selected protocol (which may be within |in|). The length
+ * of the protocol name must be written into |*out_len|. The server's advertised
+ * protocols are provided in |in| and |in_len|. The callback can assume that
+ * |in| is syntactically valid.
+ *
+ * The client must select a protocol. It is fatal to the connection if this
+ * callback returns a value other than |SSL_TLSEXT_ERR_OK|.
+ *
+ * Configuring this callback enables NPN on a client. */
+OPENSSL_EXPORT void SSL_CTX_set_next_proto_select_cb(
+ SSL_CTX *ctx, int (*cb)(SSL *ssl, uint8_t **out, uint8_t *out_len,
+ const uint8_t *in, unsigned in_len, void *arg),
+ void *arg);
+
+/* SSL_get0_next_proto_negotiated sets |*out_data| and |*out_len| to point to
+ * the client's requested protocol for this connection. If the client didn't
+ * request any protocol, then |*out_data| is set to NULL.
+ *
+ * Note that the client can request any protocol it chooses. The value returned
+ * from this function need not be a member of the list of supported protocols
+ * provided by the server. */
+OPENSSL_EXPORT void SSL_get0_next_proto_negotiated(const SSL *ssl,
+ const uint8_t **out_data,
+ unsigned *out_len);
+
+/* SSL_select_next_proto implements the standard protocol selection. It is
+ * expected that this function is called from the callback set by
+ * |SSL_CTX_set_next_proto_select_cb|.
+ *
+ * The protocol data is assumed to be a vector of 8-bit, length prefixed byte
+ * strings. The length byte itself is not included in the length. A byte
+ * string of length 0 is invalid. No byte string may be truncated.
+ *
+ * The current, but experimental algorithm for selecting the protocol is:
+ *
+ * 1) If the server doesn't support NPN then this is indicated to the
+ * callback. In this case, the client application has to abort the connection
+ * or have a default application level protocol.
+ *
+ * 2) If the server supports NPN, but advertises an empty list then the
+ * client selects the first protcol in its list, but indicates via the
+ * API that this fallback case was enacted.
+ *
+ * 3) Otherwise, the client finds the first protocol in the server's list
+ * that it supports and selects this protocol. This is because it's
+ * assumed that the server has better information about which protocol
+ * a client should use.
+ *
+ * 4) If the client doesn't support any of the server's advertised
+ * protocols, then this is treated the same as case 2.
+ *
+ * It returns either |OPENSSL_NPN_NEGOTIATED| if a common protocol was found, or
+ * |OPENSSL_NPN_NO_OVERLAP| if the fallback case was reached. */
+OPENSSL_EXPORT int SSL_select_next_proto(uint8_t **out, uint8_t *out_len,
+ const uint8_t *server,
+ unsigned server_len,
+ const uint8_t *client,
+ unsigned client_len);
+
+#define OPENSSL_NPN_UNSUPPORTED 0
+#define OPENSSL_NPN_NEGOTIATED 1
+#define OPENSSL_NPN_NO_OVERLAP 2
+
+
+/* Channel ID.
+ *
+ * See draft-balfanz-tls-channelid-01. */
+
+/* SSL_CTX_enable_tls_channel_id either configures a TLS server to accept TLS
+ * Channel IDs from clients, or configures a client to send TLS Channel IDs to
+ * a server. It returns one. */
+OPENSSL_EXPORT int SSL_CTX_enable_tls_channel_id(SSL_CTX *ctx);
+
+/* SSL_enable_tls_channel_id either configures a TLS server to accept TLS
+ * Channel IDs from clients, or configures a client to send TLS Channel IDs to
+ * server. It returns one. */
+OPENSSL_EXPORT int SSL_enable_tls_channel_id(SSL *ssl);
+
+/* SSL_CTX_set1_tls_channel_id configures a TLS client to send a TLS Channel ID
+ * to compatible servers. |private_key| must be a P-256 EC key. It returns one
+ * on success and zero on error. */
+OPENSSL_EXPORT int SSL_CTX_set1_tls_channel_id(SSL_CTX *ctx,
+ EVP_PKEY *private_key);
+
+/* SSL_set1_tls_channel_id configures a TLS client to send a TLS Channel ID to
+ * compatible servers. |private_key| must be a P-256 EC key. It returns one on
+ * success and zero on error. */
+OPENSSL_EXPORT int SSL_set1_tls_channel_id(SSL *ssl, EVP_PKEY *private_key);
+
+/* SSL_get_tls_channel_id gets the client's TLS Channel ID from a server |SSL*|
+ * and copies up to the first |max_out| bytes into |out|. The Channel ID
+ * consists of the client's P-256 public key as an (x,y) pair where each is a
+ * 32-byte, big-endian field element. It returns 0 if the client didn't offer a
+ * Channel ID and the length of the complete Channel ID otherwise. */
+OPENSSL_EXPORT size_t SSL_get_tls_channel_id(SSL *ssl, uint8_t *out,
+ size_t max_out);
+
+/* SSL_CTX_set_channel_id_cb sets a callback to be called when a TLS Channel ID
+ * is requested. The callback may set |*out_pkey| to a key, passing a reference
+ * to the caller. If none is returned, the handshake will pause and
+ * |SSL_get_error| will return |SSL_ERROR_WANT_CHANNEL_ID_LOOKUP|.
+ *
+ * See also |SSL_ERROR_WANT_CHANNEL_ID_LOOKUP|. */
+OPENSSL_EXPORT void SSL_CTX_set_channel_id_cb(
+ SSL_CTX *ctx, void (*channel_id_cb)(SSL *ssl, EVP_PKEY **out_pkey));
+
+/* SSL_CTX_get_channel_id_cb returns the callback set by
+ * |SSL_CTX_set_channel_id_cb|. */
+OPENSSL_EXPORT void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))(
+ SSL *ssl, EVP_PKEY **out_pkey);
+
+
+/* DTLS-SRTP.
+ *
+ * See RFC 5764. */
+
+/* An SRTP_PROTECTION_PROFILE is an SRTP profile for use with the use_srtp
+ * extension. */
+struct srtp_protection_profile_st {
const char *name;
unsigned long id;
-} SRTP_PROTECTION_PROFILE;
+} /* SRTP_PROTECTION_PROFILE */;
DECLARE_STACK_OF(SRTP_PROTECTION_PROFILE)
-/* An SSL_SESSION represents an SSL session that may be resumed in an
- * abbreviated handshake. */
-struct ssl_session_st {
- int ssl_version; /* what ssl version session info is being kept in here? */
+/* SRTP_* define constants for SRTP profiles. */
+#define SRTP_AES128_CM_SHA1_80 0x0001
+#define SRTP_AES128_CM_SHA1_32 0x0002
+#define SRTP_AES128_F8_SHA1_80 0x0003
+#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
+ * one on success and zero on failure. */
+OPENSSL_EXPORT int SSL_CTX_set_srtp_profiles(SSL_CTX *ctx,
+ const char *profiles);
+
+/* SSL_set_srtp_profiles enables SRTP for |ssl|. |profile| contains a
+ * colon-separated list of profile names. It returns one on success and zero on
+ * failure. */
+OPENSSL_EXPORT int SSL_set_srtp_profiles(SSL *ssl, const char *profiles);
+
+/* SSL_get_srtp_profiles returns the SRTP profiles supported by |ssl|. */
+OPENSSL_EXPORT STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(
+ SSL *ssl);
+
+/* SSL_get_selected_srtp_profile returns the selected SRTP profile, or NULL if
+ * SRTP was not negotiated. */
+OPENSSL_EXPORT const SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(
+ SSL *ssl);
+
+
+/* Pre-shared keys.
+ *
+ * Connections may be configured with PSK (Pre-Shared Key) cipher suites. These
+ * authenticate using out-of-band pre-shared keys rather than certificates. See
+ * RFC 4279.
+ *
+ * This implementation uses NUL-terminated C strings for identities and identity
+ * hints, so values with a NUL character are not supported. (RFC 4279 does not
+ * specify the format of an identity.) */
- int master_key_length;
- uint8_t master_key[SSL_MAX_MASTER_KEY_LENGTH];
- /* session_id - valid? */
- unsigned int session_id_length;
- uint8_t session_id[SSL_MAX_SSL_SESSION_ID_LENGTH];
- /* this is used to determine whether the session is being reused in
- * the appropriate context. It is up to the application to set this,
- * via SSL_new */
- unsigned int sid_ctx_length;
- uint8_t sid_ctx[SSL_MAX_SID_CTX_LENGTH];
+/* PSK_MAX_IDENTITY_LEN is the maximum supported length of a PSK identity,
+ * excluding the NUL terminator. */
+#define PSK_MAX_IDENTITY_LEN 128
- char *psk_identity;
- /* Used to indicate that session resumption is not allowed. Applications can
- * also set this bit for a new session via not_resumable_session_cb to
- * disable session caching and tickets. */
- int not_resumable;
+/* PSK_MAX_PSK_LEN is the maximum supported length of a pre-shared key. */
+#define PSK_MAX_PSK_LEN 256
- /* The cert is the certificate used to establish this connection */
- struct sess_cert_st /* SESS_CERT */ *sess_cert;
+/* SSL_CTX_set_psk_client_callback sets the callback to be called when PSK is
+ * negotiated on the client. This callback must be set to enable PSK cipher
+ * suites on the client.
+ *
+ * The callback is passed the identity hint in |hint| or NULL if none was
+ * provided. It should select a PSK identity and write the identity and the
+ * corresponding PSK to |identity| and |psk|, respectively. The identity is
+ * written as a NUL-terminated C string of length (excluding the NUL terminator)
+ * at most |max_identity_len|. The PSK's length must be at most |max_psk_len|.
+ * The callback returns the length of the PSK or 0 if no suitable identity was
+ * found. */
+OPENSSL_EXPORT void SSL_CTX_set_psk_client_callback(
+ SSL_CTX *ctx,
+ unsigned (*psk_client_callback)(
+ SSL *ssl, const char *hint, char *identity,
+ unsigned max_identity_len, uint8_t *psk, unsigned max_psk_len));
- /* This is the cert for the other end. On clients, it will be the same as
- * sess_cert->peer_key->x509 (the latter is not enough as sess_cert is not
- * retained in the external representation of sessions, see ssl_asn1.c). */
- X509 *peer;
- /* when app_verify_callback accepts a session where the peer's certificate is
- * not ok, we must remember the error for session reuse: */
- long verify_result; /* only for servers */
+/* SSL_set_psk_client_callback sets the callback to be called when PSK is
+ * negotiated on the client. This callback must be set to enable PSK cipher
+ * suites on the client. See also |SSL_CTX_set_psk_client_callback|. */
+OPENSSL_EXPORT void SSL_set_psk_client_callback(
+ SSL *ssl, unsigned (*psk_client_callback)(SSL *ssl, const char *hint,
+ char *identity,
+ unsigned max_identity_len,
+ uint8_t *psk,
+ unsigned max_psk_len));
+
+/* SSL_CTX_set_psk_server_callback sets the callback to be called when PSK is
+ * negotiated on the server. This callback must be set to enable PSK cipher
+ * suites on the server.
+ *
+ * The callback is passed the identity in |identity|. It should write a PSK of
+ * length at most |max_psk_len| to |psk| and return the number of bytes written
+ * or zero if the PSK identity is unknown. */
+OPENSSL_EXPORT void SSL_CTX_set_psk_server_callback(
+ SSL_CTX *ctx,
+ unsigned (*psk_server_callback)(SSL *ssl, const char *identity,
+ uint8_t *psk,
+ unsigned max_psk_len));
- CRYPTO_refcount_t references;
- long timeout;
- long time;
+/* SSL_set_psk_server_callback sets the callback to be called when PSK is
+ * negotiated on the server. This callback must be set to enable PSK cipher
+ * suites on the server. See also |SSL_CTX_set_psk_server_callback|. */
+OPENSSL_EXPORT void SSL_set_psk_server_callback(
+ SSL *ssl,
+ unsigned (*psk_server_callback)(SSL *ssl, const char *identity,
+ uint8_t *psk,
+ unsigned max_psk_len));
- const SSL_CIPHER *cipher;
+/* SSL_CTX_use_psk_identity_hint configures server connections to advertise an
+ * identity hint of |identity_hint|. It returns one on success and zero on
+ * error. */
+OPENSSL_EXPORT int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx,
+ const char *identity_hint);
- CRYPTO_EX_DATA ex_data; /* application specific data */
+/* SSL_use_psk_identity_hint configures server connections to advertise an
+ * identity hint of |identity_hint|. It returns one on success and zero on
+ * error. */
+OPENSSL_EXPORT int SSL_use_psk_identity_hint(SSL *ssl,
+ const char *identity_hint);
- /* These are used to make removal of session-ids more efficient and to
- * implement a maximum cache size. */
- SSL_SESSION *prev, *next;
- char *tlsext_hostname;
- /* RFC4507 info */
- uint8_t *tlsext_tick; /* Session ticket */
- size_t tlsext_ticklen; /* Session ticket length */
- uint32_t tlsext_tick_lifetime_hint; /* Session lifetime hint in seconds */
+/* SSL_get_psk_identity_hint returns the PSK identity hint advertised for |ssl|
+ * or NULL if there is none. */
+OPENSSL_EXPORT const char *SSL_get_psk_identity_hint(const SSL *ssl);
- size_t tlsext_signed_cert_timestamp_list_length;
- uint8_t *tlsext_signed_cert_timestamp_list; /* Server's list. */
+/* SSL_get_psk_identity, after the handshake completes, returns the PSK identity
+ * that was negotiated by |ssl| or NULL if PSK was not used. */
+OPENSSL_EXPORT const char *SSL_get_psk_identity(const SSL *ssl);
- /* The OCSP response that came with the session. */
- size_t ocsp_response_length;
- uint8_t *ocsp_response;
- char peer_sha256_valid; /* Non-zero if peer_sha256 is valid */
- uint8_t
- peer_sha256[SHA256_DIGEST_LENGTH]; /* SHA256 of peer certificate */
+/* Alerts.
+ *
+ * TLS and SSL 3.0 use alerts to signal error conditions. Alerts have a type
+ * (warning or fatal) and description. OpenSSL internally handles fatal alerts
+ * with dedicated error codes (see |SSL_AD_REASON_OFFSET|). Except for
+ * close_notify, warning alerts are silently ignored and may only be surfaced
+ * with |SSL_CTX_set_info_callback|. */
+
+/* SSL_AD_REASON_OFFSET is the offset between error reasons and |SSL_AD_*|
+ * values. Any error code under |ERR_LIB_SSL| with an error reason above this
+ * value corresponds to an alert description. Consumers may add or subtract
+ * |SSL_AD_REASON_OFFSET| to convert between them.
+ *
+ * make_errors.go reserves error codes above 1000 for manually-assigned errors.
+ * This value must be kept in sync with reservedReasonCode in make_errors.h */
+#define SSL_AD_REASON_OFFSET 1000
- /* original_handshake_hash contains the handshake hash (either SHA-1+MD5 or
- * SHA-2, depending on TLS version) for the original, full handshake that
- * created a session. This is used by Channel IDs during resumption. */
- uint8_t original_handshake_hash[EVP_MAX_MD_SIZE];
- unsigned int original_handshake_hash_len;
+/* SSL_AD_* are alert descriptions for SSL 3.0 and TLS. */
+#define SSL_AD_CLOSE_NOTIFY SSL3_AD_CLOSE_NOTIFY
+#define SSL_AD_UNEXPECTED_MESSAGE SSL3_AD_UNEXPECTED_MESSAGE
+#define SSL_AD_BAD_RECORD_MAC SSL3_AD_BAD_RECORD_MAC
+#define SSL_AD_DECRYPTION_FAILED TLS1_AD_DECRYPTION_FAILED
+#define SSL_AD_RECORD_OVERFLOW TLS1_AD_RECORD_OVERFLOW
+#define SSL_AD_DECOMPRESSION_FAILURE SSL3_AD_DECOMPRESSION_FAILURE
+#define SSL_AD_HANDSHAKE_FAILURE SSL3_AD_HANDSHAKE_FAILURE
+#define SSL_AD_NO_CERTIFICATE SSL3_AD_NO_CERTIFICATE /* Not used in TLS */
+#define SSL_AD_BAD_CERTIFICATE SSL3_AD_BAD_CERTIFICATE
+#define SSL_AD_UNSUPPORTED_CERTIFICATE SSL3_AD_UNSUPPORTED_CERTIFICATE
+#define SSL_AD_CERTIFICATE_REVOKED SSL3_AD_CERTIFICATE_REVOKED
+#define SSL_AD_CERTIFICATE_EXPIRED SSL3_AD_CERTIFICATE_EXPIRED
+#define SSL_AD_CERTIFICATE_UNKNOWN SSL3_AD_CERTIFICATE_UNKNOWN
+#define SSL_AD_ILLEGAL_PARAMETER SSL3_AD_ILLEGAL_PARAMETER
+#define SSL_AD_UNKNOWN_CA TLS1_AD_UNKNOWN_CA
+#define SSL_AD_ACCESS_DENIED TLS1_AD_ACCESS_DENIED
+#define SSL_AD_DECODE_ERROR TLS1_AD_DECODE_ERROR
+#define SSL_AD_DECRYPT_ERROR TLS1_AD_DECRYPT_ERROR
+#define SSL_AD_EXPORT_RESTRICTION TLS1_AD_EXPORT_RESTRICTION
+#define SSL_AD_PROTOCOL_VERSION TLS1_AD_PROTOCOL_VERSION
+#define SSL_AD_INSUFFICIENT_SECURITY TLS1_AD_INSUFFICIENT_SECURITY
+#define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR
+#define SSL_AD_USER_CANCELLED TLS1_AD_USER_CANCELLED
+#define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION
+#define SSL_AD_UNSUPPORTED_EXTENSION TLS1_AD_UNSUPPORTED_EXTENSION
+#define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE
+#define SSL_AD_UNRECOGNIZED_NAME TLS1_AD_UNRECOGNIZED_NAME
+#define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE \
+ TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
+#define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
+#define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY
+#define SSL_AD_INAPPROPRIATE_FALLBACK SSL3_AD_INAPPROPRIATE_FALLBACK
- /* extended_master_secret is true if the master secret in this session was
- * generated using EMS and thus isn't vulnerable to the Triple Handshake
- * attack. */
- char extended_master_secret;
-};
+/* SSL_alert_type_string_long returns a string description of |value| as an
+ * alert type (warning or fatal). */
+OPENSSL_EXPORT const char *SSL_alert_type_string_long(int value);
+/* SSL_alert_desc_string_long returns a string description of |value| as an
+ * alert description or "unknown" if unknown. */
+OPENSSL_EXPORT const char *SSL_alert_desc_string_long(int value);
-/* Cert related flags */
-/* Many implementations ignore some aspects of the TLS standards such as
- * enforcing certifcate chain algorithms. When this is set we enforce them. */
-#define SSL_CERT_FLAG_TLS_STRICT 0x00000001L
-/* Flags for building certificate chains */
-/* Treat any existing certificates as untrusted CAs */
-#define SSL_BUILD_CHAIN_FLAG_UNTRUSTED 0x1
-/* Don't include root CA in chain */
-#define SSL_BUILD_CHAIN_FLAG_NO_ROOT 0x2
-/* Just check certificates already there */
-#define SSL_BUILD_CHAIN_FLAG_CHECK 0x4
-/* Ignore verification errors */
-#define SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR 0x8
-/* Clear verification errors from queue */
-#define SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR 0x10
+/* ex_data functions.
+ *
+ * See |ex_data.h| for details. */
-/* SSL_set_mtu sets the |ssl|'s MTU in DTLS to |mtu|. It returns one on success
- * and zero on failure. */
-OPENSSL_EXPORT int SSL_set_mtu(SSL *ssl, unsigned mtu);
+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_unused *unused,
+ CRYPTO_EX_dup *dup_func,
+ CRYPTO_EX_free *free_func);
-/* SSL_get_secure_renegotiation_support returns one if the peer supports secure
- * renegotiation (RFC 5746) and zero otherwise. */
-OPENSSL_EXPORT int SSL_get_secure_renegotiation_support(const SSL *ssl);
+OPENSSL_EXPORT int SSL_SESSION_set_ex_data(SSL_SESSION *session, int idx,
+ void *data);
+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_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_unused *unused,
+ CRYPTO_EX_dup *dup_func,
+ CRYPTO_EX_free *free_func);
+
+
+/* Obscure functions. */
+
+/* SSL_get_rc4_state sets |*read_key| and |*write_key| to the RC4 states for
+ * the read and write directions. It returns one on success or zero if |ssl|
+ * isn't using an RC4-based cipher suite. */
+OPENSSL_EXPORT int SSL_get_rc4_state(const SSL *ssl, const RC4_KEY **read_key,
+ const RC4_KEY **write_key);
+
+/* SSL_get_ivs sets |*out_iv_len| to the length of the IVs for the ciphers
+ * underlying |ssl| and sets |*out_read_iv| and |*out_write_iv| to point to the
+ * current IVs for the read and write directions. This is only meaningful for
+ * connections with implicit IVs (i.e. CBC mode with SSLv3 or TLS 1.0).
+ *
+ * It returns one on success or zero on error. */
+OPENSSL_EXPORT int SSL_get_ivs(const SSL *ssl, const uint8_t **out_read_iv,
+ const uint8_t **out_write_iv,
+ size_t *out_iv_len);
+
+/* SSL_get_structure_sizes returns the sizes of the SSL, SSL_CTX and
+ * SSL_SESSION structures so that a test can ensure that outside code agrees on
+ * these values. */
+OPENSSL_EXPORT void SSL_get_structure_sizes(size_t *ssl_size,
+ size_t *ssl_ctx_size,
+ size_t *ssl_session_size);
/* SSL_CTX_set_msg_callback installs |cb| as the message callback for |ctx|.
* This callback will be called when sending or receiving low-level record
@@ -754,39 +2630,81 @@ 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,
+ ssl_renegotiate_once,
+ ssl_renegotiate_freely,
+ ssl_renegotiate_ignore,
+};
+/* SSL_set_renegotiate_mode configures how |ssl|, a client, reacts to
+ * renegotiation attempts by a server. If |ssl| is a server, peer-initiated
+ * renegotiations are *always* rejected and this function does nothing.
+ *
+ * The renegotiation mode defaults to |ssl_renegotiate_never|, but may be set
+ * at any point in a connection's lifetime. Set it to |ssl_renegotiate_once| to
+ * allow one renegotiation, |ssl_renegotiate_freely| to allow all
+ * renegotiations or |ssl_renegotiate_ignore| to ignore HelloRequest messages.
+ * Note that ignoring HelloRequest messages may cause the connection to stall
+ * if the server waits for the renegotiation to complete.
+ *
+ * There is no support in BoringSSL for initiating renegotiations as a client
+ * or server. */
+OPENSSL_EXPORT void SSL_set_renegotiate_mode(SSL *ssl,
+ enum ssl_renegotiate_mode_t mode);
-struct ssl_aead_ctx_st;
-typedef struct ssl_aead_ctx_st SSL_AEAD_CTX;
+/* SSL_renegotiate_pending returns one if |ssl| is in the middle of a
+ * renegotiation. */
+OPENSSL_EXPORT int SSL_renegotiate_pending(SSL *ssl);
-#define SSL_MAX_CERT_LIST_DEFAULT 1024 * 100 /* 100k max cert list */
+/* SSL_total_renegotiations returns the total number of renegotiation handshakes
+ * peformed by |ssl|. This includes the pending renegotiation, if any. */
+OPENSSL_EXPORT int SSL_total_renegotiations(const SSL *ssl);
-#define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT (1024 * 20)
+/* SSL_MAX_CERT_LIST_DEFAULT is the default maximum length, in bytes, of a peer
+ * certificate chain. */
+#define SSL_MAX_CERT_LIST_DEFAULT 1024 * 100
-#define SSL_DEFAULT_SESSION_TIMEOUT (2 * 60 * 60)
+/* SSL_CTX_get_max_cert_list returns the maximum length, in bytes, of a peer
+ * certificate chain accepted by |ctx|. */
+OPENSSL_EXPORT size_t SSL_CTX_get_max_cert_list(const SSL_CTX *ctx);
-/* This callback type is used inside SSL_CTX, SSL, and in the functions that
- * set them. It is used to override the generation of SSL/TLS session IDs in a
- * server. Return value should be zero on an error, non-zero to proceed. Also,
- * callbacks should themselves check if the id they generate is unique
- * otherwise the SSL handshake will fail with an error - callbacks can do this
- * using the 'ssl' value they're passed by;
- * SSL_has_matching_session_id(ssl, id, *id_len)
- * The length value passed in is set at the maximum size the session ID can be.
- * In SSLv2 this is 16 bytes, whereas SSLv3/TLSv1 it is 32 bytes. The callback
- * can alter this length to be less if desired, but under SSLv2 session IDs are
- * supposed to be fixed at 16 bytes so the id will be padded after the callback
- * returns in this case. It is also an error for the callback to set the size
- * to zero. */
-typedef int (*GEN_SESSION_CB)(const SSL *ssl, uint8_t *id,
- unsigned int *id_len);
+/* SSL_CTX_set_max_cert_list sets the maximum length, in bytes, of a peer
+ * certificate chain to |max_cert_list|. This affects how much memory may be
+ * consumed during the handshake. */
+OPENSSL_EXPORT void SSL_CTX_set_max_cert_list(SSL_CTX *ctx,
+ size_t max_cert_list);
+
+/* SSL_get_max_cert_list returns the maximum length, in bytes, of a peer
+ * certificate chain accepted by |ssl|. */
+OPENSSL_EXPORT size_t SSL_get_max_cert_list(const SSL *ssl);
+
+/* SSL_set_max_cert_list sets the maximum length, in bytes, of a peer
+ * certificate chain to |max_cert_list|. This affects how much memory may be
+ * consumed during the handshake. */
+OPENSSL_EXPORT void SSL_set_max_cert_list(SSL *ssl, size_t max_cert_list);
+
+/* SSL_CTX_set_max_send_fragment sets the maximum length, in bytes, of records
+ * sent by |ctx|. Beyond this length, handshake messages and application data
+ * will be split into multiple records. */
+OPENSSL_EXPORT void SSL_CTX_set_max_send_fragment(SSL_CTX *ctx,
+ size_t max_send_fragment);
+
+/* SSL_set_max_send_fragment sets the maximum length, in bytes, of records
+ * sent by |ssl|. Beyond this length, handshake messages and application data
+ * will be split into multiple records. */
+OPENSSL_EXPORT void SSL_set_max_send_fragment(SSL *ssl,
+ size_t max_send_fragment);
/* 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
@@ -810,10 +2728,374 @@ struct ssl_early_callback_ctx {
* sets |out_data| to point to the extension contents (not including the type
* and length bytes), sets |out_len| to the length of the extension contents
* and returns one. */
-OPENSSL_EXPORT char SSL_early_callback_ctx_extension_get(
+OPENSSL_EXPORT int SSL_early_callback_ctx_extension_get(
const struct ssl_early_callback_ctx *ctx, uint16_t extension_type,
const uint8_t **out_data, size_t *out_len);
+/* SSL_CTX_set_select_certificate_cb sets a callback that is called before most
+ * ClientHello processing and before the decision whether to resume a session
+ * is made. The callback may inspect the ClientHello and configure the
+ * connection. It may then return one to continue the handshake or zero to
+ * pause the handshake to perform an asynchronous operation. If paused,
+ * |SSL_get_error| will return |SSL_ERROR_PENDING_CERTIFICATE|.
+ *
+ * Note: The |ssl_early_callback_ctx| is only valid for the duration of the
+ * callback and is not valid while the handshake is paused. Further, unlike with
+ * most callbacks, when the handshake loop is resumed, it will not call the
+ * callback a second time. The caller must finish reconfiguring the connection
+ * before resuming the handshake. */
+OPENSSL_EXPORT void SSL_CTX_set_select_certificate_cb(
+ SSL_CTX *ctx, int (*cb)(const struct ssl_early_callback_ctx *));
+
+/* SSL_CTX_set_dos_protection_cb sets a callback that is called once the
+ * resumption decision for a ClientHello has been made. It can return one to
+ * allow the handshake to continue or zero to cause the handshake to abort. */
+OPENSSL_EXPORT void SSL_CTX_set_dos_protection_cb(
+ SSL_CTX *ctx, int (*cb)(const struct ssl_early_callback_ctx *));
+
+/* SSL_ST_* are possible values for |SSL_state| and the bitmasks that make them
+ * up. */
+#define SSL_ST_CONNECT 0x1000
+#define SSL_ST_ACCEPT 0x2000
+#define SSL_ST_MASK 0x0FFF
+#define SSL_ST_INIT (SSL_ST_CONNECT | SSL_ST_ACCEPT)
+#define SSL_ST_OK 0x03
+#define SSL_ST_RENEGOTIATE (0x04 | SSL_ST_INIT)
+
+/* SSL_CB_* are possible values for the |type| parameter in the info
+ * callback and the bitmasks that make them up. */
+#define SSL_CB_LOOP 0x01
+#define SSL_CB_EXIT 0x02
+#define SSL_CB_READ 0x04
+#define SSL_CB_WRITE 0x08
+#define SSL_CB_ALERT 0x4000
+#define SSL_CB_READ_ALERT (SSL_CB_ALERT | SSL_CB_READ)
+#define SSL_CB_WRITE_ALERT (SSL_CB_ALERT | SSL_CB_WRITE)
+#define SSL_CB_ACCEPT_LOOP (SSL_ST_ACCEPT | SSL_CB_LOOP)
+#define SSL_CB_ACCEPT_EXIT (SSL_ST_ACCEPT | SSL_CB_EXIT)
+#define SSL_CB_CONNECT_LOOP (SSL_ST_CONNECT | SSL_CB_LOOP)
+#define SSL_CB_CONNECT_EXIT (SSL_ST_CONNECT | SSL_CB_EXIT)
+#define SSL_CB_HANDSHAKE_START 0x10
+#define SSL_CB_HANDSHAKE_DONE 0x20
+
+/* SSL_CTX_set_info_callback configures a callback to be run when various
+ * events occur during a connection's lifetime. The |type| argumentj determines
+ * the type of event and the meaning of the |value| argument. Callbacks must
+ * ignore unexpected |type| values.
+ *
+ * |SSL_CB_READ_ALERT| is signaled for each alert received, warning or fatal.
+ * The |value| argument is a 16-bit value where the alert level (either
+ * |SSL3_AL_WARNING| or |SSL3_AL_FATAL|) is in the most-significant eight bits and
+ * the alert type (one of |SSL_AD_*|) is in the least-significant eight.
+ *
+ * |SSL_CB_WRITE_ALERT| is signaled for each alert sent. The |value| argument
+ * is constructed as with |SSL_CB_READ_ALERT|.
+ *
+ * |SSL_CB_HANDSHAKE_START| is signaled when a handshake begins. The |value|
+ * argument is always one.
+ *
+ * |SSL_CB_HANDSHAKE_DONE| is signaled when a handshake completes successfully.
+ * The |value| argument is always one. If a handshake False Starts, this event
+ * may be used to determine when the Finished message is received.
+ *
+ * The following event types expose implementation details of the handshake
+ * state machine. Consuming them is deprecated.
+ *
+ * |SSL_CB_ACCEPT_LOOP| (respectively, |SSL_CB_CONNECT_LOOP|) is signaled when
+ * a server (respectively, client) handshake progresses. The |value| argument
+ * is always one. For the duration of the callback, |SSL_state| will return the
+ * previous state.
+ *
+ * |SSL_CB_ACCEPT_EXIT| (respectively, |SSL_CB_CONNECT_EXIT|) is signaled when
+ * a server (respectively, client) handshake completes, fails, or is paused.
+ * The |value| argument is one if the handshake succeeded and <= 0
+ * otherwise. */
+OPENSSL_EXPORT void SSL_CTX_set_info_callback(
+ SSL_CTX *ctx, void (*cb)(const SSL *ssl, int type, int value));
+
+/* SSL_CTX_get_info_callback returns the callback set by
+ * |SSL_CTX_set_info_callback|. */
+OPENSSL_EXPORT void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl,
+ int type,
+ int value);
+
+/* SSL_set_info_callback configures a callback to be run at various events
+ * during a connection's lifetime. See |SSL_CTX_set_info_callback|. */
+OPENSSL_EXPORT void SSL_set_info_callback(
+ SSL *ssl, void (*cb)(const SSL *ssl, int type, int value));
+
+/* SSL_get_info_callback returns the callback set by |SSL_set_info_callback|. */
+OPENSSL_EXPORT void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl,
+ int type,
+ int value);
+
+/* SSL_state_string_long returns the current state of the handshake state
+ * machine as a string. This may be useful for debugging and logging. */
+OPENSSL_EXPORT const char *SSL_state_string_long(const SSL *ssl);
+
+/* SSL_set_SSL_CTX partially changes |ssl|'s |SSL_CTX|. |ssl| will use the
+ * certificate and session_id_context from |ctx|, and |SSL_get_SSL_CTX| will
+ * report |ctx|. However most settings and the session cache itself will
+ * continue to use the initial |SSL_CTX|. It is often used as part of SNI.
+ *
+ * TODO(davidben): Make a better story here and get rid of this API. Also
+ * determine if there's anything else affected by |SSL_set_SSL_CTX| that
+ * matters. Not as many values are affected as one might initially think. The
+ * session cache explicitly selects the initial |SSL_CTX|. Most settings are
+ * copied at |SSL_new| so |ctx|'s versions don't apply. This, notably, has some
+ * consequences for any plans to make |SSL| copy-on-write most of its
+ * configuration. */
+OPENSSL_EXPORT SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx);
+
+#define SSL_SENT_SHUTDOWN 1
+#define SSL_RECEIVED_SHUTDOWN 2
+
+/* SSL_get_shutdown returns a bitmask with a subset of |SSL_SENT_SHUTDOWN| and
+ * |SSL_RECEIVED_SHUTDOWN| to query whether close_notify was sent or received,
+ * respectively. */
+OPENSSL_EXPORT int SSL_get_shutdown(const SSL *ssl);
+
+/* SSL_get_server_key_exchange_hash, on a client, returns the hash the server
+ * used to sign the ServerKeyExchange in TLS 1.2. If not applicable, it returns
+ * |TLSEXT_hash_none|. */
+OPENSSL_EXPORT uint8_t SSL_get_server_key_exchange_hash(const SSL *ssl);
+
+
+/* Deprecated functions. */
+
+/* SSL_library_init calls |CRYPTO_library_init| and returns one. */
+OPENSSL_EXPORT int SSL_library_init(void);
+
+/* SSL_set_reject_peer_renegotiations calls |SSL_set_renegotiate_mode| with
+ * |ssl_never_renegotiate| if |reject| is one and |ssl_renegotiate_freely| if
+ * zero. */
+OPENSSL_EXPORT void SSL_set_reject_peer_renegotiations(SSL *ssl, int reject);
+
+/* SSL_CIPHER_description writes a description of |cipher| into |buf| and
+ * returns |buf|. If |buf| is NULL, it returns a newly allocated string, to be
+ * freed with |OPENSSL_free|, or NULL on error.
+ *
+ * The description includes a trailing newline and has the form:
+ * 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,
+ char *buf, int len);
+
+/* SSL_CIPHER_get_version returns the string "TLSv1/SSLv3". */
+OPENSSL_EXPORT const char *SSL_CIPHER_get_version(const SSL_CIPHER *cipher);
+
+typedef void COMP_METHOD;
+
+/* SSL_COMP_get_compression_methods returns NULL. */
+OPENSSL_EXPORT COMP_METHOD *SSL_COMP_get_compression_methods(void);
+
+/* SSL_COMP_add_compression_method returns one. */
+OPENSSL_EXPORT int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm);
+
+/* SSL_COMP_get_name returns NULL. */
+OPENSSL_EXPORT const char *SSL_COMP_get_name(const COMP_METHOD *comp);
+
+/* SSLv23_method calls |TLS_method|. */
+OPENSSL_EXPORT const SSL_METHOD *SSLv23_method(void);
+
+/* These version-specific methods behave exactly like |TLS_method| and
+ * |DTLS_method| except they also call |SSL_CTX_set_min_version| and
+ * |SSL_CTX_set_max_version| to lock connections to that protocol version. */
+OPENSSL_EXPORT const SSL_METHOD *SSLv3_method(void);
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_method(void);
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_method(void);
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_method(void);
+OPENSSL_EXPORT const SSL_METHOD *DTLSv1_method(void);
+OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_method(void);
+
+/* These client- and server-specific methods call their corresponding generic
+ * methods. */
+OPENSSL_EXPORT const SSL_METHOD *SSLv23_server_method(void);
+OPENSSL_EXPORT const SSL_METHOD *SSLv23_client_method(void);
+OPENSSL_EXPORT const SSL_METHOD *SSLv3_server_method(void);
+OPENSSL_EXPORT const SSL_METHOD *SSLv3_client_method(void);
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_server_method(void);
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_client_method(void);
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_server_method(void);
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_client_method(void);
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_server_method(void);
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_client_method(void);
+OPENSSL_EXPORT const SSL_METHOD *DTLS_server_method(void);
+OPENSSL_EXPORT const SSL_METHOD *DTLS_client_method(void);
+OPENSSL_EXPORT const SSL_METHOD *DTLSv1_server_method(void);
+OPENSSL_EXPORT const SSL_METHOD *DTLSv1_client_method(void);
+OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_server_method(void);
+OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_client_method(void);
+
+/* SSL_clear resets |ssl| to allow another connection and returns one on success
+ * or zero on failure. It returns most configuration state but releases memory
+ * associated with the current connection.
+ *
+ * Free |ssl| and create a new one instead. */
+OPENSSL_EXPORT int SSL_clear(SSL *ssl);
+
+/* SSL_CTX_set_tmp_rsa_callback does nothing. */
+OPENSSL_EXPORT void SSL_CTX_set_tmp_rsa_callback(
+ SSL_CTX *ctx, RSA *(*cb)(SSL *ssl, int is_export, int keylength));
+
+/* SSL_set_tmp_rsa_callback does nothing. */
+OPENSSL_EXPORT void SSL_set_tmp_rsa_callback(SSL *ssl,
+ RSA *(*cb)(SSL *ssl, int is_export,
+ int keylength));
+
+/* SSL_CTX_sess_connect returns zero. */
+OPENSSL_EXPORT int SSL_CTX_sess_connect(const SSL_CTX *ctx);
+
+/* SSL_CTX_sess_connect_good returns zero. */
+OPENSSL_EXPORT int SSL_CTX_sess_connect_good(const SSL_CTX *ctx);
+
+/* SSL_CTX_sess_connect_renegotiate returns zero. */
+OPENSSL_EXPORT int SSL_CTX_sess_connect_renegotiate(const SSL_CTX *ctx);
+
+/* SSL_CTX_sess_accept returns zero. */
+OPENSSL_EXPORT int SSL_CTX_sess_accept(const SSL_CTX *ctx);
+
+/* SSL_CTX_sess_accept_renegotiate returns zero. */
+OPENSSL_EXPORT int SSL_CTX_sess_accept_renegotiate(const SSL_CTX *ctx);
+
+/* SSL_CTX_sess_accept_good returns zero. */
+OPENSSL_EXPORT int SSL_CTX_sess_accept_good(const SSL_CTX *ctx);
+
+/* SSL_CTX_sess_hits returns zero. */
+OPENSSL_EXPORT int SSL_CTX_sess_hits(const SSL_CTX *ctx);
+
+/* SSL_CTX_sess_cb_hits returns zero. */
+OPENSSL_EXPORT int SSL_CTX_sess_cb_hits(const SSL_CTX *ctx);
+
+/* SSL_CTX_sess_misses returns zero. */
+OPENSSL_EXPORT int SSL_CTX_sess_misses(const SSL_CTX *ctx);
+
+/* SSL_CTX_sess_timeouts returns zero. */
+OPENSSL_EXPORT int SSL_CTX_sess_timeouts(const SSL_CTX *ctx);
+
+/* SSL_CTX_sess_cache_full returns zero. */
+OPENSSL_EXPORT int SSL_CTX_sess_cache_full(const SSL_CTX *ctx);
+
+/* SSL_cutthrough_complete calls |SSL_in_false_start|. */
+OPENSSL_EXPORT int SSL_cutthrough_complete(const SSL *s);
+
+/* SSL_num_renegotiations calls |SSL_total_renegotiations|. */
+OPENSSL_EXPORT int SSL_num_renegotiations(const SSL *ssl);
+
+/* SSL_CTX_need_tmp_RSA returns zero. */
+OPENSSL_EXPORT int SSL_CTX_need_tmp_RSA(const SSL_CTX *ctx);
+
+/* SSL_need_tmp_RSA returns zero. */
+OPENSSL_EXPORT int SSL_need_tmp_RSA(const SSL *ssl);
+
+/* SSL_CTX_set_tmp_rsa returns one. */
+OPENSSL_EXPORT int SSL_CTX_set_tmp_rsa(SSL_CTX *ctx, const RSA *rsa);
+
+/* SSL_set_tmp_rsa returns one. */
+OPENSSL_EXPORT int SSL_set_tmp_rsa(SSL *ssl, const RSA *rsa);
+
+/* SSL_CTX_get_read_ahead returns zero. */
+OPENSSL_EXPORT int SSL_CTX_get_read_ahead(const SSL_CTX *ctx);
+
+/* SSL_CTX_set_read_ahead does nothing. */
+OPENSSL_EXPORT void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes);
+
+/* SSL_get_read_ahead returns zero. */
+OPENSSL_EXPORT int SSL_get_read_ahead(const SSL *s);
+
+/* SSL_set_read_ahead does nothing. */
+OPENSSL_EXPORT void SSL_set_read_ahead(SSL *s, int yes);
+
+/* SSL_renegotiate put an error on the error queue and returns zero. */
+OPENSSL_EXPORT int SSL_renegotiate(SSL *ssl);
+
+/* SSL_set_state does nothing. */
+OPENSSL_EXPORT void SSL_set_state(SSL *ssl, int state);
+
+/* SSL_MODE_HANDSHAKE_CUTTHROUGH is the same as SSL_MODE_ENABLE_FALSE_START. */
+#define SSL_MODE_HANDSHAKE_CUTTHROUGH SSL_MODE_ENABLE_FALSE_START
+
+/* i2d_SSL_SESSION serializes |in| to the bytes pointed to by |*pp|. On success,
+ * it returns the number of bytes written and advances |*pp| by that many bytes.
+ * On failure, it returns -1. If |pp| is NULL, no bytes are written and only the
+ * length is returned.
+ *
+ * Use |SSL_SESSION_to_bytes| instead. */
+OPENSSL_EXPORT int i2d_SSL_SESSION(SSL_SESSION *in, uint8_t **pp);
+
+/* d2i_SSL_SESSION parses a serialized session from the |length| bytes pointed
+ * to by |*pp|. It returns the new |SSL_SESSION| and advances |*pp| by the
+ * number of bytes consumed on success and NULL on failure. The caller takes
+ * ownership of the new session and must call |SSL_SESSION_free| when done.
+ *
+ * If |a| is non-NULL, |*a| is released and set the new |SSL_SESSION|.
+ *
+ * Use |SSL_SESSION_from_bytes| instead. */
+OPENSSL_EXPORT SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const uint8_t **pp,
+ long length);
+
+/* i2d_SSL_SESSION_bio serializes |session| and writes the result to |bio|. It
+ * returns the number of bytes written on success and <= 0 on error. */
+OPENSSL_EXPORT int i2d_SSL_SESSION_bio(BIO *bio, const SSL_SESSION *session);
+
+/* d2i_SSL_SESSION_bio reads a serialized |SSL_SESSION| from |bio| and returns a
+ * newly-allocated |SSL_SESSION| or NULL on error. If |out| is not NULL, it also
+ * frees |*out| and sets |*out| to the new |SSL_SESSION|. */
+OPENSSL_EXPORT SSL_SESSION *d2i_SSL_SESSION_bio(BIO *bio, SSL_SESSION **out);
+
+/* ERR_load_SSL_strings does nothing. */
+OPENSSL_EXPORT void ERR_load_SSL_strings(void);
+
+/* SSL_load_error_strings does nothing. */
+OPENSSL_EXPORT void SSL_load_error_strings(void);
+
+/* SSL_CTX_set_tlsext_use_srtp calls |SSL_CTX_set_srtp_profiles|. It returns
+ * zero on success and one on failure.
+ *
+ * WARNING: this function is dangerous because it breaks the usual return value
+ * convention. Use |SSL_CTX_set_srtp_profiles| instead. */
+OPENSSL_EXPORT int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx,
+ const char *profiles);
+
+/* SSL_set_tlsext_use_srtp calls |SSL_set_srtp_profiles|. It returns zero on
+ * success and one on failure.
+ *
+ * WARNING: this function is dangerous because it breaks the usual return value
+ * convention. Use |SSL_set_srtp_profiles| instead. */
+OPENSSL_EXPORT int SSL_set_tlsext_use_srtp(SSL *ssl, const char *profiles);
+
+/* SSL_get_current_compression returns NULL. */
+OPENSSL_EXPORT const COMP_METHOD *SSL_get_current_compression(SSL *s);
+
+/* SSL_get_current_expansion returns NULL. */
+OPENSSL_EXPORT const COMP_METHOD *SSL_get_current_expansion(SSL *s);
+
+#define SSL_set_app_data(s, arg) (SSL_set_ex_data(s, 0, (char *)arg))
+#define SSL_get_app_data(s) (SSL_get_ex_data(s, 0))
+#define SSL_SESSION_set_app_data(s, a) \
+ (SSL_SESSION_set_ex_data(s, 0, (char *)a))
+#define SSL_SESSION_get_app_data(s) (SSL_SESSION_get_ex_data(s, 0))
+#define SSL_CTX_get_app_data(ctx) (SSL_CTX_get_ex_data(ctx, 0))
+#define SSL_CTX_set_app_data(ctx, arg) \
+ (SSL_CTX_set_ex_data(ctx, 0, (char *)arg))
+
+#define OpenSSL_add_ssl_algorithms() SSL_library_init()
+#define SSLeay_add_ssl_algorithms() SSL_library_init()
+
+#define SSL_get_cipher(ssl) SSL_CIPHER_get_name(SSL_get_current_cipher(ssl))
+#define SSL_get_cipher_bits(ssl, out_alg_bits) \
+ SSL_CIPHER_get_bits(SSL_get_current_cipher(ssl), out_alg_bits)
+#define SSL_get_cipher_version(ssl) \
+ SSL_CIPHER_get_version(SSL_get_current_cipher(ssl))
+#define SSL_get_cipher_name(ssl) \
+ SSL_CIPHER_get_name(SSL_get_current_cipher(ssl))
+#define SSL_get_time(session) SSL_SESSION_get_time(session)
+#define SSL_set_time(session, time) SSL_SESSION_set_time((session), (time))
+#define SSL_get_timeout(session) SSL_SESSION_get_timeout(session)
+#define SSL_set_timeout(session, timeout) \
+ SSL_SESSION_set_timeout((session), (timeout))
+
typedef struct ssl_comp_st SSL_COMP;
struct ssl_comp_st {
@@ -823,7 +3105,327 @@ struct ssl_comp_st {
};
DECLARE_STACK_OF(SSL_COMP)
-DECLARE_LHASH_OF(SSL_SESSION)
+
+/* The following flags toggle individual protocol versions. This is deprecated.
+ * Use |SSL_CTX_set_min_version| and |SSL_CTX_set_max_version| instead. */
+#define SSL_OP_NO_SSLv3 0x02000000L
+#define SSL_OP_NO_TLSv1 0x04000000L
+#define SSL_OP_NO_TLSv1_2 0x08000000L
+#define SSL_OP_NO_TLSv1_1 0x10000000L
+#define SSL_OP_NO_DTLSv1 SSL_OP_NO_TLSv1
+#define SSL_OP_NO_DTLSv1_2 SSL_OP_NO_TLSv1_2
+
+/* The following flags do nothing and are included only to make it easier to
+ * compile code with BoringSSL. */
+#define SSL_MODE_AUTO_RETRY 0
+#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
+#define SSL_OP_NETSCAPE_CHALLENGE_BUG 0
+#define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0
+#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0
+#define SSL_OP_NO_COMPRESSION 0
+#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
+#define SSL_OP_NO_SSLv2 0
+#define SSL_OP_PKCS1_CHECK_1 0
+#define SSL_OP_PKCS1_CHECK_2 0
+#define SSL_OP_SINGLE_DH_USE 0
+#define SSL_OP_SINGLE_ECDH_USE 0
+#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
+
+/* SSL_cache_hit calls |SSL_session_resumed|. */
+OPENSSL_EXPORT int SSL_cache_hit(SSL *ssl);
+
+/* SSL_get_default_timeout returns |SSL_DEFAULT_SESSION_TIMEOUT|. */
+OPENSSL_EXPORT long SSL_get_default_timeout(const SSL *ssl);
+
+/* SSL_get_version returns a string describing the TLS version used by |ssl|.
+ * For example, "TLSv1.2" or "SSLv3". */
+OPENSSL_EXPORT const char *SSL_get_version(const SSL *ssl);
+
+/* SSL_get_cipher_list returns the name of the |n|th cipher in the output of
+ * |SSL_get_ciphers| or NULL if out of range. Use |SSL_get_ciphers| insteads. */
+OPENSSL_EXPORT const char *SSL_get_cipher_list(const SSL *ssl, int n);
+
+/* SSL_CTX_set_client_cert_cb sets a callback which is called on the client if
+ * the server requests a client certificate and none is configured. On success,
+ * the callback should return one and set |*out_x509| to |*out_pkey| to a leaf
+ * certificate and private key, respectively, passing ownership. It should
+ * return zero to send no certificate and -1 to fail or pause the handshake. If
+ * the handshake is paused, |SSL_get_error| will return
+ * |SSL_ERROR_WANT_X509_LOOKUP|.
+ *
+ * The callback may call |SSL_get0_certificate_types| and
+ * |SSL_get_client_CA_list| for information on the server's certificate request.
+ *
+ * Use |SSL_CTX_set_cert_cb| instead. Configuring intermediate certificates with
+ * this function is confusing. */
+OPENSSL_EXPORT void SSL_CTX_set_client_cert_cb(
+ SSL_CTX *ctx,
+ int (*client_cert_cb)(SSL *ssl, X509 **out_x509, EVP_PKEY **out_pkey));
+
+/* SSL_CTX_get_client_cert_cb returns the callback set by
+ * |SSL_CTX_set_client_cert_cb|. */
+OPENSSL_EXPORT int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(
+ SSL *ssl, X509 **out_x509, EVP_PKEY **out_pkey);
+
+#define SSL_NOTHING 1
+#define SSL_WRITING 2
+#define SSL_READING 3
+#define SSL_X509_LOOKUP 4
+#define SSL_CHANNEL_ID_LOOKUP 5
+#define SSL_PENDING_SESSION 7
+#define SSL_CERTIFICATE_SELECTION_PENDING 8
+#define SSL_PRIVATE_KEY_OPERATION 9
+
+/* SSL_want returns one of the above values to determine what the most recent
+ * operation on |ssl| was blocked on. Use |SSL_get_error| instead. */
+OPENSSL_EXPORT int SSL_want(const SSL *ssl);
+
+#define SSL_want_nothing(ssl) (SSL_want(ssl) == SSL_NOTHING)
+#define SSL_want_read(ssl) (SSL_want(ssl) == SSL_READING)
+#define SSL_want_write(ssl) (SSL_want(ssl) == SSL_WRITING)
+#define SSL_want_x509_lookup(ssl) (SSL_want(ssl) == SSL_X509_LOOKUP)
+#define SSL_want_channel_id_lookup(ssl) (SSL_want(ssl) == SSL_CHANNEL_ID_LOOKUP)
+#define SSL_want_session(ssl) (SSL_want(ssl) == SSL_PENDING_SESSION)
+#define SSL_want_certificate(ssl) \
+ (SSL_want(ssl) == SSL_CERTIFICATE_SELECTION_PENDING)
+#define SSL_want_private_key_operation(ssl) \
+ (SSL_want(ssl) == SSL_PRIVATE_KEY_OPERATION)
+
+ /* SSL_get_finished writes up to |count| bytes of the Finished message sent by
+ * |ssl| to |buf|. It returns the total untruncated length or zero if none has
+ * been sent yet.
+ *
+ * Use |SSL_get_tls_unique| instead. */
+OPENSSL_EXPORT size_t SSL_get_finished(const SSL *ssl, void *buf, size_t count);
+
+ /* SSL_get_peer_finished writes up to |count| bytes of the Finished message
+ * received from |ssl|'s peer to |buf|. It returns the total untruncated length
+ * or zero if none has been received yet.
+ *
+ * Use |SSL_get_tls_unique| instead. */
+OPENSSL_EXPORT size_t SSL_get_peer_finished(const SSL *ssl, void *buf,
+ size_t count);
+
+/* SSL_alert_type_string returns "!". Use |SSL_alert_type_string_long|
+ * instead. */
+OPENSSL_EXPORT const char *SSL_alert_type_string(int value);
+
+/* SSL_alert_desc_string returns "!!". Use |SSL_alert_desc_string_long|
+ * instead. */
+OPENSSL_EXPORT const char *SSL_alert_desc_string(int value);
+
+/* SSL_TXT_* expand to strings. */
+#define SSL_TXT_MEDIUM "MEDIUM"
+#define SSL_TXT_HIGH "HIGH"
+#define SSL_TXT_FIPS "FIPS"
+#define SSL_TXT_kRSA "kRSA"
+#define SSL_TXT_kDHE "kDHE"
+#define SSL_TXT_kEDH "kEDH"
+#define SSL_TXT_kECDHE "kECDHE"
+#define SSL_TXT_kEECDH "kEECDH"
+#define SSL_TXT_kPSK "kPSK"
+#define SSL_TXT_aRSA "aRSA"
+#define SSL_TXT_aECDSA "aECDSA"
+#define SSL_TXT_aPSK "aPSK"
+#define SSL_TXT_DH "DH"
+#define SSL_TXT_DHE "DHE"
+#define SSL_TXT_EDH "EDH"
+#define SSL_TXT_RSA "RSA"
+#define SSL_TXT_ECDH "ECDH"
+#define SSL_TXT_ECDHE "ECDHE"
+#define SSL_TXT_EECDH "EECDH"
+#define SSL_TXT_ECDSA "ECDSA"
+#define SSL_TXT_PSK "PSK"
+#define SSL_TXT_3DES "3DES"
+#define SSL_TXT_RC4 "RC4"
+#define SSL_TXT_AES128 "AES128"
+#define SSL_TXT_AES256 "AES256"
+#define SSL_TXT_AES "AES"
+#define SSL_TXT_AES_GCM "AESGCM"
+#define SSL_TXT_CHACHA20 "CHACHA20"
+#define SSL_TXT_MD5 "MD5"
+#define SSL_TXT_SHA1 "SHA1"
+#define SSL_TXT_SHA "SHA"
+#define SSL_TXT_SHA256 "SHA256"
+#define SSL_TXT_SHA384 "SHA384"
+#define SSL_TXT_SSLV3 "SSLv3"
+#define SSL_TXT_TLSV1 "TLSv1"
+#define SSL_TXT_TLSV1_1 "TLSv1.1"
+#define SSL_TXT_TLSV1_2 "TLSv1.2"
+#define SSL_TXT_ALL "ALL"
+#define SSL_TXT_CMPDEF "COMPLEMENTOFDEFAULT"
+
+typedef struct ssl_conf_ctx_st SSL_CONF_CTX;
+
+/* SSL_state returns the current state of the handshake state machine. */
+OPENSSL_EXPORT int SSL_state(const SSL *ssl);
+
+#define SSL_get_state(ssl) SSL_state(ssl)
+
+/* SSL_state_string returns the current state of the handshake state machine as
+ * a six-letter string. Use |SSL_state_string_long| for a more intelligible
+ * string. */
+OPENSSL_EXPORT const char *SSL_state_string(const SSL *ssl);
+
+/* SSL_set_shutdown causes |ssl| to behave as if the shutdown bitmask (see
+ * |SSL_get_shutdown|) were |mode|. This may be used to skip sending or
+ * receiving close_notify in |SSL_shutdown| by causing the implementation to
+ * believe the events already happened.
+ *
+ * It is an error to use |SSL_set_shutdown| to unset a bit that has already been
+ * set. Doing so will trigger an |assert| in debug builds and otherwise be
+ * ignored.
+ *
+ * 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.
+ *
+ * This structures are exposed for historical reasons, but access to them is
+ * deprecated. */
+
+typedef struct ssl_protocol_method_st SSL_PROTOCOL_METHOD;
+typedef struct ssl3_enc_method SSL3_ENC_METHOD;
+typedef struct ssl_aead_ctx_st SSL_AEAD_CTX;
+
+struct ssl_cipher_st {
+ /* name is the OpenSSL name for the cipher. */
+ const char *name;
+ /* id is the cipher suite value bitwise OR-d with 0x03000000. */
+ uint32_t id;
+
+ /* 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_prf;
+};
+
+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
+
+struct ssl_session_st {
+ CRYPTO_refcount_t references;
+ int ssl_version; /* what ssl version session info is being kept in here? */
+
+ /* key_exchange_info contains an indication of the size of the asymmetric
+ * primitive used in the handshake that created this session. In the event
+ * that two asymmetric operations are used, this value applies to the one
+ * that controls the confidentiality of the connection. Its interpretation
+ * depends on the primitive that was used; as specified by the cipher suite:
+ * DHE: the size, in bits, of the multiplicative group.
+ * RSA: the size, in bits, of the modulus.
+ * ECDHE: the TLS id for the curve.
+ *
+ * A zero indicates that the value is unknown. */
+ uint32_t key_exchange_info;
+
+ int master_key_length;
+ uint8_t master_key[SSL_MAX_MASTER_KEY_LENGTH];
+
+ /* session_id - valid? */
+ unsigned int session_id_length;
+ uint8_t session_id[SSL_MAX_SSL_SESSION_ID_LENGTH];
+ /* this is used to determine whether the session is being reused in
+ * the appropriate context. It is up to the application to set this,
+ * via SSL_new */
+ unsigned int sid_ctx_length;
+ uint8_t sid_ctx[SSL_MAX_SID_CTX_LENGTH];
+
+ char *psk_identity;
+ /* peer is the peer's certificate. */
+ X509 *peer;
+
+ /* cert_chain is the certificate chain sent by the peer. NOTE: for historical
+ * reasons, when a client (so the peer is a server), the chain includes
+ * |peer|, but when a server it does not. */
+ STACK_OF(X509) *cert_chain;
+
+ /* when app_verify_callback accepts a session where the peer's certificate is
+ * not ok, we must remember the error for session reuse: */
+ long verify_result; /* only for servers */
+
+ long timeout;
+ long time;
+
+ const SSL_CIPHER *cipher;
+
+ CRYPTO_EX_DATA ex_data; /* application specific data */
+
+ /* These are used to make removal of session-ids more efficient and to
+ * implement a maximum cache size. */
+ SSL_SESSION *prev, *next;
+ char *tlsext_hostname;
+
+ /* RFC4507 info */
+ uint8_t *tlsext_tick; /* Session ticket */
+ size_t tlsext_ticklen; /* Session ticket length */
+
+ size_t tlsext_signed_cert_timestamp_list_length;
+ uint8_t *tlsext_signed_cert_timestamp_list; /* Server's list. */
+
+ /* The OCSP response that came with the session. */
+ size_t ocsp_response_length;
+ uint8_t *ocsp_response;
+
+ /* peer_sha256 contains the SHA-256 hash of the peer's certificate if
+ * |peer_sha256_valid| is true. */
+ uint8_t peer_sha256[SHA256_DIGEST_LENGTH];
+
+ /* original_handshake_hash contains the handshake hash (either SHA-1+MD5 or
+ * SHA-2, depending on TLS version) for the original, full handshake that
+ * created a session. This is used by Channel IDs during resumption. */
+ uint8_t original_handshake_hash[EVP_MAX_MD_SIZE];
+ unsigned original_handshake_hash_len;
+
+ uint32_t tlsext_tick_lifetime_hint; /* Session lifetime hint in seconds */
+
+ /* extended_master_secret is true if the master secret in this session was
+ * generated using EMS and thus isn't vulnerable to the Triple Handshake
+ * attack. */
+ unsigned extended_master_secret:1;
+
+ /* peer_sha256_valid is non-zero if |peer_sha256| is valid. */
+ unsigned peer_sha256_valid:1; /* Non-zero if peer_sha256 is valid */
+
+ /* not_resumable is used to indicate that session resumption is not allowed.
+ * Applications can also set this bit for a new session via
+ * not_resumable_session_cb to disable session caching and tickets. */
+ unsigned not_resumable:1;
+};
/* ssl_cipher_preference_list_st contains a list of SSL_CIPHERs with
* equal-preference groups. For TLS clients, the groups are moot because the
@@ -878,6 +3480,17 @@ struct ssl_ctx_st {
struct ssl_cipher_preference_list_st *cipher_list;
/* same as above but sorted for lookup */
STACK_OF(SSL_CIPHER) *cipher_list_by_id;
+
+ /* cipher_list_tls10 is the list of ciphers when TLS 1.0 or greater is in
+ * use. This only applies to server connections as, for clients, the version
+ * number is known at connect time and so the cipher list can be set then. If
+ * |cipher_list_tls11| is non-NULL then this applies only to TLS 1.0
+ * connections.
+ *
+ * TODO(agl): this exists to assist in the death of SSLv3. It can hopefully
+ * be removed after that. */
+ struct ssl_cipher_preference_list_st *cipher_list_tls10;
+
/* cipher_list_tls11 is the list of ciphers when TLS 1.1 or greater is in
* use. This only applies to server connections as, for clients, the version
* number is known at connect time and so the cipher list can be set then. */
@@ -921,10 +3534,8 @@ struct ssl_ctx_st {
CRYPTO_refcount_t references;
/* if defined, these override the X509_verify_cert() calls */
- int (*app_verify_callback)(X509_STORE_CTX *, void *);
+ int (*app_verify_callback)(X509_STORE_CTX *store_ctx, void *arg);
void *app_verify_arg;
- /* before OpenSSL 0.9.7, 'app_verify_arg' was ignored ('app_verify_callback'
- * was called with just one argument) */
/* Default password callback. */
pem_password_cb *default_passwd_callback;
@@ -933,20 +3544,21 @@ struct ssl_ctx_st {
void *default_passwd_callback_userdata;
/* get client cert callback */
- int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
+ int (*client_cert_cb)(SSL *ssl, X509 **out_x509, EVP_PKEY **out_pkey);
/* get channel id callback */
- void (*channel_id_cb)(SSL *ssl, EVP_PKEY **pkey);
+ void (*channel_id_cb)(SSL *ssl, EVP_PKEY **out_pkey);
CRYPTO_EX_DATA ex_data;
- STACK_OF(X509) *extra_certs;
-
+ /* custom_*_extensions stores any callback sets for custom extensions. Note
+ * that these pointers will be NULL if the stack would otherwise be empty. */
+ STACK_OF(SSL_CUSTOM_EXTENSION) *client_custom_extensions;
+ STACK_OF(SSL_CUSTOM_EXTENSION) *server_custom_extensions;
/* Default values used when no per-SSL value is defined follow */
- void (*info_callback)(const SSL *ssl, int type,
- int val); /* used if SSL's info_callback is NULL */
+ void (*info_callback)(const SSL *ssl, int type, int value);
/* what we put in client cert requests */
STACK_OF(X509_NAME) *client_CA;
@@ -972,9 +3584,6 @@ struct ssl_ctx_st {
int (*default_verify_callback)(
int ok, X509_STORE_CTX *ctx); /* called 'verify_callback' in the SSL */
- /* Default generate session ID callback. */
- GEN_SESSION_CB generate_session_id;
-
X509_VERIFY_PARAM *param;
/* select_certificate_cb is called before most ClientHello processing and
@@ -990,10 +3599,6 @@ struct ssl_ctx_st {
* abort. */
int (*dos_protection_cb) (const struct ssl_early_callback_ctx *);
- /* quiet_shutdown is true if the connection should not send a close_notify on
- * shutdown. */
- int quiet_shutdown;
-
/* Maximum amount of data to send in one fragment. actual record size can be
* more than this due to padding and MAC overheads. */
uint16_t max_send_fragment;
@@ -1002,7 +3607,7 @@ struct ssl_ctx_st {
int (*tlsext_servername_callback)(SSL *, int *, void *);
void *tlsext_servername_arg;
/* RFC 4507 session ticket keys */
- uint8_t tlsext_tick_key_name[16];
+ uint8_t tlsext_tick_key_name[SSL_TICKET_KEY_NAME_LEN];
uint8_t tlsext_tick_hmac_key[16];
uint8_t tlsext_tick_aes_key[16];
/* Callback to support customisation of ticket key setting */
@@ -1031,13 +3636,13 @@ struct ssl_ctx_st {
/* For a server, this contains a callback function by which the set of
* advertised protocols can be provided. */
- int (*next_protos_advertised_cb)(SSL *s, const uint8_t **buf,
- unsigned int *len, void *arg);
+ int (*next_protos_advertised_cb)(SSL *ssl, const uint8_t **out,
+ unsigned *out_len, void *arg);
void *next_protos_advertised_cb_arg;
/* For a client, this contains a callback function that selects the
* next protocol from the list provided by the server. */
- int (*next_proto_select_cb)(SSL *s, uint8_t **out, uint8_t *outlen,
- const uint8_t *in, unsigned int inlen, void *arg);
+ int (*next_proto_select_cb)(SSL *ssl, uint8_t **out, uint8_t *out_len,
+ const uint8_t *in, unsigned in_len, void *arg);
void *next_proto_select_cb_arg;
/* ALPN information
@@ -1051,8 +3656,8 @@ struct ssl_ctx_st {
* in: points to the client's list of supported protocols in
* wire-format.
* inlen: the length of |in|. */
- int (*alpn_select_cb)(SSL *s, const uint8_t **out, uint8_t *outlen,
- const uint8_t *in, unsigned int inlen, void *arg);
+ int (*alpn_select_cb)(SSL *s, const uint8_t **out, uint8_t *out_len,
+ const uint8_t *in, unsigned in_len, void *arg);
void *alpn_select_cb_arg;
/* For a client, this contains the list of supported protocols in wire
@@ -1064,235 +3669,49 @@ struct ssl_ctx_st {
STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;
/* EC extension values inherited by SSL structure */
- size_t tlsext_ecpointformatlist_length;
- uint8_t *tlsext_ecpointformatlist;
size_t tlsext_ellipticcurvelist_length;
uint16_t *tlsext_ellipticcurvelist;
- /* If true, a client will advertise the Channel ID extension and a server
- * will echo it. */
- char tlsext_channel_id_enabled;
- /* tlsext_channel_id_enabled_new is a hack to support both old and new
- * ChannelID signatures. It indicates that a client should advertise the new
- * ChannelID extension number. */
- char tlsext_channel_id_enabled_new;
/* The client's Channel ID private key. */
EVP_PKEY *tlsext_channel_id_private;
- /* If true, a client will request certificate timestamps. */
- char signed_cert_timestamps_enabled;
+ /* Signed certificate timestamp list to be sent to the client, if requested */
+ uint8_t *signed_cert_timestamp_list;
+ size_t signed_cert_timestamp_list_length;
- /* If true, a client will request a stapled OCSP response. */
- char ocsp_stapling_enabled;
+ /* OCSP response to be sent to the client, if requested. */
+ 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. */
void (*current_time_cb)(const SSL *ssl, struct timeval *out_clock);
-};
-
-OPENSSL_EXPORT LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx);
-/* SSL_CTX_sess_number returns the number of sessions in |ctx|'s internal
- * session cache. */
-OPENSSL_EXPORT size_t SSL_CTX_sess_number(const SSL_CTX *ctx);
-
-OPENSSL_EXPORT void SSL_CTX_sess_set_new_cb(
- SSL_CTX *ctx, int (*new_session_cb)(SSL *ssl, SSL_SESSION *sess));
-OPENSSL_EXPORT int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(SSL *ssl,
- SSL_SESSION *sess);
-OPENSSL_EXPORT void SSL_CTX_sess_set_remove_cb(
- SSL_CTX *ctx,
- void (*remove_session_cb)(SSL_CTX *ctx, SSL_SESSION *sess));
-OPENSSL_EXPORT void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(
- SSL_CTX *ctx, SSL_SESSION *sess);
-OPENSSL_EXPORT void SSL_CTX_sess_set_get_cb(
- SSL_CTX *ctx,
- SSL_SESSION *(*get_session_cb)(SSL *ssl, uint8_t *data, int len,
- int *copy));
-OPENSSL_EXPORT SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(
- SSL *ssl, uint8_t *data, int len, int *copy);
-/* SSL_magic_pending_session_ptr returns a magic SSL_SESSION* which indicates
- * that the session isn't currently unavailable. SSL_get_error will then return
- * SSL_ERROR_PENDING_SESSION and the handshake can be retried later when the
- * lookup has completed. */
-OPENSSL_EXPORT SSL_SESSION *SSL_magic_pending_session_ptr(void);
-OPENSSL_EXPORT void SSL_CTX_set_info_callback(SSL_CTX *ctx,
- void (*cb)(const SSL *ssl,
- int type, int val));
-OPENSSL_EXPORT void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl,
- int type,
- int val);
-OPENSSL_EXPORT void SSL_CTX_set_client_cert_cb(
- SSL_CTX *ctx,
- int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey));
-OPENSSL_EXPORT int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl,
- X509 **x509,
- EVP_PKEY **pkey);
-OPENSSL_EXPORT void SSL_CTX_set_channel_id_cb(
- SSL_CTX *ctx, void (*channel_id_cb)(SSL *ssl, EVP_PKEY **pkey));
-OPENSSL_EXPORT void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))(SSL *ssl,
- EVP_PKEY **pkey);
-
-/* SSL_enable_signed_cert_timestamps causes |ssl| (which must be the client end
- * of a connection) to request SCTs from the server. See
- * https://tools.ietf.org/html/rfc6962. It returns one. */
-OPENSSL_EXPORT int SSL_enable_signed_cert_timestamps(SSL *ssl);
-
-/* SSL_CTX_enable_signed_cert_timestamps enables SCT requests on all client SSL
- * objects created from |ctx|. */
-OPENSSL_EXPORT void SSL_CTX_enable_signed_cert_timestamps(SSL_CTX *ctx);
-
-/* SSL_enable_ocsp_stapling causes |ssl| (which must be the client end of a
- * connection) to request a stapled OCSP response from the server. It returns
- * one. */
-OPENSSL_EXPORT int SSL_enable_ocsp_stapling(SSL *ssl);
-
-/* SSL_CTX_enable_ocsp_stapling enables OCSP stapling on all client SSL objects
- * created from |ctx|. */
-OPENSSL_EXPORT void SSL_CTX_enable_ocsp_stapling(SSL_CTX *ctx);
-
-/* SSL_get0_signed_cert_timestamp_list sets |*out| and |*out_len| to point to
- * |*out_len| bytes of SCT information from the server. This is only valid if
- * |ssl| is a client. The SCT information is a SignedCertificateTimestampList
- * (including the two leading length bytes).
- * See https://tools.ietf.org/html/rfc6962#section-3.3
- * If no SCT was received then |*out_len| will be zero on return.
- *
- * WARNING: the returned data is not guaranteed to be well formed. */
-OPENSSL_EXPORT void SSL_get0_signed_cert_timestamp_list(const SSL *ssl,
- const uint8_t **out,
- size_t *out_len);
-
-/* SSL_get0_ocsp_response sets |*out| and |*out_len| to point to |*out_len|
- * bytes of an OCSP response from the server. This is the DER encoding of an
- * OCSPResponse type as defined in RFC 2560.
- *
- * WARNING: the returned data is not guaranteed to be well formed. */
-OPENSSL_EXPORT void SSL_get0_ocsp_response(const SSL *ssl, const uint8_t **out,
- size_t *out_len);
-
-OPENSSL_EXPORT void SSL_CTX_set_next_protos_advertised_cb(
- SSL_CTX *s,
- int (*cb)(SSL *ssl, const uint8_t **out, unsigned int *outlen, void *arg),
- void *arg);
-OPENSSL_EXPORT void SSL_CTX_set_next_proto_select_cb(
- SSL_CTX *s, int (*cb)(SSL *ssl, uint8_t **out, uint8_t *outlen,
- const uint8_t *in, unsigned int inlen, void *arg),
- void *arg);
-OPENSSL_EXPORT void SSL_get0_next_proto_negotiated(const SSL *s,
- const uint8_t **data,
- unsigned *len);
-
-OPENSSL_EXPORT int SSL_select_next_proto(uint8_t **out, uint8_t *outlen,
- const uint8_t *in, unsigned int inlen,
- const uint8_t *client,
- unsigned int client_len);
-
-#define OPENSSL_NPN_UNSUPPORTED 0
-#define OPENSSL_NPN_NEGOTIATED 1
-#define OPENSSL_NPN_NO_OVERLAP 2
-
-/* SSL_CTX_set_alpn_protos sets the ALPN protocol list on |ctx| to |protos|.
- * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit
- * length-prefixed strings). It returns zero on success and one on failure.
- *
- * WARNING: this function is dangerous because it breaks the usual return value
- * convention. */
-OPENSSL_EXPORT int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const uint8_t *protos,
- unsigned protos_len);
-
-/* SSL_set_alpn_protos sets the ALPN protocol list on |ssl| to |protos|.
- * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit
- * length-prefixed strings). It returns zero on success and one on failure.
- *
- * WARNING: this function is dangerous because it breaks the usual return value
- * convention. */
-OPENSSL_EXPORT int SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos,
- unsigned protos_len);
+ /* quiet_shutdown is true if the connection should not send a close_notify on
+ * shutdown. */
+ unsigned quiet_shutdown:1;
-OPENSSL_EXPORT void SSL_CTX_set_alpn_select_cb(
- SSL_CTX *ctx, int (*cb)(SSL *ssl, const uint8_t **out, uint8_t *outlen,
- const uint8_t *in, unsigned int inlen, void *arg),
- void *arg);
-OPENSSL_EXPORT void SSL_get0_alpn_selected(const SSL *ssl, const uint8_t **data,
- unsigned *len);
-
-/* SSL_enable_fastradio_padding controls whether fastradio padding is enabled
- * on |ssl|. If it is, ClientHello messages are padded to 1024 bytes. This
- * causes 3G radios to switch to DCH mode (high data rate). */
-OPENSSL_EXPORT void SSL_enable_fastradio_padding(SSL *ssl, char on_off);
-
-/* SSL_set_reject_peer_renegotiations controls whether renegotiation attempts by
- * the peer are rejected. It may be set at any point in a connection's lifetime
- * to control future renegotiations programmatically. By default, renegotiations
- * are rejected. (Renegotiations requested by a client are always rejected.) */
-OPENSSL_EXPORT void SSL_set_reject_peer_renegotiations(SSL *ssl, int reject);
+ /* ocsp_stapling_enabled is only used by client connections and indicates
+ * whether OCSP stapling will be requested. */
+ unsigned ocsp_stapling_enabled:1;
-/* the maximum length of the buffer given to callbacks containing the resulting
- * identity/psk */
-#define PSK_MAX_IDENTITY_LEN 128
-#define PSK_MAX_PSK_LEN 256
-OPENSSL_EXPORT void SSL_CTX_set_psk_client_callback(
- SSL_CTX *ctx,
- unsigned int (*psk_client_callback)(
- SSL *ssl, const char *hint, char *identity,
- unsigned int max_identity_len, uint8_t *psk, unsigned int max_psk_len));
-OPENSSL_EXPORT void SSL_set_psk_client_callback(
- SSL *ssl, unsigned int (*psk_client_callback)(SSL *ssl, const char *hint,
- char *identity,
- unsigned int max_identity_len,
- uint8_t *psk,
- unsigned int max_psk_len));
-OPENSSL_EXPORT void SSL_CTX_set_psk_server_callback(
- SSL_CTX *ctx,
- unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
- uint8_t *psk,
- unsigned int max_psk_len));
-OPENSSL_EXPORT void SSL_set_psk_server_callback(
- SSL *ssl,
- unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
- uint8_t *psk,
- unsigned int max_psk_len));
-OPENSSL_EXPORT int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx,
- const char *identity_hint);
-OPENSSL_EXPORT int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint);
-OPENSSL_EXPORT const char *SSL_get_psk_identity_hint(const SSL *s);
-OPENSSL_EXPORT const char *SSL_get_psk_identity(const SSL *s);
-
-#define SSL_NOTHING 1
-#define SSL_WRITING 2
-#define SSL_READING 3
-#define SSL_X509_LOOKUP 4
-#define SSL_CHANNEL_ID_LOOKUP 5
-#define SSL_PENDING_SESSION 7
-#define SSL_CERTIFICATE_SELECTION_PENDING 8
+ /* If true, a client will request certificate timestamps. */
+ unsigned signed_cert_timestamps_enabled:1;
-/* These will only be used when doing non-blocking IO */
-#define SSL_want_nothing(s) (SSL_want(s) == SSL_NOTHING)
-#define SSL_want_read(s) (SSL_want(s) == SSL_READING)
-#define SSL_want_write(s) (SSL_want(s) == SSL_WRITING)
-#define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP)
-#define SSL_want_channel_id_lookup(s) (SSL_want(s) == SSL_CHANNEL_ID_LOOKUP)
-#define SSL_want_session(s) (SSL_want(s) == SSL_PENDING_SESSION)
-#define SSL_want_certificate(s) \
- (SSL_want(s) == SSL_CERTIFICATE_SELECTION_PENDING)
+ /* tlsext_channel_id_enabled is copied from the |SSL_CTX|. For a server,
+ * means that we'll accept Channel IDs from clients. For a client, means that
+ * we'll advertise support. */
+ unsigned tlsext_channel_id_enabled:1;
+};
struct ssl_st {
/* version is the protocol version. */
int version;
- /* method is the method table corresponding to the current protocol (DTLS or
- * TLS). */
- const SSL_PROTOCOL_METHOD *method;
-
- /* enc_method is the method table corresponding to the current protocol
- * version. */
- const SSL3_ENC_METHOD *enc_method;
-
/* max_version is the maximum acceptable protocol version. If zero, the
* maximum supported version, currently (D)TLS 1.2, is used. */
uint16_t max_version;
@@ -1301,21 +3720,29 @@ struct ssl_st {
* minimum supported version, currently SSL 3.0 and DTLS 1.0, is used */
uint16_t min_version;
+ /* method is the method table corresponding to the current protocol (DTLS or
+ * TLS). */
+ const SSL_PROTOCOL_METHOD *method;
+
+ /* enc_method is the method table corresponding to the current protocol
+ * version. */
+ const SSL3_ENC_METHOD *enc_method;
+
/* There are 2 BIO's even though they are normally both the same. This is so
* data can be read and written to different handlers */
BIO *rbio; /* used by SSL_read */
BIO *wbio; /* used by SSL_write */
- BIO *bbio; /* used during session-id reuse to concatenate
- * messages */
- /* This holds a variable that indicates what we were doing when a 0 or -1 is
- * returned. This is needed for non-blocking IO so we know what request
- * needs re-doing when in SSL_accept or SSL_connect */
- int rwstate;
+ /* bbio, if non-NULL, is a buffer placed in front of |wbio| to pack handshake
+ * messages within one flight into a single |BIO_write|.
+ *
+ * TODO(davidben): This does not work right for DTLS. It assumes the MTU is
+ * smaller than the buffer size so that the buffer's internal flushing never
+ * kicks in. It also doesn't kick in for DTLS retransmission. Replace this
+ * with a better mechanism. */
+ BIO *bbio;
- /* true when we are actually in SSL_accept() or SSL_connect() */
- int in_handshake;
int (*handshake_func)(SSL *);
/* Imagine that here's a boolean member "init" that is switched as soon as
@@ -1324,19 +3751,9 @@ struct ssl_st {
* handshake_func is == 0 until then, we use this test instead of an "init"
* member. */
- /* server is true iff the this SSL* is the server half. Note: before the SSL*
- * is initialized by either SSL_set_accept_state or SSL_set_connect_state,
- * the side is not determined. In this state, server is always false. */
- int server;
-
- /* quiet_shutdown is true if the connection should not send a close_notify on
- * shutdown. */
- int quiet_shutdown;
-
int shutdown; /* we have shut things down, 0x01 sent, 0x02
* for received */
int state; /* where we are */
- int rstate; /* where we are when reading */
BUF_MEM *init_buf; /* buffer used during init */
uint8_t *init_msg; /* pointer to handshake message body, set by
@@ -1344,10 +3761,6 @@ struct ssl_st {
int init_num; /* amount read/written */
int init_off; /* amount read/written */
- /* used internally to point at a raw packet */
- uint8_t *packet;
- unsigned int packet_length;
-
struct ssl3_state_st *s3; /* SSLv3 variables */
struct dtls1_state_st *d1; /* DTLSv1 variables */
@@ -1356,8 +3769,6 @@ struct ssl_st {
const void *buf, size_t len, SSL *ssl, void *arg);
void *msg_callback_arg;
- int hit; /* reusing a previous session */
-
X509_VERIFY_PARAM *param;
/* crypto */
@@ -1373,6 +3784,11 @@ struct ssl_st {
/* This is used to hold the server certificate used */
struct cert_st /* CERT */ *cert;
+ /* This holds a variable that indicates what we were doing when a 0 or -1 is
+ * returned. This is needed for non-blocking IO so we know what request
+ * needs re-doing when in SSL_accept or SSL_connect */
+ int rwstate;
+
/* the session_id_context is used to ensure sessions are only reused
* in the appropriate context */
unsigned int sid_ctx_length;
@@ -1381,17 +3797,10 @@ struct ssl_st {
/* This can also be in the session once a session is established */
SSL_SESSION *session;
- /* Default generate session ID callback. */
- GEN_SESSION_CB generate_session_id;
-
- /* Used in SSL2 and SSL3 */
- int verify_mode; /* 0 don't care about verify failure.
- * 1 fail if verify fails */
int (*verify_callback)(int ok,
X509_STORE_CTX *ctx); /* fail if callback returns 0 */
- void (*info_callback)(const SSL *ssl, int type,
- int val); /* optional informational callback */
+ void (*info_callback)(const SSL *ssl, int type, int value);
/* Server-only: psk_identity_hint is the identity hint to send in
* PSK-based key exchanges. */
@@ -1420,13 +3829,8 @@ struct ssl_st {
* SSLv3/TLS rollback check */
uint16_t max_send_fragment;
char *tlsext_hostname;
- /* should_ack_sni is true if the SNI extension should be acked. This is
- * only used by a server. */
- char should_ack_sni;
/* RFC4507 session ticket expected to be received or sent */
int tlsext_ticket_expected;
- size_t tlsext_ecpointformatlist_length;
- uint8_t *tlsext_ecpointformatlist; /* our list */
size_t tlsext_ellipticcurvelist_length;
uint16_t *tlsext_ellipticcurvelist; /* our list */
@@ -1449,984 +3853,290 @@ struct ssl_st {
* DTLS-SRTP. */
const SRTP_PROTECTION_PROFILE *srtp_profile;
- /* Copied from the SSL_CTX. For a server, means that we'll accept Channel IDs
- * from clients. For a client, means that we'll advertise support. */
- char tlsext_channel_id_enabled;
/* The client's Channel ID private key. */
EVP_PKEY *tlsext_channel_id_private;
- /* Enable signed certificate time stamps. Currently client only. */
- char signed_cert_timestamps_enabled;
-
- /* Enable OCSP stapling. Currently client only.
- * TODO(davidben): Add a server-side implementation when it becomes
- * necesary. */
- char ocsp_stapling_enabled;
-
/* For a client, this contains the list of supported protocols in wire
* format. */
uint8_t *alpn_client_proto_list;
unsigned alpn_client_proto_list_len;
- /* fastradio_padding, if true, causes ClientHellos to be padded to 1024
- * bytes. This ensures that the cellular radio is fast forwarded to DCH (high
- * data rate) state in 3G networks. */
- char fastradio_padding;
-
- /* accept_peer_renegotiations, if one, accepts renegotiation attempts from the
- * peer. Otherwise, they will be rejected with a fatal error. */
- char accept_peer_renegotiations;
+ /* renegotiate_mode controls how peer renegotiation attempts are handled. */
+ enum ssl_renegotiate_mode_t renegotiate_mode;
/* These fields are always NULL and exist only to keep wpa_supplicant happy
* about the change to EVP_AEAD. They are only needed for EAP-FAST, which we
* don't support. */
EVP_CIPHER_CTX *enc_read_ctx;
EVP_MD_CTX *read_hash;
-};
-
-/* compatibility */
-#define SSL_set_app_data(s, arg) (SSL_set_ex_data(s, 0, (char *)arg))
-#define SSL_get_app_data(s) (SSL_get_ex_data(s, 0))
-#define SSL_SESSION_set_app_data(s, a) \
- (SSL_SESSION_set_ex_data(s, 0, (char *)a))
-#define SSL_SESSION_get_app_data(s) (SSL_SESSION_get_ex_data(s, 0))
-#define SSL_CTX_get_app_data(ctx) (SSL_CTX_get_ex_data(ctx, 0))
-#define SSL_CTX_set_app_data(ctx, arg) \
- (SSL_CTX_set_ex_data(ctx, 0, (char *)arg))
-
-/* The following are the possible values for ssl->state are are used to
- * indicate where we are up to in the SSL connection establishment. The macros
- * that follow are about the only things you should need to use and even then,
- * only when using non-blocking IO. It can also be useful to work out where you
- * were when the connection failed */
-
-#define SSL_ST_CONNECT 0x1000
-#define SSL_ST_ACCEPT 0x2000
-#define SSL_ST_MASK 0x0FFF
-#define SSL_ST_INIT (SSL_ST_CONNECT | SSL_ST_ACCEPT)
-#define SSL_ST_OK 0x03
-#define SSL_ST_RENEGOTIATE (0x04 | SSL_ST_INIT)
-
-#define SSL_CB_LOOP 0x01
-#define SSL_CB_EXIT 0x02
-#define SSL_CB_READ 0x04
-#define SSL_CB_WRITE 0x08
-#define SSL_CB_ALERT 0x4000 /* used in callback */
-#define SSL_CB_READ_ALERT (SSL_CB_ALERT | SSL_CB_READ)
-#define SSL_CB_WRITE_ALERT (SSL_CB_ALERT | SSL_CB_WRITE)
-#define SSL_CB_ACCEPT_LOOP (SSL_ST_ACCEPT | SSL_CB_LOOP)
-#define SSL_CB_ACCEPT_EXIT (SSL_ST_ACCEPT | SSL_CB_EXIT)
-#define SSL_CB_CONNECT_LOOP (SSL_ST_CONNECT | SSL_CB_LOOP)
-#define SSL_CB_CONNECT_EXIT (SSL_ST_CONNECT | SSL_CB_EXIT)
-#define SSL_CB_HANDSHAKE_START 0x10
-#define SSL_CB_HANDSHAKE_DONE 0x20
-
-/* Is the SSL_connection established? */
-#define SSL_get_state(a) SSL_state(a)
-#define SSL_is_init_finished(a) (SSL_state(a) == SSL_ST_OK)
-#define SSL_in_init(a) (SSL_state(a) & SSL_ST_INIT)
-#define SSL_in_connect_init(a) (SSL_state(a) & SSL_ST_CONNECT)
-#define SSL_in_accept_init(a) (SSL_state(a) & SSL_ST_ACCEPT)
-
-/* SSL_in_false_start returns one if |s| has a pending unfinished handshake that
- * is in False Start. |SSL_write| may be called at this point without waiting
- * for the peer, but |SSL_read| will require the handshake to be completed. */
-OPENSSL_EXPORT int SSL_in_false_start(const SSL *s);
-
-/* The following 2 states are kept in ssl->rstate when reads fail,
- * you should not need these */
-#define SSL_ST_READ_HEADER 0xF0
-#define SSL_ST_READ_BODY 0xF1
-#define SSL_ST_READ_DONE 0xF2
-
-/* Obtain latest Finished message
- * -- that we sent (SSL_get_finished)
- * -- that we expected from peer (SSL_get_peer_finished).
- * Returns length (0 == no Finished so far), copies up to 'count' bytes. */
-OPENSSL_EXPORT size_t SSL_get_finished(const SSL *s, void *buf, size_t count);
-OPENSSL_EXPORT size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count);
-
-/* use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 3 options
- * are 'ored' with SSL_VERIFY_PEER if they are desired */
-#define SSL_VERIFY_NONE 0x00
-#define SSL_VERIFY_PEER 0x01
-#define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02
-/* SSL_VERIFY_CLIENT_ONCE does nothing. */
-#define SSL_VERIFY_CLIENT_ONCE 0x04
-#define SSL_VERIFY_PEER_IF_NO_OBC 0x08
-
-#define OpenSSL_add_ssl_algorithms() SSL_library_init()
-#define SSLeay_add_ssl_algorithms() SSL_library_init()
-
-/* For backward compatibility */
-#define SSL_get_cipher(s) SSL_CIPHER_get_name(SSL_get_current_cipher(s))
-#define SSL_get_cipher_bits(s, np) \
- SSL_CIPHER_get_bits(SSL_get_current_cipher(s), np)
-#define SSL_get_cipher_version(s) \
- SSL_CIPHER_get_version(SSL_get_current_cipher(s))
-#define SSL_get_cipher_name(s) SSL_CIPHER_get_name(SSL_get_current_cipher(s))
-#define SSL_get_time(a) SSL_SESSION_get_time(a)
-#define SSL_set_time(a, b) SSL_SESSION_set_time((a), (b))
-#define SSL_get_timeout(a) SSL_SESSION_get_timeout(a)
-#define SSL_set_timeout(a, b) SSL_SESSION_set_timeout((a), (b))
-
-#define d2i_SSL_SESSION_bio(bp, s_id) \
- ASN1_d2i_bio_of(SSL_SESSION, SSL_SESSION_new, d2i_SSL_SESSION, bp, s_id)
-#define i2d_SSL_SESSION_bio(bp, s_id) \
- ASN1_i2d_bio_of(SSL_SESSION, i2d_SSL_SESSION, bp, s_id)
-DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
-
-/* make_errors.go reserves error codes above 1000 for manually-assigned errors.
- * This value must be kept in sync with reservedReasonCode in make_errors.h */
-#define SSL_AD_REASON_OFFSET \
- 1000 /* offset to get SSL_R_... value from SSL_AD_... */
-
-/* These alert types are for SSLv3 and TLSv1 */
-#define SSL_AD_CLOSE_NOTIFY SSL3_AD_CLOSE_NOTIFY
-#define SSL_AD_UNEXPECTED_MESSAGE SSL3_AD_UNEXPECTED_MESSAGE /* fatal */
-#define SSL_AD_BAD_RECORD_MAC SSL3_AD_BAD_RECORD_MAC /* fatal */
-#define SSL_AD_DECRYPTION_FAILED TLS1_AD_DECRYPTION_FAILED
-#define SSL_AD_RECORD_OVERFLOW TLS1_AD_RECORD_OVERFLOW
-#define SSL_AD_DECOMPRESSION_FAILURE SSL3_AD_DECOMPRESSION_FAILURE /* fatal */
-#define SSL_AD_HANDSHAKE_FAILURE SSL3_AD_HANDSHAKE_FAILURE /* fatal */
-#define SSL_AD_NO_CERTIFICATE SSL3_AD_NO_CERTIFICATE /* Not for TLS */
-#define SSL_AD_BAD_CERTIFICATE SSL3_AD_BAD_CERTIFICATE
-#define SSL_AD_UNSUPPORTED_CERTIFICATE SSL3_AD_UNSUPPORTED_CERTIFICATE
-#define SSL_AD_CERTIFICATE_REVOKED SSL3_AD_CERTIFICATE_REVOKED
-#define SSL_AD_CERTIFICATE_EXPIRED SSL3_AD_CERTIFICATE_EXPIRED
-#define SSL_AD_CERTIFICATE_UNKNOWN SSL3_AD_CERTIFICATE_UNKNOWN
-#define SSL_AD_ILLEGAL_PARAMETER SSL3_AD_ILLEGAL_PARAMETER /* fatal */
-#define SSL_AD_UNKNOWN_CA TLS1_AD_UNKNOWN_CA /* fatal */
-#define SSL_AD_ACCESS_DENIED TLS1_AD_ACCESS_DENIED /* fatal */
-#define SSL_AD_DECODE_ERROR TLS1_AD_DECODE_ERROR /* fatal */
-#define SSL_AD_DECRYPT_ERROR TLS1_AD_DECRYPT_ERROR
-#define SSL_AD_EXPORT_RESTRICTION TLS1_AD_EXPORT_RESTRICTION /* fatal */
-#define SSL_AD_PROTOCOL_VERSION TLS1_AD_PROTOCOL_VERSION /* fatal */
-#define SSL_AD_INSUFFICIENT_SECURITY TLS1_AD_INSUFFICIENT_SECURITY /* fatal */
-#define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR /* fatal */
-#define SSL_AD_USER_CANCELLED TLS1_AD_USER_CANCELLED
-#define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION
-#define SSL_AD_UNSUPPORTED_EXTENSION TLS1_AD_UNSUPPORTED_EXTENSION
-#define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE
-#define SSL_AD_UNRECOGNIZED_NAME TLS1_AD_UNRECOGNIZED_NAME
-#define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE \
- TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
-#define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
-#define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY /* fatal */
-#define SSL_AD_INAPPROPRIATE_FALLBACK SSL3_AD_INAPPROPRIATE_FALLBACK /* fatal */
-
-#define SSL_ERROR_NONE 0
-#define SSL_ERROR_SSL 1
-#define SSL_ERROR_WANT_READ 2
-#define SSL_ERROR_WANT_WRITE 3
-#define SSL_ERROR_WANT_X509_LOOKUP 4
-#define SSL_ERROR_SYSCALL 5 /* look at error stack/return value/errno */
-#define SSL_ERROR_ZERO_RETURN 6
-#define SSL_ERROR_WANT_CONNECT 7
-#define SSL_ERROR_WANT_ACCEPT 8
-#define SSL_ERROR_WANT_CHANNEL_ID_LOOKUP 9
-#define SSL_ERROR_PENDING_SESSION 11
-#define SSL_ERROR_PENDING_CERTIFICATE 12
-
-#define SSL_CTRL_EXTRA_CHAIN_CERT 14
-
-/* see tls1.h for macros based on these */
-#define SSL_CTRL_GET_TLSEXT_TICKET_KEYS 58
-#define SSL_CTRL_SET_TLSEXT_TICKET_KEYS 59
-
-#define SSL_CTRL_SET_SRP_ARG 78
-#define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME 79
-#define SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH 80
-#define SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD 81
-
-#define SSL_CTRL_GET_EXTRA_CHAIN_CERTS 82
-#define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS 83
-
-#define SSL_CTRL_CHAIN 88
-#define SSL_CTRL_CHAIN_CERT 89
-
-#define SSL_CTRL_GET_CURVES 90
-#define SSL_CTRL_SET_CURVES 91
-#define SSL_CTRL_SET_CURVES_LIST 92
-#define SSL_CTRL_SET_SIGALGS 97
-#define SSL_CTRL_SET_SIGALGS_LIST 98
-#define SSL_CTRL_SET_CLIENT_SIGALGS 101
-#define SSL_CTRL_SET_CLIENT_SIGALGS_LIST 102
-#define SSL_CTRL_GET_CLIENT_CERT_TYPES 103
-#define SSL_CTRL_SET_CLIENT_CERT_TYPES 104
-#define SSL_CTRL_BUILD_CERT_CHAIN 105
-#define SSL_CTRL_SET_VERIFY_CERT_STORE 106
-#define SSL_CTRL_SET_CHAIN_CERT_STORE 107
-#define SSL_CTRL_GET_SERVER_TMP_KEY 109
-#define SSL_CTRL_GET_EC_POINT_FORMATS 111
-
-#define SSL_CTRL_GET_CHAIN_CERTS 115
-#define SSL_CTRL_SELECT_CURRENT_CERT 116
-
-/* DTLSv1_get_timeout queries the next DTLS handshake timeout. If there is a
- * timeout in progress, it sets |*out| to the time remaining and returns one.
- * Otherwise, it returns zero.
- *
- * When the timeout expires, call |DTLSv1_handle_timeout| to handle the
- * retransmit behavior.
- *
- * NOTE: This function must be queried again whenever the handshake state
- * machine changes, including when |DTLSv1_handle_timeout| is called. */
-OPENSSL_EXPORT int DTLSv1_get_timeout(const SSL *ssl, struct timeval *out);
-
-/* DTLSv1_handle_timeout is called when a DTLS handshake timeout expires. If no
- * timeout had expired, it returns 0. Otherwise, it retransmits the previous
- * flight of handshake messages and returns 1. If too many timeouts had expired
- * without progress or an error occurs, it returns -1.
- *
- * NOTE: The caller's external timer should be compatible with the one |ssl|
- * queries within some fudge factor. Otherwise, the call will be a no-op, but
- * |DTLSv1_get_timeout| will return an updated timeout.
- *
- * WARNING: This function breaks the usual return value convention. */
-OPENSSL_EXPORT int DTLSv1_handle_timeout(SSL *ssl);
-
-/* SSL_session_reused returns one if |ssl| performed an abbreviated handshake
- * and zero otherwise.
- *
- * TODO(davidben): Hammer down the semantics of this API while a handshake,
- * initial or renego, is in progress. */
-OPENSSL_EXPORT int SSL_session_reused(const SSL *ssl);
-
-/* SSL_total_renegotiations returns the total number of renegotiation handshakes
- * peformed by |ssl|. This includes the pending renegotiation, if any. */
-OPENSSL_EXPORT int SSL_total_renegotiations(const SSL *ssl);
-
-/* SSL_CTX_set_tmp_dh configures |ctx| to use the group from |dh| as the group
- * for DHE. Only the group is used, so |dh| needn't have a keypair. It returns
- * one on success and zero on error. */
-OPENSSL_EXPORT int SSL_CTX_set_tmp_dh(SSL_CTX *ctx, const DH *dh);
-
-/* SSL_set_tmp_dh configures |ssl| to use the group from |dh| as the group for
- * DHE. Only the group is used, so |dh| needn't have a keypair. It returns one
- * on success and zero on error. */
-OPENSSL_EXPORT int SSL_set_tmp_dh(SSL *ssl, const DH *dh);
-
-/* 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 automatically. (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 automatically. (This is
- * recommended.) */
-OPENSSL_EXPORT int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key);
-
-/* SSL_CTX_enable_tls_channel_id either configures a TLS server to accept TLS
- * client IDs from clients, or configures a client to send TLS client IDs to
- * a server. It returns one. */
-OPENSSL_EXPORT int SSL_CTX_enable_tls_channel_id(SSL_CTX *ctx);
-
-/* SSL_enable_tls_channel_id either configures a TLS server to accept TLS
- * client IDs from clients, or configure a client to send TLS client IDs to
- * server. It returns one. */
-OPENSSL_EXPORT int SSL_enable_tls_channel_id(SSL *ssl);
-
-/* SSL_CTX_set1_tls_channel_id configures a TLS client to send a TLS Channel ID
- * to compatible servers. |private_key| must be a P-256 EC key. It returns one
- * on success and zero on error. */
-OPENSSL_EXPORT int SSL_CTX_set1_tls_channel_id(SSL_CTX *ctx,
- EVP_PKEY *private_key);
-
-/* SSL_set1_tls_channel_id configures a TLS client to send a TLS Channel ID to
- * compatible servers. |private_key| must be a P-256 EC key. It returns one on
- * success and zero on error. */
-OPENSSL_EXPORT int SSL_set1_tls_channel_id(SSL *ssl, EVP_PKEY *private_key);
-
-/* SSL_get_tls_channel_id gets the client's TLS Channel ID from a server SSL*
- * and copies up to the first |max_out| bytes into |out|. The Channel ID
- * consists of the client's P-256 public key as an (x,y) pair where each is a
- * 32-byte, big-endian field element. It returns 0 if the client didn't offer a
- * Channel ID and the length of the complete Channel ID otherwise. */
-OPENSSL_EXPORT size_t SSL_get_tls_channel_id(SSL *ssl, uint8_t *out,
- size_t max_out);
-
-#define SSL_CTX_add_extra_chain_cert(ctx, x509) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0, (char *)x509)
-#define SSL_CTX_get_extra_chain_certs(ctx, px509) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_GET_EXTRA_CHAIN_CERTS, 0, px509)
-#define SSL_CTX_get_extra_chain_certs_only(ctx, px509) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_GET_EXTRA_CHAIN_CERTS, 1, px509)
-#define SSL_CTX_clear_extra_chain_certs(ctx) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS, 0, NULL)
-
-#define SSL_CTX_set0_chain(ctx, sk) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_CHAIN, 0, (char *)sk)
-#define SSL_CTX_set1_chain(ctx, sk) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_CHAIN, 1, (char *)sk)
-#define SSL_CTX_add0_chain_cert(ctx, x509) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_CHAIN_CERT, 0, (char *)x509)
-#define SSL_CTX_add1_chain_cert(ctx, x509) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_CHAIN_CERT, 1, (char *)x509)
-#define SSL_CTX_get0_chain_certs(ctx, px509) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_GET_CHAIN_CERTS, 0, px509)
-#define SSL_CTX_clear_chain_certs(ctx) SSL_CTX_set0_chain(ctx, NULL)
-#define SSL_CTX_build_cert_chain(ctx, flags) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL)
-#define SSL_CTX_select_current_cert(ctx, x509) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_SELECT_CURRENT_CERT, 0, (char *)x509)
-
-#define SSL_CTX_set0_verify_cert_store(ctx, st) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_SET_VERIFY_CERT_STORE, 0, (char *)st)
-#define SSL_CTX_set1_verify_cert_store(ctx, st) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_SET_VERIFY_CERT_STORE, 1, (char *)st)
-#define SSL_CTX_set0_chain_cert_store(ctx, st) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_SET_CHAIN_CERT_STORE, 0, (char *)st)
-#define SSL_CTX_set1_chain_cert_store(ctx, st) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_SET_CHAIN_CERT_STORE, 1, (char *)st)
-
-#define SSL_set0_chain(ctx, sk) SSL_ctrl(ctx, SSL_CTRL_CHAIN, 0, (char *)sk)
-#define SSL_set1_chain(ctx, sk) SSL_ctrl(ctx, SSL_CTRL_CHAIN, 1, (char *)sk)
-#define SSL_add0_chain_cert(ctx, x509) \
- SSL_ctrl(ctx, SSL_CTRL_CHAIN_CERT, 0, (char *)x509)
-#define SSL_add1_chain_cert(ctx, x509) \
- SSL_ctrl(ctx, SSL_CTRL_CHAIN_CERT, 1, (char *)x509)
-#define SSL_get0_chain_certs(ctx, px509) \
- SSL_ctrl(ctx, SSL_CTRL_GET_CHAIN_CERTS, 0, px509)
-#define SSL_clear_chain_certs(ctx) SSL_set0_chain(ctx, NULL)
-#define SSL_build_cert_chain(s, flags) \
- SSL_ctrl(s, SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL)
-#define SSL_select_current_cert(ctx, x509) \
- SSL_ctrl(ctx, SSL_CTRL_SELECT_CURRENT_CERT, 0, (char *)x509)
-
-#define SSL_set0_verify_cert_store(s, st) \
- SSL_ctrl(s, SSL_CTRL_SET_VERIFY_CERT_STORE, 0, (char *)st)
-#define SSL_set1_verify_cert_store(s, st) \
- SSL_ctrl(s, SSL_CTRL_SET_VERIFY_CERT_STORE, 1, (char *)st)
-#define SSL_set0_chain_cert_store(s, st) \
- SSL_ctrl(s, SSL_CTRL_SET_CHAIN_CERT_STORE, 0, (char *)st)
-#define SSL_set1_chain_cert_store(s, st) \
- SSL_ctrl(s, SSL_CTRL_SET_CHAIN_CERT_STORE, 1, (char *)st)
-
-#define SSL_get1_curves(ctx, s) SSL_ctrl(ctx, SSL_CTRL_GET_CURVES, 0, (char *)s)
-#define SSL_CTX_set1_curves(ctx, clist, clistlen) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_SET_CURVES, clistlen, (char *)clist)
-#define SSL_CTX_set1_curves_list(ctx, s) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_SET_CURVES_LIST, 0, (char *)s)
-#define SSL_set1_curves(ctx, clist, clistlen) \
- SSL_ctrl(ctx, SSL_CTRL_SET_CURVES, clistlen, (char *)clist)
-#define SSL_set1_curves_list(ctx, s) \
- SSL_ctrl(ctx, SSL_CTRL_SET_CURVES_LIST, 0, (char *)s)
-
-#define SSL_CTX_set1_sigalgs(ctx, slist, slistlen) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_SET_SIGALGS, slistlen, (int *)slist)
-#define SSL_CTX_set1_sigalgs_list(ctx, s) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_SET_SIGALGS_LIST, 0, (char *)s)
-#define SSL_set1_sigalgs(ctx, slist, slistlen) \
- SSL_ctrl(ctx, SSL_CTRL_SET_SIGALGS, clistlen, (int *)slist)
-#define SSL_set1_sigalgs_list(ctx, s) \
- SSL_ctrl(ctx, SSL_CTRL_SET_SIGALGS_LIST, 0, (char *)s)
-
-#define SSL_CTX_set1_client_sigalgs(ctx, slist, slistlen) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_SET_CLIENT_SIGALGS, slistlen, (int *)slist)
-#define SSL_CTX_set1_client_sigalgs_list(ctx, s) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_SET_CLIENT_SIGALGS_LIST, 0, (char *)s)
-#define SSL_set1_client_sigalgs(ctx, slist, slistlen) \
- SSL_ctrl(ctx, SSL_CTRL_SET_CLIENT_SIGALGS, clistlen, (int *)slist)
-#define SSL_set1_client_sigalgs_list(ctx, s) \
- SSL_ctrl(ctx, SSL_CTRL_SET_CLIENT_SIGALGS_LIST, 0, (char *)s)
-
-#define SSL_get0_certificate_types(s, clist) \
- SSL_ctrl(s, SSL_CTRL_GET_CLIENT_CERT_TYPES, 0, (char *)clist)
-
-#define SSL_CTX_set1_client_certificate_types(ctx, clist, clistlen) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_SET_CLIENT_CERT_TYPES, clistlen, (char *)clist)
-#define SSL_set1_client_certificate_types(s, clist, clistlen) \
- SSL_ctrl(s, SSL_CTRL_SET_CLIENT_CERT_TYPES, clistlen, (char *)clist)
-
-#define SSL_get_server_tmp_key(s, pk) \
- SSL_ctrl(s, SSL_CTRL_GET_SERVER_TMP_KEY, 0, pk)
-
-#define SSL_get0_ec_point_formats(s, plst) \
- SSL_ctrl(s, SSL_CTRL_GET_EC_POINT_FORMATS, 0, (char *)plst)
-
-OPENSSL_EXPORT int SSL_CTX_set_cipher_list(SSL_CTX *, const char *str);
-OPENSSL_EXPORT int SSL_CTX_set_cipher_list_tls11(SSL_CTX *, const char *str);
-OPENSSL_EXPORT long SSL_CTX_set_timeout(SSL_CTX *ctx, long t);
-OPENSSL_EXPORT long SSL_CTX_get_timeout(const SSL_CTX *ctx);
-OPENSSL_EXPORT X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *);
-OPENSSL_EXPORT void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *);
-OPENSSL_EXPORT int SSL_want(const SSL *s);
-
-OPENSSL_EXPORT void SSL_CTX_flush_sessions(SSL_CTX *ctx, long tm);
-
-/* SSL_get_current_cipher returns the cipher used in the current outgoing
- * connection state, or NULL if the null cipher is active. */
-OPENSSL_EXPORT const SSL_CIPHER *SSL_get_current_cipher(const SSL *s);
-
-OPENSSL_EXPORT int SSL_get_fd(const SSL *s);
-OPENSSL_EXPORT int SSL_get_rfd(const SSL *s);
-OPENSSL_EXPORT int SSL_get_wfd(const SSL *s);
-OPENSSL_EXPORT const char *SSL_get_cipher_list(const SSL *s, int n);
-OPENSSL_EXPORT int SSL_pending(const SSL *s);
-OPENSSL_EXPORT int SSL_set_fd(SSL *s, int fd);
-OPENSSL_EXPORT int SSL_set_rfd(SSL *s, int fd);
-OPENSSL_EXPORT int SSL_set_wfd(SSL *s, int fd);
-OPENSSL_EXPORT void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio);
-OPENSSL_EXPORT BIO *SSL_get_rbio(const SSL *s);
-OPENSSL_EXPORT BIO *SSL_get_wbio(const SSL *s);
-OPENSSL_EXPORT int SSL_set_cipher_list(SSL *s, const char *str);
-OPENSSL_EXPORT int SSL_get_verify_mode(const SSL *s);
-OPENSSL_EXPORT int SSL_get_verify_depth(const SSL *s);
-OPENSSL_EXPORT int (*SSL_get_verify_callback(const SSL *s))(int,
- X509_STORE_CTX *);
-OPENSSL_EXPORT void SSL_set_verify(SSL *s, int mode,
- int (*callback)(int ok,
- X509_STORE_CTX *ctx));
-OPENSSL_EXPORT void SSL_set_verify_depth(SSL *s, int depth);
-OPENSSL_EXPORT void SSL_set_cert_cb(SSL *s, int (*cb)(SSL *ssl, void *arg),
- void *arg);
-OPENSSL_EXPORT int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa);
-OPENSSL_EXPORT int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, uint8_t *d, long len);
-OPENSSL_EXPORT int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey);
-OPENSSL_EXPORT int SSL_use_PrivateKey_ASN1(int pk, SSL *ssl, const uint8_t *d,
- long len);
-OPENSSL_EXPORT int SSL_use_certificate(SSL *ssl, X509 *x);
-OPENSSL_EXPORT int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *d,
- int len);
-
-OPENSSL_EXPORT int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file,
- int type);
-OPENSSL_EXPORT int SSL_use_PrivateKey_file(SSL *ssl, const char *file,
- int type);
-OPENSSL_EXPORT int SSL_use_certificate_file(SSL *ssl, const char *file,
- int type);
-OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx,
- const char *file, int type);
-OPENSSL_EXPORT int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file,
- int type);
-OPENSSL_EXPORT int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file,
- int type);
-OPENSSL_EXPORT int SSL_CTX_use_certificate_chain_file(
- SSL_CTX *ctx, const char *file); /* PEM type */
-OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file);
-OPENSSL_EXPORT int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *
- stackCAs,
- const char *file);
-OPENSSL_EXPORT int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *
- stackCAs,
- const char *dir);
-
-/* SSL_load_error_strings does nothing. */
-OPENSSL_EXPORT void SSL_load_error_strings(void);
-
-OPENSSL_EXPORT const char *SSL_state_string(const SSL *s);
-OPENSSL_EXPORT const char *SSL_rstate_string(const SSL *s);
-OPENSSL_EXPORT const char *SSL_state_string_long(const SSL *s);
-OPENSSL_EXPORT const char *SSL_rstate_string_long(const SSL *s);
-OPENSSL_EXPORT long SSL_SESSION_get_time(const SSL_SESSION *s);
-OPENSSL_EXPORT long SSL_SESSION_set_time(SSL_SESSION *s, long t);
-OPENSSL_EXPORT long SSL_SESSION_get_timeout(const SSL_SESSION *s);
-OPENSSL_EXPORT long SSL_SESSION_set_timeout(SSL_SESSION *s, long t);
-OPENSSL_EXPORT X509 *SSL_SESSION_get0_peer(SSL_SESSION *s);
-OPENSSL_EXPORT int SSL_SESSION_set1_id_context(SSL_SESSION *s,
- const uint8_t *sid_ctx,
- unsigned int sid_ctx_len);
-
-OPENSSL_EXPORT SSL_SESSION *SSL_SESSION_new(void);
-OPENSSL_EXPORT const uint8_t *SSL_SESSION_get_id(const SSL_SESSION *s,
- unsigned int *len);
-OPENSSL_EXPORT int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *ses);
-OPENSSL_EXPORT int SSL_SESSION_print(BIO *fp, const SSL_SESSION *ses);
-
-/* SSL_SESSION_up_ref, if |session| is not NULL, increments the reference count
- * of |session|. It then returns |session|. */
-OPENSSL_EXPORT SSL_SESSION *SSL_SESSION_up_ref(SSL_SESSION *session);
-
-/* SSL_SESSION_free decrements the reference count of |session|. If it reaches
- * zero, all data referenced by |session| and |session| itself are released. */
-OPENSSL_EXPORT void SSL_SESSION_free(SSL_SESSION *session);
-
-OPENSSL_EXPORT int SSL_set_session(SSL *to, SSL_SESSION *session);
-OPENSSL_EXPORT int SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c);
-OPENSSL_EXPORT int SSL_CTX_remove_session(SSL_CTX *, SSL_SESSION *c);
-OPENSSL_EXPORT int SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB);
-OPENSSL_EXPORT int SSL_set_generate_session_id(SSL *, GEN_SESSION_CB);
-OPENSSL_EXPORT int SSL_has_matching_session_id(const SSL *ssl,
- const uint8_t *id,
- unsigned int id_len);
-
-/* SSL_SESSION_to_bytes serializes |in| into a newly allocated buffer and sets
- * |*out_data| to that buffer and |*out_len| to its length. The caller takes
- * ownership of the buffer and must call |OPENSSL_free| when done. It returns
- * one on success and zero on error. */
-OPENSSL_EXPORT int SSL_SESSION_to_bytes(SSL_SESSION *in, uint8_t **out_data,
- size_t *out_len);
-
-/* SSL_SESSION_to_bytes_for_ticket serializes |in|, but excludes the session ID
- * which is not necessary in a session ticket. */
-OPENSSL_EXPORT int SSL_SESSION_to_bytes_for_ticket(SSL_SESSION *in,
- uint8_t **out_data,
- size_t *out_len);
-
-/* Deprecated: i2d_SSL_SESSION serializes |in| to the bytes pointed to by
- * |*pp|. On success, it returns the number of bytes written and advances |*pp|
- * by that many bytes. On failure, it returns -1. If |pp| is NULL, no bytes are
- * written and only the length is returned.
- *
- * Use SSL_SESSION_to_bytes instead. */
-OPENSSL_EXPORT int i2d_SSL_SESSION(SSL_SESSION *in, uint8_t **pp);
-
-/* d2i_SSL_SESSION deserializes a serialized buffer contained in the |length|
- * bytes pointed to by |*pp|. It returns the new SSL_SESSION and advances |*pp|
- * by the number of bytes consumed on success and NULL on failure. If |a| is
- * NULL, the caller takes ownership of the new session and must call
- * |SSL_SESSION_free| when done.
- *
- * If |a| and |*a| are not NULL, the SSL_SESSION at |*a| is overridden with the
- * deserialized session rather than allocating a new one. In addition, |a| is
- * not NULL, but |*a| is, |*a| is set to the new SSL_SESSION.
- *
- * Passing a value other than NULL to |a| is deprecated. */
-OPENSSL_EXPORT SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const uint8_t **pp,
- long length);
-
-OPENSSL_EXPORT X509 *SSL_get_peer_certificate(const SSL *s);
-
-OPENSSL_EXPORT STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s);
-
-OPENSSL_EXPORT int SSL_CTX_get_verify_mode(const SSL_CTX *ctx);
-OPENSSL_EXPORT int SSL_CTX_get_verify_depth(const SSL_CTX *ctx);
-OPENSSL_EXPORT int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(
- int, X509_STORE_CTX *);
-OPENSSL_EXPORT void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
- int (*callback)(int, X509_STORE_CTX *));
-OPENSSL_EXPORT void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth);
-OPENSSL_EXPORT void SSL_CTX_set_cert_verify_callback(
- SSL_CTX *ctx, int (*cb)(X509_STORE_CTX *, void *), void *arg);
-OPENSSL_EXPORT void SSL_CTX_set_cert_cb(SSL_CTX *c,
- int (*cb)(SSL *ssl, void *arg),
- void *arg);
-OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa);
-OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx,
- const uint8_t *d, long len);
-OPENSSL_EXPORT int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey);
-OPENSSL_EXPORT int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx,
- const uint8_t *d, long len);
-OPENSSL_EXPORT int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);
-OPENSSL_EXPORT int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len,
- const uint8_t *d);
-
-OPENSSL_EXPORT void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx,
- pem_password_cb *cb);
-OPENSSL_EXPORT void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx,
- void *u);
-
-OPENSSL_EXPORT int SSL_CTX_check_private_key(const SSL_CTX *ctx);
-OPENSSL_EXPORT int SSL_check_private_key(const SSL *ctx);
-
-OPENSSL_EXPORT int SSL_CTX_set_session_id_context(SSL_CTX *ctx,
- const uint8_t *sid_ctx,
- unsigned int sid_ctx_len);
-
-OPENSSL_EXPORT int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx,
- unsigned int sid_ctx_len);
-
-OPENSSL_EXPORT int SSL_CTX_set_purpose(SSL_CTX *s, int purpose);
-OPENSSL_EXPORT int SSL_set_purpose(SSL *s, int purpose);
-OPENSSL_EXPORT int SSL_CTX_set_trust(SSL_CTX *s, int trust);
-OPENSSL_EXPORT int SSL_set_trust(SSL *s, int trust);
-
-OPENSSL_EXPORT int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm);
-OPENSSL_EXPORT int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm);
-
-OPENSSL_EXPORT X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx);
-OPENSSL_EXPORT X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl);
-
-OPENSSL_EXPORT void SSL_certs_clear(SSL *s);
-OPENSSL_EXPORT int SSL_accept(SSL *ssl);
-OPENSSL_EXPORT int SSL_connect(SSL *ssl);
-OPENSSL_EXPORT int SSL_read(SSL *ssl, void *buf, int num);
-OPENSSL_EXPORT int SSL_peek(SSL *ssl, void *buf, int num);
-OPENSSL_EXPORT int SSL_write(SSL *ssl, const void *buf, int num);
-OPENSSL_EXPORT long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg);
-OPENSSL_EXPORT long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg);
-
-OPENSSL_EXPORT int SSL_get_error(const SSL *s, int ret_code);
-/* SSL_get_version returns a string describing the TLS version used by |s|. For
- * example, "TLSv1.2" or "SSLv3". */
-OPENSSL_EXPORT const char *SSL_get_version(const SSL *s);
-/* SSL_SESSION_get_version returns a string describing the TLS version used by
- * |sess|. For example, "TLSv1.2" or "SSLv3". */
-OPENSSL_EXPORT const char *SSL_SESSION_get_version(const SSL_SESSION *sess);
-
-OPENSSL_EXPORT STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s);
-
-OPENSSL_EXPORT int SSL_do_handshake(SSL *s);
-
-/* SSL_renegotiate_pending returns one if |ssl| is in the middle of a
- * renegotiation. */
-OPENSSL_EXPORT int SSL_renegotiate_pending(SSL *ssl);
-
-OPENSSL_EXPORT int SSL_shutdown(SSL *s);
-
-OPENSSL_EXPORT const char *SSL_alert_type_string_long(int value);
-OPENSSL_EXPORT const char *SSL_alert_type_string(int value);
-OPENSSL_EXPORT const char *SSL_alert_desc_string_long(int value);
-OPENSSL_EXPORT const char *SSL_alert_desc_string(int value);
-
-OPENSSL_EXPORT void SSL_set_client_CA_list(SSL *s,
- STACK_OF(X509_NAME) *name_list);
-OPENSSL_EXPORT void SSL_CTX_set_client_CA_list(SSL_CTX *ctx,
- STACK_OF(X509_NAME) *name_list);
-OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s);
-OPENSSL_EXPORT STACK_OF(X509_NAME) *
- SSL_CTX_get_client_CA_list(const SSL_CTX *s);
-OPENSSL_EXPORT int SSL_add_client_CA(SSL *ssl, X509 *x);
-OPENSSL_EXPORT int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x);
-
-OPENSSL_EXPORT long SSL_get_default_timeout(const SSL *s);
-
-OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk);
-
-OPENSSL_EXPORT X509 *SSL_get_certificate(const SSL *ssl);
-OPENSSL_EXPORT EVP_PKEY *SSL_get_privatekey(const SSL *ssl);
-
-OPENSSL_EXPORT X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx);
-OPENSSL_EXPORT EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx);
-
-OPENSSL_EXPORT void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode);
-OPENSSL_EXPORT int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx);
-OPENSSL_EXPORT void SSL_set_quiet_shutdown(SSL *ssl, int mode);
-OPENSSL_EXPORT int SSL_get_quiet_shutdown(const SSL *ssl);
-OPENSSL_EXPORT void SSL_set_shutdown(SSL *ssl, int mode);
-OPENSSL_EXPORT int SSL_get_shutdown(const SSL *ssl);
-OPENSSL_EXPORT int SSL_version(const SSL *ssl);
-OPENSSL_EXPORT int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx);
-OPENSSL_EXPORT int SSL_CTX_load_verify_locations(SSL_CTX *ctx,
- const char *CAfile,
- const char *CApath);
-#define SSL_get0_session SSL_get_session /* just peek at pointer */
-OPENSSL_EXPORT SSL_SESSION *SSL_get_session(const SSL *ssl);
-OPENSSL_EXPORT SSL_SESSION *SSL_get1_session(
- SSL *ssl); /* obtain a reference count */
-OPENSSL_EXPORT SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl);
-OPENSSL_EXPORT SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx);
-OPENSSL_EXPORT void SSL_set_info_callback(SSL *ssl,
- void (*cb)(const SSL *ssl, int type,
- int val));
-OPENSSL_EXPORT void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl,
- int type, int val);
-OPENSSL_EXPORT int SSL_state(const SSL *ssl);
-
-OPENSSL_EXPORT void SSL_set_verify_result(SSL *ssl, long v);
-OPENSSL_EXPORT long SSL_get_verify_result(const SSL *ssl);
-
-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_dup *dup_func,
- CRYPTO_EX_free *free_func);
-
-OPENSSL_EXPORT int SSL_SESSION_set_ex_data(SSL_SESSION *ss, int idx,
- void *data);
-OPENSSL_EXPORT void *SSL_SESSION_get_ex_data(const SSL_SESSION *ss, int idx);
-OPENSSL_EXPORT int SSL_SESSION_get_ex_new_index(long argl, void *argp,
- CRYPTO_EX_new *new_func,
- CRYPTO_EX_dup *dup_func,
- CRYPTO_EX_free *free_func);
-
-OPENSSL_EXPORT int SSL_CTX_set_ex_data(SSL_CTX *ssl, int idx, void *data);
-OPENSSL_EXPORT void *SSL_CTX_get_ex_data(const SSL_CTX *ssl, int idx);
-OPENSSL_EXPORT int SSL_CTX_get_ex_new_index(long argl, void *argp,
- CRYPTO_EX_new *new_func,
- CRYPTO_EX_dup *dup_func,
- CRYPTO_EX_free *free_func);
-
-OPENSSL_EXPORT int SSL_get_ex_data_X509_STORE_CTX_idx(void);
-
-/* SSL_CTX_sess_set_cache_size sets the maximum size of |ctx|'s session cache to
- * |size|. It returns the previous value. */
-OPENSSL_EXPORT unsigned long SSL_CTX_sess_set_cache_size(SSL_CTX *ctx,
- unsigned long size);
-
-/* SSL_CTX_sess_get_cache_size returns the maximum size of |ctx|'s session
- * cache. */
-OPENSSL_EXPORT unsigned long SSL_CTX_sess_get_cache_size(const SSL_CTX *ctx);
-
-/* SSL_SESS_CACHE_* are the possible session cache mode bits.
- * TODO(davidben): Document. */
-#define SSL_SESS_CACHE_OFF 0x0000
-#define SSL_SESS_CACHE_CLIENT 0x0001
-#define SSL_SESS_CACHE_SERVER 0x0002
-#define SSL_SESS_CACHE_BOTH (SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_SERVER)
-#define SSL_SESS_CACHE_NO_AUTO_CLEAR 0x0080
-#define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP 0x0100
-#define SSL_SESS_CACHE_NO_INTERNAL_STORE 0x0200
-#define SSL_SESS_CACHE_NO_INTERNAL \
- (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP | SSL_SESS_CACHE_NO_INTERNAL_STORE)
-
-/* SSL_CTX_set_session_cache_mode sets the session cache mode bits for |ctx| to
- * |mode|. It returns the previous value. */
-OPENSSL_EXPORT int SSL_CTX_set_session_cache_mode(SSL_CTX *ctx, int mode);
-
-/* SSL_CTX_get_session_cache_mode returns the session cache mode bits for
- * |ctx| */
-OPENSSL_EXPORT int SSL_CTX_get_session_cache_mode(const SSL_CTX *ctx);
-
-/* SSL_CTX_get_max_cert_list returns the maximum length, in bytes, of a peer
- * certificate chain accepted by |ctx|. */
-OPENSSL_EXPORT size_t SSL_CTX_get_max_cert_list(const SSL_CTX *ctx);
-
-/* SSL_CTX_set_max_cert_list sets the maximum length, in bytes, of a peer
- * certificate chain to |max_cert_list|. This affects how much memory may be
- * consumed during the handshake. */
-OPENSSL_EXPORT void SSL_CTX_set_max_cert_list(SSL_CTX *ctx,
- size_t max_cert_list);
-
-/* SSL_get_max_cert_list returns the maximum length, in bytes, of a peer
- * certificate chain accepted by |ssl|. */
-OPENSSL_EXPORT size_t SSL_get_max_cert_list(const SSL *ssl);
-
-/* SSL_set_max_cert_list sets the maximum length, in bytes, of a peer
- * certificate chain to |max_cert_list|. This affects how much memory may be
- * consumed during the handshake. */
-OPENSSL_EXPORT void SSL_set_max_cert_list(SSL *ssl, size_t max_cert_list);
-
-/* SSL_CTX_set_max_send_fragment sets the maximum length, in bytes, of records
- * sent by |ctx|. Beyond this length, handshake messages and application data
- * will be split into multiple records. */
-OPENSSL_EXPORT void SSL_CTX_set_max_send_fragment(SSL_CTX *ctx,
- size_t max_send_fragment);
-
-/* SSL_set_max_send_fragment sets the maximum length, in bytes, of records
- * sent by |ssl|. Beyond this length, handshake messages and application data
- * will be split into multiple records. */
-OPENSSL_EXPORT void SSL_set_max_send_fragment(SSL *ssl,
- size_t max_send_fragment);
-
-/* SSL_CTX_set_tmp_dh_callback configures |ctx| to use |callback| to determine
- * the group for DHE ciphers. |callback| should ignore |is_export| and
- * |keylength| and return a |DH| of the selected group or NULL on error. Only
- * the parameters are used, so the |DH| needn't have a generated keypair.
- *
- * WARNING: The caller does not take ownership of the resulting |DH|, so
- * |callback| must save and release the object elsewhere. */
-OPENSSL_EXPORT void SSL_CTX_set_tmp_dh_callback(
- SSL_CTX *ctx, DH *(*callback)(SSL *ssl, int is_export, int keylength));
-
-/* SSL_set_tmp_dh_callback configures |ssl| to use |callback| to determine the
- * group for DHE ciphers. |callback| should ignore |is_export| and |keylength|
- * and return a |DH| of the selected group or NULL on error. Only the
- * parameters are used, so the |DH| needn't have a generated keypair.
- *
- * WARNING: The caller does not take ownership of the resulting |DH|, so
- * |callback| must save and release the object elsewhere. */
-OPENSSL_EXPORT void SSL_set_tmp_dh_callback(SSL *ssl,
- DH *(*dh)(SSL *ssl, int is_export,
- int keylength));
-
-/* 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 automatically.
- * (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 automatically.
- * (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));
-
-OPENSSL_EXPORT const void *SSL_get_current_compression(SSL *s);
-OPENSSL_EXPORT const void *SSL_get_current_expansion(SSL *s);
-
-OPENSSL_EXPORT int SSL_cache_hit(SSL *s);
-OPENSSL_EXPORT int SSL_is_server(SSL *s);
-
-/* SSL_CTX_set_dos_protection_cb sets a callback that is called once the
- * resumption decision for a ClientHello has been made. It can return 1 to
- * allow the handshake to continue or zero to cause the handshake to abort. */
-OPENSSL_EXPORT void SSL_CTX_set_dos_protection_cb(
- SSL_CTX *ctx, int (*cb)(const struct ssl_early_callback_ctx *));
-
-/* SSL_get_structure_sizes returns the sizes of the SSL, SSL_CTX and
- * SSL_SESSION structures so that a test can ensure that outside code agrees on
- * these values. */
-OPENSSL_EXPORT void SSL_get_structure_sizes(size_t *ssl_size,
- size_t *ssl_ctx_size,
- size_t *ssl_session_size);
-
-OPENSSL_EXPORT void ERR_load_SSL_strings(void);
-
-/* SSL_get_rc4_state sets |*read_key| and |*write_key| to the RC4 states for
- * the read and write directions. It returns one on success or zero if |ssl|
- * isn't using an RC4-based cipher suite. */
-OPENSSL_EXPORT int SSL_get_rc4_state(const SSL *ssl, const RC4_KEY **read_key,
- const RC4_KEY **write_key);
-
-
-/* Deprecated functions. */
-
-/* SSL_CIPHER_description writes a description of |cipher| into |buf| and
- * returns |buf|. If |buf| is NULL, it returns a newly allocated string, to be
- * 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
- *
- * Consider |SSL_CIPHER_get_name| or |SSL_CIPHER_get_rfc_name| instead. */
-OPENSSL_EXPORT const char *SSL_CIPHER_description(const SSL_CIPHER *cipher,
- char *buf, int len);
-
-/* SSL_CIPHER_get_version returns the string "TLSv1/SSLv3". */
-OPENSSL_EXPORT const char *SSL_CIPHER_get_version(const SSL_CIPHER *cipher);
-
-/* SSL_COMP_get_compression_methods returns NULL. */
-OPENSSL_EXPORT void *SSL_COMP_get_compression_methods(void);
-
-/* SSL_COMP_add_compression_method returns one. */
-OPENSSL_EXPORT int SSL_COMP_add_compression_method(int id, void *cm);
-
-/* SSL_COMP_get_name returns NULL. */
-OPENSSL_EXPORT const char *SSL_COMP_get_name(const void *comp);
-
-/* SSLv23_method calls |TLS_method|. */
-OPENSSL_EXPORT const SSL_METHOD *SSLv23_method(void);
-
-/* Version-specific methods behave exactly like |TLS_method| and |DTLS_method|
- * except they also call |SSL_CTX_set_min_version| and |SSL_CTX_set_max_version|
- * to lock connections to that protocol version. */
-OPENSSL_EXPORT const SSL_METHOD *SSLv3_method(void);
-OPENSSL_EXPORT const SSL_METHOD *TLSv1_method(void);
-OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_method(void);
-OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_method(void);
-OPENSSL_EXPORT const SSL_METHOD *DTLSv1_method(void);
-OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_method(void);
-
-/* Client- and server-specific methods call their corresponding generic
- * methods. */
-OPENSSL_EXPORT const SSL_METHOD *SSLv23_server_method(void);
-OPENSSL_EXPORT const SSL_METHOD *SSLv23_client_method(void);
-OPENSSL_EXPORT const SSL_METHOD *SSLv3_server_method(void);
-OPENSSL_EXPORT const SSL_METHOD *SSLv3_client_method(void);
-OPENSSL_EXPORT const SSL_METHOD *TLSv1_server_method(void);
-OPENSSL_EXPORT const SSL_METHOD *TLSv1_client_method(void);
-OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_server_method(void);
-OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_client_method(void);
-OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_server_method(void);
-OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_client_method(void);
-OPENSSL_EXPORT const SSL_METHOD *DTLS_server_method(void);
-OPENSSL_EXPORT const SSL_METHOD *DTLS_client_method(void);
-OPENSSL_EXPORT const SSL_METHOD *DTLSv1_server_method(void);
-OPENSSL_EXPORT const SSL_METHOD *DTLSv1_client_method(void);
-OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_server_method(void);
-OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_client_method(void);
-
-/* SSL_clear resets |ssl| to allow another connection and returns one on success
- * or zero on failure. It returns most configuration state but releases memory
- * associated with the current connection.
- *
- * Free |ssl| and create a new one instead. */
-OPENSSL_EXPORT int SSL_clear(SSL *ssl);
-
-/* SSL_CTX_set_tmp_rsa_callback does nothing. */
-OPENSSL_EXPORT void SSL_CTX_set_tmp_rsa_callback(
- SSL_CTX *ctx, RSA *(*cb)(SSL *ssl, int is_export, int keylength));
-
-/* SSL_set_tmp_rsa_callback does nothing. */
-OPENSSL_EXPORT void SSL_set_tmp_rsa_callback(SSL *ssl,
- RSA *(*cb)(SSL *ssl, int is_export,
- int keylength));
-
-/* SSL_CTX_sess_connect returns zero. */
-OPENSSL_EXPORT int SSL_CTX_sess_connect(const SSL_CTX *ctx);
-
-/* SSL_CTX_sess_connect_good returns zero. */
-OPENSSL_EXPORT int SSL_CTX_sess_connect_good(const SSL_CTX *ctx);
-
-/* SSL_CTX_sess_connect_renegotiate returns zero. */
-OPENSSL_EXPORT int SSL_CTX_sess_connect_renegotiate(const SSL_CTX *ctx);
-
-/* SSL_CTX_sess_accept returns zero. */
-OPENSSL_EXPORT int SSL_CTX_sess_accept(const SSL_CTX *ctx);
-
-/* SSL_CTX_sess_accept_renegotiate returns zero. */
-OPENSSL_EXPORT int SSL_CTX_sess_accept_renegotiate(const SSL_CTX *ctx);
-
-/* SSL_CTX_sess_accept_good returns zero. */
-OPENSSL_EXPORT int SSL_CTX_sess_accept_good(const SSL_CTX *ctx);
-
-/* SSL_CTX_sess_hits returns zero. */
-OPENSSL_EXPORT int SSL_CTX_sess_hits(const SSL_CTX *ctx);
-
-/* SSL_CTX_sess_cb_hits returns zero. */
-OPENSSL_EXPORT int SSL_CTX_sess_cb_hits(const SSL_CTX *ctx);
-
-/* SSL_CTX_sess_misses returns zero. */
-OPENSSL_EXPORT int SSL_CTX_sess_misses(const SSL_CTX *ctx);
-
-/* SSL_CTX_sess_timeouts returns zero. */
-OPENSSL_EXPORT int SSL_CTX_sess_timeouts(const SSL_CTX *ctx);
-
-/* SSL_CTX_sess_cache_full returns zero. */
-OPENSSL_EXPORT int SSL_CTX_sess_cache_full(const SSL_CTX *ctx);
-
-/* SSL_cutthrough_complete calls |SSL_in_false_start|. */
-OPENSSL_EXPORT int SSL_cutthrough_complete(const SSL *s);
-
-/* SSL_num_renegotiations calls |SSL_total_renegotiations|. */
-OPENSSL_EXPORT int SSL_num_renegotiations(const SSL *ssl);
-
-/* SSL_CTX_need_tmp_RSA returns zero. */
-OPENSSL_EXPORT int SSL_CTX_need_tmp_RSA(const SSL_CTX *ctx);
+ /* in_handshake is non-zero when we are actually in SSL_accept() or
+ * SSL_connect() */
+ int in_handshake;
-/* SSL_need_tmp_RSA returns zero. */
-OPENSSL_EXPORT int SSL_need_tmp_RSA(const SSL *ssl);
+ /* verify_mode is a bitmask of |SSL_VERIFY_*| values. */
+ uint8_t verify_mode;
-/* SSL_CTX_set_tmp_rsa returns one. */
-OPENSSL_EXPORT int SSL_CTX_set_tmp_rsa(SSL_CTX *ctx, const RSA *rsa);
+ /* hit is true if this connection is resuming a previous session. */
+ unsigned hit:1;
-/* SSL_set_tmp_rsa returns one. */
-OPENSSL_EXPORT int SSL_set_tmp_rsa(SSL *ssl, const RSA *rsa);
-
-/* SSL_CTX_get_read_head returns zero. */
-OPENSSL_EXPORT int SSL_CTX_get_read_ahead(const SSL_CTX *ctx);
+ /* server is true iff the this SSL* is the server half. Note: before the SSL*
+ * is initialized by either SSL_set_accept_state or SSL_set_connect_state,
+ * the side is not determined. In this state, server is always false. */
+ unsigned server:1;
-/* SSL_CTX_set_read_ahead does nothing. */
-OPENSSL_EXPORT void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes);
+ /* quiet_shutdown is true if the connection should not send a close_notify on
+ * shutdown. */
+ unsigned quiet_shutdown:1;
-/* SSL_get_read_head returns zero. */
-OPENSSL_EXPORT int SSL_get_read_ahead(const SSL *s);
+ /* Enable signed certificate time stamps. Currently client only. */
+ unsigned signed_cert_timestamps_enabled:1;
-/* SSL_set_read_ahead does nothing. */
-OPENSSL_EXPORT void SSL_set_read_ahead(SSL *s, int yes);
+ /* ocsp_stapling_enabled is only used by client connections and indicates
+ * whether OCSP stapling will be requested. */
+ unsigned ocsp_stapling_enabled:1;
-/* SSL_renegotiate put an error on the error queue and returns zero. */
-OPENSSL_EXPORT int SSL_renegotiate(SSL *ssl);
+ /* tlsext_channel_id_enabled is copied from the |SSL_CTX|. For a server,
+ * means that we'll accept Channel IDs from clients. For a client, means that
+ * we'll advertise support. */
+ unsigned tlsext_channel_id_enabled:1;
+};
-/* SSL_set_state does nothing. */
-OPENSSL_EXPORT void SSL_set_state(SSL *ssl, int state);
+typedef struct ssl3_record_st {
+ /* type is the record type. */
+ uint8_t type;
+ /* length is the number of unconsumed bytes in the record. */
+ uint16_t length;
+ /* data is a non-owning pointer to the first unconsumed byte of the record. */
+ uint8_t *data;
+} SSL3_RECORD;
+
+typedef struct ssl3_buffer_st {
+ /* buf is the memory allocated for this buffer. */
+ uint8_t *buf;
+ /* offset is the offset into |buf| which the buffer contents start at. */
+ uint16_t offset;
+ /* len is the length of the buffer contents from |buf| + |offset|. */
+ uint16_t len;
+ /* cap is how much memory beyond |buf| + |offset| is available. */
+ uint16_t cap;
+} SSL3_BUFFER;
+
+typedef struct ssl3_state_st {
+ uint8_t read_sequence[8];
+ uint8_t write_sequence[8];
+
+ uint8_t server_random[SSL3_RANDOM_SIZE];
+ uint8_t client_random[SSL3_RANDOM_SIZE];
+
+ /* have_version is true if the connection's final version is known. Otherwise
+ * the version has not been negotiated yet. */
+ char have_version;
+
+ /* initial_handshake_complete is true if the initial handshake has
+ * completed. */
+ char initial_handshake_complete;
+
+ /* read_buffer holds data from the transport to be processed. */
+ SSL3_BUFFER read_buffer;
+ /* write_buffer holds data to be written to the transport. */
+ SSL3_BUFFER write_buffer;
+
+ SSL3_RECORD rrec; /* each decoded record goes in here */
+
+ /* 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 */
+ int wpend_tot; /* number bytes written */
+ int wpend_type;
+ int wpend_ret; /* number of bytes submitted */
+ const uint8_t *wpend_buf;
+
+ /* handshake_buffer, if non-NULL, contains the handshake transcript. */
+ BUF_MEM *handshake_buffer;
+ /* handshake_hash, if initialized with an |EVP_MD|, maintains the handshake
+ * hash. For TLS 1.1 and below, it is the SHA-1 half. */
+ EVP_MD_CTX handshake_hash;
+ /* handshake_md5, if initialized with an |EVP_MD|, maintains the MD5 half of
+ * the handshake hash for TLS 1.1 and below. */
+ EVP_MD_CTX handshake_md5;
+
+ int warn_alert;
+ int fatal_alert;
+ /* we allow one fatal and one warning alert to be outstanding, send close
+ * alert via the warning alert */
+ int alert_dispatch;
+ uint8_t send_alert[2];
+
+ int total_renegotiations;
+
+ /* empty_record_count is the number of consecutive empty records received. */
+ uint8_t empty_record_count;
+
+ /* warning_alert_count is the number of consecutive warning alerts
+ * received. */
+ uint8_t warning_alert_count;
+
+ /* State pertaining to the pending handshake.
+ *
+ * TODO(davidben): State is current spread all over the place. Move
+ * pending handshake state here so it can be managed separately from
+ * established connection state in case of renegotiations. */
+ struct {
+ uint8_t finish_md[EVP_MAX_MD_SIZE];
+ int finish_md_len;
+ uint8_t peer_finish_md[EVP_MAX_MD_SIZE];
+ int peer_finish_md_len;
+
+ unsigned long message_size;
+ int message_type;
+
+ /* used to hold the new cipher we are going to use */
+ const SSL_CIPHER *new_cipher;
+
+ /* used when SSL_ST_FLUSH_DATA is entered */
+ int next_state;
+
+ int reuse_message;
+
+ union {
+ /* sent is a bitset where the bits correspond to elements of kExtensions
+ * in t1_lib.c. Each bit is set if that extension was sent in a
+ * ClientHello. It's not used by servers. */
+ uint32_t sent;
+ /* received is a bitset, like |sent|, but is used by servers to record
+ * which extensions were received from a client. */
+ uint32_t received;
+ } extensions;
+
+ union {
+ /* sent is a bitset where the bits correspond to elements of
+ * |client_custom_extensions| in the |SSL_CTX|. Each bit is set if that
+ * extension was sent in a ClientHello. It's not used by servers. */
+ uint16_t sent;
+ /* received is a bitset, like |sent|, but is used by servers to record
+ * which custom extensions were received from a client. The bits here
+ * correspond to |server_custom_extensions|. */
+ uint16_t received;
+ } custom_extensions;
+
+ /* SNI extension */
+
+ /* should_ack_sni is used by a server and indicates that the SNI extension
+ * should be echoed in the ServerHello. */
+ unsigned should_ack_sni:1;
+
+
+ /* Client-only: cert_req determines if a client certificate is to be sent.
+ * This is 0 if no client Certificate message is to be sent, 1 if there is
+ * a client certificate, and 2 to send an empty client Certificate
+ * message. */
+ int cert_req;
+
+ /* Client-only: ca_names contains the list of CAs received in a
+ * CertificateRequest message. */
+ STACK_OF(X509_NAME) *ca_names;
+
+ /* Client-only: certificate_types contains the set of certificate types
+ * received in a CertificateRequest message. */
+ uint8_t *certificate_types;
+ size_t num_certificate_types;
+
+ int key_block_length;
+ uint8_t *key_block;
+
+ const EVP_AEAD *new_aead;
+ uint8_t new_mac_secret_len;
+ uint8_t new_fixed_iv_len;
+ uint8_t new_variable_iv_len;
+
+ /* Server-only: cert_request is true if a client certificate was
+ * requested. */
+ int cert_request;
+
+ /* certificate_status_expected is true if OCSP stapling was negotiated and
+ * the server is expected to send a CertificateStatus message. (This is
+ * used on both the client and server sides.) */
+ unsigned certificate_status_expected:1;
+
+ /* ocsp_stapling_requested is true if a client requested OCSP stapling. */
+ unsigned ocsp_stapling_requested:1;
+
+ /* Server-only: peer_ellipticcurvelist contains the EC curve IDs advertised
+ * by the peer. This is only set on the server's end. The server does not
+ * advertise this extension to the client. */
+ uint16_t *peer_ellipticcurvelist;
+ size_t peer_ellipticcurvelist_length;
+
+ /* extended_master_secret indicates whether the extended master secret
+ * computation is used in this handshake. Note that this is different from
+ * whether it was used for the current session. If this is a resumption
+ * handshake then EMS might be negotiated in the client and server hello
+ * messages, but it doesn't matter if the session that's being resumed
+ * didn't use it to create the master secret initially. */
+ char extended_master_secret;
+
+ /* Client-only: peer_psk_identity_hint is the psk_identity_hint sent by the
+ * server when using a PSK key exchange. */
+ char *peer_psk_identity_hint;
+
+ /* new_mac_secret_size is unused and exists only until wpa_supplicant can
+ * be updated. It is only needed for EAP-FAST, which we don't support. */
+ uint8_t new_mac_secret_size;
+
+ /* Client-only: in_false_start is one if there is a pending handshake in
+ * False Start. The client may write data at this point. */
+ char in_false_start;
+
+ /* server_key_exchange_hash, on a client, is the hash the server used to
+ * sign the ServerKeyExchange in TLS 1.2. If not applicable, it is
+ * |TLSEXT_hash_none|. */
+ uint8_t server_key_exchange_hash;
+
+ /* ecdh_ctx is the current ECDH instance. */
+ SSL_ECDH_CTX ecdh_ctx;
+
+ /* peer_key is the peer's ECDH key. */
+ uint8_t *peer_key;
+ uint16_t peer_key_len;
+ } tmp;
+
+ /* Connection binding to prevent renegotiation attacks */
+ uint8_t previous_client_finished[EVP_MAX_MD_SIZE];
+ uint8_t previous_client_finished_len;
+ uint8_t previous_server_finished[EVP_MAX_MD_SIZE];
+ uint8_t previous_server_finished_len;
+ int send_connection_binding; /* TODOEKR */
+
+ /* Set if we saw the Next Protocol Negotiation extension from our peer. */
+ int next_proto_neg_seen;
+ /* ALPN information
+ * (we are in the process of transitioning from NPN to ALPN.) */
-/* Android compatibility section.
+ /* In a server these point to the selected ALPN protocol after the
+ * ClientHello has been processed. In a client these contain the protocol
+ * that the server selected once the ServerHello has been processed. */
+ uint8_t *alpn_selected;
+ size_t alpn_selected_len;
+
+ /* In a client, this means that the server supported Channel ID and that a
+ * Channel ID was sent. In a server it means that we echoed support for
+ * Channel IDs and that tlsext_channel_id will be valid after the
+ * handshake. */
+ char tlsext_channel_id_valid;
+ /* For a server:
+ * If |tlsext_channel_id_valid| is true, then this contains the
+ * verified Channel ID from the client: a P256 point, (x,y), where
+ * each are big-endian values. */
+ uint8_t tlsext_channel_id[64];
+} SSL3_STATE;
+
+
+/* Android compatibility section (hidden).
*
* These functions are declared, temporarily, for Android because
* wpa_supplicant will take a little time to sync with upstream. Outside of
@@ -2440,313 +4150,144 @@ OPENSSL_EXPORT int SSL_set_session_secret_cb(SSL *s, void *cb, void *arg);
OPENSSL_EXPORT int SSL_set_session_ticket_ext_cb(SSL *s, void *cb, void *arg);
OPENSSL_EXPORT int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method);
-#define OPENSSL_VERSION_TEXT "BoringSSL"
-
-#define SSLEAY_VERSION 0
-
-/* SSLeay_version is a compatibility function that returns the string
- * "BoringSSL". */
-OPENSSL_EXPORT const char *SSLeay_version(int unused);
-
-/* Preprocessor compatibility section.
+/* Preprocessor compatibility section (hidden).
*
* Historically, a number of APIs were implemented in OpenSSL as macros and
* constants to 'ctrl' functions. To avoid breaking #ifdefs in consumers, this
- * section defines a number of legacy macros. */
+ * section defines a number of legacy macros.
+ *
+ * Although using either the CTRL values or their wrapper macros in #ifdefs is
+ * still supported, the CTRL values may not be passed to |SSL_ctrl| and
+ * |SSL_CTX_ctrl|. Call the functions (previously wrapper macros) instead. */
-#define SSL_CTRL_NEED_TMP_RSA doesnt_exist
-#define SSL_CTRL_SET_TMP_RSA doesnt_exist
-#define SSL_CTRL_SET_TMP_DH doesnt_exist
-#define SSL_CTRL_SET_TMP_ECDH doesnt_exist
-#define SSL_CTRL_SET_TMP_RSA_CB doesnt_exist
-#define SSL_CTRL_SET_TMP_DH_CB doesnt_exist
-#define SSL_CTRL_SET_TMP_ECDH_CB doesnt_exist
-#define SSL_CTRL_GET_SESSION_REUSED doesnt_exist
+#define DTLS_CTRL_GET_TIMEOUT doesnt_exist
+#define DTLS_CTRL_HANDLE_TIMEOUT doesnt_exist
+#define SSL_CTRL_CHAIN doesnt_exist
+#define SSL_CTRL_CHAIN_CERT doesnt_exist
+#define SSL_CTRL_CHANNEL_ID doesnt_exist
+#define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS doesnt_exist
+#define SSL_CTRL_CLEAR_MODE doesnt_exist
+#define SSL_CTRL_CLEAR_OPTIONS doesnt_exist
+#define SSL_CTRL_EXTRA_CHAIN_CERT doesnt_exist
+#define SSL_CTRL_GET_CHAIN_CERTS doesnt_exist
+#define SSL_CTRL_GET_CHANNEL_ID doesnt_exist
+#define SSL_CTRL_GET_CLIENT_CERT_TYPES doesnt_exist
+#define SSL_CTRL_GET_EXTRA_CHAIN_CERTS doesnt_exist
+#define SSL_CTRL_GET_MAX_CERT_LIST doesnt_exist
#define SSL_CTRL_GET_NUM_RENEGOTIATIONS doesnt_exist
+#define SSL_CTRL_GET_READ_AHEAD doesnt_exist
+#define SSL_CTRL_GET_RI_SUPPORT doesnt_exist
+#define SSL_CTRL_GET_SESSION_REUSED doesnt_exist
+#define SSL_CTRL_GET_SESS_CACHE_MODE doesnt_exist
+#define SSL_CTRL_GET_SESS_CACHE_SIZE doesnt_exist
+#define SSL_CTRL_GET_TLSEXT_TICKET_KEYS doesnt_exist
#define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS doesnt_exist
+#define SSL_CTRL_MODE doesnt_exist
+#define SSL_CTRL_NEED_TMP_RSA doesnt_exist
+#define SSL_CTRL_OPTIONS doesnt_exist
+#define SSL_CTRL_SESS_NUMBER doesnt_exist
+#define SSL_CTRL_SET_CHANNEL_ID doesnt_exist
+#define SSL_CTRL_SET_CURVES doesnt_exist
+#define SSL_CTRL_SET_MAX_CERT_LIST doesnt_exist
+#define SSL_CTRL_SET_MAX_SEND_FRAGMENT doesnt_exist
#define SSL_CTRL_SET_MSG_CALLBACK doesnt_exist
#define SSL_CTRL_SET_MSG_CALLBACK_ARG doesnt_exist
#define SSL_CTRL_SET_MTU doesnt_exist
-#define SSL_CTRL_SESS_NUMBER doesnt_exist
-#define SSL_CTRL_OPTIONS doesnt_exist
-#define SSL_CTRL_MODE doesnt_exist
-#define SSL_CTRL_GET_READ_AHEAD doesnt_exist
#define SSL_CTRL_SET_READ_AHEAD doesnt_exist
-#define SSL_CTRL_SET_SESS_CACHE_SIZE doesnt_exist
-#define SSL_CTRL_GET_SESS_CACHE_SIZE doesnt_exist
#define SSL_CTRL_SET_SESS_CACHE_MODE doesnt_exist
-#define SSL_CTRL_GET_SESS_CACHE_MODE doesnt_exist
-#define SSL_CTRL_GET_MAX_CERT_LIST doesnt_exist
-#define SSL_CTRL_SET_MAX_CERT_LIST doesnt_exist
-#define SSL_CTRL_SET_MAX_SEND_FRAGMENT doesnt_exist
-#define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB doesnt_exist
-#define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG doesnt_exist
+#define SSL_CTRL_SET_SESS_CACHE_SIZE doesnt_exist
#define SSL_CTRL_SET_TLSEXT_HOSTNAME doesnt_exist
+#define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG doesnt_exist
+#define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB doesnt_exist
+#define SSL_CTRL_SET_TLSEXT_TICKET_KEYS doesnt_exist
#define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB doesnt_exist
-#define DTLS_CTRL_GET_TIMEOUT doesnt_exist
-#define DTLS_CTRL_HANDLE_TIMEOUT doesnt_exist
-#define SSL_CTRL_GET_RI_SUPPORT doesnt_exist
-#define SSL_CTRL_CLEAR_OPTIONS doesnt_exist
-#define SSL_CTRL_CLEAR_MODE doesnt_exist
-#define SSL_CTRL_CHANNEL_ID doesnt_exist
-#define SSL_CTRL_GET_CHANNEL_ID doesnt_exist
-#define SSL_CTRL_SET_CHANNEL_ID doesnt_exist
+#define SSL_CTRL_SET_TMP_DH doesnt_exist
+#define SSL_CTRL_SET_TMP_DH_CB doesnt_exist
+#define SSL_CTRL_SET_TMP_ECDH doesnt_exist
+#define SSL_CTRL_SET_TMP_ECDH_CB doesnt_exist
+#define SSL_CTRL_SET_TMP_RSA doesnt_exist
+#define SSL_CTRL_SET_TMP_RSA_CB doesnt_exist
-#define SSL_CTX_need_tmp_RSA SSL_CTX_need_tmp_RSA
-#define SSL_need_tmp_RSA SSL_need_tmp_RSA
-#define SSL_CTX_set_tmp_rsa SSL_CTX_set_tmp_rsa
-#define SSL_set_tmp_rsa SSL_set_tmp_rsa
-#define SSL_CTX_set_tmp_dh SSL_CTX_set_tmp_dh
-#define SSL_set_tmp_dh SSL_set_tmp_dh
-#define SSL_CTX_set_tmp_ecdh SSL_CTX_set_tmp_ecdh
-#define SSL_set_tmp_ecdh SSL_set_tmp_ecdh
-#define SSL_session_reused SSL_session_reused
-#define SSL_num_renegotiations SSL_num_renegotiations
-#define SSL_total_renegotiations SSL_total_renegotiations
-#define SSL_CTX_set_msg_callback_arg SSL_CTX_set_msg_callback_arg
-#define SSL_set_msg_callback_arg SSL_set_msg_callback_arg
-#define SSL_set_mtu SSL_set_mtu
-#define SSL_CTX_sess_number SSL_CTX_sess_number
-#define SSL_CTX_get_options SSL_CTX_get_options
-#define SSL_CTX_set_options SSL_CTX_set_options
-#define SSL_get_options SSL_get_options
-#define SSL_set_options SSL_set_options
+#define DTLSv1_get_timeout DTLSv1_get_timeout
+#define DTLSv1_handle_timeout DTLSv1_handle_timeout
+#define SSL_CTX_add0_chain_cert SSL_CTX_add0_chain_cert
+#define SSL_CTX_add1_chain_cert SSL_CTX_add1_chain_cert
+#define SSL_CTX_add_extra_chain_cert SSL_CTX_add_extra_chain_cert
+#define SSL_CTX_clear_extra_chain_certs SSL_CTX_clear_extra_chain_certs
+#define SSL_CTX_clear_chain_certs SSL_CTX_clear_chain_certs
+#define SSL_CTX_clear_mode SSL_CTX_clear_mode
+#define SSL_CTX_clear_options SSL_CTX_clear_options
+#define SSL_CTX_enable_tls_channel_id SSL_CTX_enable_tls_channel_id
+#define SSL_CTX_get0_chain_certs SSL_CTX_get0_chain_certs
+#define SSL_CTX_get_extra_chain_certs SSL_CTX_get_extra_chain_certs
+#define SSL_CTX_get_max_cert_list SSL_CTX_get_max_cert_list
#define SSL_CTX_get_mode SSL_CTX_get_mode
-#define SSL_CTX_set_mode SSL_CTX_set_mode
-#define SSL_get_mode SSL_get_mode
-#define SSL_set_mode SSL_set_mode
+#define SSL_CTX_get_options SSL_CTX_get_options
#define SSL_CTX_get_read_ahead SSL_CTX_get_read_ahead
-#define SSL_CTX_set_read_ahead SSL_CTX_set_read_ahead
-#define SSL_CTX_sess_set_cache_size SSL_CTX_sess_set_cache_size
-#define SSL_CTX_sess_get_cache_size SSL_CTX_sess_get_cache_size
-#define SSL_CTX_set_session_cache_mode SSL_CTX_set_session_cache_mode
#define SSL_CTX_get_session_cache_mode SSL_CTX_get_session_cache_mode
-#define SSL_CTX_get_max_cert_list SSL_CTX_get_max_cert_list
-#define SSL_get_max_cert_list SSL_get_max_cert_list
+#define SSL_CTX_get_tlsext_ticket_keys SSL_CTX_get_tlsext_ticket_keys
+#define SSL_CTX_need_tmp_RSA SSL_CTX_need_tmp_RSA
+#define SSL_CTX_sess_get_cache_size SSL_CTX_sess_get_cache_size
+#define SSL_CTX_sess_number SSL_CTX_sess_number
+#define SSL_CTX_sess_set_cache_size SSL_CTX_sess_set_cache_size
+#define SSL_CTX_set0_chain SSL_CTX_set0_chain
+#define SSL_CTX_set1_chain SSL_CTX_set1_chain
+#define SSL_CTX_set1_curves SSL_CTX_set1_curves
+#define SSL_CTX_set1_tls_channel_id SSL_CTX_set1_tls_channel_id
#define SSL_CTX_set_max_cert_list SSL_CTX_set_max_cert_list
-#define SSL_set_max_cert_list SSL_set_max_cert_list
#define SSL_CTX_set_max_send_fragment SSL_CTX_set_max_send_fragment
-#define SSL_set_max_send_fragment SSL_set_max_send_fragment
+#define SSL_CTX_set_mode SSL_CTX_set_mode
+#define SSL_CTX_set_msg_callback_arg SSL_CTX_set_msg_callback_arg
+#define SSL_CTX_set_options SSL_CTX_set_options
+#define SSL_CTX_set_read_ahead SSL_CTX_set_read_ahead
+#define SSL_CTX_set_session_cache_mode SSL_CTX_set_session_cache_mode
+#define SSL_CTX_set_tlsext_servername_arg SSL_CTX_set_tlsext_servername_arg
#define SSL_CTX_set_tlsext_servername_callback \
SSL_CTX_set_tlsext_servername_callback
-#define SSL_CTX_set_tlsext_servername_arg SSL_CTX_set_tlsext_servername_arg
-#define SSL_set_tlsext_host_name SSL_set_tlsext_host_name
#define SSL_CTX_set_tlsext_ticket_key_cb SSL_CTX_set_tlsext_ticket_key_cb
-#define DTLSv1_get_timeout DTLSv1_get_timeout
-#define DTLSv1_handle_timeout DTLSv1_handle_timeout
-#define SSL_get_secure_renegotiation_support \
- SSL_get_secure_renegotiation_support
-#define SSL_CTX_clear_options SSL_CTX_clear_options
-#define SSL_clear_options SSL_clear_options
-#define SSL_CTX_clear_mode SSL_CTX_clear_mode
+#define SSL_CTX_set_tlsext_ticket_keys SSL_CTX_set_tlsext_ticket_keys
+#define SSL_CTX_set_tmp_dh SSL_CTX_set_tmp_dh
+#define SSL_CTX_set_tmp_ecdh SSL_CTX_set_tmp_ecdh
+#define SSL_CTX_set_tmp_rsa SSL_CTX_set_tmp_rsa
+#define SSL_add0_chain_cert SSL_add0_chain_cert
+#define SSL_add1_chain_cert SSL_add1_chain_cert
+#define SSL_clear_chain_certs SSL_clear_chain_certs
#define SSL_clear_mode SSL_clear_mode
-#define SSL_CTX_enable_tls_channel_id SSL_CTX_enable_tls_channel_id
+#define SSL_clear_options SSL_clear_options
#define SSL_enable_tls_channel_id SSL_enable_tls_channel_id
-#define SSL_set1_tls_channel_id SSL_set1_tls_channel_id
-#define SSL_CTX_set1_tls_channel_id SSL_CTX_set1_tls_channel_id
+#define SSL_get0_certificate_types SSL_get0_certificate_types
+#define SSL_get0_chain_certs SSL_get0_chain_certs
+#define SSL_get_max_cert_list SSL_get_max_cert_list
+#define SSL_get_mode SSL_get_mode
+#define SSL_get_options SSL_get_options
+#define SSL_get_secure_renegotiation_support \
+ SSL_get_secure_renegotiation_support
#define SSL_get_tls_channel_id SSL_get_tls_channel_id
+#define SSL_need_tmp_RSA SSL_need_tmp_RSA
+#define SSL_num_renegotiations SSL_num_renegotiations
+#define SSL_session_reused SSL_session_reused
+#define SSL_set0_chain SSL_set0_chain
+#define SSL_set1_chain SSL_set1_chain
+#define SSL_set1_curves SSL_set1_curves
+#define SSL_set1_tls_channel_id SSL_set1_tls_channel_id
+#define SSL_set_max_cert_list SSL_set_max_cert_list
+#define SSL_set_max_send_fragment SSL_set_max_send_fragment
+#define SSL_set_mode SSL_set_mode
+#define SSL_set_msg_callback_arg SSL_set_msg_callback_arg
+#define SSL_set_mtu SSL_set_mtu
+#define SSL_set_options SSL_set_options
+#define SSL_set_tlsext_host_name SSL_set_tlsext_host_name
+#define SSL_set_tmp_dh SSL_set_tmp_dh
+#define SSL_set_tmp_ecdh SSL_set_tmp_ecdh
+#define SSL_set_tmp_rsa SSL_set_tmp_rsa
+#define SSL_total_renegotiations SSL_total_renegotiations
#if defined(__cplusplus)
} /* extern C */
#endif
-
-/* Library consumers assume these headers are included by ssl.h, but they depend
- * on ssl.h, so include them after all declarations.
- *
- * TODO(davidben): The separation between ssl.h and these version-specific
- * headers introduces circular dependencies and is inconsistent. The function
- * declarations should move to ssl.h. Many of the constants can probably be
- * pruned or unexported. */
-#include <openssl/ssl2.h>
-#include <openssl/ssl3.h>
-#include <openssl/tls1.h> /* This is mostly sslv3 with a few tweaks */
-#include <openssl/ssl23.h>
-#include <openssl/srtp.h> /* Support for the use_srtp extension */
-
-
-/* BEGIN ERROR CODES */
-/* The following lines are auto generated by the script make_errors.go. Any
- * changes made after this point may be overwritten when the script is next run.
- */
-#define SSL_F_SSL_CTX_check_private_key 100
-#define SSL_F_SSL_CTX_new 101
-#define SSL_F_SSL_CTX_set_cipher_list 102
-#define SSL_F_SSL_CTX_set_cipher_list_tls11 103
-#define SSL_F_SSL_CTX_set_session_id_context 104
-#define SSL_F_SSL_CTX_use_PrivateKey 105
-#define SSL_F_SSL_CTX_use_PrivateKey_ASN1 106
-#define SSL_F_SSL_CTX_use_PrivateKey_file 107
-#define SSL_F_SSL_CTX_use_RSAPrivateKey 108
-#define SSL_F_SSL_CTX_use_RSAPrivateKey_ASN1 109
-#define SSL_F_SSL_CTX_use_RSAPrivateKey_file 110
-#define SSL_F_SSL_CTX_use_certificate 111
-#define SSL_F_SSL_CTX_use_certificate_ASN1 112
-#define SSL_F_SSL_CTX_use_certificate_chain_file 113
-#define SSL_F_SSL_CTX_use_certificate_file 114
-#define SSL_F_SSL_CTX_use_psk_identity_hint 115
-#define SSL_F_SSL_SESSION_new 116
-#define SSL_F_SSL_SESSION_print_fp 117
-#define SSL_F_SSL_SESSION_set1_id_context 118
-#define SSL_F_SSL_SESSION_to_bytes_full 119
-#define SSL_F_SSL_accept 120
-#define SSL_F_SSL_add_dir_cert_subjects_to_stack 121
-#define SSL_F_SSL_add_file_cert_subjects_to_stack 122
-#define SSL_F_SSL_check_private_key 123
-#define SSL_F_SSL_clear 124
-#define SSL_F_SSL_connect 125
-#define SSL_F_SSL_do_handshake 126
-#define SSL_F_SSL_load_client_CA_file 127
-#define SSL_F_SSL_new 128
-#define SSL_F_SSL_peek 129
-#define SSL_F_SSL_read 130
-#define SSL_F_SSL_renegotiate 131
-#define SSL_F_SSL_set_cipher_list 132
-#define SSL_F_SSL_set_fd 133
-#define SSL_F_SSL_set_rfd 134
-#define SSL_F_SSL_set_session_id_context 135
-#define SSL_F_SSL_set_wfd 136
-#define SSL_F_SSL_shutdown 137
-#define SSL_F_SSL_use_PrivateKey 138
-#define SSL_F_SSL_use_PrivateKey_ASN1 139
-#define SSL_F_SSL_use_PrivateKey_file 140
-#define SSL_F_SSL_use_RSAPrivateKey 141
-#define SSL_F_SSL_use_RSAPrivateKey_ASN1 142
-#define SSL_F_SSL_use_RSAPrivateKey_file 143
-#define SSL_F_SSL_use_certificate 144
-#define SSL_F_SSL_use_certificate_ASN1 145
-#define SSL_F_SSL_use_certificate_file 146
-#define SSL_F_SSL_use_psk_identity_hint 147
-#define SSL_F_SSL_write 148
-#define SSL_F_d2i_SSL_SESSION 149
-#define SSL_F_d2i_SSL_SESSION_get_octet_string 150
-#define SSL_F_d2i_SSL_SESSION_get_string 151
-#define SSL_F_do_ssl3_write 152
-#define SSL_F_dtls1_accept 153
-#define SSL_F_dtls1_buffer_record 154
-#define SSL_F_dtls1_check_timeout_num 155
-#define SSL_F_dtls1_connect 156
-#define SSL_F_dtls1_do_write 157
-#define SSL_F_dtls1_get_hello_verify 158
-#define SSL_F_dtls1_get_message 159
-#define SSL_F_dtls1_get_message_fragment 160
-#define SSL_F_dtls1_preprocess_fragment 161
-#define SSL_F_dtls1_process_record 162
-#define SSL_F_dtls1_read_bytes 163
-#define SSL_F_dtls1_send_hello_verify_request 164
-#define SSL_F_dtls1_write_app_data 165
-#define SSL_F_i2d_SSL_SESSION 166
-#define SSL_F_ssl3_accept 167
-#define SSL_F_ssl3_cert_verify_hash 169
-#define SSL_F_ssl3_check_cert_and_algorithm 170
-#define SSL_F_ssl3_connect 171
-#define SSL_F_ssl3_ctrl 172
-#define SSL_F_ssl3_ctx_ctrl 173
-#define SSL_F_ssl3_digest_cached_records 174
-#define SSL_F_ssl3_do_change_cipher_spec 175
-#define SSL_F_ssl3_expect_change_cipher_spec 176
-#define SSL_F_ssl3_get_cert_status 177
-#define SSL_F_ssl3_get_cert_verify 178
-#define SSL_F_ssl3_get_certificate_request 179
-#define SSL_F_ssl3_get_channel_id 180
-#define SSL_F_ssl3_get_client_certificate 181
-#define SSL_F_ssl3_get_client_hello 182
-#define SSL_F_ssl3_get_client_key_exchange 183
-#define SSL_F_ssl3_get_finished 184
-#define SSL_F_ssl3_get_initial_bytes 185
-#define SSL_F_ssl3_get_message 186
-#define SSL_F_ssl3_get_new_session_ticket 187
-#define SSL_F_ssl3_get_next_proto 188
-#define SSL_F_ssl3_get_record 189
-#define SSL_F_ssl3_get_server_certificate 190
-#define SSL_F_ssl3_get_server_done 191
-#define SSL_F_ssl3_get_server_hello 192
-#define SSL_F_ssl3_get_server_key_exchange 193
-#define SSL_F_ssl3_get_v2_client_hello 194
-#define SSL_F_ssl3_handshake_mac 195
-#define SSL_F_ssl3_prf 196
-#define SSL_F_ssl3_read_bytes 197
-#define SSL_F_ssl3_read_n 198
-#define SSL_F_ssl3_send_cert_verify 199
-#define SSL_F_ssl3_send_certificate_request 200
-#define SSL_F_ssl3_send_channel_id 201
-#define SSL_F_ssl3_send_client_certificate 202
-#define SSL_F_ssl3_send_client_hello 203
-#define SSL_F_ssl3_send_client_key_exchange 204
-#define SSL_F_ssl3_send_server_certificate 205
-#define SSL_F_ssl3_send_server_hello 206
-#define SSL_F_ssl3_send_server_key_exchange 207
-#define SSL_F_ssl3_setup_read_buffer 208
-#define SSL_F_ssl3_setup_write_buffer 209
-#define SSL_F_ssl3_write_bytes 210
-#define SSL_F_ssl3_write_pending 211
-#define SSL_F_ssl_add_cert_chain 212
-#define SSL_F_ssl_add_cert_to_buf 213
-#define SSL_F_ssl_add_clienthello_renegotiate_ext 214
-#define SSL_F_ssl_add_clienthello_tlsext 215
-#define SSL_F_ssl_add_clienthello_use_srtp_ext 216
-#define SSL_F_ssl_add_serverhello_renegotiate_ext 217
-#define SSL_F_ssl_add_serverhello_tlsext 218
-#define SSL_F_ssl_add_serverhello_use_srtp_ext 219
-#define SSL_F_ssl_build_cert_chain 220
-#define SSL_F_ssl_bytes_to_cipher_list 221
-#define SSL_F_ssl_cert_dup 222
-#define SSL_F_ssl_cert_inst 223
-#define SSL_F_ssl_cert_new 224
-#define SSL_F_ssl_check_serverhello_tlsext 225
-#define SSL_F_ssl_check_srvr_ecc_cert_and_alg 226
-#define SSL_F_ssl_cipher_process_rulestr 227
-#define SSL_F_ssl_cipher_strength_sort 228
-#define SSL_F_ssl_create_cipher_list 229
-#define SSL_F_ssl_ctx_log_master_secret 230
-#define SSL_F_ssl_ctx_log_rsa_client_key_exchange 231
-#define SSL_F_ssl_ctx_make_profiles 232
-#define SSL_F_ssl_get_new_session 233
-#define SSL_F_ssl_get_prev_session 234
-#define SSL_F_ssl_get_server_cert_index 235
-#define SSL_F_ssl_get_sign_pkey 236
-#define SSL_F_ssl_init_wbio_buffer 237
-#define SSL_F_ssl_parse_clienthello_renegotiate_ext 238
-#define SSL_F_ssl_parse_clienthello_tlsext 239
-#define SSL_F_ssl_parse_clienthello_use_srtp_ext 240
-#define SSL_F_ssl_parse_serverhello_renegotiate_ext 241
-#define SSL_F_ssl_parse_serverhello_tlsext 242
-#define SSL_F_ssl_parse_serverhello_use_srtp_ext 243
-#define SSL_F_ssl_scan_clienthello_tlsext 244
-#define SSL_F_ssl_scan_serverhello_tlsext 245
-#define SSL_F_ssl_sess_cert_new 246
-#define SSL_F_ssl_set_cert 247
-#define SSL_F_ssl_set_pkey 248
-#define SSL_F_ssl_verify_cert_chain 252
-#define SSL_F_tls12_check_peer_sigalg 253
-#define SSL_F_tls1_aead_ctx_init 254
-#define SSL_F_tls1_cert_verify_mac 255
-#define SSL_F_tls1_change_cipher_state 256
-#define SSL_F_tls1_change_cipher_state_aead 257
-#define SSL_F_tls1_check_duplicate_extensions 258
-#define SSL_F_tls1_enc 259
-#define SSL_F_tls1_export_keying_material 260
-#define SSL_F_tls1_prf 261
-#define SSL_F_tls1_setup_key_block 262
-#define SSL_F_dtls1_get_buffered_message 263
-#define SSL_F_dtls1_process_fragment 264
-#define SSL_F_dtls1_hm_fragment_new 265
-#define SSL_F_ssl3_seal_record 266
-#define SSL_F_ssl3_record_sequence_update 267
-#define SSL_F_SSL_CTX_set_tmp_dh 268
-#define SSL_F_SSL_CTX_set_tmp_ecdh 269
-#define SSL_F_SSL_set_tmp_dh 270
-#define SSL_F_SSL_set_tmp_ecdh 271
-#define SSL_F_SSL_CTX_set1_tls_channel_id 272
-#define SSL_F_SSL_set1_tls_channel_id 273
-#define SSL_F_SSL_set_tlsext_host_name 274
-#define SSL_F_ssl3_output_cert_chain 275
-#define SSL_F_SSL_AEAD_CTX_new 276
-#define SSL_F_SSL_AEAD_CTX_open 277
-#define SSL_F_SSL_AEAD_CTX_seal 278
-#define SSL_F_dtls1_seal_record 279
#define SSL_R_APP_DATA_IN_HANDSHAKE 100
#define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 101
#define SSL_R_BAD_ALERT 102
@@ -2756,175 +4297,147 @@ OPENSSL_EXPORT const char *SSLeay_version(int unused);
#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_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/ssl2.h b/src/include/openssl/ssl2.h
deleted file mode 100644
index b8401fa..0000000
--- a/src/include/openssl/ssl2.h
+++ /dev/null
@@ -1,268 +0,0 @@
-/* ssl/ssl2.h */
-/* 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 HEADER_SSL2_H
-#define HEADER_SSL2_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Protocol Version Codes */
-#define SSL2_VERSION 0x0002
-#define SSL2_VERSION_MAJOR 0x00
-#define SSL2_VERSION_MINOR 0x02
-/* #define SSL2_CLIENT_VERSION 0x0002 */
-/* #define SSL2_SERVER_VERSION 0x0002 */
-
-/* Protocol Message Codes */
-#define SSL2_MT_ERROR 0
-#define SSL2_MT_CLIENT_HELLO 1
-#define SSL2_MT_CLIENT_MASTER_KEY 2
-#define SSL2_MT_CLIENT_FINISHED 3
-#define SSL2_MT_SERVER_HELLO 4
-#define SSL2_MT_SERVER_VERIFY 5
-#define SSL2_MT_SERVER_FINISHED 6
-#define SSL2_MT_REQUEST_CERTIFICATE 7
-#define SSL2_MT_CLIENT_CERTIFICATE 8
-
-/* Error Message Codes */
-#define SSL2_PE_UNDEFINED_ERROR 0x0000
-#define SSL2_PE_NO_CIPHER 0x0001
-#define SSL2_PE_NO_CERTIFICATE 0x0002
-#define SSL2_PE_BAD_CERTIFICATE 0x0004
-#define SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE 0x0006
-
-/* Cipher Kind Values */
-#define SSL2_CK_NULL_WITH_MD5 0x02000000 /* v3 */
-#define SSL2_CK_RC4_128_WITH_MD5 0x02010080
-#define SSL2_CK_RC4_128_EXPORT40_WITH_MD5 0x02020080
-#define SSL2_CK_RC2_128_CBC_WITH_MD5 0x02030080
-#define SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5 0x02040080
-#define SSL2_CK_IDEA_128_CBC_WITH_MD5 0x02050080
-#define SSL2_CK_DES_64_CBC_WITH_MD5 0x02060040
-#define SSL2_CK_DES_64_CBC_WITH_SHA 0x02060140 /* v3 */
-#define SSL2_CK_DES_192_EDE3_CBC_WITH_MD5 0x020700c0
-#define SSL2_CK_DES_192_EDE3_CBC_WITH_SHA 0x020701c0 /* v3 */
-#define SSL2_CK_RC4_64_WITH_MD5 0x02080080 /* MS hack */
-
-#define SSL2_CK_DES_64_CFB64_WITH_MD5_1 0x02ff0800 /* SSLeay */
-#define SSL2_CK_NULL 0x02ff0810 /* SSLeay */
-
-#define SSL2_TXT_DES_64_CFB64_WITH_MD5_1 "DES-CFB-M1"
-#define SSL2_TXT_NULL_WITH_MD5 "NULL-MD5"
-#define SSL2_TXT_RC4_128_WITH_MD5 "RC4-MD5"
-#define SSL2_TXT_RC4_128_EXPORT40_WITH_MD5 "EXP-RC4-MD5"
-#define SSL2_TXT_RC2_128_CBC_WITH_MD5 "RC2-CBC-MD5"
-#define SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 "EXP-RC2-CBC-MD5"
-#define SSL2_TXT_IDEA_128_CBC_WITH_MD5 "IDEA-CBC-MD5"
-#define SSL2_TXT_DES_64_CBC_WITH_MD5 "DES-CBC-MD5"
-#define SSL2_TXT_DES_64_CBC_WITH_SHA "DES-CBC-SHA"
-#define SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5 "DES-CBC3-MD5"
-#define SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA "DES-CBC3-SHA"
-#define SSL2_TXT_RC4_64_WITH_MD5 "RC4-64-MD5"
-
-#define SSL2_TXT_NULL "NULL"
-
-/* Flags for the SSL_CIPHER.algorithm2 field */
-#define SSL2_CF_5_BYTE_ENC 0x01
-#define SSL2_CF_8_BYTE_ENC 0x02
-
-/* Certificate Type Codes */
-#define SSL2_CT_X509_CERTIFICATE 0x01
-
-/* Authentication Type Code */
-#define SSL2_AT_MD5_WITH_RSA_ENCRYPTION 0x01
-
-#define SSL2_MAX_SSL_SESSION_ID_LENGTH 32
-
-/* Upper/Lower Bounds */
-#define SSL2_MAX_MASTER_KEY_LENGTH_IN_BITS 256
-#ifdef OPENSSL_SYS_MPE
-#define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER 29998u
-#else
-#define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER 32767u /* 2^15-1 */
-#endif
-#define SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER 16383 /* 2^14-1 */
-
-#define SSL2_CHALLENGE_LENGTH 16
-/*#define SSL2_CHALLENGE_LENGTH 32 */
-#define SSL2_MIN_CHALLENGE_LENGTH 16
-#define SSL2_MAX_CHALLENGE_LENGTH 32
-#define SSL2_CONNECTION_ID_LENGTH 16
-#define SSL2_MAX_CONNECTION_ID_LENGTH 16
-#define SSL2_SSL_SESSION_ID_LENGTH 16
-#define SSL2_MAX_CERT_CHALLENGE_LENGTH 32
-#define SSL2_MIN_CERT_CHALLENGE_LENGTH 16
-#define SSL2_MAX_KEY_MATERIAL_LENGTH 24
-
-#ifndef OPENSSL_NO_SSL_INTERN
-
-typedef struct ssl2_state_st
- {
- int three_byte_header;
- int clear_text; /* clear text */
- int escape; /* not used in SSLv2 */
- int ssl2_rollback; /* used if SSLv23 rolled back to SSLv2 */
-
- /* non-blocking io info, used to make sure the same
- * args were passwd */
- unsigned int wnum; /* number of bytes sent so far */
- int wpend_tot;
- const unsigned char *wpend_buf;
-
- int wpend_off; /* offset to data to write */
- int wpend_len; /* number of bytes passwd to write */
- int wpend_ret; /* number of bytes to return to caller */
-
- /* buffer raw data */
- int rbuf_left;
- int rbuf_offs;
- unsigned char *rbuf;
- unsigned char *wbuf;
-
- unsigned char *write_ptr;/* used to point to the start due to
- * 2/3 byte header. */
-
- unsigned int padding;
- unsigned int rlength; /* passed to ssl2_enc */
- int ract_data_length; /* Set when things are encrypted. */
- unsigned int wlength; /* passed to ssl2_enc */
- int wact_data_length; /* Set when things are decrypted. */
- unsigned char *ract_data;
- unsigned char *wact_data;
- unsigned char *mac_data;
-
- unsigned char *read_key;
- unsigned char *write_key;
-
- /* Stuff specifically to do with this SSL session */
- unsigned int challenge_length;
- unsigned char challenge[SSL2_MAX_CHALLENGE_LENGTH];
- unsigned int conn_id_length;
- unsigned char conn_id[SSL2_MAX_CONNECTION_ID_LENGTH];
- unsigned int key_material_length;
- unsigned char key_material[SSL2_MAX_KEY_MATERIAL_LENGTH*2];
-
- unsigned long read_sequence;
- unsigned long write_sequence;
-
- struct {
- unsigned int conn_id_length;
- unsigned int cert_type;
- unsigned int cert_length;
- unsigned int csl;
- unsigned int clear;
- unsigned int enc;
- unsigned char ccl[SSL2_MAX_CERT_CHALLENGE_LENGTH];
- unsigned int cipher_spec_length;
- unsigned int session_id_length;
- unsigned int clen;
- unsigned int rlen;
- } tmp;
- } SSL2_STATE;
-
-#endif
-
-/* SSLv2 */
-/* client */
-#define SSL2_ST_SEND_CLIENT_HELLO_A (0x10|SSL_ST_CONNECT)
-#define SSL2_ST_SEND_CLIENT_HELLO_B (0x11|SSL_ST_CONNECT)
-#define SSL2_ST_GET_SERVER_HELLO_A (0x20|SSL_ST_CONNECT)
-#define SSL2_ST_GET_SERVER_HELLO_B (0x21|SSL_ST_CONNECT)
-#define SSL2_ST_SEND_CLIENT_MASTER_KEY_A (0x30|SSL_ST_CONNECT)
-#define SSL2_ST_SEND_CLIENT_MASTER_KEY_B (0x31|SSL_ST_CONNECT)
-#define SSL2_ST_SEND_CLIENT_FINISHED_A (0x40|SSL_ST_CONNECT)
-#define SSL2_ST_SEND_CLIENT_FINISHED_B (0x41|SSL_ST_CONNECT)
-#define SSL2_ST_SEND_CLIENT_CERTIFICATE_A (0x50|SSL_ST_CONNECT)
-#define SSL2_ST_SEND_CLIENT_CERTIFICATE_B (0x51|SSL_ST_CONNECT)
-#define SSL2_ST_SEND_CLIENT_CERTIFICATE_C (0x52|SSL_ST_CONNECT)
-#define SSL2_ST_SEND_CLIENT_CERTIFICATE_D (0x53|SSL_ST_CONNECT)
-#define SSL2_ST_GET_SERVER_VERIFY_A (0x60|SSL_ST_CONNECT)
-#define SSL2_ST_GET_SERVER_VERIFY_B (0x61|SSL_ST_CONNECT)
-#define SSL2_ST_GET_SERVER_FINISHED_A (0x70|SSL_ST_CONNECT)
-#define SSL2_ST_GET_SERVER_FINISHED_B (0x71|SSL_ST_CONNECT)
-#define SSL2_ST_CLIENT_START_ENCRYPTION (0x80|SSL_ST_CONNECT)
-#define SSL2_ST_X509_GET_CLIENT_CERTIFICATE (0x90|SSL_ST_CONNECT)
-/* server */
-#define SSL2_ST_GET_CLIENT_HELLO_A (0x10|SSL_ST_ACCEPT)
-#define SSL2_ST_GET_CLIENT_HELLO_B (0x11|SSL_ST_ACCEPT)
-#define SSL2_ST_GET_CLIENT_HELLO_C (0x12|SSL_ST_ACCEPT)
-#define SSL2_ST_SEND_SERVER_HELLO_A (0x20|SSL_ST_ACCEPT)
-#define SSL2_ST_SEND_SERVER_HELLO_B (0x21|SSL_ST_ACCEPT)
-#define SSL2_ST_GET_CLIENT_MASTER_KEY_A (0x30|SSL_ST_ACCEPT)
-#define SSL2_ST_GET_CLIENT_MASTER_KEY_B (0x31|SSL_ST_ACCEPT)
-#define SSL2_ST_SEND_SERVER_VERIFY_A (0x40|SSL_ST_ACCEPT)
-#define SSL2_ST_SEND_SERVER_VERIFY_B (0x41|SSL_ST_ACCEPT)
-#define SSL2_ST_SEND_SERVER_VERIFY_C (0x42|SSL_ST_ACCEPT)
-#define SSL2_ST_GET_CLIENT_FINISHED_A (0x50|SSL_ST_ACCEPT)
-#define SSL2_ST_GET_CLIENT_FINISHED_B (0x51|SSL_ST_ACCEPT)
-#define SSL2_ST_SEND_SERVER_FINISHED_A (0x60|SSL_ST_ACCEPT)
-#define SSL2_ST_SEND_SERVER_FINISHED_B (0x61|SSL_ST_ACCEPT)
-#define SSL2_ST_SEND_REQUEST_CERTIFICATE_A (0x70|SSL_ST_ACCEPT)
-#define SSL2_ST_SEND_REQUEST_CERTIFICATE_B (0x71|SSL_ST_ACCEPT)
-#define SSL2_ST_SEND_REQUEST_CERTIFICATE_C (0x72|SSL_ST_ACCEPT)
-#define SSL2_ST_SEND_REQUEST_CERTIFICATE_D (0x73|SSL_ST_ACCEPT)
-#define SSL2_ST_SERVER_START_ENCRYPTION (0x80|SSL_ST_ACCEPT)
-#define SSL2_ST_X509_GET_SERVER_CERTIFICATE (0x90|SSL_ST_ACCEPT)
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
diff --git a/src/include/openssl/ssl3.h b/src/include/openssl/ssl3.h
index 640a228..957b740 100644
--- a/src/include/openssl/ssl3.h
+++ b/src/include/openssl/ssl3.h
@@ -114,13 +114,10 @@
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
*/
-#ifndef HEADER_SSL3_H
-#define HEADER_SSL3_H
+#ifndef OPENSSL_HEADER_SSL3_H
+#define OPENSSL_HEADER_SSL3_H
#include <openssl/aead.h>
-#include <openssl/buf.h>
-#include <openssl/evp.h>
-#include <openssl/ssl.h>
#include <openssl/type_check.h>
#ifdef __cplusplus
@@ -128,10 +125,14 @@ extern "C" {
#endif
-/* Signalling cipher suite value: from RFC5746 */
+/* These are kept to support clients that negotiates higher protocol versions
+ * using SSLv2 client hello records. */
+#define SSL2_MT_CLIENT_HELLO 1
+#define SSL2_VERSION 0x0002
+
+/* Signalling cipher suite value from RFC 5746. */
#define SSL3_CK_SCSV 0x030000FF
-/* Fallback signalling cipher suite value: not IANA assigned.
- * See https://tools.ietf.org/html/draft-bmoeller-tls-downgrade-scsv-01 */
+/* Fallback signalling cipher suite value from RFC 7507. */
#define SSL3_CK_FALLBACK_SCSV 0x03005600
#define SSL3_CK_RSA_NULL_MD5 0x03000001
@@ -230,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 */
@@ -269,29 +268,11 @@ OPENSSL_COMPILE_ASSERT(
#define SSL3_MD_CLIENT_FINISHED_CONST "\x43\x4C\x4E\x54"
#define SSL3_MD_SERVER_FINISHED_CONST "\x53\x52\x56\x52"
-#define SSL3_VERSION 0x0300
-#define SSL3_VERSION_MAJOR 0x03
-#define SSL3_VERSION_MINOR 0x00
-
#define SSL3_RT_CHANGE_CIPHER_SPEC 20
#define SSL3_RT_ALERT 21
#define SSL3_RT_HANDSHAKE 22
#define SSL3_RT_APPLICATION_DATA 23
-/* Pseudo content types to indicate additional parameters */
-#define TLS1_RT_CRYPTO 0x1000
-#define TLS1_RT_CRYPTO_PREMASTER (TLS1_RT_CRYPTO | 0x1)
-#define TLS1_RT_CRYPTO_CLIENT_RANDOM (TLS1_RT_CRYPTO | 0x2)
-#define TLS1_RT_CRYPTO_SERVER_RANDOM (TLS1_RT_CRYPTO | 0x3)
-#define TLS1_RT_CRYPTO_MASTER (TLS1_RT_CRYPTO | 0x4)
-
-#define TLS1_RT_CRYPTO_READ 0x0000
-#define TLS1_RT_CRYPTO_WRITE 0x0100
-#define TLS1_RT_CRYPTO_MAC (TLS1_RT_CRYPTO | 0x5)
-#define TLS1_RT_CRYPTO_KEY (TLS1_RT_CRYPTO | 0x6)
-#define TLS1_RT_CRYPTO_IV (TLS1_RT_CRYPTO | 0x7)
-#define TLS1_RT_CRYPTO_FIXED_IV (TLS1_RT_CRYPTO | 0x8)
-
/* Pseudo content type for SSL/TLS header info */
#define SSL3_RT_HEADER 0x100
@@ -312,34 +293,6 @@ OPENSSL_COMPILE_ASSERT(
#define SSL3_AD_ILLEGAL_PARAMETER 47 /* fatal */
#define SSL3_AD_INAPPROPRIATE_FALLBACK 86 /* fatal */
-typedef struct ssl3_record_st {
- /* type is the record type. */
- uint8_t type;
- /* length is the number of unconsumed bytes of |data|. */
- 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|. */
- uint8_t *data;
- /* epoch, in DTLS, is the epoch number of the record. */
- uint16_t epoch;
- /* seq_num, in DTLS, is the sequence number of the record. The top two bytes
- * are always zero.
- *
- * TODO(davidben): This is confusing. They should include the epoch or the
- * field should be six bytes. */
- uint8_t seq_num[8];
-} SSL3_RECORD;
-
-typedef struct ssl3_buffer_st {
- uint8_t *buf; /* at least SSL3_RT_MAX_PACKET_SIZE bytes, see
- ssl3_setup_buffers() */
- size_t len; /* buffer size */
- int offset; /* where to 'copy from' */
- int left; /* how many bytes left */
-} SSL3_BUFFER;
-
#define SSL3_CT_RSA_SIGN 1
#define SSL3_CT_DSS_SIGN 2
#define SSL3_CT_RSA_FIXED_DH 3
@@ -348,208 +301,12 @@ typedef struct ssl3_buffer_st {
#define SSL3_CT_DSS_EPHEMERAL_DH 6
#define SSL3_CT_FORTEZZA_DMS 20
-
-/* 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;
-
- /* The value of 'extra' when the buffers were initialized */
- int init_extra;
-
- /* have_version is true if the connection's final version is known. Otherwise
- * the version has not been negotiated yet. */
- char have_version;
-
- /* initial_handshake_complete is true if the initial handshake has
- * completed. */
- char initial_handshake_complete;
-
- /* sniff_buffer is used by the server in the initial handshake to read a
- * V2ClientHello before the record layer is initialized. */
- BUF_MEM *sniff_buffer;
- size_t sniff_buffer_len;
-
- SSL3_BUFFER rbuf; /* read IO goes into here */
- SSL3_BUFFER wbuf; /* write IO goes into here */
-
- 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;
-
- /* partial write - check the numbers match */
- unsigned int wnum; /* number of bytes sent so far */
- int wpend_tot; /* number bytes written */
- int wpend_type;
- int wpend_ret; /* number of bytes submitted */
- const uint8_t *wpend_buf;
-
- /* used during startup, digest all incoming/outgoing packets */
- BIO *handshake_buffer;
- /* When set of handshake digests is determined, buffer is hashed and freed
- * and MD_CTX-es for all required digests are stored in this array */
- EVP_MD_CTX **handshake_dgst;
- /* 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
- * alert via the warning alert */
- int alert_dispatch;
- uint8_t send_alert[2];
-
- int total_renegotiations;
-
- /* State pertaining to the pending handshake.
- *
- * TODO(davidben): State is current spread all over the place. Move
- * 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];
- int finish_md_len;
- uint8_t peer_finish_md[EVP_MAX_MD_SIZE * 2];
- int peer_finish_md_len;
-
- unsigned long message_size;
- int message_type;
-
- /* 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;
-
- int reuse_message;
-
- /* Client-only: cert_req determines if a client certificate is to be sent.
- * This is 0 if no client Certificate message is to be sent, 1 if there is
- * a client certificate, and 2 to send an empty client Certificate
- * message. */
- int cert_req;
-
- /* Client-only: ca_names contains the list of CAs received in a
- * CertificateRequest message. */
- STACK_OF(X509_NAME) *ca_names;
-
- /* Client-only: certificate_types contains the set of certificate types
- * received in a CertificateRequest message. */
- uint8_t *certificate_types;
- size_t num_certificate_types;
-
- int key_block_length;
- uint8_t *key_block;
-
- const EVP_AEAD *new_aead;
- uint8_t new_mac_secret_len;
- uint8_t new_fixed_iv_len;
- uint8_t new_variable_iv_len;
-
- /* Server-only: cert_request is true if a client certificate was
- * requested. */
- int cert_request;
-
- /* certificate_status_expected is true if OCSP stapling was negotiated and
- * the server is expected to send a CertificateStatus message. */
- char certificate_status_expected;
-
- /* peer_ecpointformatlist contains the EC point formats advertised by the
- * peer. */
- uint8_t *peer_ecpointformatlist;
- size_t peer_ecpointformatlist_length;
-
- /* Server-only: peer_ellipticcurvelist contains the EC curve IDs advertised
- * by the peer. This is only set on the server's end. The server does not
- * advertise this extension to the client. */
- uint16_t *peer_ellipticcurvelist;
- size_t peer_ellipticcurvelist_length;
-
- /* extended_master_secret indicates whether the extended master secret
- * computation is used in this handshake. Note that this is different from
- * whether it was used for the current session. If this is a resumption
- * handshake then EMS might be negotiated in the client and server hello
- * messages, but it doesn't matter if the session that's being resumed
- * didn't use it to create the master secret initially. */
- char extended_master_secret;
-
- /* Client-only: peer_psk_identity_hint is the psk_identity_hint sent by the
- * server when using a PSK key exchange. */
- char *peer_psk_identity_hint;
-
- /* new_mac_secret_size is unused and exists only until wpa_supplicant can
- * be updated. It is only needed for EAP-FAST, which we don't support. */
- uint8_t new_mac_secret_size;
-
- /* Client-only: in_false_start is one if there is a pending handshake in
- * False Start. The client may write data at this point. */
- char in_false_start;
- } tmp;
-
- /* Connection binding to prevent renegotiation attacks */
- uint8_t previous_client_finished[EVP_MAX_MD_SIZE];
- uint8_t previous_client_finished_len;
- uint8_t previous_server_finished[EVP_MAX_MD_SIZE];
- uint8_t previous_server_finished_len;
- int send_connection_binding; /* TODOEKR */
-
- /* Set if we saw the Next Protocol Negotiation extension from our peer. */
- int next_proto_neg_seen;
-
- /* ALPN information
- * (we are in the process of transitioning from NPN to ALPN.) */
-
- /* In a server these point to the selected ALPN protocol after the
- * ClientHello has been processed. In a client these contain the protocol
- * that the server selected once the ServerHello has been processed. */
- uint8_t *alpn_selected;
- size_t alpn_selected_len;
-
- /* In a client, this means that the server supported Channel ID and that a
- * Channel ID was sent. In a server it means that we echoed support for
- * Channel IDs and that tlsext_channel_id will be valid after the
- * handshake. */
- char tlsext_channel_id_valid;
- /* tlsext_channel_id_new means that the updated Channel ID extension was
- * negotiated. This is a temporary hack in the code to support both forms of
- * Channel ID extension while we transition to the new format, which fixed a
- * security issue. */
- char tlsext_channel_id_new;
- /* For a server:
- * If |tlsext_channel_id_valid| is true, then this contains the
- * verified Channel ID from the client: a P256 point, (x,y), where
- * each are big-endian values. */
- uint8_t tlsext_channel_id[64];
-} SSL3_STATE;
-
/* SSLv3 */
/* client */
/* extra state */
#define SSL3_ST_CW_FLUSH (0x100 | SSL_ST_CONNECT)
#define SSL3_ST_FALSE_START (0x101 | SSL_ST_CONNECT)
+#define SSL3_ST_VERIFY_SERVER_CERT (0x102 | SSL_ST_CONNECT)
/* write to server */
#define SSL3_ST_CW_CLNT_HELLO_A (0x110 | SSL_ST_CONNECT)
#define SSL3_ST_CW_CLNT_HELLO_B (0x111 | SSL_ST_CONNECT)
@@ -575,6 +332,7 @@ typedef struct ssl3_state_st {
#define SSL3_ST_CW_KEY_EXCH_B (0x181 | SSL_ST_CONNECT)
#define SSL3_ST_CW_CERT_VRFY_A (0x190 | SSL_ST_CONNECT)
#define SSL3_ST_CW_CERT_VRFY_B (0x191 | SSL_ST_CONNECT)
+#define SSL3_ST_CW_CERT_VRFY_C (0x192 | SSL_ST_CONNECT)
#define SSL3_ST_CW_CHANGE_A (0x1A0 | SSL_ST_CONNECT)
#define SSL3_ST_CW_CHANGE_B (0x1A1 | SSL_ST_CONNECT)
#define SSL3_ST_CW_NEXT_PROTO_A (0x200 | SSL_ST_CONNECT)
@@ -598,7 +356,6 @@ typedef struct ssl3_state_st {
/* read from client */
#define SSL3_ST_SR_INITIAL_BYTES (0x240 | SSL_ST_ACCEPT)
#define SSL3_ST_SR_V2_CLIENT_HELLO (0x241 | SSL_ST_ACCEPT)
-/* Do not change the number values, they do matter */
#define SSL3_ST_SR_CLNT_HELLO_A (0x110 | SSL_ST_ACCEPT)
#define SSL3_ST_SR_CLNT_HELLO_B (0x111 | SSL_ST_ACCEPT)
#define SSL3_ST_SR_CLNT_HELLO_C (0x112 | SSL_ST_ACCEPT)
@@ -613,6 +370,7 @@ typedef struct ssl3_state_st {
#define SSL3_ST_SW_CERT_B (0x141 | SSL_ST_ACCEPT)
#define SSL3_ST_SW_KEY_EXCH_A (0x150 | SSL_ST_ACCEPT)
#define SSL3_ST_SW_KEY_EXCH_B (0x151 | SSL_ST_ACCEPT)
+#define SSL3_ST_SW_KEY_EXCH_C (0x152 | SSL_ST_ACCEPT)
#define SSL3_ST_SW_CERT_REQ_A (0x160 | SSL_ST_ACCEPT)
#define SSL3_ST_SW_CERT_REQ_B (0x161 | SSL_ST_ACCEPT)
#define SSL3_ST_SW_SRVR_DONE_A (0x170 | SSL_ST_ACCEPT)
@@ -622,6 +380,7 @@ typedef struct ssl3_state_st {
#define SSL3_ST_SR_CERT_B (0x181 | SSL_ST_ACCEPT)
#define SSL3_ST_SR_KEY_EXCH_A (0x190 | SSL_ST_ACCEPT)
#define SSL3_ST_SR_KEY_EXCH_B (0x191 | SSL_ST_ACCEPT)
+#define SSL3_ST_SR_KEY_EXCH_C (0x192 | SSL_ST_ACCEPT)
#define SSL3_ST_SR_CERT_VRFY_A (0x1A0 | SSL_ST_ACCEPT)
#define SSL3_ST_SR_CERT_VRFY_B (0x1A1 | SSL_ST_ACCEPT)
#define SSL3_ST_SR_CHANGE (0x1B0 | SSL_ST_ACCEPT)
@@ -676,6 +435,7 @@ typedef struct ssl3_state_st {
#ifdef __cplusplus
-}
-#endif
+} /* extern C */
#endif
+
+#endif /* OPENSSL_HEADER_SSL3_H */
diff --git a/src/include/openssl/stack.h b/src/include/openssl/stack.h
index 350fa14..16b9f4f 100644
--- a/src/include/openssl/stack.h
+++ b/src/include/openssl/stack.h
@@ -111,11 +111,6 @@ typedef struct stack_st {
#define STACK_OF(type) struct stack_st_##type
-#define DEFINE_STACK_OF(type) \
-STACK_OF(type) {\
- _STACK stack; \
-}
-
#define DECLARE_STACK_OF(type) STACK_OF(type);
/* The make_macros.sh script in this directory parses the following lines and
@@ -139,13 +134,12 @@ STACK_OF(type) {\
* STACK_OF:GENERAL_NAME
* STACK_OF:GENERAL_NAMES
* STACK_OF:GENERAL_SUBTREE
- * STACK_OF:MIME_HEADER
- * STACK_OF:PKCS7_SIGNER_INFO
- * STACK_OF:PKCS7_RECIP_INFO
* STACK_OF:POLICYINFO
* STACK_OF:POLICYQUALINFO
* STACK_OF:POLICY_MAPPING
+ * STACK_OF:RSA_additional_prime
* STACK_OF:SSL_COMP
+ * STACK_OF:SSL_CUSTOM_EXTENSION
* STACK_OF:STACK_OF_X509_NAME_ENTRY
* STACK_OF:SXNETID
* STACK_OF:X509
diff --git a/src/include/openssl/stack_macros.h b/src/include/openssl/stack_macros.h
index dadcf6b..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_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)))
-
-/* 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)))
-
/* POLICYINFO */
#define sk_POLICYINFO_new(comp) \
((STACK_OF(POLICYINFO) *)sk_new(CHECKED_CAST( \
@@ -1937,6 +1681,99 @@
copy_func), \
CHECKED_CAST(void (*)(void *), void (*)(POLICY_MAPPING *), free_func)))
+/* RSA_additional_prime */
+#define sk_RSA_additional_prime_new(comp) \
+ ((STACK_OF(RSA_additional_prime) *)sk_new(CHECKED_CAST( \
+ stack_cmp_func, \
+ int (*)(const RSA_additional_prime **a, const RSA_additional_prime **b), \
+ comp)))
+
+#define sk_RSA_additional_prime_new_null() \
+ ((STACK_OF(RSA_additional_prime) *)sk_new_null())
+
+#define sk_RSA_additional_prime_num(sk) \
+ sk_num(CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk))
+
+#define sk_RSA_additional_prime_zero(sk) \
+ sk_zero(CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk));
+
+#define sk_RSA_additional_prime_value(sk, i) \
+ ((RSA_additional_prime *)sk_value( \
+ CHECKED_CAST(_STACK *, const STACK_OF(RSA_additional_prime) *, sk), \
+ (i)))
+
+#define sk_RSA_additional_prime_set(sk, i, p) \
+ ((RSA_additional_prime *)sk_set( \
+ CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk), (i), \
+ CHECKED_CAST(void *, RSA_additional_prime *, p)))
+
+#define sk_RSA_additional_prime_free(sk) \
+ sk_free(CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk))
+
+#define sk_RSA_additional_prime_pop_free(sk, free_func) \
+ sk_pop_free(CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk), \
+ CHECKED_CAST(void (*)(void *), void (*)(RSA_additional_prime *), \
+ free_func))
+
+#define sk_RSA_additional_prime_insert(sk, p, where) \
+ sk_insert(CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk), \
+ CHECKED_CAST(void *, RSA_additional_prime *, p), (where))
+
+#define sk_RSA_additional_prime_delete(sk, where) \
+ ((RSA_additional_prime *)sk_delete( \
+ CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk), (where)))
+
+#define sk_RSA_additional_prime_delete_ptr(sk, p) \
+ ((RSA_additional_prime *)sk_delete_ptr( \
+ CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk), \
+ CHECKED_CAST(void *, RSA_additional_prime *, p)))
+
+#define sk_RSA_additional_prime_find(sk, out_index, p) \
+ sk_find(CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk), \
+ (out_index), CHECKED_CAST(void *, RSA_additional_prime *, p))
+
+#define sk_RSA_additional_prime_shift(sk) \
+ ((RSA_additional_prime *)sk_shift( \
+ CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk)))
+
+#define sk_RSA_additional_prime_push(sk, p) \
+ sk_push(CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk), \
+ CHECKED_CAST(void *, RSA_additional_prime *, p))
+
+#define sk_RSA_additional_prime_pop(sk) \
+ ((RSA_additional_prime *)sk_pop( \
+ CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk)))
+
+#define sk_RSA_additional_prime_dup(sk) \
+ ((STACK_OF(RSA_additional_prime) *)sk_dup( \
+ CHECKED_CAST(_STACK *, const STACK_OF(RSA_additional_prime) *, sk)))
+
+#define sk_RSA_additional_prime_sort(sk) \
+ sk_sort(CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk))
+
+#define sk_RSA_additional_prime_is_sorted(sk) \
+ sk_is_sorted( \
+ CHECKED_CAST(_STACK *, const STACK_OF(RSA_additional_prime) *, sk))
+
+#define sk_RSA_additional_prime_set_cmp_func(sk, comp) \
+ ((int (*)(const RSA_additional_prime **a, const RSA_additional_prime **b)) \
+ sk_set_cmp_func( \
+ CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk), \
+ CHECKED_CAST(stack_cmp_func, \
+ int (*)(const RSA_additional_prime **a, \
+ const RSA_additional_prime **b), \
+ comp)))
+
+#define sk_RSA_additional_prime_deep_copy(sk, copy_func, free_func) \
+ ((STACK_OF(RSA_additional_prime) *)sk_deep_copy( \
+ CHECKED_CAST(const _STACK *, const STACK_OF(RSA_additional_prime) *, \
+ sk), \
+ CHECKED_CAST(void *(*)(void *), \
+ RSA_additional_prime *(*)(RSA_additional_prime *), \
+ copy_func), \
+ CHECKED_CAST(void (*)(void *), void (*)(RSA_additional_prime *), \
+ free_func)))
+
/* SSL_COMP */
#define sk_SSL_COMP_new(comp) \
((STACK_OF(SSL_COMP) *)sk_new(CHECKED_CAST( \
@@ -2013,6 +1850,99 @@
CHECKED_CAST(void *(*)(void *), SSL_COMP *(*)(SSL_COMP *), copy_func), \
CHECKED_CAST(void (*)(void *), void (*)(SSL_COMP *), free_func)))
+/* SSL_CUSTOM_EXTENSION */
+#define sk_SSL_CUSTOM_EXTENSION_new(comp) \
+ ((STACK_OF(SSL_CUSTOM_EXTENSION) *)sk_new(CHECKED_CAST( \
+ stack_cmp_func, \
+ int (*)(const SSL_CUSTOM_EXTENSION **a, const SSL_CUSTOM_EXTENSION **b), \
+ comp)))
+
+#define sk_SSL_CUSTOM_EXTENSION_new_null() \
+ ((STACK_OF(SSL_CUSTOM_EXTENSION) *)sk_new_null())
+
+#define sk_SSL_CUSTOM_EXTENSION_num(sk) \
+ sk_num(CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk))
+
+#define sk_SSL_CUSTOM_EXTENSION_zero(sk) \
+ sk_zero(CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk));
+
+#define sk_SSL_CUSTOM_EXTENSION_value(sk, i) \
+ ((SSL_CUSTOM_EXTENSION *)sk_value( \
+ CHECKED_CAST(_STACK *, const STACK_OF(SSL_CUSTOM_EXTENSION) *, sk), \
+ (i)))
+
+#define sk_SSL_CUSTOM_EXTENSION_set(sk, i, p) \
+ ((SSL_CUSTOM_EXTENSION *)sk_set( \
+ CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk), (i), \
+ CHECKED_CAST(void *, SSL_CUSTOM_EXTENSION *, p)))
+
+#define sk_SSL_CUSTOM_EXTENSION_free(sk) \
+ sk_free(CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk))
+
+#define sk_SSL_CUSTOM_EXTENSION_pop_free(sk, free_func) \
+ sk_pop_free(CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk), \
+ CHECKED_CAST(void (*)(void *), void (*)(SSL_CUSTOM_EXTENSION *), \
+ free_func))
+
+#define sk_SSL_CUSTOM_EXTENSION_insert(sk, p, where) \
+ sk_insert(CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk), \
+ CHECKED_CAST(void *, SSL_CUSTOM_EXTENSION *, p), (where))
+
+#define sk_SSL_CUSTOM_EXTENSION_delete(sk, where) \
+ ((SSL_CUSTOM_EXTENSION *)sk_delete( \
+ CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk), (where)))
+
+#define sk_SSL_CUSTOM_EXTENSION_delete_ptr(sk, p) \
+ ((SSL_CUSTOM_EXTENSION *)sk_delete_ptr( \
+ CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk), \
+ CHECKED_CAST(void *, SSL_CUSTOM_EXTENSION *, p)))
+
+#define sk_SSL_CUSTOM_EXTENSION_find(sk, out_index, p) \
+ sk_find(CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk), \
+ (out_index), CHECKED_CAST(void *, SSL_CUSTOM_EXTENSION *, p))
+
+#define sk_SSL_CUSTOM_EXTENSION_shift(sk) \
+ ((SSL_CUSTOM_EXTENSION *)sk_shift( \
+ CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk)))
+
+#define sk_SSL_CUSTOM_EXTENSION_push(sk, p) \
+ sk_push(CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk), \
+ CHECKED_CAST(void *, SSL_CUSTOM_EXTENSION *, p))
+
+#define sk_SSL_CUSTOM_EXTENSION_pop(sk) \
+ ((SSL_CUSTOM_EXTENSION *)sk_pop( \
+ CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk)))
+
+#define sk_SSL_CUSTOM_EXTENSION_dup(sk) \
+ ((STACK_OF(SSL_CUSTOM_EXTENSION) *)sk_dup( \
+ CHECKED_CAST(_STACK *, const STACK_OF(SSL_CUSTOM_EXTENSION) *, sk)))
+
+#define sk_SSL_CUSTOM_EXTENSION_sort(sk) \
+ sk_sort(CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk))
+
+#define sk_SSL_CUSTOM_EXTENSION_is_sorted(sk) \
+ sk_is_sorted( \
+ CHECKED_CAST(_STACK *, const STACK_OF(SSL_CUSTOM_EXTENSION) *, sk))
+
+#define sk_SSL_CUSTOM_EXTENSION_set_cmp_func(sk, comp) \
+ ((int (*)(const SSL_CUSTOM_EXTENSION **a, const SSL_CUSTOM_EXTENSION **b)) \
+ sk_set_cmp_func( \
+ CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk), \
+ CHECKED_CAST(stack_cmp_func, \
+ int (*)(const SSL_CUSTOM_EXTENSION **a, \
+ const SSL_CUSTOM_EXTENSION **b), \
+ comp)))
+
+#define sk_SSL_CUSTOM_EXTENSION_deep_copy(sk, copy_func, free_func) \
+ ((STACK_OF(SSL_CUSTOM_EXTENSION) *)sk_deep_copy( \
+ CHECKED_CAST(const _STACK *, const STACK_OF(SSL_CUSTOM_EXTENSION) *, \
+ sk), \
+ CHECKED_CAST(void *(*)(void *), \
+ SSL_CUSTOM_EXTENSION *(*)(SSL_CUSTOM_EXTENSION *), \
+ copy_func), \
+ CHECKED_CAST(void (*)(void *), void (*)(SSL_CUSTOM_EXTENSION *), \
+ free_func)))
+
/* STACK_OF_X509_NAME_ENTRY */
#define sk_STACK_OF_X509_NAME_ENTRY_new(comp) \
((STACK_OF(STACK_OF_X509_NAME_ENTRY) *)sk_new(CHECKED_CAST( \
@@ -3591,25 +3521,25 @@
#define sk_void_new_null() ((STACK_OF(void)*)sk_new_null())
-#define sk_void_num(sk) sk_num(CHECKED_CAST(_STACK *, STACK_OF(void)*, sk))
+#define sk_void_num(sk) sk_num(CHECKED_CAST(_STACK *, STACK_OF(void) *, sk))
-#define sk_void_zero(sk) sk_zero(CHECKED_CAST(_STACK *, STACK_OF(void)*, sk));
+#define sk_void_zero(sk) sk_zero(CHECKED_CAST(_STACK *, STACK_OF(void) *, sk));
#define sk_void_value(sk, i) \
- ((void *)sk_value(CHECKED_CAST(_STACK *, const STACK_OF(void)*, sk), (i)))
+ ((void *)sk_value(CHECKED_CAST(_STACK *, const STACK_OF(void) *, sk), (i)))
#define sk_void_set(sk, i, p) \
((void *)sk_set(CHECKED_CAST(_STACK *, STACK_OF(void)*, sk), (i), \
CHECKED_CAST(void *, void *, p)))
-#define sk_void_free(sk) sk_free(CHECKED_CAST(_STACK *, STACK_OF(void)*, sk))
+#define sk_void_free(sk) sk_free(CHECKED_CAST(_STACK *, STACK_OF(void) *, sk))
-#define sk_void_pop_free(sk, free_func) \
- sk_pop_free(CHECKED_CAST(_STACK *, STACK_OF(void)*, sk), \
+#define sk_void_pop_free(sk, free_func) \
+ sk_pop_free(CHECKED_CAST(_STACK *, STACK_OF(void) *, sk), \
CHECKED_CAST(void (*)(void *), void (*)(void *), free_func))
-#define sk_void_insert(sk, p, where) \
- sk_insert(CHECKED_CAST(_STACK *, STACK_OF(void)*, sk), \
+#define sk_void_insert(sk, p, where) \
+ sk_insert(CHECKED_CAST(_STACK *, STACK_OF(void) *, sk), \
CHECKED_CAST(void *, void *, p), (where))
#define sk_void_delete(sk, where) \
@@ -3619,27 +3549,27 @@
((void *)sk_delete_ptr(CHECKED_CAST(_STACK *, STACK_OF(void)*, sk), \
CHECKED_CAST(void *, void *, p)))
-#define sk_void_find(sk, out_index, p) \
- sk_find(CHECKED_CAST(_STACK *, STACK_OF(void)*, sk), (out_index), \
+#define sk_void_find(sk, out_index, p) \
+ sk_find(CHECKED_CAST(_STACK *, STACK_OF(void) *, sk), (out_index), \
CHECKED_CAST(void *, void *, p))
#define sk_void_shift(sk) \
((void *)sk_shift(CHECKED_CAST(_STACK *, STACK_OF(void)*, sk)))
-#define sk_void_push(sk, p) \
- sk_push(CHECKED_CAST(_STACK *, STACK_OF(void)*, sk), \
+#define sk_void_push(sk, p) \
+ sk_push(CHECKED_CAST(_STACK *, STACK_OF(void) *, sk), \
CHECKED_CAST(void *, void *, p))
#define sk_void_pop(sk) \
((void *)sk_pop(CHECKED_CAST(_STACK *, STACK_OF(void)*, sk)))
#define sk_void_dup(sk) \
- ((STACK_OF(void)*)sk_dup(CHECKED_CAST(_STACK *, const STACK_OF(void)*, sk)))
+ ((STACK_OF(void)*)sk_dup(CHECKED_CAST(_STACK *, const STACK_OF(void) *, sk)))
-#define sk_void_sort(sk) sk_sort(CHECKED_CAST(_STACK *, STACK_OF(void)*, sk))
+#define sk_void_sort(sk) sk_sort(CHECKED_CAST(_STACK *, STACK_OF(void) *, sk))
#define sk_void_is_sorted(sk) \
- sk_is_sorted(CHECKED_CAST(_STACK *, const STACK_OF(void)*, sk))
+ sk_is_sorted(CHECKED_CAST(_STACK *, const STACK_OF(void) *, sk))
#define sk_void_set_cmp_func(sk, comp) \
((int (*)(const void **a, const void **b))sk_set_cmp_func( \
@@ -3649,7 +3579,7 @@
#define sk_void_deep_copy(sk, copy_func, free_func) \
((STACK_OF(void)*)sk_deep_copy( \
- CHECKED_CAST(const _STACK *, const STACK_OF(void)*, sk), \
+ CHECKED_CAST(const _STACK *, const STACK_OF(void) *, sk), \
CHECKED_CAST(void *(*)(void *), void *(*)(void *), copy_func), \
CHECKED_CAST(void (*)(void *), void (*)(void *), free_func)))
diff --git a/src/include/openssl/time_support.h b/src/include/openssl/time_support.h
index 912e672..cec430d 100644
--- a/src/include/openssl/time_support.h
+++ b/src/include/openssl/time_support.h
@@ -55,8 +55,8 @@
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
-#ifndef OPENSSL_HEADER_TIME_H
-#define OPENSSL_HEADER_TIME_H
+#ifndef OPENSSL_HEADER_TIME_SUPPORT_H
+#define OPENSSL_HEADER_TIME_SUPPORT_H
#include <openssl/base.h>
@@ -87,4 +87,4 @@ int OPENSSL_gmtime_diff(int *out_days, int *out_secs, const struct tm *from,
} /* extern C */
#endif
-#endif /* OPENSSL_HEADER_TIME_H */
+#endif /* OPENSSL_HEADER_TIME_SUPPORT_H */
diff --git a/src/include/openssl/tls1.h b/src/include/openssl/tls1.h
index f2bee27..92d2752 100644
--- a/src/include/openssl/tls1.h
+++ b/src/include/openssl/tls1.h
@@ -1,4 +1,3 @@
-/* ssl/tls1.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -148,11 +147,10 @@
* OTHERWISE.
*/
-#ifndef HEADER_TLS1_H
-#define HEADER_TLS1_H
+#ifndef OPENSSL_HEADER_TLS1_H
+#define OPENSSL_HEADER_TLS1_H
-#include <openssl/buf.h>
-#include <openssl/stack.h>
+#include <openssl/base.h>
#ifdef __cplusplus
extern "C" {
@@ -209,7 +207,7 @@ extern "C" {
#define TLSEXT_TYPE_signature_algorithms 13
/* ExtensionType value from RFC5764 */
-#define TLSEXT_TYPE_use_srtp 14
+#define TLSEXT_TYPE_srtp 14
/* ExtensionType value from RFC5620 */
#define TLSEXT_TYPE_heartbeat 15
@@ -217,10 +215,7 @@ extern "C" {
/* ExtensionType value from RFC7301 */
#define TLSEXT_TYPE_application_layer_protocol_negotiation 16
-/* ExtensionType value for TLS padding extension.
- * http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml
- * http://tools.ietf.org/html/draft-agl-tls-padding-03
- */
+/* ExtensionType value from RFC7685 */
#define TLSEXT_TYPE_padding 21
/* https://tools.ietf.org/html/draft-ietf-tls-session-hash-01 */
@@ -239,11 +234,8 @@ extern "C" {
#define TLSEXT_TYPE_next_proto_neg 13172
/* This is not an IANA defined extension number */
-#define TLSEXT_TYPE_channel_id 30031
-#define TLSEXT_TYPE_channel_id_new 30032
+#define TLSEXT_TYPE_channel_id 30032
-/* NameType value from RFC 3546 */
-#define TLSEXT_NAMETYPE_host_name 0
/* status request value from RFC 3546 */
#define TLSEXT_STATUSTYPE_ocsp 1
@@ -278,83 +270,6 @@ extern "C" {
#define TLSEXT_MAXLEN_host_name 255
-OPENSSL_EXPORT const char *SSL_get_servername(const SSL *s, const int type);
-OPENSSL_EXPORT int SSL_get_servername_type(const SSL *s);
-
-/* SSL_export_keying_material exports a value derived from the master secret, as
- * specified in RFC 5705. It writes |out_len| bytes to |out| given a label and
- * optional context. (Since a zero length context is allowed, the |use_context|
- * flag controls whether a context is included.)
- *
- * It returns one on success and zero otherwise. */
-OPENSSL_EXPORT int SSL_export_keying_material(
- SSL *s, 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);
-
-OPENSSL_EXPORT int SSL_get_sigalgs(SSL *s, int idx, int *psign, int *phash,
- int *psignandhash, uint8_t *rsig,
- uint8_t *rhash);
-
-OPENSSL_EXPORT int SSL_get_shared_sigalgs(SSL *s, int idx, int *psign,
- int *phash, int *psignandhash,
- uint8_t *rsig, uint8_t *rhash);
-
-/* SSL_set_tlsext_host_name, for a client, configures |ssl| to advertise |name|
- * in the server_name extension. It returns one on success and zero on error. */
-OPENSSL_EXPORT int SSL_set_tlsext_host_name(SSL *ssl, const char *name);
-
-/* SSL_CTX_set_tlsext_servername_callback configures |callback| to be called on
- * the server after ClientHello extensions have been parsed and returns one.
- * |callback| may use |SSL_get_servername| to examine the server_name extension
- * and return a |SSL_TLSEXT_ERR_*| value. If it returns |SSL_TLSEXT_ERR_NOACK|,
- * the server_name extension is not acknowledged in the ServerHello. If the
- * return value signals an alert, |callback| should set |*out_alert| to the
- * alert to send. */
-OPENSSL_EXPORT int SSL_CTX_set_tlsext_servername_callback(
- SSL_CTX *ctx, int (*callback)(SSL *ssl, int *out_alert, void *arg));
-
-#define SSL_TLSEXT_ERR_OK 0
-#define SSL_TLSEXT_ERR_ALERT_WARNING 1
-#define SSL_TLSEXT_ERR_ALERT_FATAL 2
-#define SSL_TLSEXT_ERR_NOACK 3
-
-/* SSL_CTX_set_tlsext_servername_arg sets the argument to the servername
- * callback and returns one. See |SSL_CTX_set_tlsext_servername_callback|. */
-OPENSSL_EXPORT int SSL_CTX_set_tlsext_servername_arg(SSL_CTX *ctx, void *arg);
-
-#define SSL_CTX_get_tlsext_ticket_keys(ctx, keys, keylen) \
- SSL_CTX_ctrl((ctx), SSL_CTRL_GET_TLSEXT_TICKET_KEYS, (keylen), (keys))
-#define SSL_CTX_set_tlsext_ticket_keys(ctx, keys, keylen) \
- SSL_CTX_ctrl((ctx), SSL_CTRL_SET_TLSEXT_TICKET_KEYS, (keylen), (keys))
-
-/* SSL_CTX_set_tlsext_ticket_key_cb sets the ticket callback to |callback| and
- * returns one. |callback| will be called when encrypting a new ticket and when
- * decrypting a ticket from the client.
- *
- * In both modes, |ctx| and |hmac_ctx| will already have been initialized with
- * |EVP_CIPHER_CTX_init| and |HMAC_CTX_init|, respectively. |callback|
- * configures |hmac_ctx| with an HMAC digest and key, and configures |ctx|
- * for encryption or decryption, based on the mode.
- *
- * When encrypting a new ticket, |encrypt| will be one. It writes a public
- * 16-byte key name to |key_name| and a fresh IV to |iv|. The output IV length
- * must match |EVP_CIPHER_CTX_iv_length| of the cipher selected. In this mode,
- * |callback| returns 1 on success and -1 on error.
- *
- * When decrypting a ticket, |encrypt| will be zero. |key_name| will point to a
- * 16-byte key name and |iv| points to an IV. The length of the IV consumed must
- * match |EVP_CIPHER_CTX_iv_length| of the cipher selected. In this mode,
- * |callback| returns -1 to abort the handshake, 0 if decrypting the ticket
- * failed, and 1 or 2 on success. If it returns 2, the ticket will be renewed.
- * This may be used to re-key the ticket.
- *
- * WARNING: |callback| wildly breaks the usual return value convention and is
- * called in two different modes. */
-OPENSSL_EXPORT int SSL_CTX_set_tlsext_ticket_key_cb(
- SSL_CTX *ctx, int (*callback)(SSL *ssl, uint8_t *key_name, uint8_t *iv,
- EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
- int encrypt));
-
/* PSK ciphersuites from 4279 */
#define TLS1_CK_PSK_WITH_RC4_128_SHA 0x0300008A
#define TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA 0x0300008B
@@ -512,9 +427,17 @@ OPENSSL_EXPORT int SSL_CTX_set_tlsext_ticket_key_cb(
#define TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256 0x0300C031
#define TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384 0x0300C032
-#define TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305 0x0300CC13
-#define TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305 0x0300CC14
-#define TLS1_CK_DHE_RSA_CHACHA20_POLY1305 0x0300CC15
+#define TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD 0x0300CC13
+#define TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD 0x0300CC14
+
+#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_WITH_CHACHA20_POLY1305_SHA256
/* XXX
* Inconsistency alert:
@@ -676,10 +599,25 @@ OPENSSL_EXPORT int SSL_CTX_set_tlsext_ticket_key_cb(
#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"
-#define TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305 "ECDHE-RSA-CHACHA20-POLY1305"
-#define TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 \
+/* 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"
+
+#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_DHE_RSA_WITH_CHACHA20_POLY1305 "DHE-RSA-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_SHA256
#define TLS_CT_RSA_SIGN 1
#define TLS_CT_DSS_SIGN 2
@@ -709,6 +647,7 @@ OPENSSL_EXPORT int SSL_CTX_set_tlsext_ticket_key_cb(
#ifdef __cplusplus
-}
-#endif
+} /* extern C */
#endif
+
+#endif /* OPENSSL_HEADER_TLS1_H */
diff --git a/src/include/openssl/x509.h b/src/include/openssl/x509.h
index 69c7da6..a5aaf31 100644
--- a/src/include/openssl/x509.h
+++ b/src/include/openssl/x509.h
@@ -1,4 +1,3 @@
-/* crypto/x509/x509.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -102,22 +101,22 @@ extern "C" {
#define X509v3_KU_DECIPHER_ONLY 0x8000
#define X509v3_KU_UNDEF 0xffff
-typedef struct X509_objects_st
+struct X509_objects_st
{
int nid;
int (*a2i)(void);
int (*i2a)(void);
- } X509_OBJECTS;
+ } /* X509_OBJECTS */;
DECLARE_ASN1_SET_OF(X509_ALGOR)
typedef STACK_OF(X509_ALGOR) X509_ALGORS;
-typedef struct X509_val_st
+struct X509_val_st
{
ASN1_TIME *notBefore;
ASN1_TIME *notAfter;
- } X509_VAL;
+ } /* X509_VAL */;
struct X509_pubkey_st
{
@@ -126,25 +125,25 @@ struct X509_pubkey_st
EVP_PKEY *pkey;
};
-typedef struct X509_sig_st
+struct X509_sig_st
{
X509_ALGOR *algor;
ASN1_OCTET_STRING *digest;
- } X509_SIG;
+ } /* X509_SIG */;
-typedef struct X509_name_entry_st
+struct X509_name_entry_st
{
ASN1_OBJECT *object;
ASN1_STRING *value;
int set;
int size; /* temp variable */
- } X509_NAME_ENTRY;
+ } /* X509_NAME_ENTRY */;
DECLARE_STACK_OF(X509_NAME_ENTRY)
DECLARE_ASN1_SET_OF(X509_NAME_ENTRY)
/* we always keep X509_NAMEs in 2 forms. */
-typedef struct X509_name_st
+struct X509_name_st
{
STACK_OF(X509_NAME_ENTRY) *entries;
int modified; /* true if 'bytes' needs to be built */
@@ -156,18 +155,18 @@ typedef struct X509_name_st
/* unsigned long hash; Keep the hash around for lookups */
unsigned char *canon_enc;
int canon_enclen;
- } X509_NAME;
+ } /* X509_NAME */;
DECLARE_STACK_OF(X509_NAME)
#define X509_EX_V_NETSCAPE_HACK 0x8000
#define X509_EX_V_INIT 0x0001
-typedef struct X509_extension_st
+struct X509_extension_st
{
ASN1_OBJECT *object;
ASN1_BOOLEAN critical;
ASN1_OCTET_STRING *value;
- } X509_EXTENSION;
+ } /* X509_EXTENSION */;
typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS;
@@ -175,7 +174,7 @@ DECLARE_STACK_OF(X509_EXTENSION)
DECLARE_ASN1_SET_OF(X509_EXTENSION)
/* a sequence of these are used */
-typedef struct x509_attributes_st
+struct x509_attributes_st
{
ASN1_OBJECT *object;
int single; /* 0 for a set, 1 for a single item (which is wrong) */
@@ -184,13 +183,13 @@ typedef struct x509_attributes_st
/* 0 */ STACK_OF(ASN1_TYPE) *set;
/* 1 */ ASN1_TYPE *single;
} value;
- } X509_ATTRIBUTE;
+ } /* X509_ATTRIBUTE */;
DECLARE_STACK_OF(X509_ATTRIBUTE)
DECLARE_ASN1_SET_OF(X509_ATTRIBUTE)
-typedef struct X509_req_info_st
+struct X509_req_info_st
{
ASN1_ENCODING enc;
ASN1_INTEGER *version;
@@ -198,17 +197,17 @@ typedef struct X509_req_info_st
X509_PUBKEY *pubkey;
/* d=2 hl=2 l= 0 cons: cont: 00 */
STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
- } X509_REQ_INFO;
+ } /* X509_REQ_INFO */;
-typedef struct X509_req_st
+struct X509_req_st
{
X509_REQ_INFO *req_info;
X509_ALGOR *sig_alg;
ASN1_BIT_STRING *signature;
CRYPTO_refcount_t references;
- } X509_REQ;
+ } /* X509_REQ */;
-typedef struct x509_cinf_st
+struct x509_cinf_st
{
ASN1_INTEGER *version; /* [ 0 ] default of v1 */
ASN1_INTEGER *serialNumber;
@@ -221,7 +220,7 @@ typedef struct x509_cinf_st
ASN1_BIT_STRING *subjectUID; /* [ 2 ] optional in v2 */
STACK_OF(X509_EXTENSION) *extensions; /* [ 3 ] optional in v3 */
ASN1_ENCODING enc;
- } X509_CINF;
+ } /* X509_CINF */;
/* This stuff is certificate "auxiliary info"
* it contains details which are useful in certificate
@@ -229,14 +228,14 @@ typedef struct x509_cinf_st
* the end of the certificate itself
*/
-typedef struct x509_cert_aux_st
+struct x509_cert_aux_st
{
STACK_OF(ASN1_OBJECT) *trust; /* trusted uses */
STACK_OF(ASN1_OBJECT) *reject; /* rejected uses */
ASN1_UTF8STRING *alias; /* "friendly name" */
ASN1_OCTET_STRING *keyid; /* key id of private key */
STACK_OF(X509_ALGOR) *other; /* other unspecified info */
- } X509_CERT_AUX;
+ } /* X509_CERT_AUX */;
struct x509_st
{
@@ -269,21 +268,21 @@ DECLARE_ASN1_SET_OF(X509)
/* This is used for a table of trust checking functions */
-typedef struct x509_trust_st {
+struct x509_trust_st {
int trust;
int flags;
int (*check_trust)(struct x509_trust_st *, X509 *, int);
char *name;
int arg1;
void *arg2;
-} X509_TRUST;
+} /* X509_TRUST */;
DECLARE_STACK_OF(X509_TRUST)
-typedef struct x509_cert_pair_st {
+struct x509_cert_pair_st {
X509 *forward;
X509 *reverse;
-} X509_CERT_PAIR;
+} /* X509_CERT_PAIR */;
/* standard trust ids */
@@ -403,7 +402,7 @@ struct x509_revoked_st
DECLARE_STACK_OF(X509_REVOKED)
DECLARE_ASN1_SET_OF(X509_REVOKED)
-typedef struct X509_crl_info_st
+struct X509_crl_info_st
{
ASN1_INTEGER *version;
X509_ALGOR *sig_alg;
@@ -413,7 +412,7 @@ typedef struct X509_crl_info_st
STACK_OF(X509_REVOKED) *revoked;
STACK_OF(X509_EXTENSION) /* [0] */ *extensions;
ASN1_ENCODING enc;
- } X509_CRL_INFO;
+ } /* X509_CRL_INFO */;
struct X509_crl_st
{
@@ -441,7 +440,7 @@ struct X509_crl_st
DECLARE_STACK_OF(X509_CRL)
DECLARE_ASN1_SET_OF(X509_CRL)
-typedef struct private_key_st
+struct private_key_st
{
int version;
/* The PKCS#8 data types */
@@ -458,10 +457,10 @@ typedef struct private_key_st
/* expanded version of 'enc_algor' */
EVP_CIPHER_INFO cipher;
- } X509_PKEY;
+ } /* X509_PKEY */;
#ifndef OPENSSL_NO_EVP
-typedef struct X509_info_st
+struct X509_info_st
{
X509 *x509;
X509_CRL *crl;
@@ -471,7 +470,7 @@ typedef struct X509_info_st
int enc_len;
char *enc_data;
- } X509_INFO;
+ } /* X509_INFO */;
DECLARE_STACK_OF(X509_INFO)
#endif
@@ -480,25 +479,25 @@ DECLARE_STACK_OF(X509_INFO)
* Pat Richard <patr@x509.com> and are used to manipulate
* Netscapes spki structures - useful if you are writing a CA web page
*/
-typedef struct Netscape_spkac_st
+struct Netscape_spkac_st
{
X509_PUBKEY *pubkey;
ASN1_IA5STRING *challenge; /* challenge sent in atlas >= PR2 */
- } NETSCAPE_SPKAC;
+ } /* NETSCAPE_SPKAC */;
-typedef struct Netscape_spki_st
+struct Netscape_spki_st
{
NETSCAPE_SPKAC *spkac; /* signed public key and challenge */
X509_ALGOR *sig_algor;
ASN1_BIT_STRING *signature;
- } NETSCAPE_SPKI;
+ } /* NETSCAPE_SPKI */;
/* Netscape certificate sequence structure */
-typedef struct Netscape_certificate_sequence
+struct Netscape_certificate_sequence
{
ASN1_OBJECT *type;
STACK_OF(X509) *certs;
- } NETSCAPE_CERT_SEQUENCE;
+ } /* NETSCAPE_CERT_SEQUENCE */;
/* Unused (and iv length is wrong)
typedef struct CBCParameter_st
@@ -509,24 +508,24 @@ typedef struct CBCParameter_st
/* Password based encryption structure */
-typedef struct PBEPARAM_st {
+struct PBEPARAM_st {
ASN1_OCTET_STRING *salt;
ASN1_INTEGER *iter;
-} PBEPARAM;
+} /* PBEPARAM */;
/* Password based encryption V2 structures */
-typedef struct PBE2PARAM_st {
+struct PBE2PARAM_st {
X509_ALGOR *keyfunc;
X509_ALGOR *encryption;
-} PBE2PARAM;
+} /* PBE2PARAM */;
-typedef struct PBKDF2PARAM_st {
+struct PBKDF2PARAM_st {
ASN1_TYPE *salt; /* Usually OCTET STRING but could be anything */
ASN1_INTEGER *iter;
ASN1_INTEGER *keylength;
X509_ALGOR *prf;
-} PBKDF2PARAM;
+} /* PBKDF2PARAM */;
/* PKCS#8 private key info structure */
@@ -619,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,
@@ -788,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);
@@ -896,6 +893,7 @@ OPENSSL_EXPORT int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name);
OPENSSL_EXPORT int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm);
OPENSSL_EXPORT int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm);
OPENSSL_EXPORT int X509_CRL_sort(X509_CRL *crl);
+OPENSSL_EXPORT void X509_CRL_up_ref(X509_CRL *crl);
OPENSSL_EXPORT int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial);
OPENSSL_EXPORT int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm);
@@ -1217,65 +1215,6 @@ OPENSSL_EXPORT int PKCS7_get_PEM_CRLs(STACK_OF(X509_CRL) *out_crls,
}
#endif
-#define X509_F_ASN1_digest 100
-#define X509_F_ASN1_item_sign_ctx 101
-#define X509_F_ASN1_item_verify 102
-#define X509_F_NETSCAPE_SPKI_b64_decode 103
-#define X509_F_NETSCAPE_SPKI_b64_encode 104
-#define X509_F_PKCS7_get_certificates 105
-#define X509_F_X509_ATTRIBUTE_create_by_NID 106
-#define X509_F_X509_ATTRIBUTE_create_by_OBJ 107
-#define X509_F_X509_ATTRIBUTE_create_by_txt 108
-#define X509_F_X509_ATTRIBUTE_get0_data 109
-#define X509_F_X509_ATTRIBUTE_set1_data 110
-#define X509_F_X509_CRL_add0_revoked 111
-#define X509_F_X509_CRL_diff 112
-#define X509_F_X509_CRL_print_fp 113
-#define X509_F_X509_EXTENSION_create_by_NID 114
-#define X509_F_X509_EXTENSION_create_by_OBJ 115
-#define X509_F_X509_INFO_new 116
-#define X509_F_X509_NAME_ENTRY_create_by_NID 117
-#define X509_F_X509_NAME_ENTRY_create_by_txt 118
-#define X509_F_X509_NAME_ENTRY_set_object 119
-#define X509_F_X509_NAME_add_entry 120
-#define X509_F_X509_NAME_oneline 121
-#define X509_F_X509_NAME_print 122
-#define X509_F_X509_PKEY_new 123
-#define X509_F_X509_PUBKEY_get 124
-#define X509_F_X509_PUBKEY_set 125
-#define X509_F_X509_REQ_check_private_key 126
-#define X509_F_X509_REQ_to_X509 127
-#define X509_F_X509_STORE_CTX_get1_issuer 128
-#define X509_F_X509_STORE_CTX_init 129
-#define X509_F_X509_STORE_CTX_new 130
-#define X509_F_X509_STORE_CTX_purpose_inherit 131
-#define X509_F_X509_STORE_add_cert 132
-#define X509_F_X509_STORE_add_crl 133
-#define X509_F_X509_TRUST_add 134
-#define X509_F_X509_TRUST_set 135
-#define X509_F_X509_check_private_key 136
-#define X509_F_X509_get_pubkey_parameters 137
-#define X509_F_X509_load_cert_crl_file 138
-#define X509_F_X509_load_cert_file 139
-#define X509_F_X509_load_crl_file 140
-#define X509_F_X509_print_ex_fp 141
-#define X509_F_X509_to_X509_REQ 142
-#define X509_F_X509_verify_cert 143
-#define X509_F_X509at_add1_attr 144
-#define X509_F_X509v3_add_ext 145
-#define X509_F_add_cert_dir 146
-#define X509_F_by_file_ctrl 147
-#define X509_F_check_policy 148
-#define X509_F_dir_ctrl 149
-#define X509_F_get_cert_by_subject 150
-#define X509_F_i2d_DSA_PUBKEY 151
-#define X509_F_i2d_EC_PUBKEY 152
-#define X509_F_i2d_RSA_PUBKEY 153
-#define X509_F_x509_name_encode 154
-#define X509_F_x509_name_ex_d2i 155
-#define X509_F_x509_name_ex_new 156
-#define X509_F_pkcs7_parse_header 157
-#define X509_F_PKCS7_get_CRLs 158
#define X509_R_AKID_MISMATCH 100
#define X509_R_BAD_PKCS7_VERSION 101
#define X509_R_BAD_X509_FILETYPE 102
diff --git a/src/include/openssl/x509_vfy.h b/src/include/openssl/x509_vfy.h
index 146e047..b39ef49 100644
--- a/src/include/openssl/x509_vfy.h
+++ b/src/include/openssl/x509_vfy.h
@@ -1,4 +1,3 @@
-/* crypto/x509/x509_vfy.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -499,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/include/openssl/x509v3.h b/src/include/openssl/x509v3.h
index 5caa5c1..b7b8ba7 100644
--- a/src/include/openssl/x509v3.h
+++ b/src/include/openssl/x509v3.h
@@ -731,63 +731,6 @@ void ERR_load_X509V3_strings(void);
#ifdef __cplusplus
}
#endif
-#define X509V3_F_SXNET_add_id_INTEGER 100
-#define X509V3_F_SXNET_add_id_asc 101
-#define X509V3_F_SXNET_add_id_ulong 102
-#define X509V3_F_SXNET_get_id_asc 103
-#define X509V3_F_SXNET_get_id_ulong 104
-#define X509V3_F_X509V3_EXT_add 105
-#define X509V3_F_X509V3_EXT_add_alias 106
-#define X509V3_F_X509V3_EXT_free 107
-#define X509V3_F_X509V3_EXT_i2d 108
-#define X509V3_F_X509V3_EXT_nconf 109
-#define X509V3_F_X509V3_add1_i2d 110
-#define X509V3_F_X509V3_add_value 111
-#define X509V3_F_X509V3_get_section 112
-#define X509V3_F_X509V3_get_string 113
-#define X509V3_F_X509V3_get_value_bool 114
-#define X509V3_F_X509V3_parse_list 115
-#define X509V3_F_X509_PURPOSE_add 116
-#define X509V3_F_X509_PURPOSE_set 117
-#define X509V3_F_a2i_GENERAL_NAME 118
-#define X509V3_F_copy_email 119
-#define X509V3_F_copy_issuer 120
-#define X509V3_F_do_dirname 121
-#define X509V3_F_do_ext_i2d 122
-#define X509V3_F_do_ext_nconf 123
-#define X509V3_F_gnames_from_sectname 124
-#define X509V3_F_hex_to_string 125
-#define X509V3_F_i2s_ASN1_ENUMERATED 126
-#define X509V3_F_i2s_ASN1_IA5STRING 127
-#define X509V3_F_i2s_ASN1_INTEGER 128
-#define X509V3_F_i2v_AUTHORITY_INFO_ACCESS 129
-#define X509V3_F_notice_section 130
-#define X509V3_F_nref_nos 131
-#define X509V3_F_policy_section 132
-#define X509V3_F_process_pci_value 133
-#define X509V3_F_r2i_certpol 134
-#define X509V3_F_r2i_pci 135
-#define X509V3_F_s2i_ASN1_IA5STRING 136
-#define X509V3_F_s2i_ASN1_INTEGER 137
-#define X509V3_F_s2i_ASN1_OCTET_STRING 138
-#define X509V3_F_s2i_skey_id 139
-#define X509V3_F_set_dist_point_name 140
-#define X509V3_F_string_to_hex 141
-#define X509V3_F_v2i_ASN1_BIT_STRING 142
-#define X509V3_F_v2i_AUTHORITY_INFO_ACCESS 143
-#define X509V3_F_v2i_AUTHORITY_KEYID 144
-#define X509V3_F_v2i_BASIC_CONSTRAINTS 145
-#define X509V3_F_v2i_EXTENDED_KEY_USAGE 146
-#define X509V3_F_v2i_GENERAL_NAMES 147
-#define X509V3_F_v2i_GENERAL_NAME_ex 148
-#define X509V3_F_v2i_NAME_CONSTRAINTS 149
-#define X509V3_F_v2i_POLICY_CONSTRAINTS 150
-#define X509V3_F_v2i_POLICY_MAPPINGS 151
-#define X509V3_F_v2i_crld 152
-#define X509V3_F_v2i_idp 153
-#define X509V3_F_v2i_issuer_alt 154
-#define X509V3_F_v2i_subject_alt 155
-#define X509V3_F_v3_generic_extension 156
#define X509V3_R_BAD_IP_ADDRESS 100
#define X509V3_R_BAD_OBJECT 101
#define X509V3_R_BN_DEC2BN_ERROR 102
diff --git a/src/ssl/CMakeLists.txt b/src/ssl/CMakeLists.txt
index cf5a29d..c82cb9b 100644
--- a/src/ssl/CMakeLists.txt
+++ b/src/ssl/CMakeLists.txt
@@ -1,10 +1,11 @@
-include_directories(. .. ../include)
+include_directories(../include)
add_subdirectory(pqueue)
add_library(
ssl
+ custom_extensions.c
d1_both.c
d1_clnt.c
d1_lib.c
@@ -12,6 +13,7 @@ add_library(
d1_pkt.c
d1_srtp.c
d1_srvr.c
+ dtls_record.c
s3_both.c
s3_clnt.c
s3_enc.c
@@ -20,22 +22,25 @@ add_library(
s3_pkt.c
s3_srvr.c
ssl_aead_ctx.c
- ssl_algs.c
ssl_asn1.c
+ ssl_buffer.c
ssl_cert.c
ssl_cipher.c
+ ssl_ecdh.c
+ ssl_file.c
ssl_lib.c
ssl_rsa.c
- ssl_sess.c
+ ssl_session.c
ssl_stat.c
- ssl_txt.c
t1_enc.c
t1_lib.c
- t1_reneg.c
+ tls_record.c
$<TARGET_OBJECTS:pqueue>
)
+target_link_libraries(ssl crypto)
+
add_executable(
ssl_test
@@ -45,3 +50,4 @@ add_executable(
)
target_link_libraries(ssl_test ssl crypto)
+add_dependencies(all_tests ssl_test)
diff --git a/src/ssl/custom_extensions.c b/src/ssl/custom_extensions.c
new file mode 100644
index 0000000..c94543d
--- /dev/null
+++ b/src/ssl/custom_extensions.c
@@ -0,0 +1,257 @@
+/* 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. */
+
+#include <openssl/ssl.h>
+
+#include <assert.h>
+#include <string.h>
+
+#include <openssl/bytestring.h>
+#include <openssl/err.h>
+#include <openssl/mem.h>
+#include <openssl/stack.h>
+
+#include "internal.h"
+
+
+void SSL_CUSTOM_EXTENSION_free(SSL_CUSTOM_EXTENSION *custom_extension) {
+ OPENSSL_free(custom_extension);
+}
+
+static const SSL_CUSTOM_EXTENSION *custom_ext_find(
+ STACK_OF(SSL_CUSTOM_EXTENSION) *stack,
+ unsigned *out_index, uint16_t value) {
+ size_t i;
+ for (i = 0; i < sk_SSL_CUSTOM_EXTENSION_num(stack); i++) {
+ const SSL_CUSTOM_EXTENSION *ext = sk_SSL_CUSTOM_EXTENSION_value(stack, i);
+ if (ext->value == value) {
+ if (out_index != NULL) {
+ *out_index = i;
+ }
+ return ext;
+ }
+ }
+
+ return NULL;
+}
+
+/* default_add_callback is used as the |add_callback| when the user doesn't
+ * provide one. For servers, it does nothing while, for clients, it causes an
+ * empty extension to be included. */
+static int default_add_callback(SSL *ssl, unsigned extension_value,
+ const uint8_t **out, size_t *out_len,
+ int *out_alert_value, void *add_arg) {
+ if (ssl->server) {
+ return 0;
+ }
+ *out_len = 0;
+ return 1;
+}
+
+static int custom_ext_add_hello(SSL *ssl, CBB *extensions) {
+ STACK_OF(SSL_CUSTOM_EXTENSION) *stack = ssl->ctx->client_custom_extensions;
+ if (ssl->server) {
+ stack = ssl->ctx->server_custom_extensions;
+ }
+
+ if (stack == NULL) {
+ return 1;
+ }
+
+ size_t i;
+ for (i = 0; i < sk_SSL_CUSTOM_EXTENSION_num(stack); i++) {
+ const SSL_CUSTOM_EXTENSION *ext = sk_SSL_CUSTOM_EXTENSION_value(stack, i);
+
+ if (ssl->server &&
+ !(ssl->s3->tmp.custom_extensions.received & (1u << i))) {
+ /* Servers cannot echo extensions that the client didn't send. */
+ continue;
+ }
+
+ const uint8_t *contents;
+ size_t contents_len;
+ int alert = SSL_AD_DECODE_ERROR;
+ CBB contents_cbb;
+
+ switch (ext->add_callback(ssl, ext->value, &contents, &contents_len, &alert,
+ ext->add_arg)) {
+ case 1:
+ if (!CBB_add_u16(extensions, ext->value) ||
+ !CBB_add_u16_length_prefixed(extensions, &contents_cbb) ||
+ !CBB_add_bytes(&contents_cbb, contents, contents_len) ||
+ !CBB_flush(extensions)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ ERR_add_error_dataf("extension: %u", (unsigned) ext->value);
+ if (ext->free_callback && 0 < contents_len) {
+ ext->free_callback(ssl, ext->value, contents, ext->add_arg);
+ }
+ return 0;
+ }
+
+ if (ext->free_callback && 0 < contents_len) {
+ ext->free_callback(ssl, ext->value, contents, ext->add_arg);
+ }
+
+ if (!ssl->server) {
+ assert((ssl->s3->tmp.custom_extensions.sent & (1u << i)) == 0);
+ ssl->s3->tmp.custom_extensions.sent |= (1u << i);
+ }
+ break;
+
+ case 0:
+ break;
+
+ default:
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CUSTOM_EXTENSION_ERROR);
+ ERR_add_error_dataf("extension: %u", (unsigned) ext->value);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+int custom_ext_add_clienthello(SSL *ssl, CBB *extensions) {
+ return custom_ext_add_hello(ssl, extensions);
+}
+
+int custom_ext_parse_serverhello(SSL *ssl, int *out_alert, uint16_t value,
+ const CBS *extension) {
+ unsigned index;
+ const SSL_CUSTOM_EXTENSION *ext =
+ custom_ext_find(ssl->ctx->client_custom_extensions, &index, value);
+
+ if (/* Unknown extensions are not allowed in a ServerHello. */
+ ext == NULL ||
+ /* Also, if we didn't send the extension, that's also unacceptable. */
+ !(ssl->s3->tmp.custom_extensions.sent & (1u << index))) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
+ ERR_add_error_dataf("extension: %u", (unsigned)value);
+ *out_alert = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+
+ if (ext->parse_callback != NULL &&
+ !ext->parse_callback(ssl, value, CBS_data(extension), CBS_len(extension),
+ out_alert, ext->parse_arg)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CUSTOM_EXTENSION_ERROR);
+ ERR_add_error_dataf("extension: %u", (unsigned)ext->value);
+ return 0;
+ }
+
+ return 1;
+}
+
+int custom_ext_parse_clienthello(SSL *ssl, int *out_alert, uint16_t value,
+ const CBS *extension) {
+ unsigned index;
+ const SSL_CUSTOM_EXTENSION *ext =
+ custom_ext_find(ssl->ctx->server_custom_extensions, &index, value);
+
+ if (ext == NULL) {
+ return 1;
+ }
+
+ assert((ssl->s3->tmp.custom_extensions.received & (1u << index)) == 0);
+ ssl->s3->tmp.custom_extensions.received |= (1u << index);
+
+ if (ext->parse_callback &&
+ !ext->parse_callback(ssl, value, CBS_data(extension), CBS_len(extension),
+ out_alert, ext->parse_arg)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CUSTOM_EXTENSION_ERROR);
+ ERR_add_error_dataf("extension: %u", (unsigned)ext->value);
+ return 0;
+ }
+
+ return 1;
+}
+
+int custom_ext_add_serverhello(SSL *ssl, CBB *extensions) {
+ return custom_ext_add_hello(ssl, extensions);
+}
+
+/* MAX_NUM_CUSTOM_EXTENSIONS is the maximum number of custom extensions that
+ * can be set on an |SSL_CTX|. It's determined by the size of the bitset used
+ * to track when an extension has been sent. */
+#define MAX_NUM_CUSTOM_EXTENSIONS \
+ (sizeof(((struct ssl3_state_st *)NULL)->tmp.custom_extensions.sent) * 8)
+
+static int custom_ext_append(STACK_OF(SSL_CUSTOM_EXTENSION) **stack,
+ unsigned extension_value,
+ SSL_custom_ext_add_cb add_cb,
+ SSL_custom_ext_free_cb free_cb, void *add_arg,
+ SSL_custom_ext_parse_cb parse_cb,
+ void *parse_arg) {
+ if (add_cb == NULL ||
+ 0xffff < extension_value ||
+ SSL_extension_supported(extension_value) ||
+ /* Specifying a free callback without an add callback is nonsensical
+ * and an error. */
+ (*stack != NULL &&
+ (MAX_NUM_CUSTOM_EXTENSIONS <= sk_SSL_CUSTOM_EXTENSION_num(*stack) ||
+ custom_ext_find(*stack, NULL, extension_value) != NULL))) {
+ return 0;
+ }
+
+ SSL_CUSTOM_EXTENSION *ext = OPENSSL_malloc(sizeof(SSL_CUSTOM_EXTENSION));
+ if (ext == NULL) {
+ return 0;
+ }
+ ext->add_callback = add_cb;
+ ext->add_arg = add_arg;
+ ext->free_callback = free_cb;
+ ext->parse_callback = parse_cb;
+ ext->parse_arg = parse_arg;
+ ext->value = extension_value;
+
+ if (*stack == NULL) {
+ *stack = sk_SSL_CUSTOM_EXTENSION_new_null();
+ if (*stack == NULL) {
+ SSL_CUSTOM_EXTENSION_free(ext);
+ return 0;
+ }
+ }
+
+ if (!sk_SSL_CUSTOM_EXTENSION_push(*stack, ext)) {
+ SSL_CUSTOM_EXTENSION_free(ext);
+ if (sk_SSL_CUSTOM_EXTENSION_num(*stack) == 0) {
+ sk_SSL_CUSTOM_EXTENSION_free(*stack);
+ *stack = NULL;
+ }
+ return 0;
+ }
+
+ return 1;
+}
+
+int SSL_CTX_add_client_custom_ext(SSL_CTX *ctx, unsigned extension_value,
+ SSL_custom_ext_add_cb add_cb,
+ SSL_custom_ext_free_cb free_cb, void *add_arg,
+ SSL_custom_ext_parse_cb parse_cb,
+ void *parse_arg) {
+ return custom_ext_append(&ctx->client_custom_extensions, extension_value,
+ add_cb ? add_cb : default_add_callback, free_cb,
+ add_arg, parse_cb, parse_arg);
+}
+
+int SSL_CTX_add_server_custom_ext(SSL_CTX *ctx, unsigned extension_value,
+ SSL_custom_ext_add_cb add_cb,
+ SSL_custom_ext_free_cb free_cb, void *add_arg,
+ SSL_custom_ext_parse_cb parse_cb,
+ void *parse_arg) {
+ return custom_ext_append(&ctx->server_custom_extensions, extension_value,
+ add_cb ? add_cb : default_add_callback, free_cb,
+ add_arg, parse_cb, parse_arg);
+}
diff --git a/src/ssl/d1_both.c b/src/ssl/d1_both.c
index ac35a66..ee4cbc9 100644
--- a/src/ssl/d1_both.c
+++ b/src/ssl/d1_both.c
@@ -111,6 +111,8 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <limits.h>
#include <stdio.h>
@@ -143,56 +145,44 @@ static const unsigned int kDefaultMTU = 1500 - 28;
* current one to buffer. */
static const unsigned int kHandshakeBufferSize = 10;
-static void dtls1_fix_message_header(SSL *s, unsigned long frag_off,
- unsigned long frag_len);
-static unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p);
-
-static hm_fragment *dtls1_hm_fragment_new(unsigned long frag_len,
- int reassembly) {
- hm_fragment *frag = NULL;
- uint8_t *buf = NULL;
- uint8_t *bitmask = NULL;
-
- frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment));
+static hm_fragment *dtls1_hm_fragment_new(size_t frag_len, int reassembly) {
+ hm_fragment *frag = OPENSSL_malloc(sizeof(hm_fragment));
if (frag == NULL) {
- OPENSSL_PUT_ERROR(SSL, dtls1_hm_fragment_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return NULL;
}
+ memset(frag, 0, sizeof(hm_fragment));
- if (frag_len) {
- buf = (uint8_t *)OPENSSL_malloc(frag_len);
- if (buf == NULL) {
- OPENSSL_PUT_ERROR(SSL, dtls1_hm_fragment_new, ERR_R_MALLOC_FAILURE);
- OPENSSL_free(frag);
- return NULL;
+ /* If the handshake message is empty, |frag->fragment| and |frag->reassembly|
+ * are NULL. */
+ if (frag_len > 0) {
+ frag->fragment = OPENSSL_malloc(frag_len);
+ if (frag->fragment == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
}
- }
- /* zero length fragment gets zero frag->fragment */
- frag->fragment = buf;
-
- /* Initialize reassembly bitmask if necessary */
- if (reassembly && frag_len > 0) {
- if (frag_len + 7 < frag_len) {
- OPENSSL_PUT_ERROR(SSL, dtls1_hm_fragment_new, ERR_R_OVERFLOW);
- return NULL;
- }
- size_t bitmask_len = (frag_len + 7) / 8;
- bitmask = (uint8_t *)OPENSSL_malloc(bitmask_len);
- if (bitmask == NULL) {
- OPENSSL_PUT_ERROR(SSL, dtls1_hm_fragment_new, ERR_R_MALLOC_FAILURE);
- if (buf != NULL) {
- OPENSSL_free(buf);
+ if (reassembly) {
+ /* Initialize reassembly bitmask. */
+ if (frag_len + 7 < frag_len) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ goto err;
}
- OPENSSL_free(frag);
- return NULL;
+ size_t bitmask_len = (frag_len + 7) / 8;
+ frag->reassembly = OPENSSL_malloc(bitmask_len);
+ if (frag->reassembly == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ memset(frag->reassembly, 0, bitmask_len);
}
- memset(bitmask, 0, bitmask_len);
}
- frag->reassembly = bitmask;
-
return frag;
+
+err:
+ dtls1_hm_fragment_free(frag);
+ return NULL;
}
void dtls1_hm_fragment_free(hm_fragment *frag) {
@@ -257,142 +247,181 @@ static void dtls1_hm_fragment_mark(hm_fragment *frag, size_t start,
frag->reassembly = NULL;
}
-/* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or
- * SSL3_RT_CHANGE_CIPHER_SPEC) */
-int dtls1_do_write(SSL *s, int type, enum dtls1_use_epoch_t use_epoch) {
- int ret;
- int curr_mtu;
- unsigned int len, frag_off;
-
- /* AHA! Figure out the MTU, and stick to the right size */
- if (s->d1->mtu < dtls1_min_mtu() &&
- !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) {
- long mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
+static void dtls1_update_mtu(SSL *ssl) {
+ /* TODO(davidben): What is this code doing and do we need it? */
+ if (ssl->d1->mtu < dtls1_min_mtu() &&
+ !(SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) {
+ long mtu = BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
if (mtu >= 0 && mtu <= (1 << 30) && (unsigned)mtu >= dtls1_min_mtu()) {
- s->d1->mtu = (unsigned)mtu;
+ ssl->d1->mtu = (unsigned)mtu;
} else {
- s->d1->mtu = kDefaultMTU;
- BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU, s->d1->mtu, NULL);
+ ssl->d1->mtu = kDefaultMTU;
+ BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_SET_MTU, ssl->d1->mtu, NULL);
}
}
- /* should have something reasonable now */
- assert(s->d1->mtu >= dtls1_min_mtu());
-
- if (s->init_off == 0 && type == SSL3_RT_HANDSHAKE) {
- assert(s->init_num ==
- (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH);
- }
-
- /* Determine the maximum overhead of the current cipher. */
- size_t max_overhead = SSL_AEAD_CTX_max_overhead(s->aead_write_ctx);
-
- frag_off = 0;
- while (s->init_num) {
- /* Account for data in the buffering BIO; multiple records may be packed
- * into a single packet during the handshake.
- *
- * TODO(davidben): This is buggy; if the MTU is larger than the buffer size,
- * the large record will be split across two packets. Moreover, in that
- * case, the |dtls1_write_bytes| call may not return synchronously. This
- * will break on retry as the |s->init_off| and |s->init_num| adjustment
- * will run a second time. */
- curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) -
- DTLS1_RT_HEADER_LENGTH - max_overhead;
-
- if (curr_mtu <= DTLS1_HM_HEADER_LENGTH) {
- /* Flush the buffer and continue with a fresh packet.
- *
- * TODO(davidben): If |BIO_flush| is not synchronous and requires multiple
- * calls to |dtls1_do_write|, |frag_off| will be wrong. */
- ret = BIO_flush(SSL_get_wbio(s));
- if (ret <= 0) {
- return ret;
- }
- assert(BIO_wpending(SSL_get_wbio(s)) == 0);
- curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH - max_overhead;
+ /* The MTU should be above the minimum now. */
+ assert(ssl->d1->mtu >= dtls1_min_mtu());
+}
+
+/* dtls1_max_record_size returns the maximum record body length that may be
+ * written without exceeding the MTU. It accounts for any buffering installed on
+ * the write BIO. If no record may be written, it returns zero. */
+static size_t dtls1_max_record_size(SSL *ssl) {
+ size_t ret = ssl->d1->mtu;
+
+ size_t overhead = ssl_max_seal_overhead(ssl);
+ if (ret <= overhead) {
+ return 0;
+ }
+ ret -= overhead;
+
+ size_t pending = BIO_wpending(SSL_get_wbio(ssl));
+ if (ret <= pending) {
+ return 0;
+ }
+ ret -= pending;
+
+ return ret;
+}
+
+static int dtls1_write_change_cipher_spec(SSL *ssl,
+ enum dtls1_use_epoch_t use_epoch) {
+ dtls1_update_mtu(ssl);
+
+ /* During the handshake, wbio is buffered to pack messages together. Flush the
+ * buffer if the ChangeCipherSpec would not fit in a packet. */
+ if (dtls1_max_record_size(ssl) == 0) {
+ ssl->rwstate = SSL_WRITING;
+ int ret = BIO_flush(SSL_get_wbio(ssl));
+ if (ret <= 0) {
+ return ret;
}
+ ssl->rwstate = SSL_NOTHING;
+ }
- /* XDTLS: this function is too long. split out the CCS part */
- if (type == SSL3_RT_HANDSHAKE) {
- /* If this isn't the first fragment, reserve space to prepend a new
- * fragment header. This will override the body of a previous fragment. */
- if (s->init_off != 0) {
- assert(s->init_off > DTLS1_HM_HEADER_LENGTH);
- s->init_off -= DTLS1_HM_HEADER_LENGTH;
- s->init_num += DTLS1_HM_HEADER_LENGTH;
- }
+ 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);
+ if (ret <= 0) {
+ return ret;
+ }
- if (curr_mtu <= DTLS1_HM_HEADER_LENGTH) {
- /* To make forward progress, the MTU must, at minimum, fit the handshake
- * header and one byte of handshake body. */
- OPENSSL_PUT_ERROR(SSL, dtls1_do_write, SSL_R_MTU_TOO_SMALL);
- return -1;
- }
+ if (ssl->msg_callback != NULL) {
+ ssl->msg_callback(1 /* write */, ssl->version, SSL3_RT_CHANGE_CIPHER_SPEC,
+ kChangeCipherSpec, sizeof(kChangeCipherSpec), ssl,
+ ssl->msg_callback_arg);
+ }
- if (s->init_num > curr_mtu) {
- len = curr_mtu;
- } else {
- len = s->init_num;
- }
- assert(len >= DTLS1_HM_HEADER_LENGTH);
+ return 1;
+}
- dtls1_fix_message_header(s, frag_off, len - DTLS1_HM_HEADER_LENGTH);
- dtls1_write_message_header(
- s, (uint8_t *)&s->init_buf->data[s->init_off]);
- } else {
- assert(type == SSL3_RT_CHANGE_CIPHER_SPEC);
- /* ChangeCipherSpec cannot be fragmented. */
- if (s->init_num > curr_mtu) {
- OPENSSL_PUT_ERROR(SSL, dtls1_do_write, SSL_R_MTU_TOO_SMALL);
- return -1;
+int dtls1_do_handshake_write(SSL *ssl, enum dtls1_use_epoch_t use_epoch) {
+ dtls1_update_mtu(ssl);
+
+ int ret = -1;
+ CBB cbb;
+ CBB_zero(&cbb);
+ /* Allocate a temporary buffer to hold the message fragments to avoid
+ * clobbering the message. */
+ uint8_t *buf = OPENSSL_malloc(ssl->d1->mtu);
+ if (buf == NULL) {
+ goto err;
+ }
+
+ /* Consume the message header. Fragments will have different headers
+ * prepended. */
+ if (ssl->init_off == 0) {
+ ssl->init_off += DTLS1_HM_HEADER_LENGTH;
+ ssl->init_num -= DTLS1_HM_HEADER_LENGTH;
+ }
+ assert(ssl->init_off >= DTLS1_HM_HEADER_LENGTH);
+
+ do {
+ /* During the handshake, wbio is buffered to pack messages together. Flush
+ * the buffer if there isn't enough room to make progress. */
+ if (dtls1_max_record_size(ssl) < DTLS1_HM_HEADER_LENGTH + 1) {
+ ssl->rwstate = SSL_WRITING;
+ int flush_ret = BIO_flush(SSL_get_wbio(ssl));
+ if (flush_ret <= 0) {
+ ret = flush_ret;
+ goto err;
}
- len = s->init_num;
+ ssl->rwstate = SSL_NOTHING;
+ assert(BIO_wpending(SSL_get_wbio(ssl)) == 0);
}
- ret = dtls1_write_bytes(s, type, &s->init_buf->data[s->init_off], len,
- use_epoch);
- if (ret < 0) {
- return -1;
+ size_t todo = dtls1_max_record_size(ssl);
+ if (todo < DTLS1_HM_HEADER_LENGTH + 1) {
+ /* To make forward progress, the MTU must, at minimum, fit the handshake
+ * header and one byte of handshake body. */
+ OPENSSL_PUT_ERROR(SSL, SSL_R_MTU_TOO_SMALL);
+ goto err;
}
+ todo -= DTLS1_HM_HEADER_LENGTH;
- /* bad if this assert fails, only part of the handshake message got sent.
- * But why would this happen? */
- assert(len == (unsigned int)ret);
-
- if (ret == 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 (todo > (size_t)ssl->init_num) {
+ todo = ssl->init_num;
+ }
+ if (todo >= (1u << 24)) {
+ todo = (1u << 24) - 1;
+ }
- s->init_off = 0; /* done writing this message */
- s->init_num = 0;
+ size_t len;
+ if (!CBB_init_fixed(&cbb, buf, ssl->d1->mtu) ||
+ !CBB_add_u8(&cbb, ssl->d1->w_msg_hdr.type) ||
+ !CBB_add_u24(&cbb, ssl->d1->w_msg_hdr.msg_len) ||
+ !CBB_add_u16(&cbb, ssl->d1->w_msg_hdr.seq) ||
+ !CBB_add_u24(&cbb, ssl->init_off - DTLS1_HM_HEADER_LENGTH) ||
+ !CBB_add_u24(&cbb, todo) ||
+ !CBB_add_bytes(
+ &cbb, (const uint8_t *)ssl->init_buf->data + ssl->init_off, todo) ||
+ !CBB_finish(&cbb, NULL, &len)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
- return 1;
+ int write_ret = dtls1_write_bytes(ssl, SSL3_RT_HANDSHAKE, buf, len,
+ use_epoch);
+ if (write_ret <= 0) {
+ ret = write_ret;
+ goto err;
}
- s->init_off += ret;
- s->init_num -= ret;
- frag_off += (ret -= DTLS1_HM_HEADER_LENGTH);
+ ssl->init_off += todo;
+ ssl->init_num -= todo;
+ } while (ssl->init_num > 0);
+
+ if (ssl->msg_callback != NULL) {
+ ssl->msg_callback(
+ 1 /* write */, ssl->version, SSL3_RT_HANDSHAKE, ssl->init_buf->data,
+ (size_t)(ssl->init_off + ssl->init_num), ssl, ssl->msg_callback_arg);
}
- return 0;
+ ssl->init_off = 0;
+ ssl->init_num = 0;
+
+ ret = 1;
+
+err:
+ CBB_cleanup(&cbb);
+ OPENSSL_free(buf);
+ return ret;
}
/* 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
@@ -400,12 +429,12 @@ 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);
- if (ret != chunk) {
+ int ret = dtls1_read_bytes(ssl, SSL3_RT_HANDSHAKE, discard, chunk, 0);
+ if (ret != (int) chunk) {
return 0;
}
frag_len -= chunk;
@@ -418,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) {
@@ -439,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);
@@ -450,9 +479,8 @@ static hm_fragment *dtls1_get_buffered_message(
frag->msg_header.msg_len != msg_hdr->msg_len) {
/* The new fragment must be compatible with the previous fragments from
* this message. */
- OPENSSL_PUT_ERROR(SSL, dtls1_get_buffered_message,
- SSL_R_FRAGMENT_MISMATCH);
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_FRAGMENT_MISMATCH);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return NULL;
}
}
@@ -460,33 +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) {
- /* Read handshake message header.
- *
- * TODO(davidben): ssl_read_bytes allows splitting the fragment header and
- * body across two records. Change this interface to consume the fragment in
- * one pass. */
+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, dtls1_process_fragment, SSL_R_UNEXPECTED_MESSAGE);
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
return -1;
}
@@ -494,29 +518,31 @@ static int dtls1_process_fragment(SSL *s) {
struct hm_header_st msg_hdr;
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 |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)) {
- OPENSSL_PUT_ERROR(SSL, dtls1_process_fragment,
- SSL_R_EXCESSIVE_MESSAGE_SIZE);
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ 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(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;
}
@@ -524,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;
@@ -532,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 != frag_len) {
- OPENSSL_PUT_ERROR(SSL, dtls1_process_fragment, SSL_R_UNEXPECTED_MESSAGE);
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ if (ret != (int) frag_len) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_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);
@@ -547,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;
@@ -555,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, dtls1_get_message, SSL_R_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;
@@ -582,29 +608,26 @@ 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) {
- OPENSSL_PUT_ERROR(SSL, dtls1_get_message, SSL_R_EXCESSIVE_MESSAGE_SIZE);
- goto err;
- }
-
- CBB 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)) {
- OPENSSL_PUT_ERROR(SSL, dtls1_get_message, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE);
goto err;
}
/* Reconstruct the assembled message. */
size_t len;
- if (!CBB_add_u8(&cbb, frag->msg_header.type) ||
+ CBB cbb;
+ CBB_zero(&cbb);
+ 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) ||
!CBB_add_u24(&cbb, 0 /* frag_off */) ||
@@ -612,43 +635,43 @@ long dtls1_get_message(SSL *s, int st1, int stn, int msg_type, long max,
!CBB_add_bytes(&cbb, frag->fragment, frag->msg_header.msg_len) ||
!CBB_finish(&cbb, NULL, &len)) {
CBB_cleanup(&cbb);
- OPENSSL_PUT_ERROR(SSL, dtls1_get_message, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
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, dtls1_get_message, SSL_R_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);
@@ -656,59 +679,30 @@ err:
return -1;
}
-/* 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 dtls1_send_change_cipher_spec(SSL *s, int a, int b) {
- uint8_t *p;
-
- if (s->state == a) {
- p = (uint8_t *)s->init_buf->data;
- *p++ = SSL3_MT_CCS;
- s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
- s->init_num = DTLS1_CCS_HEADER_LENGTH;
-
- s->init_off = 0;
-
- dtls1_set_message_header(s, SSL3_MT_CCS, 0, s->d1->handshake_write_seq, 0,
- 0);
-
- /* buffer the message to handle re-xmits */
- dtls1_buffer_message(s, 1);
-
- s->state = b;
- }
-
- /* SSL3_ST_CW_CHANGE_B */
- return dtls1_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC, dtls1_use_current_epoch);
-}
-
-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);
}
-int dtls1_get_queue_priority(unsigned short seq, int is_ccs) {
+static uint16_t dtls1_get_queue_priority(uint16_t seq, int is_ccs) {
+ assert(seq * 2 >= seq);
+
/* The index of the retransmission queue actually is the message sequence
* number, since the queue only contains messages of a single handshake.
* However, the ChangeCipherSpec has no message sequence number and so using
@@ -720,54 +714,47 @@ int dtls1_get_queue_priority(unsigned short seq, int is_ccs) {
return seq * 2 - is_ccs;
}
-static int dtls1_retransmit_message(SSL *s, hm_fragment *frag) {
- int ret;
- /* XDTLS: for now assuming that read/writes are blocking */
- unsigned long header_length;
-
- /* assert(s->init_num == 0);
- assert(s->init_off == 0); */
-
- if (frag->msg_header.is_ccs) {
- header_length = DTLS1_CCS_HEADER_LENGTH;
- } else {
- header_length = DTLS1_HM_HEADER_LENGTH;
- }
-
- memcpy(s->init_buf->data, frag->fragment,
- frag->msg_header.msg_len + header_length);
- s->init_num = frag->msg_header.msg_len + header_length;
-
- dtls1_set_message_header(s, frag->msg_header.type,
- frag->msg_header.msg_len, frag->msg_header.seq,
- 0, frag->msg_header.frag_len);
-
+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;
}
- ret = dtls1_do_write(s, frag->msg_header.is_ccs ? SSL3_RT_CHANGE_CIPHER_SPEC
- : SSL3_RT_HANDSHAKE,
- use_epoch);
+ /* TODO(davidben): This cannot handle non-blocking writes. */
+ int ret;
+ if (frag->msg_header.is_ccs) {
+ ret = dtls1_write_change_cipher_spec(ssl, use_epoch);
+ } else {
+ /* Restore the message body.
+ * TODO(davidben): Make this less stateful. */
+ memcpy(ssl->init_buf->data, frag->fragment,
+ frag->msg_header.msg_len + DTLS1_HM_HEADER_LENGTH);
+ ssl->init_num = frag->msg_header.msg_len + DTLS1_HM_HEADER_LENGTH;
- (void)BIO_flush(SSL_get_wbio(s));
+ 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(ssl, use_epoch);
+ }
+
+ /* TODO(davidben): Check return value? */
+ (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;
}
}
@@ -775,71 +762,101 @@ int dtls1_retransmit_buffered_messages(SSL *s) {
return 1;
}
-int dtls1_buffer_message(SSL *s, int is_ccs) {
- pitem *item;
- hm_fragment *frag;
+/* dtls1_buffer_change_cipher_spec adds a ChangeCipherSpec to the current
+ * handshake flight, ordered just before the handshake message numbered
+ * |seq|. */
+static int dtls1_buffer_change_cipher_spec(SSL *ssl, uint16_t seq) {
+ hm_fragment *frag = dtls1_hm_fragment_new(0 /* frag_len */,
+ 0 /* no reassembly */);
+ if (frag == NULL) {
+ return 0;
+ }
+ frag->msg_header.is_ccs = 1;
+ frag->msg_header.epoch = ssl->d1->w_epoch;
+
+ uint16_t priority = dtls1_get_queue_priority(seq, 1 /* is_ccs */);
uint8_t seq64be[8];
+ memset(seq64be, 0, sizeof(seq64be));
+ seq64be[6] = (uint8_t)(priority >> 8);
+ seq64be[7] = (uint8_t)priority;
+ pitem *item = pitem_new(seq64be, frag);
+ if (item == NULL) {
+ dtls1_hm_fragment_free(frag);
+ return 0;
+ }
+
+ pqueue_insert(ssl->d1->sent_messages, item);
+ return 1;
+}
+
+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);
- 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);
- if (is_ccs) {
- assert(s->d1->w_msg_hdr.msg_len + DTLS1_CCS_HEADER_LENGTH ==
- (unsigned int)s->init_num);
- } else {
- 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.is_ccs = is_ccs;
- frag->msg_header.epoch = s->d1->w_epoch;
+ frag->msg_header.frag_len = ssl->d1->w_msg_hdr.msg_len;
+ frag->msg_header.is_ccs = 0;
+ frag->msg_header.epoch = ssl->d1->w_epoch;
+ uint16_t priority = dtls1_get_queue_priority(frag->msg_header.seq,
+ 0 /* handshake */);
+ uint8_t seq64be[8];
memset(seq64be, 0, sizeof(seq64be));
- seq64be[6] = (uint8_t)(
- dtls1_get_queue_priority(frag->msg_header.seq, frag->msg_header.is_ccs) >>
- 8);
- seq64be[7] = (uint8_t)(
- dtls1_get_queue_priority(frag->msg_header.seq, frag->msg_header.is_ccs));
+ seq64be[6] = (uint8_t)(priority >> 8);
+ seq64be[7] = (uint8_t)priority;
- item = pitem_new(seq64be, frag);
+ pitem *item = pitem_new(seq64be, frag);
if (item == NULL) {
dtls1_hm_fragment_free(frag);
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 *ssl, int a, int b) {
+ if (ssl->state == a) {
+ /* Buffer the message to handle retransmits. */
+ 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(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;
@@ -848,27 +865,6 @@ void dtls1_set_message_header(SSL *s, uint8_t mt, unsigned long len,
msg_hdr->frag_len = frag_len;
}
-static void dtls1_fix_message_header(SSL *s, unsigned long frag_off,
- unsigned long frag_len) {
- struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
-
- msg_hdr->frag_off = frag_off;
- msg_hdr->frag_len = frag_len;
-}
-
-static uint8_t *dtls1_write_message_header(SSL *s, uint8_t *p) {
- struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
-
- *p++ = msg_hdr->type;
- l2n3(msg_hdr->msg_len, p);
-
- s2n(msg_hdr->seq, p);
- l2n3(msg_hdr->frag_off, p);
- l2n3(msg_hdr->frag_len, p);
-
- return p;
-}
-
unsigned int dtls1_min_mtu(void) {
return kMinMTU;
}
diff --git a/src/ssl/d1_clnt.c b/src/ssl/d1_clnt.c
index 92fb8f6..ad5eb50 100644
--- a/src/ssl/d1_clnt.c
+++ b/src/ssl/d1_clnt.c
@@ -112,6 +112,8 @@
* [including the GNU Public Licence.]
*/
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <stdio.h>
#include <string.h>
@@ -128,397 +130,402 @@
#include "internal.h"
-static int dtls1_get_hello_verify(SSL *s);
-int dtls1_connect(SSL *s) {
+static int dtls1_get_hello_verify(SSL *ssl);
+
+int dtls1_connect(SSL *ssl) {
BUF_MEM *buf = NULL;
- void (*cb)(const SSL *ssl, int type, int val) = 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;
-
- /* every DTLS ClientHello resets Finished MAC */
- if (!ssl3_init_finished_mac(s)) {
- OPENSSL_PUT_ERROR(SSL, dtls1_connect, ERR_R_INTERNAL_ERROR);
- ret = -1;
- goto end;
- }
-
- 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_CR_KEY_EXCH_A;
+ 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_CR_KEY_EXCH_A:
- case SSL3_ST_CR_KEY_EXCH_B:
- ret = ssl3_get_server_key_exchange(s);
+ case SSL3_ST_VERIFY_SERVER_CERT:
+ ret = ssl3_verify_server_cert(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_CR_CERT_REQ_A;
- s->init_num = 0;
- /* at this point we check that we have the
- * required stuff from the server */
- if (!ssl3_check_cert_and_algorithm(s)) {
- ret = -1;
+ 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(ssl);
+ if (ret <= 0) {
goto end;
}
+ 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:
- dtls1_start_timer(s);
- ret = ssl3_send_cert_verify(s);
+ case SSL3_ST_CW_CERT_VRFY_C:
+ 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_CR_KEY_EXCH_A;
- 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:
- OPENSSL_PUT_ERROR(SSL, dtls1_connect, SSL_R_UNKNOWN_STATE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_STATE);
ret = -1;
goto end;
}
/* 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);
@@ -526,34 +533,34 @@ 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) ||
CBS_len(&hello_verify_request) != 0) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, dtls1_get_hello_verify, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
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 ef7a9c9..7f08b06 100644
--- a/src/ssl/d1_lib.c
+++ b/src/ssl/d1_lib.c
@@ -54,12 +54,18 @@
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
-#include <openssl/base.h>
+#include <openssl/ssl.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
+#include <openssl/err.h>
+#include <openssl/mem.h>
+#include <openssl/obj.h>
+
+#include "internal.h"
+
#if defined(OPENSSL_WINDOWS)
#include <sys/timeb.h>
#else
@@ -67,11 +73,6 @@
#include <sys/time.h>
#endif
-#include <openssl/err.h>
-#include <openssl/mem.h>
-#include <openssl/obj.h>
-
-#include "internal.h"
/* DTLS1_MTU_TIMEOUTS is the maximum number of timeouts to expire
* before starting to decrease the MTU. */
@@ -83,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);
@@ -103,72 +104,73 @@ 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) {
- /* DTLS does not support stream ciphers. */
- return cipher->algorithm_enc != SSL_RC4;
+ /* DTLS does not support stream ciphers. The NULL cipher is rejected because
+ * it's not needed. */
+ 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) {
@@ -211,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;
}
@@ -228,41 +230,41 @@ 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, dtls1_check_timeout_num, SSL_R_READ_TIMEOUT_EXPIRED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_READ_TIMEOUT_EXPIRED);
return -1;
}
@@ -305,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, 0);
+ dtls1_buffer_message(ssl);
/* Add the new message to the handshake hash. Serialize the message
* header as if it were a single fragment. */
@@ -328,10 +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_finish_mac(s, serialised_header, sizeof(serialised_header)) &&
- ssl3_finish_mac(s, message + DTLS1_HM_HEADER_LENGTH, len);
+ return ssl3_update_handshake_hash(ssl, serialised_header,
+ sizeof(serialised_header)) &&
+ ssl3_update_handshake_hash(ssl, message + DTLS1_HM_HEADER_LENGTH, len);
}
-int dtls1_handshake_write(SSL *s) {
- return dtls1_do_write(s, SSL3_RT_HANDSHAKE, 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 d90f75b..49a2595 100644
--- a/src/ssl/d1_meth.c
+++ b/src/ssl/d1_meth.c
@@ -1,4 +1,3 @@
-/* ssl/d1_meth.h */
/*
* DTLS implementation written by Nagendra Modadugu
* (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
@@ -55,6 +54,8 @@
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
+#include <openssl/ssl.h>
+
#include "internal.h"
@@ -66,11 +67,10 @@ 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,
- ssl3_ctrl,
- ssl3_ctx_ctrl,
dtls1_supports_cipher,
DTLS1_HM_HEADER_LENGTH,
dtls1_set_handshake_header,
diff --git a/src/ssl/d1_pkt.c b/src/ssl/d1_pkt.c
index 553499f..f2ade3a 100644
--- a/src/ssl/d1_pkt.c
+++ b/src/ssl/d1_pkt.c
@@ -109,6 +109,8 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <stdio.h>
#include <string.h>
@@ -122,352 +124,158 @@
#include "internal.h"
-/* mod 128 saturating subtract of two 64-bit values in big-endian order */
-static int satsub64be(const uint8_t *v1, const uint8_t *v2) {
- int ret, sat, brw, i;
-
- if (sizeof(long) == 8) {
- do {
- const union {
- long one;
- char little;
- } is_endian = {1};
- long l;
-
- if (is_endian.little) {
- break;
- }
- /* not reached on little-endians */
- /* following test is redundant, because input is
- * always aligned, but I take no chances... */
- if (((size_t)v1 | (size_t)v2) & 0x7) {
- break;
- }
-
- l = *((long *)v1);
- l -= *((long *)v2);
- if (l > 128) {
- return 128;
- } else if (l < -128) {
- return -128;
- } else {
- return (int)l;
- }
- } while (0);
- }
-
- ret = (int)v1[7] - (int)v2[7];
- sat = 0;
- brw = ret >> 8; /* brw is either 0 or -1 */
- if (ret & 0x80) {
- for (i = 6; i >= 0; i--) {
- brw += (int)v1[i] - (int)v2[i];
- sat |= ~brw;
- brw >>= 8;
- }
- } else {
- for (i = 6; i >= 0; i--) {
- brw += (int)v1[i] - (int)v2[i];
- sat |= brw;
- brw >>= 8;
- }
- }
- brw <<= 8; /* brw is either 0 or -256 */
-
- if (sat & 0xff) {
- return brw | 0x80;
- } else {
- return brw + (ret & 0xFF);
- }
-}
-
-static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap);
-static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap);
-static int dtls1_process_record(SSL *s);
-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);
-static int dtls1_process_record(SSL *s) {
- int al;
- SSL3_RECORD *rr = &s->s3->rrec;
-
- /* check is not needed I believe */
- if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
- al = SSL_AD_RECORD_OVERFLOW;
- OPENSSL_PUT_ERROR(SSL, dtls1_process_record,
- SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
- goto f_err;
- }
-
- /* |rr->data| points to |rr->length| bytes of ciphertext in |s->packet|. */
- rr->data = &s->packet[DTLS1_RT_HEADER_LENGTH];
-
- uint8_t seq[8];
- seq[0] = rr->epoch >> 8;
- seq[1] = rr->epoch & 0xff;
- memcpy(&seq[2], &rr->seq_num[2], 6);
-
- /* Decrypt the packet in-place. Note it is important that |SSL_AEAD_CTX_open|
- * not write beyond |rr->length|. There may be another record in the packet.
- *
- * TODO(davidben): This assumes |s->version| is the same as the record-layer
- * version which isn't always true, but it only differs with the NULL cipher
- * which ignores the parameter. */
- size_t plaintext_len;
- if (!SSL_AEAD_CTX_open(s->aead_read_ctx, rr->data, &plaintext_len, rr->length,
- rr->type, s->version, seq, rr->data, rr->length)) {
- /* Bad packets are silently dropped in DTLS. Clear the error queue of any
- * errors decryption may have added. */
- ERR_clear_error();
- rr->length = 0;
- s->packet_length = 0;
- goto err;
- }
-
- if (plaintext_len > SSL3_RT_MAX_PLAIN_LENGTH) {
- al = SSL_AD_RECORD_OVERFLOW;
- OPENSSL_PUT_ERROR(SSL, dtls1_process_record, SSL_R_DATA_LENGTH_TOO_LONG);
- goto f_err;
- }
- assert(plaintext_len < (1u << 16));
- rr->length = plaintext_len;
-
- rr->off = 0;
- /* So at this point the following is true
- * ssl->s3->rrec.type is the type of record
- * ssl->s3->rrec.length == number of bytes in record
- * ssl->s3->rrec.off == offset to first valid byte
- * ssl->s3->rrec.data == the first byte of the record body. */
-
- /* we have pulled in a full packet so zero things */
- s->packet_length = 0;
- return 1;
-
-f_err:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
-
-err:
- return 0;
-}
-
-/* Call this to get a new input record.
- * It will return <= 0 if more data is needed, normally due to an error
- * or non-blocking IO.
- * When it finishes, one packet has been decoded and can be found in
- * ssl->s3->rrec.type - is the type of record
- * ssl->s3->rrec.data, - data
- * ssl->s3->rrec.length, - number of bytes
- *
- * used only by dtls1_read_bytes */
-int dtls1_get_record(SSL *s) {
- uint8_t ssl_major, ssl_minor;
- int n;
- SSL3_RECORD *rr;
- uint8_t *p = NULL;
- uint16_t version;
-
- rr = &(s->s3->rrec);
-
- /* get something from the wire */
+/* dtls1_get_record reads a new input record. On success, it places it in
+ * |ssl->s3->rrec| and returns one. Otherwise it returns <= 0 on error or if
+ * more data is needed. */
+static int dtls1_get_record(SSL *ssl) {
again:
- /* check if we have the header */
- if ((s->rstate != SSL_ST_READ_BODY) ||
- (s->packet_length < DTLS1_RT_HEADER_LENGTH)) {
- n = ssl3_read_n(s, DTLS1_RT_HEADER_LENGTH, 0);
- /* read timeout is handled by dtls1_read_bytes */
- if (n <= 0) {
- return n; /* error or non-blocking */
- }
-
- /* this packet contained a partial record, dump it */
- if (s->packet_length != DTLS1_RT_HEADER_LENGTH) {
- s->packet_length = 0;
- goto again;
+ /* Read a new packet if there is no unconsumed one. */
+ if (ssl_read_buffer_len(ssl) == 0) {
+ int ret = ssl_read_buffer_extend_to(ssl, 0 /* unused */);
+ if (ret <= 0) {
+ return ret;
}
+ }
+ assert(ssl_read_buffer_len(ssl) > 0);
- s->rstate = SSL_ST_READ_BODY;
-
- p = s->packet;
+ /* Ensure the packet is large enough to decrypt in-place. */
+ if (ssl_read_buffer_len(ssl) < ssl_record_prefix_len(ssl)) {
+ ssl_read_buffer_clear(ssl);
+ goto again;
+ }
- if (s->msg_callback) {
- s->msg_callback(0, 0, SSL3_RT_HEADER, p, DTLS1_RT_HEADER_LENGTH, s,
- s->msg_callback_arg);
- }
+ uint8_t *out = ssl_read_buffer(ssl) + ssl_record_prefix_len(ssl);
+ size_t max_out = ssl_read_buffer_len(ssl) - ssl_record_prefix_len(ssl);
+ uint8_t type, alert;
+ size_t len, consumed;
+ switch (dtls_open_record(ssl, &type, out, &len, &consumed, &alert, max_out,
+ ssl_read_buffer(ssl), ssl_read_buffer_len(ssl))) {
+ case ssl_open_record_success:
+ ssl_read_buffer_consume(ssl, consumed);
- /* Pull apart the header into the DTLS1_RECORD */
- rr->type = *(p++);
- ssl_major = *(p++);
- ssl_minor = *(p++);
- version = (((uint16_t)ssl_major) << 8) | ssl_minor;
-
- /* sequence number is 64 bits, with top 2 bytes = epoch */
- n2s(p, rr->epoch);
-
- memcpy(&(s->s3->read_sequence[2]), p, 6);
- p += 6;
-
- n2s(p, rr->length);
-
- /* Lets check version */
- if (s->s3->have_version) {
- if (version != s->version) {
- /* The record's version doesn't match, so silently drop it.
- *
- * TODO(davidben): This doesn't work. The DTLS record layer is not
- * packet-based, so the remainder of the packet isn't dropped and we
- * get a framing error. It's also unclear what it means to silently
- * drop a record in a packet containing two records. */
- rr->length = 0;
- s->packet_length = 0;
- goto again;
+ if (len > 0xffff) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ return -1;
}
- }
- if ((version & 0xff00) != (s->version & 0xff00)) {
- /* wrong version, silently discard record */
- rr->length = 0;
- s->packet_length = 0;
- goto again;
- }
+ SSL3_RECORD *rr = &ssl->s3->rrec;
+ rr->type = type;
+ rr->length = (uint16_t)len;
+ rr->data = out;
+ return 1;
- if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
- /* record too long, silently discard it */
- rr->length = 0;
- s->packet_length = 0;
+ case ssl_open_record_discard:
+ ssl_read_buffer_consume(ssl, consumed);
goto again;
- }
-
- /* now s->rstate == SSL_ST_READ_BODY */
- }
- /* s->rstate == SSL_ST_READ_BODY, get and decode the data */
-
- if (rr->length > s->packet_length - DTLS1_RT_HEADER_LENGTH) {
- /* now s->packet_length == DTLS1_RT_HEADER_LENGTH */
- n = ssl3_read_n(s, rr->length, 1);
- /* This packet contained a partial record, dump it. */
- if (n != rr->length) {
- rr->length = 0;
- s->packet_length = 0;
- goto again;
- }
+ case ssl_open_record_error:
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ return -1;
- /* now n == rr->length,
- * and s->packet_length == DTLS1_RT_HEADER_LENGTH + rr->length */
+ case ssl_open_record_partial:
+ /* Impossible in DTLS. */
+ break;
}
- s->rstate = SSL_ST_READ_HEADER; /* set state for later operations */
- if (rr->epoch != s->d1->r_epoch) {
- /* This record is from the wrong epoch. If it is the next epoch, it could be
- * buffered. For simplicity, drop it and expect retransmit to handle it
- * later; DTLS is supposed to handle packet loss. */
- rr->length = 0;
- s->packet_length = 0;
- goto again;
- }
+ assert(0);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return -1;
+}
- /* Check whether this is a repeat, or aged record. */
- if (!dtls1_record_replay_check(s, &s->d1->bitmap)) {
- rr->length = 0;
- s->packet_length = 0; /* dump this record */
- goto again; /* get another record */
+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);
- /* just read a 0 length packet */
- if (rr->length == 0) {
- goto again;
+ 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 (!dtls1_process_record(s)) {
- rr->length = 0;
- s->packet_length = 0; /* dump this record */
- goto again; /* get another record */
+ if (ssl->msg_callback != NULL) {
+ ssl->msg_callback(0, ssl->version, SSL3_RT_CHANGE_CIPHER_SPEC, &byte, 1,
+ ssl, ssl->msg_callback_arg);
}
- dtls1_record_bitmap_update(s, &s->d1->bitmap); /* Mark receipt of record. */
return 1;
}
-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);
-}
-
void dtls1_read_close_notify(SSL *ssl) {
- dtls1_read_bytes(ssl, 0, NULL, 0, 0);
+ /* 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
+ * peer never received our close_notify. Report to the caller that the channel
+ * has fully shut down. */
+ ssl->shutdown |= SSL_RECEIVED_SHUTDOWN;
}
/* 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)
- * - 0 (during a shutdown, no data has to be returned)
+ * - 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 type2, int val) = NULL;
+ void (*cb)(const SSL *ssl, int type, int value) = NULL;
- /* XXX: check what the second '&& type' is about */
- if ((type && (type != SSL3_RT_APPLICATION_DATA) &&
- (type != SSL3_RT_HANDSHAKE) && type) ||
- (peek && (type != SSL3_RT_APPLICATION_DATA))) {
- OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, ERR_R_INTERNAL_ERROR);
+ 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;
}
if (i == 0) {
- OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, SSL_R_SSL_HANDSHAKE_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
return -1;
}
}
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 || s->rstate == SSL_ST_READ_BODY) {
- ret = dtls1_get_record(s);
+ if (rr->length == 0) {
+ 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;
@@ -479,38 +287,32 @@ 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;
- OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, SSL_R_APP_DATA_IN_HANDSHAKE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_APP_DATA_IN_HANDSHAKE);
goto f_err;
}
+ /* Discard empty records. */
+ if (rr->length == 0) {
+ goto start;
+ }
+
if (len <= 0) {
return len;
}
@@ -521,13 +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) {
- s->rstate = SSL_ST_READ_HEADER;
- rr->off = 0;
+ /* The record has been consumed, so we may now clear the buffer. */
+ ssl_read_buffer_discard(ssl);
}
}
@@ -542,255 +344,173 @@ start:
/* Alerts may not be fragmented. */
if (rr->length < 2) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, SSL_R_BAD_ALERT);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ALERT);
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;
- OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes,
- SSL_AD_REASON_OFFSET + 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;
- OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, SSL_R_UNKNOWN_ALERT_TYPE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_ALERT_TYPE);
goto f_err;
}
goto start;
}
- if (s->shutdown & SSL_SENT_SHUTDOWN) {
- /* but we have not received a shutdown */
- s->rwstate = SSL_NOTHING;
+ /* 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;
- return 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, dtls1_read_bytes, SSL_R_BAD_CHANGE_CIPHER_SPEC);
- goto f_err;
- }
-
- 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);
- }
-
- /* 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, dtls1_read_bytes, SSL_R_BAD_HANDSHAKE_RECORD);
+ 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, dtls1_read_bytes, SSL_R_UNEXPECTED_RECORD);
+ 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;
}
if (i == 0) {
- OPENSSL_PUT_ERROR(SSL, dtls1_write_app_data, SSL_R_SSL_HANDSHAKE_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
return -1;
}
}
if (len > SSL3_RT_MAX_PLAIN_LENGTH) {
- OPENSSL_PUT_ERROR(SSL, dtls1_write_app_data, SSL_R_DTLS_MESSAGE_TOO_BIG);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DTLS_MESSAGE_TOO_BIG);
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;
}
-/* dtls1_seal_record seals a new record of type |type| and plaintext |in| and
- * writes it to |out|. At most |max_out| bytes will be written. It returns one
- * on success and zero on error. On success, it updates the write sequence
- * number. */
-static int dtls1_seal_record(SSL *s, uint8_t *out, size_t *out_len,
- size_t max_out, uint8_t type, const uint8_t *in,
- size_t in_len, enum dtls1_use_epoch_t use_epoch) {
- if (max_out < DTLS1_RT_HEADER_LENGTH) {
- OPENSSL_PUT_ERROR(SSL, dtls1_seal_record, SSL_R_BUFFER_TOO_SMALL);
- return 0;
- }
-
- /* Determine the parameters for the current epoch. */
- uint16_t epoch = s->d1->w_epoch;
- SSL_AEAD_CTX *aead = s->aead_write_ctx;
- uint8_t *seq = s->s3->write_sequence;
- if (use_epoch == dtls1_use_previous_epoch) {
- /* DTLS renegotiation is unsupported, so only epochs 0 (NULL cipher) and 1
- * (negotiated cipher) exist. */
- assert(s->d1->w_epoch == 1);
- epoch = s->d1->w_epoch - 1;
- aead = NULL;
- seq = s->d1->last_write_sequence;
- }
-
- out[0] = type;
-
- uint16_t wire_version = s->s3->have_version ? s->version : DTLS1_VERSION;
- out[1] = wire_version >> 8;
- out[2] = wire_version & 0xff;
-
- out[3] = epoch >> 8;
- out[4] = epoch & 0xff;
- memcpy(&out[5], &seq[2], 6);
-
- size_t ciphertext_len;
- if (!SSL_AEAD_CTX_seal(aead, out + DTLS1_RT_HEADER_LENGTH, &ciphertext_len,
- max_out - DTLS1_RT_HEADER_LENGTH, type, wire_version,
- &out[3] /* seq */, in, in_len) ||
- !ssl3_record_sequence_update(&seq[2], 6)) {
- return 0;
- }
-
- if (ciphertext_len >= 1 << 16) {
- OPENSSL_PUT_ERROR(SSL, dtls1_seal_record, ERR_R_OVERFLOW);
- return 0;
- }
- out[11] = ciphertext_len >> 8;
- out[12] = ciphertext_len & 0xff;
-
- *out_len = DTLS1_RT_HEADER_LENGTH + ciphertext_len;
-
- if (s->msg_callback) {
- s->msg_callback(1 /* write */, 0, SSL3_RT_HEADER, out,
- DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg);
- }
-
- return 1;
-}
-
-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) {
- SSL3_BUFFER *wb = &s->s3->wbuf;
-
- /* ssl3_write_pending drops the write if |BIO_write| fails in DTLS, so there
- * is never pending data. */
- assert(s->s3->wbuf.left == 0);
+ /* 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(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;
}
/* if it went, fall through and send more stuff */
}
- if (wb->buf == NULL && !ssl3_setup_write_buffer(s)) {
+ if (len > SSL3_RT_MAX_PLAIN_LENGTH) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return -1;
}
@@ -798,130 +518,61 @@ static int do_dtls1_write(SSL *s, int type, const uint8_t *buf,
return 0;
}
- /* Align the output so the ciphertext is aligned to |SSL3_ALIGN_PAYLOAD|. */
- uintptr_t align = (uintptr_t)wb->buf + DTLS1_RT_HEADER_LENGTH;
- align = (0 - align) & (SSL3_ALIGN_PAYLOAD - 1);
- uint8_t *out = wb->buf + align;
- wb->offset = align;
- size_t max_out = wb->len - wb->offset;
-
+ size_t max_out = len + ssl_max_seal_overhead(ssl);
+ uint8_t *out;
size_t ciphertext_len;
- if (!dtls1_seal_record(s, out, &ciphertext_len, max_out, type, buf, len,
- use_epoch)) {
+ 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(ssl);
return -1;
}
+ ssl_write_buffer_set_len(ssl, ciphertext_len);
- /* now let's set up wb */
- wb->left = 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;
-
- /* we now just need to write the buffer */
- return ssl3_write_pending(s, type, buf, len);
-}
-
-static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap) {
- int cmp;
- unsigned int shift;
- const uint8_t *seq = s->s3->read_sequence;
-
- cmp = satsub64be(seq, bitmap->max_seq_num);
- if (cmp > 0) {
- memcpy(s->s3->rrec.seq_num, seq, 8);
- return 1; /* this record in new */
- }
- shift = -cmp;
- if (shift >= sizeof(bitmap->map) * 8) {
- return 0; /* stale, outside the window */
- } else if (bitmap->map & (((uint64_t)1) << shift)) {
- return 0; /* record previously received */
+ int ret = ssl_write_buffer_flush(ssl);
+ if (ret <= 0) {
+ return ret;
}
-
- memcpy(s->s3->rrec.seq_num, seq, 8);
- return 1;
+ return (int)len;
}
-static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap) {
- int cmp;
- unsigned int shift;
- const uint8_t *seq = s->s3->read_sequence;
-
- cmp = satsub64be(seq, bitmap->max_seq_num);
- if (cmp > 0) {
- shift = cmp;
- if (shift < sizeof(bitmap->map) * 8) {
- bitmap->map <<= shift, bitmap->map |= 1UL;
- } else {
- bitmap->map = 1UL;
- }
- memcpy(bitmap->max_seq_num, seq, 8);
- } else {
- shift = -cmp;
- if (shift < sizeof(bitmap->map) * 8) {
- bitmap->map |= ((uint64_t)1) << shift;
- }
- }
-}
-
-int dtls1_dispatch_alert(SSL *s) {
+int dtls1_dispatch_alert(SSL *ssl) {
int i, j;
- void (*cb)(const SSL *ssl, int type, int val) = NULL;
+ 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 5928fc8..5dba8ef 100644
--- a/src/ssl/d1_srtp.c
+++ b/src/ssl/d1_srtp.c
@@ -114,6 +114,8 @@
Copyright (C) 2011, RTFM, Inc.
*/
+#include <openssl/ssl.h>
+
#include <stdio.h>
#include <string.h>
@@ -122,17 +124,22 @@
#include <openssl/obj.h>
#include "internal.h"
-#include <openssl/srtp.h>
-static const SRTP_PROTECTION_PROFILE srtp_known_profiles[] = {
+const SRTP_PROTECTION_PROFILE kSRTPProfiles[] = {
+ {
+ "SRTP_AES128_CM_SHA1_80", SRTP_AES128_CM_SHA1_80,
+ },
{
- "SRTP_AES128_CM_SHA1_80", SRTP_AES128_CM_SHA1_80,
+ "SRTP_AES128_CM_SHA1_32", SRTP_AES128_CM_SHA1_32,
},
{
- "SRTP_AES128_CM_SHA1_32", SRTP_AES128_CM_SHA1_32,
+ "SRTP_AEAD_AES_128_GCM", SRTP_AEAD_AES_128_GCM,
},
- {0},
+ {
+ "SRTP_AEAD_AES_256_GCM", SRTP_AEAD_AES_256_GCM,
+ },
+ {0, 0},
};
static int find_profile_by_name(const char *profile_name,
@@ -140,7 +147,7 @@ static int find_profile_by_name(const char *profile_name,
size_t len) {
const SRTP_PROTECTION_PROFILE *p;
- p = srtp_known_profiles;
+ p = kSRTPProfiles;
while (p->name) {
if (len == strlen(p->name) && !strncmp(p->name, profile_name, len)) {
*pptr = p;
@@ -153,22 +160,6 @@ static int find_profile_by_name(const char *profile_name,
return 0;
}
-static int find_profile_by_num(unsigned profile_num,
- const SRTP_PROTECTION_PROFILE **pptr) {
- const SRTP_PROTECTION_PROFILE *p;
-
- p = srtp_known_profiles;
- while (p->name) {
- if (p->id == profile_num) {
- *pptr = p;
- return 1;
- }
- p++;
- }
-
- return 0;
-}
-
static int ssl_ctx_make_profiles(const char *profiles_string,
STACK_OF(SRTP_PROTECTION_PROFILE) **out) {
STACK_OF(SRTP_PROTECTION_PROFILE) *profiles;
@@ -178,8 +169,7 @@ static int ssl_ctx_make_profiles(const char *profiles_string,
profiles = sk_SRTP_PROTECTION_PROFILE_new_null();
if (profiles == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_ctx_make_profiles,
- SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES);
return 0;
}
@@ -187,11 +177,11 @@ static int ssl_ctx_make_profiles(const char *profiles_string,
const SRTP_PROTECTION_PROFILE *p;
col = strchr(ptr, ':');
- if (find_profile_by_name(ptr, &p, col ? col - ptr : strlen(ptr))) {
+ if (find_profile_by_name(ptr, &p,
+ col ? (size_t)(col - ptr) : strlen(ptr))) {
sk_SRTP_PROTECTION_PROFILE_push(profiles, p);
} else {
- OPENSSL_PUT_ERROR(SSL, ssl_ctx_make_profiles,
- SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE);
return 0;
}
@@ -209,28 +199,28 @@ int SSL_CTX_set_srtp_profiles(SSL_CTX *ctx, const char *profiles) {
return ssl_ctx_make_profiles(profiles, &ctx->srtp_profiles);
}
-int SSL_set_srtp_profiles(SSL *s, const char *profiles) {
- return ssl_ctx_make_profiles(profiles, &s->srtp_profiles);
+int SSL_set_srtp_profiles(SSL *ssl, const char *profiles) {
+ return ssl_ctx_make_profiles(profiles, &ssl->srtp_profiles);
}
-STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *s) {
- if (s == NULL) {
+STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl) {
+ if (ssl == NULL) {
return NULL;
}
- if (s->srtp_profiles != NULL) {
- return s->srtp_profiles;
+ if (ssl->srtp_profiles != NULL) {
+ return ssl->srtp_profiles;
}
- if (s->ctx != NULL && s->ctx->srtp_profiles != NULL) {
- return s->ctx->srtp_profiles;
+ if (ssl->ctx != NULL && ssl->ctx->srtp_profiles != NULL) {
+ return ssl->ctx->srtp_profiles;
}
return NULL;
}
-const SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s) {
- return s->srtp_profile;
+const SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *ssl) {
+ return ssl->srtp_profile;
}
int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles) {
@@ -238,195 +228,7 @@ int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles) {
return !SSL_CTX_set_srtp_profiles(ctx, profiles);
}
-int SSL_set_tlsext_use_srtp(SSL *s, const char *profiles) {
+int SSL_set_tlsext_use_srtp(SSL *ssl, const char *profiles) {
/* This API inverts its return value. */
- return !SSL_set_srtp_profiles(s, profiles);
-}
-
-/* Note: this function returns 0 length if there are no profiles specified */
-int ssl_add_clienthello_use_srtp_ext(SSL *s, uint8_t *p, int *len, int maxlen) {
- int ct = 0;
- int i;
- STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = 0;
- const SRTP_PROTECTION_PROFILE *prof;
-
- clnt = SSL_get_srtp_profiles(s);
- ct = sk_SRTP_PROTECTION_PROFILE_num(clnt); /* -1 if clnt == 0 */
-
- if (p) {
- if (ct == 0) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_use_srtp_ext,
- SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST);
- return 0;
- }
-
- if (2 + ct * 2 + 1 > maxlen) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_use_srtp_ext,
- SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG);
- return 0;
- }
-
- /* Add the length */
- s2n(ct * 2, p);
- for (i = 0; i < ct; i++) {
- prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i);
- s2n(prof->id, p);
- }
-
- /* Add an empty use_mki value */
- *p++ = 0;
- }
-
- *len = 2 + ct * 2 + 1;
-
- return 1;
-}
-
-int ssl_parse_clienthello_use_srtp_ext(SSL *s, CBS *cbs, int *out_alert) {
- CBS profile_ids, srtp_mki;
- const SRTP_PROTECTION_PROFILE *cprof, *sprof;
- STACK_OF(SRTP_PROTECTION_PROFILE) *client_profiles = 0, *server_profiles;
- size_t i, j;
- int ret = 0;
-
- if (!CBS_get_u16_length_prefixed(cbs, &profile_ids) ||
- CBS_len(&profile_ids) < 2 ||
- !CBS_get_u8_length_prefixed(cbs, &srtp_mki) ||
- CBS_len(cbs) != 0) {
- OPENSSL_PUT_ERROR(SSL, ssl_parse_clienthello_use_srtp_ext,
- SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
- *out_alert = SSL_AD_DECODE_ERROR;
- goto done;
- }
-
- client_profiles = sk_SRTP_PROTECTION_PROFILE_new_null();
- if (client_profiles == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_parse_clienthello_use_srtp_ext,
- ERR_R_MALLOC_FAILURE);
- *out_alert = SSL_AD_INTERNAL_ERROR;
- goto done;
- }
-
- while (CBS_len(&profile_ids) > 0) {
- uint16_t profile_id;
-
- if (!CBS_get_u16(&profile_ids, &profile_id)) {
- *out_alert = SSL_AD_DECODE_ERROR;
- goto done;
- }
-
- if (find_profile_by_num(profile_id, &cprof)) {
- sk_SRTP_PROTECTION_PROFILE_push(client_profiles, cprof);
- }
- }
-
- /* Discard the MKI value for now. */
-
- server_profiles = SSL_get_srtp_profiles(s);
-
- /* Pick the server's most preferred profile. */
- for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(server_profiles); i++) {
- sprof = sk_SRTP_PROTECTION_PROFILE_value(server_profiles, i);
-
- for (j = 0; j < sk_SRTP_PROTECTION_PROFILE_num(client_profiles); j++) {
- cprof = sk_SRTP_PROTECTION_PROFILE_value(client_profiles, j);
-
- if (cprof->id == sprof->id) {
- s->srtp_profile = sprof;
- ret = 1;
- goto done;
- }
- }
- }
-
- ret = 1;
-
-done:
- if (client_profiles) {
- sk_SRTP_PROTECTION_PROFILE_free(client_profiles);
- }
-
- return ret;
-}
-
-int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len,
- int maxlen) {
- if (p) {
- if (maxlen < 5) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_use_srtp_ext,
- SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG);
- return 0;
- }
-
- if (s->srtp_profile == 0) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_use_srtp_ext,
- SSL_R_USE_SRTP_NOT_NEGOTIATED);
- return 0;
- }
-
- s2n(2, p);
- s2n(s->srtp_profile->id, p);
- *p++ = 0;
- }
-
- *len = 5;
-
- return 1;
-}
-
-int ssl_parse_serverhello_use_srtp_ext(SSL *s, CBS *cbs, int *out_alert) {
- CBS profile_ids, srtp_mki;
- uint16_t profile_id;
- size_t i;
-
- STACK_OF(SRTP_PROTECTION_PROFILE) *client_profiles;
- const SRTP_PROTECTION_PROFILE *prof;
-
- /* The extension consists of a u16-prefixed profile ID list containing a
- * single uint16_t profile ID, then followed by a u8-prefixed srtp_mki field.
- *
- * See https://tools.ietf.org/html/rfc5764#section-4.1.1 */
- if (!CBS_get_u16_length_prefixed(cbs, &profile_ids) ||
- !CBS_get_u16(&profile_ids, &profile_id) || CBS_len(&profile_ids) != 0 ||
- !CBS_get_u8_length_prefixed(cbs, &srtp_mki) || CBS_len(cbs) != 0) {
- OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_use_srtp_ext,
- SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
-
- if (CBS_len(&srtp_mki) != 0) {
- /* Must be no MKI, since we never offer one. */
- OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_use_srtp_ext,
- SSL_R_BAD_SRTP_MKI_VALUE);
- *out_alert = SSL_AD_ILLEGAL_PARAMETER;
- return 0;
- }
-
- client_profiles = SSL_get_srtp_profiles(s);
-
- /* Throw an error if the server gave us an unsolicited extension */
- if (client_profiles == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_use_srtp_ext,
- SSL_R_NO_SRTP_PROFILES);
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
-
- /* Check to see if the server gave us something we support
- (and presumably offered). */
- for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(client_profiles); i++) {
- prof = sk_SRTP_PROTECTION_PROFILE_value(client_profiles, i);
-
- if (prof->id == profile_id) {
- s->srtp_profile = prof;
- *out_alert = 0;
- return 1;
- }
- }
-
- OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_use_srtp_ext,
- SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
- *out_alert = SSL_AD_ILLEGAL_PARAMETER;
- return 0;
+ return !SSL_set_srtp_profiles(ssl, profiles);
}
diff --git a/src/ssl/d1_srvr.c b/src/ssl/d1_srvr.c
index e49a3f0..3ba9411 100644
--- a/src/ssl/d1_srvr.c
+++ b/src/ssl/d1_srvr.c
@@ -112,6 +112,8 @@
* [including the GNU Public Licence.]
*/
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <stdio.h>
@@ -128,125 +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 val) = 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++;
-
- if (s->cert == NULL) {
- OPENSSL_PUT_ERROR(SSL, dtls1_accept, SSL_R_NO_CERTIFICATE_SET);
- return -1;
- }
+ 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_finished_mac(s)) {
- OPENSSL_PUT_ERROR(SSL, dtls1_accept, ERR_R_INTERNAL_ERROR);
+ 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;
+ }
+ ssl->init_num = 0;
+ break;
+
+ case SSL3_ST_SW_CERT_STATUS_A:
+ case SSL3_ST_SW_CERT_STATUS_B:
+ ret = ssl3_send_certificate_status(ssl);
+ if (ret <= 0) {
+ goto end;
}
- 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:
- alg_a = s->s3->tmp.new_cipher->algorithm_auth;
+ case SSL3_ST_SW_KEY_EXCH_C:
+ alg_a = ssl->s3->tmp.new_cipher->algorithm_auth;
/* Send a ServerKeyExchange message if:
* - The key exchange is ephemeral or anonymous
@@ -256,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;
}
@@ -267,199 +275,211 @@ 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:
- ret = ssl3_get_client_key_exchange(s);
+ case SSL3_ST_SR_KEY_EXCH_C:
+ 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:
- OPENSSL_PUT_ERROR(SSL, dtls1_accept, SSL_R_UNKNOWN_STATE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_STATE);
ret = -1;
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/dtls_record.c b/src/ssl/dtls_record.c
new file mode 100644
index 0000000..940494a
--- /dev/null
+++ b/src/ssl/dtls_record.c
@@ -0,0 +1,308 @@
+/* DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* 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.] */
+
+#include <openssl/ssl.h>
+
+#include <assert.h>
+#include <string.h>
+
+#include <openssl/bytestring.h>
+#include <openssl/err.h>
+
+#include "internal.h"
+
+
+/* to_u64_be treats |in| as a 8-byte big-endian integer and returns the value as
+ * a |uint64_t|. */
+static uint64_t to_u64_be(const uint8_t in[8]) {
+ uint64_t ret = 0;
+ unsigned i;
+ for (i = 0; i < 8; i++) {
+ ret <<= 8;
+ ret |= in[i];
+ }
+ return ret;
+}
+
+/* dtls1_bitmap_should_discard returns one if |seq_num| has been seen in |bitmap|
+ * or is stale. Otherwise it returns zero. */
+static int dtls1_bitmap_should_discard(DTLS1_BITMAP *bitmap,
+ const uint8_t seq_num[8]) {
+ const unsigned kWindowSize = sizeof(bitmap->map) * 8;
+
+ uint64_t seq_num_u = to_u64_be(seq_num);
+ if (seq_num_u > bitmap->max_seq_num) {
+ return 0;
+ }
+ uint64_t idx = bitmap->max_seq_num - seq_num_u;
+ return idx >= kWindowSize || (bitmap->map & (((uint64_t)1) << idx));
+}
+
+/* dtls1_bitmap_record updates |bitmap| to record receipt of sequence number
+ * |seq_num|. It slides the window forward if needed. It is an error to call
+ * this function on a stale sequence number. */
+static void dtls1_bitmap_record(DTLS1_BITMAP *bitmap,
+ const uint8_t seq_num[8]) {
+ const unsigned kWindowSize = sizeof(bitmap->map) * 8;
+
+ uint64_t seq_num_u = to_u64_be(seq_num);
+ /* Shift the window if necessary. */
+ if (seq_num_u > bitmap->max_seq_num) {
+ uint64_t shift = seq_num_u - bitmap->max_seq_num;
+ if (shift >= kWindowSize) {
+ bitmap->map = 0;
+ } else {
+ bitmap->map <<= shift;
+ }
+ bitmap->max_seq_num = seq_num_u;
+ }
+
+ uint64_t idx = bitmap->max_seq_num - seq_num_u;
+ if (idx < kWindowSize) {
+ bitmap->map |= ((uint64_t)1) << idx;
+ }
+}
+
+enum ssl_open_record_t dtls_open_record(
+ SSL *ssl, uint8_t *out_type, uint8_t *out, size_t *out_len,
+ size_t *out_consumed, uint8_t *out_alert, size_t max_out, const uint8_t *in,
+ size_t in_len) {
+ CBS cbs;
+ CBS_init(&cbs, in, in_len);
+
+ /* Decode the record. */
+ uint8_t type;
+ uint16_t version;
+ uint8_t sequence[8];
+ CBS body;
+ if (!CBS_get_u8(&cbs, &type) ||
+ !CBS_get_u16(&cbs, &version) ||
+ !CBS_copy_bytes(&cbs, sequence, 8) ||
+ !CBS_get_u16_length_prefixed(&cbs, &body) ||
+ (ssl->s3->have_version && version != ssl->version) ||
+ (version >> 8) != DTLS1_VERSION_MAJOR ||
+ CBS_len(&body) > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
+ /* The record header was incomplete or malformed. Drop the entire packet. */
+ *out_consumed = in_len;
+ return ssl_open_record_discard;
+ }
+
+ if (ssl->msg_callback != NULL) {
+ ssl->msg_callback(0 /* read */, 0, SSL3_RT_HEADER, in,
+ DTLS1_RT_HEADER_LENGTH, ssl, ssl->msg_callback_arg);
+ }
+
+ uint16_t epoch = (((uint16_t)sequence[0]) << 8) | sequence[1];
+ if (epoch != ssl->d1->r_epoch ||
+ dtls1_bitmap_should_discard(&ssl->d1->bitmap, sequence)) {
+ /* Drop this record. It's from the wrong epoch or is a replay. Note that if
+ * |epoch| is the next epoch, the record could be buffered for later. For
+ * simplicity, drop it and expect retransmit to handle it later; DTLS must
+ * handle packet loss anyway. */
+ *out_consumed = in_len - CBS_len(&cbs);
+ return ssl_open_record_discard;
+ }
+
+ /* Decrypt the body. */
+ size_t plaintext_len;
+ if (!SSL_AEAD_CTX_open(ssl->aead_read_ctx, out, &plaintext_len, max_out,
+ type, version, sequence, CBS_data(&body),
+ CBS_len(&body))) {
+ /* Bad packets are silently dropped in DTLS. See section 4.2.1 of RFC 6347.
+ * Clear the error queue of any errors decryption may have added. Drop the
+ * entire packet as it must not have come from the peer.
+ *
+ * TODO(davidben): This doesn't distinguish malloc failures from encryption
+ * failures. */
+ ERR_clear_error();
+ *out_consumed = in_len - CBS_len(&cbs);
+ return ssl_open_record_discard;
+ }
+
+ /* Check the plaintext length. */
+ 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;
+ }
+
+ dtls1_bitmap_record(&ssl->d1->bitmap, sequence);
+
+ /* TODO(davidben): Limit the number of empty records as in TLS? This is only
+ * useful if we also limit discarded packets. */
+
+ *out_type = type;
+ *out_len = plaintext_len;
+ *out_consumed = in_len - CBS_len(&cbs);
+ return ssl_open_record_success;
+}
+
+int dtls_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,
+ enum dtls1_use_epoch_t use_epoch) {
+ /* Determine the parameters for the current epoch. */
+ uint16_t epoch = ssl->d1->w_epoch;
+ SSL_AEAD_CTX *aead = ssl->aead_write_ctx;
+ uint8_t *seq = ssl->s3->write_sequence;
+ if (use_epoch == dtls1_use_previous_epoch) {
+ /* DTLS renegotiation is unsupported, so only epochs 0 (NULL cipher) and 1
+ * (negotiated cipher) exist. */
+ assert(ssl->d1->w_epoch == 1);
+ epoch = ssl->d1->w_epoch - 1;
+ aead = NULL;
+ seq = ssl->d1->last_write_sequence;
+ }
+
+ if (max_out < DTLS1_RT_HEADER_LENGTH) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+ /* Check the record header does not alias any part of the input.
+ * |SSL_AEAD_CTX_seal| will internally enforce other aliasing requirements. */
+ if (in < out + DTLS1_RT_HEADER_LENGTH && out < in + in_len) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT);
+ return 0;
+ }
+
+ out[0] = type;
+
+ uint16_t wire_version = ssl->s3->have_version ? ssl->version : DTLS1_VERSION;
+ out[1] = wire_version >> 8;
+ out[2] = wire_version & 0xff;
+
+ out[3] = epoch >> 8;
+ out[4] = epoch & 0xff;
+ memcpy(&out[5], &seq[2], 6);
+
+ size_t ciphertext_len;
+ if (!SSL_AEAD_CTX_seal(aead, out + DTLS1_RT_HEADER_LENGTH, &ciphertext_len,
+ max_out - DTLS1_RT_HEADER_LENGTH, type, wire_version,
+ &out[3] /* seq */, in, in_len) ||
+ !ssl3_record_sequence_update(&seq[2], 6)) {
+ return 0;
+ }
+
+ if (ciphertext_len >= 1 << 16) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ return 0;
+ }
+ out[11] = ciphertext_len >> 8;
+ out[12] = ciphertext_len & 0xff;
+
+ *out_len = DTLS1_RT_HEADER_LENGTH + ciphertext_len;
+
+ if (ssl->msg_callback) {
+ ssl->msg_callback(1 /* write */, 0, SSL3_RT_HEADER, out,
+ DTLS1_RT_HEADER_LENGTH, ssl, ssl->msg_callback_arg);
+ }
+
+ return 1;
+}
diff --git a/src/ssl/internal.h b/src/ssl/internal.h
index 7d9a5ad..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
@@ -181,7 +181,9 @@
#define SSL_AES256 0x00000008L
#define SSL_AES128GCM 0x00000010L
#define SSL_AES256GCM 0x00000020L
-#define SSL_CHACHA20POLY1305 0x00000040L
+#define SSL_CHACHA20POLY1305_OLD 0x00000040L
+#define SSL_eNULL 0x00000080L
+#define SSL_CHACHA20POLY1305 0x00000100L
#define SSL_AES (SSL_AES128 | SSL_AES256 | SSL_AES128GCM | SSL_AES256GCM)
@@ -193,39 +195,15 @@
/* 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 |algorithm2| (handshake digests and other extra flags). */
-
-#define SSL_HANDSHAKE_MAC_MD5 0x10
-#define SSL_HANDSHAKE_MAC_SHA 0x20
-#define SSL_HANDSHAKE_MAC_SHA256 0x40
-#define SSL_HANDSHAKE_MAC_SHA384 0x80
-#define SSL_HANDSHAKE_MAC_DEFAULT \
- (SSL_HANDSHAKE_MAC_MD5 | SSL_HANDSHAKE_MAC_SHA)
+/* Bits for |algorithm_prf| (handshake digest). */
+#define SSL_HANDSHAKE_MAC_DEFAULT 0x1
+#define SSL_HANDSHAKE_MAC_SHA256 0x2
+#define SSL_HANDSHAKE_MAC_SHA384 0x4
/* SSL_MAX_DIGEST is the number of digest types which exist. When adding a new
* one, update the table in ssl_cipher.c. */
#define SSL_MAX_DIGEST 4
-/* SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD is a flag in
- * SSL_CIPHER.algorithm2 which indicates that the variable part of the nonce is
- * included as a prefix of the record. (AES-GCM, for example, does with with an
- * 8-byte variable nonce.) */
-#define SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD (1<<22)
-
-/* 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,
@@ -236,11 +214,11 @@ int ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead,
size_t *out_fixed_iv_len,
const SSL_CIPHER *cipher, uint16_t version);
-/* ssl_get_handshake_digest looks up the |i|th handshake digest type and sets
- * |*out_mask| to the |SSL_HANDSHAKE_MAC_*| mask and |*out_md| to the
- * |EVP_MD|. It returns one on successs and zero if |i| >= |SSL_MAX_DIGEST|. */
-int ssl_get_handshake_digest(uint32_t *out_mask, const EVP_MD **out_md,
- size_t i);
+/* ssl_get_handshake_digest returns the |EVP_MD| corresponding to
+ * |algorithm_prf|. It returns SHA-1 for |SSL_HANDSHAKE_DEFAULT|. The caller is
+ * responsible for maintaining the additional MD5 digest and switching to
+ * SHA-256 in TLS 1.2. */
+const EVP_MD *ssl_get_handshake_digest(uint32_t algorithm_prf);
/* ssl_create_cipher_list evaluates |rule_str| according to the ciphers in
* |ssl_method|. It sets |*out_cipher_list| to a newly-allocated
@@ -254,18 +232,12 @@ ssl_create_cipher_list(const SSL_PROTOCOL_METHOD *ssl_method,
STACK_OF(SSL_CIPHER) **out_cipher_list_by_id,
const char *rule_str);
-/* SSL_PKEY_* denote certificate types. */
-#define SSL_PKEY_RSA_ENC 0
-#define SSL_PKEY_RSA_SIGN 1
-#define SSL_PKEY_ECC 2
-#define SSL_PKEY_NUM 3
-
/* ssl_cipher_get_value returns the cipher suite id of |cipher|. */
uint16_t ssl_cipher_get_value(const SSL_CIPHER *cipher);
-/* ssl_cipher_get_cert_index returns the |SSL_PKEY_*| value corresponding to the
- * certificate type of |cipher| or -1 if there is none. */
-int ssl_cipher_get_cert_index(const SSL_CIPHER *cipher);
+/* ssl_cipher_get_key_type returns the |EVP_PKEY_*| value corresponding to the
+ * server key used in |cipher| or |EVP_PKEY_NONE| if there is none. */
+int ssl_cipher_get_key_type(const SSL_CIPHER *cipher);
/* ssl_cipher_has_server_public_key returns 1 if |cipher| involves a server
* public key in the key exchange, sent in a server Certificate message.
@@ -275,11 +247,16 @@ int ssl_cipher_has_server_public_key(const SSL_CIPHER *cipher);
/* ssl_cipher_requires_server_key_exchange returns 1 if |cipher| requires a
* ServerKeyExchange message. Otherwise it returns 0.
*
- * Unlike ssl_cipher_has_server_public_key, some ciphers take optional
- * ServerKeyExchanges. PSK and RSA_PSK only use the ServerKeyExchange to
- * communicate a psk_identity_hint, so it is optional. */
+ * Unlike |ssl_cipher_has_server_public_key|, this function may return zero
+ * while still allowing |cipher| an optional ServerKeyExchange. This is the
+ * case for plain PSK ciphers. */
int ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher);
+/* ssl_cipher_get_record_split_len, for TLS 1.0 CBC mode ciphers, returns the
+ * length of an encrypted 1-byte record, for use in record-splitting. Otherwise
+ * it returns zero. */
+size_t ssl_cipher_get_record_split_len(const SSL_CIPHER *cipher);
+
/* Encryption layer. */
@@ -290,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. */
@@ -305,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
@@ -350,6 +330,301 @@ int SSL_AEAD_CTX_seal(SSL_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
size_t in_len);
+/* DTLS replay bitmap. */
+
+/* DTLS1_BITMAP maintains a sliding window of 64 sequence numbers to detect
+ * replayed packets. It should be initialized by zeroing every field. */
+typedef struct dtls1_bitmap_st {
+ /* map is a bit mask of the last 64 sequence numbers. Bit
+ * |1<<i| corresponds to |max_seq_num - i|. */
+ uint64_t map;
+ /* max_seq_num is the largest sequence number seen so far as a 64-bit
+ * integer. */
+ uint64_t max_seq_num;
+} DTLS1_BITMAP;
+
+
+/* Record layer. */
+
+/* ssl_record_prefix_len returns the length of the prefix before the ciphertext
+ * of a record for |ssl|.
+ *
+ * TODO(davidben): Expose this as part of public API once the high-level
+ * buffer-free APIs are available. */
+size_t ssl_record_prefix_len(const SSL *ssl);
+
+enum ssl_open_record_t {
+ ssl_open_record_success,
+ ssl_open_record_discard,
+ ssl_open_record_partial,
+ ssl_open_record_error,
+};
+
+/* tls_open_record decrypts a record from |in|.
+ *
+ * On success, it returns |ssl_open_record_success|. It sets |*out_type| to the
+ * record type, |*out_len| to the plaintext length, and writes the record body
+ * to |out|. It sets |*out_consumed| to the number of bytes of |in| consumed.
+ * Note that |*out_len| may be zero.
+ *
+ * If a record was successfully processed but should be discarded, it returns
+ * |ssl_open_record_discard| and sets |*out_consumed| to the number of bytes
+ * consumed.
+ *
+ * If the input did not contain a complete record, it returns
+ * |ssl_open_record_partial|. It sets |*out_consumed| to the total number of
+ * bytes necessary. It is guaranteed that a successful call to |tls_open_record|
+ * will consume at least that many bytes.
+ *
+ * On failure, it returns |ssl_open_record_error| and sets |*out_alert| to an
+ * alert to emit.
+ *
+ * If |in| and |out| alias, |out| must be <= |in| + |ssl_record_prefix_len|. */
+enum ssl_open_record_t tls_open_record(
+ SSL *ssl, uint8_t *out_type, uint8_t *out, size_t *out_len,
+ size_t *out_consumed, uint8_t *out_alert, size_t max_out, const uint8_t *in,
+ size_t in_len);
+
+/* dtls_open_record implements |tls_open_record| for DTLS. It never returns
+ * |ssl_open_record_partial| but otherwise behaves analogously. */
+enum ssl_open_record_t dtls_open_record(
+ SSL *ssl, uint8_t *out_type, uint8_t *out, size_t *out_len,
+ size_t *out_consumed, uint8_t *out_alert, size_t max_out, const uint8_t *in,
+ size_t in_len);
+
+/* ssl_seal_prefix_len returns the length of the prefix before the ciphertext
+ * when sealing a record with |ssl|. Note that this value may differ from
+ * |ssl_record_prefix_len| when TLS 1.0 CBC record-splitting is enabled. Sealing
+ * a small record may also result in a smaller output than this value.
+ *
+ * TODO(davidben): Expose this as part of public API once the high-level
+ * buffer-free APIs are available. */
+size_t ssl_seal_prefix_len(const SSL *ssl);
+
+/* ssl_max_seal_overhead returns the maximum overhead of sealing a record with
+ * |ssl|. This includes |ssl_seal_prefix_len|.
+ *
+ * TODO(davidben): Expose this as part of public API once the high-level
+ * buffer-free APIs are available. */
+size_t ssl_max_seal_overhead(const SSL *ssl);
+
+/* tls_seal_record seals a new record of type |type| and body |in| and writes it
+ * to |out|. At most |max_out| bytes will be written. It returns one on success
+ * and zero on error. If enabled, |tls_seal_record| implements TLS 1.0 CBC 1/n-1
+ * record splitting and may write two records concatenated.
+ *
+ * For a large record, the ciphertext will begin |ssl_seal_prefix_len| bytes
+ * into out. Aligning |out| appropriately may improve performance. It writes at
+ * most |in_len| + |ssl_max_seal_overhead| bytes to |out|.
+ *
+ * If |in| and |out| alias, |out| + |ssl_seal_prefix_len| must be <= |in|. */
+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);
+
+enum dtls1_use_epoch_t {
+ dtls1_use_previous_epoch,
+ dtls1_use_current_epoch,
+};
+
+/* dtls_seal_record implements |tls_seal_record| for DTLS. |use_epoch| selects
+ * which epoch's cipher state to use. */
+int dtls_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,
+ enum dtls1_use_epoch_t use_epoch);
+
+
+/* Private key operations. */
+
+/* ssl_has_private_key returns one if |ssl| has a private key
+ * configured and zero otherwise. */
+int ssl_has_private_key(SSL *ssl);
+
+/* ssl_private_key_* call the corresponding function on the
+ * |SSL_PRIVATE_KEY_METHOD| for |ssl|, if configured. Otherwise, they implement
+ * the operation with |EVP_PKEY|. */
+
+int ssl_private_key_type(SSL *ssl);
+
+size_t ssl_private_key_max_signature_len(SSL *ssl);
+
+enum ssl_private_key_result_t ssl_private_key_sign(
+ SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, const EVP_MD *md,
+ const uint8_t *in, size_t in_len);
+
+enum ssl_private_key_result_t ssl_private_key_sign_complete(
+ SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out);
+
+enum ssl_private_key_result_t ssl_private_key_decrypt(
+ SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
+ const uint8_t *in, size_t in_len);
+
+enum ssl_private_key_result_t ssl_private_key_decrypt_complete(
+ SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out);
+
+
+/* Custom extensions */
+
+/* ssl_custom_extension (a.k.a. SSL_CUSTOM_EXTENSION) is a structure that
+ * contains information about custom-extension callbacks. */
+struct ssl_custom_extension {
+ SSL_custom_ext_add_cb add_callback;
+ void *add_arg;
+ SSL_custom_ext_free_cb free_callback;
+ SSL_custom_ext_parse_cb parse_callback;
+ void *parse_arg;
+ uint16_t value;
+};
+
+void SSL_CUSTOM_EXTENSION_free(SSL_CUSTOM_EXTENSION *custom_extension);
+
+int custom_ext_add_clienthello(SSL *ssl, CBB *extensions);
+int custom_ext_parse_serverhello(SSL *ssl, int *out_alert, uint16_t value,
+ const CBS *extension);
+int custom_ext_parse_clienthello(SSL *ssl, int *out_alert, uint16_t value,
+ const CBS *extension);
+int custom_ext_add_serverhello(SSL *ssl, CBB *extensions);
+
+
+/* Handshake hash.
+ *
+ * The TLS handshake maintains a transcript of all handshake messages. At
+ * various points in the protocol, this is either a handshake buffer, a rolling
+ * hash (selected by cipher suite) or both. */
+
+/* ssl3_init_handshake_buffer initializes the handshake buffer and resets the
+ * handshake hash. It returns one success and zero on failure. */
+int ssl3_init_handshake_buffer(SSL *ssl);
+
+/* ssl3_init_handshake_hash initializes the handshake hash based on the pending
+ * cipher and the contents of the handshake buffer. Subsequent calls to
+ * |ssl3_update_handshake_hash| will update the rolling hash. It returns one on
+ * success and zero on failure. It is an error to call this function after the
+ * handshake buffer is released. */
+int ssl3_init_handshake_hash(SSL *ssl);
+
+/* ssl3_free_handshake_buffer releases the handshake buffer. Subsequent calls
+ * to |ssl3_update_handshake_hash| will not update the handshake buffer. */
+void ssl3_free_handshake_buffer(SSL *ssl);
+
+/* ssl3_free_handshake_hash releases the handshake hash. */
+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. */
+uint8_t *ssl_read_buffer(SSL *ssl);
+
+/* ssl_read_buffer_len returns the length of the read buffer. */
+size_t ssl_read_buffer_len(const SSL *ssl);
+
+/* ssl_read_buffer_extend_to extends the read buffer to the desired length. For
+ * TLS, it reads to the end of the buffer until the buffer is |len| bytes
+ * long. For DTLS, it reads a new packet and ignores |len|. It returns one on
+ * success, zero on EOF, and a negative number on error.
+ *
+ * It is an error to call |ssl_read_buffer_extend_to| in DTLS when the buffer is
+ * non-empty. */
+int ssl_read_buffer_extend_to(SSL *ssl, size_t len);
+
+/* ssl_read_buffer_consume consumes |len| bytes from the read buffer. It
+ * advances the data pointer and decrements the length. The memory consumed will
+ * remain valid until the next call to |ssl_read_buffer_extend| or it is
+ * discarded with |ssl_read_buffer_discard|. */
+void ssl_read_buffer_consume(SSL *ssl, size_t len);
+
+/* ssl_read_buffer_discard discards the consumed bytes from the read buffer. If
+ * the buffer is now empty, it releases memory used by it. */
+void ssl_read_buffer_discard(SSL *ssl);
+
+/* ssl_read_buffer_clear releases all memory associated with the read buffer and
+ * zero-initializes it. */
+void ssl_read_buffer_clear(SSL *ssl);
+
+/* ssl_write_buffer_is_pending returns one if the write buffer has pending data
+ * and zero if is empty. */
+int ssl_write_buffer_is_pending(const SSL *ssl);
+
+/* ssl_write_buffer_init initializes the write buffer. On success, it sets
+ * |*out_ptr| to the start of the write buffer with space for up to |max_len|
+ * bytes. It returns one on success and zero on failure. Call
+ * |ssl_write_buffer_set_len| to complete initialization. */
+int ssl_write_buffer_init(SSL *ssl, uint8_t **out_ptr, size_t max_len);
+
+/* ssl_write_buffer_set_len is called after |ssl_write_buffer_init| to complete
+ * initialization after |len| bytes are written to the buffer. */
+void ssl_write_buffer_set_len(SSL *ssl, size_t len);
+
+/* ssl_write_buffer_flush flushes the write buffer to the transport. It returns
+ * one on success and <= 0 on error. For DTLS, whether or not the write
+ * succeeds, the write buffer will be cleared. */
+int ssl_write_buffer_flush(SSL *ssl);
+
+/* ssl_write_buffer_clear releases all memory associated with the write buffer
+ * and zero-initializes it. */
+void ssl_write_buffer_clear(SSL *ssl);
+
+
/* Underdocumented functions.
*
* Functions below here haven't been touched up and may be underdocumented. */
@@ -459,35 +734,15 @@ int SSL_AEAD_CTX_seal(SSL_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
#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)
-/* Allow TLS 1.2 ciphersuites: applies to DTLS 1.2 as well as TLS 1.2: may
- * apply to others in future. */
-#define SSL_USE_TLS1_2_CIPHERS(s) \
- (s->enc_method->enc_flags & SSL_ENC_FLAG_TLS1_2_CIPHERS)
-/* Determine if a client can use TLS 1.2 ciphersuites: can't rely on method
- * flags because it may not be set to correct version yet. */
-#define SSL_CLIENT_USE_TLS1_2_CIPHERS(s) \
- ((SSL_IS_DTLS(s) && s->client_version <= DTLS1_2_VERSION) || \
- (!SSL_IS_DTLS(s) && s->client_version >= TLS1_2_VERSION))
-
-/* 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 PENDING_SESSION -10000
+#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 {
@@ -495,75 +750,44 @@ enum ssl_hash_message_t {
ssl_hash_message,
};
-typedef struct cert_pkey_st {
+/* Structure containing decoded values of signature algorithms extension */
+typedef struct tls_sigalgs_st {
+ uint8_t rsign;
+ uint8_t rhash;
+} TLS_SIGALGS;
+
+typedef struct cert_st {
X509 *x509;
EVP_PKEY *privatekey;
/* Chain for this certificate */
STACK_OF(X509) *chain;
-} CERT_PKEY;
-typedef struct cert_st {
- /* Current active set */
- CERT_PKEY *key; /* ALWAYS points to an element of the pkeys array
- * Probably it would make more sense to store
- * an index, not a pointer. */
+ /* key_method, if non-NULL, is a set of callbacks to call for private key
+ * operations. */
+ const SSL_PRIVATE_KEY_METHOD *key_method;
/* For clients the following masks are of *disabled* key and auth algorithms
- * based on the current session.
+ * based on the current configuration.
*
* TODO(davidben): Remove these. They get checked twice: when sending the
- * ClientHello and when processing the ServerHello. However, mask_ssl is a
- * different value both times. mask_k and mask_a are not, but is a
- * round-about way of checking the server's cipher was one of the advertised
- * ones. (Currently it checks the masks and then the list of ciphers prior to
- * applying the masks in ClientHello.) */
+ * ClientHello and when processing the ServerHello. */
uint32_t mask_k;
uint32_t mask_a;
- uint32_t mask_ssl;
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);
- CERT_PKEY pkeys[SSL_PKEY_NUM];
-
- /* Server-only: client_certificate_types is list of certificate types to
- * include in the CertificateRequest message.
- */
- uint8_t *client_certificate_types;
- size_t num_client_certificate_types;
-
- /* signature algorithms peer reports: e.g. supported signature
- * algorithms extension for server or as part of a certificate
- * request for client. */
- uint8_t *peer_sigalgs;
- /* Size of above array */
+ /* 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. */
+ TLS_SIGALGS *peer_sigalgs;
+ /* peer_sigalgslen is the number of entries in |peer_sigalgs|. */
size_t peer_sigalgslen;
- /* suppported signature algorithms.
- * When set on a client this is sent in the client hello as the
- * supported signature algorithms extension. For servers
- * it represents the signature algorithms we are willing to use. */
- uint8_t *conf_sigalgs;
- /* Size of above array */
- size_t conf_sigalgslen;
- /* Client authentication signature algorithms, if not set then
- * uses conf_sigalgs. On servers these will be the signature
- * algorithms sent to the client in a cerificate request for TLS 1.2.
- * On a client this represents the signature algortithms we are
- * willing to use for client authentication. */
- uint8_t *client_sigalgs;
- /* Size of above array */
- size_t client_sigalgslen;
- /* Signature algorithms shared by client and server: cached
- * because these are used most often. */
- TLS_SIGALGS *shared_sigalgs;
- size_t shared_sigalgslen;
+
+ /* digest_nids, if non-NULL, is the set of digests supported by |privatekey|
+ * in decreasing order of preference. */
+ int *digest_nids;
+ size_t num_digest_nids;
/* Certificate setup callback: if set is called whenever a
* certificate may be required (client or server). the callback
@@ -573,41 +797,8 @@ typedef struct cert_st {
* supported signature algorithms or curves. */
int (*cert_cb)(SSL *ssl, void *arg);
void *cert_cb_arg;
-
- /* Optional X509_STORE for chain building or certificate validation
- * If NULL the parent SSL_CTX store is used instead. */
- X509_STORE *chain_store;
- X509_STORE *verify_store;
} CERT;
-typedef struct sess_cert_st {
- STACK_OF(X509) *cert_chain; /* as received from peer (not for SSL2) */
-
- /* The 'peer_...' members are used only by clients. */
- int peer_cert_type;
-
- CERT_PKEY *peer_key; /* points to an element of peer_pkeys (never NULL!) */
- CERT_PKEY peer_pkeys[SSL_PKEY_NUM];
- /* Obviously we don't have the private keys of these,
- * so maybe we shouldn't even use the CERT_PKEY type here. */
-
- DH *peer_dh_tmp;
- EC_KEY *peer_ecdh_tmp;
-} SESS_CERT;
-
-/* Structure containing decoded values of signature algorithms extension */
-struct tls_sigalgs_st {
- /* NID of hash algorithm */
- int hash_nid;
- /* NID of signature algorithm */
- int sign_nid;
- /* Combined hash and signature NID */
- int signandhash_nid;
- /* Raw values used in extension */
- uint8_t rsign;
- uint8_t rhash;
-};
-
/* SSL_METHOD is a compatibility structure to support the legacy version-locked
* methods. */
struct ssl_method_st {
@@ -623,28 +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);
- long (*ssl_ctrl)(SSL *s, int cmd, long larg, void *parg);
- long (*ssl_ctx_ctrl)(SSL_CTX *ctx, int cmd, long larg, void *parg);
+ 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
@@ -668,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 */
@@ -683,9 +873,6 @@ struct ssl3_enc_method {
#define SSL_ENC_FLAG_SIGALGS 0x2
/* Uses SHA256 default PRF */
#define SSL_ENC_FLAG_SHA256_PRF 0x4
-/* Allow TLS 1.2 ciphersuites: applies to DTLS 1.2 as well as TLS 1.2:
- * may apply to others in future. */
-#define SSL_ENC_FLAG_TLS1_2_CIPHERS 0x8
/* lengths of messages */
#define DTLS1_COOKIE_LENGTH 256
@@ -698,15 +885,6 @@ struct ssl3_enc_method {
#define DTLS1_AL_HEADER_LENGTH 2
-typedef struct dtls1_bitmap_st {
- /* map is a bit mask of the last 64 sequence numbers. Bit
- * |1<<i| corresponds to |max_seq_num - i|. */
- uint64_t map;
- /* max_seq_num is the largest sequence number seen so far. It
- * is a 64-bit value in big-endian encoding. */
- uint8_t max_seq_num[8];
-} DTLS1_BITMAP;
-
/* TODO(davidben): This structure is used for both incoming messages and
* outgoing messages. |is_ccs| and |epoch| are only used in the latter and
* should be moved elsewhere. */
@@ -747,7 +925,9 @@ typedef struct dtls1_state_st {
/* records being received in the current epoch */
DTLS1_BITMAP bitmap;
- /* handshake message numbers */
+ /* handshake message numbers.
+ * TODO(davidben): It doesn't make much sense to store both of these. Only
+ * store one. */
uint16_t handshake_write_seq;
uint16_t next_handshake_write_seq;
@@ -783,130 +963,117 @@ 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;
extern const SSL3_ENC_METHOD TLSv1_1_enc_data;
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);
void ssl_cert_free(CERT *c);
-SESS_CERT *ssl_sess_cert_new(void);
-void ssl_sess_cert_free(SESS_CERT *sc);
-int ssl_set_peer_cert_type(SESS_CERT *c, int type);
-int ssl_get_new_session(SSL *s, int session);
-int ssl_get_prev_session(SSL *s, const struct ssl_early_callback_ctx *ctx);
-STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs);
-int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, uint8_t *p);
-struct ssl_cipher_preference_list_st *ssl_cipher_preference_list_dup(
- struct ssl_cipher_preference_list_st *cipher_list);
+int ssl_get_new_session(SSL *ssl, int is_server);
+
+enum ssl_session_result_t {
+ ssl_session_success,
+ ssl_session_error,
+ ssl_session_retry,
+};
+
+/* ssl_get_prev_session looks up the previous session based on |ctx|. On
+ * success, it sets |*out_session| to the session or NULL if none was found. It
+ * sets |*out_send_ticket| to whether a ticket should be sent at the end of the
+ * handshake. If the session could not be looked up synchronously, it returns
+ * |ssl_session_retry| and should be called again. Otherwise, it returns
+ * |ssl_session_error|. */
+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 *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);
-
-int ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain);
-int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain);
-int ssl_cert_add0_chain_cert(CERT *c, X509 *x);
-int ssl_cert_add1_chain_cert(CERT *c, X509 *x);
-int ssl_cert_select_current(CERT *c, X509 *x);
-void ssl_cert_set_cert_cb(CERT *c, int (*cb)(SSL *ssl, void *arg), void *arg);
-
-int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk);
-int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l);
-int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags);
-int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref);
-CERT_PKEY *ssl_get_server_send_pkey(const SSL *s);
-EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *c);
-void ssl_update_cache(SSL *s, int mode);
-int ssl_cert_type(EVP_PKEY *pkey);
+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);
+int ssl_cert_add0_chain_cert(CERT *cert, X509 *x509);
+int ssl_cert_add1_chain_cert(CERT *cert, X509 *x509);
+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 *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_init_finished_mac(SSL *s);
-int ssl3_send_server_certificate(SSL *s);
-int ssl3_send_new_session_ticket(SSL *s);
-int ssl3_send_cert_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
* have room for EVP_MAX_MD_SIZE bytes. For TLS 1.2 and up, |*out_md| is used
- * for the hash function, otherwise the hash function depends on the type of
- * |pkey| and is written to |*out_md|. It returns one on success and zero on
+ * 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,
- const EVP_MD **out_md, EVP_PKEY *pkey);
+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_finish_mac(SSL *s, const uint8_t *buf, int len);
-void ssl3_free_digest_list(SSL *s);
-int ssl3_output_cert_chain(SSL *s, CERT_PKEY *cpk);
+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_setup_read_buffer(SSL *s);
-int ssl3_setup_write_buffer(SSL *s);
-int ssl3_release_read_buffer(SSL *s);
-int ssl3_release_write_buffer(SSL *s);
-
-enum should_free_handshake_buffer_t {
- free_handshake_buffer,
- dont_free_handshake_buffer,
-};
-int ssl3_digest_cached_records(SSL *s, enum should_free_handshake_buffer_t);
-int ssl3_new(SSL *s);
-void ssl3_free(SSL *s);
-int ssl3_accept(SSL *s);
-int ssl3_connect(SSL *s);
-long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg);
-long ssl3_ctx_ctrl(SSL_CTX *s, int cmd, long larg, void *parg);
+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. */
@@ -914,135 +1081,119 @@ 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);
-
-enum dtls1_use_epoch_t {
- dtls1_use_previous_epoch,
- dtls1_use_current_epoch,
-};
+int ssl3_set_handshake_header(SSL *ssl, int htype, unsigned long len);
+int ssl3_handshake_write(SSL *ssl);
-int dtls1_do_write(SSL *s, int type, enum dtls1_use_epoch_t use_epoch);
-int ssl3_read_n(SSL *s, int n, int extend);
+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);
-int ssl3_write_pending(SSL *s, int type, const uint8_t *buf, unsigned int len);
-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 ccs);
-int dtls1_get_queue_priority(unsigned short seq, int is_ccs);
-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 *s);
-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_check_cert_and_algorithm(SSL *s);
-int ssl3_send_next_proto(SSL *s);
-int ssl3_send_channel_id(SSL *s);
-
-int dtls1_client_hello(SSL *s);
+int ssl3_send_client_hello(SSL *ssl);
+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 *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_send_server_hello(SSL *s);
-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_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 *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_get_record(SSL *s);
-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);
int tls1_alert_code(int code);
int ssl3_alert_code(int code);
-int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s);
-
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_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
@@ -1054,78 +1205,87 @@ 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);
-uint8_t *ssl_add_clienthello_tlsext(SSL *s, uint8_t *buf, uint8_t *limit,
- size_t header_len);
-uint8_t *ssl_add_serverhello_tlsext(SSL *s, uint8_t *buf, uint8_t *limit);
-int ssl_parse_clienthello_tlsext(SSL *s, CBS *cbs);
-int ssl_parse_serverhello_tlsext(SSL *s, CBS *cbs);
-int ssl_prepare_clienthello_tlsext(SSL *s);
-int ssl_prepare_serverhello_tlsext(SSL *s);
+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
+ * length of the ClientHello written so far and is used to compute the padding
+ * length. (It does not include the record header.) */
+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 *ssl, CBS *cbs);
+int ssl_parse_serverhello_tlsext(SSL *ssl, CBS *cbs);
#define tlsext_tick_md EVP_sha256
-int tls1_process_ticket(SSL *s, const struct ssl_early_callback_ctx *ctx,
- SSL_SESSION **ret);
-int tls12_get_sigandhash(uint8_t *p, const EVP_PKEY *pk, const EVP_MD *md);
-int tls12_get_sigid(const EVP_PKEY *pk);
+/* tls_process_ticket processes the session ticket extension. On success, it
+ * sets |*out_session| to the decrypted session or NULL if the ticket was
+ * rejected. It sets |*out_send_ticket| to whether a new ticket should be sent
+ * at the end of the handshake. It returns one on success and zero on fatal
+ * error. */
+int tls_process_ticket(SSL *ssl, SSL_SESSION **out_session,
+ int *out_send_ticket, const uint8_t *ticket,
+ size_t ticket_len, const uint8_t *session_id,
+ size_t session_id_len);
+
+/* 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_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);
-int tls1_channel_id_hash(EVP_MD_CTX *ctx, SSL *s);
-int tls1_record_handshake_hashes_for_channel_id(SSL *s);
+/* tls1_channel_id_hash computes the hash to be signed by Channel ID and writes
+ * it to |out|, which must contain at least |EVP_MAX_MD_SIZE| bytes. It returns
+ * one on success and zero on failure. */
+int tls1_channel_id_hash(SSL *ssl, uint8_t *out, size_t *out_len);
-int tls1_set_sigalgs_list(CERT *c, const char *str, int client);
-int tls1_set_sigalgs(CERT *c, const int *salg, size_t salglen, int client);
+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
@@ -1134,29 +1294,23 @@ 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);
-
-int ssl_add_serverhello_renegotiate_ext(SSL *s, uint8_t *p, int *len,
- int maxlen);
-int ssl_parse_serverhello_renegotiate_ext(SSL *s, CBS *cbs, int *out_alert);
-int ssl_add_clienthello_renegotiate_ext(SSL *s, uint8_t *p, int *len,
- int maxlen);
-int ssl_parse_clienthello_renegotiate_ext(SSL *s, CBS *cbs, int *out_alert);
-uint32_t ssl_get_algorithm2(SSL *s);
-int tls1_process_sigalgs(SSL *s, const CBS *sigalgs);
-
-/* tls1_choose_signing_digest returns a digest for use with |pkey| based on the
- * peer's preferences recorded for |s| and the digests supported by |pkey|. */
-const EVP_MD *tls1_choose_signing_digest(SSL *s, EVP_PKEY *pkey);
-
-size_t tls12_get_psigalgs(SSL *s, const uint8_t **psigs);
-int tls12_check_peer_sigalg(const EVP_MD **out_md, int *out_alert, SSL *s,
- CBS *cbs, EVP_PKEY *pkey);
-void ssl_set_client_disabled(SSL *s);
-
-int ssl_add_clienthello_use_srtp_ext(SSL *s, uint8_t *p, int *len, int maxlen);
-int ssl_parse_clienthello_use_srtp_ext(SSL *s, CBS *cbs, int *out_alert);
-int ssl_add_serverhello_use_srtp_ext(SSL *s, uint8_t *p, int *len, int maxlen);
-int ssl_parse_serverhello_use_srtp_ext(SSL *s, CBS *cbs, int *out_alert);
+uint16_t ssl3_version_from_wire(SSL *ssl, uint16_t wire_version);
+
+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 *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,
+ * writes the relevant digest into |*out_md| and returns 1. Otherwise it
+ * 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 *ssl);
#endif /* OPENSSL_HEADER_SSL_INTERNAL_H */
diff --git a/src/ssl/pqueue/CMakeLists.txt b/src/ssl/pqueue/CMakeLists.txt
index 53d2a8b..3a8b82b 100644
--- a/src/ssl/pqueue/CMakeLists.txt
+++ b/src/ssl/pqueue/CMakeLists.txt
@@ -17,3 +17,4 @@ add_executable(
)
target_link_libraries(pqueue_test ssl crypto)
+add_dependencies(all_tests pqueue_test)
diff --git a/src/ssl/pqueue/pqueue_test.c b/src/ssl/pqueue/pqueue_test.c
index 5a68fc4..f76e4a3 100644
--- a/src/ssl/pqueue/pqueue_test.c
+++ b/src/ssl/pqueue/pqueue_test.c
@@ -15,6 +15,7 @@
#include <stdio.h>
#include <string.h>
+#include <openssl/crypto.h>
#include <openssl/pqueue.h>
#include <openssl/ssl.h>
@@ -117,7 +118,7 @@ static int fixed_random(void) {
}
int main(void) {
- SSL_library_init();
+ CRYPTO_library_init();
if (!trivial() || !fixed_random()) {
return 1;
diff --git a/src/ssl/s3_both.c b/src/ssl/s3_both.c
index 06338b7..01a7e8c 100644
--- a/src/ssl/s3_both.c
+++ b/src/ssl/s3_both.c
@@ -110,6 +110,8 @@
* ECC cipher suite support in OpenSSL originally developed by
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <limits.h>
#include <stdio.h>
@@ -128,327 +130,316 @@
#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, ssl3_get_finished, 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;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_finished, SSL_R_BAD_DIGEST_LENGTH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_DIGEST_LENGTH);
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, ssl3_get_finished, SSL_R_DIGEST_CHECK_FAILED);
+ 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, CERT_PKEY *cpk) {
+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 (cpk == NULL) {
- /* TLSv1 sends a chain with nothing in it, instead of an alert. */
- if (!BUF_MEM_grow_clean(s->init_buf, l)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_output_cert_chain, ERR_R_BUF_LIB);
- return 0;
- }
- } else if (!ssl_add_cert_chain(s, cpk, &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, ssl3_get_message, SSL_R_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, ssl3_get_message, SSL_R_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) {
al = SSL_AD_ILLEGAL_PARAMETER;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_message, SSL_R_EXCESSIVE_MESSAGE_SIZE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE);
goto f_err;
}
- if (l && !BUF_MEM_grow_clean(s->init_buf, l + 4)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_message, ERR_R_BUF_LIB);
+ 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_finish_mac(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
@@ -456,63 +447,47 @@ 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,
- const EVP_MD **out_md, EVP_PKEY *pkey) {
+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)) {
- const uint8_t *hdata;
- size_t hdatalen;
+ if (SSL_USE_SIGALGS(ssl)) {
EVP_MD_CTX mctx;
unsigned len;
- if (!BIO_mem_contents(s->s3->handshake_buffer, &hdata, &hdatalen)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_cert_verify_hash, ERR_R_INTERNAL_ERROR);
- return 0;
- }
EVP_MD_CTX_init(&mctx);
if (!EVP_DigestInit_ex(&mctx, *out_md, NULL) ||
- !EVP_DigestUpdate(&mctx, hdata, hdatalen) ||
+ !EVP_DigestUpdate(&mctx, ssl->s3->handshake_buffer->data,
+ ssl->s3->handshake_buffer->length) ||
!EVP_DigestFinal(&mctx, out, &len)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_cert_verify_hash, ERR_R_EVP_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB);
EVP_MD_CTX_cleanup(&mctx);
return 0;
}
*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) {
+ } else if (pkey_type == EVP_PKEY_RSA) {
+ 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) {
+ } else if (pkey_type == EVP_PKEY_EC) {
+ if (ssl->enc_method->cert_verify_mac(ssl, NID_sha1, out) == 0) {
return 0;
}
*out_len = SHA_DIGEST_LENGTH;
*out_md = EVP_sha1();
} else {
- OPENSSL_PUT_ERROR(SSL, ssl3_cert_verify_hash, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}
-int ssl_cert_type(EVP_PKEY *pkey) {
- switch (pkey->type) {
- case EVP_PKEY_RSA:
- return SSL_PKEY_RSA_ENC;
- case EVP_PKEY_EC:
- return SSL_PKEY_ECC;
- default:
- return -1;
- }
-}
-
int ssl_verify_alarm_type(long type) {
int al;
@@ -581,92 +556,6 @@ int ssl_verify_alarm_type(long type) {
return al;
}
-int ssl3_setup_read_buffer(SSL *s) {
- uint8_t *p;
- size_t len, align = 0, headerlen;
-
- if (SSL_IS_DTLS(s)) {
- headerlen = DTLS1_RT_HEADER_LENGTH;
- } else {
- headerlen = SSL3_RT_HEADER_LENGTH;
- }
-
-#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0
- align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
-#endif
-
- if (s->s3->rbuf.buf == NULL) {
- len = SSL3_RT_MAX_ENCRYPTED_LENGTH + headerlen + align;
- if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) {
- s->s3->init_extra = 1;
- len += SSL3_RT_MAX_EXTRA;
- }
- p = OPENSSL_malloc(len);
- if (p == NULL) {
- goto err;
- }
- s->s3->rbuf.buf = p;
- s->s3->rbuf.len = len;
- }
-
- s->packet = &s->s3->rbuf.buf[0];
- return 1;
-
-err:
- OPENSSL_PUT_ERROR(SSL, ssl3_setup_read_buffer, ERR_R_MALLOC_FAILURE);
- return 0;
-}
-
-int ssl3_setup_write_buffer(SSL *s) {
- uint8_t *p;
- size_t len, align = 0, headerlen;
-
- if (SSL_IS_DTLS(s)) {
- headerlen = DTLS1_RT_HEADER_LENGTH + 1;
- } else {
- headerlen = SSL3_RT_HEADER_LENGTH;
- }
-
-#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0
- align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
-#endif
-
- if (s->s3->wbuf.buf == NULL) {
- len = s->max_send_fragment + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD +
- headerlen + align;
- /* Account for 1/n-1 record splitting. */
- if (s->mode & SSL_MODE_CBC_RECORD_SPLITTING) {
- len += headerlen + align + 1 + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
- }
-
- p = OPENSSL_malloc(len);
- if (p == NULL) {
- goto err;
- }
- s->s3->wbuf.buf = p;
- s->s3->wbuf.len = len;
- }
-
- return 1;
-
-err:
- OPENSSL_PUT_ERROR(SSL, ssl3_setup_write_buffer, ERR_R_MALLOC_FAILURE);
- return 0;
-}
-
-int ssl3_release_write_buffer(SSL *s) {
- OPENSSL_free(s->s3->wbuf.buf);
- s->s3->wbuf.buf = NULL;
- return 1;
-}
-
-int ssl3_release_read_buffer(SSL *s) {
- OPENSSL_free(s->s3->rbuf.buf);
- s->s3->rbuf.buf = NULL;
- s->packet = NULL;
- return 1;
-}
-
int ssl_fill_hello_random(uint8_t *out, size_t len, int is_server) {
if (is_server) {
const uint32_t current_time = time(NULL);
diff --git a/src/ssl/s3_clnt.c b/src/ssl/s3_clnt.c
index 159e2d7..5f68037 100644
--- a/src/ssl/s3_clnt.c
+++ b/src/ssl/s3_clnt.c
@@ -1,4 +1,3 @@
-/* ssl/s3_clnt.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -148,57 +147,62 @@
* OTHERWISE.
*/
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <stdio.h>
#include <string.h>
+#include <openssl/bn.h>
#include <openssl/buf.h>
#include <openssl/bytestring.h>
-#include <openssl/rand.h>
-#include <openssl/obj.h>
+#include <openssl/dh.h>
+#include <openssl/ec_key.h>
+#include <openssl/ecdsa.h>
#include <openssl/err.h>
#include <openssl/evp.h>
-#include <openssl/mem.h>
#include <openssl/md5.h>
-#include <openssl/dh.h>
-#include <openssl/bn.h>
+#include <openssl/mem.h>
+#include <openssl/obj.h>
+#include <openssl/rand.h>
#include <openssl/x509.h>
+#include <openssl/x509v3.h>
#include "internal.h"
#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 val) = 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)) {
@@ -206,121 +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_finished_mac(s)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_connect, ERR_R_INTERNAL_ERROR);
+ 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_CR_KEY_EXCH_A;
+ 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_CR_KEY_EXCH_A:
- case SSL3_ST_CR_KEY_EXCH_B:
- ret = ssl3_get_server_key_exchange(s);
+ case SSL3_ST_VERIFY_SERVER_CERT:
+ ret = ssl3_verify_server_cert(ssl);
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_CR_CERT_REQ_A;
- s->init_num = 0;
- /* at this point we check that we have the
- * required stuff from the server */
- if (!ssl3_check_cert_and_algorithm(s)) {
- ret = -1;
+ 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(ssl);
+ if (ret <= 0) {
goto end;
}
+ 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;
@@ -328,64 +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:
- ret = ssl3_send_cert_verify(s);
+ case SSL3_ST_CW_CERT_VRFY_C:
+ 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;
}
@@ -394,344 +400,353 @@ 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. */
- if (s->s3->tlsext_channel_id_new) {
- ret = tls1_record_handshake_hashes_for_channel_id(s);
- if (ret <= 0) {
- goto end;
- }
+ 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_CR_KEY_EXCH_A;
- 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);
- s->init_num = 0;
- s->s3->tmp.in_false_start = 0;
- s->s3->initial_handshake_complete = 1;
+ const int is_initial_handshake = !ssl->s3->initial_handshake_complete;
- ssl_update_cache(s, SSL_SESS_CACHE_CLIENT);
+ 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(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;
default:
- OPENSSL_PUT_ERROR(SSL, ssl3_connect, SSL_R_UNKNOWN_STATE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_STATE);
ret = -1;
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;
}
-int ssl3_send_client_hello(SSL *s) {
- uint8_t *buf, *p, *d;
- int i;
- unsigned long l;
-
- buf = (uint8_t *)s->init_buf->data;
- if (s->state == SSL3_ST_CW_CLNT_HELLO_A) {
- if (!s->s3->have_version) {
- uint16_t max_version = ssl3_get_max_client_version(s);
- /* Disabling all versions is silly: return an error. */
- if (max_version == 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_hello, SSL_R_WRONG_SSL_VERSION);
- goto err;
- }
- s->version = max_version;
- s->client_version = max_version;
- }
+static int ssl3_write_client_cipher_list(SSL *ssl, CBB *out) {
+ /* Prepare disabled cipher masks. */
+ ssl_set_client_disabled(ssl);
- /* If the configured session was created at a version higher than our
- * maximum version, drop it. */
- if (s->session &&
- (s->session->session_id_length == 0 || s->session->not_resumable ||
- (!SSL_IS_DTLS(s) && s->session->ssl_version > s->version) ||
- (SSL_IS_DTLS(s) && s->session->ssl_version < s->version))) {
- SSL_set_session(s, NULL);
- }
+ CBB child;
+ if (!CBB_add_u16_length_prefixed(out, &child)) {
+ return 0;
+ }
- /* else use the pre-loaded session */
- p = s->s3->client_random;
+ STACK_OF(SSL_CIPHER) *ciphers = SSL_get_ciphers(ssl);
- /* If resending the ClientHello in DTLS after a HelloVerifyRequest, don't
- * renegerate the client_random. The random must be reused. */
- if ((!SSL_IS_DTLS(s) || !s->d1->send_cookie) &&
- !ssl_fill_hello_random(p, sizeof(s->s3->client_random),
- 0 /* client */)) {
- goto err;
+ int any_enabled = 0;
+ size_t i;
+ for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
+ const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
+ /* Skip disabled ciphers */
+ if ((cipher->algorithm_mkey & ssl->cert->mask_k) ||
+ (cipher->algorithm_auth & ssl->cert->mask_a)) {
+ continue;
}
-
- /* Do the message type and length last. Note: the final argument to
- * ssl_add_clienthello_tlsext below depends on the size of this prefix. */
- d = p = ssl_handshake_start(s);
-
- /* version indicates the negotiated version: for example from an SSLv2/v3
- * compatible client hello). The client_version field is the maximum
- * version we permit and it is also used in RSA encrypted premaster
- * secrets. Some servers can choke if we initially report a higher version
- * then renegotiate to a lower one in the premaster secret. This didn't
- * happen with TLS 1.0 as most servers supported it but it can with TLS 1.1
- * or later if the server only supports 1.0.
- *
- * Possible scenario with previous logic:
- * 1. Client hello indicates TLS 1.2
- * 2. Server hello says TLS 1.0
- * 3. RSA encrypted premaster secret uses 1.2.
- * 4. Handhaked proceeds using TLS 1.0.
- * 5. Server sends hello request to renegotiate.
- * 6. Client hello indicates TLS v1.0 as we now
- * know that is maximum server supports.
- * 7. Server chokes on RSA encrypted premaster secret
- * containing version 1.0.
- *
- * For interoperability it should be OK to always use the maximum version
- * we support in client hello and then rely on the checking of version to
- * ensure the servers isn't being inconsistent: for example initially
- * negotiating with TLS 1.0 and renegotiating with TLS 1.2. We do this by
- * using client_version in client hello and not resetting it to the
- * negotiated version. */
- *(p++) = s->client_version >> 8;
- *(p++) = s->client_version & 0xff;
-
- /* Random stuff */
- memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE);
- p += SSL3_RANDOM_SIZE;
-
- /* Session ID */
- if (s->s3->initial_handshake_complete || s->session == NULL) {
- /* Renegotiations do not participate in session resumption. */
- i = 0;
- } else {
- i = s->session->session_id_length;
+ if (SSL_CIPHER_get_min_version(cipher) >
+ ssl3_version_from_wire(ssl, ssl->client_version)) {
+ continue;
}
- *(p++) = i;
- if (i != 0) {
- if (i > (int)sizeof(s->session->session_id)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_hello, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- memcpy(p, s->session->session_id, i);
- p += i;
+ any_enabled = 1;
+ if (!CBB_add_u16(&child, ssl_cipher_get_value(cipher))) {
+ return 0;
}
+ }
- /* cookie stuff for DTLS */
- if (SSL_IS_DTLS(s)) {
- if (s->d1->cookie_len > sizeof(s->d1->cookie)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_hello, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- *(p++) = s->d1->cookie_len;
- memcpy(p, s->d1->cookie, s->d1->cookie_len);
- p += s->d1->cookie_len;
- }
+ /* If all ciphers were disabled, return the error to the caller. */
+ if (!any_enabled) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHERS_AVAILABLE);
+ return 0;
+ }
- /* Ciphers supported */
- i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &p[2]);
- if (i == 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_hello,
- SSL_R_NO_CIPHERS_AVAILABLE);
- goto err;
+ /* For SSLv3, the SCSV is added. Otherwise the renegotiation extension is
+ * added. */
+ if (ssl->client_version == SSL3_VERSION &&
+ !ssl->s3->initial_handshake_complete) {
+ if (!CBB_add_u16(&child, SSL3_CK_SCSV & 0xffff)) {
+ return 0;
}
- s2n(i, p);
- p += i;
+ /* The renegotiation extension is required to be at index zero. */
+ ssl->s3->tmp.extensions.sent |= (1u << 0);
+ }
- /* COMPRESSION */
- *(p++) = 1;
- *(p++) = 0; /* Add the NULL method */
+ if ((ssl->mode & SSL_MODE_SEND_FALLBACK_SCSV) &&
+ !CBB_add_u16(&child, SSL3_CK_FALLBACK_SCSV & 0xffff)) {
+ return 0;
+ }
- /* TLS extensions*/
- if (ssl_prepare_clienthello_tlsext(s) <= 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_hello, SSL_R_CLIENTHELLO_TLSEXT);
- goto err;
- }
+ return CBB_flush(out);
+}
- p = ssl_add_clienthello_tlsext(s, p, buf + SSL3_RT_MAX_PLAIN_LENGTH,
- p - buf);
- if (p == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_hello, ERR_R_INTERNAL_ERROR);
+int ssl3_send_client_hello(SSL *ssl) {
+ if (ssl->state == SSL3_ST_CW_CLNT_HELLO_B) {
+ return ssl_do_write(ssl);
+ }
+
+ /* In DTLS, reset the handshake buffer each time a new ClientHello is
+ * assembled. We may send multiple if we receive HelloVerifyRequest. */
+ if (SSL_IS_DTLS(ssl) && !ssl3_init_handshake_buffer(ssl)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+
+ CBB cbb;
+ CBB_zero(&cbb);
+
+ assert(ssl->state == SSL3_ST_CW_CLNT_HELLO_A);
+ if (!ssl->s3->have_version) {
+ uint16_t max_version = ssl3_get_max_client_version(ssl);
+ /* Disabling all versions is silly: return an error. */
+ if (max_version == 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SSL_VERSION);
goto err;
}
- l = p - d;
- if (!ssl_set_handshake_header(s, SSL3_MT_CLIENT_HELLO, l)) {
+ ssl->version = max_version;
+ /* Only set |ssl->client_version| on the initial handshake. Renegotiations,
+ * although locked to a version, reuse the value. When using the plain RSA
+ * key exchange, the ClientHello version is checked in the premaster secret.
+ * Some servers fail when this value changes. */
+ ssl->client_version = max_version;
+ }
+
+ /* If the configured session has expired or was created at a version higher
+ * than our maximum version, drop it. */
+ if (ssl->session != NULL &&
+ (ssl->session->session_id_length == 0 || ssl->session->not_resumable ||
+ ssl->session->timeout < (long)(time(NULL) - ssl->session->time) ||
+ (!SSL_IS_DTLS(ssl) && ssl->session->ssl_version > ssl->version) ||
+ (SSL_IS_DTLS(ssl) && ssl->session->ssl_version < ssl->version))) {
+ SSL_set_session(ssl, NULL);
+ }
+
+ /* If resending the ClientHello in DTLS after a HelloVerifyRequest, don't
+ * renegerate the client_random. The random must be reused. */
+ if ((!SSL_IS_DTLS(ssl) || !ssl->d1->send_cookie) &&
+ !ssl_fill_hello_random(ssl->s3->client_random,
+ sizeof(ssl->s3->client_random), 0 /* client */)) {
+ goto err;
+ }
+
+ /* Renegotiations do not participate in session resumption. */
+ int has_session = ssl->session != NULL &&
+ !ssl->s3->initial_handshake_complete;
+
+ CBB child;
+ if (!CBB_init_fixed(&cbb, ssl_handshake_start(ssl),
+ ssl->init_buf->max - SSL_HM_HEADER_LENGTH(ssl)) ||
+ !CBB_add_u16(&cbb, ssl->client_version) ||
+ !CBB_add_bytes(&cbb, ssl->s3->client_random, SSL3_RANDOM_SIZE) ||
+ !CBB_add_u8_length_prefixed(&cbb, &child) ||
+ (has_session &&
+ !CBB_add_bytes(&child, ssl->session->session_id,
+ ssl->session->session_id_length))) {
+ goto err;
+ }
+
+ if (SSL_IS_DTLS(ssl)) {
+ if (!CBB_add_u8_length_prefixed(&cbb, &child) ||
+ !CBB_add_bytes(&child, ssl->d1->cookie, ssl->d1->cookie_len)) {
goto err;
}
- s->state = SSL3_ST_CW_CLNT_HELLO_B;
}
- /* SSL3_ST_CW_CLNT_HELLO_B */
- return ssl_do_write(s);
+ size_t length;
+ if (!ssl3_write_client_cipher_list(ssl, &cbb) ||
+ !CBB_add_u8(&cbb, 1 /* one compression method */) ||
+ !CBB_add_u8(&cbb, 0 /* null compression */) ||
+ !ssl_add_clienthello_tlsext(ssl, &cbb,
+ CBB_len(&cbb) + SSL_HM_HEADER_LENGTH(ssl)) ||
+ !CBB_finish(&cbb, NULL, &length) ||
+ !ssl_set_handshake_header(ssl, SSL3_MT_CLIENT_HELLO, length)) {
+ goto err;
+ }
+
+ ssl->state = SSL3_ST_CW_CLNT_HELLO_B;
+ return ssl_do_write(ssl);
err:
+ CBB_cleanup(&cbb);
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;
- uint32_t mask_ssl;
- 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);
@@ -746,13 +761,12 @@ int ssl3_get_server_hello(SSL *s) {
* parameters. Note: this error code comes after the original one.
*
* See https://crbug.com/446505. */
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello,
- SSL_R_HANDSHAKE_FAILURE_ON_CLIENT_HELLO);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_FAILURE_ON_CLIENT_HELLO);
}
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) ||
@@ -761,129 +775,123 @@ int ssl3_get_server_hello(SSL *s) {
!CBS_get_u16(&server_hello, &cipher_suite) ||
!CBS_get_u8(&server_hello, &compression_method)) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
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)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_UNSUPPORTED_PROTOCOL);
- s->version = 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);
+ 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) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_WRONG_SSL_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, ssl3_get_server_hello,
+ 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)) {
+ 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);
if (c == NULL) {
/* unknown cipher */
al = SSL_AD_ILLEGAL_PARAMETER;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello,
- SSL_R_UNKNOWN_CIPHER_RETURNED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CIPHER_RETURNED);
goto f_err;
}
- /* ct->mask_ssl was computed from client capabilities. Now
- * that the final version is known, compute a new mask_ssl. */
- if (!SSL_USE_TLS1_2_CIPHERS(s)) {
- mask_ssl = SSL_TLSV1_2;
- } else {
- mask_ssl = 0;
- }
/* 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_ssl & mask_ssl) ||
- (c->algorithm_mkey & ct->mask_k) ||
- (c->algorithm_auth & ct->mask_a)) {
+ 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, ssl3_get_server_hello, SSL_R_WRONG_CIPHER_RETURNED);
+ 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;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_WRONG_CIPHER_RETURNED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED);
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, ssl3_get_server_hello,
- SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);
+ 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, ssl3_get_server_hello,
- SSL_R_OLD_SESSION_VERSION_NOT_RETURNED);
+ 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(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, release the handshake buffer. */
- if ((!SSL_USE_SIGALGS(s) || s->hit) &&
- !ssl3_digest_cached_records(s, free_handshake_buffer)) {
- goto f_err;
+ * different hash. Otherwise, the handshake buffer may be released. */
+ if (!SSL_USE_SIGALGS(ssl) || ssl->hit) {
+ ssl3_free_handshake_buffer(ssl);
}
/* Only the NULL compression algorithm is supported. */
if (compression_method != 0) {
al = SSL_AD_ILLEGAL_PARAMETER;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello,
- SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
goto f_err;
}
/* TLS extensions */
- if (!ssl_parse_serverhello_tlsext(s, &server_hello)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_PARSE_TLSEXT);
+ if (!ssl_parse_serverhello_tlsext(ssl, &server_hello)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT);
goto err;
}
@@ -891,19 +899,18 @@ int ssl3_get_server_hello(SSL *s) {
if (CBS_len(&server_hello) != 0) {
/* wrong packet length */
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_BAD_PACKET_LENGTH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_PACKET_LENGTH);
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) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello,
- SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION);
+ if (ssl->session->extended_master_secret) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION);
} else {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello,
- SSL_R_RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION);
}
goto f_err;
}
@@ -911,41 +918,84 @@ 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;
}
-int ssl3_get_server_certificate(SSL *s) {
- int al, i, ok, ret = -1;
+/* 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) {
+ goto err;
+ }
+
+ /* 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) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CERTIFICATE_TYPE);
+ goto err;
+ }
+
+ 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) &&
+ !(leaf->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE)) {
+ 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;
+
+err:
+ EVP_PKEY_free(pkey);
+ return ret;
+}
+
+int ssl3_get_server_certificate(SSL *ssl) {
+ int al, ok, ret = -1;
unsigned long n;
X509 *x = NULL;
STACK_OF(X509) *sk = NULL;
- SESS_CERT *sc;
EVP_PKEY *pkey = NULL;
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) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!CBS_get_u24_length_prefixed(&cbs, &certificate_list) ||
+ CBS_len(&certificate_list) == 0 ||
CBS_len(&cbs) != 0) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, SSL_R_LENGTH_MISMATCH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
@@ -953,97 +1003,51 @@ int ssl3_get_server_certificate(SSL *s) {
CBS certificate;
if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate)) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate,
- SSL_R_CERT_LENGTH_MISMATCH);
+ 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, ssl3_get_server_certificate, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
goto f_err;
}
if (data != CBS_data(&certificate) + CBS_len(&certificate)) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate,
- SSL_R_CERT_LENGTH_MISMATCH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH);
goto f_err;
}
if (!sk_X509_push(sk, x)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
x = NULL;
}
- i = ssl_verify_cert_chain(s, sk);
- if (s->verify_mode != SSL_VERIFY_NONE && i <= 0) {
- al = ssl_verify_alarm_type(s->verify_result);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate,
- SSL_R_CERTIFICATE_VERIFY_FAILED);
+ X509 *leaf = sk_X509_value(sk, 0);
+ if (!ssl3_check_leaf_certificate(ssl, leaf)) {
+ al = SSL_AD_ILLEGAL_PARAMETER;
goto f_err;
}
- ERR_clear_error(); /* but we keep s->verify_result */
- sc = ssl_sess_cert_new();
- if (sc == NULL) {
- goto err;
- }
-
- ssl_sess_cert_free(s->session->sess_cert);
- s->session->sess_cert = sc;
-
- sc->cert_chain = sk;
- /* Inconsistency alert: cert_chain does include the peer's certificate, which
- * we don't include in s3_srvr.c */
- x = sk_X509_value(sk, 0);
+ /* NOTE: Unlike the server half, the client's copy of |cert_chain| includes
+ * the leaf. */
+ sk_X509_pop_free(ssl->session->cert_chain, X509_free);
+ ssl->session->cert_chain = sk;
sk = NULL;
- /* VRS 19990621: possible memory leak; sk=null ==> !sk_pop_free() @end*/
-
- pkey = X509_get_pubkey(x);
-
- if (pkey == NULL || EVP_PKEY_missing_parameters(pkey)) {
- x = NULL;
- al = SSL3_AL_FATAL;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate,
- SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS);
- goto f_err;
- }
-
- i = ssl_cert_type(pkey);
- if (i < 0) {
- x = NULL;
- al = SSL3_AL_FATAL;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate,
- SSL_R_UNKNOWN_CERTIFICATE_TYPE);
- goto f_err;
- }
- int exp_idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher);
- if (exp_idx >= 0 && i != exp_idx) {
- x = NULL;
- al = SSL_AD_ILLEGAL_PARAMETER;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate,
- SSL_R_WRONG_CERTIFICATE_TYPE);
- goto f_err;
- }
- sc->peer_cert_type = i;
- X509_free(sc->peer_pkeys[i].x509);
- sc->peer_pkeys[i].x509 = X509_up_ref(x);
- sc->peer_key = &(sc->peer_pkeys[i]);
+ X509_free(ssl->session->peer);
+ ssl->session->peer = X509_up_ref(leaf);
- X509_free(s->session->peer);
- s->session->peer = X509_up_ref(x);
+ ssl->session->verify_result = ssl->verify_result;
- s->session->verify_result = s->verify_result;
-
- x = NULL;
ret = 1;
if (0) {
f_err:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
}
err:
@@ -1053,76 +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)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
- SSL_R_UNEXPECTED_MESSAGE);
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ 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(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
return -1;
}
- /* In plain PSK ciphersuite, ServerKeyExchange can be
- omitted if no identity hint is sent. Set session->sess_cert anyway to
- avoid problems later.*/
- if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aPSK) {
- /* PSK ciphersuites that also send a Certificate would have already
- * initialized |sess_cert|. */
- if (s->session->sess_cert == NULL) {
- s->session->sess_cert = ssl_sess_cert_new();
- if (s->session->sess_cert == NULL) {
- return -1;
- }
- }
-
+ /* In plain PSK ciphersuite, ServerKeyExchange may be omitted to send no
+ * identity hint. */
+ 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;
- if (s->session->sess_cert != NULL) {
- DH_free(s->session->sess_cert->peer_dh_tmp);
- s->session->sess_cert->peer_dh_tmp = NULL;
- EC_KEY_free(s->session->sess_cert->peer_ecdh_tmp);
- s->session->sess_cert->peer_ecdh_tmp = NULL;
- } else {
- s->session->sess_cert = ssl_sess_cert_new();
- if (s->session->sess_cert == NULL) {
- return -1;
- }
- }
-
- 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) {
@@ -1132,7 +1111,7 @@ int ssl3_get_server_key_exchange(SSL *s) {
if (!CBS_get_u16_length_prefixed(&server_key_exchange,
&psk_identity_hint)) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
@@ -1146,23 +1125,20 @@ int ssl3_get_server_key_exchange(SSL *s) {
if (CBS_len(&psk_identity_hint) > PSK_MAX_IDENTITY_LEN ||
CBS_contains_zero_byte(&psk_identity_hint)) {
al = SSL_AD_HANDSHAKE_FAILURE;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
- SSL_R_DATA_LENGTH_TOO_LONG);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
goto f_err;
}
/* 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, ssl3_get_server_key_exchange,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto f_err;
}
}
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) ||
@@ -1170,113 +1146,78 @@ int ssl3_get_server_key_exchange(SSL *s) {
!CBS_get_u16_length_prefixed(&server_key_exchange, &dh_Ys) ||
CBS_len(&dh_Ys) == 0) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
dh = DH_new();
if (dh == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, 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, ssl3_get_server_key_exchange, 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;
}
- if (DH_num_bits(dh) < 1024) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
- SSL_R_BAD_DH_P_LENGTH);
+ 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;
}
- if (alg_a & SSL_aRSA) {
- pkey = X509_get_pubkey(
- s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
- }
- /* else anonymous DH, so no certificate or pkey. */
-
- s->session->sess_cert->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, ssl3_get_server_key_exchange, 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, ssl3_get_server_key_exchange,
- 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);
- if (ecdh == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
- 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, ssl3_get_server_key_exchange, 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, ssl3_get_server_key_exchange,
- 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, ssl3_get_server_key_exchange, SSL_R_BAD_ECPOINT);
- goto f_err;
- }
-
- /* The ECC/TLS specification does not mention the use of DSA to sign
- * ECParameters in the server key exchange message. We do support RSA and
- * ECDSA. */
- if (alg_a & SSL_aRSA) {
- pkey = X509_get_pubkey(
- s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
- } else if (alg_a & SSL_aECDSA) {
- pkey =
- X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_ECC].x509);
- }
- /* else anonymous ECDH, so no certificate or pkey. */
- EC_KEY_set_public_key(ecdh, srvr_ecpoint);
- s->session->sess_cert->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, ssl3_get_server_key_exchange,
- SSL_R_UNEXPECTED_MESSAGE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
goto f_err;
}
@@ -1286,14 +1227,25 @@ int ssl3_get_server_key_exchange(SSL *s) {
CBS_init(&parameter, CBS_data(&server_key_exchange_orig),
CBS_len(&server_key_exchange_orig) - CBS_len(&server_key_exchange));
- /* if it was signed, check the signature */
- if (pkey != NULL) {
- CBS signature;
+ /* ServerKeyExchange should be signed by the server's public key. */
+ 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 (!tls12_check_peer_sigalg(&md, &al, s, &server_key_exchange, pkey)) {
+ if (SSL_USE_SIGALGS(ssl)) {
+ uint8_t hash, signature;
+ if (!CBS_get_u8(&server_key_exchange, &hash) ||
+ !CBS_get_u8(&server_key_exchange, &signature)) {
+ al = SSL_AD_DECODE_ERROR;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
+ goto f_err;
+ }
+ if (!tls12_check_peer_sigalg(ssl, &md, &al, hash, signature, pkey)) {
goto f_err;
}
+ ssl->s3->tmp.server_key_exchange_hash = hash;
} else if (pkey->type == EVP_PKEY_RSA) {
md = EVP_md5_sha1();
} else {
@@ -1301,17 +1253,18 @@ int ssl3_get_server_key_exchange(SSL *s) {
}
/* The last field in |server_key_exchange| is the signature. */
+ CBS signature;
if (!CBS_get_u16_length_prefixed(&server_key_exchange, &signature) ||
CBS_len(&server_key_exchange) != 0) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
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)) ||
@@ -1319,24 +1272,16 @@ int ssl3_get_server_key_exchange(SSL *s) {
CBS_len(&signature))) {
/* bad signature */
al = SSL_AD_DECRYPT_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_BAD_SIGNATURE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE);
goto f_err;
}
} else {
- if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) {
- /* Might be wrong key type, check it */
- if (ssl3_check_cert_and_algorithm(s)) {
- /* Otherwise this shouldn't happen */
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
- ERR_R_INTERNAL_ERROR);
- }
- goto err;
- }
- /* still data left over */
+ /* PSK ciphers are the only supported certificate-less ciphers. */
+ assert(alg_a == SSL_aPSK);
+
if (CBS_len(&server_key_exchange) > 0) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
- SSL_R_EXTRA_DATA_IN_MESSAGE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_EXTRA_DATA_IN_MESSAGE);
goto f_err;
}
}
@@ -1345,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);
@@ -1361,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;
@@ -1371,75 +1314,65 @@ 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 we get here we don't need any cached handshake records as we wont be
- * doing client auth. */
- if (s->s3->handshake_buffer &&
- !ssl3_digest_cached_records(s, free_handshake_buffer)) {
- goto err;
- }
+ 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(ssl);
return 1;
}
- if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_REQUEST) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request,
- SSL_R_WRONG_MESSAGE_TYPE);
+ 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) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
/* get the certificate types */
if (!CBS_get_u8_length_prefixed(&cbs, &certificate_types)) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, SSL_R_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)) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, SSL_R_DECODE_ERROR);
- goto err;
- }
-
- if (!tls1_process_sigalgs(s, &supported_signature_algorithms)) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request,
- SSL_R_SIGNATURE_ALGORITHMS_ERROR);
+ if (!CBS_get_u16_length_prefixed(&cbs, &supported_signature_algorithms) ||
+ !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;
}
}
/* get the CA RDNs */
if (!CBS_get_u16_length_prefixed(&cbs, &certificate_authorities)) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, SSL_R_LENGTH_MISMATCH);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_LENGTH_MISMATCH);
goto err;
}
@@ -1447,45 +1380,43 @@ 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);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request,
- SSL_R_CA_DN_TOO_LONG);
+ 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);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, ERR_R_ASN1_LIB);
+ 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);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, ERR_R_INTERNAL_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);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request,
- SSL_R_CA_DN_LENGTH_MISMATCH);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CA_DN_LENGTH_MISMATCH);
goto err;
}
if (!sk_X509_NAME_push(ca_sk, xn)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
/* 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;
@@ -1495,102 +1426,130 @@ err:
return ret;
}
-int ssl3_get_new_session_ticket(SSL *s) {
+int ssl3_get_new_session_ticket(SSL *ssl) {
int ok, al;
- long n;
- CBS new_session_ticket, ticket;
-
- 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) {
return n;
}
- CBS_init(&new_session_ticket, s->init_msg, n);
-
- if (!CBS_get_u32(&new_session_ticket,
- &s->session->tlsext_tick_lifetime_hint) ||
+ CBS new_session_ticket, ticket;
+ uint32_t ticket_lifetime_hint;
+ 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) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_new_session_ticket, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
- if (!CBS_stow(&ticket, &s->session->tlsext_tick,
- &s->session->tlsext_ticklen)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_new_session_ticket, ERR_R_MALLOC_FAILURE);
+ if (CBS_len(&ticket) == 0) {
+ /* RFC 5077 allows a server to change its mind and send no ticket after
+ * negotiating the extension. The value of |tlsext_ticket_expected| is
+ * checked in |ssl_update_cache| so is cleared here to avoid an unnecessary
+ * update. */
+ ssl->tlsext_ticket_expected = 0;
+ return 1;
+ }
+
+ 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(ssl->session, &bytes, &bytes_len)) {
+ goto err;
+ }
+ SSL_SESSION *new_session = SSL_SESSION_from_bytes(bytes, bytes_len);
+ OPENSSL_free(bytes);
+ if (new_session == NULL) {
+ /* This should never happen. */
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
+ SSL_SESSION_free(ssl->session);
+ ssl->session = new_session;
+ }
+
+ if (!CBS_stow(&ticket, &ssl->session->tlsext_tick,
+ &ssl->session->tlsext_ticklen)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
+ 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) ||
CBS_len(&ocsp_response) == 0 ||
CBS_len(&certificate_status) != 0) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_status, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
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, ssl3_get_cert_status, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto f_err;
}
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);
@@ -1601,783 +1560,534 @@ 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);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_done, SSL_R_LENGTH_MISMATCH);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_LENGTH_MISMATCH);
return -1;
}
return 1;
}
+OPENSSL_COMPILE_ASSERT(sizeof(size_t) >= sizeof(unsigned),
+ SIZE_T_IS_SMALLER_THAN_UNSIGNED);
+
+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);
-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];
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, ssl3_send_client_key_exchange,
- 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, ssl3_send_client_key_exchange,
- ERR_R_INTERNAL_ERROR);
- goto err;
- } else if (psk_len == 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- SSL_R_PSK_IDENTITY_NOT_FOUND);
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
- goto err;
- }
-
- identity_len = OPENSSL_strnlen(identity, sizeof(identity));
- if (identity_len > PSK_MAX_IDENTITY_LEN) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_INTERNAL_ERROR);
- goto err;
- }
+ uint32_t alg_k = ssl->s3->tmp.new_cipher->algorithm_mkey;
+ uint32_t alg_a = ssl->s3->tmp.new_cipher->algorithm_auth;
- OPENSSL_free(s->session->psk_identity);
- s->session->psk_identity = BUF_strdup(identity);
- if (s->session->psk_identity == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
- 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;
+ }
- /* Write out psk_identity. */
- s2n(identity_len, p);
- memcpy(p, identity, identity_len);
- p += identity_len;
- n = 2 + identity_len;
+ 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);
- /* Depending on the key exchange method, compute |pms| and |pms_len|. */
- if (alg_k & SSL_kRSA) {
- RSA *rsa;
- size_t enc_pms_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;
+ }
- pms_len = SSL_MAX_MASTER_KEY_LENGTH;
- pms = OPENSSL_malloc(pms_len);
- if (pms == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
- goto err;
- }
+ /* 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;
+ }
+ }
- if (s->session->sess_cert == NULL) {
- /* We should always have a server certificate with SSL_kRSA. */
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_INTERNAL_ERROR);
- 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->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
- if (pkey == NULL ||
- pkey->type != EVP_PKEY_RSA ||
- pkey->pkey.rsa == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_INTERNAL_ERROR);
- EVP_PKEY_free(pkey);
- goto err;
- }
+ EVP_PKEY *pkey = X509_get_pubkey(ssl->session->peer);
+ if (pkey == NULL) {
+ goto err;
+ }
- 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, ssl3_send_client_key_exchange,
- 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;
- SESS_CERT *scert = s->session->sess_cert;
- int dh_len;
- size_t pub_len;
-
- if (scert == NULL) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- SSL_R_UNEXPECTED_MESSAGE);
- goto err;
- }
-
- if (scert->peer_dh_tmp == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_INTERNAL_ERROR);
- goto err;
- }
- dh_srvr = scert->peer_dh_tmp;
-
- /* generate a new random key */
- dh_clnt = DHparams_dup(dh_srvr);
- if (dh_clnt == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_DH_LIB);
- goto err;
- }
- if (!DH_generate_key(dh_clnt)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, 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, ssl3_send_client_key_exchange,
- 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, ssl3_send_client_key_exchange, 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 field_size = 0, ecdh_len;
-
- if (s->session->sess_cert == NULL) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- SSL_R_UNEXPECTED_MESSAGE);
- goto err;
- }
-
- if (s->session->sess_cert->peer_ecdh_tmp == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
- tkey = s->session->sess_cert->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, ssl3_send_client_key_exchange,
- ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
- clnt_ecdh = EC_KEY_new();
- if (clnt_ecdh == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- if (!EC_KEY_set_group(clnt_ecdh, srvr_group)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_EC_LIB);
- goto err;
- }
-
- /* Generate a new ECDH key pair */
- if (!EC_KEY_generate_key(clnt_ecdh)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_ECDH_LIB);
- goto err;
- }
-
- field_size = EC_GROUP_get_degree(srvr_group);
- if (field_size <= 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, 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, ssl3_send_client_key_exchange,
- 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, ssl3_send_client_key_exchange, 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, ssl3_send_client_key_exchange,
- 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, ssl3_send_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
- goto err;
- }
- memset(pms, 0, pms_len);
- } else {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_INTERNAL_ERROR);
+ 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 {
+ child_ok = CBB_add_u16_length_prefixed(&cbb, &child);
+ }
- /* 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;
+ if (!child_ok ||
+ !SSL_ECDH_CTX_generate_keypair(&ssl->s3->tmp.ecdh_ctx, &child) ||
+ !CBB_flush(&cbb)) {
+ goto err;
+ }
- if (!CBB_init(&cbb, 2 + psk_len + 2 + pms_len)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
- goto err;
- }
- if (!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, ssl3_send_client_key_exchange,
- ERR_R_INTERNAL_ERROR);
- 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) {
- uint8_t *buf, *p;
- const EVP_MD *md = NULL;
- uint8_t digest[EVP_MAX_MD_SIZE];
- size_t digest_length;
- EVP_PKEY *pkey;
- EVP_PKEY_CTX *pctx = NULL;
- size_t signature_length = 0;
- unsigned long n = 0;
-
- buf = (uint8_t *)s->init_buf->data;
-
- if (s->state == SSL3_ST_CW_CERT_VRFY_A) {
- p = ssl_handshake_start(s);
- pkey = s->cert->key->privatekey;
-
- /* Write out the digest type if needbe. */
- if (SSL_USE_SIGALGS(s)) {
- md = tls1_choose_signing_digest(s, pkey);
- if (!tls12_get_sigandhash(p, pkey, md)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_cert_verify, ERR_R_INTERNAL_ERROR);
+int ssl3_send_cert_verify(SSL *ssl) {
+ if (ssl->state == SSL3_ST_CW_CERT_VRFY_C) {
+ return ssl_do_write(ssl);
+ }
+
+ CBB cbb, child;
+ if (!CBB_init_fixed(&cbb, ssl_handshake_start(ssl),
+ ssl->init_buf->max - SSL_HM_HEADER_LENGTH(ssl))) {
+ goto err;
+ }
+
+ assert(ssl_has_private_key(ssl));
+
+ 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;
}
- p += 2;
- n += 2;
}
- /* Compute the digest. */
- if (!ssl3_cert_verify_hash(s, digest, &digest_length, &md, pkey)) {
+ /* 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;
}
/* The handshake buffer is no longer necessary. */
- if (s->s3->handshake_buffer &&
- !ssl3_digest_cached_records(s, free_handshake_buffer)) {
- goto err;
- }
+ ssl3_free_handshake_buffer(ssl);
/* Sign the digest. */
- pctx = EVP_PKEY_CTX_new(pkey, NULL);
- if (pctx == NULL) {
+ uint8_t *ptr;
+ if (!CBB_add_u16_length_prefixed(&cbb, &child) ||
+ !CBB_reserve(&child, &ptr, max_sig_len)) {
goto err;
}
-
- /* Initialize the EVP_PKEY_CTX and determine the size of the signature. */
- if (!EVP_PKEY_sign_init(pctx) || !EVP_PKEY_CTX_set_signature_md(pctx, md) ||
- !EVP_PKEY_sign(pctx, NULL, &signature_length, digest, digest_length)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_cert_verify, ERR_R_EVP_LIB);
+ 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);
+ }
- if (p + 2 + signature_length > buf + SSL3_RT_MAX_PLAIN_LENGTH) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_cert_verify, SSL_R_DATA_LENGTH_TOO_LONG);
+ switch (sign_result) {
+ case ssl_private_key_success:
+ ssl->rwstate = SSL_NOTHING;
+ break;
+ case ssl_private_key_failure:
+ ssl->rwstate = SSL_NOTHING;
goto err;
- }
-
- if (!EVP_PKEY_sign(pctx, &p[2], &signature_length, digest, digest_length)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_cert_verify, ERR_R_EVP_LIB);
+ case ssl_private_key_retry:
+ ssl->rwstate = SSL_PRIVATE_KEY_OPERATION;
+ ssl->state = SSL3_ST_CW_CERT_VRFY_B;
goto err;
- }
-
- s2n(signature_length, p);
- n += signature_length + 2;
+ }
- if (!ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_VERIFY, n)) {
- goto err;
- }
- s->state = SSL3_ST_CW_CERT_VRFY_B;
+ 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;
}
- EVP_PKEY_CTX_free(pctx);
- return ssl_do_write(s);
+ ssl->state = SSL3_ST_CW_CERT_VRFY_C;
+ return ssl_do_write(ssl);
err:
- EVP_PKEY_CTX_free(pctx);
+ CBB_cleanup(&cbb);
return -1;
}
/* ssl3_has_client_certificate returns true if a client certificate is
* configured. */
-static int ssl3_has_client_certificate(SSL *s) {
- return s->cert && s->cert->key->x509 && s->cert->key->privatekey;
+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) {
i = 0;
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_certificate,
- SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
}
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. */
- if (s->s3->handshake_buffer &&
- !ssl3_digest_cached_records(s, free_handshake_buffer)) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
- return -1;
- }
+ 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) {
- CERT_PKEY *cert_pkey = (s->s3->tmp.cert_req == 2) ? NULL : s->cert->key;
- if (!ssl3_output_cert_chain(s, cert_pkey)) {
+ 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(ssl);
+ l2n3(0, p);
+ if (!ssl_set_handshake_header(ssl, SSL3_MT_CERTIFICATE, 3)) {
+ return -1;
+ }
+ } else if (!ssl3_output_cert_chain(ssl)) {
return -1;
}
+ ssl->state = SSL3_ST_CW_CERT_D;
}
/* SSL3_ST_CW_CERT_D */
- return ssl_do_write(s);
+ return ssl_do_write(ssl);
}
-#define has_bits(i, m) (((i) & (m)) == (m))
-
-int ssl3_check_cert_and_algorithm(SSL *s) {
- int i, idx;
- long alg_k, alg_a;
- EVP_PKEY *pkey = NULL;
- SESS_CERT *sc;
- DH *dh;
-
- /* we don't have a certificate */
- if (!ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) {
- return 1;
- }
-
- alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
- alg_a = s->s3->tmp.new_cipher->algorithm_auth;
-
- sc = s->session->sess_cert;
- if (sc == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_check_cert_and_algorithm, ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
- dh = s->session->sess_cert->peer_dh_tmp;
-
- /* This is the passed certificate */
-
- idx = sc->peer_cert_type;
- if (idx == SSL_PKEY_ECC) {
- if (ssl_check_srvr_ecc_cert_and_alg(sc->peer_pkeys[idx].x509, s) == 0) {
- /* check failed */
- OPENSSL_PUT_ERROR(SSL, ssl3_check_cert_and_algorithm, SSL_R_BAD_ECC_CERT);
- goto f_err;
- } else {
- return 1;
- }
- } else if (alg_a & SSL_aECDSA) {
- OPENSSL_PUT_ERROR(SSL, ssl3_check_cert_and_algorithm,
- SSL_R_MISSING_ECDSA_SIGNING_CERT);
- goto f_err;
- }
- pkey = X509_get_pubkey(sc->peer_pkeys[idx].x509);
- i = X509_certificate_type(sc->peer_pkeys[idx].x509, pkey);
- EVP_PKEY_free(pkey);
-
- /* Check that we have a certificate if we require one */
- if ((alg_a & SSL_aRSA) && !has_bits(i, EVP_PK_RSA | EVP_PKT_SIGN)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_check_cert_and_algorithm,
- SSL_R_MISSING_RSA_SIGNING_CERT);
- goto f_err;
- }
-
- if ((alg_k & SSL_kRSA) && !has_bits(i, EVP_PK_RSA | EVP_PKT_ENC)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_check_cert_and_algorithm,
- SSL_R_MISSING_RSA_ENCRYPTING_CERT);
- goto f_err;
- }
-
- if ((alg_k & SSL_kDHE) &&
- !(has_bits(i, EVP_PK_DH | EVP_PKT_EXCH) || dh != NULL)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_check_cert_and_algorithm, SSL_R_MISSING_DH_KEY);
- goto f_err;
+int ssl3_send_next_proto(SSL *ssl) {
+ if (ssl->state == SSL3_ST_CW_NEXT_PROTO_B) {
+ return ssl_do_write(ssl);
+ }
+
+ assert(ssl->state == SSL3_ST_CW_NEXT_PROTO_A);
+
+ static const uint8_t kZero[32] = {0};
+ size_t padding_len = 32 - ((ssl->next_proto_negotiated_len + 2) % 32);
+
+ CBB cbb, child;
+ size_t length;
+ CBB_zero(&cbb);
+ if (!CBB_init_fixed(&cbb, ssl_handshake_start(ssl),
+ ssl->init_buf->max - SSL_HM_HEADER_LENGTH(ssl)) ||
+ !CBB_add_u8_length_prefixed(&cbb, &child) ||
+ !CBB_add_bytes(&child, ssl->next_proto_negotiated,
+ ssl->next_proto_negotiated_len) ||
+ !CBB_add_u8_length_prefixed(&cbb, &child) ||
+ !CBB_add_bytes(&child, kZero, padding_len) ||
+ !CBB_finish(&cbb, NULL, &length) ||
+ !ssl_set_handshake_header(ssl, SSL3_MT_NEXT_PROTO, length)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ CBB_cleanup(&cbb);
+ return -1;
}
- return 1;
-
-f_err:
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
-err:
- return 0;
+ ssl->state = SSL3_ST_CW_NEXT_PROTO_B;
+ return ssl_do_write(ssl);
}
-int ssl3_send_next_proto(SSL *s) {
- unsigned int len, padding_len;
- uint8_t *d, *p;
-
- if (s->state == SSL3_ST_CW_NEXT_PROTO_A) {
- len = s->next_proto_negotiated_len;
- padding_len = 32 - ((len + 2) % 32);
-
- d = p = ssl_handshake_start(s);
- *(p++) = len;
- memcpy(p, s->next_proto_negotiated, len);
- p += len;
- *(p++) = padding_len;
- memset(p, 0, padding_len);
- p += padding_len;
-
- if (!ssl_set_handshake_header(s, SSL3_MT_NEXT_PROTO, p - d)) {
- return -1;
- }
- s->state = SSL3_ST_CW_NEXT_PROTO_B;
+int ssl3_send_channel_id(SSL *ssl) {
+ if (ssl->state == SSL3_ST_CW_CHANNEL_ID_B) {
+ return ssl_do_write(ssl);
}
- return ssl_do_write(s);
-}
-
-int ssl3_send_channel_id(SSL *s) {
- uint8_t *d;
- int ret = -1, public_key_len;
- EVP_MD_CTX md_ctx;
- size_t sig_len;
- ECDSA_SIG *sig = NULL;
- uint8_t *public_key = NULL, *derp, *der_sig = NULL;
-
- if (s->state != SSL3_ST_CW_CHANNEL_ID_A) {
- return ssl_do_write(s);
- }
+ assert(ssl->state == SSL3_ST_CW_CHANNEL_ID_A);
- if (!s->tlsext_channel_id_private && s->ctx->channel_id_cb) {
+ if (ssl->tlsext_channel_id_private == NULL &&
+ ssl->ctx->channel_id_cb != NULL) {
EVP_PKEY *key = NULL;
- s->ctx->channel_id_cb(s, &key);
- if (key != NULL) {
- s->tlsext_channel_id_private = key;
+ ssl->ctx->channel_id_cb(ssl, &key);
+ if (key != NULL &&
+ !SSL_set1_tls_channel_id(ssl, key)) {
+ EVP_PKEY_free(key);
+ return -1;
}
+ EVP_PKEY_free(key);
}
- if (!s->tlsext_channel_id_private) {
- s->rwstate = SSL_CHANNEL_ID_LOOKUP;
+ if (ssl->tlsext_channel_id_private == NULL) {
+ ssl->rwstate = SSL_CHANNEL_ID_LOOKUP;
return -1;
}
- s->rwstate = SSL_NOTHING;
-
- d = ssl_handshake_start(s);
- if (s->s3->tlsext_channel_id_new) {
- s2n(TLSEXT_TYPE_channel_id_new, d);
- } else {
- s2n(TLSEXT_TYPE_channel_id, d);
- }
- s2n(TLSEXT_CHANNEL_ID_SIZE, d);
-
- EVP_MD_CTX_init(&md_ctx);
-
- public_key_len = i2d_PublicKey(s->tlsext_channel_id_private, NULL);
- if (public_key_len <= 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id,
- SSL_R_CANNOT_SERIALIZE_PUBLIC_KEY);
- goto err;
- }
-
- /* i2d_PublicKey will produce an ANSI X9.62 public key which, for a
- * P-256 key, is 0x04 (meaning uncompressed) followed by the x and y
- * field elements as 32-byte, big-endian numbers. */
- if (public_key_len != 65) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, SSL_R_CHANNEL_ID_NOT_P256);
- goto err;
- }
- public_key = OPENSSL_malloc(public_key_len);
- if (!public_key) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, ERR_R_MALLOC_FAILURE);
- goto err;
- }
+ ssl->rwstate = SSL_NOTHING;
- derp = public_key;
- i2d_PublicKey(s->tlsext_channel_id_private, &derp);
-
- if (EVP_DigestSignInit(&md_ctx, NULL, EVP_sha256(), NULL,
- s->tlsext_channel_id_private) != 1) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id,
- SSL_R_EVP_DIGESTSIGNINIT_FAILED);
- goto err;
- }
-
- if (!tls1_channel_id_hash(&md_ctx, s)) {
- goto err;
- }
-
- if (!EVP_DigestSignFinal(&md_ctx, NULL, &sig_len)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id,
- SSL_R_EVP_DIGESTSIGNFINAL_FAILED);
- goto err;
+ 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;
}
- der_sig = OPENSSL_malloc(sig_len);
- if (!der_sig) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, ERR_R_MALLOC_FAILURE);
+ int ret = -1;
+ BIGNUM *x = BN_new();
+ BIGNUM *y = BN_new();
+ ECDSA_SIG *sig = NULL;
+ if (x == NULL || y == NULL ||
+ !EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec_key),
+ EC_KEY_get0_public_key(ec_key),
+ x, y, NULL)) {
goto err;
}
- if (!EVP_DigestSignFinal(&md_ctx, der_sig, &sig_len)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id,
- SSL_R_EVP_DIGESTSIGNFINAL_FAILED);
+ uint8_t digest[EVP_MAX_MD_SIZE];
+ size_t digest_len;
+ if (!tls1_channel_id_hash(ssl, digest, &digest_len)) {
goto err;
}
- derp = der_sig;
- sig = d2i_ECDSA_SIG(NULL, (const uint8_t **)&derp, sig_len);
+ sig = ECDSA_do_sign(digest, digest_len, ec_key);
if (sig == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, SSL_R_D2I_ECDSA_SIG);
- goto err;
- }
-
- /* The first byte of public_key will be 0x4, denoting an uncompressed key. */
- memcpy(d, public_key + 1, 64);
- d += 64;
- if (!BN_bn2bin_padded(d, 32, sig->r) ||
- !BN_bn2bin_padded(d + 32, 32, sig->s)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, ERR_R_INTERNAL_ERROR);
goto err;
}
- if (!ssl_set_handshake_header(s, SSL3_MT_ENCRYPTED_EXTENSIONS,
- 2 + 2 + TLSEXT_CHANNEL_ID_SIZE)) {
+ CBB cbb, child;
+ size_t length;
+ CBB_zero(&cbb);
+ if (!CBB_init_fixed(&cbb, ssl_handshake_start(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) ||
+ !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);
+ CBB_cleanup(&cbb);
goto err;
}
- s->state = SSL3_ST_CW_CHANNEL_ID_B;
- ret = ssl_do_write(s);
+ ssl->state = SSL3_ST_CW_CHANNEL_ID_B;
+ ret = ssl_do_write(ssl);
err:
- EVP_MD_CTX_cleanup(&md_ctx);
- OPENSSL_free(public_key);
- OPENSSL_free(der_sig);
+ BN_free(x);
+ BN_free(y);
ECDSA_SIG_free(sig);
-
return ret;
}
-int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey) {
- int i = 0;
- if (s->ctx->client_cert_cb) {
- i = s->ctx->client_cert_cb(s, px509, ppkey);
+int ssl_do_client_cert_cb(SSL *ssl, X509 **out_x509, EVP_PKEY **out_pkey) {
+ if (ssl->ctx->client_cert_cb == NULL) {
+ return 0;
}
- return i;
+ return ssl->ctx->client_cert_cb(ssl, out_x509, out_pkey);
+}
+
+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 ssl->verify_result */
+ }
+
+ return ret;
}
diff --git a/src/ssl/s3_enc.c b/src/ssl/s3_enc.c
index fbe68da..89d861a 100644
--- a/src/ssl/s3_enc.c
+++ b/src/ssl/s3_enc.c
@@ -4,21 +4,21 @@
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
- *g
+ *
* 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).
- *g
+ *
* 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.
- *g
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -33,10 +33,10 @@
* 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) fromg
+ * 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)"
- *g
+ *
* 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
@@ -48,7 +48,7 @@
* 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.
- *g
+ *
* 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
@@ -62,7 +62,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.g
+ * 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
@@ -133,6 +133,8 @@
* OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
* OTHERWISE. */
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <stdio.h>
#include <string.h>
@@ -160,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) {
@@ -180,7 +182,7 @@ int ssl3_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret,
k++;
if (k > sizeof(buf)) {
/* bug: 'buf' is too small for this ciphersuite */
- OPENSSL_PUT_ERROR(SSL, ssl3_prf, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return 0;
}
@@ -189,7 +191,7 @@ int ssl3_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret,
}
c++;
if (!EVP_DigestInit_ex(&sha1, EVP_sha1(), NULL)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_prf, ERR_LIB_EVP);
+ OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP);
return 0;
}
EVP_DigestUpdate(&sha1, buf, k);
@@ -204,7 +206,7 @@ int ssl3_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret,
EVP_DigestFinal_ex(&sha1, smd, NULL);
if (!EVP_DigestInit_ex(&md5, EVP_md5(), NULL)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_prf, ERR_LIB_EVP);
+ OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP);
return 0;
}
EVP_DigestUpdate(&md5, secret, secret_len);
@@ -226,122 +228,101 @@ 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_finished_mac(SSL *s) {
- BIO_free(s->s3->handshake_buffer);
- ssl3_free_digest_list(s);
- s->s3->handshake_buffer = BIO_new(BIO_s_mem());
- if (s->s3->handshake_buffer == NULL) {
- return 0;
- }
- BIO_set_close(s->s3->handshake_buffer, BIO_CLOSE);
-
- return 1;
+int ssl3_init_handshake_buffer(SSL *ssl) {
+ ssl3_free_handshake_buffer(ssl);
+ ssl3_free_handshake_hash(ssl);
+ ssl->s3->handshake_buffer = BUF_MEM_new();
+ return ssl->s3->handshake_buffer != NULL;
}
-void ssl3_free_digest_list(SSL *s) {
- int i;
- if (!s->s3->handshake_dgst) {
- return;
- }
- for (i = 0; i < SSL_MAX_DIGEST; i++) {
- if (s->s3->handshake_dgst[i]) {
- EVP_MD_CTX_destroy(s->s3->handshake_dgst[i]);
- }
+/* init_digest_with_data calls |EVP_DigestInit_ex| on |ctx| with |md| and then
+ * writes the data in |buf| to it. */
+static int init_digest_with_data(EVP_MD_CTX *ctx, const EVP_MD *md,
+ const BUF_MEM *buf) {
+ if (!EVP_DigestInit_ex(ctx, md, NULL)) {
+ return 0;
}
- OPENSSL_free(s->s3->handshake_dgst);
- s->s3->handshake_dgst = NULL;
+ EVP_DigestUpdate(ctx, buf->data, buf->length);
+ return 1;
}
-int ssl3_finish_mac(SSL *s, const uint8_t *buf, int len) {
- int i;
+int ssl3_init_handshake_hash(SSL *ssl) {
+ ssl3_free_handshake_hash(ssl);
- if (s->s3->handshake_buffer) {
- return BIO_write(s->s3->handshake_buffer, (void *)buf, len) >= 0;
+ uint32_t algorithm_prf = ssl_get_algorithm_prf(ssl);
+ if (!init_digest_with_data(&ssl->s3->handshake_hash,
+ ssl_get_handshake_digest(algorithm_prf),
+ ssl->s3->handshake_buffer)) {
+ return 0;
}
- for (i = 0; i < SSL_MAX_DIGEST; i++) {
- if (s->s3->handshake_dgst[i] != NULL) {
- EVP_DigestUpdate(s->s3->handshake_dgst[i], buf, len);
- }
+ if (algorithm_prf == SSL_HANDSHAKE_MAC_DEFAULT &&
+ !init_digest_with_data(&ssl->s3->handshake_md5, EVP_md5(),
+ ssl->s3->handshake_buffer)) {
+ return 0;
}
+
return 1;
}
-int ssl3_digest_cached_records(
- SSL *s, enum should_free_handshake_buffer_t should_free_handshake_buffer) {
- int i;
- uint32_t mask;
- const EVP_MD *md;
- const uint8_t *hdata;
- size_t hdatalen;
-
- /* Allocate handshake_dgst array */
- ssl3_free_digest_list(s);
- s->s3->handshake_dgst = OPENSSL_malloc(SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *));
- if (s->s3->handshake_dgst == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_digest_cached_records, ERR_R_MALLOC_FAILURE);
- return 0;
- }
+void ssl3_free_handshake_hash(SSL *ssl) {
+ EVP_MD_CTX_cleanup(&ssl->s3->handshake_hash);
+ EVP_MD_CTX_cleanup(&ssl->s3->handshake_md5);
+}
- memset(s->s3->handshake_dgst, 0, SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *));
- if (!BIO_mem_contents(s->s3->handshake_buffer, &hdata, &hdatalen)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_digest_cached_records,
- SSL_R_BAD_HANDSHAKE_LENGTH);
- return 0;
- }
+void ssl3_free_handshake_buffer(SSL *ssl) {
+ BUF_MEM_free(ssl->s3->handshake_buffer);
+ ssl->s3->handshake_buffer = NULL;
+}
- /* Loop through bits of algorithm2 field and create MD_CTX-es */
- for (i = 0; ssl_get_handshake_digest(&mask, &md, i); i++) {
- if ((mask & ssl_get_algorithm2(s)) && md) {
- s->s3->handshake_dgst[i] = EVP_MD_CTX_create();
- if (s->s3->handshake_dgst[i] == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_digest_cached_records, ERR_LIB_EVP);
- return 0;
- }
- if (!EVP_DigestInit_ex(s->s3->handshake_dgst[i], md, NULL)) {
- EVP_MD_CTX_destroy(s->s3->handshake_dgst[i]);
- s->s3->handshake_dgst[i] = NULL;
- OPENSSL_PUT_ERROR(SSL, ssl3_digest_cached_records, ERR_LIB_EVP);
- return 0;
- }
- EVP_DigestUpdate(s->s3->handshake_dgst[i], hdata, hdatalen);
- } else {
- s->s3->handshake_dgst[i] = NULL;
+int ssl3_update_handshake_hash(SSL *ssl, const uint8_t *in, size_t in_len) {
+ /* Depending on the state of the handshake, either the handshake buffer may be
+ * active, the rolling hash, or both. */
+
+ if (ssl->s3->handshake_buffer != NULL) {
+ size_t new_len = ssl->s3->handshake_buffer->length + in_len;
+ if (new_len < in_len) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ return 0;
}
+ if (!BUF_MEM_grow(ssl->s3->handshake_buffer, new_len)) {
+ return 0;
+ }
+ memcpy(ssl->s3->handshake_buffer->data + new_len - in_len, in, in_len);
}
- if (should_free_handshake_buffer == free_handshake_buffer) {
- /* Free handshake_buffer BIO */
- BIO_free(s->s3->handshake_buffer);
- s->s3->handshake_buffer = NULL;
+ if (EVP_MD_CTX_md(&ssl->s3->handshake_hash) != NULL) {
+ EVP_DigestUpdate(&ssl->s3->handshake_hash, in, in_len);
+ }
+ if (EVP_MD_CTX_md(&ssl->s3->handshake_md5) != NULL) {
+ EVP_DigestUpdate(&ssl->s3->handshake_md5, in, 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;
}
@@ -350,59 +331,49 @@ 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;
- int npad, n;
+ size_t npad, n;
unsigned int i;
uint8_t md_buf[EVP_MAX_MD_SIZE];
- EVP_MD_CTX ctx, *d = NULL;
-
- if (s->s3->handshake_buffer &&
- !ssl3_digest_cached_records(s, free_handshake_buffer)) {
- return 0;
- }
-
- /* Search for digest of specified type in the handshake_dgst array. */
- for (i = 0; i < SSL_MAX_DIGEST; i++) {
- if (s->s3->handshake_dgst[i] &&
- EVP_MD_CTX_type(s->s3->handshake_dgst[i]) == md_nid) {
- d = s->s3->handshake_dgst[i];
- break;
- }
- }
-
- if (!d) {
- OPENSSL_PUT_ERROR(SSL, ssl3_handshake_mac, SSL_R_NO_REQUIRED_DIGEST);
+ EVP_MD_CTX ctx;
+ const EVP_MD_CTX *ctx_template;
+
+ if (md_nid == NID_md5) {
+ 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;
}
EVP_MD_CTX_init(&ctx);
- if (!EVP_MD_CTX_copy_ex(&ctx, d)) {
+ if (!EVP_MD_CTX_copy_ex(&ctx, ctx_template)) {
EVP_MD_CTX_cleanup(&ctx);
- OPENSSL_PUT_ERROR(SSL, ssl3_handshake_mac, ERR_LIB_EVP);
+ OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP);
return 0;
}
n = EVP_MD_CTX_size(&ctx);
- if (n < 0) {
- return 0;
- }
npad = (48 / n) * n;
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);
if (!EVP_DigestInit_ex(&ctx, EVP_MD_CTX_md(&ctx), NULL)) {
EVP_MD_CTX_cleanup(&ctx);
- OPENSSL_PUT_ERROR(SSL, ssl3_handshake_mac, ERR_LIB_EVP);
+ 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);
@@ -420,7 +391,7 @@ int ssl3_record_sequence_update(uint8_t *seq, size_t seq_len) {
return 1;
}
}
- OPENSSL_PUT_ERROR(SSL, ssl3_record_sequence_update, ERR_R_OVERFLOW);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
return 0;
}
diff --git a/src/ssl/s3_lib.c b/src/ssl/s3_lib.c
index 1c28a73..64f9f8c 100644
--- a/src/ssl/s3_lib.c
+++ b/src/ssl/s3_lib.c
@@ -146,12 +146,15 @@
* OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
* OTHERWISE. */
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <openssl/buf.h>
#include <openssl/dh.h>
+#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/md5.h>
#include <openssl/mem.h>
@@ -178,20 +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_finish_mac(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);
@@ -199,49 +205,47 @@ int ssl3_new(SSL *s) {
goto err;
}
memset(s3, 0, sizeof *s3);
- memset(s3->rrec.seq_num, 0, sizeof(s3->rrec.seq_num));
- s->s3 = s3;
+ EVP_MD_CTX_init(&s3->handshake_hash);
+ EVP_MD_CTX_init(&s3->handshake_md5);
+
+ 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;
}
- BUF_MEM_free(s->s3->sniff_buffer);
- ssl3_cleanup_key_block(s);
- ssl3_release_read_buffer(s);
- ssl3_release_write_buffer(s);
- DH_free(s->s3->tmp.dh);
- EC_KEY_free(s->s3->tmp.ecdh);
-
- 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_ecpointformatlist);
- OPENSSL_free(s->s3->tmp.peer_ellipticcurvelist);
- OPENSSL_free(s->s3->tmp.peer_psk_identity_hint);
- BIO_free(s->s3->handshake_buffer);
- ssl3_free_digest_list(s);
- OPENSSL_free(s->s3->alpn_selected);
-
- OPENSSL_cleanse(s->s3, sizeof *s->s3);
- OPENSSL_free(s->s3);
- s->s3 = NULL;
+ 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(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(ssl->s3, sizeof *ssl->s3);
+ OPENSSL_free(ssl->s3);
+ ssl->s3 = NULL;
}
-static int ssl3_set_req_cert_type(CERT *c, const uint8_t *p, size_t len);
-
int SSL_session_reused(const SSL *ssl) {
return ssl->hit;
}
@@ -274,7 +278,7 @@ int SSL_CTX_set_tmp_dh(SSL_CTX *ctx, const DH *dh) {
DH_free(ctx->cert->dh_tmp);
ctx->cert->dh_tmp = DHparams_dup(dh);
if (ctx->cert->dh_tmp == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_set_tmp_dh, ERR_R_DH_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
return 0;
}
return 1;
@@ -284,7 +288,7 @@ int SSL_set_tmp_dh(SSL *ssl, const DH *dh) {
DH_free(ssl->cert->dh_tmp);
ssl->cert->dh_tmp = DHparams_dup(dh);
if (ssl->cert->dh_tmp == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_set_tmp_dh, ERR_R_DH_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
return 0;
}
return 1;
@@ -292,20 +296,20 @@ int SSL_set_tmp_dh(SSL *ssl, const DH *dh) {
int SSL_CTX_set_tmp_ecdh(SSL_CTX *ctx, const EC_KEY *ec_key) {
if (ec_key == NULL || EC_KEY_get0_group(ec_key) == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_set_tmp_ecdh, ERR_R_PASSED_NULL_PARAMETER);
+ 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) {
if (ec_key == NULL || EC_KEY_get0_group(ec_key) == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_set_tmp_ecdh, ERR_R_PASSED_NULL_PARAMETER);
+ 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) {
@@ -322,8 +326,7 @@ int SSL_CTX_set1_tls_channel_id(SSL_CTX *ctx, EVP_PKEY *private_key) {
ctx->tlsext_channel_id_enabled = 1;
if (EVP_PKEY_id(private_key) != EVP_PKEY_EC ||
EVP_PKEY_bits(private_key) != 256) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_set1_tls_channel_id,
- SSL_R_CHANNEL_ID_NOT_P256);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_NOT_P256);
return 0;
}
EVP_PKEY_free(ctx->tlsext_channel_id_private);
@@ -332,14 +335,18 @@ 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) {
- ssl->tlsext_channel_id_enabled = 1;
- if (EVP_PKEY_id(private_key) != EVP_PKEY_EC ||
- EVP_PKEY_bits(private_key) != 256) {
- OPENSSL_PUT_ERROR(SSL, SSL_set1_tls_channel_id, SSL_R_CHANNEL_ID_NOT_P256);
+ 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;
}
+
EVP_PKEY_free(ssl->tlsext_channel_id_private);
ssl->tlsext_channel_id_private = EVP_PKEY_up_ref(private_key);
+ ssl->tlsext_channel_id_enabled = 1;
+
return 1;
}
@@ -359,238 +366,36 @@ int SSL_set_tlsext_host_name(SSL *ssl, const char *name) {
return 1;
}
if (strlen(name) > TLSEXT_MAXLEN_host_name) {
- OPENSSL_PUT_ERROR(SSL, SSL_set_tlsext_host_name,
- SSL_R_SSL3_EXT_INVALID_SERVERNAME);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SSL3_EXT_INVALID_SERVERNAME);
return 0;
}
ssl->tlsext_hostname = BUF_strdup(name);
if (ssl->tlsext_hostname == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_set_tlsext_host_name, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
return 1;
}
-long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) {
- int ret = 0;
-
- switch (cmd) {
- case SSL_CTRL_CHAIN:
- if (larg) {
- return ssl_cert_set1_chain(s->cert, (STACK_OF(X509) *)parg);
- } else {
- return ssl_cert_set0_chain(s->cert, (STACK_OF(X509) *)parg);
- }
-
- case SSL_CTRL_CHAIN_CERT:
- if (larg) {
- return ssl_cert_add1_chain_cert(s->cert, (X509 *)parg);
- } else {
- return ssl_cert_add0_chain_cert(s->cert, (X509 *)parg);
- }
-
- case SSL_CTRL_GET_CHAIN_CERTS:
- *(STACK_OF(X509) **)parg = s->cert->key->chain;
- ret = 1;
- break;
-
- case SSL_CTRL_SELECT_CURRENT_CERT:
- return ssl_cert_select_current(s->cert, (X509 *)parg);
-
- case SSL_CTRL_GET_CURVES: {
- const uint16_t *clist = s->s3->tmp.peer_ellipticcurvelist;
- size_t clistlen = s->s3->tmp.peer_ellipticcurvelist_length;
- if (parg) {
- size_t i;
- int *cptr = parg;
- int nid;
- for (i = 0; i < clistlen; i++) {
- nid = tls1_ec_curve_id2nid(clist[i]);
- if (nid != NID_undef) {
- cptr[i] = nid;
- } else {
- cptr[i] = TLSEXT_nid_unknown | clist[i];
- }
- }
- }
- return (int)clistlen;
- }
-
- case SSL_CTRL_SET_CURVES:
- return tls1_set_curves(&s->tlsext_ellipticcurvelist,
- &s->tlsext_ellipticcurvelist_length, parg, larg);
-
- case SSL_CTRL_SET_SIGALGS:
- return tls1_set_sigalgs(s->cert, parg, larg, 0);
-
- case SSL_CTRL_SET_CLIENT_SIGALGS:
- return tls1_set_sigalgs(s->cert, parg, larg, 1);
-
- case SSL_CTRL_GET_CLIENT_CERT_TYPES: {
- const uint8_t **pctype = parg;
- if (s->server || !s->s3->tmp.cert_req) {
- return 0;
- }
- if (pctype) {
- *pctype = s->s3->tmp.certificate_types;
- }
- return (int)s->s3->tmp.num_certificate_types;
- }
-
- case SSL_CTRL_SET_CLIENT_CERT_TYPES:
- if (!s->server) {
- return 0;
- }
- return ssl3_set_req_cert_type(s->cert, parg, larg);
-
- case SSL_CTRL_BUILD_CERT_CHAIN:
- return ssl_build_cert_chain(s->cert, s->ctx->cert_store, larg);
-
- case SSL_CTRL_SET_VERIFY_CERT_STORE:
- return ssl_cert_set_cert_store(s->cert, parg, 0, larg);
-
- case SSL_CTRL_SET_CHAIN_CERT_STORE:
- return ssl_cert_set_cert_store(s->cert, parg, 1, larg);
-
- case SSL_CTRL_GET_SERVER_TMP_KEY:
- if (s->server || !s->session || !s->session->sess_cert) {
- return 0;
- } else {
- SESS_CERT *sc;
- EVP_PKEY *ptmp;
- int rv = 0;
- sc = s->session->sess_cert;
- if (!sc->peer_dh_tmp && !sc->peer_ecdh_tmp) {
- return 0;
- }
- ptmp = EVP_PKEY_new();
- if (!ptmp) {
- return 0;
- }
- if (sc->peer_dh_tmp) {
- rv = EVP_PKEY_set1_DH(ptmp, sc->peer_dh_tmp);
- } else if (sc->peer_ecdh_tmp) {
- rv = EVP_PKEY_set1_EC_KEY(ptmp, sc->peer_ecdh_tmp);
- }
- if (rv) {
- *(EVP_PKEY **)parg = ptmp;
- return 1;
- }
- EVP_PKEY_free(ptmp);
- return 0;
- }
-
- case SSL_CTRL_GET_EC_POINT_FORMATS: {
- const uint8_t **pformat = parg;
- if (!s->s3->tmp.peer_ecpointformatlist) {
- return 0;
- }
- *pformat = s->s3->tmp.peer_ecpointformatlist;
- return (int)s->s3->tmp.peer_ecpointformatlist_length;
- }
-
- default:
- break;
+size_t SSL_get0_certificate_types(SSL *ssl, const uint8_t **out_types) {
+ if (ssl->server || !ssl->s3->tmp.cert_req) {
+ *out_types = NULL;
+ return 0;
}
-
- return ret;
+ *out_types = ssl->s3->tmp.certificate_types;
+ return ssl->s3->tmp.num_certificate_types;
}
-long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) {
- switch (cmd) {
- case SSL_CTRL_SET_TLSEXT_TICKET_KEYS:
- case SSL_CTRL_GET_TLSEXT_TICKET_KEYS: {
- uint8_t *keys = parg;
- if (!keys) {
- return 48;
- }
- if (larg != 48) {
- OPENSSL_PUT_ERROR(SSL, ssl3_ctx_ctrl, SSL_R_INVALID_TICKET_KEYS_LENGTH);
- return 0;
- }
- if (cmd == SSL_CTRL_SET_TLSEXT_TICKET_KEYS) {
- memcpy(ctx->tlsext_tick_key_name, keys, 16);
- memcpy(ctx->tlsext_tick_hmac_key, keys + 16, 16);
- memcpy(ctx->tlsext_tick_aes_key, keys + 32, 16);
- } else {
- memcpy(keys, ctx->tlsext_tick_key_name, 16);
- memcpy(keys + 16, ctx->tlsext_tick_hmac_key, 16);
- memcpy(keys + 32, ctx->tlsext_tick_aes_key, 16);
- }
- return 1;
- }
-
- case SSL_CTRL_SET_CURVES:
- return tls1_set_curves(&ctx->tlsext_ellipticcurvelist,
- &ctx->tlsext_ellipticcurvelist_length, parg, larg);
-
- case SSL_CTRL_SET_SIGALGS:
- return tls1_set_sigalgs(ctx->cert, parg, larg, 0);
-
- case SSL_CTRL_SET_CLIENT_SIGALGS:
- return tls1_set_sigalgs(ctx->cert, parg, larg, 1);
-
- case SSL_CTRL_SET_CLIENT_CERT_TYPES:
- return ssl3_set_req_cert_type(ctx->cert, parg, larg);
-
- case SSL_CTRL_BUILD_CERT_CHAIN:
- return ssl_build_cert_chain(ctx->cert, ctx->cert_store, larg);
-
- case SSL_CTRL_SET_VERIFY_CERT_STORE:
- return ssl_cert_set_cert_store(ctx->cert, parg, 0, larg);
-
- case SSL_CTRL_SET_CHAIN_CERT_STORE:
- return ssl_cert_set_cert_store(ctx->cert, parg, 1, larg);
-
- case SSL_CTRL_EXTRA_CHAIN_CERT:
- if (ctx->extra_certs == NULL) {
- ctx->extra_certs = sk_X509_new_null();
- if (ctx->extra_certs == NULL) {
- return 0;
- }
- }
- sk_X509_push(ctx->extra_certs, (X509 *)parg);
- break;
-
- case SSL_CTRL_GET_EXTRA_CHAIN_CERTS:
- if (ctx->extra_certs == NULL && larg == 0) {
- *(STACK_OF(X509) **)parg = ctx->cert->key->chain;
- } else {
- *(STACK_OF(X509) **)parg = ctx->extra_certs;
- }
- break;
-
- case SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS:
- sk_X509_pop_free(ctx->extra_certs, X509_free);
- ctx->extra_certs = NULL;
- break;
-
- case SSL_CTRL_CHAIN:
- if (larg) {
- return ssl_cert_set1_chain(ctx->cert, (STACK_OF(X509) *)parg);
- } else {
- return ssl_cert_set0_chain(ctx->cert, (STACK_OF(X509) *)parg);
- }
-
- case SSL_CTRL_CHAIN_CERT:
- if (larg) {
- return ssl_cert_add1_chain_cert(ctx->cert, (X509 *)parg);
- } else {
- return ssl_cert_add0_chain_cert(ctx->cert, (X509 *)parg);
- }
-
- case SSL_CTRL_GET_CHAIN_CERTS:
- *(STACK_OF(X509) **)parg = ctx->cert->key->chain;
- break;
-
- case SSL_CTRL_SELECT_CURRENT_CERT:
- return ssl_cert_select_current(ctx->cert, (X509 *)parg);
-
- default:
- return 0;
- }
+int SSL_CTX_set1_curves(SSL_CTX *ctx, const int *curves, size_t curves_len) {
+ return tls1_set_curves(&ctx->tlsext_ellipticcurvelist,
+ &ctx->tlsext_ellipticcurvelist_length, curves,
+ curves_len);
+}
- return 1;
+int SSL_set1_curves(SSL *ssl, const int *curves, size_t curves_len) {
+ return tls1_set_curves(&ssl->tlsext_ellipticcurvelist,
+ &ssl->tlsext_ellipticcurvelist_length, curves,
+ curves_len);
}
int SSL_CTX_set_tlsext_servername_callback(
@@ -604,6 +409,36 @@ int SSL_CTX_set_tlsext_servername_arg(SSL_CTX *ctx, void *arg) {
return 1;
}
+int SSL_CTX_get_tlsext_ticket_keys(SSL_CTX *ctx, void *out, size_t len) {
+ if (out == NULL) {
+ return 48;
+ }
+ if (len != 48) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_TICKET_KEYS_LENGTH);
+ return 0;
+ }
+ uint8_t *out_bytes = out;
+ memcpy(out_bytes, ctx->tlsext_tick_key_name, 16);
+ memcpy(out_bytes + 16, ctx->tlsext_tick_hmac_key, 16);
+ memcpy(out_bytes + 32, ctx->tlsext_tick_aes_key, 16);
+ return 1;
+}
+
+int SSL_CTX_set_tlsext_ticket_keys(SSL_CTX *ctx, const void *in, size_t len) {
+ if (in == NULL) {
+ return 48;
+ }
+ if (len != 48) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_TICKET_KEYS_LENGTH);
+ return 0;
+ }
+ const uint8_t *in_bytes = in;
+ memcpy(ctx->tlsext_tick_key_name, in_bytes, 16);
+ memcpy(ctx->tlsext_tick_hmac_key, in_bytes + 16, 16);
+ memcpy(ctx->tlsext_tick_aes_key, in_bytes + 32, 16);
+ return 1;
+}
+
int SSL_CTX_set_tlsext_ticket_key_cb(
SSL_CTX *ctx, int (*callback)(SSL *ssl, uint8_t *key_name, uint8_t *iv,
EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
@@ -612,25 +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->ctx != NULL && s->ctx->cipher_list != NULL) {
- return s->ctx->cipher_list;
+ if (ssl->version >= TLS1_VERSION && ssl->ctx != NULL &&
+ ssl->ctx->cipher_list_tls10 != NULL) {
+ return ssl->ctx->cipher_list_tls10;
+ }
+
+ 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;
@@ -647,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;
@@ -657,15 +497,16 @@ 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);
ok = 1;
- /* Skip TLS v1.2 only ciphersuites if not supported */
- if ((c->algorithm_ssl & SSL_TLSV1_2) && !SSL_USE_TLS1_2_CIPHERS(s)) {
+ /* Check the TLS version. */
+ if (SSL_CIPHER_get_min_version(c) >
+ ssl3_version_from_wire(ssl, ssl->version)) {
ok = 0;
}
@@ -701,22 +542,15 @@ 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;
int have_rsa_sign = 0;
int have_ecdsa_sign = 0;
- /* If we have custom certificate types set, use them */
- if (s->cert->client_certificate_types) {
- memcpy(p, s->cert->client_certificate_types,
- s->cert->num_client_certificate_types);
- return s->cert->num_client_certificate_types;
- }
-
/* 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:
@@ -735,43 +569,20 @@ 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;
}
return ret;
}
-static int ssl3_set_req_cert_type(CERT *c, const uint8_t *p, size_t len) {
- OPENSSL_free(c->client_certificate_types);
- c->client_certificate_types = NULL;
- c->num_client_certificate_types = 0;
-
- if (!p || !len) {
- return 1;
- }
-
- if (len > 0xff) {
- return 0;
- }
-
- c->client_certificate_types = BUF_memdup(p, len);
- if (!c->client_certificate_types) {
- return 0;
- }
-
- c->num_client_certificate_types = len;
- return 1;
-}
-
/* If we are using default SHA1+MD5 algorithms switch to new SHA256 PRF and
* handshake macs if required. */
-uint32_t ssl_get_algorithm2(SSL *s) {
- static const uint32_t kMask = SSL_HANDSHAKE_MAC_DEFAULT;
- uint32_t alg2 = s->s3->tmp.new_cipher->algorithm2;
- if (s->enc_method->enc_flags & SSL_ENC_FLAG_SHA256_PRF &&
- (alg2 & kMask) == kMask) {
+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;
}
- return alg2;
+ return algorithm_prf;
}
diff --git a/src/ssl/s3_meth.c b/src/ssl/s3_meth.c
index 66bbb29..b60b5f2 100644
--- a/src/ssl/s3_meth.c
+++ b/src/ssl/s3_meth.c
@@ -54,6 +54,8 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
+#include <openssl/ssl.h>
+
#include "internal.h"
@@ -65,11 +67,10 @@ 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,
- ssl3_ctrl,
- ssl3_ctx_ctrl,
ssl3_supports_cipher,
SSL3_HM_HEADER_LENGTH,
ssl3_set_handshake_header,
diff --git a/src/ssl/s3_pkt.c b/src/ssl/s3_pkt.c
index 4a9ae83..4c1133c 100644
--- a/src/ssl/s3_pkt.c
+++ b/src/ssl/s3_pkt.c
@@ -106,6 +106,8 @@
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <limits.h>
#include <stdio.h>
@@ -120,282 +122,64 @@
#include "internal.h"
-static int do_ssl3_write(SSL *s, int type, const uint8_t *buf, unsigned int len,
- char fragment);
-static int ssl3_get_record(SSL *s);
-
-int ssl3_read_n(SSL *s, int n, int extend) {
- /* If |extend| is 0, obtain new n-byte packet;
- * if |extend| is 1, increase packet by another n bytes.
- *
- * The packet will be in the sub-array of |s->s3->rbuf.buf| specified by
- * |s->packet| and |s->packet_length|. (If DTLS and |extend| is 0, additional
- * bytes will be read into |rbuf|, up to the size of the buffer.)
- *
- * TODO(davidben): |dtls1_get_record| and |ssl3_get_record| have very
- * different needs. Separate the two record layers. In DTLS, |BIO_read| is
- * called at most once, and only when |extend| is 0. In TLS, the buffer never
- * contains more than one record. */
- int i, len, left;
- uintptr_t align = 0;
- uint8_t *pkt;
- SSL3_BUFFER *rb;
-
- if (n <= 0) {
- return n;
- }
+static int do_ssl3_write(SSL *ssl, int type, const uint8_t *buf, unsigned len);
- rb = &s->s3->rbuf;
- if (rb->buf == NULL && !ssl3_setup_read_buffer(s)) {
- return -1;
- }
+/* kMaxWarningAlerts is the number of consecutive warning alerts that will be
+ * processed. */
+static const uint8_t kMaxWarningAlerts = 4;
- left = rb->left;
-
- align = (uintptr_t)rb->buf + SSL3_RT_HEADER_LENGTH;
- align = (0 - align) & (SSL3_ALIGN_PAYLOAD - 1);
-
- if (!extend) {
- /* start with empty packet ... */
- if (left == 0) {
- rb->offset = align;
- } else if (align != 0 && left >= SSL3_RT_HEADER_LENGTH) {
- /* check if next packet length is large enough to justify payload
- * alignment... */
- pkt = rb->buf + rb->offset;
- if (pkt[0] == SSL3_RT_APPLICATION_DATA && (pkt[3] << 8 | pkt[4]) >= 128) {
- /* Note that even if packet is corrupted and its length field is
- * insane, we can only be led to wrong decision about whether memmove
- * will occur or not. Header values has no effect on memmove arguments
- * and therefore no buffer overrun can be triggered. */
- memmove(rb->buf + align, pkt, left);
- rb->offset = align;
+/* ssl3_get_record reads a new input record. On success, it places it in
+ * |ssl->s3->rrec| and returns one. Otherwise it returns <= 0 on error or if
+ * more data is needed. */
+static int ssl3_get_record(SSL *ssl) {
+ int ret;
+again:
+ /* Ensure the buffer is large enough to decrypt in-place. */
+ ret = ssl_read_buffer_extend_to(ssl, ssl_record_prefix_len(ssl));
+ if (ret <= 0) {
+ return ret;
+ }
+ assert(ssl_read_buffer_len(ssl) >= ssl_record_prefix_len(ssl));
+
+ uint8_t *out = ssl_read_buffer(ssl) + ssl_record_prefix_len(ssl);
+ size_t max_out = ssl_read_buffer_len(ssl) - ssl_record_prefix_len(ssl);
+ uint8_t type, alert;
+ size_t len, consumed;
+ switch (tls_open_record(ssl, &type, out, &len, &consumed, &alert, max_out,
+ ssl_read_buffer(ssl), ssl_read_buffer_len(ssl))) {
+ case ssl_open_record_success:
+ ssl_read_buffer_consume(ssl, consumed);
+
+ if (len > 0xffff) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ return -1;
}
- }
- s->packet = rb->buf + rb->offset;
- s->packet_length = 0;
- /* ... now we can act as if 'extend' was set */
- }
- /* In DTLS, if there is leftover data from the previous packet or |extend| is
- * true, clamp to the previous read. DTLS records may not span packet
- * boundaries. */
- if (SSL_IS_DTLS(s) && n > left && (left > 0 || extend)) {
- n = left;
- }
+ SSL3_RECORD *rr = &ssl->s3->rrec;
+ rr->type = type;
+ rr->length = (uint16_t)len;
+ rr->data = out;
+ return 1;
- /* if there is enough in the buffer from a previous read, take some */
- if (left >= n) {
- s->packet_length += n;
- rb->left = left - n;
- rb->offset += n;
- return n;
- }
-
- /* else we need to read more data */
-
- len = s->packet_length;
- pkt = rb->buf + align;
- /* Move any available bytes to front of buffer: |len| bytes already pointed
- * to by |packet|, |left| extra ones at the end. */
- if (s->packet != pkt) {
- /* len > 0 */
- memmove(pkt, s->packet, len + left);
- s->packet = pkt;
- rb->offset = len + align;
- }
-
- if (n > (int)(rb->len - rb->offset)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_read_n, ERR_R_INTERNAL_ERROR);
- return -1;
- }
-
- int max = n;
- if (SSL_IS_DTLS(s) && !extend) {
- max = rb->len - rb->offset;
- }
-
- while (left < n) {
- /* Now we have len+left bytes at the front of s->s3->rbuf.buf and need to
- * read in more until we have len+n (up to len+max if possible). */
- ERR_clear_system_error();
- if (s->rbio != NULL) {
- s->rwstate = SSL_READING;
- i = BIO_read(s->rbio, pkt + len + left, max - left);
- } else {
- OPENSSL_PUT_ERROR(SSL, ssl3_read_n, SSL_R_READ_BIO_NOT_SET);
- i = -1;
- }
-
- if (i <= 0) {
- rb->left = left;
- if (len + left == 0) {
- ssl3_release_read_buffer(s);
+ case ssl_open_record_partial:
+ ret = ssl_read_buffer_extend_to(ssl, consumed);
+ if (ret <= 0) {
+ return ret;
}
- return i;
- }
- left += i;
- /* reads should *never* span multiple packets for DTLS because the
- * underlying transport protocol is message oriented as opposed to byte
- * oriented as in the TLS case. */
- if (SSL_IS_DTLS(s) && n > left) {
- n = left; /* makes the while condition false */
- }
- }
-
- /* done reading, now the book-keeping */
- rb->offset += n;
- rb->left = left - n;
- s->packet_length += n;
- s->rwstate = SSL_NOTHING;
-
- return n;
-}
-
-/* MAX_EMPTY_RECORDS defines the number of consecutive, empty records that will
- * be processed per call to ssl3_get_record. Without this limit an attacker
- * could send empty records at a faster rate than we can process and cause
- * ssl3_get_record to loop forever. */
-#define MAX_EMPTY_RECORDS 32
-
-/* Call this to get a new input record. It will return <= 0 if more data is
- * needed, normally due to an error or non-blocking IO. When it finishes, one
- * packet has been decoded and can be found in
- * ssl->s3->rrec.type - is the type of record
- * ssl->s3->rrec.data - data
- * ssl->s3->rrec.length - number of bytes */
-/* used only by ssl3_read_bytes */
-static int ssl3_get_record(SSL *s) {
- uint8_t ssl_major, ssl_minor;
- int al, n, i, ret = -1;
- SSL3_RECORD *rr = &s->s3->rrec;
- uint8_t *p;
- uint16_t version;
- size_t extra;
- unsigned empty_record_count = 0;
+ goto again;
-again:
- /* check if we have the header */
- if (s->rstate != SSL_ST_READ_BODY ||
- s->packet_length < SSL3_RT_HEADER_LENGTH) {
- n = ssl3_read_n(s, SSL3_RT_HEADER_LENGTH, 0);
- if (n <= 0) {
- return n; /* error or non-blocking */
- }
- s->rstate = SSL_ST_READ_BODY;
-
- /* Some bytes were read, so the read buffer must be existant and
- * |s->s3->init_extra| is defined. */
- assert(s->s3->rbuf.buf != NULL);
- extra = s->s3->init_extra ? SSL3_RT_MAX_EXTRA : 0;
-
- p = s->packet;
- if (s->msg_callback) {
- s->msg_callback(0, 0, SSL3_RT_HEADER, p, 5, s, s->msg_callback_arg);
- }
-
- /* Pull apart the header into the SSL3_RECORD */
- rr->type = *(p++);
- ssl_major = *(p++);
- ssl_minor = *(p++);
- version = (((uint16_t)ssl_major) << 8) | ssl_minor;
- n2s(p, rr->length);
+ case ssl_open_record_discard:
+ ssl_read_buffer_consume(ssl, consumed);
+ goto again;
- if (s->s3->have_version && version != s->version) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_record, SSL_R_WRONG_VERSION_NUMBER);
- al = SSL_AD_PROTOCOL_VERSION;
- goto f_err;
- }
-
- if ((version >> 8) != SSL3_VERSION_MAJOR) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_record, SSL_R_WRONG_VERSION_NUMBER);
- goto err;
- }
-
- if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH + extra) {
- al = SSL_AD_RECORD_OVERFLOW;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_record, SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
- goto f_err;
- }
-
- /* now s->rstate == SSL_ST_READ_BODY */
- } else {
- /* |packet_length| is non-zero and |s->rstate| is |SSL_ST_READ_BODY|. The
- * read buffer must be existant and |s->s3->init_extra| is defined. */
- assert(s->s3->rbuf.buf != NULL);
- extra = s->s3->init_extra ? SSL3_RT_MAX_EXTRA : 0;
- }
-
- /* s->rstate == SSL_ST_READ_BODY, get and decode the data */
-
- if (rr->length > s->packet_length - SSL3_RT_HEADER_LENGTH) {
- /* now s->packet_length == SSL3_RT_HEADER_LENGTH */
- i = rr->length;
- n = ssl3_read_n(s, i, 1);
- if (n <= 0) {
- /* Error or non-blocking IO. Now |n| == |rr->length|, and
- * |s->packet_length| == |SSL3_RT_HEADER_LENGTH| + |rr->length|. */
- return n;
- }
- }
-
- s->rstate = SSL_ST_READ_HEADER; /* set state for later operations */
-
- /* |rr->data| points to |rr->length| bytes of ciphertext in |s->packet|. */
- rr->data = &s->packet[SSL3_RT_HEADER_LENGTH];
-
- /* Decrypt the packet in-place.
- *
- * TODO(davidben): This assumes |s->version| is the same as the record-layer
- * version which isn't always true, but it only differs with the NULL cipher
- * which ignores the parameter. */
- size_t plaintext_len;
- if (!SSL_AEAD_CTX_open(s->aead_read_ctx, rr->data, &plaintext_len, rr->length,
- rr->type, s->version, s->s3->read_sequence, rr->data,
- rr->length)) {
- al = SSL_AD_BAD_RECORD_MAC;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_record,
- SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
- goto f_err;
- }
- if (!ssl3_record_sequence_update(s->s3->read_sequence, 8)) {
- goto err;
- }
- if (plaintext_len > SSL3_RT_MAX_PLAIN_LENGTH + extra) {
- al = SSL_AD_RECORD_OVERFLOW;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_record, SSL_R_DATA_LENGTH_TOO_LONG);
- goto f_err;
- }
- assert(plaintext_len <= (1u << 16));
- rr->length = plaintext_len;
-
- rr->off = 0;
- /* So at this point the following is true:
- * ssl->s3->rrec.type is the type of record;
- * ssl->s3->rrec.length is the number of bytes in the record;
- * ssl->s3->rrec.off is the offset to first valid byte;
- * ssl->s3->rrec.data the first byte of the record body. */
-
- /* we have pulled in a full packet so zero things */
- s->packet_length = 0;
-
- /* just read a 0 length packet */
- if (rr->length == 0) {
- empty_record_count++;
- if (empty_record_count > MAX_EMPTY_RECORDS) {
- al = SSL_AD_UNEXPECTED_MESSAGE;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_record, SSL_R_TOO_MANY_EMPTY_FRAGMENTS);
- goto f_err;
- }
- goto again;
+ case ssl_open_record_error:
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ return -1;
}
- return 1;
-
-f_err:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
-err:
- return ret;
+ assert(0);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return -1;
}
int ssl3_write_app_data(SSL *ssl, const void *buf, int len) {
@@ -404,23 +188,23 @@ 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;
}
if (i == 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_write_bytes, SSL_R_SSL_HANDSHAKE_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
return -1;
}
}
@@ -433,40 +217,29 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) {
* beyond the end of the users buffer ... so we trap and report the error in
* a way the user will notice. */
if (len < 0 || (size_t)len < tot) {
- OPENSSL_PUT_ERROR(SSL, ssl3_write_bytes, SSL_R_BAD_LENGTH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_LENGTH);
return -1;
}
- int record_split_done = 0;
n = (len - tot);
for (;;) {
/* max contains the maximum number of bytes that we can put into a
* record. */
- unsigned max = s->max_send_fragment;
- /* fragment is true if do_ssl3_write should send the first byte in its own
- * record in order to randomise a CBC IV. */
- int fragment = 0;
- if (!record_split_done && s->s3->need_record_splitting &&
- type == SSL3_RT_APPLICATION_DATA) {
- /* Only the the first record per write call needs to be split. The
- * remaining plaintext was determined before the IV was randomized. */
- fragment = 1;
- record_split_done = 1;
- }
+ unsigned max = ssl->max_send_fragment;
if (n > max) {
nw = max;
} else {
nw = n;
}
- i = do_ssl3_write(s, type, &buf[tot], nw, fragment);
+ 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;
}
@@ -475,301 +248,174 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) {
}
}
-/* ssl3_seal_record seals a new record of type |type| and plaintext |in| and
- * writes it to |out|. At most |max_out| bytes will be written. It returns one
- * on success and zero on error. On success, it updates the write sequence
- * number. */
-static int ssl3_seal_record(SSL *s, uint8_t *out, size_t *out_len,
- size_t max_out, uint8_t type, const uint8_t *in,
- size_t in_len) {
- if (max_out < SSL3_RT_HEADER_LENGTH) {
- OPENSSL_PUT_ERROR(SSL, ssl3_seal_record, SSL_R_BUFFER_TOO_SMALL);
- return 0;
- }
-
- out[0] = type;
-
- /* Some servers hang if initial ClientHello is larger than 256 bytes and
- * record version number > TLS 1.0. */
- uint16_t wire_version = s->version;
- if (!s->s3->have_version && s->version > SSL3_VERSION) {
- wire_version = TLS1_VERSION;
- }
- out[1] = wire_version >> 8;
- out[2] = wire_version & 0xff;
-
- size_t ciphertext_len;
- if (!SSL_AEAD_CTX_seal(s->aead_write_ctx, out + SSL3_RT_HEADER_LENGTH,
- &ciphertext_len, max_out - SSL3_RT_HEADER_LENGTH,
- type, wire_version, s->s3->write_sequence, in,
- in_len) ||
- !ssl3_record_sequence_update(s->s3->write_sequence, 8)) {
- return 0;
+static int ssl3_write_pending(SSL *ssl, int type, const uint8_t *buf,
+ unsigned int len) {
+ 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;
}
- if (ciphertext_len >= 1 << 16) {
- OPENSSL_PUT_ERROR(SSL, ssl3_seal_record, ERR_R_OVERFLOW);
- return 0;
+ int ret = ssl_write_buffer_flush(ssl);
+ if (ret <= 0) {
+ return ret;
}
- out[3] = ciphertext_len >> 8;
- out[4] = ciphertext_len & 0xff;
-
- *out_len = SSL3_RT_HEADER_LENGTH + ciphertext_len;
-
- if (s->msg_callback) {
- s->msg_callback(1 /* write */, 0, SSL3_RT_HEADER, out, SSL3_RT_HEADER_LENGTH,
- s, s->msg_callback_arg);
- }
-
- return 1;
+ return ssl->s3->wpend_ret;
}
-/* do_ssl3_write writes an SSL record of the given type. If |fragment| is 1
- * then it splits the record into a one byte record and a record with the rest
- * of the data in order to randomise a CBC IV. */
-static int do_ssl3_write(SSL *s, int type, const uint8_t *buf, unsigned int len,
- char fragment) {
- SSL3_BUFFER *wb = &s->s3->wbuf;
-
- /* first check if there is a SSL3_BUFFER still being written out. This will
- * happen with non blocking IO */
- if (wb->left != 0) {
- return ssl3_write_pending(s, type, buf, len);
+/* do_ssl3_write writes an SSL record of the given type. */
+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(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;
}
/* if it went, fall through and send more stuff */
}
- if (wb->buf == NULL && !ssl3_setup_write_buffer(s)) {
+ if (len > SSL3_RT_MAX_PLAIN_LENGTH) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return -1;
}
if (len == 0) {
return 0;
}
- if (len == 1) {
- /* No sense in fragmenting a one-byte record. */
- fragment = 0;
- }
- /* Align the output so the ciphertext is aligned to |SSL3_ALIGN_PAYLOAD|. */
- uintptr_t align;
- if (fragment) {
- /* Only CBC-mode ciphers require fragmenting. CBC-mode ciphertext is a
- * multiple of the block size which we may assume is aligned. Thus we only
- * need to account for a second copy of the record header. */
- align = (uintptr_t)wb->buf + 2 * SSL3_RT_HEADER_LENGTH;
- } else {
- align = (uintptr_t)wb->buf + SSL3_RT_HEADER_LENGTH;
- }
- align = (0 - align) & (SSL3_ALIGN_PAYLOAD - 1);
- uint8_t *out = wb->buf + align;
- wb->offset = align;
- size_t max_out = wb->len - wb->offset;
-
- const uint8_t *orig_buf = buf;
- unsigned int orig_len = len;
- size_t fragment_len = 0;
- if (fragment) {
- /* Write the first byte in its own record as a countermeasure against
- * known-IV weaknesses in CBC ciphersuites. (See
- * http://www.openssl.org/~bodo/tls-cbc.txt.) */
- if (!ssl3_seal_record(s, out, &fragment_len, max_out, type, buf, 1)) {
- return -1;
- }
- out += fragment_len;
- max_out -= fragment_len;
- buf++;
- len--;
+ size_t max_out = len + ssl_max_seal_overhead(ssl);
+ if (max_out < len) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ return -1;
}
-
- assert((((uintptr_t)out + SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1))
- == 0);
+ uint8_t *out;
size_t ciphertext_len;
- if (!ssl3_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;
}
- ciphertext_len += fragment_len;
-
- /* now let's set up wb */
- wb->left = 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 = orig_len;
- s->s3->wpend_buf = orig_buf;
- s->s3->wpend_type = type;
- s->s3->wpend_ret = orig_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, orig_buf, orig_len);
+ return ssl3_write_pending(ssl, type, buf, len);
}
-/* if s->s3->wbuf.left != 0, we need to call this */
-int ssl3_write_pending(SSL *s, int type, const uint8_t *buf, unsigned int len) {
- int i;
- SSL3_BUFFER *wb = &(s->s3->wbuf);
+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 (s->s3->wpend_tot > (int)len ||
- (s->s3->wpend_buf != buf &&
- !(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)) ||
- s->s3->wpend_type != type) {
- OPENSSL_PUT_ERROR(SSL, ssl3_write_pending, SSL_R_BAD_WRITE_RETRY);
- return -1;
+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);
- for (;;) {
- ERR_clear_system_error();
- if (s->wbio != NULL) {
- s->rwstate = SSL_WRITING;
- i = BIO_write(s->wbio, (char *)&(wb->buf[wb->offset]),
- (unsigned int)wb->left);
- } else {
- OPENSSL_PUT_ERROR(SSL, ssl3_write_pending, SSL_R_BIO_NOT_SET);
- i = -1;
- }
- if (i == wb->left) {
- wb->left = 0;
- wb->offset += i;
- ssl3_release_write_buffer(s);
- s->rwstate = SSL_NOTHING;
- return s->s3->wpend_ret;
- } else if (i <= 0) {
- if (SSL_IS_DTLS(s)) {
- /* For DTLS, just drop it. That's kind of the whole point in
- * using a datagram service */
- wb->left = 0;
- }
- return i;
- }
- /* TODO(davidben): This codepath is used in DTLS, but the write
- * payload may not split across packets. */
- wb->offset += i;
- wb->left -= i;
+ 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;
}
-}
-/* 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, ssl3_expect_change_cipher_spec,
- SSL_R_UNPROCESSED_HANDSHAKE_DATA);
- return 0;
+ if (ssl->msg_callback != NULL) {
+ ssl->msg_callback(0, ssl->version, SSL3_RT_CHANGE_CIPHER_SPEC, &byte, 1,
+ ssl, ssl->msg_callback_arg);
}
- s->s3->flags |= SSL3_FLAGS_EXPECT_CCS;
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);
-}
-
void ssl3_read_close_notify(SSL *ssl) {
ssl3_read_bytes(ssl, 0, NULL, 0, 0);
}
+static int ssl3_can_renegotiate(SSL *ssl) {
+ switch (ssl->renegotiate_mode) {
+ case ssl_renegotiate_never:
+ return 0;
+ case ssl_renegotiate_once:
+ return ssl->s3->total_renegotiations == 0;
+ case ssl_renegotiate_freely:
+ return 1;
+ case ssl_renegotiate_ignore:
+ return 1;
+ }
+
+ assert(0);
+ return 0;
+}
+
/* 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_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 type2, int val) = NULL;
+ 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, ssl3_read_bytes, ERR_R_INTERNAL_ERROR);
+ 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;
}
if (i == 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_SSL_HANDSHAKE_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
return -1;
}
}
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 || s->rstate == SSL_ST_READ_BODY) {
- ret = ssl3_get_record(s);
+ if (rr->length == 0) {
+ ret = ssl3_get_record(ssl);
if (ret <= 0) {
return ret;
}
@@ -777,45 +423,33 @@ 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, ssl3_read_bytes,
- 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, ssl3_read_bytes, 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 == 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 != 0 && type == rr->type) {
+ ssl->s3->warning_alert_count = 0;
+
+ /* 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;
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_APP_DATA_IN_HANDSHAKE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_APP_DATA_IN_HANDSHAKE);
goto f_err;
}
+ /* Discard empty records. */
+ if (rr->length == 0) {
+ goto start;
+ }
+
if (len <= 0) {
return len;
}
@@ -826,16 +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) {
- s->rstate = SSL_ST_READ_HEADER;
- rr->off = 0;
- if (s->s3->rbuf.left == 0) {
- ssl3_release_read_buffer(s);
- }
+ /* The record has been consumed, so we may now clear the buffer. */
+ ssl_read_buffer_discard(ssl);
}
}
@@ -844,70 +475,70 @@ 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->accept_peer_renegotiations || s->server) {
+ if (ssl->server || !ssl3_can_renegotiate(ssl)) {
al = SSL_AD_NO_RENEGOTIATION;
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_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, ssl3_read_bytes, 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);
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
goto err;
}
+ if (ssl->renegotiate_mode == ssl_renegotiate_ignore) {
+ goto start;
+ }
+
/* Renegotiation is only supported at quiescent points in the application
* 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 (s->s3->wbuf.left != 0 || s->s3->rbuf.left != 0) {
+ if (ssl_write_buffer_is_pending(ssl)) {
al = SSL_AD_NO_RENEGOTIATION;
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_NO_RENEGOTIATION);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION);
goto f_err;
}
/* Begin a new handshake. */
- 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;
}
if (i == 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_SSL_HANDSHAKE_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
return -1;
}
@@ -921,33 +552,34 @@ start:
/* Alerts may not be fragmented. */
if (rr->length < 2) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_BAD_ALERT);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ALERT);
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;
}
@@ -960,123 +592,84 @@ start:
* peer refused it where we carry on. */
else if (alert_descr == SSL_AD_NO_RENEGOTIATION) {
al = SSL_AD_HANDSHAKE_FAILURE;
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_NO_RENEGOTIATION);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION);
+ goto f_err;
+ }
+
+ 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;
}
} else if (alert_level == SSL3_AL_FATAL) {
char tmp[16];
- s->rwstate = SSL_NOTHING;
- s->s3->fatal_alert = alert_descr;
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes,
- SSL_AD_REASON_OFFSET + 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;
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_UNKNOWN_ALERT_TYPE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_ALERT_TYPE);
goto f_err;
}
goto start;
}
- if (s->shutdown & SSL_SENT_SHUTDOWN) {
- /* but we have not received a shutdown */
- s->rwstate = SSL_NOTHING;
- rr->length = 0;
- return 0;
- }
-
- 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, ssl3_read_bytes, 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, ssl3_read_bytes, 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, ssl3_read_bytes, SSL_R_CCS_RECEIVED_EARLY);
- goto f_err;
- }
-
- s->s3->flags &= ~SSL3_FLAGS_EXPECT_CCS;
-
+ if (ssl->shutdown & SSL_SENT_SHUTDOWN) {
+ /* close_notify has been sent, so discard all records other than alerts. */
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;
- }
+ 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, ssl3_read_bytes, SSL_R_UNEXPECTED_RECORD);
+ 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, ssl3_do_change_cipher_spec,
- SSL_R_CCS_RECEIVED_EARLY);
+ 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;
}
@@ -1085,16 +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 (s->s3->wbuf.left == 0) {
- /* data is still being written out. */
- return s->method->ssl_dispatch_alert(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 ssl->method->ssl_dispatch_alert(ssl);
}
/* else data is still being written out, we will get written some time in the
@@ -1102,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 val) = NULL;
+ 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, 0);
+ 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 a72e17e..49a1a95 100644
--- a/src/ssl/s3_srvr.c
+++ b/src/ssl/s3_srvr.c
@@ -146,6 +146,8 @@
* OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
* OTHERWISE. */
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <stdio.h>
#include <string.h>
@@ -172,147 +174,154 @@
#include "../crypto/dh/internal.h"
-/* INITIAL_SNIFF_BUFFER_SIZE is the number of bytes read in the initial sniff
- * buffer. */
-#define INITIAL_SNIFF_BUFFER_SIZE 8
-
-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 val) = 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_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) {
- OPENSSL_PUT_ERROR(SSL, ssl3_accept, SSL_R_NO_CERTIFICATE_SET);
+ 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_finished_mac(s)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_accept, ERR_R_INTERNAL_ERROR);
+ 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(ssl);
+ if (ret <= 0) {
+ goto end;
+ }
+ 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:
- alg_a = s->s3->tmp.new_cipher->algorithm_auth;
+ case SSL3_ST_SW_KEY_EXCH_C:
+ alg_a = ssl->s3->tmp.new_cipher->algorithm_auth;
/* Send a ServerKeyExchange message if:
* - The key exchange is ephemeral or anonymous
@@ -321,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;
}
@@ -331,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:
@@ -366,150 +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:
- ret = ssl3_get_client_key_exchange(s);
+ case SSL3_ST_SR_KEY_EXCH_C:
+ 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_new) {
- 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;
}
@@ -517,112 +525,89 @@ 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;
+ 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;
goto end;
default:
- OPENSSL_PUT_ERROR(SSL, ssl3_accept, SSL_R_UNKNOWN_STATE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_STATE);
ret = -1;
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;
}
-static int ssl3_read_sniff_buffer(SSL *s, size_t n) {
- if (s->s3->sniff_buffer == NULL) {
- s->s3->sniff_buffer = BUF_MEM_new();
- }
- if (s->s3->sniff_buffer == NULL || !BUF_MEM_grow(s->s3->sniff_buffer, n)) {
- return -1;
- }
-
- while (s->s3->sniff_buffer_len < n) {
- int ret;
-
- s->rwstate = SSL_READING;
- ret = BIO_read(s->rbio, s->s3->sniff_buffer->data + s->s3->sniff_buffer_len,
- n - s->s3->sniff_buffer_len);
- if (ret <= 0) {
- return ret;
- }
- s->rwstate = SSL_NOTHING;
- s->s3->sniff_buffer_len += ret;
- }
-
- return 1;
-}
-
-int ssl3_get_initial_bytes(SSL *s) {
- int ret;
- const uint8_t *p;
-
- /* Read the first 8 bytes. To recognize a ClientHello or V2ClientHello only
- * needs the first 6 bytes, but 8 is needed to recognize CONNECT below. */
- ret = ssl3_read_sniff_buffer(s, INITIAL_SNIFF_BUFFER_SIZE);
+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(ssl, SSL3_RT_HEADER_LENGTH);
if (ret <= 0) {
return ret;
}
- assert(s->s3->sniff_buffer_len >= INITIAL_SNIFF_BUFFER_SIZE);
- p = (const uint8_t *)s->s3->sniff_buffer->data;
+ 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
@@ -631,49 +616,28 @@ int ssl3_get_initial_bytes(SSL *s) {
strncmp("POST ", (const char *)p, 5) == 0 ||
strncmp("HEAD ", (const char *)p, 5) == 0 ||
strncmp("PUT ", (const char *)p, 4) == 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_initial_bytes, SSL_R_HTTP_REQUEST);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_HTTP_REQUEST);
return -1;
}
- if (strncmp("CONNECT ", (const char *)p, 8) == 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_initial_bytes, SSL_R_HTTPS_PROXY_REQUEST);
+ if (strncmp("CONNE", (const char *)p, 5) == 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_HTTPS_PROXY_REQUEST);
return -1;
}
- /* Determine if this is a ClientHello or V2ClientHello. */
+ /* Determine if this is a V2ClientHello. */
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;
- return 1;
- }
- if (p[0] == SSL3_RT_HANDSHAKE && p[1] >= SSL3_VERSION_MAJOR &&
- p[5] == SSL3_MT_CLIENT_HELLO) {
- /* This is a ClientHello. Initialize the record layer with the already
- * consumed data and continue the handshake. */
- if (!ssl3_setup_read_buffer(s)) {
- return -1;
- }
- assert(s->rstate == SSL_ST_READ_HEADER);
- /* There cannot have already been data in the record layer. */
- assert(s->s3->rbuf.left == 0);
- memcpy(s->s3->rbuf.buf, p, s->s3->sniff_buffer_len);
- s->s3->rbuf.offset = 0;
- s->s3->rbuf.left = s->s3->sniff_buffer_len;
- s->packet_length = 0;
-
- BUF_MEM_free(s->s3->sniff_buffer);
- s->s3->sniff_buffer = NULL;
- s->s3->sniff_buffer_len = 0;
-
- s->state = SSL3_ST_SR_CLNT_HELLO_A;
+ ssl->state = SSL3_ST_SR_V2_CLIENT_HELLO;
return 1;
}
- OPENSSL_PUT_ERROR(SSL, ssl3_get_initial_bytes, SSL_R_UNKNOWN_PROTOCOL);
- return -1;
+ /* Fall through to the standard logic. */
+ 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;
@@ -683,41 +647,39 @@ int ssl3_get_v2_client_hello(SSL *s) {
CBB client_hello, hello_body, cipher_suites;
uint8_t random[SSL3_RANDOM_SIZE];
- /* Read the remainder of the V2ClientHello. We have previously read 8 bytes
- * in ssl3_get_initial_bytes. */
- assert(s->s3->sniff_buffer_len >= INITIAL_SNIFF_BUFFER_SIZE);
- p = (const uint8_t *)s->s3->sniff_buffer->data;
+ /* Determine the length of the V2ClientHello. */
+ 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, ssl3_get_v2_client_hello, SSL_R_RECORD_TOO_LARGE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE);
return -1;
}
- if (msg_length < INITIAL_SNIFF_BUFFER_SIZE - 2) {
- /* Reject lengths that are too short early. We have already read 8 bytes,
- * so we should not attempt to process an (invalid) V2ClientHello which
- * would be shorter than that. */
- OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello,
- SSL_R_RECORD_LENGTH_MISMATCH);
+ if (msg_length < SSL3_RT_HEADER_LENGTH - 2) {
+ /* Reject lengths that are too short early. We have already read
+ * |SSL3_RT_HEADER_LENGTH| bytes, so we should not attempt to process an
+ * (invalid) V2ClientHello which would be shorter than that. */
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_LENGTH_MISMATCH);
return -1;
}
- ret = ssl3_read_sniff_buffer(s, msg_length + 2);
+ /* Read the remainder of the V2ClientHello. */
+ ret = ssl_read_buffer_extend_to(ssl, 2 + msg_length);
if (ret <= 0) {
return ret;
}
- assert(s->s3->sniff_buffer_len == msg_length + 2);
- CBS_init(&v2_client_hello, (const uint8_t *)s->s3->sniff_buffer->data + 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 Finished
+ /* The V2ClientHello without the length is incorporated into the handshake
* hash. */
- if (!ssl3_finish_mac(s, CBS_data(&v2_client_hello),
- CBS_len(&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) ||
@@ -729,7 +691,7 @@ int ssl3_get_v2_client_hello(SSL *s) {
!CBS_get_bytes(&v2_client_hello, &session_id, session_id_length) ||
!CBS_get_bytes(&v2_client_hello, &challenge, challenge_length) ||
CBS_len(&v2_client_hello) != 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
return -1;
}
@@ -747,12 +709,10 @@ int ssl3_get_v2_client_hello(SSL *s) {
rand_len);
/* Write out an equivalent SSLv3 ClientHello. */
- if (!CBB_init_fixed(&client_hello, (uint8_t *)s->init_buf->data,
- s->init_buf->max)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, ERR_R_MALLOC_FAILURE);
- return -1;
- }
- if (!CBB_add_u8(&client_hello, SSL3_MT_CLIENT_HELLO) ||
+ CBB_zero(&client_hello);
+ 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) ||
!CBB_add_bytes(&hello_body, random, SSL3_RANDOM_SIZE) ||
@@ -760,7 +720,7 @@ int ssl3_get_v2_client_hello(SSL *s) {
!CBB_add_u8(&hello_body, 0) ||
!CBB_add_u16_length_prefixed(&hello_body, &cipher_suites)) {
CBB_cleanup(&client_hello);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return -1;
}
@@ -769,7 +729,7 @@ int ssl3_get_v2_client_hello(SSL *s) {
uint32_t cipher_spec;
if (!CBS_get_u24(&cipher_specs, &cipher_spec)) {
CBB_cleanup(&client_hello);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
return -1;
}
@@ -779,7 +739,7 @@ int ssl3_get_v2_client_hello(SSL *s) {
}
if (!CBB_add_u16(&cipher_suites, cipher_spec)) {
CBB_cleanup(&client_hello);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return -1;
}
}
@@ -788,25 +748,24 @@ int ssl3_get_v2_client_hello(SSL *s) {
if (!CBB_add_u8(&hello_body, 1) || !CBB_add_u8(&hello_body, 0) ||
!CBB_finish(&client_hello, NULL, &len)) {
CBB_cleanup(&client_hello);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return -1;
}
/* 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;
- /* Drop the sniff buffer. */
- BUF_MEM_free(s->s3->sniff_buffer);
- s->s3->sniff_buffer = NULL;
- s->s3->sniff_buffer_len = 0;
+ /* Consume and discard the V2ClientHello. */
+ 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;
@@ -815,16 +774,17 @@ int ssl3_get_client_hello(SSL *s) {
CBS client_hello;
uint16_t client_version;
CBS client_random, session_id, cipher_suites, compression_methods;
+ SSL_SESSION *session = NULL;
/* We do this so that we will respond with our native type. If we are TLSv1
* 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);
@@ -832,77 +792,75 @@ 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;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello,
- SSL_R_CLIENTHELLO_PARSE_FAILED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
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:
/* Connection rejected. */
al = SSL_AD_ACCESS_DENIED;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello,
- SSL_R_CONNECTION_REJECTED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
goto f_err;
default:
/* fallthrough */;
}
}
- s->state = SSL3_ST_SR_CLNT_HELLO_D;
+ ssl->state = SSL3_ST_SR_CLNT_HELLO_D;
break;
default:
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_UNKNOWN_STATE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_STATE);
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) ||
CBS_len(&session_id) > SSL_MAX_SSL_SESSION_ID_LENGTH) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
/* 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) ||
CBS_len(&cookie) > DTLS1_COOKIE_LENGTH) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
}
@@ -912,36 +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, ssl3_get_client_hello, SSL_R_UNSUPPORTED_PROTOCOL);
- s->version = s->client_version;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL);
+ 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)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_WRONG_VERSION_NUMBER);
+ 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;
- int session_ret = ssl_get_prev_session(s, &early_ctx);
- if (session_ret == PENDING_SESSION) {
- s->rwstate = SSL_PENDING_SESSION;
- goto err;
- } else if (session_ret == -1) {
- goto err;
+ ssl->hit = 0;
+ int send_new_ticket = 0;
+ 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:
+ ssl->rwstate = SSL_PENDING_SESSION;
+ goto err;
}
+ 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
@@ -950,40 +912,54 @@ 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) &&
ems_len == 0;
- if (session_ret == 1) {
- if (s->session->extended_master_secret &&
+ if (session != NULL) {
+ if (session->extended_master_secret &&
!have_extended_master_secret) {
/* A ClientHello without EMS that attempts to resume a session with EMS
* is fatal to the connection. */
al = SSL_AD_HANDSHAKE_FAILURE;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello,
- SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION);
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 == s->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 == s->session->extended_master_secret;
+ have_extended_master_secret == session->extended_master_secret;
}
- if (!s->hit && !ssl_get_new_session(s, 1)) {
- goto err;
+ if (ssl->hit) {
+ /* Use the new session. */
+ SSL_SESSION_free(ssl->session);
+ ssl->session = session;
+ session = NULL;
+
+ ssl->verify_result = ssl->session->verify_result;
+ } else {
+ if (!ssl_get_new_session(ssl, 1 /* server */)) {
+ goto err;
+ }
+
+ /* Clear the session ID if we want the session to be single-use. */
+ 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, ssl3_get_client_hello, SSL_R_CONNECTION_REJECTED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
goto f_err;
}
@@ -993,20 +969,20 @@ int ssl3_get_client_hello(SSL *s) {
!CBS_get_u8_length_prefixed(&client_hello, &compression_methods) ||
CBS_len(&compression_methods) == 0) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
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);
@@ -1020,8 +996,7 @@ int ssl3_get_client_hello(SSL *s) {
/* we need to have the cipher in the cipher list if we are asked to reuse
* it */
al = SSL_AD_ILLEGAL_PARAMETER;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello,
- SSL_R_REQUIRED_CIPHER_MISSING);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_REQUIRED_CIPHER_MISSING);
goto f_err;
}
}
@@ -1030,15 +1005,14 @@ int ssl3_get_client_hello(SSL *s) {
if (memchr(CBS_data(&compression_methods), 0,
CBS_len(&compression_methods)) == NULL) {
al = SSL_AD_ILLEGAL_PARAMETER;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello,
- SSL_R_NO_COMPRESSION_SPECIFIED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_COMPRESSION_SPECIFIED);
goto f_err;
}
/* TLS extensions. */
- if (s->version >= SSL3_VERSION &&
- !ssl_parse_clienthello_tlsext(s, &client_hello)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_PARSE_TLSEXT);
+ if (ssl->version >= SSL3_VERSION &&
+ !ssl_parse_clienthello_tlsext(ssl, &client_hello)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT);
goto err;
}
@@ -1046,69 +1020,73 @@ int ssl3_get_client_hello(SSL *s) {
if (CBS_len(&client_hello) != 0) {
/* wrong packet length */
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_BAD_PACKET_LENGTH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_PACKET_LENGTH);
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, ssl3_get_client_hello, SSL_R_EMS_STATE_INCONSISTENT);
+ 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, ssl3_get_client_hello, SSL_R_NO_CIPHERS_PASSED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHERS_PASSED);
goto f_err;
}
/* 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, ssl3_get_client_hello, SSL_R_CERT_CB_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, ssl3_get_client_hello, SSL_R_NO_SHARED_CIPHER);
+ 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(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_digest_cached_records(s, free_handshake_buffer)) {
- goto f_err;
+ if (!SSL_USE_SIGALGS(ssl) || !ssl->s3->tmp.cert_request) {
+ ssl3_free_handshake_buffer(ssl);
}
/* we now have the following setup;
@@ -1117,408 +1095,297 @@ 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:
sk_SSL_CIPHER_free(ciphers);
+ SSL_SESSION_free(session);
return ret;
}
-int ssl3_send_server_hello(SSL *s) {
- uint8_t *buf;
- uint8_t *p, *d;
- int sl;
- unsigned long l;
+int ssl3_send_server_hello(SSL *ssl) {
+ if (ssl->state == SSL3_ST_SW_SRVR_HELLO_B) {
+ return ssl_do_write(ssl);
+ }
- if (s->state == SSL3_ST_SW_SRVR_HELLO_A) {
- /* We only accept ChannelIDs on connections with ECDHE in order to avoid a
- * known attack while we fix ChannelID itself. */
- if (s->s3->tlsext_channel_id_valid &&
- (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kECDHE) == 0) {
- s->s3->tlsext_channel_id_valid = 0;
- }
+ assert(ssl->state == SSL3_ST_SW_SRVR_HELLO_A);
- /* If this is a resumption and the original handshake didn't support
- * ChannelID then we didn't record the original handshake hashes in the
- * session and so cannot resume with ChannelIDs. */
- if (s->hit && s->s3->tlsext_channel_id_new &&
- s->session->original_handshake_hash_len == 0) {
- s->s3->tlsext_channel_id_valid = 0;
- }
+ /* We only accept ChannelIDs on connections with ECDHE in order to avoid a
+ * known attack while we fix ChannelID itself. */
+ if (ssl->s3->tlsext_channel_id_valid &&
+ (ssl->s3->tmp.new_cipher->algorithm_mkey & SSL_kECDHE) == 0) {
+ ssl->s3->tlsext_channel_id_valid = 0;
+ }
- buf = (uint8_t *)s->init_buf->data;
- /* Do the message type and length last */
- d = p = ssl_handshake_start(s);
+ /* If this is a resumption and the original handshake didn't support
+ * ChannelID then we didn't record the original handshake hashes in the
+ * session and so cannot resume with ChannelIDs. */
+ if (ssl->hit && ssl->session->original_handshake_hash_len == 0) {
+ ssl->s3->tlsext_channel_id_valid = 0;
+ }
- *(p++) = s->version >> 8;
- *(p++) = s->version & 0xff;
+ if (!ssl_fill_hello_random(ssl->s3->server_random, SSL3_RANDOM_SIZE,
+ 1 /* server */)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
- /* Random stuff */
- if (!ssl_fill_hello_random(s->s3->server_random, SSL3_RANDOM_SIZE,
- 1 /* server */)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_hello, ERR_R_INTERNAL_ERROR);
- return -1;
- }
- memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE);
- p += SSL3_RANDOM_SIZE;
-
- /* There are several cases for the session ID to send
- * back in the server hello:
- * - For session reuse from the session cache, we send back the old session
- * ID.
- * - If stateless session reuse (using a session ticket) is successful, we
- * send back the client's "session ID" (which doesn't actually identify
- * the session).
- * - If it is a new session, we send back the new session ID.
- * - However, if we want the new session to be single-use, we send back a
- * 0-length session ID.
- * s->hit is non-zero in either case of session reuse, so the following
- * won't overwrite an ID that we're supposed to send back. */
- if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER) && !s->hit) {
- s->session->session_id_length = 0;
- }
-
- sl = s->session->session_id_length;
- if (sl > (int)sizeof(s->session->session_id)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_hello, ERR_R_INTERNAL_ERROR);
- return -1;
- }
- *(p++) = sl;
- memcpy(p, s->session->session_id, sl);
- p += sl;
+ CBB cbb, session_id;
+ size_t length;
+ CBB_zero(&cbb);
+ if (!CBB_init_fixed(&cbb, ssl_handshake_start(ssl),
+ ssl->init_buf->max - SSL_HM_HEADER_LENGTH(ssl)) ||
+ !CBB_add_u16(&cbb, ssl->version) ||
+ !CBB_add_bytes(&cbb, ssl->s3->server_random, SSL3_RANDOM_SIZE) ||
+ !CBB_add_u8_length_prefixed(&cbb, &session_id) ||
+ !CBB_add_bytes(&session_id, ssl->session->session_id,
+ ssl->session->session_id_length) ||
+ !CBB_add_u16(&cbb, ssl_cipher_get_value(ssl->s3->tmp.new_cipher)) ||
+ !CBB_add_u8(&cbb, 0 /* no compression */) ||
+ !ssl_add_serverhello_tlsext(ssl, &cbb) ||
+ !CBB_finish(&cbb, NULL, &length) ||
+ !ssl_set_handshake_header(ssl, SSL3_MT_SERVER_HELLO, length)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ CBB_cleanup(&cbb);
+ return -1;
+ }
- /* put the cipher */
- s2n(ssl_cipher_get_value(s->s3->tmp.new_cipher), p);
+ ssl->state = SSL3_ST_SW_SRVR_HELLO_B;
+ return ssl_do_write(ssl);
+}
- /* put the compression method */
- *(p++) = 0;
- if (ssl_prepare_serverhello_tlsext(s) <= 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_hello, SSL_R_SERVERHELLO_TLSEXT);
- return -1;
- }
- p = ssl_add_serverhello_tlsext(s, p, buf + SSL3_RT_MAX_PLAIN_LENGTH);
- if (p == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_hello, ERR_R_INTERNAL_ERROR);
+int ssl3_send_certificate_status(SSL *ssl) {
+ if (ssl->state == SSL3_ST_SW_CERT_STATUS_A) {
+ CBB out, ocsp_response;
+ size_t length;
+
+ CBB_zero(&out);
+ if (!CBB_init_fixed(&out, ssl_handshake_start(ssl),
+ ssl->init_buf->max - SSL_HM_HEADER_LENGTH(ssl)) ||
+ !CBB_add_u8(&out, TLSEXT_STATUSTYPE_ocsp) ||
+ !CBB_add_u24_length_prefixed(&out, &ocsp_response) ||
+ !CBB_add_bytes(&ocsp_response, ssl->ctx->ocsp_response,
+ ssl->ctx->ocsp_response_length) ||
+ !CBB_finish(&out, NULL, &length) ||
+ !ssl_set_handshake_header(ssl, SSL3_MT_CERTIFICATE_STATUS, length)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ CBB_cleanup(&out);
return -1;
}
- /* do the header */
- l = (p - d);
- if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_HELLO, l)) {
- return -1;
- }
- s->state = SSL3_ST_SW_SRVR_HELLO_B;
+ ssl->state = SSL3_ST_SW_CERT_STATUS_B;
}
- /* SSL3_ST_SW_SRVR_HELLO_B */
- return ssl_do_write(s);
+ /* SSL3_ST_SW_CERT_STATUS_B */
+ 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;
- EVP_PKEY *pkey;
- 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], kn;
- BUF_MEM *buf;
- EVP_MD_CTX md_ctx;
+int ssl3_send_server_key_exchange(SSL *ssl) {
+ if (ssl->state == SSL3_ST_SW_KEY_EXCH_C) {
+ return ssl_do_write(ssl);
+ }
- EVP_MD_CTX_init(&md_ctx);
- 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;
+ CBB cbb, child;
+ if (!CBB_init_fixed(&cbb, ssl_handshake_start(ssl),
+ ssl->init_buf->max - SSL_HM_HEADER_LENGTH(ssl))) {
+ goto err;
+ }
- buf = s->init_buf;
+ 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;
- 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;
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange,
- SSL_R_MISSING_TMP_DH_KEY);
- goto f_err;
- }
-
- if (s->s3->tmp.dh != NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange,
- ERR_R_INTERNAL_ERROR);
+ if (params == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_TMP_DH_KEY);
+ 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, ssl3_send_server_key_exchange, ERR_R_DH_LIB);
goto err;
}
- s->s3->tmp.dh = dh;
- if (!DH_generate_key(dh)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, 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;
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange,
- SSL_R_MISSING_TMP_ECDH_KEY);
- goto f_err;
- }
-
- if (s->s3->tmp.ecdh != NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange,
- ERR_R_INTERNAL_ERROR);
+ uint16_t curve_id;
+ if (!tls1_get_shared_curve(ssl, &curve_id)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_TMP_ECDH_KEY);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
goto err;
}
- ecdh = EC_KEY_new_by_curve_name(nid);
- if (ecdh == NULL) {
+ 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;
}
- s->s3->tmp.ecdh = ecdh;
-
- if (!EC_KEY_generate_key(ecdh)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, 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, ssl3_send_server_key_exchange,
- SSL_R_UNSUPPORTED_ELLIPTIC_CURVE);
- 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, ssl3_send_server_key_exchange,
- 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, ssl3_send_server_key_exchange, ERR_R_ECDH_LIB);
- 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, ssl3_send_server_key_exchange,
- SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
- goto f_err;
- }
-
- for (i = 0; i < 4 && r[i] != NULL; i++) {
- nr[i] = BN_num_bytes(r[i]);
- n += 2 + nr[i];
- }
-
- if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) {
- pkey = ssl_get_sign_pkey(s, s->s3->tmp.new_cipher);
- if (pkey == NULL) {
- al = SSL_AD_DECODE_ERROR;
- goto f_err;
- }
- kn = EVP_PKEY_size(pkey);
} else {
- pkey = NULL;
- kn = 0;
+ assert(alg_k & SSL_kPSK);
}
- if (!BUF_MEM_grow_clean(buf, n + SSL_HM_HEADER_LENGTH(s) + kn)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, ERR_LIB_BUF);
- goto err;
- }
- d = p = ssl_handshake_start(s);
+ /* 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;
+ }
- for (i = 0; i < 4 && r[i] != NULL; i++) {
- s2n(nr[i], p);
- BN_bn2bin(r[i], p);
- p += nr[i];
+ /* 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;
}
- /* 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;
- }
-
- /* not anonymous */
- if (pkey != NULL) {
- /* n is the length of the params, they start at &(d[4]) and p points to
- * the space at the end. */
- const EVP_MD *md;
- size_t sig_len = EVP_PKEY_size(pkey);
+ size_t params_len = CBB_len(&cbb);
/* Determine signature algorithm. */
- if (SSL_USE_SIGALGS(s)) {
- md = tls1_choose_signing_digest(s, pkey);
- if (!tls12_get_sigandhash(p, pkey, md)) {
- /* Should never happen */
- al = SSL_AD_INTERNAL_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange,
- ERR_R_INTERNAL_ERROR);
- goto f_err;
+ 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);
+ 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_DigestSignInit(&md_ctx, NULL, md, NULL, pkey) ||
- !EVP_DigestSignUpdate(&md_ctx, s->s3->client_random,
- SSL3_RANDOM_SIZE) ||
- !EVP_DigestSignUpdate(&md_ctx, s->s3->server_random,
- SSL3_RANDOM_SIZE) ||
- !EVP_DigestSignUpdate(&md_ctx, d, n) ||
- !EVP_DigestSignFinal(&md_ctx, &p[2], &sig_len)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, 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(ssl, ptr, &sig_len, max_sig_len, md,
+ digest, digest_len);
+ } else {
+ assert(ssl->state == SSL3_ST_SW_KEY_EXCH_B);
- s2n(sig_len, p);
- n += sig_len + 2;
- if (SSL_USE_SIGALGS(s)) {
- n += 2;
+ /* 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);
}
- if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_KEY_EXCHANGE, n)) {
- 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;
}
}
- s->state = SSL3_ST_SW_KEY_EXCH_B;
- EVP_MD_CTX_cleanup(&md_ctx);
- return ssl_do_write(s);
+ size_t length;
+ if (!CBB_finish(&cbb, NULL, &length) ||
+ !ssl_set_handshake_header(ssl, SSL3_MT_SERVER_KEY_EXCHANGE, length)) {
+ goto err;
+ }
+ 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;
@@ -1526,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;
@@ -1551,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)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_certificate_request, ERR_R_BUF_LIB);
+ 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;
@@ -1570,56 +1437,48 @@ 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;
}
-int ssl3_get_client_key_exchange(SSL *s) {
- int al, ok;
- long n;
+int ssl3_get_client_key_exchange(SSL *ssl) {
+ int al;
CBS client_key_exchange;
uint32_t alg_k;
uint32_t alg_a;
uint8_t *premaster_secret = NULL;
size_t premaster_secret_len = 0;
- RSA *rsa = NULL;
uint8_t *decrypt_buf = NULL;
- EVP_PKEY *pkey = 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;
- uint8_t psk[PSK_MAX_PSK_LEN];
- n = s->method->ssl_get_message(s, SSL3_ST_SR_KEY_EXCH_A,
- SSL3_ST_SR_KEY_EXCH_B,
- SSL3_MT_CLIENT_KEY_EXCHANGE, 2048, /* ??? */
- ssl_hash_message, &ok);
+ unsigned psk_len = 0;
+ uint8_t psk[PSK_MAX_PSK_LEN];
- if (!ok) {
- return n;
+ if (ssl->state == SSL3_ST_SR_KEY_EXCH_A ||
+ ssl->state == SSL3_ST_SR_KEY_EXCH_B) {
+ int ok;
+ 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, n);
-
- 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) {
@@ -1629,45 +1488,40 @@ int ssl3_get_client_key_exchange(SSL *s) {
* then this is the only field in the message. */
if (!CBS_get_u16_length_prefixed(&client_key_exchange, &psk_identity) ||
((alg_k & SSL_kPSK) && CBS_len(&client_key_exchange) != 0)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
al = SSL_AD_DECODE_ERROR;
goto f_err;
}
- if (s->psk_server_callback == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- SSL_R_PSK_NO_SERVER_CB);
+ if (ssl->psk_server_callback == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_NO_SERVER_CB);
al = SSL_AD_INTERNAL_ERROR;
goto f_err;
}
if (CBS_len(&psk_identity) > PSK_MAX_IDENTITY_LEN ||
CBS_contains_zero_byte(&psk_identity)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- SSL_R_DATA_LENGTH_TOO_LONG);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
al = SSL_AD_ILLEGAL_PARAMETER;
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, ssl3_get_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
+ 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, ssl3_get_client_key_exchange,
- ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
al = SSL_AD_INTERNAL_ERROR;
goto f_err;
} else if (psk_len == 0) {
/* PSK related to the given identity not found */
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- SSL_R_PSK_IDENTITY_NOT_FOUND);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND);
al = SSL_AD_UNKNOWN_PSK_IDENTITY;
goto f_err;
}
@@ -1676,284 +1530,153 @@ 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 rsa_size, decrypt_len, premaster_index, j;
-
- pkey = s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey;
- if (pkey == NULL || pkey->type != EVP_PKEY_RSA || pkey->pkey.rsa == NULL) {
- al = SSL_AD_HANDSHAKE_FAILURE;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- SSL_R_MISSING_RSA_CERTIFICATE);
- goto f_err;
+ /* 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);
+ goto err;
}
- rsa = pkey->pkey.rsa;
- /* TLS and [incidentally] DTLS{0xFEFF} */
- if (s->version > SSL3_VERSION) {
- CBS copy = client_key_exchange;
- 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)) {
+ enum ssl_private_key_result_t decrypt_result;
+ 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;
+ }
+ 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) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
+ OPENSSL_PUT_ERROR(SSL,
SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
goto f_err;
- } else {
- encrypted_premaster_secret = copy;
}
+ } else {
+ encrypted_premaster_secret = client_key_exchange;
}
- } 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. */
- rsa_size = RSA_size(rsa);
- if (rsa_size < SSL_MAX_MASTER_KEY_LENGTH) {
- al = SSL_AD_DECRYPT_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- SSL_R_DECRYPTION_FAILED);
- goto f_err;
- }
- /* 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))) {
- goto 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(
+ ssl, decrypt_buf, &decrypt_len, rsa_size,
+ CBS_data(&encrypted_premaster_secret),
+ CBS_len(&encrypted_premaster_secret));
+ } else {
+ assert(ssl->state == SSL3_ST_SR_KEY_EXCH_C);
+ /* Complete async decrypt. */
+ decrypt_result = ssl_private_key_decrypt_complete(
+ ssl, decrypt_buf, &decrypt_len, rsa_size);
}
- /* Allocate a buffer large enough for an RSA decryption. */
- decrypt_buf = OPENSSL_malloc(rsa_size);
- if (decrypt_buf == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
- goto err;
+ switch (decrypt_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_SR_KEY_EXCH_C;
+ goto err;
}
- /* Decrypt with no padding. PKCS#1 padding will be removed as part of the
- * timing-sensitive code below. */
- if (!RSA_decrypt(rsa, &decrypt_len, decrypt_buf, rsa_size,
- CBS_data(&encrypted_premaster_secret),
- CBS_len(&encrypted_premaster_secret), RSA_NO_PADDING)) {
- 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, ssl3_get_client_key_exchange,
- 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, ssl3_get_client_key_exchange,
- 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));
-
- /* 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, ssl3_get_client_key_exchange,
- 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, ssl3_get_client_key_exchange,
- SSL_R_MISSING_TMP_DH_KEY);
- 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, ssl3_get_client_key_exchange, SSL_R_BN_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
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, ssl3_get_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
- BN_clear_free(pub);
+ if (!RAND_bytes(premaster_secret, premaster_secret_len)) {
goto err;
}
- dh_len = DH_compute_key(premaster_secret, pub, dh_srvr);
- if (dh_len <= 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, ERR_R_DH_LIB);
- BN_clear_free(pub);
- goto err;
+ /* 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_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 field_size = 0, 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, ssl3_get_client_key_exchange,
- 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;
-
- group = EC_KEY_get0_group(tkey);
- priv_key = EC_KEY_get0_private_key(tkey);
+ /* 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));
- if (!EC_KEY_set_group(srvr_ecdh, group) ||
- !EC_KEY_set_private_key(srvr_ecdh, priv_key)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, 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, ssl3_get_client_key_exchange,
- 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, ssl3_get_client_key_exchange, SSL_R_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, ssl3_get_client_key_exchange,
- 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, ssl3_get_client_key_exchange, ERR_R_EC_LIB);
- goto err;
- }
-
- /* Allocate a buffer for both the secret and the PSK. */
- field_size = EC_GROUP_get_degree(group);
- if (field_size <= 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, 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, ssl3_get_client_key_exchange,
- 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, ssl3_get_client_key_exchange, 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. */
premaster_secret_len = psk_len;
premaster_secret = OPENSSL_malloc(premaster_secret_len);
if (premaster_secret == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
memset(premaster_secret, 0, premaster_secret_len);
} else {
al = SSL_AD_HANDSHAKE_FAILURE;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- SSL_R_UNKNOWN_CIPHER_TYPE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CIPHER_TYPE);
goto f_err;
}
@@ -1964,18 +1687,14 @@ int ssl3_get_client_key_exchange(SSL *s) {
uint8_t *new_data;
size_t new_len;
- if (!CBB_init(&new_premaster, 2 + psk_len + 2 + premaster_secret_len)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
- goto err;
- }
- if (!CBB_add_u16_length_prefixed(&new_premaster, &child) ||
+ CBB_zero(&new_premaster);
+ if (!CBB_init(&new_premaster, 2 + psk_len + 2 + premaster_secret_len) ||
+ !CBB_add_u16_length_prefixed(&new_premaster, &child) ||
!CBB_add_bytes(&child, premaster_secret, premaster_secret_len) ||
!CBB_add_u16_length_prefixed(&new_premaster, &child) ||
!CBB_add_bytes(&child, psk, psk_len) ||
!CBB_finish(&new_premaster, &new_data, &new_len)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
CBB_cleanup(&new_premaster);
goto err;
}
@@ -1987,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];
@@ -2031,15 +1744,12 @@ int ssl3_get_cert_verify(SSL *s) {
* CertificateVerify is required if and only if there's a client certificate.
* */
if (peer == NULL) {
- if (s->s3->handshake_buffer &&
- !ssl3_digest_cached_records(s, free_handshake_buffer)) {
- return -1;
- }
+ 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);
@@ -2055,31 +1765,35 @@ int ssl3_get_cert_verify(SSL *s) {
if (!(X509_certificate_type(peer, pkey) & EVP_PKT_SIGN) ||
(pkey->type != EVP_PKEY_RSA && pkey->type != EVP_PKEY_EC)) {
al = SSL_AD_UNSUPPORTED_CERTIFICATE;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_verify,
- SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
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) &&
- !tls12_check_peer_sigalg(&md, &al, s, &certificate_verify, pkey)) {
- goto f_err;
+ if (SSL_USE_SIGALGS(ssl)) {
+ uint8_t hash, signature_type;
+ if (!CBS_get_u8(&certificate_verify, &hash) ||
+ !CBS_get_u8(&certificate_verify, &signature_type)) {
+ al = SSL_AD_DECODE_ERROR;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
+ goto f_err;
+ }
+ 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)) {
+ 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.*/
- if (s->s3->handshake_buffer &&
- !ssl3_digest_cached_records(s, free_handshake_buffer)) {
- goto err;
- }
- if (!ssl3_hash_current_message(s)) {
+ ssl3_free_handshake_buffer(ssl);
+ if (!ssl3_hash_current_message(ssl)) {
goto err;
}
@@ -2087,7 +1801,7 @@ int ssl3_get_cert_verify(SSL *s) {
if (!CBS_get_u16_length_prefixed(&certificate_verify, &signature) ||
CBS_len(&certificate_verify) != 0) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_verify, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
@@ -2100,7 +1814,7 @@ int ssl3_get_cert_verify(SSL *s) {
!EVP_PKEY_verify(pctx, CBS_data(&signature), CBS_len(&signature), digest,
digest_length)) {
al = SSL_AD_DECRYPT_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_verify, SSL_R_BAD_SIGNATURE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE);
goto f_err;
}
@@ -2108,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:
@@ -2118,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;
@@ -2127,53 +1841,52 @@ 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)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate,
- SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
+ 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) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate,
+ 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, ssl3_get_client_certificate,
- SSL_R_WRONG_MESSAGE_TYPE);
+ 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) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!CBS_get_u24_length_prefixed(&certificate_msg, &certificate_list) ||
CBS_len(&certificate_msg) != 0) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
@@ -2183,87 +1896,71 @@ int ssl3_get_client_certificate(SSL *s) {
if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate)) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
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, ssl3_get_client_certificate, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
goto f_err;
}
if (data != CBS_data(&certificate) + CBS_len(&certificate)) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate,
- SSL_R_CERT_LENGTH_MISMATCH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH);
goto f_err;
}
if (!sk_X509_push(sk, x)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
x = NULL;
}
if (sk_X509_num(sk) <= 0) {
+ /* No client certificate so the handshake buffer may be discarded. */
+ 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, ssl3_get_client_certificate,
- SSL_R_NO_CERTIFICATES_RETURNED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATES_RETURNED);
goto f_err;
- }
- /* Fail for TLS only if we required a certificate */
- else if ((s->verify_mode & SSL_VERIFY_PEER) &&
- (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate,
- SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
+ } 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;
}
- /* No client certificate so digest cached records */
- if (s->s3->handshake_buffer &&
- !ssl3_digest_cached_records(s, free_handshake_buffer)) {
- al = SSL_AD_INTERNAL_ERROR;
- 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);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate,
- SSL_R_CERTIFICATE_VERIFY_FAILED);
+ 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;
- /* With the current implementation, sess_cert will always be NULL when we
- * arrive here. */
- if (s->session->sess_cert == NULL) {
- s->session->sess_cert = ssl_sess_cert_new();
- if (s->session->sess_cert == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- }
- sk_X509_pop_free(s->session->sess_cert->cert_chain, X509_free);
- s->session->sess_cert->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 */
@@ -2273,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:
@@ -2282,29 +1979,20 @@ err:
return ret;
}
-int ssl3_send_server_certificate(SSL *s) {
- CERT_PKEY *cpk;
-
- if (s->state == SSL3_ST_SW_CERT_A) {
- cpk = ssl_get_server_send_pkey(s);
- if (cpk == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_certificate,
- ERR_R_INTERNAL_ERROR);
+int ssl3_send_server_certificate(SSL *ssl) {
+ if (ssl->state == SSL3_ST_SW_CERT_A) {
+ if (!ssl3_output_cert_chain(ssl)) {
return 0;
}
-
- if (!ssl3_output_cert_chain(s, cpk)) {
- 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;
@@ -2314,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 +
@@ -2327,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;
}
@@ -2340,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. */
@@ -2348,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;
}
@@ -2385,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;
@@ -2414,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);
@@ -2436,20 +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) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_next_proto,
- SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION);
+ 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);
@@ -2458,19 +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, ssl3_get_next_proto,
- 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;
@@ -2480,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;
}
@@ -2489,14 +2165,13 @@ 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;
- EVP_MD_CTX md_ctx;
- uint8_t channel_id_hash[SHA256_DIGEST_LENGTH];
- unsigned int channel_id_hash_len;
+ uint8_t channel_id_hash[EVP_MAX_MD_SIZE];
+ size_t channel_id_hash_len;
const uint8_t *p;
- uint16_t extension_type, expected_extension_type;
+ uint16_t extension_type;
EC_GROUP *p256 = NULL;
EC_KEY *key = NULL;
EC_POINT *point = NULL;
@@ -2504,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);
@@ -2515,33 +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. */
- channel_id_hash_len = sizeof(channel_id_hash);
- EVP_MD_CTX_init(&md_ctx);
- if (!EVP_DigestInit_ex(&md_ctx, EVP_sha256(), NULL) ||
- !tls1_channel_id_hash(&md_ctx, s) ||
- !EVP_DigestFinal(&md_ctx, channel_id_hash, &channel_id_hash_len)) {
- EVP_MD_CTX_cleanup(&md_ctx);
+ if (!tls1_channel_id_hash(ssl, channel_id_hash, &channel_id_hash_len)) {
return -1;
}
- EVP_MD_CTX_cleanup(&md_ctx);
assert(channel_id_hash_len == SHA256_DIGEST_LENGTH);
- if (!ssl3_hash_current_message(s)) {
- 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, ssl3_get_channel_id,
- SSL_R_GOT_CHANNEL_ID_BEFORE_A_CCS);
+ if (!ssl3_hash_current_message(ssl)) {
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
@@ -2554,23 +2212,19 @@ int ssl3_get_channel_id(SSL *s) {
* uint8 y[32];
* uint8 r[32];
* uint8 s[32]; */
- expected_extension_type = TLSEXT_TYPE_channel_id;
- if (s->s3->tlsext_channel_id_new) {
- expected_extension_type = TLSEXT_TYPE_channel_id_new;
- }
if (!CBS_get_u16(&encrypted_extensions, &extension_type) ||
!CBS_get_u16_length_prefixed(&encrypted_extensions, &extension) ||
CBS_len(&encrypted_extensions) != 0 ||
- extension_type != expected_extension_type ||
+ extension_type != TLSEXT_TYPE_channel_id ||
CBS_len(&extension) != TLSEXT_CHANNEL_ID_SIZE) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_channel_id, SSL_R_INVALID_MESSAGE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_MESSAGE);
return -1;
}
p256 = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
if (!p256) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_channel_id, SSL_R_NO_P256_SUPPORT);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_P256_SUPPORT);
return -1;
}
@@ -2591,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;
}
@@ -2604,13 +2259,12 @@ int ssl3_get_channel_id(SSL *s) {
/* We stored the handshake hash in |tlsext_channel_id| the first time that we
* were called. */
if (!ECDSA_do_verify(channel_id_hash, channel_id_hash_len, &sig, key)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_channel_id,
- SSL_R_CHANNEL_ID_SIGNATURE_INVALID);
- s->s3->tlsext_channel_id_valid = 0;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_SIGNATURE_INVALID);
+ 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 c2fba1d..8829679 100644
--- a/src/ssl/ssl_aead_ctx.c
+++ b/src/ssl/ssl_aead_ctx.c
@@ -12,6 +12,8 @@
* 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>
@@ -34,7 +36,7 @@ SSL_AEAD_CTX *SSL_AEAD_CTX_new(enum evp_aead_direction_t direction,
const EVP_AEAD *aead;
size_t discard;
if (!ssl_cipher_get_evp_aead(&aead, &discard, &discard, cipher, version)) {
- OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_new, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return 0;
}
@@ -43,7 +45,7 @@ SSL_AEAD_CTX *SSL_AEAD_CTX_new(enum evp_aead_direction_t direction,
/* This is a "stateful" AEAD (for compatibility with pre-AEAD cipher
* suites). */
if (mac_key_len + enc_key_len + fixed_iv_len > sizeof(merged_key)) {
- OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_new, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return 0;
}
memcpy(merged_key, mac_key, mac_key_len);
@@ -56,7 +58,7 @@ SSL_AEAD_CTX *SSL_AEAD_CTX_new(enum evp_aead_direction_t direction,
SSL_AEAD_CTX *aead_ctx = (SSL_AEAD_CTX *)OPENSSL_malloc(sizeof(SSL_AEAD_CTX));
if (aead_ctx == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return NULL;
}
memset(aead_ctx, 0, sizeof(SSL_AEAD_CTX));
@@ -72,20 +74,24 @@ 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, SSL_AEAD_CTX_new, 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;
- aead_ctx->variable_nonce_included_in_record =
- (cipher->algorithm2 &
- SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD) != 0;
+
+ 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;
+ }
} else {
aead_ctx->variable_nonce_included_in_record = 1;
aead_ctx->random_variable_nonce = 1;
@@ -146,7 +152,7 @@ int SSL_AEAD_CTX_open(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len,
if (aead == NULL) {
/* Handle the initial NULL cipher. */
if (in_len > max_out) {
- OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_open, SSL_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
return 0;
}
memmove(out, in, in_len);
@@ -161,7 +167,7 @@ int SSL_AEAD_CTX_open(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len,
size_t overhead = SSL_AEAD_CTX_max_overhead(aead);
if (in_len < overhead) {
/* Publicly invalid. */
- OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_open, SSL_R_BAD_PACKET_LENGTH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_PACKET_LENGTH);
return 0;
}
plaintext_len = in_len - overhead;
@@ -173,12 +179,21 @@ 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. */
- OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_open, SSL_R_BAD_PACKET_LENGTH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_PACKET_LENGTH);
return 0;
}
memcpy(nonce + nonce_len, in, aead->variable_nonce_len);
@@ -190,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);
}
@@ -201,7 +225,7 @@ int SSL_AEAD_CTX_seal(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len,
if (aead == NULL) {
/* Handle the initial NULL cipher. */
if (in_len > max_out) {
- OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_seal, SSL_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
return 0;
}
memmove(out, in, in_len);
@@ -216,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)) {
@@ -227,19 +260,20 @@ 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_AEAD_CTX_seal, SSL_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
return 0;
}
if (out < in + in_len && in < out + aead->variable_nonce_len) {
- OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_seal, SSL_R_OUTPUT_ALIASES_INPUT);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT);
return 0;
}
memcpy(out, nonce + aead->fixed_nonce_len, aead->variable_nonce_len);
@@ -248,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 d1ac1b6..5ec33eb 100644
--- a/src/ssl/ssl_asn1.c
+++ b/src/ssl/ssl_asn1.c
@@ -80,6 +80,8 @@
* OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
* OTHERWISE. */
+#include <openssl/ssl.h>
+
#include <limits.h>
#include <string.h>
@@ -114,8 +116,10 @@
* signedCertTimestampList [15] OCTET STRING OPTIONAL,
* -- contents of SCT extension
* ocspResponse [16] OCTET STRING OPTIONAL,
- * -- stapled OCSP response from the server
+ * -- stapled OCSP response from the server
* extendedMasterSecret [17] BOOLEAN OPTIONAL,
+ * keyExchangeInfo [18] INTEGER OPTIONAL,
+ * certChain [19] SEQUENCE OF Certificate OPTIONAL,
* }
*
* Note: historically this serialization has included other optional
@@ -126,13 +130,15 @@
* compressionMethod [11] OCTET STRING OPTIONAL,
* srpUsername [12] OCTET STRING OPTIONAL, */
+static const unsigned kVersion = 1;
+
static const int kTimeTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1;
static const int kTimeoutTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 2;
static const int kPeerTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3;
- static const int kSessionIDContextTag =
+static const int kSessionIDContextTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 4;
static const int kVerifyResultTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 5;
@@ -154,8 +160,28 @@ static const int kOCSPResponseTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 16;
static const int kExtendedMasterSecretTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 17;
+static const int kKeyExchangeInfoTag =
+ CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 18;
+static const int kCertChainTag =
+ CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 19;
+
+static int add_X509(CBB *cbb, X509 *x509) {
+ int len = i2d_X509(x509, NULL);
+ if (len < 0) {
+ return 0;
+ }
+ uint8_t *buf;
+ if (!CBB_add_space(cbb, &buf, len)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ if (buf != NULL && i2d_X509(x509, &buf) < 0) {
+ return 0;
+ }
+ return 1;
+}
-static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
+static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, uint8_t **out_data,
size_t *out_len, int for_ticket) {
CBB cbb, session, child, child2;
@@ -163,12 +189,10 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
return 0;
}
- if (!CBB_init(&cbb, 0)) {
- return 0;
- }
-
- if (!CBB_add_asn1(&cbb, &session, CBS_ASN1_SEQUENCE) ||
- !CBB_add_asn1_uint64(&session, SSL_SESSION_ASN1_VERSION) ||
+ CBB_zero(&cbb);
+ if (!CBB_init(&cbb, 0) ||
+ !CBB_add_asn1(&cbb, &session, CBS_ASN1_SEQUENCE) ||
+ !CBB_add_asn1_uint64(&session, kVersion) ||
!CBB_add_asn1_uint64(&session, in->ssl_version) ||
!CBB_add_asn1(&session, &child, CBS_ASN1_OCTETSTRING) ||
!CBB_add_u16(&child, (uint16_t)(in->cipher->id & 0xffff)) ||
@@ -178,14 +202,14 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
for_ticket ? 0 : in->session_id_length) ||
!CBB_add_asn1(&session, &child, CBS_ASN1_OCTETSTRING) ||
!CBB_add_bytes(&child, in->master_key, in->master_key_length)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
if (in->time != 0) {
if (!CBB_add_asn1(&session, &child, kTimeTag) ||
!CBB_add_asn1_uint64(&child, in->time)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -193,7 +217,7 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
if (in->timeout != 0) {
if (!CBB_add_asn1(&session, &child, kTimeoutTag) ||
!CBB_add_asn1_uint64(&child, in->timeout)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -201,17 +225,11 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
/* The peer certificate is only serialized if the SHA-256 isn't
* serialized instead. */
if (in->peer && !in->peer_sha256_valid) {
- uint8_t *buf;
- int len = i2d_X509(in->peer, NULL);
- if (len < 0) {
- goto err;
- }
- if (!CBB_add_asn1(&session, &child, kPeerTag) ||
- !CBB_add_space(&child, &buf, len)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ if (!CBB_add_asn1(&session, &child, kPeerTag)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
- if (buf != NULL && i2d_X509(in->peer, &buf) < 0) {
+ if (!add_X509(&child, in->peer)) {
goto err;
}
}
@@ -221,14 +239,14 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
if (!CBB_add_asn1(&session, &child, kSessionIDContextTag) ||
!CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
!CBB_add_bytes(&child2, in->sid_ctx, in->sid_ctx_length)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
if (in->verify_result != X509_V_OK) {
if (!CBB_add_asn1(&session, &child, kVerifyResultTag) ||
!CBB_add_asn1_uint64(&child, in->verify_result)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -238,7 +256,7 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
!CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
!CBB_add_bytes(&child2, (const uint8_t *)in->tlsext_hostname,
strlen(in->tlsext_hostname))) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -248,7 +266,7 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
!CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
!CBB_add_bytes(&child2, (const uint8_t *)in->psk_identity,
strlen(in->psk_identity))) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -256,16 +274,16 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
if (in->tlsext_tick_lifetime_hint > 0) {
if (!CBB_add_asn1(&session, &child, kTicketLifetimeHintTag) ||
!CBB_add_asn1_uint64(&child, in->tlsext_tick_lifetime_hint)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
- if (in->tlsext_tick) {
+ if (in->tlsext_tick && !for_ticket) {
if (!CBB_add_asn1(&session, &child, kTicketTag) ||
!CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
!CBB_add_bytes(&child2, in->tlsext_tick, in->tlsext_ticklen)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -274,7 +292,7 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
if (!CBB_add_asn1(&session, &child, kPeerSHA256Tag) ||
!CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
!CBB_add_bytes(&child2, in->peer_sha256, sizeof(in->peer_sha256))) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -284,7 +302,7 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
!CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
!CBB_add_bytes(&child2, in->original_handshake_hash,
in->original_handshake_hash_len)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -294,7 +312,7 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
!CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
!CBB_add_bytes(&child2, in->tlsext_signed_cert_timestamp_list,
in->tlsext_signed_cert_timestamp_list_length)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -303,7 +321,7 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
if (!CBB_add_asn1(&session, &child, kOCSPResponseTag) ||
!CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
!CBB_add_bytes(&child2, in->ocsp_response, in->ocsp_response_length)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -312,13 +330,35 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
if (!CBB_add_asn1(&session, &child, kExtendedMasterSecretTag) ||
!CBB_add_asn1(&child, &child2, CBS_ASN1_BOOLEAN) ||
!CBB_add_u8(&child2, 0xff)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
+ if (in->key_exchange_info > 0 &&
+ (!CBB_add_asn1(&session, &child, kKeyExchangeInfoTag) ||
+ !CBB_add_asn1_uint64(&child, in->key_exchange_info))) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /* The certificate chain is only serialized if the leaf's SHA-256 isn't
+ * serialized instead. */
+ if (in->cert_chain != NULL && !in->peer_sha256_valid) {
+ if (!CBB_add_asn1(&session, &child, kCertChainTag)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ size_t i;
+ for (i = 0; i < sk_X509_num(in->cert_chain); i++) {
+ if (!add_X509(&child, sk_X509_value(in->cert_chain, i))) {
+ goto err;
+ }
+ }
+ }
+
if (!CBB_finish(&cbb, out_data, out_len)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
return 1;
@@ -328,11 +368,12 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
return 0;
}
-int SSL_SESSION_to_bytes(SSL_SESSION *in, uint8_t **out_data, size_t *out_len) {
+int SSL_SESSION_to_bytes(const SSL_SESSION *in, uint8_t **out_data,
+ size_t *out_len) {
return SSL_SESSION_to_bytes_full(in, out_data, out_len, 0);
}
-int SSL_SESSION_to_bytes_for_ticket(SSL_SESSION *in, uint8_t **out_data,
+int SSL_SESSION_to_bytes_for_ticket(const SSL_SESSION *in, uint8_t **out_data,
size_t *out_len) {
return SSL_SESSION_to_bytes_full(in, out_data, out_len, 1);
}
@@ -347,7 +388,7 @@ int i2d_SSL_SESSION(SSL_SESSION *in, uint8_t **pp) {
if (len > INT_MAX) {
OPENSSL_free(out);
- OPENSSL_PUT_ERROR(SSL, i2d_SSL_SESSION, ERR_R_OVERFLOW);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
return -1;
}
@@ -360,26 +401,26 @@ int i2d_SSL_SESSION(SSL_SESSION *in, uint8_t **pp) {
return len;
}
-/* d2i_SSL_SESSION_get_string gets an optional ASN.1 OCTET STRING
+/* SSL_SESSION_parse_string gets an optional ASN.1 OCTET STRING
* explicitly tagged with |tag| from |cbs| and saves it in |*out|. On
* entry, if |*out| is not NULL, it frees the existing contents. If
* the element was not found, it sets |*out| to NULL. It returns one
* on success, whether or not the element was found, and zero on
* decode error. */
-static int d2i_SSL_SESSION_get_string(CBS *cbs, char **out, unsigned tag) {
+static int SSL_SESSION_parse_string(CBS *cbs, char **out, unsigned tag) {
CBS value;
int present;
if (!CBS_get_optional_asn1_octet_string(cbs, &value, &present, tag)) {
- OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, SSL_R_INVALID_SSL_SESSION);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
return 0;
}
if (present) {
if (CBS_contains_zero_byte(&value)) {
- OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, SSL_R_INVALID_SSL_SESSION);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
return 0;
}
if (!CBS_strdup(&value, out)) {
- OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
} else {
@@ -389,180 +430,179 @@ static int d2i_SSL_SESSION_get_string(CBS *cbs, char **out, unsigned tag) {
return 1;
}
-/* d2i_SSL_SESSION_get_string gets an optional ASN.1 OCTET STRING
+/* SSL_SESSION_parse_string gets an optional ASN.1 OCTET STRING
* explicitly tagged with |tag| from |cbs| and stows it in |*out_ptr|
* and |*out_len|. If |*out_ptr| is not NULL, it frees the existing
* contents. On entry, if the element was not found, it sets
* |*out_ptr| to NULL. It returns one on success, whether or not the
* element was found, and zero on decode error. */
-static int d2i_SSL_SESSION_get_octet_string(CBS *cbs, uint8_t **out_ptr,
- size_t *out_len, unsigned tag) {
+static int SSL_SESSION_parse_octet_string(CBS *cbs, uint8_t **out_ptr,
+ size_t *out_len, unsigned tag) {
CBS value;
if (!CBS_get_optional_asn1_octet_string(cbs, &value, NULL, tag)) {
- OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, SSL_R_INVALID_SSL_SESSION);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
return 0;
}
if (!CBS_stow(&value, out_ptr, out_len)) {
- OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
return 1;
}
-SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const uint8_t **pp, long length) {
- SSL_SESSION *ret, *allocated = NULL;
- CBS cbs, session, cipher, session_id, master_key;
- CBS peer, sid_ctx, peer_sha256, original_handshake_hash;
- int has_peer, has_peer_sha256, extended_master_secret;
- uint64_t version, ssl_version;
- uint64_t session_time, timeout, verify_result, ticket_lifetime_hint;
-
- if (a && *a) {
- ret = *a;
- } else {
- ret = allocated = SSL_SESSION_new();
- if (allocated == NULL) {
- goto err;
- }
+/* SSL_SESSION_parse_bounded_octet_string parses an optional ASN.1 OCTET STRING
+ * explicitly tagged with |tag| of size at most |max_out|. */
+static int SSL_SESSION_parse_bounded_octet_string(
+ CBS *cbs, uint8_t *out, unsigned *out_len, unsigned max_out, unsigned tag) {
+ CBS value;
+ if (!CBS_get_optional_asn1_octet_string(cbs, &value, NULL, tag) ||
+ CBS_len(&value) > max_out) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
+ return 0;
}
+ memcpy(out, CBS_data(&value), CBS_len(&value));
+ *out_len = (unsigned)CBS_len(&value);
+ return 1;
+}
- CBS_init(&cbs, *pp, length);
- if (!CBS_get_asn1(&cbs, &session, CBS_ASN1_SEQUENCE) ||
- !CBS_get_asn1_uint64(&session, &version) ||
- !CBS_get_asn1_uint64(&session, &ssl_version) ||
- !CBS_get_asn1(&session, &cipher, CBS_ASN1_OCTETSTRING) ||
- !CBS_get_asn1(&session, &session_id, CBS_ASN1_OCTETSTRING) ||
- !CBS_get_asn1(&session, &master_key, CBS_ASN1_OCTETSTRING) ||
- !CBS_get_optional_asn1_uint64(&session, &session_time, kTimeTag,
- time(NULL)) ||
- !CBS_get_optional_asn1_uint64(&session, &timeout, kTimeoutTag, 3) ||
- !CBS_get_optional_asn1(&session, &peer, &has_peer, kPeerTag) ||
- !CBS_get_optional_asn1_octet_string(&session, &sid_ctx, NULL,
- kSessionIDContextTag) ||
- !CBS_get_optional_asn1_uint64(&session, &verify_result, kVerifyResultTag,
- X509_V_OK)) {
- OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, SSL_R_INVALID_SSL_SESSION);
- goto err;
- }
- if (!d2i_SSL_SESSION_get_string(&session, &ret->tlsext_hostname,
- kHostNameTag) ||
- !d2i_SSL_SESSION_get_string(&session, &ret->psk_identity,
- kPSKIdentityTag)) {
- goto err;
- }
- if (!CBS_get_optional_asn1_uint64(&session, &ticket_lifetime_hint,
- kTicketLifetimeHintTag, 0)) {
- OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, SSL_R_INVALID_SSL_SESSION);
- goto err;
+static int SSL_SESSION_parse_long(CBS *cbs, long *out, unsigned tag,
+ long default_value) {
+ uint64_t value;
+ if (!CBS_get_optional_asn1_uint64(cbs, &value, tag,
+ (uint64_t)default_value) ||
+ value > LONG_MAX) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
+ return 0;
}
- if (!d2i_SSL_SESSION_get_octet_string(&session, &ret->tlsext_tick,
- &ret->tlsext_ticklen, kTicketTag)) {
- goto err;
+ *out = (long)value;
+ return 1;
+}
+
+static int SSL_SESSION_parse_u32(CBS *cbs, uint32_t *out, unsigned tag,
+ uint32_t default_value) {
+ uint64_t value;
+ if (!CBS_get_optional_asn1_uint64(cbs, &value, tag,
+ (uint64_t)default_value) ||
+ value > 0xffffffff) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
+ return 0;
}
- if (!CBS_get_optional_asn1_octet_string(&session, &peer_sha256,
- &has_peer_sha256, kPeerSHA256Tag) ||
- !CBS_get_optional_asn1_octet_string(&session, &original_handshake_hash,
- NULL, kOriginalHandshakeHashTag)) {
- OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, SSL_R_INVALID_SSL_SESSION);
- goto err;
+ *out = (uint32_t)value;
+ return 1;
+}
+
+static X509 *parse_x509(CBS *cbs) {
+ if (CBS_len(cbs) > LONG_MAX) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
+ return NULL;
}
- if (!d2i_SSL_SESSION_get_octet_string(
- &session, &ret->tlsext_signed_cert_timestamp_list,
- &ret->tlsext_signed_cert_timestamp_list_length,
- kSignedCertTimestampListTag) ||
- !d2i_SSL_SESSION_get_octet_string(
- &session, &ret->ocsp_response, &ret->ocsp_response_length,
- kOCSPResponseTag)) {
- goto err;
+ const uint8_t *ptr = CBS_data(cbs);
+ X509 *ret = d2i_X509(NULL, &ptr, (long)CBS_len(cbs));
+ if (ret == NULL) {
+ return NULL;
}
- if (!CBS_get_optional_asn1_bool(&session, &extended_master_secret,
- kExtendedMasterSecretTag,
- 0 /* default to false */) ||
- CBS_len(&session) != 0) {
- OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, SSL_R_INVALID_SSL_SESSION);
+ CBS_skip(cbs, ptr - CBS_data(cbs));
+ return ret;
+}
+
+static SSL_SESSION *SSL_SESSION_parse(CBS *cbs) {
+ SSL_SESSION *ret = SSL_SESSION_new();
+ if (ret == NULL) {
goto err;
}
- ret->extended_master_secret = extended_master_secret;
- if (version != SSL_SESSION_ASN1_VERSION) {
- OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, SSL_R_INVALID_SSL_SESSION);
+ CBS session;
+ uint64_t version, ssl_version;
+ if (!CBS_get_asn1(cbs, &session, CBS_ASN1_SEQUENCE) ||
+ !CBS_get_asn1_uint64(&session, &version) ||
+ version != kVersion ||
+ !CBS_get_asn1_uint64(&session, &ssl_version)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
goto err;
}
-
/* Only support SSLv3/TLS and DTLS. */
if ((ssl_version >> 8) != SSL3_VERSION_MAJOR &&
(ssl_version >> 8) != (DTLS1_VERSION >> 8)) {
- OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, SSL_R_UNKNOWN_SSL_VERSION);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_SSL_VERSION);
goto err;
}
ret->ssl_version = ssl_version;
+ CBS cipher;
uint16_t cipher_value;
- if (!CBS_get_u16(&cipher, &cipher_value) || CBS_len(&cipher) != 0) {
- OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, SSL_R_CIPHER_CODE_WRONG_LENGTH);
+ if (!CBS_get_asn1(&session, &cipher, CBS_ASN1_OCTETSTRING) ||
+ !CBS_get_u16(&cipher, &cipher_value) ||
+ CBS_len(&cipher) != 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
goto err;
}
ret->cipher = SSL_get_cipher_by_value(cipher_value);
if (ret->cipher == NULL) {
- OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, SSL_R_UNSUPPORTED_CIPHER);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_CIPHER);
goto err;
}
- if (CBS_len(&session_id) > SSL3_MAX_SSL_SESSION_ID_LENGTH) {
- OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, SSL_R_INVALID_SSL_SESSION);
+ CBS session_id, master_key;
+ if (!CBS_get_asn1(&session, &session_id, CBS_ASN1_OCTETSTRING) ||
+ CBS_len(&session_id) > SSL3_MAX_SSL_SESSION_ID_LENGTH ||
+ !CBS_get_asn1(&session, &master_key, CBS_ASN1_OCTETSTRING) ||
+ CBS_len(&master_key) > SSL_MAX_MASTER_KEY_LENGTH) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
goto err;
}
memcpy(ret->session_id, CBS_data(&session_id), CBS_len(&session_id));
ret->session_id_length = CBS_len(&session_id);
-
- if (CBS_len(&master_key) > SSL_MAX_MASTER_KEY_LENGTH) {
- OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, SSL_R_INVALID_SSL_SESSION);
- goto err;
- }
memcpy(ret->master_key, CBS_data(&master_key), CBS_len(&master_key));
ret->master_key_length = CBS_len(&master_key);
- if (session_time > LONG_MAX ||
- timeout > LONG_MAX) {
- OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, SSL_R_INVALID_SSL_SESSION);
+ if (!SSL_SESSION_parse_long(&session, &ret->time, kTimeTag, time(NULL)) ||
+ !SSL_SESSION_parse_long(&session, &ret->timeout, kTimeoutTag, 3)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
goto err;
}
- ret->time = session_time;
- ret->timeout = timeout;
+ CBS peer;
+ int has_peer;
+ if (!CBS_get_optional_asn1(&session, &peer, &has_peer, kPeerTag)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
+ goto err;
+ }
X509_free(ret->peer);
ret->peer = NULL;
if (has_peer) {
- const uint8_t *ptr;
- ptr = CBS_data(&peer);
- ret->peer = d2i_X509(NULL, &ptr, CBS_len(&peer));
+ ret->peer = parse_x509(&peer);
if (ret->peer == NULL) {
goto err;
}
- if (ptr != CBS_data(&peer) + CBS_len(&peer)) {
- OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, SSL_R_INVALID_SSL_SESSION);
+ if (CBS_len(&peer) != 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
goto err;
}
}
- if (CBS_len(&sid_ctx) > sizeof(ret->sid_ctx)) {
- OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, SSL_R_INVALID_SSL_SESSION);
- goto err;
- }
- memcpy(ret->sid_ctx, CBS_data(&sid_ctx), CBS_len(&sid_ctx));
- ret->sid_ctx_length = CBS_len(&sid_ctx);
-
- if (verify_result > LONG_MAX ||
- ticket_lifetime_hint > 0xffffffff) {
- OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, SSL_R_INVALID_SSL_SESSION);
+ if (!SSL_SESSION_parse_bounded_octet_string(
+ &session, ret->sid_ctx, &ret->sid_ctx_length, sizeof(ret->sid_ctx),
+ kSessionIDContextTag) ||
+ !SSL_SESSION_parse_long(&session, &ret->verify_result, kVerifyResultTag,
+ X509_V_OK) ||
+ !SSL_SESSION_parse_string(&session, &ret->tlsext_hostname,
+ kHostNameTag) ||
+ !SSL_SESSION_parse_string(&session, &ret->psk_identity,
+ kPSKIdentityTag) ||
+ !SSL_SESSION_parse_u32(&session, &ret->tlsext_tick_lifetime_hint,
+ kTicketLifetimeHintTag, 0) ||
+ !SSL_SESSION_parse_octet_string(&session, &ret->tlsext_tick,
+ &ret->tlsext_ticklen, kTicketTag)) {
goto err;
}
- ret->verify_result = verify_result;
- ret->tlsext_tick_lifetime_hint = ticket_lifetime_hint;
- if (has_peer_sha256) {
- if (CBS_len(&peer_sha256) != sizeof(ret->peer_sha256)) {
- OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, SSL_R_INVALID_SSL_SESSION);
+ if (CBS_peek_asn1_tag(&session, kPeerSHA256Tag)) {
+ CBS child, peer_sha256;
+ if (!CBS_get_asn1(&session, &child, kPeerSHA256Tag) ||
+ !CBS_get_asn1(&child, &peer_sha256, CBS_ASN1_OCTETSTRING) ||
+ CBS_len(&peer_sha256) != sizeof(ret->peer_sha256) ||
+ CBS_len(&child) != 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
goto err;
}
memcpy(ret->peer_sha256, CBS_data(&peer_sha256), sizeof(ret->peer_sha256));
@@ -571,22 +611,108 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const uint8_t **pp, long length) {
ret->peer_sha256_valid = 0;
}
- if (CBS_len(&original_handshake_hash) >
- sizeof(ret->original_handshake_hash)) {
- OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, SSL_R_INVALID_SSL_SESSION);
+ if (!SSL_SESSION_parse_bounded_octet_string(
+ &session, ret->original_handshake_hash,
+ &ret->original_handshake_hash_len,
+ sizeof(ret->original_handshake_hash), kOriginalHandshakeHashTag) ||
+ !SSL_SESSION_parse_octet_string(
+ &session, &ret->tlsext_signed_cert_timestamp_list,
+ &ret->tlsext_signed_cert_timestamp_list_length,
+ kSignedCertTimestampListTag) ||
+ !SSL_SESSION_parse_octet_string(
+ &session, &ret->ocsp_response, &ret->ocsp_response_length,
+ kOCSPResponseTag)) {
goto err;
}
- memcpy(ret->original_handshake_hash, CBS_data(&original_handshake_hash),
- CBS_len(&original_handshake_hash));
- ret->original_handshake_hash_len = CBS_len(&original_handshake_hash);
- if (a) {
- *a = ret;
+ int extended_master_secret;
+ if (!CBS_get_optional_asn1_bool(&session, &extended_master_secret,
+ kExtendedMasterSecretTag,
+ 0 /* default to false */)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
+ goto err;
}
- *pp = CBS_data(&cbs);
+ ret->extended_master_secret = !!extended_master_secret;
+
+ if (!SSL_SESSION_parse_u32(&session, &ret->key_exchange_info,
+ kKeyExchangeInfoTag, 0)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
+ goto err;
+ }
+
+ CBS cert_chain;
+ int has_cert_chain;
+ if (!CBS_get_optional_asn1(&session, &cert_chain, &has_cert_chain,
+ kCertChainTag)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
+ goto err;
+ }
+ sk_X509_pop_free(ret->cert_chain, X509_free);
+ ret->cert_chain = NULL;
+ if (has_cert_chain) {
+ ret->cert_chain = sk_X509_new_null();
+ if (ret->cert_chain == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ while (CBS_len(&cert_chain) > 0) {
+ X509 *x509 = parse_x509(&cert_chain);
+ if (x509 == NULL) {
+ goto err;
+ }
+ if (!sk_X509_push(ret->cert_chain, x509)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ X509_free(x509);
+ goto err;
+ }
+ }
+ }
+
+ if (CBS_len(&session) != 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
+ goto err;
+ }
+
return ret;
err:
- SSL_SESSION_free(allocated);
+ SSL_SESSION_free(ret);
return NULL;
}
+
+SSL_SESSION *SSL_SESSION_from_bytes(const uint8_t *in, size_t in_len) {
+ CBS cbs;
+ CBS_init(&cbs, in, in_len);
+ SSL_SESSION *ret = SSL_SESSION_parse(&cbs);
+ if (ret == NULL) {
+ return NULL;
+ }
+ if (CBS_len(&cbs) != 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
+ SSL_SESSION_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
+SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const uint8_t **pp, long length) {
+ if (length < 0) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return NULL;
+ }
+
+ CBS cbs;
+ CBS_init(&cbs, *pp, length);
+
+ SSL_SESSION *ret = SSL_SESSION_parse(&cbs);
+ if (ret == NULL) {
+ return NULL;
+ }
+
+ if (a) {
+ SSL_SESSION_free(*a);
+ *a = ret;
+ }
+ *pp = CBS_data(&cbs);
+ return ret;
+}
diff --git a/src/ssl/ssl_buffer.c b/src/ssl/ssl_buffer.c
new file mode 100644
index 0000000..7fd74e4
--- /dev/null
+++ b/src/ssl/ssl_buffer.c
@@ -0,0 +1,319 @@
+/* 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 <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/mem.h>
+#include <openssl/type_check.h>
+
+#include "internal.h"
+
+
+OPENSSL_COMPILE_ASSERT(0xffff <= INT_MAX, uint16_fits_in_int);
+
+OPENSSL_COMPILE_ASSERT((SSL3_ALIGN_PAYLOAD & (SSL3_ALIGN_PAYLOAD - 1)) == 0,
+ align_to_a_power_of_two);
+
+/* setup_buffer initializes |buf| with capacity |cap|, aligned such that data
+ * written after |header_len| is aligned to a |SSL3_ALIGN_PAYLOAD|-byte
+ * boundary. It returns one on success and zero on error. */
+static int setup_buffer(SSL3_BUFFER *buf, size_t header_len, size_t cap) {
+ if (buf->buf != NULL || cap > 0xffff) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ /* Add up to |SSL3_ALIGN_PAYLOAD| - 1 bytes of slack for alignment. */
+ buf->buf = OPENSSL_malloc(cap + SSL3_ALIGN_PAYLOAD - 1);
+ if (buf->buf == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ /* Arrange the buffer such that the record body is aligned. */
+ buf->offset = (0 - header_len - (uintptr_t)buf->buf) &
+ (SSL3_ALIGN_PAYLOAD - 1);
+ buf->len = 0;
+ buf->cap = cap;
+ return 1;
+}
+
+static void consume_buffer(SSL3_BUFFER *buf, size_t len) {
+ if (len > buf->len) {
+ abort();
+ }
+ buf->offset += (uint16_t)len;
+ buf->len -= (uint16_t)len;
+ buf->cap -= (uint16_t)len;
+}
+
+static void clear_buffer(SSL3_BUFFER *buf) {
+ OPENSSL_free(buf->buf);
+ memset(buf, 0, sizeof(SSL3_BUFFER));
+}
+
+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
+ * returns one on success and zero on failure. */
+static int setup_read_buffer(SSL *ssl) {
+ SSL3_BUFFER *buf = &ssl->s3->read_buffer;
+
+ if (buf->buf != NULL) {
+ return 1;
+ }
+
+ size_t header_len = ssl_record_prefix_len(ssl);
+ size_t cap = SSL3_RT_MAX_ENCRYPTED_LENGTH;
+ if (SSL_IS_DTLS(ssl)) {
+ cap += DTLS1_RT_HEADER_LENGTH;
+ } else {
+ cap += SSL3_RT_HEADER_LENGTH;
+ }
+
+ return setup_buffer(buf, header_len, cap);
+}
+
+uint8_t *ssl_read_buffer(SSL *ssl) {
+ return ssl->s3->read_buffer.buf + ssl->s3->read_buffer.offset;
+}
+
+size_t ssl_read_buffer_len(const SSL *ssl) {
+ return ssl->s3->read_buffer.len;
+}
+
+static int dtls_read_buffer_next_packet(SSL *ssl) {
+ SSL3_BUFFER *buf = &ssl->s3->read_buffer;
+
+ if (buf->len > 0) {
+ /* It is an error to call |dtls_read_buffer_extend| when the read buffer is
+ * not empty. */
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+
+ /* Read a single packet from |ssl->rbio|. |buf->cap| must fit in an int. */
+ ssl->rwstate = SSL_READING;
+ int ret = BIO_read(ssl->rbio, buf->buf + buf->offset, (int)buf->cap);
+ if (ret <= 0) {
+ return ret;
+ }
+ ssl->rwstate = SSL_NOTHING;
+ /* |BIO_read| was bound by |buf->cap|, so this cannot overflow. */
+ buf->len = (uint16_t)ret;
+ return 1;
+}
+
+static int tls_read_buffer_extend_to(SSL *ssl, size_t len) {
+ SSL3_BUFFER *buf = &ssl->s3->read_buffer;
+
+ if (len > buf->cap) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
+ return -1;
+ }
+
+ /* Read until the target length is reached. */
+ while (buf->len < len) {
+ /* The amount of data to read is bounded by |buf->cap|, which must fit in an
+ * int. */
+ ssl->rwstate = SSL_READING;
+ int ret = BIO_read(ssl->rbio, buf->buf + buf->offset + buf->len,
+ (int)(len - buf->len));
+ if (ret <= 0) {
+ return ret;
+ }
+ ssl->rwstate = SSL_NOTHING;
+ /* |BIO_read| was bound by |buf->cap - buf->len|, so this cannot
+ * overflow. */
+ buf->len += (uint16_t)ret;
+ }
+
+ return 1;
+}
+
+int ssl_read_buffer_extend_to(SSL *ssl, size_t len) {
+ /* |ssl_read_buffer_extend_to| implicitly discards any consumed data. */
+ ssl_read_buffer_discard(ssl);
+
+ if (!setup_read_buffer(ssl)) {
+ return -1;
+ }
+
+ if (ssl->rbio == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BIO_NOT_SET);
+ return -1;
+ }
+
+ ERR_clear_system_error();
+
+ int ret;
+ if (SSL_IS_DTLS(ssl)) {
+ /* |len| is ignored for a datagram transport. */
+ ret = dtls_read_buffer_next_packet(ssl);
+ } else {
+ ret = tls_read_buffer_extend_to(ssl, len);
+ }
+
+ if (ret <= 0) {
+ /* If the buffer was empty originally and remained empty after attempting to
+ * extend it, release the buffer until the next attempt. */
+ ssl_read_buffer_discard(ssl);
+ }
+ return ret;
+}
+
+void ssl_read_buffer_consume(SSL *ssl, size_t len) {
+ SSL3_BUFFER *buf = &ssl->s3->read_buffer;
+
+ consume_buffer(buf, len);
+ if (!SSL_IS_DTLS(ssl)) {
+ /* The TLS stack never reads beyond the current record, so there will never
+ * be unconsumed data. If read-ahead is ever reimplemented,
+ * |ssl_read_buffer_discard| will require a |memcpy| to shift the excess
+ * back to the front of the buffer, to ensure there is enough space for the
+ * next record. */
+ assert(buf->len == 0);
+ }
+}
+
+void ssl_read_buffer_discard(SSL *ssl) {
+ if (ssl->s3->read_buffer.len == 0) {
+ ssl_read_buffer_clear(ssl);
+ }
+}
+
+void ssl_read_buffer_clear(SSL *ssl) {
+ clear_buffer(&ssl->s3->read_buffer);
+}
+
+
+int ssl_write_buffer_is_pending(const SSL *ssl) {
+ return ssl->s3->write_buffer.len > 0;
+}
+
+OPENSSL_COMPILE_ASSERT(SSL3_RT_HEADER_LENGTH * 2 +
+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD * 2 +
+ SSL3_RT_MAX_PLAIN_LENGTH <= 0xffff,
+ maximum_tls_write_buffer_too_large);
+
+OPENSSL_COMPILE_ASSERT(DTLS1_RT_HEADER_LENGTH +
+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD +
+ SSL3_RT_MAX_PLAIN_LENGTH <= 0xffff,
+ maximum_dtls_write_buffer_too_large);
+
+int ssl_write_buffer_init(SSL *ssl, uint8_t **out_ptr, size_t max_len) {
+ SSL3_BUFFER *buf = &ssl->s3->write_buffer;
+
+ if (buf->buf != NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ size_t header_len = ssl_seal_prefix_len(ssl);
+
+ /* TODO(davidben): This matches the original behavior in keeping the malloc
+ * size consistent. Does this matter? |cap| could just be |max_len|. */
+ size_t cap = SSL3_RT_MAX_PLAIN_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
+ if (SSL_IS_DTLS(ssl)) {
+ cap += DTLS1_RT_HEADER_LENGTH;
+ } else {
+ cap += SSL3_RT_HEADER_LENGTH;
+ if (ssl->mode & SSL_MODE_CBC_RECORD_SPLITTING) {
+ cap += SSL3_RT_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
+ }
+ }
+
+ if (max_len > cap) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+
+ if (!setup_buffer(buf, header_len, cap)) {
+ return 0;
+ }
+ *out_ptr = buf->buf + buf->offset;
+ return 1;
+}
+
+void ssl_write_buffer_set_len(SSL *ssl, size_t len) {
+ SSL3_BUFFER *buf = &ssl->s3->write_buffer;
+
+ if (len > buf->cap) {
+ abort();
+ }
+ buf->len = len;
+}
+
+static int tls_write_buffer_flush(SSL *ssl) {
+ SSL3_BUFFER *buf = &ssl->s3->write_buffer;
+
+ while (buf->len > 0) {
+ ssl->rwstate = SSL_WRITING;
+ int ret = BIO_write(ssl->wbio, buf->buf + buf->offset, buf->len);
+ if (ret <= 0) {
+ return ret;
+ }
+ ssl->rwstate = SSL_NOTHING;
+ consume_buffer(buf, (size_t)ret);
+ }
+ ssl_write_buffer_clear(ssl);
+ return 1;
+}
+
+static int dtls_write_buffer_flush(SSL *ssl) {
+ SSL3_BUFFER *buf = &ssl->s3->write_buffer;
+ if (buf->len == 0) {
+ return 1;
+ }
+
+ ssl->rwstate = SSL_WRITING;
+ int ret = BIO_write(ssl->wbio, buf->buf + buf->offset, buf->len);
+ if (ret <= 0) {
+ /* If the write failed, drop the write buffer anyway. Datagram transports
+ * can't write half a packet, so the caller is expected to retry from the
+ * top. */
+ ssl_write_buffer_clear(ssl);
+ return ret;
+ }
+ ssl->rwstate = SSL_NOTHING;
+ ssl_write_buffer_clear(ssl);
+ return 1;
+}
+
+int ssl_write_buffer_flush(SSL *ssl) {
+ if (ssl->wbio == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BIO_NOT_SET);
+ return -1;
+ }
+ ERR_clear_system_error();
+
+ if (SSL_IS_DTLS(ssl)) {
+ return dtls_write_buffer_flush(ssl);
+ } else {
+ return tls_write_buffer_flush(ssl);
+ }
+}
+
+void ssl_write_buffer_clear(SSL *ssl) {
+ clear_buffer(&ssl->s3->write_buffer);
+}
diff --git a/src/ssl/ssl_cert.c b/src/ssl/ssl_cert.c
index f1fd675..4952cfd 100644
--- a/src/ssl/ssl_cert.c
+++ b/src/ssl/ssl_cert.c
@@ -112,161 +112,82 @@
* ECC cipher suite support in OpenSSL originally developed by
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */
-#include <errno.h>
-#include <stdio.h>
+#include <openssl/ssl.h>
+
#include <string.h>
-#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/buf.h>
+#include <openssl/ec_key.h>
#include <openssl/dh.h>
#include <openssl/err.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
-#include <openssl/pem.h>
+#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include "../crypto/dh/internal.h"
-#include "../crypto/directory.h"
#include "../crypto/internal.h"
#include "internal.h"
-static CRYPTO_once_t g_x509_store_ex_data_index_once;
-static int g_x509_store_ex_data_index;
-
-static void ssl_x509_store_ex_data_index_init(void) {
- g_x509_store_ex_data_index = X509_STORE_CTX_get_ex_new_index(
- 0, "SSL for verify callback", NULL, NULL, NULL);
-}
-
int SSL_get_ex_data_X509_STORE_CTX_idx(void) {
- CRYPTO_once(&g_x509_store_ex_data_index_once,
- ssl_x509_store_ex_data_index_init);
- return g_x509_store_ex_data_index;
+ /* The ex_data index to go from |X509_STORE_CTX| to |SSL| always uses the
+ * reserved app_data slot. Before ex_data was introduced, app_data was used.
+ * Avoid breaking any software which assumes |X509_STORE_CTX_get_app_data|
+ * works. */
+ return 0;
}
CERT *ssl_cert_new(void) {
- CERT *ret;
-
- ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
+ CERT *ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
if (ret == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_cert_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return NULL;
}
memset(ret, 0, sizeof(CERT));
- ret->key = &ret->pkeys[SSL_PKEY_RSA_ENC];
return ret;
}
CERT *ssl_cert_dup(CERT *cert) {
- CERT *ret;
- int i;
-
- ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
+ CERT *ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
if (ret == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return NULL;
}
memset(ret, 0, sizeof(CERT));
- ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]];
- /* or ret->key = ret->pkeys + (cert->key - cert->pkeys), if you find that
- * more readable */
-
ret->mask_k = cert->mask_k;
ret->mask_a = cert->mask_a;
if (cert->dh_tmp != NULL) {
ret->dh_tmp = DHparams_dup(cert->dh_tmp);
if (ret->dh_tmp == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_DH_LIB);
+ 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, ssl_cert_dup, 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, ssl_cert_dup, 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;
-
- for (i = 0; i < SSL_PKEY_NUM; i++) {
- CERT_PKEY *cpk = cert->pkeys + i;
- CERT_PKEY *rpk = ret->pkeys + i;
- if (cpk->x509 != NULL) {
- rpk->x509 = X509_up_ref(cpk->x509);
- }
-
- if (cpk->privatekey != NULL) {
- rpk->privatekey = EVP_PKEY_up_ref(cpk->privatekey);
- }
-
- if (cpk->chain) {
- rpk->chain = X509_chain_up_ref(cpk->chain);
- if (!rpk->chain) {
- OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- }
- }
-
- /* Copy over signature algorithm configuration. */
- if (cert->conf_sigalgs) {
- ret->conf_sigalgs = BUF_memdup(cert->conf_sigalgs, cert->conf_sigalgslen);
- if (!ret->conf_sigalgs) {
- goto err;
- }
- ret->conf_sigalgslen = cert->conf_sigalgslen;
+ if (cert->x509 != NULL) {
+ ret->x509 = X509_up_ref(cert->x509);
}
- if (cert->client_sigalgs) {
- ret->client_sigalgs = BUF_memdup(cert->client_sigalgs,
- cert->client_sigalgslen);
- if (!ret->client_sigalgs) {
- goto err;
- }
- ret->client_sigalgslen = cert->client_sigalgslen;
+ if (cert->privatekey != NULL) {
+ ret->privatekey = EVP_PKEY_up_ref(cert->privatekey);
}
- /* Copy any custom client certificate types */
- if (cert->client_certificate_types) {
- ret->client_certificate_types = BUF_memdup(
- cert->client_certificate_types, cert->num_client_certificate_types);
- if (!ret->client_certificate_types) {
+ if (cert->chain) {
+ ret->chain = X509_chain_up_ref(cert->chain);
+ if (!ret->chain) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
- ret->num_client_certificate_types = cert->num_client_certificate_types;
}
ret->cert_cb = cert->cert_cb;
ret->cert_cb_arg = cert->cert_cb_arg;
- if (cert->verify_store) {
- CRYPTO_refcount_inc(&cert->verify_store->references);
- ret->verify_store = cert->verify_store;
- }
-
- if (cert->chain_store) {
- CRYPTO_refcount_inc(&cert->chain_store->references);
- ret->chain_store = cert->chain_store;
- }
-
return ret;
err:
@@ -275,27 +196,18 @@ err:
}
/* Free up and clear all certificates and chains */
-void ssl_cert_clear_certs(CERT *c) {
- int i;
- if (c == NULL) {
+void ssl_cert_clear_certs(CERT *cert) {
+ if (cert == NULL) {
return;
}
- for (i = 0; i < SSL_PKEY_NUM; i++) {
- CERT_PKEY *cpk = c->pkeys + i;
- if (cpk->x509) {
- X509_free(cpk->x509);
- cpk->x509 = NULL;
- }
- if (cpk->privatekey) {
- EVP_PKEY_free(cpk->privatekey);
- cpk->privatekey = NULL;
- }
- if (cpk->chain) {
- sk_X509_pop_free(cpk->chain, X509_free);
- cpk->chain = NULL;
- }
- }
+ X509_free(cert->x509);
+ cert->x509 = NULL;
+ EVP_PKEY_free(cert->privatekey);
+ cert->privatekey = NULL;
+ sk_X509_pop_free(cert->chain, X509_free);
+ cert->chain = NULL;
+ cert->key_method = NULL;
}
void ssl_cert_free(CERT *c) {
@@ -307,38 +219,29 @@ void ssl_cert_free(CERT *c) {
ssl_cert_clear_certs(c);
OPENSSL_free(c->peer_sigalgs);
- OPENSSL_free(c->conf_sigalgs);
- OPENSSL_free(c->client_sigalgs);
- OPENSSL_free(c->shared_sigalgs);
- OPENSSL_free(c->client_certificate_types);
- X509_STORE_free(c->verify_store);
- X509_STORE_free(c->chain_store);
+ OPENSSL_free(c->digest_nids);
OPENSSL_free(c);
}
-int ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain) {
- CERT_PKEY *cpk = c->key;
- if (!cpk) {
- return 0;
- }
- sk_X509_pop_free(cpk->chain, X509_free);
- cpk->chain = chain;
+int ssl_cert_set0_chain(CERT *cert, STACK_OF(X509) *chain) {
+ sk_X509_pop_free(cert->chain, X509_free);
+ cert->chain = chain;
return 1;
}
-int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain) {
+int ssl_cert_set1_chain(CERT *cert, STACK_OF(X509) *chain) {
STACK_OF(X509) *dchain;
- if (!chain) {
- return ssl_cert_set0_chain(c, NULL);
+ if (chain == NULL) {
+ return ssl_cert_set0_chain(cert, NULL);
}
dchain = X509_chain_up_ref(chain);
- if (!dchain) {
+ if (dchain == NULL) {
return 0;
}
- if (!ssl_cert_set0_chain(c, dchain)) {
+ if (!ssl_cert_set0_chain(cert, dchain)) {
sk_X509_pop_free(dchain, X509_free);
return 0;
}
@@ -346,143 +249,71 @@ int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain) {
return 1;
}
-int ssl_cert_add0_chain_cert(CERT *c, X509 *x) {
- CERT_PKEY *cpk = c->key;
- if (!cpk) {
- return 0;
- }
-
- if (!cpk->chain) {
- cpk->chain = sk_X509_new_null();
+int ssl_cert_add0_chain_cert(CERT *cert, X509 *x509) {
+ if (cert->chain == NULL) {
+ cert->chain = sk_X509_new_null();
}
- if (!cpk->chain || !sk_X509_push(cpk->chain, x)) {
+ if (cert->chain == NULL || !sk_X509_push(cert->chain, x509)) {
return 0;
}
return 1;
}
-int ssl_cert_add1_chain_cert(CERT *c, X509 *x) {
- if (!ssl_cert_add0_chain_cert(c, x)) {
+int ssl_cert_add1_chain_cert(CERT *cert, X509 *x509) {
+ if (!ssl_cert_add0_chain_cert(cert, x509)) {
return 0;
}
- X509_up_ref(x);
+ X509_up_ref(x509);
return 1;
}
-int ssl_cert_select_current(CERT *c, X509 *x) {
- int i;
- if (x == NULL) {
- return 0;
- }
-
- for (i = 0; i < SSL_PKEY_NUM; i++) {
- if (c->pkeys[i].x509 == x) {
- c->key = &c->pkeys[i];
- return 1;
- }
- }
-
- for (i = 0; i < SSL_PKEY_NUM; i++) {
- if (c->pkeys[i].x509 && !X509_cmp(c->pkeys[i].x509, x)) {
- c->key = &c->pkeys[i];
- return 1;
- }
- }
-
- return 0;
-}
-
void ssl_cert_set_cert_cb(CERT *c, int (*cb)(SSL *ssl, void *arg), void *arg) {
c->cert_cb = cb;
c->cert_cb_arg = arg;
}
-SESS_CERT *ssl_sess_cert_new(void) {
- SESS_CERT *ret;
-
- ret = OPENSSL_malloc(sizeof *ret);
- if (ret == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_sess_cert_new, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
-
- memset(ret, 0, sizeof *ret);
- ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA_ENC]);
-
- return ret;
-}
-
-void ssl_sess_cert_free(SESS_CERT *sc) {
- int i;
-
- if (sc == NULL) {
- return;
- }
-
- sk_X509_pop_free(sc->cert_chain, X509_free);
-
- for (i = 0; i < SSL_PKEY_NUM; i++) {
- X509_free(sc->peer_pkeys[i].x509);
+int ssl_verify_cert_chain(SSL *ssl, STACK_OF(X509) *cert_chain) {
+ if (cert_chain == NULL || sk_X509_num(cert_chain) == 0) {
+ return 0;
}
- DH_free(sc->peer_dh_tmp);
- EC_KEY_free(sc->peer_ecdh_tmp);
-
- OPENSSL_free(sc);
-}
-
-int ssl_set_peer_cert_type(SESS_CERT *sc, int type) {
- sc->peer_cert_type = type;
- return 1;
-}
-
-int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) {
- X509 *x;
- int i;
- X509_STORE *verify_store;
+ X509 *leaf = sk_X509_value(cert_chain, 0);
+ int ret = 0;
X509_STORE_CTX ctx;
-
- if (s->cert->verify_store) {
- verify_store = s->cert->verify_store;
- } else {
- verify_store = s->ctx->cert_store;
- }
-
- if (sk == NULL || sk_X509_num(sk) == 0) {
+ if (!X509_STORE_CTX_init(&ctx, ssl->ctx->cert_store, leaf, cert_chain)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB);
return 0;
}
-
- x = sk_X509_value(sk, 0);
- if (!X509_STORE_CTX_init(&ctx, verify_store, x, sk)) {
- OPENSSL_PUT_ERROR(SSL, ssl_verify_cert_chain, ERR_R_X509_LIB);
- return 0;
+ if (!X509_STORE_CTX_set_ex_data(&ctx, SSL_get_ex_data_X509_STORE_CTX_idx(),
+ ssl)) {
+ goto err;
}
- X509_STORE_CTX_set_ex_data(&ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), s);
/* We need to inherit the verify parameters. These can be determined by the
* context: if its a server it will verify SSL client certificates or vice
* versa. */
- X509_STORE_CTX_set_default(&ctx, s->server ? "ssl_client" : "ssl_server");
+ X509_STORE_CTX_set_default(&ctx, ssl->server ? "ssl_client" : "ssl_server");
/* Anything non-default in "param" should overwrite anything in the ctx. */
- X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param);
+ X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), ssl->param);
- if (s->verify_callback) {
- X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback);
+ if (ssl->verify_callback) {
+ X509_STORE_CTX_set_verify_cb(&ctx, ssl->verify_callback);
}
- if (s->ctx->app_verify_callback != NULL) {
- i = s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg);
+ if (ssl->ctx->app_verify_callback != NULL) {
+ ret = ssl->ctx->app_verify_callback(&ctx, ssl->ctx->app_verify_arg);
} else {
- i = X509_verify_cert(&ctx);
+ ret = X509_verify_cert(&ctx);
}
- s->verify_result = ctx.error;
- X509_STORE_CTX_cleanup(&ctx);
+ ssl->verify_result = ctx.error;
- return i;
+err:
+ X509_STORE_CTX_cleanup(&ctx);
+ return ret;
}
static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list,
@@ -491,15 +322,17 @@ static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list,
*ca_list = name_list;
}
-STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk) {
- size_t i;
- STACK_OF(X509_NAME) *ret;
- X509_NAME *name;
+STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *list) {
+ STACK_OF(X509_NAME) *ret = sk_X509_NAME_new_null();
+ if (ret == NULL) {
+ return NULL;
+ }
- ret = sk_X509_NAME_new_null();
- for (i = 0; i < sk_X509_NAME_num(sk); i++) {
- name = X509_NAME_dup(sk_X509_NAME_value(sk, i));
+ size_t i;
+ for (i = 0; i < sk_X509_NAME_num(list); i++) {
+ X509_NAME *name = X509_NAME_dup(sk_X509_NAME_value(list, i));
if (name == NULL || !sk_X509_NAME_push(ret, name)) {
+ X509_NAME_free(name);
sk_X509_NAME_pop_free(ret, X509_NAME_free);
return NULL;
}
@@ -508,38 +341,38 @@ STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk) {
return ret;
}
-void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list) {
- set_client_CA_list(&(s->client_CA), name_list);
+void SSL_set_client_CA_list(SSL *ssl, STACK_OF(X509_NAME) *name_list) {
+ set_client_CA_list(&ssl->client_CA, name_list);
}
void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) {
- set_client_CA_list(&(ctx->client_CA), name_list);
+ set_client_CA_list(&ctx->client_CA, name_list);
}
STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) {
return ctx->client_CA;
}
-STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s) {
- if (s->server) {
- if (s->client_CA != NULL) {
- return s->client_CA;
- } else {
- return s->ctx->client_CA;
- }
- } else {
- if ((s->version >> 8) == SSL3_VERSION_MAJOR && s->s3 != NULL) {
- return s->s3->tmp.ca_names;
- } else {
- return NULL;
- }
+STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl) {
+ /* For historical reasons, this function is used both to query configuration
+ * state on a server as well as handshake state on a client. However, whether
+ * |ssl| is a client or server is not known until explicitly configured with
+ * |SSL_set_connect_state|. If |handshake_func| is NULL, |ssl| is in an
+ * indeterminate mode and |ssl->server| is unset. */
+ if (ssl->handshake_func != NULL && !ssl->server) {
+ return ssl->s3->tmp.ca_names;
}
+
+ if (ssl->client_CA != NULL) {
+ return ssl->client_CA;
+ }
+ return ssl->ctx->client_CA;
}
-static int add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x) {
+static int add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x509) {
X509_NAME *name;
- if (x == NULL) {
+ if (x509 == NULL) {
return 0;
}
if (*sk == NULL) {
@@ -549,7 +382,7 @@ static int add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x) {
}
}
- name = X509_NAME_dup(X509_get_subject_name(x));
+ name = X509_NAME_dup(X509_get_subject_name(x509));
if (name == NULL) {
return 0;
}
@@ -562,195 +395,12 @@ static int add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x) {
return 1;
}
-int SSL_add_client_CA(SSL *ssl, X509 *x) {
- return add_client_CA(&(ssl->client_CA), x);
+int SSL_add_client_CA(SSL *ssl, X509 *x509) {
+ return add_client_CA(&ssl->client_CA, x509);
}
-int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) {
- return add_client_CA(&(ctx->client_CA), x);
-}
-
-static int xname_cmp(const X509_NAME **a, const X509_NAME **b) {
- return X509_NAME_cmp(*a, *b);
-}
-
-/* Load CA certs from a file into a STACK. Note that it is somewhat misnamed;
- * it doesn't really have anything to do with clients (except that a common use
- * for a stack of CAs is to send it to the client). Actually, it doesn't have
- * much to do with CAs, either, since it will load any old cert.
- *
- * \param file the file containing one or more certs.
- * \return a ::STACK containing the certs. */
-STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) {
- BIO *in;
- X509 *x = NULL;
- X509_NAME *xn = NULL;
- STACK_OF(X509_NAME) *ret = NULL, *sk;
-
- sk = sk_X509_NAME_new(xname_cmp);
- in = BIO_new(BIO_s_file());
-
- if (sk == NULL || in == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_load_client_CA_file, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- if (!BIO_read_filename(in, file)) {
- goto err;
- }
-
- for (;;) {
- if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) {
- break;
- }
- if (ret == NULL) {
- ret = sk_X509_NAME_new_null();
- if (ret == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_load_client_CA_file, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- }
- xn = X509_get_subject_name(x);
- if (xn == NULL) {
- goto err;
- }
-
- /* check for duplicates */
- xn = X509_NAME_dup(xn);
- if (xn == NULL) {
- goto err;
- }
- if (sk_X509_NAME_find(sk, NULL, xn)) {
- X509_NAME_free(xn);
- } else {
- sk_X509_NAME_push(sk, xn);
- sk_X509_NAME_push(ret, xn);
- }
- }
-
- if (0) {
- err:
- sk_X509_NAME_pop_free(ret, X509_NAME_free);
- ret = NULL;
- }
-
- sk_X509_NAME_free(sk);
- BIO_free(in);
- X509_free(x);
- if (ret != NULL) {
- ERR_clear_error();
- }
- return ret;
-}
-
-/* Add a file of certs to a stack.
- *
- * \param stack the stack to add to.
- * \param file the file to add from. All certs in this file that are not
- * already in the stack will be added.
- * \return 1 for success, 0 for failure. Note that in the case of failure some
- * certs may have been added to \c stack. */
-int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
- const char *file) {
- BIO *in;
- X509 *x = NULL;
- X509_NAME *xn = NULL;
- int ret = 1;
- int (*oldcmp)(const X509_NAME **a, const X509_NAME **b);
-
- oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp);
- in = BIO_new(BIO_s_file());
-
- if (in == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_add_file_cert_subjects_to_stack,
- ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- if (!BIO_read_filename(in, file)) {
- goto err;
- }
-
- for (;;) {
- if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) {
- break;
- }
- xn = X509_get_subject_name(x);
- if (xn == NULL) {
- goto err;
- }
- xn = X509_NAME_dup(xn);
- if (xn == NULL) {
- goto err;
- }
- if (sk_X509_NAME_find(stack, NULL, xn)) {
- X509_NAME_free(xn);
- } else {
- sk_X509_NAME_push(stack, xn);
- }
- }
-
- ERR_clear_error();
-
- if (0) {
- err:
- ret = 0;
- }
-
- BIO_free(in);
- X509_free(x);
-
- (void) sk_X509_NAME_set_cmp_func(stack, oldcmp);
-
- return ret;
-}
-
-/* Add a directory of certs to a stack.
- *
- * \param stack the stack to append to.
- * \param dir the directory to append from. All files in this directory will be
- * examined as potential certs. Any that are acceptable to
- * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will
- * be included.
- * \return 1 for success, 0 for failure. Note that in the case of failure some
- * certs may have been added to \c stack. */
-int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
- const char *dir) {
- OPENSSL_DIR_CTX *d = NULL;
- const char *filename;
- int ret = 0;
-
- /* Note that a side effect is that the CAs will be sorted by name */
- while ((filename = OPENSSL_DIR_read(&d, dir))) {
- char buf[1024];
- int r;
-
- if (strlen(dir) + strlen(filename) + 2 > sizeof(buf)) {
- OPENSSL_PUT_ERROR(SSL, SSL_add_dir_cert_subjects_to_stack,
- SSL_R_PATH_TOO_LONG);
- goto err;
- }
-
- r = BIO_snprintf(buf, sizeof buf, "%s/%s", dir, filename);
- if (r <= 0 || r >= (int)sizeof(buf) ||
- !SSL_add_file_cert_subjects_to_stack(stack, buf)) {
- goto err;
- }
- }
-
- if (errno) {
- OPENSSL_PUT_ERROR(SSL, SSL_add_dir_cert_subjects_to_stack, ERR_R_SYS_LIB);
- ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')");
- goto err;
- }
-
- ret = 1;
-
-err:
- if (d) {
- OPENSSL_DIR_end(&d);
- }
- return ret;
+int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x509) {
+ return add_client_CA(&ctx->client_CA, x509);
}
/* Add a certificate to a BUF_MEM structure */
@@ -760,7 +410,7 @@ static int ssl_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x) {
n = i2d_X509(x, NULL);
if (!BUF_MEM_grow_clean(buf, (int)(n + (*l) + 3))) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_cert_to_buf, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
return 0;
}
p = (uint8_t *)&(buf->data[*l]);
@@ -772,34 +422,21 @@ static int ssl_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x) {
}
/* Add certificate chain to internal SSL BUF_MEM structure. */
-int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l) {
- BUF_MEM *buf = s->init_buf;
+int ssl_add_cert_chain(SSL *ssl, unsigned long *l) {
+ CERT *cert = ssl->cert;
+ BUF_MEM *buf = ssl->init_buf;
int no_chain = 0;
size_t i;
- X509 *x = cpk->x509;
- STACK_OF(X509) *extra_certs;
- X509_STORE *chain_store;
+ X509 *x = cert->x509;
+ STACK_OF(X509) *chain = cert->chain;
if (x == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_cert_chain, SSL_R_NO_CERTIFICATE_SET);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
return 0;
}
- if (s->cert->chain_store) {
- chain_store = s->cert->chain_store;
- } else {
- chain_store = s->ctx->cert_store;
- }
-
- /* If we have a certificate specific chain use it, else use parent ctx. */
- if (cpk && cpk->chain) {
- extra_certs = cpk->chain;
- } else {
- extra_certs = s->ctx->extra_certs;
- }
-
- if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || extra_certs) {
+ if ((ssl->mode & SSL_MODE_NO_AUTO_CHAIN) || chain != NULL) {
no_chain = 1;
}
@@ -808,8 +445,8 @@ int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l) {
return 0;
}
- for (i = 0; i < sk_X509_num(extra_certs); i++) {
- x = sk_X509_value(extra_certs, i);
+ for (i = 0; i < sk_X509_num(chain); i++) {
+ x = sk_X509_value(chain, i);
if (!ssl_add_cert_to_buf(buf, l, x)) {
return 0;
}
@@ -817,8 +454,8 @@ int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l) {
} else {
X509_STORE_CTX xs_ctx;
- if (!X509_STORE_CTX_init(&xs_ctx, chain_store, x, NULL)) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_cert_chain, ERR_R_X509_LIB);
+ if (!X509_STORE_CTX_init(&xs_ctx, ssl->ctx->cert_store, x, NULL)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB);
return 0;
}
X509_verify_cert(&xs_ctx);
@@ -838,132 +475,65 @@ int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l) {
return 1;
}
-/* Build a certificate chain for current certificate */
-int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags) {
- CERT_PKEY *cpk = c->key;
- X509_STORE_CTX xs_ctx;
- STACK_OF(X509) *chain = NULL, *untrusted = NULL;
- X509 *x;
- int i, rv = 0;
- uint32_t error;
-
- if (!cpk->x509) {
- OPENSSL_PUT_ERROR(SSL, ssl_build_cert_chain, SSL_R_NO_CERTIFICATE_SET);
- goto err;
- }
-
- /* Rearranging and check the chain: add everything to a store */
- if (flags & SSL_BUILD_CHAIN_FLAG_CHECK) {
- size_t j;
- chain_store = X509_STORE_new();
- if (!chain_store) {
- goto err;
- }
-
- for (j = 0; j < sk_X509_num(cpk->chain); j++) {
- x = sk_X509_value(cpk->chain, j);
- if (!X509_STORE_add_cert(chain_store, x)) {
- error = ERR_peek_last_error();
- if (ERR_GET_LIB(error) != ERR_LIB_X509 ||
- ERR_GET_REASON(error) != X509_R_CERT_ALREADY_IN_HASH_TABLE) {
- goto err;
- }
- ERR_clear_error();
- }
- }
+int SSL_CTX_set0_chain(SSL_CTX *ctx, STACK_OF(X509) *chain) {
+ return ssl_cert_set0_chain(ctx->cert, chain);
+}
- /* Add EE cert too: it might be self signed */
- if (!X509_STORE_add_cert(chain_store, cpk->x509)) {
- error = ERR_peek_last_error();
- if (ERR_GET_LIB(error) != ERR_LIB_X509 ||
- ERR_GET_REASON(error) != X509_R_CERT_ALREADY_IN_HASH_TABLE) {
- goto err;
- }
- ERR_clear_error();
- }
- } else {
- if (c->chain_store) {
- chain_store = c->chain_store;
- }
+int SSL_CTX_set1_chain(SSL_CTX *ctx, STACK_OF(X509) *chain) {
+ return ssl_cert_set1_chain(ctx->cert, chain);
+}
- if (flags & SSL_BUILD_CHAIN_FLAG_UNTRUSTED) {
- untrusted = cpk->chain;
- }
- }
+int SSL_set0_chain(SSL *ssl, STACK_OF(X509) *chain) {
+ return ssl_cert_set0_chain(ssl->cert, chain);
+}
- if (!X509_STORE_CTX_init(&xs_ctx, chain_store, cpk->x509, untrusted)) {
- OPENSSL_PUT_ERROR(SSL, ssl_build_cert_chain, ERR_R_X509_LIB);
- goto err;
- }
+int SSL_set1_chain(SSL *ssl, STACK_OF(X509) *chain) {
+ return ssl_cert_set1_chain(ssl->cert, chain);
+}
- i = X509_verify_cert(&xs_ctx);
- if (i <= 0 && flags & SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR) {
- if (flags & SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR) {
- ERR_clear_error();
- }
- i = 1;
- rv = 2;
- }
+int SSL_CTX_add0_chain_cert(SSL_CTX *ctx, X509 *x509) {
+ return ssl_cert_add0_chain_cert(ctx->cert, x509);
+}
- if (i > 0) {
- chain = X509_STORE_CTX_get1_chain(&xs_ctx);
- }
- if (i <= 0) {
- OPENSSL_PUT_ERROR(SSL, ssl_build_cert_chain,
- SSL_R_CERTIFICATE_VERIFY_FAILED);
- i = X509_STORE_CTX_get_error(&xs_ctx);
- ERR_add_error_data(2, "Verify error:", X509_verify_cert_error_string(i));
+int SSL_CTX_add1_chain_cert(SSL_CTX *ctx, X509 *x509) {
+ return ssl_cert_add1_chain_cert(ctx->cert, x509);
+}
- X509_STORE_CTX_cleanup(&xs_ctx);
- goto err;
- }
+int SSL_CTX_add_extra_chain_cert(SSL_CTX *ctx, X509 *x509) {
+ return SSL_CTX_add0_chain_cert(ctx, x509);
+}
- X509_STORE_CTX_cleanup(&xs_ctx);
- if (cpk->chain) {
- sk_X509_pop_free(cpk->chain, X509_free);
- }
+int SSL_add0_chain_cert(SSL *ssl, X509 *x509) {
+ return ssl_cert_add0_chain_cert(ssl->cert, x509);
+}
- /* Remove EE certificate from chain */
- x = sk_X509_shift(chain);
- X509_free(x);
- if (flags & SSL_BUILD_CHAIN_FLAG_NO_ROOT) {
- if (sk_X509_num(chain) > 0) {
- /* See if last cert is self signed */
- x = sk_X509_value(chain, sk_X509_num(chain) - 1);
- X509_check_purpose(x, -1, 0);
- if (x->ex_flags & EXFLAG_SS) {
- x = sk_X509_pop(chain);
- X509_free(x);
- }
- }
- }
+int SSL_add1_chain_cert(SSL *ssl, X509 *x509) {
+ return ssl_cert_add1_chain_cert(ssl->cert, x509);
+}
- cpk->chain = chain;
- if (rv == 0) {
- rv = 1;
- }
+int SSL_CTX_clear_chain_certs(SSL_CTX *ctx) {
+ return SSL_CTX_set0_chain(ctx, NULL);
+}
-err:
- if (flags & SSL_BUILD_CHAIN_FLAG_CHECK) {
- X509_STORE_free(chain_store);
- }
+int SSL_CTX_clear_extra_chain_certs(SSL_CTX *ctx) {
+ return SSL_CTX_clear_chain_certs(ctx);
+}
- return rv;
+int SSL_clear_chain_certs(SSL *ssl) {
+ return SSL_set0_chain(ssl, NULL);
}
-int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref) {
- X509_STORE **pstore;
- if (chain) {
- pstore = &c->chain_store;
- } else {
- pstore = &c->verify_store;
- }
+int SSL_CTX_get0_chain_certs(const SSL_CTX *ctx, STACK_OF(X509) **out_chain) {
+ *out_chain = ctx->cert->chain;
+ return 1;
+}
- X509_STORE_free(*pstore);
- *pstore = store;
+int SSL_CTX_get_extra_chain_certs(const SSL_CTX *ctx,
+ STACK_OF(X509) **out_chain) {
+ return SSL_CTX_get0_chain_certs(ctx, out_chain);
+}
- if (ref && store) {
- CRYPTO_refcount_inc(&store->references);
- }
+int SSL_get0_chain_certs(const SSL *ssl, STACK_OF(X509) **out_chain) {
+ *out_chain = ssl->cert->chain;
return 1;
}
diff --git a/src/ssl/ssl_cipher.c b/src/ssl/ssl_cipher.c
index 8d03c9e..77fa8fa 100644
--- a/src/ssl/ssl_cipher.c
+++ b/src/ssl/ssl_cipher.c
@@ -138,6 +138,8 @@
* OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
* OTHERWISE. */
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <stdio.h>
#include <string.h>
@@ -153,27 +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_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,
},
@@ -181,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,
},
@@ -212,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 */
@@ -268,88 +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,
- SSL_HANDSHAKE_MAC_SHA256 |
- SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
- 128, 128,
+ TLS1_CK_RSA_WITH_AES_128_GCM_SHA256,
+ SSL_kRSA,
+ SSL_aRSA,
+ SSL_AES128GCM,
+ SSL_AEAD,
+ SSL_HANDSHAKE_MAC_SHA256,
},
/* 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,
- SSL_HANDSHAKE_MAC_SHA384 |
- SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
- 256, 256,
+ TLS1_CK_RSA_WITH_AES_256_GCM_SHA384,
+ SSL_kRSA,
+ SSL_aRSA,
+ SSL_AES256GCM,
+ SSL_AEAD,
+ SSL_HANDSHAKE_MAC_SHA384,
},
/* 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,
- SSL_HANDSHAKE_MAC_SHA256 |
- SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
- 128, 128,
+ TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256,
+ SSL_kDHE,
+ SSL_aRSA,
+ SSL_AES128GCM,
+ SSL_AEAD,
+ SSL_HANDSHAKE_MAC_SHA256,
},
/* 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,
- SSL_HANDSHAKE_MAC_SHA384 |
- SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
- 256, 256,
+ TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384,
+ SSL_kDHE,
+ SSL_aRSA,
+ SSL_AES256GCM,
+ SSL_AEAD,
+ SSL_HANDSHAKE_MAC_SHA384,
},
/* 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,
},
@@ -358,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,
},
@@ -393,41 +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,
- SSL_HANDSHAKE_MAC_SHA256 |
- SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
- 128, 128,
+ TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+ SSL_kECDHE,
+ SSL_aECDSA,
+ SSL_AES128GCM,
+ SSL_AEAD,
+ SSL_HANDSHAKE_MAC_SHA256,
},
/* 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,
- SSL_HANDSHAKE_MAC_SHA384 |
- SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
- 256, 256,
+ TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+ SSL_kECDHE,
+ SSL_aECDSA,
+ SSL_AES256GCM,
+ SSL_AEAD,
+ SSL_HANDSHAKE_MAC_SHA384,
},
/* 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,
- SSL_HANDSHAKE_MAC_SHA256 |
- SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
- 128, 128,
+ TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ SSL_kECDHE,
+ SSL_aRSA,
+ SSL_AES128GCM,
+ SSL_AEAD,
+ SSL_HANDSHAKE_MAC_SHA256,
},
/* 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,
- SSL_HANDSHAKE_MAC_SHA384 |
- SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
- 256, 256,
+ TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+ SSL_kECDHE,
+ SSL_aRSA,
+ SSL_AES256GCM,
+ SSL_AEAD,
+ SSL_HANDSHAKE_MAC_SHA384,
},
/* ECDHE-PSK cipher suites. */
@@ -436,60 +542,83 @@ 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,
},
/* ChaCha20-Poly1305 cipher suites. */
-#if !defined(ANDROID)
+#if !defined(BORINGSSL_ANDROID_SYSTEM)
{
- TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305,
- TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, SSL_kECDHE, SSL_aRSA,
- SSL_CHACHA20POLY1305, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH,
+ 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_HANDSHAKE_MAC_SHA256,
- 256, 0,
},
{
- TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
- TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, SSL_kECDHE, SSL_aECDSA,
- SSL_CHACHA20POLY1305, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH,
+ 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_HANDSHAKE_MAC_SHA256,
- 256, 0,
},
+#endif
+ /* Cipher CCA8 */
{
- TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305,
- TLS1_CK_DHE_RSA_CHACHA20_POLY1305, SSL_kDHE, SSL_aRSA,
- SSL_CHACHA20POLY1305, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH,
+ 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,
- 256, 0,
},
-#endif
-};
-static const size_t kCiphersLen = sizeof(kCiphers) / sizeof(kCiphers[0]);
+ /* 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,
+ },
-struct handshake_digest {
- uint32_t mask;
- const EVP_MD *(*md_func)(void);
+ /* 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 struct handshake_digest ssl_handshake_digests[SSL_MAX_DIGEST] = {
- {SSL_HANDSHAKE_MAC_MD5, EVP_md5},
- {SSL_HANDSHAKE_MAC_SHA, EVP_sha1},
- {SSL_HANDSHAKE_MAC_SHA256, EVP_sha256},
- {SSL_HANDSHAKE_MAC_SHA384, EVP_sha384},
-};
+static const size_t kCiphersLen = sizeof(kCiphers) / sizeof(kCiphers[0]);
#define CIPHER_ADD 1
#define CIPHER_KILL 2
@@ -516,12 +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[] = {
- {SSL_TXT_ALL, ~0u, ~0u, ~0u, ~0u, ~0u, ~0u},
+ /* "ALL" doesn't include eNULL (must be specifically enabled) */
+ {"ALL", ~0u, ~0u, ~SSL_eNULL, ~0u, 0},
/* The "COMPLEMENTOFDEFAULT" rule is omitted. It matches nothing. */
@@ -529,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) */
- {SSL_TXT_kRSA, SSL_kRSA, ~0u, ~0u, ~0u, ~0u, ~0u},
+ {"kRSA", SSL_kRSA, ~0u, ~0u, ~0u, 0},
- {SSL_TXT_kDHE, SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {SSL_TXT_kEDH, SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {SSL_TXT_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},
- {SSL_TXT_kECDHE, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {SSL_TXT_kEECDH, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {SSL_TXT_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},
- {SSL_TXT_kPSK, SSL_kPSK, ~0u, ~0u, ~0u, ~0u, ~0u},
+ {"kPSK", SSL_kPSK, ~0u, ~0u, ~0u, 0},
/* server authentication aliases */
- {SSL_TXT_aRSA, ~0u, SSL_aRSA, ~0u, ~0u, ~0u, ~0u},
- {SSL_TXT_aECDSA, ~0u, SSL_aECDSA, ~0u, ~0u, ~0u, ~0u},
- {SSL_TXT_ECDSA, ~0u, SSL_aECDSA, ~0u, ~0u, ~0u, ~0u},
- {SSL_TXT_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 */
- {SSL_TXT_DHE, SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {SSL_TXT_EDH, SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {SSL_TXT_ECDHE, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {SSL_TXT_EECDH, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {SSL_TXT_RSA, SSL_kRSA, SSL_aRSA, ~0u, ~0u, ~0u, ~0u},
- {SSL_TXT_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 */
- {SSL_TXT_3DES, ~0u, ~0u, SSL_3DES, ~0u, ~0u, ~0u},
- {SSL_TXT_RC4, ~0u, ~0u, SSL_RC4, ~0u, ~0u, ~0u},
- {SSL_TXT_AES128, ~0u, ~0u, SSL_AES128 | SSL_AES128GCM, ~0u, ~0u, ~0u},
- {SSL_TXT_AES256, ~0u, ~0u, SSL_AES256 | SSL_AES256GCM, ~0u, ~0u, ~0u},
- {SSL_TXT_AES, ~0u, ~0u, SSL_AES, ~0u, ~0u, ~0u},
- {SSL_TXT_AES_GCM, ~0u, ~0u, SSL_AES128GCM | SSL_AES256GCM, ~0u, ~0u, ~0u},
- {SSL_TXT_CHACHA20, ~0u, ~0u, SSL_CHACHA20POLY1305, ~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 */
- {SSL_TXT_MD5, ~0u, ~0u, ~0u, SSL_MD5, ~0u, ~0u},
- {SSL_TXT_SHA1, ~0u, ~0u, ~0u, SSL_SHA1, ~0u, ~0u},
- {SSL_TXT_SHA, ~0u, ~0u, ~0u, SSL_SHA1, ~0u, ~0u},
- {SSL_TXT_SHA256, ~0u, ~0u, ~0u, SSL_SHA256, ~0u, ~0u},
- {SSL_TXT_SHA384, ~0u, ~0u, ~0u, SSL_SHA384, ~0u, ~0u},
-
- /* protocol version aliases */
- {SSL_TXT_SSLV3, ~0u, ~0u, ~0u, ~0u, SSL_SSLV3, ~0u},
- {SSL_TXT_TLSV1, ~0u, ~0u, ~0u, ~0u, SSL_TLSV1, ~0u},
- {SSL_TXT_TLSV1_2, ~0u, ~0u, ~0u, ~0u, SSL_TLSV1_2, ~0u},
-
- /* strength classes */
- {SSL_TXT_MEDIUM, ~0u, ~0u, ~0u, ~0u, ~0u, SSL_MEDIUM},
- {SSL_TXT_HIGH, ~0u, ~0u, ~0u, ~0u, ~0u, SSL_HIGH},
- /* FIPS 140-2 approved ciphersuite */
- {SSL_TXT_FIPS, ~0u, ~0u, ~0u, ~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 =
@@ -630,13 +763,18 @@ int ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead,
*out_fixed_iv_len = 4;
return 1;
-#if !defined(ANDROID)
- case SSL_CHACHA20POLY1305:
- *out_aead = EVP_aead_chacha20_poly1305();
+#if !defined(BORINGSSL_ANDROID_SYSTEM)
+ case SSL_CHACHA20POLY1305_OLD:
+ *out_aead = EVP_aead_chacha20_poly1305_old();
*out_fixed_iv_len = 0;
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:
@@ -725,19 +863,36 @@ int ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead,
return 0;
}
+ case SSL_eNULL:
+ switch (cipher->algorithm_mac) {
+ case SSL_SHA1:
+ if (version == SSL3_VERSION) {
+ *out_aead = EVP_aead_null_sha1_ssl3();
+ } else {
+ *out_aead = EVP_aead_null_sha1_tls();
+ }
+ *out_mac_secret_len = SHA_DIGEST_LENGTH;
+ return 1;
+ default:
+ return 0;
+ }
+
default:
return 0;
}
}
-int ssl_get_handshake_digest(uint32_t *out_mask, const EVP_MD **out_md,
- size_t idx) {
- if (idx >= SSL_MAX_DIGEST) {
- return 0;
+const EVP_MD *ssl_get_handshake_digest(uint32_t algorithm_prf) {
+ switch (algorithm_prf) {
+ case SSL_HANDSHAKE_MAC_DEFAULT:
+ return EVP_sha1();
+ case SSL_HANDSHAKE_MAC_SHA256:
+ return EVP_sha256();
+ case SSL_HANDSHAKE_MAC_SHA384:
+ return EVP_sha384();
+ default:
+ return NULL;
}
- *out_mask = ssl_handshake_digests[idx].mask;
- *out_md = ssl_handshake_digests[idx].md_func();
- return 1;
}
#define ITEM_SEP(a) \
@@ -840,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;
}
@@ -894,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;
}
@@ -971,15 +1125,16 @@ 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;
}
number_uses = OPENSSL_malloc((max_strength_bits + 1) * sizeof(int));
if (!number_uses) {
- OPENSSL_PUT_ERROR(SSL, ssl_cipher_strength_sort, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
memset(number_uses, 0, (max_strength_bits + 1) * sizeof(int));
@@ -988,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;
}
@@ -996,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);
}
}
@@ -1009,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;
@@ -1041,8 +1196,7 @@ static int ssl_cipher_process_rulestr(const SSL_PROTOCOL_METHOD *ssl_method,
continue;
} else if (!(ch >= 'a' && ch <= 'z') && !(ch >= 'A' && ch <= 'Z') &&
!(ch >= '0' && ch <= '9')) {
- OPENSSL_PUT_ERROR(SSL, ssl_cipher_process_rulestr,
- SSL_R_UNEXPECTED_OPERATOR_IN_GROUP);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_OPERATOR_IN_GROUP);
retval = in_group = 0;
break;
} else {
@@ -1062,7 +1216,7 @@ static int ssl_cipher_process_rulestr(const SSL_PROTOCOL_METHOD *ssl_method,
l++;
} else if (ch == '[') {
if (in_group) {
- OPENSSL_PUT_ERROR(SSL, ssl_cipher_process_rulestr, SSL_R_NESTED_GROUP);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NESTED_GROUP);
retval = in_group = 0;
break;
}
@@ -1077,8 +1231,7 @@ static int ssl_cipher_process_rulestr(const SSL_PROTOCOL_METHOD *ssl_method,
/* If preference groups are enabled, the only legal operator is +.
* Otherwise the in_group bits will get mixed up. */
if (has_group && rule != CIPHER_ADD) {
- OPENSSL_PUT_ERROR(SSL, ssl_cipher_process_rulestr,
- SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS);
retval = in_group = 0;
break;
}
@@ -1094,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;
@@ -1110,8 +1263,7 @@ static int ssl_cipher_process_rulestr(const SSL_PROTOCOL_METHOD *ssl_method,
if (buf_len == 0) {
/* We hit something we cannot deal with, it is no command or separator
* nor alphanumeric, so we call this an error. */
- OPENSSL_PUT_ERROR(SSL, ssl_cipher_process_rulestr,
- SSL_R_INVALID_COMMAND);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND);
retval = in_group = 0;
l++;
break;
@@ -1140,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;
}
}
@@ -1158,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 */
@@ -1165,8 +1345,7 @@ static int ssl_cipher_process_rulestr(const SSL_PROTOCOL_METHOD *ssl_method,
if (buf_len == 8 && !strncmp(buf, "STRENGTH", 8)) {
ok = ssl_cipher_strength_sort(head_p, tail_p);
} else {
- OPENSSL_PUT_ERROR(SSL, ssl_cipher_process_rulestr,
- SSL_R_INVALID_COMMAND);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND);
}
if (ok == 0) {
@@ -1178,15 +1357,14 @@ 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);
}
}
if (in_group) {
- OPENSSL_PUT_ERROR(SSL, ssl_cipher_process_rulestr, SSL_R_INVALID_COMMAND);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND);
retval = 0;
}
@@ -1216,7 +1394,7 @@ ssl_create_cipher_list(const SSL_PROTOCOL_METHOD *ssl_method,
* allocation. */
co_list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * kCiphersLen);
if (co_list == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_create_cipher_list, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -1227,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,
+ 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_AES128GCM, ~0u, ~0u, ~0u, CIPHER_ADD,
- -1, 0, &head, &tail);
- ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305, ~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, ~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. */
@@ -1390,12 +1573,60 @@ int SSL_CIPHER_has_MD5_HMAC(const SSL_CIPHER *cipher) {
return (cipher->algorithm_mac & SSL_MD5) != 0;
}
+int SSL_CIPHER_has_SHA1_HMAC(const SSL_CIPHER *cipher) {
+ return (cipher->algorithm_mac & SSL_SHA1) != 0;
+}
+
int SSL_CIPHER_is_AESGCM(const SSL_CIPHER *cipher) {
- return (cipher->algorithm_mac & (SSL_AES128GCM | SSL_AES256GCM)) != 0;
+ return (cipher->algorithm_enc & (SSL_AES128GCM | SSL_AES256GCM)) != 0;
+}
+
+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) != 0;
+ return (cipher->algorithm_enc &
+ (SSL_CHACHA20POLY1305 | SSL_CHACHA20POLY1305_OLD)) != 0;
+}
+
+int SSL_CIPHER_is_NULL(const SSL_CIPHER *cipher) {
+ return (cipher->algorithm_enc & SSL_eNULL) != 0;
+}
+
+int SSL_CIPHER_is_RC4(const SSL_CIPHER *cipher) {
+ return (cipher->algorithm_enc & SSL_RC4) != 0;
+}
+
+int SSL_CIPHER_is_block_cipher(const SSL_CIPHER *cipher) {
+ /* Neither stream cipher nor AEAD. */
+ return (cipher->algorithm_enc & (SSL_RC4 | SSL_eNULL)) == 0 &&
+ cipher->algorithm_mac != SSL_AEAD;
+}
+
+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_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;
}
/* return the actual cipher being used */
@@ -1463,6 +1694,7 @@ static const char *ssl_cipher_get_enc_name(const SSL_CIPHER *cipher) {
case SSL_AES256GCM:
return "AES_256_GCM";
case SSL_CHACHA20POLY1305:
+ case SSL_CHACHA20POLY1305_OLD:
return "CHACHA20_POLY1305";
break;
default:
@@ -1472,27 +1704,24 @@ static const char *ssl_cipher_get_enc_name(const SSL_CIPHER *cipher) {
}
static const char *ssl_cipher_get_prf_name(const SSL_CIPHER *cipher) {
- if ((cipher->algorithm2 & SSL_HANDSHAKE_MAC_DEFAULT) ==
- SSL_HANDSHAKE_MAC_DEFAULT) {
- /* Before TLS 1.2, the PRF component is the hash used in the HMAC, which is
- * only ever MD5 or SHA-1. */
- switch (cipher->algorithm_mac) {
- case SSL_MD5:
- return "MD5";
- case SSL_SHA1:
- return "SHA";
- default:
- assert(0);
- return "UNKNOWN";
- }
- } else if (cipher->algorithm2 & SSL_HANDSHAKE_MAC_SHA256) {
- return "SHA256";
- } else if (cipher->algorithm2 & SSL_HANDSHAKE_MAC_SHA384) {
- return "SHA384";
- } else {
- assert(0);
- return "UNKNOWN";
+ switch (cipher->algorithm_prf) {
+ case SSL_HANDSHAKE_MAC_DEFAULT:
+ /* Before TLS 1.2, the PRF component is the hash used in the HMAC, which is
+ * only ever MD5 or SHA-1. */
+ switch (cipher->algorithm_mac) {
+ case SSL_MD5:
+ return "MD5";
+ case SSL_SHA1:
+ return "SHA";
+ }
+ break;
+ case SSL_HANDSHAKE_MAC_SHA256:
+ return "SHA256";
+ case SSL_HANDSHAKE_MAC_SHA384:
+ return "SHA384";
}
+ assert(0);
+ return "UNKNOWN";
}
char *SSL_CIPHER_get_rfc_name(const SSL_CIPHER *cipher) {
@@ -1530,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:
@@ -1621,10 +1875,18 @@ const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf,
enc = "AESGCM(256)";
break;
+ case SSL_CHACHA20POLY1305_OLD:
+ enc = "ChaCha20-Poly1305-Old";
+ break;
+
case SSL_CHACHA20POLY1305:
enc = "ChaCha20-Poly1305";
break;
+ case SSL_eNULL:
+ enc="None";
+ break;
+
default:
enc = "unknown";
break;
@@ -1666,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;
}
@@ -1674,29 +1936,28 @@ const char *SSL_CIPHER_get_version(const SSL_CIPHER *cipher) {
return "TLSv1/SSLv3";
}
-void *SSL_COMP_get_compression_methods(void) { return NULL; }
+COMP_METHOD *SSL_COMP_get_compression_methods(void) { return NULL; }
-int SSL_COMP_add_compression_method(int id, void *cm) { return 1; }
+int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) { return 1; }
-const char *SSL_COMP_get_name(const void *comp) { return NULL; }
+const char *SSL_COMP_get_name(const COMP_METHOD *comp) { return NULL; }
-int ssl_cipher_get_cert_index(const SSL_CIPHER *cipher) {
+int ssl_cipher_get_key_type(const SSL_CIPHER *cipher) {
uint32_t alg_a = cipher->algorithm_auth;
if (alg_a & SSL_aECDSA) {
- return SSL_PKEY_ECC;
+ return EVP_PKEY_EC;
} else if (alg_a & SSL_aRSA) {
- return SSL_PKEY_RSA_ENC;
+ return EVP_PKEY_RSA;
}
- return -1;
+ return EVP_PKEY_NONE;
}
int ssl_cipher_has_server_public_key(const SSL_CIPHER *cipher) {
- /* PSK-authenticated ciphers do not use a public key, except for
- * RSA_PSK. */
- if ((cipher->algorithm_auth & SSL_aPSK) &&
- !(cipher->algorithm_mkey & SSL_kRSA)) {
+ /* PSK-authenticated ciphers do not use a certificate. (RSA_PSK is not
+ * supported.) */
+ if (cipher->algorithm_auth & SSL_aPSK) {
return 0;
}
@@ -1713,3 +1974,34 @@ int ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher) {
/* It is optional in all others. */
return 0;
}
+
+size_t ssl_cipher_get_record_split_len(const SSL_CIPHER *cipher) {
+ size_t block_size;
+ switch (cipher->algorithm_enc) {
+ case SSL_3DES:
+ block_size = 8;
+ break;
+ case SSL_AES128:
+ case SSL_AES256:
+ block_size = 16;
+ break;
+ default:
+ return 0;
+ }
+
+ size_t mac_len;
+ switch (cipher->algorithm_mac) {
+ case SSL_MD5:
+ mac_len = MD5_DIGEST_LENGTH;
+ break;
+ case SSL_SHA1:
+ mac_len = SHA_DIGEST_LENGTH;
+ break;
+ default:
+ return 0;
+ }
+
+ size_t ret = 1 + mac_len;
+ ret += block_size - (ret % block_size);
+ return ret;
+}
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_file.c b/src/ssl/ssl_file.c
new file mode 100644
index 0000000..42cf800
--- /dev/null
+++ b/src/ssl/ssl_file.c
@@ -0,0 +1,633 @@
+/* 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.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/ssl.h>
+
+#include <errno.h>
+#include <string.h>
+
+#include <openssl/asn1.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/mem.h>
+#include <openssl/pem.h>
+#include <openssl/stack.h>
+#include <openssl/x509.h>
+
+#include "../crypto/directory.h"
+#include "internal.h"
+
+
+static int xname_cmp(const X509_NAME **a, const X509_NAME **b) {
+ return X509_NAME_cmp(*a, *b);
+}
+
+/* TODO(davidben): Is there any reason this doesn't call
+ * |SSL_add_file_cert_subjects_to_stack|? */
+STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) {
+ BIO *in;
+ X509 *x = NULL;
+ X509_NAME *xn = NULL;
+ STACK_OF(X509_NAME) *ret = NULL, *sk;
+
+ sk = sk_X509_NAME_new(xname_cmp);
+ in = BIO_new(BIO_s_file());
+
+ if (sk == NULL || in == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (!BIO_read_filename(in, file)) {
+ goto err;
+ }
+
+ for (;;) {
+ if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) {
+ break;
+ }
+ if (ret == NULL) {
+ ret = sk_X509_NAME_new_null();
+ if (ret == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+ xn = X509_get_subject_name(x);
+ if (xn == NULL) {
+ goto err;
+ }
+
+ /* check for duplicates */
+ xn = X509_NAME_dup(xn);
+ if (xn == NULL) {
+ goto err;
+ }
+ if (sk_X509_NAME_find(sk, NULL, xn)) {
+ X509_NAME_free(xn);
+ } else {
+ sk_X509_NAME_push(sk, xn);
+ sk_X509_NAME_push(ret, xn);
+ }
+ }
+
+ if (0) {
+ err:
+ sk_X509_NAME_pop_free(ret, X509_NAME_free);
+ ret = NULL;
+ }
+
+ sk_X509_NAME_free(sk);
+ BIO_free(in);
+ X509_free(x);
+ if (ret != NULL) {
+ ERR_clear_error();
+ }
+ return ret;
+}
+
+int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
+ const char *file) {
+ BIO *in;
+ X509 *x = NULL;
+ X509_NAME *xn = NULL;
+ int ret = 1;
+ int (*oldcmp)(const X509_NAME **a, const X509_NAME **b);
+
+ oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp);
+ in = BIO_new(BIO_s_file());
+
+ if (in == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (!BIO_read_filename(in, file)) {
+ goto err;
+ }
+
+ for (;;) {
+ if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) {
+ break;
+ }
+ xn = X509_get_subject_name(x);
+ if (xn == NULL) {
+ goto err;
+ }
+ xn = X509_NAME_dup(xn);
+ if (xn == NULL) {
+ goto err;
+ }
+ if (sk_X509_NAME_find(stack, NULL, xn)) {
+ X509_NAME_free(xn);
+ } else {
+ sk_X509_NAME_push(stack, xn);
+ }
+ }
+
+ ERR_clear_error();
+
+ if (0) {
+ err:
+ ret = 0;
+ }
+
+ BIO_free(in);
+ X509_free(x);
+
+ (void) sk_X509_NAME_set_cmp_func(stack, oldcmp);
+
+ return ret;
+}
+
+/* Add a directory of certs to a stack.
+ *
+ * \param stack the stack to append to.
+ * \param dir the directory to append from. All files in this directory will be
+ * examined as potential certs. Any that are acceptable to
+ * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will
+ * be included.
+ * \return 1 for success, 0 for failure. Note that in the case of failure some
+ * certs may have been added to \c stack. */
+int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
+ const char *dir) {
+ OPENSSL_DIR_CTX *d = NULL;
+ const char *filename;
+ int ret = 0;
+
+ /* Note that a side effect is that the CAs will be sorted by name */
+ while ((filename = OPENSSL_DIR_read(&d, dir))) {
+ char buf[1024];
+ int r;
+
+ if (strlen(dir) + strlen(filename) + 2 > sizeof(buf)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_PATH_TOO_LONG);
+ goto err;
+ }
+
+ r = BIO_snprintf(buf, sizeof buf, "%s/%s", dir, filename);
+ if (r <= 0 || r >= (int)sizeof(buf) ||
+ !SSL_add_file_cert_subjects_to_stack(stack, buf)) {
+ goto err;
+ }
+ }
+
+ if (errno) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
+ ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')");
+ goto err;
+ }
+
+ ret = 1;
+
+err:
+ if (d) {
+ OPENSSL_DIR_end(&d);
+ }
+ return ret;
+}
+
+int SSL_use_certificate_file(SSL *ssl, const char *file, int type) {
+ int reason_code;
+ BIO *in;
+ int ret = 0;
+ X509 *x = NULL;
+
+ in = BIO_new(BIO_s_file());
+ if (in == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
+ goto end;
+ }
+
+ if (BIO_read_filename(in, file) <= 0) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
+ goto end;
+ }
+
+ if (type == SSL_FILETYPE_ASN1) {
+ reason_code = ERR_R_ASN1_LIB;
+ x = d2i_X509_bio(in, NULL);
+ } else if (type == SSL_FILETYPE_PEM) {
+ reason_code = ERR_R_PEM_LIB;
+ x = PEM_read_bio_X509(in, NULL, ssl->ctx->default_passwd_callback,
+ ssl->ctx->default_passwd_callback_userdata);
+ } else {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE);
+ goto end;
+ }
+
+ if (x == NULL) {
+ OPENSSL_PUT_ERROR(SSL, reason_code);
+ goto end;
+ }
+
+ ret = SSL_use_certificate(ssl, x);
+
+end:
+ X509_free(x);
+ BIO_free(in);
+
+ return ret;
+}
+
+int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) {
+ int reason_code, ret = 0;
+ BIO *in;
+ RSA *rsa = NULL;
+
+ in = BIO_new(BIO_s_file());
+ if (in == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
+ goto end;
+ }
+
+ if (BIO_read_filename(in, file) <= 0) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
+ goto end;
+ }
+
+ if (type == SSL_FILETYPE_ASN1) {
+ reason_code = ERR_R_ASN1_LIB;
+ rsa = d2i_RSAPrivateKey_bio(in, NULL);
+ } else if (type == SSL_FILETYPE_PEM) {
+ reason_code = ERR_R_PEM_LIB;
+ rsa =
+ PEM_read_bio_RSAPrivateKey(in, NULL, ssl->ctx->default_passwd_callback,
+ ssl->ctx->default_passwd_callback_userdata);
+ } else {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE);
+ goto end;
+ }
+
+ if (rsa == NULL) {
+ OPENSSL_PUT_ERROR(SSL, reason_code);
+ goto end;
+ }
+ ret = SSL_use_RSAPrivateKey(ssl, rsa);
+ RSA_free(rsa);
+
+end:
+ BIO_free(in);
+ return ret;
+}
+
+int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) {
+ int reason_code, ret = 0;
+ BIO *in;
+ EVP_PKEY *pkey = NULL;
+
+ in = BIO_new(BIO_s_file());
+ if (in == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
+ goto end;
+ }
+
+ if (BIO_read_filename(in, file) <= 0) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
+ goto end;
+ }
+
+ if (type == SSL_FILETYPE_PEM) {
+ reason_code = ERR_R_PEM_LIB;
+ pkey = PEM_read_bio_PrivateKey(in, NULL, ssl->ctx->default_passwd_callback,
+ ssl->ctx->default_passwd_callback_userdata);
+ } else if (type == SSL_FILETYPE_ASN1) {
+ reason_code = ERR_R_ASN1_LIB;
+ pkey = d2i_PrivateKey_bio(in, NULL);
+ } else {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE);
+ goto end;
+ }
+
+ if (pkey == NULL) {
+ OPENSSL_PUT_ERROR(SSL, reason_code);
+ goto end;
+ }
+ ret = SSL_use_PrivateKey(ssl, pkey);
+ EVP_PKEY_free(pkey);
+
+end:
+ BIO_free(in);
+ return ret;
+}
+
+int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) {
+ int reason_code;
+ BIO *in;
+ int ret = 0;
+ X509 *x = NULL;
+
+ in = BIO_new(BIO_s_file());
+ if (in == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
+ goto end;
+ }
+
+ if (BIO_read_filename(in, file) <= 0) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
+ goto end;
+ }
+
+ if (type == SSL_FILETYPE_ASN1) {
+ reason_code = ERR_R_ASN1_LIB;
+ x = d2i_X509_bio(in, NULL);
+ } else if (type == SSL_FILETYPE_PEM) {
+ reason_code = ERR_R_PEM_LIB;
+ x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
+ ctx->default_passwd_callback_userdata);
+ } else {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE);
+ goto end;
+ }
+
+ if (x == NULL) {
+ OPENSSL_PUT_ERROR(SSL, reason_code);
+ goto end;
+ }
+
+ ret = SSL_CTX_use_certificate(ctx, x);
+
+end:
+ X509_free(x);
+ BIO_free(in);
+ return ret;
+}
+
+int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) {
+ int reason_code, ret = 0;
+ BIO *in;
+ RSA *rsa = NULL;
+
+ in = BIO_new(BIO_s_file());
+ if (in == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
+ goto end;
+ }
+
+ if (BIO_read_filename(in, file) <= 0) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
+ goto end;
+ }
+
+ if (type == SSL_FILETYPE_ASN1) {
+ reason_code = ERR_R_ASN1_LIB;
+ rsa = d2i_RSAPrivateKey_bio(in, NULL);
+ } else if (type == SSL_FILETYPE_PEM) {
+ reason_code = ERR_R_PEM_LIB;
+ rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ctx->default_passwd_callback,
+ ctx->default_passwd_callback_userdata);
+ } else {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE);
+ goto end;
+ }
+
+ if (rsa == NULL) {
+ OPENSSL_PUT_ERROR(SSL, reason_code);
+ goto end;
+ }
+ ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
+ RSA_free(rsa);
+
+end:
+ BIO_free(in);
+ return ret;
+}
+
+int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) {
+ int reason_code, ret = 0;
+ BIO *in;
+ EVP_PKEY *pkey = NULL;
+
+ in = BIO_new(BIO_s_file());
+ if (in == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
+ goto end;
+ }
+
+ if (BIO_read_filename(in, file) <= 0) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
+ goto end;
+ }
+
+ if (type == SSL_FILETYPE_PEM) {
+ reason_code = ERR_R_PEM_LIB;
+ pkey = PEM_read_bio_PrivateKey(in, NULL, ctx->default_passwd_callback,
+ ctx->default_passwd_callback_userdata);
+ } else if (type == SSL_FILETYPE_ASN1) {
+ reason_code = ERR_R_ASN1_LIB;
+ pkey = d2i_PrivateKey_bio(in, NULL);
+ } else {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE);
+ goto end;
+ }
+
+ if (pkey == NULL) {
+ OPENSSL_PUT_ERROR(SSL, reason_code);
+ goto end;
+ }
+ ret = SSL_CTX_use_PrivateKey(ctx, pkey);
+ EVP_PKEY_free(pkey);
+
+end:
+ BIO_free(in);
+ return ret;
+}
+
+/* Read a file that contains our certificate in "PEM" format, possibly followed
+ * by a sequence of CA certificates that should be sent to the peer in the
+ * Certificate message. */
+int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) {
+ BIO *in;
+ int ret = 0;
+ X509 *x = NULL;
+
+ ERR_clear_error(); /* clear error stack for SSL_CTX_use_certificate() */
+
+ in = BIO_new(BIO_s_file());
+ if (in == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
+ goto end;
+ }
+
+ if (BIO_read_filename(in, file) <= 0) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
+ goto end;
+ }
+
+ x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback,
+ ctx->default_passwd_callback_userdata);
+ if (x == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_PEM_LIB);
+ goto end;
+ }
+
+ ret = SSL_CTX_use_certificate(ctx, x);
+
+ if (ERR_peek_error() != 0) {
+ ret = 0; /* Key/certificate mismatch doesn't imply ret==0 ... */
+ }
+
+ if (ret) {
+ /* If we could set up our certificate, now proceed to the CA
+ * certificates. */
+ X509 *ca;
+ int r;
+ uint32_t err;
+
+ SSL_CTX_clear_chain_certs(ctx);
+
+ while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
+ ctx->default_passwd_callback_userdata)) !=
+ NULL) {
+ r = SSL_CTX_add0_chain_cert(ctx, ca);
+ if (!r) {
+ X509_free(ca);
+ ret = 0;
+ goto end;
+ }
+ /* Note that we must not free r if it was successfully added to the chain
+ * (while we must free the main certificate, since its reference count is
+ * increased by SSL_CTX_use_certificate). */
+ }
+
+ /* When the while loop ends, it's usually just EOF. */
+ err = ERR_peek_last_error();
+ if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
+ ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
+ ERR_clear_error();
+ } else {
+ ret = 0; /* some real error */
+ }
+ }
+
+end:
+ X509_free(x);
+ BIO_free(in);
+ return ret;
+}
+
+void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb) {
+ ctx->default_passwd_callback = cb;
+}
+
+void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *data) {
+ ctx->default_passwd_callback_userdata = data;
+}
+
+SSL_SESSION *d2i_SSL_SESSION_bio(BIO *bio, SSL_SESSION **out) {
+ return ASN1_d2i_bio_of(SSL_SESSION, SSL_SESSION_new, d2i_SSL_SESSION, bio,
+ out);
+}
+
+int i2d_SSL_SESSION_bio(BIO *bio, const SSL_SESSION *session) {
+ return ASN1_i2d_bio_of(SSL_SESSION, i2d_SSL_SESSION, bio, session);
+}
+
+IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION)
diff --git a/src/ssl/ssl_lib.c b/src/ssl/ssl_lib.c
index e95226f..08578a6 100644
--- a/src/ssl/ssl_lib.c
+++ b/src/ssl/ssl_lib.c
@@ -138,11 +138,14 @@
* OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
* OTHERWISE. */
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <openssl/bytestring.h>
+#include <openssl/crypto.h>
#include <openssl/dh.h>
#include <openssl/err.h>
#include <openssl/lhash.h>
@@ -155,6 +158,10 @@
#include "../crypto/internal.h"
+/* |SSL_R_UNKNOWN_PROTOCOL| is no longer emitted, but continue to define it
+ * to avoid downstream churn. */
+OPENSSL_DECLARE_ERROR_REASON(SSL, UNKNOWN_PROTOCOL)
+
/* Some error codes are special. Ensure the make_errors.go script never
* regresses this. */
OPENSSL_COMPILE_ASSERT(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION ==
@@ -164,358 +171,287 @@ OPENSSL_COMPILE_ASSERT(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION ==
/* kMaxHandshakeSize is the maximum size, in bytes, of a handshake message. */
static const size_t kMaxHandshakeSize = (1u << 24) - 1;
-static CRYPTO_EX_DATA_CLASS g_ex_data_class_ssl = CRYPTO_EX_DATA_CLASS_INIT;
-static CRYPTO_EX_DATA_CLASS g_ex_data_class_ssl_ctx = CRYPTO_EX_DATA_CLASS_INIT;
+static CRYPTO_EX_DATA_CLASS g_ex_data_class_ssl =
+ CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;
+static CRYPTO_EX_DATA_CLASS g_ex_data_class_ssl_ctx =
+ CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;
-int SSL_clear(SSL *ssl) {
- if (ssl->method == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_clear, SSL_R_NO_METHOD_SPECIFIED);
- return 0;
- }
+int SSL_library_init(void) {
+ CRYPTO_library_init();
+ return 1;
+}
- if (ssl_clear_bad_session(ssl)) {
- SSL_SESSION_free(ssl->session);
- ssl->session = NULL;
- }
+static uint32_t ssl_session_hash(const SSL_SESSION *a) {
+ uint32_t hash =
+ ((uint32_t)a->session_id[0]) |
+ ((uint32_t)a->session_id[1] << 8) |
+ ((uint32_t)a->session_id[2] << 16) |
+ ((uint32_t)a->session_id[3] << 24);
- ssl->hit = 0;
- ssl->shutdown = 0;
+ return hash;
+}
- /* SSL_clear may be called before or after the |ssl| is initialized in either
- * accept or connect state. In the latter case, SSL_clear should preserve the
- * half and reset |ssl->state| accordingly. */
- if (ssl->handshake_func != NULL) {
- if (ssl->server) {
- SSL_set_accept_state(ssl);
- } else {
- SSL_set_connect_state(ssl);
- }
- } else {
- assert(ssl->state == 0);
+/* NB: If this function (or indeed the hash function which uses a sort of
+ * coarser function than this one) is changed, ensure
+ * SSL_CTX_has_matching_session_id() is checked accordingly. It relies on being
+ * able to construct an SSL_SESSION that will collide with any existing session
+ * with a matching session ID. */
+static int ssl_session_cmp(const SSL_SESSION *a, const SSL_SESSION *b) {
+ if (a->ssl_version != b->ssl_version) {
+ return 1;
}
- /* TODO(davidben): Some state on |ssl| is reset both in |SSL_new| and
- * |SSL_clear| because it is per-connection state rather than configuration
- * state. Per-connection state should be on |ssl->s3| and |ssl->d1| so it is
- * naturally reset at the right points between |SSL_new|, |SSL_clear|, and
- * |ssl3_new|. */
-
- ssl->rwstate = SSL_NOTHING;
- ssl->rstate = SSL_ST_READ_HEADER;
-
- BUF_MEM_free(ssl->init_buf);
- ssl->init_buf = NULL;
-
- ssl->packet = NULL;
- ssl->packet_length = 0;
+ if (a->session_id_length != b->session_id_length) {
+ return 1;
+ }
- ssl_clear_cipher_ctx(ssl);
+ return memcmp(a->session_id, b->session_id, a->session_id_length);
+}
- OPENSSL_free(ssl->next_proto_negotiated);
- ssl->next_proto_negotiated = NULL;
- ssl->next_proto_negotiated_len = 0;
+SSL_CTX *SSL_CTX_new(const SSL_METHOD *method) {
+ SSL_CTX *ret = NULL;
- /* The ssl->d1->mtu is simultaneously configuration (preserved across
- * clear) and connection-specific state (gets reset).
- *
- * TODO(davidben): Avoid this. */
- unsigned mtu = 0;
- if (ssl->d1 != NULL) {
- mtu = ssl->d1->mtu;
+ if (method == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NULL_SSL_METHOD_PASSED);
+ return NULL;
}
- ssl->method->ssl_free(ssl);
- if (!ssl->method->ssl_new(ssl)) {
- return 0;
+ if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS);
+ goto err;
}
- ssl->enc_method = ssl3_get_enc_method(ssl->version);
- assert(ssl->enc_method != NULL);
- if (SSL_IS_DTLS(ssl) && (SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) {
- ssl->d1->mtu = mtu;
+ ret = (SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX));
+ if (ret == NULL) {
+ goto err;
}
- ssl->client_version = ssl->version;
-
- return 1;
-}
+ memset(ret, 0, sizeof(SSL_CTX));
-SSL *SSL_new(SSL_CTX *ctx) {
- SSL *s;
+ ret->method = method->method;
- if (ctx == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_new, SSL_R_NULL_SSL_CTX);
- return NULL;
- }
- if (ctx->method == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_new, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION);
- return NULL;
- }
+ CRYPTO_MUTEX_init(&ret->lock);
- s = (SSL *)OPENSSL_malloc(sizeof(SSL));
- if (s == NULL) {
- goto err;
- }
- memset(s, 0, sizeof(SSL));
+ ret->session_cache_mode = SSL_SESS_CACHE_SERVER;
+ ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT;
- s->min_version = ctx->min_version;
- s->max_version = ctx->max_version;
+ /* We take the system default */
+ ret->session_timeout = SSL_DEFAULT_SESSION_TIMEOUT;
- s->options = ctx->options;
- s->mode = ctx->mode;
- s->max_cert_list = ctx->max_cert_list;
+ ret->references = 1;
- s->cert = ssl_cert_dup(ctx->cert);
- if (s->cert == NULL) {
+ ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT;
+ ret->verify_mode = SSL_VERIFY_NONE;
+ ret->cert = ssl_cert_new();
+ if (ret->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;
- s->generate_session_id = ctx->generate_session_id;
-
- s->param = X509_VERIFY_PARAM_new();
- if (!s->param) {
+ ret->sessions = lh_SSL_SESSION_new(ssl_session_hash, ssl_session_cmp);
+ if (ret->sessions == NULL) {
goto err;
}
- X509_VERIFY_PARAM_inherit(s->param, ctx->param);
- s->quiet_shutdown = ctx->quiet_shutdown;
- s->max_send_fragment = ctx->max_send_fragment;
-
- CRYPTO_refcount_inc(&ctx->references);
- s->ctx = ctx;
- s->tlsext_ticket_expected = 0;
- CRYPTO_refcount_inc(&ctx->references);
- s->initial_ctx = ctx;
- if (ctx->tlsext_ecpointformatlist) {
- s->tlsext_ecpointformatlist = BUF_memdup(
- ctx->tlsext_ecpointformatlist, ctx->tlsext_ecpointformatlist_length);
- if (!s->tlsext_ecpointformatlist) {
- goto err;
- }
- s->tlsext_ecpointformatlist_length = ctx->tlsext_ecpointformatlist_length;
+ ret->cert_store = X509_STORE_new();
+ if (ret->cert_store == NULL) {
+ goto err;
}
- if (ctx->tlsext_ellipticcurvelist) {
- s->tlsext_ellipticcurvelist =
- BUF_memdup(ctx->tlsext_ellipticcurvelist,
- ctx->tlsext_ellipticcurvelist_length * 2);
- if (!s->tlsext_ellipticcurvelist) {
- goto err;
- }
- s->tlsext_ellipticcurvelist_length = ctx->tlsext_ellipticcurvelist_length;
+ ssl_create_cipher_list(ret->method, &ret->cipher_list,
+ &ret->cipher_list_by_id, SSL_DEFAULT_CIPHER_LIST);
+ if (ret->cipher_list == NULL ||
+ sk_SSL_CIPHER_num(ret->cipher_list->ciphers) <= 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_LIBRARY_HAS_NO_CIPHERS);
+ goto err2;
}
- s->next_proto_negotiated = NULL;
- 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) {
- goto err;
- }
- s->alpn_client_proto_list_len = s->ctx->alpn_client_proto_list_len;
+ ret->param = X509_VERIFY_PARAM_new();
+ if (!ret->param) {
+ goto err;
}
- s->verify_result = X509_V_OK;
- s->method = ctx->method;
-
- if (!s->method->ssl_new(s)) {
+ ret->client_CA = sk_X509_NAME_new_null();
+ if (ret->client_CA == NULL) {
goto err;
}
- s->enc_method = ssl3_get_enc_method(s->version);
- assert(s->enc_method != NULL);
- s->rwstate = SSL_NOTHING;
- s->rstate = SSL_ST_READ_HEADER;
+ CRYPTO_new_ex_data(&ret->ex_data);
- CRYPTO_new_ex_data(&g_ex_data_class_ssl, s, &s->ex_data);
+ ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
- s->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) {
- goto err;
- }
+ /* Setup RFC4507 ticket keys */
+ if (!RAND_bytes(ret->tlsext_tick_key_name, 16) ||
+ !RAND_bytes(ret->tlsext_tick_hmac_key, 16) ||
+ !RAND_bytes(ret->tlsext_tick_aes_key, 16)) {
+ ret->options |= SSL_OP_NO_TICKET;
}
- s->psk_client_callback = ctx->psk_client_callback;
- s->psk_server_callback = ctx->psk_server_callback;
- s->tlsext_channel_id_enabled = ctx->tlsext_channel_id_enabled;
- if (ctx->tlsext_channel_id_private) {
- s->tlsext_channel_id_private =
- EVP_PKEY_up_ref(ctx->tlsext_channel_id_private);
+ /* Lock the SSL_CTX to the specified version, for compatibility with legacy
+ * uses of SSL_METHOD. */
+ if (method->version != 0) {
+ SSL_CTX_set_max_version(ret, method->version);
+ SSL_CTX_set_min_version(ret, method->version);
}
- s->signed_cert_timestamps_enabled = s->ctx->signed_cert_timestamps_enabled;
- s->ocsp_stapling_enabled = s->ctx->ocsp_stapling_enabled;
-
- return s;
+ return ret;
err:
- SSL_free(s);
- OPENSSL_PUT_ERROR(SSL, SSL_new, ERR_R_MALLOC_FAILURE);
-
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+err2:
+ SSL_CTX_free(ret);
return NULL;
}
-int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const uint8_t *sid_ctx,
- unsigned int sid_ctx_len) {
- if (sid_ctx_len > sizeof ctx->sid_ctx) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_set_session_id_context,
- SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
- return 0;
+void SSL_CTX_free(SSL_CTX *ctx) {
+ if (ctx == NULL ||
+ !CRYPTO_refcount_dec_and_test_zero(&ctx->references)) {
+ return;
}
- ctx->sid_ctx_length = sid_ctx_len;
- memcpy(ctx->sid_ctx, sid_ctx, sid_ctx_len);
- return 1;
-}
+ X509_VERIFY_PARAM_free(ctx->param);
-int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx,
- unsigned int sid_ctx_len) {
- if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) {
- OPENSSL_PUT_ERROR(SSL, SSL_set_session_id_context,
- SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
- return 0;
- }
- ssl->sid_ctx_length = sid_ctx_len;
- memcpy(ssl->sid_ctx, sid_ctx, sid_ctx_len);
+ /* Free internal session cache. However: the remove_cb() may reference the
+ * ex_data of SSL_CTX, thus the ex_data store can only be removed after the
+ * sessions were flushed. As the ex_data handling routines might also touch
+ * the session cache, the most secure solution seems to be: empty (flush) the
+ * cache, then free ex_data, then finally free the cache. (See ticket
+ * [openssl.org #212].) */
+ SSL_CTX_flush_sessions(ctx, 0);
- return 1;
-}
+ CRYPTO_free_ex_data(&g_ex_data_class_ssl_ctx, ctx, &ctx->ex_data);
-int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb) {
- ctx->generate_session_id = cb;
- return 1;
-}
+ CRYPTO_MUTEX_cleanup(&ctx->lock);
+ lh_SSL_SESSION_free(ctx->sessions);
+ X509_STORE_free(ctx->cert_store);
+ ssl_cipher_preference_list_free(ctx->cipher_list);
+ sk_SSL_CIPHER_free(ctx->cipher_list_by_id);
+ ssl_cipher_preference_list_free(ctx->cipher_list_tls10);
+ ssl_cipher_preference_list_free(ctx->cipher_list_tls11);
+ ssl_cert_free(ctx->cert);
+ sk_SSL_CUSTOM_EXTENSION_pop_free(ctx->client_custom_extensions,
+ SSL_CUSTOM_EXTENSION_free);
+ sk_SSL_CUSTOM_EXTENSION_pop_free(ctx->server_custom_extensions,
+ SSL_CUSTOM_EXTENSION_free);
+ sk_X509_NAME_pop_free(ctx->client_CA, X509_NAME_free);
+ sk_SRTP_PROTECTION_PROFILE_free(ctx->srtp_profiles);
+ OPENSSL_free(ctx->psk_identity_hint);
+ OPENSSL_free(ctx->tlsext_ellipticcurvelist);
+ OPENSSL_free(ctx->alpn_client_proto_list);
+ OPENSSL_free(ctx->ocsp_response);
+ OPENSSL_free(ctx->signed_cert_timestamp_list);
+ EVP_PKEY_free(ctx->tlsext_channel_id_private);
-int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb) {
- ssl->generate_session_id = cb;
- return 1;
+ OPENSSL_free(ctx);
}
-int SSL_has_matching_session_id(const SSL *ssl, const uint8_t *id,
- unsigned int id_len) {
- /* A quick examination of SSL_SESSION_hash and SSL_SESSION_cmp shows how we
- * can "construct" a session to give us the desired check - ie. to find if
- * there's a session in the hash table that would conflict with any new
- * session built out of this id/id_len and the ssl_version in use by this
- * SSL. */
- SSL_SESSION r, *p;
-
- if (id_len > sizeof r.session_id) {
- return 0;
+SSL *SSL_new(SSL_CTX *ctx) {
+ if (ctx == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NULL_SSL_CTX);
+ return NULL;
+ }
+ if (ctx->method == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION);
+ return NULL;
}
- r.ssl_version = ssl->version;
- r.session_id_length = id_len;
- memcpy(r.session_id, id, id_len);
-
- CRYPTO_MUTEX_lock_read(&ssl->ctx->lock);
- p = lh_SSL_SESSION_retrieve(ssl->ctx->sessions, &r);
- CRYPTO_MUTEX_unlock(&ssl->ctx->lock);
- return p != NULL;
-}
-
-int SSL_CTX_set_purpose(SSL_CTX *s, int purpose) {
- return X509_VERIFY_PARAM_set_purpose(s->param, purpose);
-}
-
-int SSL_set_purpose(SSL *s, int purpose) {
- return X509_VERIFY_PARAM_set_purpose(s->param, purpose);
-}
+ SSL *ssl = (SSL *)OPENSSL_malloc(sizeof(SSL));
+ if (ssl == NULL) {
+ goto err;
+ }
+ memset(ssl, 0, sizeof(SSL));
-int SSL_CTX_set_trust(SSL_CTX *s, int trust) {
- return X509_VERIFY_PARAM_set_trust(s->param, trust);
-}
+ ssl->min_version = ctx->min_version;
+ ssl->max_version = ctx->max_version;
-int SSL_set_trust(SSL *s, int trust) {
- return X509_VERIFY_PARAM_set_trust(s->param, trust);
-}
+ ssl->options = ctx->options;
+ ssl->mode = ctx->mode;
+ ssl->max_cert_list = ctx->max_cert_list;
-int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm) {
- return X509_VERIFY_PARAM_set1(ctx->param, vpm);
-}
+ ssl->cert = ssl_cert_dup(ctx->cert);
+ if (ssl->cert == NULL) {
+ goto err;
+ }
-int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm) {
- return X509_VERIFY_PARAM_set1(ssl->param, vpm);
-}
+ 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;
-void ssl_cipher_preference_list_free(
- struct ssl_cipher_preference_list_st *cipher_list) {
- if (cipher_list == NULL) {
- return;
+ ssl->param = X509_VERIFY_PARAM_new();
+ if (!ssl->param) {
+ goto err;
}
- sk_SSL_CIPHER_free(cipher_list->ciphers);
- OPENSSL_free(cipher_list->in_group_flags);
- OPENSSL_free(cipher_list);
-}
+ X509_VERIFY_PARAM_inherit(ssl->param, ctx->param);
+ ssl->quiet_shutdown = ctx->quiet_shutdown;
+ ssl->max_send_fragment = ctx->max_send_fragment;
-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);
+ CRYPTO_refcount_inc(&ctx->references);
+ ssl->ctx = ctx;
+ CRYPTO_refcount_inc(&ctx->references);
+ ssl->initial_ctx = ctx;
- ret = OPENSSL_malloc(sizeof(struct ssl_cipher_preference_list_st));
- if (!ret) {
- goto err;
+ if (ctx->tlsext_ellipticcurvelist) {
+ ssl->tlsext_ellipticcurvelist =
+ BUF_memdup(ctx->tlsext_ellipticcurvelist,
+ ctx->tlsext_ellipticcurvelist_length * 2);
+ if (!ssl->tlsext_ellipticcurvelist) {
+ goto err;
+ }
+ ssl->tlsext_ellipticcurvelist_length = ctx->tlsext_ellipticcurvelist_length;
}
- ret->ciphers = NULL;
- ret->in_group_flags = NULL;
- ret->ciphers = sk_SSL_CIPHER_dup(cipher_list->ciphers);
- if (!ret->ciphers) {
- goto err;
+ 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;
+ }
+ ssl->alpn_client_proto_list_len = ssl->ctx->alpn_client_proto_list_len;
}
- ret->in_group_flags = BUF_memdup(cipher_list->in_group_flags, n);
- if (!ret->in_group_flags) {
+
+ ssl->verify_result = X509_V_OK;
+ ssl->method = ctx->method;
+
+ if (!ssl->method->ssl_new(ssl)) {
goto err;
}
+ ssl->enc_method = ssl3_get_enc_method(ssl->version);
+ assert(ssl->enc_method != NULL);
- return ret;
-
-err:
- ssl_cipher_preference_list_free(ret);
- return NULL;
-}
+ ssl->rwstate = SSL_NOTHING;
-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);
+ CRYPTO_new_ex_data(&ssl->ex_data);
- 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;
+ ssl->psk_identity_hint = NULL;
+ if (ctx->psk_identity_hint) {
+ ssl->psk_identity_hint = BUF_strdup(ctx->psk_identity_hint);
+ if (ssl->psk_identity_hint == NULL) {
+ goto err;
+ }
}
- ret->in_group_flags = OPENSSL_malloc(n);
- if (!ret->in_group_flags) {
- goto err;
+ ssl->psk_client_callback = ctx->psk_client_callback;
+ ssl->psk_server_callback = ctx->psk_server_callback;
+
+ ssl->tlsext_channel_id_enabled = ctx->tlsext_channel_id_enabled;
+ if (ctx->tlsext_channel_id_private) {
+ ssl->tlsext_channel_id_private =
+ EVP_PKEY_up_ref(ctx->tlsext_channel_id_private);
}
- memset(ret->in_group_flags, 0, n);
- return ret;
-err:
- ssl_cipher_preference_list_free(ret);
- return NULL;
-}
+ ssl->signed_cert_timestamps_enabled =
+ ssl->ctx->signed_cert_timestamps_enabled;
+ ssl->ocsp_stapling_enabled = ssl->ctx->ocsp_stapling_enabled;
-X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) { return ctx->param; }
+ return ssl;
-X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) { return ssl->param; }
+err:
+ SSL_free(ssl);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
-void SSL_certs_clear(SSL *s) { ssl_cert_clear_certs(s->cert); }
+ return NULL;
+}
void SSL_free(SSL *ssl) {
if (ssl == NULL) {
@@ -556,7 +492,6 @@ void SSL_free(SSL *ssl) {
OPENSSL_free(ssl->tlsext_hostname);
SSL_CTX_free(ssl->initial_ctx);
- OPENSSL_free(ssl->tlsext_ecpointformatlist);
OPENSSL_free(ssl->tlsext_ellipticcurvelist);
OPENSSL_free(ssl->alpn_client_proto_list);
EVP_PKEY_free(ssl->tlsext_channel_id_private);
@@ -573,466 +508,662 @@ void SSL_free(SSL *ssl) {
OPENSSL_free(ssl);
}
-void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio) {
+void SSL_set_connect_state(SSL *ssl) {
+ ssl->server = 0;
+ ssl->shutdown = 0;
+ ssl->state = SSL_ST_CONNECT;
+ ssl->handshake_func = ssl->method->ssl_connect;
+ /* clear the current cipher */
+ ssl_clear_cipher_ctx(ssl);
+}
+
+void SSL_set_accept_state(SSL *ssl) {
+ ssl->server = 1;
+ ssl->shutdown = 0;
+ ssl->state = SSL_ST_ACCEPT;
+ ssl->handshake_func = ssl->method->ssl_accept;
+ /* clear the current cipher */
+ ssl_clear_cipher_ctx(ssl);
+}
+
+void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio) {
/* If the output buffering BIO is still in place, remove it. */
- if (s->bbio != NULL) {
- if (s->wbio == s->bbio) {
- s->wbio = s->wbio->next_bio;
- s->bbio->next_bio = NULL;
+ if (ssl->bbio != NULL) {
+ if (ssl->wbio == ssl->bbio) {
+ ssl->wbio = ssl->wbio->next_bio;
+ ssl->bbio->next_bio = NULL;
}
}
- if (s->rbio != rbio) {
- BIO_free_all(s->rbio);
+ if (ssl->rbio != rbio) {
+ BIO_free_all(ssl->rbio);
}
- if (s->wbio != wbio && s->rbio != s->wbio) {
- BIO_free_all(s->wbio);
+ if (ssl->wbio != wbio && ssl->rbio != ssl->wbio) {
+ BIO_free_all(ssl->wbio);
}
- s->rbio = rbio;
- s->wbio = wbio;
+ ssl->rbio = rbio;
+ ssl->wbio = wbio;
}
-BIO *SSL_get_rbio(const SSL *s) { return s->rbio; }
-
-BIO *SSL_get_wbio(const SSL *s) { return s->wbio; }
+BIO *SSL_get_rbio(const SSL *ssl) { return ssl->rbio; }
-int SSL_get_fd(const SSL *s) { return SSL_get_rfd(s); }
+BIO *SSL_get_wbio(const SSL *ssl) { return ssl->wbio; }
-int SSL_get_rfd(const SSL *s) {
- int ret = -1;
- BIO *b, *r;
+int SSL_do_handshake(SSL *ssl) {
+ if (ssl->handshake_func == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_TYPE_NOT_SET);
+ return -1;
+ }
- b = SSL_get_rbio(s);
- r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR);
- if (r != NULL) {
- BIO_get_fd(r, &ret);
+ if (!SSL_in_init(ssl)) {
+ return 1;
}
- return ret;
+
+ return ssl->handshake_func(ssl);
}
-int SSL_get_wfd(const SSL *s) {
- int ret = -1;
- BIO *b, *r;
+int SSL_connect(SSL *ssl) {
+ if (ssl->handshake_func == 0) {
+ /* Not properly initialized yet */
+ SSL_set_connect_state(ssl);
+ }
- b = SSL_get_wbio(s);
- r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR);
- if (r != NULL) {
- BIO_get_fd(r, &ret);
+ if (ssl->handshake_func != ssl->method->ssl_connect) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return -1;
}
- return ret;
+ return ssl->handshake_func(ssl);
}
-int SSL_set_fd(SSL *s, int fd) {
- int ret = 0;
- BIO *bio = NULL;
+int SSL_accept(SSL *ssl) {
+ if (ssl->handshake_func == 0) {
+ /* Not properly initialized yet */
+ SSL_set_accept_state(ssl);
+ }
- bio = BIO_new(BIO_s_fd());
+ if (ssl->handshake_func != ssl->method->ssl_accept) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
- if (bio == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_set_fd, ERR_R_BUF_LIB);
- goto err;
+ return ssl->handshake_func(ssl);
+}
+
+int SSL_read(SSL *ssl, void *buf, int num) {
+ if (ssl->handshake_func == 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
+ return -1;
}
- BIO_set_fd(bio, fd, BIO_NOCLOSE);
- SSL_set_bio(s, bio, bio);
- ret = 1;
-err:
- return ret;
+ if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN) {
+ ssl->rwstate = SSL_NOTHING;
+ return 0;
+ }
+
+ ERR_clear_system_error();
+ return ssl->method->ssl_read_app_data(ssl, buf, num, 0);
}
-int SSL_set_wfd(SSL *s, int fd) {
- int ret = 0;
- BIO *bio = NULL;
+int SSL_peek(SSL *ssl, void *buf, int num) {
+ if (ssl->handshake_func == 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
+ return -1;
+ }
- if (s->rbio == NULL || BIO_method_type(s->rbio) != BIO_TYPE_FD ||
- (int)BIO_get_fd(s->rbio, NULL) != fd) {
- bio = BIO_new(BIO_s_fd());
+ if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN) {
+ return 0;
+ }
- if (bio == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_set_wfd, ERR_R_BUF_LIB);
- goto err;
- }
- BIO_set_fd(bio, fd, BIO_NOCLOSE);
- SSL_set_bio(s, SSL_get_rbio(s), bio);
- } else {
- SSL_set_bio(s, SSL_get_rbio(s), SSL_get_rbio(s));
+ ERR_clear_system_error();
+ return ssl->method->ssl_read_app_data(ssl, buf, num, 1);
+}
+
+int SSL_write(SSL *ssl, const void *buf, int num) {
+ if (ssl->handshake_func == 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
+ return -1;
}
- ret = 1;
+ if (ssl->shutdown & SSL_SENT_SHUTDOWN) {
+ ssl->rwstate = SSL_NOTHING;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
+ return -1;
+ }
-err:
- return ret;
+ ERR_clear_system_error();
+ return ssl->method->ssl_write_app_data(ssl, buf, num);
}
-int SSL_set_rfd(SSL *s, int fd) {
- int ret = 0;
- BIO *bio = NULL;
+int SSL_shutdown(SSL *ssl) {
+ /* Note that this function behaves differently from what one might expect.
+ * Return values are 0 for no success (yet), 1 for success; but calling it
+ * once is usually not enough, even if blocking I/O is used (see
+ * ssl3_shutdown). */
- if (s->wbio == NULL || BIO_method_type(s->wbio) != BIO_TYPE_FD ||
- (int)BIO_get_fd(s->wbio, NULL) != fd) {
- bio = BIO_new(BIO_s_fd());
+ if (ssl->handshake_func == 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
+ return -1;
+ }
- if (bio == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_set_rfd, ERR_R_BUF_LIB);
- goto err;
+ if (SSL_in_init(ssl)) {
+ return 1;
+ }
+
+ /* Do nothing if configured not to send a close_notify. */
+ if (ssl->quiet_shutdown) {
+ ssl->shutdown = SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN;
+ return 1;
+ }
+
+ if (!(ssl->shutdown & SSL_SENT_SHUTDOWN)) {
+ ssl->shutdown |= SSL_SENT_SHUTDOWN;
+ ssl3_send_alert(ssl, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY);
+
+ /* our shutdown alert has been sent now, and if it still needs to be
+ * written, ssl->s3->alert_dispatch will be true */
+ if (ssl->s3->alert_dispatch) {
+ return -1; /* return WANT_WRITE */
+ }
+ } else if (ssl->s3->alert_dispatch) {
+ /* resend it if not sent */
+ int ret = ssl->method->ssl_dispatch_alert(ssl);
+ if (ret == -1) {
+ /* we only get to return -1 here the 2nd/Nth invocation, we must have
+ * already signalled return 0 upon a previous invoation, return
+ * WANT_WRITE */
+ return ret;
+ }
+ } else if (!(ssl->shutdown & SSL_RECEIVED_SHUTDOWN)) {
+ /* If we are waiting for a close from our peer, we are closed */
+ ssl->method->ssl_read_close_notify(ssl);
+ if (!(ssl->shutdown & SSL_RECEIVED_SHUTDOWN)) {
+ return -1; /* return WANT_READ */
}
- BIO_set_fd(bio, fd, BIO_NOCLOSE);
- SSL_set_bio(s, bio, SSL_get_wbio(s));
- } else {
- SSL_set_bio(s, SSL_get_wbio(s), SSL_get_wbio(s));
}
- ret = 1;
-err:
- return ret;
+ if (ssl->shutdown == (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN) &&
+ !ssl->s3->alert_dispatch) {
+ return 1;
+ } else {
+ return 0;
+ }
}
-/* return length of latest Finished message we sent, copy to 'buf' */
-size_t SSL_get_finished(const SSL *s, void *buf, size_t count) {
- size_t ret = 0;
+int SSL_get_error(const SSL *ssl, int ret_code) {
+ int reason;
+ uint32_t err;
+ BIO *bio;
- if (s->s3 != NULL) {
- ret = s->s3->tmp.finish_md_len;
- if (count > ret) {
- count = ret;
+ if (ret_code > 0) {
+ return SSL_ERROR_NONE;
+ }
+
+ /* Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake etc,
+ * where we do encode the error */
+ err = ERR_peek_error();
+ if (err != 0) {
+ if (ERR_GET_LIB(err) == ERR_LIB_SYS) {
+ return SSL_ERROR_SYSCALL;
}
- memcpy(buf, s->s3->tmp.finish_md, count);
+ return SSL_ERROR_SSL;
}
- return ret;
-}
+ if (ret_code == 0) {
+ if ((ssl->shutdown & SSL_RECEIVED_SHUTDOWN) &&
+ (ssl->s3->warn_alert == SSL_AD_CLOSE_NOTIFY)) {
+ /* The socket was cleanly shut down with a close_notify. */
+ return SSL_ERROR_ZERO_RETURN;
+ }
+ /* An EOF was observed which violates the protocol, and the underlying
+ * transport does not participate in the error queue. Bubble up to the
+ * caller. */
+ return SSL_ERROR_SYSCALL;
+ }
-/* return length of latest Finished message we expected, copy to 'buf' */
-size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count) {
- size_t ret = 0;
+ if (SSL_want_session(ssl)) {
+ return SSL_ERROR_PENDING_SESSION;
+ }
- if (s->s3 != NULL) {
- ret = s->s3->tmp.peer_finish_md_len;
- if (count > ret) {
- count = ret;
+ if (SSL_want_certificate(ssl)) {
+ return SSL_ERROR_PENDING_CERTIFICATE;
+ }
+
+ if (SSL_want_read(ssl)) {
+ bio = SSL_get_rbio(ssl);
+ if (BIO_should_read(bio)) {
+ return SSL_ERROR_WANT_READ;
+ }
+
+ if (BIO_should_write(bio)) {
+ /* 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
+ * 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;
+ }
+
+ if (BIO_should_io_special(bio)) {
+ reason = BIO_get_retry_reason(bio);
+ if (reason == BIO_RR_CONNECT) {
+ return SSL_ERROR_WANT_CONNECT;
+ }
+
+ if (reason == BIO_RR_ACCEPT) {
+ return SSL_ERROR_WANT_ACCEPT;
+ }
+
+ return SSL_ERROR_SYSCALL; /* unknown */
}
- memcpy(buf, s->s3->tmp.peer_finish_md, count);
}
- return ret;
+ if (SSL_want_write(ssl)) {
+ bio = SSL_get_wbio(ssl);
+ if (BIO_should_write(bio)) {
+ return SSL_ERROR_WANT_WRITE;
+ }
+
+ if (BIO_should_read(bio)) {
+ /* See above (SSL_want_read(ssl) with BIO_should_write(bio)) */
+ return SSL_ERROR_WANT_READ;
+ }
+
+ if (BIO_should_io_special(bio)) {
+ reason = BIO_get_retry_reason(bio);
+ if (reason == BIO_RR_CONNECT) {
+ return SSL_ERROR_WANT_CONNECT;
+ }
+
+ if (reason == BIO_RR_ACCEPT) {
+ return SSL_ERROR_WANT_ACCEPT;
+ }
+
+ return SSL_ERROR_SYSCALL;
+ }
+ }
+
+ if (SSL_want_x509_lookup(ssl)) {
+ return SSL_ERROR_WANT_X509_LOOKUP;
+ }
+
+ if (SSL_want_channel_id_lookup(ssl)) {
+ return SSL_ERROR_WANT_CHANNEL_ID_LOOKUP;
+ }
+
+ if (SSL_want_private_key_operation(ssl)) {
+ return SSL_ERROR_WANT_PRIVATE_KEY_OPERATION;
+ }
+
+ return SSL_ERROR_SYSCALL;
}
-int SSL_get_verify_mode(const SSL *s) { return s->verify_mode; }
+void SSL_CTX_set_min_version(SSL_CTX *ctx, uint16_t version) {
+ ctx->min_version = version;
+}
-int SSL_get_verify_depth(const SSL *s) {
- return X509_VERIFY_PARAM_get_depth(s->param);
+void SSL_CTX_set_max_version(SSL_CTX *ctx, uint16_t version) {
+ ctx->max_version = version;
}
-int (*SSL_get_verify_callback(const SSL *s))(int, X509_STORE_CTX *) {
- return s->verify_callback;
+void SSL_set_min_version(SSL *ssl, uint16_t version) {
+ ssl->min_version = version;
}
-int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) { return ctx->verify_mode; }
+void SSL_set_max_version(SSL *ssl, uint16_t version) {
+ ssl->max_version = version;
+}
-int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) {
- return X509_VERIFY_PARAM_get_depth(ctx->param);
+uint32_t SSL_CTX_set_options(SSL_CTX *ctx, uint32_t options) {
+ ctx->options |= options;
+ return ctx->options;
}
-int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(int, X509_STORE_CTX *) {
- return ctx->default_verify_callback;
+uint32_t SSL_CTX_clear_options(SSL_CTX *ctx, uint32_t options) {
+ ctx->options &= ~options;
+ return ctx->options;
}
-void SSL_set_verify(SSL *s, int mode,
- int (*callback)(int ok, X509_STORE_CTX *ctx)) {
- s->verify_mode = mode;
- if (callback != NULL) {
- s->verify_callback = callback;
- }
+uint32_t SSL_CTX_get_options(const SSL_CTX *ctx) { return ctx->options; }
+
+uint32_t SSL_set_options(SSL *ssl, uint32_t options) {
+ ssl->options |= options;
+ return ssl->options;
}
-void SSL_set_verify_depth(SSL *s, int depth) {
- X509_VERIFY_PARAM_set_depth(s->param, depth);
+uint32_t SSL_clear_options(SSL *ssl, uint32_t options) {
+ ssl->options &= ~options;
+ return ssl->options;
}
-int SSL_CTX_get_read_ahead(const SSL_CTX *ctx) { return 0; }
+uint32_t SSL_get_options(const SSL *ssl) { return ssl->options; }
-int SSL_get_read_ahead(const SSL *s) { return 0; }
+uint32_t SSL_CTX_set_mode(SSL_CTX *ctx, uint32_t mode) {
+ ctx->mode |= mode;
+ return ctx->mode;
+}
-void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes) { }
+uint32_t SSL_CTX_clear_mode(SSL_CTX *ctx, uint32_t mode) {
+ ctx->mode &= ~mode;
+ return ctx->mode;
+}
-void SSL_set_read_ahead(SSL *s, int yes) { }
+uint32_t SSL_CTX_get_mode(const SSL_CTX *ctx) { return ctx->mode; }
-int SSL_pending(const SSL *s) {
- if (s->rstate == SSL_ST_READ_BODY) {
- return 0;
- }
+uint32_t SSL_set_mode(SSL *ssl, uint32_t mode) {
+ ssl->mode |= mode;
+ return ssl->mode;
+}
- return (s->s3->rrec.type == SSL3_RT_APPLICATION_DATA) ? s->s3->rrec.length
- : 0;
+uint32_t SSL_clear_mode(SSL *ssl, uint32_t mode) {
+ ssl->mode &= ~mode;
+ return ssl->mode;
}
-X509 *SSL_get_peer_certificate(const SSL *s) {
- X509 *r;
+uint32_t SSL_get_mode(const SSL *ssl) { return ssl->mode; }
- if (s == NULL || s->session == NULL) {
- r = NULL;
- } else {
- r = s->session->peer;
+X509 *SSL_get_peer_certificate(const SSL *ssl) {
+ if (ssl == NULL || ssl->session == NULL || ssl->session->peer == NULL) {
+ return NULL;
}
+ return X509_up_ref(ssl->session->peer);
+}
- if (r == NULL) {
+STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *ssl) {
+ if (ssl == NULL || ssl->session == NULL) {
return NULL;
}
-
- return X509_up_ref(r);
+ return ssl->session->cert_chain;
}
-STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s) {
- STACK_OF(X509) *r;
-
- if (s == NULL || s->session == NULL || s->session->sess_cert == NULL) {
- r = NULL;
- } else {
- r = s->session->sess_cert->cert_chain;
+int SSL_get_tls_unique(const SSL *ssl, uint8_t *out, size_t *out_len,
+ size_t max_out) {
+ /* The tls-unique value is the first Finished message in the handshake, which
+ * is the client's in a full handshake and the server's for a resumption. See
+ * https://tools.ietf.org/html/rfc5929#section-3.1. */
+ const uint8_t *finished = ssl->s3->previous_client_finished;
+ size_t finished_len = ssl->s3->previous_client_finished_len;
+ if (ssl->hit) {
+ /* tls-unique is broken for resumed sessions unless EMS is used. */
+ if (!ssl->session->extended_master_secret) {
+ goto err;
+ }
+ finished = ssl->s3->previous_server_finished;
+ finished_len = ssl->s3->previous_server_finished_len;
}
- /* If we are a client, cert_chain includes the peer's own certificate; if we
- * are a server, it does not. */
- return r;
-}
-
-/* Fix this so it checks all the valid key/cert options */
-int SSL_CTX_check_private_key(const SSL_CTX *ctx) {
- if (ctx == NULL || ctx->cert == NULL || ctx->cert->key->x509 == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_check_private_key,
- SSL_R_NO_CERTIFICATE_ASSIGNED);
- return 0;
+ if (!ssl->s3->initial_handshake_complete ||
+ ssl->version < TLS1_VERSION) {
+ goto err;
}
- if (ctx->cert->key->privatekey == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_check_private_key,
- SSL_R_NO_PRIVATE_KEY_ASSIGNED);
- return 0;
+ *out_len = finished_len;
+ if (finished_len > max_out) {
+ *out_len = max_out;
}
- return X509_check_private_key(ctx->cert->key->x509,
- ctx->cert->key->privatekey);
-}
+ memcpy(out, finished, *out_len);
+ return 1;
-/* Fix this function so that it takes an optional type parameter */
-int SSL_check_private_key(const SSL *ssl) {
- if (ssl == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_check_private_key, ERR_R_PASSED_NULL_PARAMETER);
- return 0;
- }
+err:
+ *out_len = 0;
+ memset(out, 0, max_out);
+ return 0;
+}
- if (ssl->cert == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_check_private_key,
- SSL_R_NO_CERTIFICATE_ASSIGNED);
+int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const uint8_t *sid_ctx,
+ unsigned sid_ctx_len) {
+ if (sid_ctx_len > sizeof(ctx->sid_ctx)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
return 0;
}
+ ctx->sid_ctx_length = sid_ctx_len;
+ memcpy(ctx->sid_ctx, sid_ctx, sid_ctx_len);
- if (ssl->cert->key->x509 == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_check_private_key,
- SSL_R_NO_CERTIFICATE_ASSIGNED);
- return 0;
- }
+ return 1;
+}
- if (ssl->cert->key->privatekey == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_check_private_key,
- SSL_R_NO_PRIVATE_KEY_ASSIGNED);
+int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx,
+ unsigned sid_ctx_len) {
+ if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
return 0;
}
+ ssl->sid_ctx_length = sid_ctx_len;
+ memcpy(ssl->sid_ctx, sid_ctx, sid_ctx_len);
- return X509_check_private_key(ssl->cert->key->x509,
- ssl->cert->key->privatekey);
+ return 1;
}
-int SSL_accept(SSL *s) {
- if (s->handshake_func == 0) {
- /* Not properly initialized yet */
- SSL_set_accept_state(s);
- }
-
- if (s->handshake_func != s->method->ssl_accept) {
- OPENSSL_PUT_ERROR(SSL, SSL_accept, ERR_R_INTERNAL_ERROR);
- return -1;
- }
+int SSL_CTX_set_purpose(SSL_CTX *ctx, int purpose) {
+ return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
+}
- return s->handshake_func(s);
+int SSL_set_purpose(SSL *ssl, int purpose) {
+ return X509_VERIFY_PARAM_set_purpose(ssl->param, purpose);
}
-int SSL_connect(SSL *s) {
- if (s->handshake_func == 0) {
- /* Not properly initialized yet */
- SSL_set_connect_state(s);
- }
+int SSL_CTX_set_trust(SSL_CTX *ctx, int trust) {
+ return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
+}
- if (s->handshake_func != s->method->ssl_connect) {
- OPENSSL_PUT_ERROR(SSL, SSL_connect, ERR_R_INTERNAL_ERROR);
- return -1;
- }
+int SSL_set_trust(SSL *ssl, int trust) {
+ return X509_VERIFY_PARAM_set_trust(ssl->param, trust);
+}
- return s->handshake_func(s);
+int SSL_CTX_set1_param(SSL_CTX *ctx, const X509_VERIFY_PARAM *param) {
+ return X509_VERIFY_PARAM_set1(ctx->param, param);
}
-long SSL_get_default_timeout(const SSL *s) {
- return SSL_DEFAULT_SESSION_TIMEOUT;
+int SSL_set1_param(SSL *ssl, const X509_VERIFY_PARAM *param) {
+ return X509_VERIFY_PARAM_set1(ssl->param, param);
}
-int SSL_read(SSL *s, void *buf, int num) {
- if (s->handshake_func == 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_read, SSL_R_UNINITIALIZED);
- return -1;
+void ssl_cipher_preference_list_free(
+ struct ssl_cipher_preference_list_st *cipher_list) {
+ if (cipher_list == NULL) {
+ return;
}
+ sk_SSL_CIPHER_free(cipher_list->ciphers);
+ OPENSSL_free(cipher_list->in_group_flags);
+ OPENSSL_free(cipher_list);
+}
- if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
- s->rwstate = SSL_NOTHING;
- return 0;
- }
+X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) { return ctx->param; }
- ERR_clear_system_error();
- return s->method->ssl_read_app_data(s, buf, num, 0);
-}
+X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) { return ssl->param; }
-int SSL_peek(SSL *s, void *buf, int num) {
- if (s->handshake_func == 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_peek, SSL_R_UNINITIALIZED);
- return -1;
- }
+void SSL_certs_clear(SSL *ssl) { ssl_cert_clear_certs(ssl->cert); }
- if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
- return 0;
+int SSL_get_fd(const SSL *ssl) { return SSL_get_rfd(ssl); }
+
+int SSL_get_rfd(const SSL *ssl) {
+ int ret = -1;
+ BIO *b = BIO_find_type(SSL_get_rbio(ssl), BIO_TYPE_DESCRIPTOR);
+ if (b != NULL) {
+ BIO_get_fd(b, &ret);
}
+ return ret;
+}
- ERR_clear_system_error();
- return s->method->ssl_read_app_data(s, buf, num, 1);
+int SSL_get_wfd(const SSL *ssl) {
+ int ret = -1;
+ BIO *b = BIO_find_type(SSL_get_wbio(ssl), BIO_TYPE_DESCRIPTOR);
+ if (b != NULL) {
+ BIO_get_fd(b, &ret);
+ }
+ return ret;
}
-int SSL_write(SSL *s, const void *buf, int num) {
- if (s->handshake_func == 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_write, SSL_R_UNINITIALIZED);
- return -1;
+int SSL_set_fd(SSL *ssl, int fd) {
+ BIO *bio = BIO_new(BIO_s_fd());
+ if (bio == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
+ return 0;
}
+ BIO_set_fd(bio, fd, BIO_NOCLOSE);
+ SSL_set_bio(ssl, bio, bio);
+ return 1;
+}
- if (s->shutdown & SSL_SENT_SHUTDOWN) {
- s->rwstate = SSL_NOTHING;
- OPENSSL_PUT_ERROR(SSL, SSL_write, SSL_R_PROTOCOL_IS_SHUTDOWN);
- return -1;
+int SSL_set_wfd(SSL *ssl, int fd) {
+ if (ssl->rbio == NULL ||
+ BIO_method_type(ssl->rbio) != BIO_TYPE_FD ||
+ BIO_get_fd(ssl->rbio, NULL) != fd) {
+ BIO *bio = BIO_new(BIO_s_fd());
+ if (bio == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
+ return 0;
+ }
+ BIO_set_fd(bio, fd, BIO_NOCLOSE);
+ SSL_set_bio(ssl, SSL_get_rbio(ssl), bio);
+ } else {
+ SSL_set_bio(ssl, SSL_get_rbio(ssl), SSL_get_rbio(ssl));
}
- ERR_clear_system_error();
- return s->method->ssl_write_app_data(s, buf, num);
+ return 1;
}
-int SSL_shutdown(SSL *s) {
- /* Note that this function behaves differently from what one might expect.
- * Return values are 0 for no success (yet), 1 for success; but calling it
- * once is usually not enough, even if blocking I/O is used (see
- * ssl3_shutdown). */
-
- if (s->handshake_func == 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_shutdown, SSL_R_UNINITIALIZED);
- return -1;
+int SSL_set_rfd(SSL *ssl, int fd) {
+ if (ssl->wbio == NULL || BIO_method_type(ssl->wbio) != BIO_TYPE_FD ||
+ BIO_get_fd(ssl->wbio, NULL) != fd) {
+ BIO *bio = BIO_new(BIO_s_fd());
+ if (bio == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
+ return 0;
+ }
+ BIO_set_fd(bio, fd, BIO_NOCLOSE);
+ SSL_set_bio(ssl, bio, SSL_get_wbio(ssl));
+ } else {
+ SSL_set_bio(ssl, SSL_get_wbio(ssl), SSL_get_wbio(ssl));
}
+ return 1;
+}
- if (SSL_in_init(s)) {
- return 1;
- }
+size_t SSL_get_finished(const SSL *ssl, void *buf, size_t count) {
+ size_t ret = 0;
- /* Do nothing if configured not to send a close_notify. */
- if (s->quiet_shutdown) {
- s->shutdown = SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN;
- return 1;
+ if (ssl->s3 != NULL) {
+ ret = ssl->s3->tmp.finish_md_len;
+ if (count > ret) {
+ count = ret;
+ }
+ memcpy(buf, ssl->s3->tmp.finish_md, count);
}
- if (!(s->shutdown & SSL_SENT_SHUTDOWN)) {
- s->shutdown |= SSL_SENT_SHUTDOWN;
- ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY);
+ return ret;
+}
- /* our shutdown alert has been sent now, and if it still needs to be
- * written, s->s3->alert_dispatch will be true */
- if (s->s3->alert_dispatch) {
- return -1; /* return WANT_WRITE */
- }
- } else if (s->s3->alert_dispatch) {
- /* resend it if not sent */
- int ret = s->method->ssl_dispatch_alert(s);
- if (ret == -1) {
- /* we only get to return -1 here the 2nd/Nth invocation, we must have
- * already signalled return 0 upon a previous invoation, return
- * WANT_WRITE */
- return ret;
- }
- } else if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) {
- /* If we are waiting for a close from our peer, we are closed */
- s->method->ssl_read_close_notify(s);
- if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) {
- return -1; /* return WANT_READ */
+size_t SSL_get_peer_finished(const SSL *ssl, void *buf, size_t count) {
+ size_t ret = 0;
+
+ if (ssl->s3 != NULL) {
+ ret = ssl->s3->tmp.peer_finish_md_len;
+ if (count > ret) {
+ count = ret;
}
+ memcpy(buf, ssl->s3->tmp.peer_finish_md, count);
}
- if (s->shutdown == (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN) &&
- !s->s3->alert_dispatch) {
- return 1;
- } else {
- return 0;
- }
+ return ret;
}
-int SSL_renegotiate(SSL *ssl) {
- /* Caller-initiated renegotiation is not supported. */
- OPENSSL_PUT_ERROR(SSL, SSL_renegotiate, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
+int SSL_get_verify_mode(const SSL *ssl) { return ssl->verify_mode; }
+
+int SSL_get_verify_depth(const SSL *ssl) {
+ return X509_VERIFY_PARAM_get_depth(ssl->param);
}
-int SSL_renegotiate_pending(SSL *ssl) {
- return SSL_in_init(ssl) && ssl->s3->initial_handshake_complete;
+int SSL_get_extms_support(const SSL *ssl) {
+ return ssl->s3->tmp.extended_master_secret == 1;
}
-uint32_t SSL_CTX_set_options(SSL_CTX *ctx, uint32_t options) {
- ctx->options |= options;
- return ctx->options;
+int (*SSL_get_verify_callback(const SSL *ssl))(int, X509_STORE_CTX *) {
+ return ssl->verify_callback;
}
-uint32_t SSL_set_options(SSL *ssl, uint32_t options) {
- ssl->options |= options;
- return ssl->options;
+int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) { return ctx->verify_mode; }
+
+int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) {
+ return X509_VERIFY_PARAM_get_depth(ctx->param);
}
-uint32_t SSL_CTX_clear_options(SSL_CTX *ctx, uint32_t options) {
- ctx->options &= ~options;
- return ctx->options;
+int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(
+ int ok, X509_STORE_CTX *store_ctx) {
+ return ctx->default_verify_callback;
}
-uint32_t SSL_clear_options(SSL *ssl, uint32_t options) {
- ssl->options &= ~options;
- return ssl->options;
+void SSL_set_verify(SSL *ssl, int mode,
+ int (*callback)(int ok, X509_STORE_CTX *store_ctx)) {
+ ssl->verify_mode = mode;
+ if (callback != NULL) {
+ ssl->verify_callback = callback;
+ }
}
-uint32_t SSL_CTX_get_options(const SSL_CTX *ctx) { return ctx->options; }
+void SSL_set_verify_depth(SSL *ssl, int depth) {
+ X509_VERIFY_PARAM_set_depth(ssl->param, depth);
+}
-uint32_t SSL_get_options(const SSL *ssl) { return ssl->options; }
+int SSL_CTX_get_read_ahead(const SSL_CTX *ctx) { return 0; }
-uint32_t SSL_CTX_set_mode(SSL_CTX *ctx, uint32_t mode) {
- ctx->mode |= mode;
- return ctx->mode;
+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 *ssl, int yes) { }
+
+int SSL_pending(const SSL *ssl) {
+ if (ssl->s3->rrec.type != SSL3_RT_APPLICATION_DATA) {
+ return 0;
+ }
+ return ssl->s3->rrec.length;
}
-uint32_t SSL_set_mode(SSL *ssl, uint32_t mode) {
- ssl->mode |= mode;
- return ssl->mode;
+/* Fix this so it checks all the valid key/cert options */
+int SSL_CTX_check_private_key(const SSL_CTX *ctx) {
+ if (ctx->cert->x509 == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_ASSIGNED);
+ return 0;
+ }
+
+ if (ctx->cert->privatekey == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED);
+ return 0;
+ }
+
+ return X509_check_private_key(ctx->cert->x509, ctx->cert->privatekey);
}
-uint32_t SSL_CTX_clear_mode(SSL_CTX *ctx, uint32_t mode) {
- ctx->mode &= ~mode;
- return ctx->mode;
+/* Fix this function so that it takes an optional type parameter */
+int SSL_check_private_key(const SSL *ssl) {
+ if (ssl->cert->x509 == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_ASSIGNED);
+ return 0;
+ }
+
+ if (ssl->cert->privatekey == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED);
+ return 0;
+ }
+
+ return X509_check_private_key(ssl->cert->x509, ssl->cert->privatekey);
}
-uint32_t SSL_clear_mode(SSL *ssl, uint32_t mode) {
- ssl->mode &= ~mode;
- return ssl->mode;
+long SSL_get_default_timeout(const SSL *ssl) {
+ return SSL_DEFAULT_SESSION_TIMEOUT;
}
-uint32_t SSL_CTX_get_mode(const SSL_CTX *ctx) { return ctx->mode; }
+int SSL_renegotiate(SSL *ssl) {
+ /* Caller-initiated renegotiation is not supported. */
+ OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+}
-uint32_t SSL_get_mode(const SSL *ssl) { return ssl->mode; }
+int SSL_renegotiate_pending(SSL *ssl) {
+ return SSL_in_init(ssl) && ssl->s3->initial_handshake_complete;
+}
size_t SSL_CTX_get_max_cert_list(const SSL_CTX *ctx) {
return ctx->max_cert_list;
@@ -1088,10 +1219,6 @@ int SSL_get_secure_renegotiation_support(const SSL *ssl) {
return ssl->s3->send_connection_binding;
}
-long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) {
- return s->method->ssl_ctrl(s, cmd, larg, parg);
-}
-
LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx) { return ctx->sessions; }
size_t SSL_CTX_sess_number(const SSL_CTX *ctx) {
@@ -1118,28 +1245,27 @@ int SSL_CTX_get_session_cache_mode(const SSL_CTX *ctx) {
return ctx->session_cache_mode;
}
-long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) {
- return ctx->method->ssl_ctx_ctrl(ctx, cmd, larg, parg);
-}
-
-/* return a STACK of the ciphers available for the SSL and in order of
- * preference */
-STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s) {
- if (s == NULL) {
+STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *ssl) {
+ if (ssl == NULL) {
return NULL;
}
- if (s->cipher_list != NULL) {
- return s->cipher_list->ciphers;
+ if (ssl->cipher_list != NULL) {
+ return ssl->cipher_list->ciphers;
+ }
+
+ if (ssl->version >= TLS1_1_VERSION && ssl->ctx != NULL &&
+ ssl->ctx->cipher_list_tls11 != NULL) {
+ return ssl->ctx->cipher_list_tls11->ciphers;
}
- if (s->version >= TLS1_1_VERSION && s->ctx != NULL &&
- s->ctx->cipher_list_tls11 != NULL) {
- return s->ctx->cipher_list_tls11->ciphers;
+ if (ssl->version >= TLS1_VERSION && ssl->ctx != NULL &&
+ ssl->ctx->cipher_list_tls10 != NULL) {
+ return ssl->ctx->cipher_list_tls10->ciphers;
}
- if (s->ctx != NULL && s->ctx->cipher_list != NULL) {
- return s->ctx->cipher_list->ciphers;
+ if (ssl->ctx != NULL && ssl->ctx->cipher_list != NULL) {
+ return ssl->ctx->cipher_list->ciphers;
}
return NULL;
@@ -1147,32 +1273,31 @@ STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s) {
/* 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;
}
-/* The old interface to get the same thing as SSL_get_ciphers() */
-const char *SSL_get_cipher_list(const SSL *s, int n) {
+const char *SSL_get_cipher_list(const SSL *ssl, int n) {
const SSL_CIPHER *c;
STACK_OF(SSL_CIPHER) *sk;
- if (s == NULL) {
+ if (ssl == NULL) {
return NULL;
}
- sk = SSL_get_ciphers(s);
+ sk = SSL_get_ciphers(ssl);
if (sk == NULL || n < 0 || (size_t)n >= sk_SSL_CIPHER_num(sk)) {
return NULL;
}
@@ -1185,119 +1310,87 @@ const char *SSL_get_cipher_list(const SSL *s, int n) {
return c->name;
}
-/* specify the ciphers to be used by default by the SSL_CTX */
int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) {
- STACK_OF(SSL_CIPHER) *sk;
-
- sk = ssl_create_cipher_list(ctx->method, &ctx->cipher_list,
- &ctx->cipher_list_by_id, str);
- /* ssl_create_cipher_list may return an empty stack if it was unable to find
- * a cipher matching the given rule string (for example if the rule string
- * specifies a cipher which has been disabled). This is not an error as far
- * as ssl_create_cipher_list is concerned, and hence ctx->cipher_list and
- * ctx->cipher_list_by_id has been updated. */
- if (sk == NULL) {
+ STACK_OF(SSL_CIPHER) *cipher_list = ssl_create_cipher_list(
+ ctx->method, &ctx->cipher_list, &ctx->cipher_list_by_id, str);
+ if (cipher_list == NULL) {
return 0;
- } else if (sk_SSL_CIPHER_num(sk) == 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_set_cipher_list, SSL_R_NO_CIPHER_MATCH);
+ }
+
+ /* |ssl_create_cipher_list| may succeed but return an empty cipher list. */
+ if (sk_SSL_CIPHER_num(cipher_list) == 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
return 0;
}
return 1;
}
-int SSL_CTX_set_cipher_list_tls11(SSL_CTX *ctx, const char *str) {
- STACK_OF(SSL_CIPHER) *sk;
-
- sk = ssl_create_cipher_list(ctx->method, &ctx->cipher_list_tls11, NULL, str);
- if (sk == NULL) {
+int SSL_CTX_set_cipher_list_tls10(SSL_CTX *ctx, const char *str) {
+ STACK_OF(SSL_CIPHER) *cipher_list = ssl_create_cipher_list(
+ ctx->method, &ctx->cipher_list_tls10, NULL, str);
+ if (cipher_list == NULL) {
return 0;
- } else if (sk_SSL_CIPHER_num(sk) == 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_set_cipher_list_tls11,
- SSL_R_NO_CIPHER_MATCH);
+ }
+
+ /* |ssl_create_cipher_list| may succeed but return an empty cipher list. */
+ if (sk_SSL_CIPHER_num(cipher_list) == 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
return 0;
}
return 1;
}
-/* specify the ciphers to be used by the SSL */
-int SSL_set_cipher_list(SSL *s, const char *str) {
- STACK_OF(SSL_CIPHER) *sk;
-
- sk = ssl_create_cipher_list(s->ctx->method, &s->cipher_list,
- &s->cipher_list_by_id, str);
-
- /* see comment in SSL_CTX_set_cipher_list */
- if (sk == NULL) {
+int SSL_CTX_set_cipher_list_tls11(SSL_CTX *ctx, const char *str) {
+ STACK_OF(SSL_CIPHER) *cipher_list = ssl_create_cipher_list(
+ ctx->method, &ctx->cipher_list_tls11, NULL, str);
+ if (cipher_list == NULL) {
return 0;
- } else if (sk_SSL_CIPHER_num(sk) == 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_set_cipher_list, SSL_R_NO_CIPHER_MATCH);
+ }
+
+ /* |ssl_create_cipher_list| may succeed but return an empty cipher list. */
+ if (sk_SSL_CIPHER_num(cipher_list) == 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
return 0;
}
return 1;
}
-int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, uint8_t *p) {
- size_t i;
- const SSL_CIPHER *c;
- CERT *ct = s->cert;
- uint8_t *q;
- /* Set disabled masks for this session */
- ssl_set_client_disabled(s);
-
- if (sk == NULL) {
+int SSL_set_cipher_list(SSL *ssl, const char *str) {
+ STACK_OF(SSL_CIPHER) *cipher_list = ssl_create_cipher_list(
+ ssl->ctx->method, &ssl->cipher_list, &ssl->cipher_list_by_id, str);
+ if (cipher_list == NULL) {
return 0;
}
- q = p;
- for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
- c = sk_SSL_CIPHER_value(sk, i);
- /* Skip disabled ciphers */
- if (c->algorithm_ssl & ct->mask_ssl ||
- c->algorithm_mkey & ct->mask_k ||
- c->algorithm_auth & ct->mask_a) {
- continue;
- }
- s2n(ssl_cipher_get_value(c), p);
- }
-
- /* If all ciphers were disabled, return the error to the caller. */
- if (p == q) {
+ /* |ssl_create_cipher_list| may succeed but return an empty cipher list. */
+ if (sk_SSL_CIPHER_num(cipher_list) == 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
return 0;
}
- /* Add SCSVs. */
- if (!s->s3->initial_handshake_complete) {
- s2n(SSL3_CK_SCSV & 0xffff, p);
- }
-
- if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV) {
- s2n(SSL3_CK_FALLBACK_SCSV & 0xffff, p);
- }
-
- return p - q;
+ 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) {
- OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list,
- SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
return NULL;
}
sk = sk_SSL_CIPHER_new_null();
if (sk == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -1305,31 +1398,29 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs) {
uint16_t cipher_suite;
if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
- OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
goto err;
}
/* 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) {
- OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list,
- SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+ if (ssl->s3->initial_handshake_complete) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
+ 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) {
- OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list,
- SSL_R_INAPPROPRIATE_FALLBACK);
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL3_AD_INAPPROPRIATE_FALLBACK);
+ 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(ssl, SSL3_AL_FATAL, SSL3_AD_INAPPROPRIATE_FALLBACK);
goto err;
}
continue;
@@ -1337,7 +1428,7 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs) {
c = SSL_get_cipher_by_value(cipher_suite);
if (c != NULL && !sk_SSL_CIPHER_push(sk, c)) {
- OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -1349,21 +1440,25 @@ err:
return NULL;
}
-
-/* return a servername extension value if provided in Client Hello, or NULL. So
- * far, only host_name types are defined (RFC 3546). */
-const char *SSL_get_servername(const SSL *s, const int type) {
+const char *SSL_get_servername(const SSL *ssl, const int type) {
if (type != TLSEXT_NAMETYPE_host_name) {
return NULL;
}
- return s->session && !s->tlsext_hostname ? s->session->tlsext_hostname
- : s->tlsext_hostname;
+ /* Historically, |SSL_get_servername| was also the configuration getter
+ * corresponding to |SSL_set_tlsext_host_name|. */
+ if (ssl->tlsext_hostname != NULL) {
+ return ssl->tlsext_hostname;
+ }
+
+ if (ssl->session == NULL) {
+ return NULL;
+ }
+ return ssl->session->tlsext_hostname;
}
-int SSL_get_servername_type(const SSL *s) {
- if (s->session &&
- (!s->tlsext_hostname ? s->session->tlsext_hostname : s->tlsext_hostname)) {
+int SSL_get_servername_type(const SSL *ssl) {
+ if (ssl->session != NULL && ssl->session->tlsext_hostname != NULL) {
return TLSEXT_NAMETYPE_host_name;
}
@@ -1415,39 +1510,37 @@ void SSL_get0_ocsp_response(const SSL *ssl, const uint8_t **out,
*out_len = session->ocsp_response_length;
}
-/* SSL_select_next_proto implements the standard protocol selection. It is
- * expected that this function is called from the callback set by
- * SSL_CTX_set_next_proto_select_cb.
- *
- * The protocol data is assumed to be a vector of 8-bit, length prefixed byte
- * strings. The length byte itself is not included in the length. A byte
- * string of length 0 is invalid. No byte string may be truncated.
- *
- * The current, but experimental algorithm for selecting the protocol is:
- *
- * 1) If the server doesn't support NPN then this is indicated to the
- * callback. In this case, the client application has to abort the connection
- * or have a default application level protocol.
- *
- * 2) If the server supports NPN, but advertises an empty list then the
- * client selects the first protcol in its list, but indicates via the
- * API that this fallback case was enacted.
- *
- * 3) Otherwise, the client finds the first protocol in the server's list
- * that it supports and selects this protocol. This is because it's
- * assumed that the server has better information about which protocol
- * a client should use.
- *
- * 4) If the client doesn't support any of the server's advertised
- * protocols, then this is treated the same as case 2.
- *
- * It returns either
- * OPENSSL_NPN_NEGOTIATED if a common protocol was found, or
- * OPENSSL_NPN_NO_OVERLAP if the fallback case was reached.
- */
-int SSL_select_next_proto(uint8_t **out, uint8_t *outlen, const uint8_t *server,
- unsigned int server_len, const uint8_t *client,
- unsigned int client_len) {
+int SSL_CTX_set_signed_cert_timestamp_list(SSL_CTX *ctx, const uint8_t *list,
+ size_t list_len) {
+ OPENSSL_free(ctx->signed_cert_timestamp_list);
+ ctx->signed_cert_timestamp_list_length = 0;
+
+ ctx->signed_cert_timestamp_list = BUF_memdup(list, list_len);
+ if (ctx->signed_cert_timestamp_list == NULL) {
+ return 0;
+ }
+ ctx->signed_cert_timestamp_list_length = list_len;
+
+ return 1;
+}
+
+int SSL_CTX_set_ocsp_response(SSL_CTX *ctx, const uint8_t *response,
+ size_t response_len) {
+ OPENSSL_free(ctx->ocsp_response);
+ ctx->ocsp_response_length = 0;
+
+ ctx->ocsp_response = BUF_memdup(response, response_len);
+ if (ctx->ocsp_response == NULL) {
+ return 0;
+ }
+ ctx->ocsp_response_length = response_len;
+
+ return 1;
+}
+
+int SSL_select_next_proto(uint8_t **out, uint8_t *out_len,
+ const uint8_t *server, unsigned server_len,
+ const uint8_t *client, unsigned client_len) {
unsigned int i, j;
const uint8_t *result;
int status = OPENSSL_NPN_UNSUPPORTED;
@@ -1475,57 +1568,31 @@ int SSL_select_next_proto(uint8_t **out, uint8_t *outlen, const uint8_t *server,
found:
*out = (uint8_t *)result + 1;
- *outlen = result[0];
+ *out_len = result[0];
return status;
}
-/* SSL_get0_next_proto_negotiated sets *data and *len to point to the client's
- * requested protocol for this connection and returns 0. If the client didn't
- * request any protocol, then *data is set to NULL.
- *
- * Note that the client can request any protocol it chooses. The value returned
- * from this function need not be a member of the list of supported protocols
- * provided by the callback. */
-void SSL_get0_next_proto_negotiated(const SSL *s, const uint8_t **data,
- unsigned *len) {
- *data = s->next_proto_negotiated;
- if (!*data) {
- *len = 0;
+void SSL_get0_next_proto_negotiated(const SSL *ssl, const uint8_t **out_data,
+ unsigned *out_len) {
+ *out_data = ssl->next_proto_negotiated;
+ if (*out_data == NULL) {
+ *out_len = 0;
} else {
- *len = s->next_proto_negotiated_len;
+ *out_len = ssl->next_proto_negotiated_len;
}
}
-/* SSL_CTX_set_next_protos_advertised_cb sets a callback that is called when a
- * TLS server needs a list of supported protocols for Next Protocol
- * Negotiation. The returned list must be in wire format. The list is returned
- * by setting |out| to point to it and |outlen| to its length. This memory will
- * not be modified, but one should assume that the SSL* keeps a reference to
- * it.
- *
- * The callback should return SSL_TLSEXT_ERR_OK if it wishes to advertise.
- * Otherwise, no such extension will be included in the ServerHello. */
void SSL_CTX_set_next_protos_advertised_cb(
SSL_CTX *ctx,
- int (*cb)(SSL *ssl, const uint8_t **out, unsigned int *outlen, void *arg),
+ int (*cb)(SSL *ssl, const uint8_t **out, unsigned *out_len, void *arg),
void *arg) {
ctx->next_protos_advertised_cb = cb;
ctx->next_protos_advertised_cb_arg = arg;
}
-/* SSL_CTX_set_next_proto_select_cb sets a callback that is called when a
- * client needs to select a protocol from the server's provided list. |out|
- * must be set to point to the selected protocol (which may be within |in|).
- * The length of the protocol name must be written into |outlen|. The server's
- * advertised protocols are provided in |in| and |inlen|. The callback can
- * assume that |in| is syntactically valid.
- *
- * The client must select a protocol. It is fatal to the connection if this
- * callback returns a value other than SSL_TLSEXT_ERR_OK.
- */
void SSL_CTX_set_next_proto_select_cb(
- SSL_CTX *ctx, int (*cb)(SSL *s, uint8_t **out, uint8_t *outlen,
- const uint8_t *in, unsigned int inlen, void *arg),
+ SSL_CTX *ctx, int (*cb)(SSL *ssl, uint8_t **out, uint8_t *out_len,
+ const uint8_t *in, unsigned in_len, void *arg),
void *arg) {
ctx->next_proto_select_cb = cb;
ctx->next_proto_select_cb_arg = arg;
@@ -1554,251 +1621,43 @@ int SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos, unsigned protos_len) {
return 0;
}
-/* SSL_CTX_set_alpn_select_cb sets a callback function on |ctx| that is called
- * during ClientHello processing in order to select an ALPN protocol from the
- * client's list of offered protocols. */
void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx,
int (*cb)(SSL *ssl, const uint8_t **out,
- uint8_t *outlen, const uint8_t *in,
- unsigned int inlen, void *arg),
+ uint8_t *out_len, const uint8_t *in,
+ unsigned in_len, void *arg),
void *arg) {
ctx->alpn_select_cb = cb;
ctx->alpn_select_cb_arg = arg;
}
-/* SSL_get0_alpn_selected gets the selected ALPN protocol (if any) from |ssl|.
- * On return it sets |*data| to point to |*len| bytes of protocol name (not
- * including the leading length-prefix byte). If the server didn't respond with
- * a negotiated protocol then |*len| will be zero. */
-void SSL_get0_alpn_selected(const SSL *ssl, const uint8_t **data,
- unsigned *len) {
- *data = NULL;
+void SSL_get0_alpn_selected(const SSL *ssl, const uint8_t **out_data,
+ unsigned *out_len) {
+ *out_data = NULL;
if (ssl->s3) {
- *data = ssl->s3->alpn_selected;
+ *out_data = ssl->s3->alpn_selected;
}
- if (*data == NULL) {
- *len = 0;
+ if (*out_data == NULL) {
+ *out_len = 0;
} else {
- *len = ssl->s3->alpn_selected_len;
+ *out_len = ssl->s3->alpn_selected_len;
}
}
-int SSL_export_keying_material(SSL *s, uint8_t *out, size_t out_len,
+int SSL_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->version < TLS1_VERSION) {
+ if (ssl->version < TLS1_VERSION) {
return 0;
}
- return s->enc_method->export_keying_material(
- s, out, out_len, label, label_len, context, context_len, use_context);
-}
-
-static uint32_t ssl_session_hash(const SSL_SESSION *a) {
- uint32_t hash =
- ((uint32_t)a->session_id[0]) ||
- ((uint32_t)a->session_id[1] << 8) ||
- ((uint32_t)a->session_id[2] << 16) ||
- ((uint32_t)a->session_id[3] << 24);
-
- return hash;
-}
-
-/* NB: If this function (or indeed the hash function which uses a sort of
- * coarser function than this one) is changed, ensure
- * SSL_CTX_has_matching_session_id() is checked accordingly. It relies on being
- * able to construct an SSL_SESSION that will collide with any existing session
- * with a matching session ID. */
-static int ssl_session_cmp(const SSL_SESSION *a, const SSL_SESSION *b) {
- if (a->ssl_version != b->ssl_version) {
- return 1;
- }
-
- if (a->session_id_length != b->session_id_length) {
- return 1;
- }
-
- return memcmp(a->session_id, b->session_id, a->session_id_length);
-}
-
-SSL_CTX *SSL_CTX_new(const SSL_METHOD *method) {
- SSL_CTX *ret = NULL;
-
- if (method == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_new, SSL_R_NULL_SSL_METHOD_PASSED);
- return NULL;
- }
-
- if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_new, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS);
- goto err;
- }
-
- ret = (SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX));
- if (ret == NULL) {
- goto err;
- }
-
- memset(ret, 0, sizeof(SSL_CTX));
-
- ret->method = method->method;
-
- CRYPTO_MUTEX_init(&ret->lock);
-
- ret->cert_store = NULL;
- ret->session_cache_mode = SSL_SESS_CACHE_SERVER;
- ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT;
- ret->session_cache_head = NULL;
- ret->session_cache_tail = NULL;
-
- /* We take the system default */
- ret->session_timeout = SSL_DEFAULT_SESSION_TIMEOUT;
-
- ret->new_session_cb = 0;
- ret->remove_session_cb = 0;
- ret->get_session_cb = 0;
- ret->generate_session_id = 0;
-
- ret->references = 1;
- ret->quiet_shutdown = 0;
-
- ret->info_callback = NULL;
-
- ret->app_verify_callback = 0;
- ret->app_verify_arg = NULL;
-
- ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT;
- ret->msg_callback = 0;
- ret->msg_callback_arg = NULL;
- ret->verify_mode = SSL_VERIFY_NONE;
- ret->sid_ctx_length = 0;
- ret->default_verify_callback = NULL;
- ret->cert = ssl_cert_new();
- if (ret->cert == NULL) {
- goto err;
- }
-
- ret->default_passwd_callback = 0;
- ret->default_passwd_callback_userdata = NULL;
- ret->client_cert_cb = 0;
-
- ret->sessions = lh_SSL_SESSION_new(ssl_session_hash, ssl_session_cmp);
- if (ret->sessions == NULL) {
- goto err;
- }
- ret->cert_store = X509_STORE_new();
- if (ret->cert_store == NULL) {
- goto err;
- }
-
- ssl_create_cipher_list(ret->method, &ret->cipher_list,
- &ret->cipher_list_by_id, SSL_DEFAULT_CIPHER_LIST);
- if (ret->cipher_list == NULL ||
- sk_SSL_CIPHER_num(ret->cipher_list->ciphers) <= 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_new, SSL_R_LIBRARY_HAS_NO_CIPHERS);
- goto err2;
- }
-
- ret->param = X509_VERIFY_PARAM_new();
- if (!ret->param) {
- goto err;
- }
-
- ret->client_CA = sk_X509_NAME_new_null();
- if (ret->client_CA == NULL) {
- goto err;
- }
-
- CRYPTO_new_ex_data(&g_ex_data_class_ssl_ctx, ret, &ret->ex_data);
-
- ret->extra_certs = NULL;
-
- ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
-
- ret->tlsext_servername_callback = 0;
- ret->tlsext_servername_arg = NULL;
- /* Setup RFC4507 ticket keys */
- if (!RAND_bytes(ret->tlsext_tick_key_name, 16) ||
- !RAND_bytes(ret->tlsext_tick_hmac_key, 16) ||
- !RAND_bytes(ret->tlsext_tick_aes_key, 16)) {
- ret->options |= SSL_OP_NO_TICKET;
- }
-
- ret->next_protos_advertised_cb = 0;
- ret->next_proto_select_cb = 0;
- ret->psk_identity_hint = NULL;
- ret->psk_client_callback = NULL;
- ret->psk_server_callback = NULL;
-
- /* 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) {
- SSL_CTX_set_max_version(ret, method->version);
- SSL_CTX_set_min_version(ret, method->version);
- }
-
- return ret;
-
-err:
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_new, ERR_R_MALLOC_FAILURE);
-err2:
- SSL_CTX_free(ret);
- return NULL;
-}
-
-void SSL_CTX_free(SSL_CTX *ctx) {
- if (ctx == NULL ||
- !CRYPTO_refcount_dec_and_test_zero(&ctx->references)) {
- return;
- }
-
- X509_VERIFY_PARAM_free(ctx->param);
-
- /* Free internal session cache. However: the remove_cb() may reference the
- * ex_data of SSL_CTX, thus the ex_data store can only be removed after the
- * sessions were flushed. As the ex_data handling routines might also touch
- * the session cache, the most secure solution seems to be: empty (flush) the
- * cache, then free ex_data, then finally free the cache. (See ticket
- * [openssl.org #212].) */
- SSL_CTX_flush_sessions(ctx, 0);
-
- CRYPTO_free_ex_data(&g_ex_data_class_ssl_ctx, ctx, &ctx->ex_data);
-
- CRYPTO_MUTEX_cleanup(&ctx->lock);
- lh_SSL_SESSION_free(ctx->sessions);
- X509_STORE_free(ctx->cert_store);
- ssl_cipher_preference_list_free(ctx->cipher_list);
- sk_SSL_CIPHER_free(ctx->cipher_list_by_id);
- ssl_cipher_preference_list_free(ctx->cipher_list_tls11);
- ssl_cert_free(ctx->cert);
- sk_X509_NAME_pop_free(ctx->client_CA, X509_NAME_free);
- sk_X509_pop_free(ctx->extra_certs, X509_free);
- sk_SRTP_PROTECTION_PROFILE_free(ctx->srtp_profiles);
- OPENSSL_free(ctx->psk_identity_hint);
- OPENSSL_free(ctx->tlsext_ecpointformatlist);
- OPENSSL_free(ctx->tlsext_ellipticcurvelist);
- OPENSSL_free(ctx->alpn_client_proto_list);
- EVP_PKEY_free(ctx->tlsext_channel_id_private);
- BIO_free(ctx->keylog_bio);
-
- OPENSSL_free(ctx);
-}
-
-void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb) {
- ctx->default_passwd_callback = cb;
-}
-
-void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u) {
- ctx->default_passwd_callback_userdata = u;
+ return ssl->enc_method->export_keying_material(
+ ssl, out, out_len, label, label_len, context, context_len, use_context);
}
void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx,
- int (*cb)(X509_STORE_CTX *, void *),
+ int (*cb)(X509_STORE_CTX *store_ctx,
+ void *arg),
void *arg) {
ctx->app_verify_callback = cb;
ctx->app_verify_arg = arg;
@@ -1814,63 +1673,54 @@ void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) {
X509_VERIFY_PARAM_set_depth(ctx->param, depth);
}
-void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb)(SSL *ssl, void *arg),
+void SSL_CTX_set_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, void *arg),
void *arg) {
- ssl_cert_set_cert_cb(c->cert, cb, arg);
+ ssl_cert_set_cert_cb(ctx->cert, cb, arg);
}
-void SSL_set_cert_cb(SSL *s, int (*cb)(SSL *ssl, void *arg), void *arg) {
- ssl_cert_set_cert_cb(s->cert, cb, arg);
+void SSL_set_cert_cb(SSL *ssl, int (*cb)(SSL *ssl, void *arg), void *arg) {
+ ssl_cert_set_cert_cb(ssl->cert, cb, arg);
}
-static int ssl_has_key(SSL *s, size_t idx) {
- CERT_PKEY *cpk = &s->cert->pkeys[idx];
- return cpk->x509 && cpk->privatekey;
-}
-
-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;
- int rsa_enc, rsa_sign, dh_tmp;
+ CERT *c = ssl->cert;
+ int have_rsa_cert = 0, dh_tmp;
uint32_t mask_k, mask_a;
- int have_ecc_cert, ecdsa_ok;
+ int have_ecc_cert = 0, ecdsa_ok;
X509 *x;
- if (c == NULL) {
- /* TODO(davidben): Is this codepath possible? */
- *out_mask_k = 0;
- *out_mask_a = 0;
- return;
- }
-
dh_tmp = (c->dh_tmp != NULL || c->dh_tmp_cb != NULL);
- rsa_enc = ssl_has_key(s, SSL_PKEY_RSA_ENC);
- rsa_sign = ssl_has_key(s, SSL_PKEY_RSA_SIGN);
- have_ecc_cert = ssl_has_key(s, SSL_PKEY_ECC);
+ 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(ssl) == EVP_PKEY_EC) {
+ have_ecc_cert = 1;
+ }
+ }
+
mask_k = 0;
mask_a = 0;
- if (rsa_enc) {
- mask_k |= SSL_kRSA;
- }
if (dh_tmp) {
mask_k |= SSL_kDHE;
}
- if (rsa_enc || rsa_sign) {
+ if (have_rsa_cert) {
+ mask_k |= SSL_kRSA;
mask_a |= SSL_aRSA;
}
/* An ECC certificate may be usable for ECDSA cipher suites depending on the
* key usage extension and on the client's curve preferences. */
if (have_ecc_cert) {
- x = c->pkeys[SSL_PKEY_ECC].x509;
+ x = c->x509;
/* This call populates extension flags (ex_flags). */
X509_check_purpose(x, -1, 0);
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) {
@@ -1879,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;
}
@@ -1894,102 +1745,34 @@ void ssl_get_compatible_server_ciphers(SSL *s, uint32_t *out_mask_k,
*out_mask_a = mask_a;
}
-/* This handy macro borrowed from crypto/x509v3/v3_purp.c */
-#define ku_reject(x, usage) \
- (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
-
-int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) {
- const SSL_CIPHER *cs = s->s3->tmp.new_cipher;
- uint32_t alg_a = cs->algorithm_auth;
- int signature_nid = 0, md_nid = 0, pk_nid = 0;
-
- /* This call populates the ex_flags field correctly */
- X509_check_purpose(x, -1, 0);
- if (x->sig_alg && x->sig_alg->algorithm) {
- signature_nid = OBJ_obj2nid(x->sig_alg->algorithm);
- OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid);
- }
- if (alg_a & SSL_aECDSA) {
- /* key usage, if present, must allow signing */
- if (ku_reject(x, X509v3_KU_DIGITAL_SIGNATURE)) {
- OPENSSL_PUT_ERROR(SSL, ssl_check_srvr_ecc_cert_and_alg,
- SSL_R_ECC_CERT_NOT_FOR_SIGNING);
- return 0;
- }
- }
-
- return 1; /* all checks are ok */
-}
-
-static int ssl_get_server_cert_index(const SSL *s) {
- int idx;
- idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher);
- if (idx == SSL_PKEY_RSA_ENC && !s->cert->pkeys[SSL_PKEY_RSA_ENC].x509) {
- idx = SSL_PKEY_RSA_SIGN;
- }
- if (idx == -1) {
- OPENSSL_PUT_ERROR(SSL, ssl_get_server_cert_index, ERR_R_INTERNAL_ERROR);
- }
- return idx;
-}
-
-CERT_PKEY *ssl_get_server_send_pkey(const SSL *s) {
- int i = ssl_get_server_cert_index(s);
-
- /* This may or may not be an error. */
- if (i < 0) {
- return NULL;
- }
-
- /* May be NULL. */
- return &s->cert->pkeys[i];
-}
-
-EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *cipher) {
- uint32_t alg_a = cipher->algorithm_auth;
- CERT *c = s->cert;
- int idx = -1;
-
- if (alg_a & SSL_aRSA) {
- if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL) {
- idx = SSL_PKEY_RSA_SIGN;
- } else if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey != NULL) {
- idx = SSL_PKEY_RSA_ENC;
- }
- } else if ((alg_a & SSL_aECDSA) &&
- (c->pkeys[SSL_PKEY_ECC].privatekey != NULL)) {
- idx = SSL_PKEY_ECC;
- }
-
- if (idx == -1) {
- OPENSSL_PUT_ERROR(SSL, ssl_get_sign_pkey, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
-
- return c->pkeys[idx].privatekey;
-}
-
-void ssl_update_cache(SSL *s, int mode) {
+void ssl_update_cache(SSL *ssl, int mode) {
+ SSL_CTX *ctx = ssl->initial_ctx;
/* Never cache sessions with empty session IDs. */
- if (s->session->session_id_length == 0) {
+ if (ssl->session->session_id_length == 0 ||
+ (ctx->session_cache_mode & mode) != mode) {
return;
}
- SSL_CTX *ctx = s->initial_ctx;
- if ((ctx->session_cache_mode & mode) == mode && !s->hit &&
- ((ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_STORE) ||
- SSL_CTX_add_session(ctx, s->session)) &&
- ctx->new_session_cb != NULL) {
- /* Note: |new_session_cb| is called whether the internal session cache is
- * used or not. */
- if (!ctx->new_session_cb(s, SSL_SESSION_up_ref(s->session))) {
- SSL_SESSION_free(s->session);
+ /* Clients never use the internal session cache. */
+ int use_internal_cache = ssl->server && !(ctx->session_cache_mode &
+ SSL_SESS_CACHE_NO_INTERNAL_STORE);
+
+ /* A client may see new sessions on abbreviated handshakes if the server
+ * decides to renew the ticket. Once the handshake is completed, it should be
+ * inserted into the cache. */
+ if (!ssl->hit || (!ssl->server && ssl->tlsext_ticket_expected)) {
+ if (use_internal_cache) {
+ SSL_CTX_add_session(ctx, ssl->session);
+ }
+ if (ctx->new_session_cb != NULL &&
+ !ctx->new_session_cb(ssl, SSL_SESSION_up_ref(ssl->session))) {
+ /* |new_session_cb|'s return value signals whether it took ownership. */
+ SSL_SESSION_free(ssl->session);
}
}
- if (!(ctx->session_cache_mode & SSL_SESS_CACHE_NO_AUTO_CLEAR) &&
- !(ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_STORE) &&
- (ctx->session_cache_mode & mode) == mode) {
+ if (use_internal_cache &&
+ !(ctx->session_cache_mode & SSL_SESS_CACHE_NO_AUTO_CLEAR)) {
/* Automatically flush the internal session cache every 255 connections. */
int flush_cache = 0;
CRYPTO_MUTEX_lock_write(&ctx->lock);
@@ -2006,143 +1789,6 @@ void ssl_update_cache(SSL *s, int mode) {
}
}
-int SSL_get_error(const SSL *s, int ret_code) {
- int reason;
- uint32_t err;
- BIO *bio;
-
- if (ret_code > 0) {
- return SSL_ERROR_NONE;
- }
-
- /* Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake etc,
- * where we do encode the error */
- err = ERR_peek_error();
- if (err != 0) {
- if (ERR_GET_LIB(err) == ERR_LIB_SYS) {
- return SSL_ERROR_SYSCALL;
- }
- return SSL_ERROR_SSL;
- }
-
- if (ret_code == 0) {
- if ((s->shutdown & SSL_RECEIVED_SHUTDOWN) &&
- (s->s3->warn_alert == SSL_AD_CLOSE_NOTIFY)) {
- /* The socket was cleanly shut down with a close_notify. */
- return SSL_ERROR_ZERO_RETURN;
- }
- /* An EOF was observed which violates the protocol, and the underlying
- * transport does not participate in the error queue. Bubble up to the
- * caller. */
- return SSL_ERROR_SYSCALL;
- }
-
- if (SSL_want_session(s)) {
- return SSL_ERROR_PENDING_SESSION;
- }
-
- if (SSL_want_certificate(s)) {
- return SSL_ERROR_PENDING_CERTIFICATE;
- }
-
- if (SSL_want_read(s)) {
- bio = SSL_get_rbio(s);
- if (BIO_should_read(bio)) {
- return SSL_ERROR_WANT_READ;
- }
-
- if (BIO_should_write(bio)) {
- /* 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
- * around that bug; so it might be safer to keep it. */
- return SSL_ERROR_WANT_WRITE;
- }
-
- if (BIO_should_io_special(bio)) {
- reason = BIO_get_retry_reason(bio);
- if (reason == BIO_RR_CONNECT) {
- return SSL_ERROR_WANT_CONNECT;
- }
-
- if (reason == BIO_RR_ACCEPT) {
- return SSL_ERROR_WANT_ACCEPT;
- }
-
- return SSL_ERROR_SYSCALL; /* unknown */
- }
- }
-
- if (SSL_want_write(s)) {
- bio = SSL_get_wbio(s);
- if (BIO_should_write(bio)) {
- return SSL_ERROR_WANT_WRITE;
- }
-
- if (BIO_should_read(bio)) {
- /* See above (SSL_want_read(s) with BIO_should_write(bio)) */
- return SSL_ERROR_WANT_READ;
- }
-
- if (BIO_should_io_special(bio)) {
- reason = BIO_get_retry_reason(bio);
- if (reason == BIO_RR_CONNECT) {
- return SSL_ERROR_WANT_CONNECT;
- }
-
- if (reason == BIO_RR_ACCEPT) {
- return SSL_ERROR_WANT_ACCEPT;
- }
-
- return SSL_ERROR_SYSCALL;
- }
- }
-
- if (SSL_want_x509_lookup(s)) {
- return SSL_ERROR_WANT_X509_LOOKUP;
- }
-
- if (SSL_want_channel_id_lookup(s)) {
- return SSL_ERROR_WANT_CHANNEL_ID_LOOKUP;
- }
-
- return SSL_ERROR_SYSCALL;
-}
-
-int SSL_do_handshake(SSL *s) {
- int ret = 1;
-
- if (s->handshake_func == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_do_handshake, SSL_R_CONNECTION_TYPE_NOT_SET);
- return -1;
- }
-
- if (SSL_in_init(s)) {
- ret = s->handshake_func(s);
- }
- return ret;
-}
-
-void SSL_set_accept_state(SSL *ssl) {
- ssl->server = 1;
- ssl->shutdown = 0;
- ssl->state = SSL_ST_ACCEPT;
- ssl->handshake_func = ssl->method->ssl_accept;
- /* clear the current cipher */
- ssl_clear_cipher_ctx(ssl);
-}
-
-void SSL_set_connect_state(SSL *ssl) {
- ssl->server = 0;
- ssl->shutdown = 0;
- ssl->state = SSL_ST_CONNECT;
- ssl->handshake_func = ssl->method->ssl_connect;
- /* clear the current cipher */
- ssl_clear_cipher_ctx(ssl);
-}
-
static const char *ssl_get_version(int version) {
switch (version) {
case TLS1_2_VERSION:
@@ -2168,32 +1814,32 @@ static const char *ssl_get_version(int version) {
}
}
-const char *SSL_get_version(const SSL *s) {
- return ssl_get_version(s->version);
+const char *SSL_get_version(const SSL *ssl) {
+ return ssl_get_version(ssl->version);
}
-const char *SSL_SESSION_get_version(const SSL_SESSION *sess) {
- return ssl_get_version(sess->ssl_version);
+const char *SSL_SESSION_get_version(const SSL_SESSION *session) {
+ return ssl_get_version(session->ssl_version);
}
-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;
+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;
}
-X509 *SSL_get_certificate(const SSL *s) {
- if (s->cert != NULL) {
- return s->cert->key->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->key->privatekey;
+EVP_PKEY *SSL_get_privatekey(const SSL *ssl) {
+ if (ssl->cert != NULL) {
+ return ssl->cert->privatekey;
}
return NULL;
@@ -2201,7 +1847,7 @@ EVP_PKEY *SSL_get_privatekey(const SSL *s) {
X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx) {
if (ctx->cert != NULL) {
- return ctx->cert->key->x509;
+ return ctx->cert->x509;
}
return NULL;
@@ -2209,89 +1855,97 @@ X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx) {
EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx) {
if (ctx->cert != NULL) {
- return ctx->cert->key->privatekey;
+ return ctx->cert->privatekey;
}
return NULL;
}
-const SSL_CIPHER *SSL_get_current_cipher(const SSL *s) {
- if (s->aead_write_ctx == NULL) {
+const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl) {
+ if (ssl->aead_write_ctx == NULL) {
return NULL;
}
- return s->aead_write_ctx->cipher;
+ return ssl->aead_write_ctx->cipher;
}
-const void *SSL_get_current_compression(SSL *s) { return NULL; }
+const COMP_METHOD *SSL_get_current_compression(SSL *ssl) { return NULL; }
-const void *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);
}
}
BIO_reset(bbio);
if (!BIO_set_read_buffer_size(bbio, 1)) {
- OPENSSL_PUT_ERROR(SSL, ssl_init_wbio_buffer, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
return 0;
}
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) {
- ctx->quiet_shutdown = mode;
+ ctx->quiet_shutdown = (mode != 0);
}
int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx) {
return ctx->quiet_shutdown;
}
-void SSL_set_quiet_shutdown(SSL *s, int mode) { s->quiet_shutdown = mode; }
+void SSL_set_quiet_shutdown(SSL *ssl, int mode) {
+ ssl->quiet_shutdown = (mode != 0);
+}
-int SSL_get_quiet_shutdown(const SSL *s) { return s->quiet_shutdown; }
+int SSL_get_quiet_shutdown(const SSL *ssl) { return ssl->quiet_shutdown; }
-void SSL_set_shutdown(SSL *s, int mode) { s->shutdown = mode; }
+void SSL_set_shutdown(SSL *ssl, int mode) {
+ /* It is an error to clear any bits that have already been set. (We can't try
+ * to get a second close_notify or send two.) */
+ assert((ssl->shutdown & mode) == ssl->shutdown);
-int SSL_get_shutdown(const SSL *s) { return s->shutdown; }
+ ssl->shutdown |= mode;
+}
-int SSL_version(const SSL *s) { return s->version; }
+int SSL_get_shutdown(const SSL *ssl) { return ssl->shutdown; }
+
+int SSL_version(const SSL *ssl) { return ssl->version; }
SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) { return ssl->ctx; }
@@ -2322,18 +1976,18 @@ int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) {
return X509_STORE_set_default_paths(ctx->cert_store);
}
-int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
- const char *CApath) {
- return X509_STORE_load_locations(ctx->cert_store, CAfile, CApath);
+int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *ca_file,
+ const char *ca_dir) {
+ return X509_STORE_load_locations(ctx->cert_store, ca_file, ca_dir);
}
void SSL_set_info_callback(SSL *ssl,
- void (*cb)(const SSL *ssl, int type, int val)) {
+ void (*cb)(const SSL *ssl, int type, int value)) {
ssl->info_callback = cb;
}
-void (*SSL_get_info_callback(const SSL *ssl))(const SSL * /*ssl*/, int /*type*/,
- int /*val*/) {
+void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl, int type,
+ int value) {
return ssl->info_callback;
}
@@ -2341,45 +1995,47 @@ int SSL_state(const SSL *ssl) { return ssl->state; }
void SSL_set_state(SSL *ssl, int state) { }
-void SSL_set_verify_result(SSL *ssl, long arg) { ssl->verify_result = arg; }
+void SSL_set_verify_result(SSL *ssl, long result) {
+ ssl->verify_result = 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;
}
-int SSL_set_ex_data(SSL *s, int idx, void *arg) {
- return CRYPTO_set_ex_data(&s->ex_data, idx, arg);
+int SSL_set_ex_data(SSL *ssl, int idx, void *arg) {
+ return CRYPTO_set_ex_data(&ssl->ex_data, idx, arg);
}
-void *SSL_get_ex_data(const SSL *s, int idx) {
- return CRYPTO_get_ex_data(&s->ex_data, idx);
+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;
}
-int SSL_CTX_set_ex_data(SSL_CTX *s, int idx, void *arg) {
- return CRYPTO_set_ex_data(&s->ex_data, idx, arg);
+int SSL_CTX_set_ex_data(SSL_CTX *ctx, int idx, void *arg) {
+ return CRYPTO_set_ex_data(&ctx->ex_data, idx, arg);
}
-void *SSL_CTX_get_ex_data(const SSL_CTX *s, int idx) {
- return CRYPTO_get_ex_data(&s->ex_data, idx);
+void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx) {
+ return CRYPTO_get_ex_data(&ctx->ex_data, idx);
}
X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx) {
@@ -2391,7 +2047,7 @@ void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store) {
ctx->cert_store = store;
}
-int SSL_want(const SSL *s) { return s->rwstate; }
+int SSL_want(const SSL *ssl) { return ssl->rwstate; }
void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,
RSA *(*cb)(SSL *ssl, int is_export,
@@ -2413,22 +2069,9 @@ 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_CTX_use_psk_identity_hint,
- SSL_R_DATA_LENGTH_TOO_LONG);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
return 0;
}
@@ -2446,24 +2089,23 @@ int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint) {
return 1;
}
-int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint) {
- if (s == NULL) {
+int SSL_use_psk_identity_hint(SSL *ssl, const char *identity_hint) {
+ if (ssl == NULL) {
return 0;
}
if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_psk_identity_hint,
- SSL_R_DATA_LENGTH_TOO_LONG);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
return 0;
}
/* Clear currently configured hint, if any. */
- OPENSSL_free(s->psk_identity_hint);
- s->psk_identity_hint = NULL;
+ OPENSSL_free(ssl->psk_identity_hint);
+ ssl->psk_identity_hint = NULL;
if (identity_hint != NULL) {
- s->psk_identity_hint = BUF_strdup(identity_hint);
- if (s->psk_identity_hint == NULL) {
+ ssl->psk_identity_hint = BUF_strdup(identity_hint);
+ if (ssl->psk_identity_hint == NULL) {
return 0;
}
}
@@ -2471,63 +2113,47 @@ int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint) {
return 1;
}
-const char *SSL_get_psk_identity_hint(const SSL *s) {
- if (s == NULL) {
+const char *SSL_get_psk_identity_hint(const SSL *ssl) {
+ if (ssl == NULL) {
return NULL;
}
- return s->psk_identity_hint;
+ return ssl->psk_identity_hint;
}
-const char *SSL_get_psk_identity(const SSL *s) {
- if (s == NULL || s->session == NULL) {
+const char *SSL_get_psk_identity(const SSL *ssl) {
+ if (ssl == NULL || ssl->session == NULL) {
return NULL;
}
- return s->session->psk_identity;
+ return ssl->session->psk_identity;
}
void SSL_set_psk_client_callback(
- SSL *s, unsigned int (*cb)(SSL *ssl, const char *hint, char *identity,
- unsigned int max_identity_len, uint8_t *psk,
- unsigned int max_psk_len)) {
- s->psk_client_callback = cb;
+ SSL *ssl, unsigned (*cb)(SSL *ssl, const char *hint, char *identity,
+ unsigned max_identity_len, uint8_t *psk,
+ unsigned max_psk_len)) {
+ ssl->psk_client_callback = cb;
}
void SSL_CTX_set_psk_client_callback(
- SSL_CTX *ctx, unsigned int (*cb)(SSL *ssl, const char *hint, char *identity,
- unsigned int max_identity_len,
- uint8_t *psk, unsigned int max_psk_len)) {
+ SSL_CTX *ctx, unsigned (*cb)(SSL *ssl, const char *hint, char *identity,
+ unsigned max_identity_len, uint8_t *psk,
+ unsigned max_psk_len)) {
ctx->psk_client_callback = cb;
}
void SSL_set_psk_server_callback(
- SSL *s, unsigned int (*cb)(SSL *ssl, const char *identity, uint8_t *psk,
- unsigned int max_psk_len)) {
- s->psk_server_callback = cb;
+ SSL *ssl, unsigned (*cb)(SSL *ssl, const char *identity, uint8_t *psk,
+ unsigned max_psk_len)) {
+ ssl->psk_server_callback = cb;
}
void SSL_CTX_set_psk_server_callback(
- SSL_CTX *ctx, unsigned int (*cb)(SSL *ssl, const char *identity,
- uint8_t *psk, unsigned int max_psk_len)) {
+ SSL_CTX *ctx, unsigned (*cb)(SSL *ssl, const char *identity,
+ uint8_t *psk, unsigned max_psk_len)) {
ctx->psk_server_callback = cb;
}
-void SSL_CTX_set_min_version(SSL_CTX *ctx, uint16_t version) {
- ctx->min_version = version;
-}
-
-void SSL_CTX_set_max_version(SSL_CTX *ctx, uint16_t version) {
- ctx->max_version = version;
-}
-
-void SSL_set_min_version(SSL *ssl, uint16_t version) {
- ssl->min_version = version;
-}
-
-void SSL_set_max_version(SSL *ssl, uint16_t version) {
- ssl->max_version = version;
-}
-
void SSL_CTX_set_msg_callback(SSL_CTX *ctx,
void (*cb)(int write_p, int version,
int content_type, const void *buf,
@@ -2550,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) {
@@ -2572,97 +2198,86 @@ 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;
}
if (encrypted_premaster_len < 8) {
- OPENSSL_PUT_ERROR(SSL, ssl_ctx_log_rsa_client_key_exchange,
- ERR_R_INTERNAL_ERROR);
- return 0;
- }
-
- if (!CBB_init(&cbb, 4 + 16 + 1 + premaster_len * 2 + 1)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return 0;
}
- if (!CBB_add_bytes(&cbb, (const uint8_t *)"RSA ", 4) ||
+ 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
* logged. */
!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;
}
if (client_random_len != 32) {
- OPENSSL_PUT_ERROR(SSL, ssl_ctx_log_master_secret, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return 0;
}
- if (!CBB_init(&cbb, 14 + 64 + 1 + master_len * 2 + 1)) {
- return 0;
- }
-
- if (!CBB_add_bytes(&cbb, (const uint8_t *)"CLIENT_RANDOM ", 14) ||
+ 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_in_false_start(const SSL *s) {
- return s->s3->tmp.in_false_start;
+int SSL_is_init_finished(const SSL *ssl) {
+ return ssl->state == SSL_ST_OK;
}
-int SSL_cutthrough_complete(const SSL *s) {
- return SSL_in_false_start(s);
+int SSL_in_init(const SSL *ssl) {
+ return (ssl->state & SSL_ST_INIT) != 0;
+}
+
+int SSL_in_false_start(const SSL *ssl) {
+ return ssl->s3->tmp.in_false_start;
+}
+
+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,
@@ -2672,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);
+ cipher->algorithm_mac == SSL_AEAD;
}
const SSL3_ENC_METHOD *ssl3_get_enc_method(uint16_t version) {
@@ -2707,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
@@ -2800,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)) {
@@ -2823,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;
@@ -2877,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;
}
@@ -2898,21 +2516,27 @@ uint16_t ssl3_version_from_wire(SSL *s, uint16_t wire_version) {
return version;
}
-int SSL_cache_hit(SSL *s) { return s->hit; }
+int SSL_cache_hit(SSL *ssl) { return SSL_session_reused(ssl); }
-int SSL_is_server(SSL *s) { return s->server; }
+int SSL_is_server(SSL *ssl) { return ssl->server; }
+
+void SSL_CTX_set_select_certificate_cb(
+ SSL_CTX *ctx, int (*cb)(const struct ssl_early_callback_ctx *)) {
+ ctx->select_certificate_cb = cb;
+}
void SSL_CTX_set_dos_protection_cb(
SSL_CTX *ctx, int (*cb)(const struct ssl_early_callback_ctx *)) {
ctx->dos_protection_cb = cb;
}
-void SSL_enable_fastradio_padding(SSL *s, char on_off) {
- s->fastradio_padding = on_off;
+void SSL_set_renegotiate_mode(SSL *ssl, enum ssl_renegotiate_mode_t mode) {
+ ssl->renegotiate_mode = mode;
}
-void SSL_set_reject_peer_renegotiations(SSL *s, int reject) {
- s->accept_peer_renegotiations = !reject;
+void SSL_set_reject_peer_renegotiations(SSL *ssl, int reject) {
+ SSL_set_renegotiate_mode(
+ ssl, reject ? ssl_renegotiate_never : ssl_renegotiate_freely);
}
int SSL_get_rc4_state(const SSL *ssl, const RC4_KEY **read_key,
@@ -2925,39 +2549,94 @@ int SSL_get_rc4_state(const SSL *ssl, const RC4_KEY **read_key,
EVP_AEAD_CTX_get_rc4_state(&ssl->aead_write_ctx->ctx, write_key);
}
-int SSL_get_tls_unique(const SSL *ssl, uint8_t *out, size_t *out_len,
- size_t max_out) {
- /* The tls-unique value is the first Finished message in the handshake, which
- * is the client's in a full handshake and the server's for a resumption. See
- * https://tools.ietf.org/html/rfc5929#section-3.1. */
- const uint8_t *finished = ssl->s3->previous_client_finished;
- size_t finished_len = ssl->s3->previous_client_finished_len;
- if (ssl->hit) {
- /* tls-unique is broken for resumed sessions unless EMS is used. */
- if (!ssl->session->extended_master_secret) {
- goto err;
+int SSL_get_ivs(const SSL *ssl, const uint8_t **out_read_iv,
+ const uint8_t **out_write_iv, size_t *out_iv_len) {
+ if (ssl->aead_read_ctx == NULL || ssl->aead_write_ctx == NULL) {
+ return 0;
+ }
+
+ size_t write_iv_len;
+ if (!EVP_AEAD_CTX_get_iv(&ssl->aead_read_ctx->ctx, out_read_iv, out_iv_len) ||
+ !EVP_AEAD_CTX_get_iv(&ssl->aead_write_ctx->ctx, out_write_iv,
+ &write_iv_len) ||
+ *out_iv_len != write_iv_len) {
+ return 0;
+ }
+
+ return 1;
+}
+
+uint8_t SSL_get_server_key_exchange_hash(const SSL *ssl) {
+ return ssl->s3->tmp.server_key_exchange_hash;
+}
+
+int SSL_clear(SSL *ssl) {
+ if (ssl->method == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_METHOD_SPECIFIED);
+ return 0;
+ }
+
+ if (ssl_clear_bad_session(ssl)) {
+ SSL_SESSION_free(ssl->session);
+ ssl->session = NULL;
+ }
+
+ ssl->hit = 0;
+ ssl->shutdown = 0;
+
+ /* SSL_clear may be called before or after the |ssl| is initialized in either
+ * accept or connect state. In the latter case, SSL_clear should preserve the
+ * half and reset |ssl->state| accordingly. */
+ if (ssl->handshake_func != NULL) {
+ if (ssl->server) {
+ SSL_set_accept_state(ssl);
+ } else {
+ SSL_set_connect_state(ssl);
}
- finished = ssl->s3->previous_server_finished;
- finished_len = ssl->s3->previous_server_finished_len;
+ } else {
+ assert(ssl->state == 0);
}
- if (!ssl->s3->initial_handshake_complete ||
- ssl->version < TLS1_VERSION) {
- goto err;
+ /* TODO(davidben): Some state on |ssl| is reset both in |SSL_new| and
+ * |SSL_clear| because it is per-connection state rather than configuration
+ * state. Per-connection state should be on |ssl->s3| and |ssl->d1| so it is
+ * naturally reset at the right points between |SSL_new|, |SSL_clear|, and
+ * |ssl3_new|. */
+
+ ssl->rwstate = SSL_NOTHING;
+
+ BUF_MEM_free(ssl->init_buf);
+ ssl->init_buf = NULL;
+
+ ssl_clear_cipher_ctx(ssl);
+
+ OPENSSL_free(ssl->next_proto_negotiated);
+ ssl->next_proto_negotiated = NULL;
+ ssl->next_proto_negotiated_len = 0;
+
+ /* The ssl->d1->mtu is simultaneously configuration (preserved across
+ * clear) and connection-specific state (gets reset).
+ *
+ * TODO(davidben): Avoid this. */
+ unsigned mtu = 0;
+ if (ssl->d1 != NULL) {
+ mtu = ssl->d1->mtu;
}
- *out_len = finished_len;
- if (finished_len > max_out) {
- *out_len = max_out;
+ ssl->method->ssl_free(ssl);
+ if (!ssl->method->ssl_new(ssl)) {
+ return 0;
}
+ ssl->enc_method = ssl3_get_enc_method(ssl->version);
+ assert(ssl->enc_method != NULL);
- memcpy(out, finished, *out_len);
- return 1;
+ if (SSL_IS_DTLS(ssl) && (SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) {
+ ssl->d1->mtu = mtu;
+ }
-err:
- *out_len = 0;
- memset(out, 0, max_out);
- return 0;
+ ssl->client_version = ssl->version;
+
+ return 1;
}
int SSL_CTX_sess_connect(const SSL_CTX *ctx) { return 0; }
@@ -2971,3 +2650,5 @@ int SSL_CTX_sess_cb_hits(const SSL_CTX *ctx) { return 0; }
int SSL_CTX_sess_misses(const SSL_CTX *ctx) { return 0; }
int SSL_CTX_sess_timeouts(const SSL_CTX *ctx) { return 0; }
int SSL_CTX_sess_cache_full(const SSL_CTX *ctx) { return 0; }
+void ERR_load_SSL_strings(void) {}
+void SSL_load_error_strings(void) {}
diff --git a/src/ssl/ssl_rsa.c b/src/ssl/ssl_rsa.c
index 87f4c1c..990979b 100644
--- a/src/ssl/ssl_rsa.c
+++ b/src/ssl/ssl_rsa.c
@@ -54,84 +54,49 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
-#include <stdio.h>
+#include <openssl/ssl.h>
+
+#include <limits.h>
-#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
-#include <openssl/pem.h>
#include <openssl/x509.h>
#include "internal.h"
+
static int ssl_set_cert(CERT *c, X509 *x509);
static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
+static int is_key_type_supported(int key_type) {
+ return key_type == EVP_PKEY_RSA || key_type == EVP_PKEY_EC;
+}
+
int SSL_use_certificate(SSL *ssl, X509 *x) {
if (x == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_certificate, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
return ssl_set_cert(ssl->cert, x);
}
-int SSL_use_certificate_file(SSL *ssl, const char *file, int type) {
- int reason_code;
- BIO *in;
- int ret = 0;
- X509 *x = NULL;
-
- in = BIO_new(BIO_s_file());
- if (in == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_file, ERR_R_BUF_LIB);
- goto end;
- }
-
- if (BIO_read_filename(in, file) <= 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_file, ERR_R_SYS_LIB);
- goto end;
- }
-
- if (type == SSL_FILETYPE_ASN1) {
- reason_code = ERR_R_ASN1_LIB;
- x = d2i_X509_bio(in, NULL);
- } else if (type == SSL_FILETYPE_PEM) {
- reason_code = ERR_R_PEM_LIB;
- x = PEM_read_bio_X509(in, NULL, ssl->ctx->default_passwd_callback,
- ssl->ctx->default_passwd_callback_userdata);
- } else {
- OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_file, SSL_R_BAD_SSL_FILETYPE);
- goto end;
- }
-
- if (x == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_file, reason_code);
- goto end;
+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;
}
- ret = SSL_use_certificate(ssl, x);
-
-end:
- X509_free(x);
- BIO_free(in);
-
- return ret;
-}
-
-int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *d, int len) {
- X509 *x;
- int ret;
-
- x = d2i_X509(NULL, &d, (long)len);
- if (x == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_ASN1, ERR_R_ASN1_LIB);
+ 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;
}
@@ -140,13 +105,13 @@ int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) {
int ret;
if (rsa == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
pkey = EVP_PKEY_new();
if (pkey == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey, ERR_R_EVP_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB);
return 0;
}
@@ -160,86 +125,36 @@ int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) {
}
static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) {
- int i;
-
- i = ssl_cert_type(pkey);
- if (i < 0) {
- OPENSSL_PUT_ERROR(SSL, ssl_set_pkey, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
+ if (!is_key_type_supported(pkey->type)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
return 0;
}
- if (c->pkeys[i].x509 != NULL) {
+ if (c->x509 != NULL) {
/* Sanity-check that the private key and the certificate match, unless the
* key is opaque (in case of, say, a smartcard). */
if (!EVP_PKEY_is_opaque(pkey) &&
- !X509_check_private_key(c->pkeys[i].x509, pkey)) {
- X509_free(c->pkeys[i].x509);
- c->pkeys[i].x509 = NULL;
+ !X509_check_private_key(c->x509, pkey)) {
+ X509_free(c->x509);
+ c->x509 = NULL;
return 0;
}
}
- EVP_PKEY_free(c->pkeys[i].privatekey);
- c->pkeys[i].privatekey = EVP_PKEY_up_ref(pkey);
- c->key = &(c->pkeys[i]);
+ EVP_PKEY_free(c->privatekey);
+ c->privatekey = EVP_PKEY_up_ref(pkey);
return 1;
}
-int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) {
- int reason_code, ret = 0;
- BIO *in;
- RSA *rsa = NULL;
-
- in = BIO_new(BIO_s_file());
- if (in == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_file, ERR_R_BUF_LIB);
- goto end;
- }
-
- if (BIO_read_filename(in, file) <= 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_file, ERR_R_SYS_LIB);
- goto end;
- }
-
- if (type == SSL_FILETYPE_ASN1) {
- reason_code = ERR_R_ASN1_LIB;
- rsa = d2i_RSAPrivateKey_bio(in, NULL);
- } else if (type == SSL_FILETYPE_PEM) {
- reason_code = ERR_R_PEM_LIB;
- rsa =
- PEM_read_bio_RSAPrivateKey(in, NULL, ssl->ctx->default_passwd_callback,
- ssl->ctx->default_passwd_callback_userdata);
- } else {
- OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_file, SSL_R_BAD_SSL_FILETYPE);
- goto end;
- }
-
- if (rsa == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_file, reason_code);
- goto end;
- }
- ret = SSL_use_RSAPrivateKey(ssl, rsa);
- RSA_free(rsa);
-
-end:
- BIO_free(in);
- return ret;
-}
-
-int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, uint8_t *d, long len) {
- int ret;
- const uint8_t *p;
- RSA *rsa;
-
- p = d;
- rsa = d2i_RSAPrivateKey(NULL, &p, (long)len);
+int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) {
+ RSA *rsa = RSA_private_key_from_bytes(der, der_len);
if (rsa == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_ASN1, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
return 0;
}
- ret = SSL_use_RSAPrivateKey(ssl, rsa);
+ int ret = SSL_use_RSAPrivateKey(ssl, rsa);
RSA_free(rsa);
return ret;
}
@@ -248,7 +163,7 @@ int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) {
int ret;
if (pkey == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
@@ -256,67 +171,29 @@ int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) {
return ret;
}
-int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) {
- int reason_code, ret = 0;
- BIO *in;
- EVP_PKEY *pkey = NULL;
-
- in = BIO_new(BIO_s_file());
- if (in == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_file, ERR_R_BUF_LIB);
- goto end;
- }
-
- if (BIO_read_filename(in, file) <= 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_file, ERR_R_SYS_LIB);
- goto end;
- }
-
- if (type == SSL_FILETYPE_PEM) {
- reason_code = ERR_R_PEM_LIB;
- pkey = PEM_read_bio_PrivateKey(in, NULL, ssl->ctx->default_passwd_callback,
- ssl->ctx->default_passwd_callback_userdata);
- } else if (type == SSL_FILETYPE_ASN1) {
- reason_code = ERR_R_ASN1_LIB;
- pkey = d2i_PrivateKey_bio(in, NULL);
- } else {
- OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_file, SSL_R_BAD_SSL_FILETYPE);
- goto end;
- }
-
- if (pkey == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_file, reason_code);
- goto end;
+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;
}
- ret = SSL_use_PrivateKey(ssl, pkey);
- EVP_PKEY_free(pkey);
-
-end:
- BIO_free(in);
- 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;
-
- p = d;
- pkey = d2i_PrivateKey(type, NULL, &p, (long)len);
- if (pkey == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_ASN1, ERR_R_ASN1_LIB);
+ 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;
}
int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) {
if (x == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate,
- ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
@@ -324,32 +201,28 @@ int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) {
}
static int ssl_set_cert(CERT *c, X509 *x) {
- EVP_PKEY *pkey;
- int i;
-
- pkey = X509_get_pubkey(x);
+ EVP_PKEY *pkey = X509_get_pubkey(x);
if (pkey == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_set_cert, SSL_R_X509_LIB);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_X509_LIB);
return 0;
}
- i = ssl_cert_type(pkey);
- if (i < 0) {
- OPENSSL_PUT_ERROR(SSL, ssl_set_cert, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
+ if (!is_key_type_supported(pkey->type)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
EVP_PKEY_free(pkey);
return 0;
}
- if (c->pkeys[i].privatekey != NULL) {
+ if (c->privatekey != NULL) {
/* Sanity-check that the private key and the certificate match, unless the
* key is opaque (in case of, say, a smartcard). */
- if (!EVP_PKEY_is_opaque(c->pkeys[i].privatekey) &&
- !X509_check_private_key(x, c->pkeys[i].privatekey)) {
+ if (!EVP_PKEY_is_opaque(c->privatekey) &&
+ !X509_check_private_key(x, c->privatekey)) {
/* don't fail for a cert/key mismatch, just free current private key
* (when switching to a different cert & key, first this function should
* be used, then ssl_set_pkey */
- EVP_PKEY_free(c->pkeys[i].privatekey);
- c->pkeys[i].privatekey = NULL;
+ EVP_PKEY_free(c->privatekey);
+ c->privatekey = NULL;
/* clear error queue */
ERR_clear_error();
}
@@ -357,68 +230,29 @@ static int ssl_set_cert(CERT *c, X509 *x) {
EVP_PKEY_free(pkey);
- X509_free(c->pkeys[i].x509);
- c->pkeys[i].x509 = X509_up_ref(x);
- c->key = &(c->pkeys[i]);
+ X509_free(c->x509);
+ c->x509 = X509_up_ref(x);
return 1;
}
-int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) {
- int reason_code;
- BIO *in;
- int ret = 0;
- X509 *x = NULL;
-
- in = BIO_new(BIO_s_file());
- if (in == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_file, ERR_R_BUF_LIB);
- goto end;
- }
-
- if (BIO_read_filename(in, file) <= 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_file, ERR_R_SYS_LIB);
- goto end;
- }
-
- if (type == SSL_FILETYPE_ASN1) {
- reason_code = ERR_R_ASN1_LIB;
- x = d2i_X509_bio(in, NULL);
- } else if (type == SSL_FILETYPE_PEM) {
- reason_code = ERR_R_PEM_LIB;
- x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
- ctx->default_passwd_callback_userdata);
- } else {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_file,
- SSL_R_BAD_SSL_FILETYPE);
- goto end;
- }
-
- if (x == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_file, reason_code);
- goto end;
+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;
}
- ret = SSL_CTX_use_certificate(ctx, x);
-
-end:
- X509_free(x);
- BIO_free(in);
- return ret;
-}
-
-int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const uint8_t *d) {
- X509 *x;
- int ret;
-
- x = d2i_X509(NULL, &d, (long)len);
- if (x == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_ASN1, ERR_R_ASN1_LIB);
+ 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;
}
@@ -427,14 +261,13 @@ int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) {
EVP_PKEY *pkey;
if (rsa == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey,
- ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
pkey = EVP_PKEY_new();
if (pkey == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey, ERR_R_EVP_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB);
return 0;
}
@@ -446,201 +279,145 @@ int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) {
return ret;
}
-int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) {
- int reason_code, ret = 0;
- BIO *in;
- RSA *rsa = NULL;
-
- in = BIO_new(BIO_s_file());
- if (in == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_file, ERR_R_BUF_LIB);
- goto end;
- }
-
- if (BIO_read_filename(in, file) <= 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_file, ERR_R_SYS_LIB);
- goto end;
- }
-
- if (type == SSL_FILETYPE_ASN1) {
- reason_code = ERR_R_ASN1_LIB;
- rsa = d2i_RSAPrivateKey_bio(in, NULL);
- } else if (type == SSL_FILETYPE_PEM) {
- reason_code = ERR_R_PEM_LIB;
- rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ctx->default_passwd_callback,
- ctx->default_passwd_callback_userdata);
- } else {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_file,
- SSL_R_BAD_SSL_FILETYPE);
- goto end;
- }
-
- if (rsa == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_file, reason_code);
- goto end;
- }
- ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
- RSA_free(rsa);
-
-end:
- BIO_free(in);
- return ret;
-}
-
-int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const uint8_t *d, long len) {
- int ret;
- const uint8_t *p;
- RSA *rsa;
-
- p = d;
- rsa = d2i_RSAPrivateKey(NULL, &p, (long)len);
+int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const uint8_t *der,
+ size_t der_len) {
+ RSA *rsa = RSA_private_key_from_bytes(der, der_len);
if (rsa == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_ASN1, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
return 0;
}
- ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
+ int ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
RSA_free(rsa);
return ret;
}
int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) {
if (pkey == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
return ssl_set_pkey(ctx->cert, pkey);
}
-int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) {
- int reason_code, ret = 0;
- BIO *in;
- EVP_PKEY *pkey = NULL;
-
- in = BIO_new(BIO_s_file());
- if (in == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_file, ERR_R_BUF_LIB);
- goto end;
- }
-
- if (BIO_read_filename(in, file) <= 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_file, ERR_R_SYS_LIB);
- goto end;
+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;
}
- if (type == SSL_FILETYPE_PEM) {
- reason_code = ERR_R_PEM_LIB;
- pkey = PEM_read_bio_PrivateKey(in, NULL, ctx->default_passwd_callback,
- ctx->default_passwd_callback_userdata);
- } else if (type == SSL_FILETYPE_ASN1) {
- reason_code = ERR_R_ASN1_LIB;
- pkey = d2i_PrivateKey_bio(in, NULL);
- } else {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_file, SSL_R_BAD_SSL_FILETYPE);
- goto end;
+ 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;
}
- if (pkey == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_file, reason_code);
- goto end;
- }
- ret = SSL_CTX_use_PrivateKey(ctx, pkey);
+ int ret = SSL_CTX_use_PrivateKey(ctx, pkey);
EVP_PKEY_free(pkey);
-
-end:
- BIO_free(in);
return ret;
}
-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;
+void SSL_set_private_key_method(SSL *ssl,
+ const SSL_PRIVATE_KEY_METHOD *key_method) {
+ ssl->cert->key_method = key_method;
+}
- p = d;
- pkey = d2i_PrivateKey(type, NULL, &p, (long)len);
- if (pkey == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_ASN1, ERR_R_ASN1_LIB);
+int SSL_set_private_key_digest_prefs(SSL *ssl, const int *digest_nids,
+ size_t num_digests) {
+ OPENSSL_free(ssl->cert->digest_nids);
+
+ ssl->cert->num_digest_nids = 0;
+ ssl->cert->digest_nids = BUF_memdup(digest_nids, num_digests*sizeof(int));
+ if (ssl->cert->digest_nids == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
- ret = SSL_CTX_use_PrivateKey(ctx, pkey);
- EVP_PKEY_free(pkey);
- return ret;
+ ssl->cert->num_digest_nids = num_digests;
+ return 1;
}
+int ssl_has_private_key(SSL *ssl) {
+ return ssl->cert->privatekey != NULL || ssl->cert->key_method != NULL;
+}
-/* Read a file that contains our certificate in "PEM" format, possibly followed
- * by a sequence of CA certificates that should be sent to the peer in the
- * Certificate message. */
-int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) {
- BIO *in;
- int ret = 0;
- X509 *x = NULL;
+int ssl_private_key_type(SSL *ssl) {
+ if (ssl->cert->key_method != NULL) {
+ return ssl->cert->key_method->type(ssl);
+ }
+ return EVP_PKEY_id(ssl->cert->privatekey);
+}
- ERR_clear_error(); /* clear error stack for SSL_CTX_use_certificate() */
+size_t ssl_private_key_max_signature_len(SSL *ssl) {
+ if (ssl->cert->key_method != NULL) {
+ return ssl->cert->key_method->max_signature_len(ssl);
+ }
+ return EVP_PKEY_size(ssl->cert->privatekey);
+}
- in = BIO_new(BIO_s_file());
- if (in == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_chain_file, ERR_R_BUF_LIB);
- goto end;
+enum ssl_private_key_result_t ssl_private_key_sign(
+ SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, const EVP_MD *md,
+ const uint8_t *in, size_t in_len) {
+ if (ssl->cert->key_method != NULL) {
+ return ssl->cert->key_method->sign(ssl, out, out_len, max_out, md, in,
+ in_len);
}
- if (BIO_read_filename(in, file) <= 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_chain_file, ERR_R_SYS_LIB);
+ enum ssl_private_key_result_t ret = ssl_private_key_failure;
+ EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(ssl->cert->privatekey, NULL);
+ if (ctx == NULL) {
goto end;
}
- x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback,
- ctx->default_passwd_callback_userdata);
- if (x == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_chain_file, ERR_R_PEM_LIB);
+ size_t len = max_out;
+ if (!EVP_PKEY_sign_init(ctx) ||
+ !EVP_PKEY_CTX_set_signature_md(ctx, md) ||
+ !EVP_PKEY_sign(ctx, out, &len, in, in_len)) {
goto end;
}
+ *out_len = len;
+ ret = ssl_private_key_success;
- ret = SSL_CTX_use_certificate(ctx, x);
-
- if (ERR_peek_error() != 0) {
- ret = 0; /* Key/certificate mismatch doesn't imply ret==0 ... */
- }
+end:
+ EVP_PKEY_CTX_free(ctx);
+ return ret;
+}
- if (ret) {
- /* If we could set up our certificate, now proceed to the CA
- * certificates. */
- X509 *ca;
- int r;
- uint32_t err;
+enum ssl_private_key_result_t ssl_private_key_sign_complete(
+ SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out) {
+ /* Only custom keys may be asynchronous. */
+ return ssl->cert->key_method->sign_complete(ssl, out, out_len, max_out);
+}
- SSL_CTX_clear_chain_certs(ctx);
+enum ssl_private_key_result_t ssl_private_key_decrypt(
+ SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
+ const uint8_t *in, size_t in_len) {
+ if (ssl->cert->key_method != NULL) {
+ return ssl->cert->key_method->decrypt(ssl, out, out_len, max_out, in,
+ in_len);
+ }
- while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
- ctx->default_passwd_callback_userdata)) !=
- NULL) {
- r = SSL_CTX_add0_chain_cert(ctx, ca);
- if (!r) {
- X509_free(ca);
- ret = 0;
- goto end;
- }
- /* Note that we must not free r if it was successfully added to the chain
- * (while we must free the main certificate, since its reference count is
- * increased by SSL_CTX_use_certificate). */
- }
+ 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;
+ }
- /* When the while loop ends, it's usually just EOF. */
- err = ERR_peek_last_error();
- if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
- ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
- ERR_clear_error();
- } else {
- ret = 0; /* some real error */
- }
+ /* 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)) {
+ return ssl_private_key_failure;
}
+ return ssl_private_key_success;
+}
-end:
- X509_free(x);
- BIO_free(in);
- return ret;
+enum ssl_private_key_result_t ssl_private_key_decrypt_complete(
+ SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out) {
+ /* Only custom keys may be asynchronous. */
+ return ssl->cert->key_method->decrypt_complete(ssl, out, out_len, max_out);
}
diff --git a/src/ssl/ssl_sess.c b/src/ssl/ssl_sess.c
deleted file mode 100644
index 9ab4585..0000000
--- a/src/ssl/ssl_sess.c
+++ /dev/null
@@ -1,878 +0,0 @@
-/* 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.]
- */
-/* ====================================================================
- * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-/* ====================================================================
- * Copyright 2005 Nokia. All rights reserved.
- *
- * The portions of the attached software ("Contribution") is developed by
- * Nokia Corporation and is licensed pursuant to the OpenSSL open source
- * license.
- *
- * The Contribution, originally written by Mika Kousa and Pasi Eronen of
- * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
- * support (see RFC 4279) to OpenSSL.
- *
- * No patent licenses or other rights except those expressly stated in
- * the OpenSSL open source license shall be deemed granted or received
- * expressly, by implication, estoppel, or otherwise.
- *
- * No assurances are provided by Nokia that the Contribution does not
- * infringe the patent or other intellectual property rights of any third
- * party or that the license provides you with all the necessary rights
- * to make use of the Contribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
- * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
- * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
- * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
- * OTHERWISE. */
-
-#include <stdio.h>
-#include <string.h>
-
-#include <openssl/err.h>
-#include <openssl/lhash.h>
-#include <openssl/mem.h>
-#include <openssl/rand.h>
-
-#include "internal.h"
-#include "../crypto/internal.h"
-
-
-/* The address of this is a magic value, a pointer to which is returned by
- * SSL_magic_pending_session_ptr(). It allows a session callback to indicate
- * that it needs to asynchronously fetch session information. */
-static const char g_pending_session_magic = 0;
-
-static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
-
-static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s);
-static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s);
-static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck);
-
-SSL_SESSION *SSL_magic_pending_session_ptr(void) {
- return (SSL_SESSION *)&g_pending_session_magic;
-}
-
-SSL_SESSION *SSL_get_session(const SSL *ssl)
-{
- /* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */
- return ssl->session;
-}
-
-SSL_SESSION *SSL_get1_session(SSL *ssl) {
- /* variant of SSL_get_session: caller really gets something */
- return SSL_SESSION_up_ref(ssl->session);
-}
-
-int SSL_SESSION_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
- 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)) {
- return -1;
- }
- return index;
-}
-
-int SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg) {
- return CRYPTO_set_ex_data(&s->ex_data, idx, arg);
-}
-
-void *SSL_SESSION_get_ex_data(const SSL_SESSION *s, int idx) {
- return CRYPTO_get_ex_data(&s->ex_data, idx);
-}
-
-SSL_SESSION *SSL_SESSION_new(void) {
- SSL_SESSION *ss;
-
- ss = (SSL_SESSION *)OPENSSL_malloc(sizeof(SSL_SESSION));
- if (ss == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_new, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- memset(ss, 0, sizeof(SSL_SESSION));
-
- ss->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */
- ss->references = 1;
- ss->timeout = SSL_DEFAULT_SESSION_TIMEOUT;
- ss->time = (unsigned long)time(NULL);
- CRYPTO_new_ex_data(&g_ex_data_class, ss, &ss->ex_data);
- return ss;
-}
-
-const uint8_t *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len) {
- if (len) {
- *len = s->session_id_length;
- }
- return s->session_id;
-}
-
-/* Even with SSLv2, we have 16 bytes (128 bits) of session ID space.
- * SSLv3/TLSv1 has 32 bytes (256 bits). As such, filling the ID with random
- * gunk repeatedly until we have no conflict is going to complete in one
- * iteration pretty much "most" of the time (btw: understatement). So, if it
- * takes us 10 iterations and we still can't avoid a conflict - well that's a
- * reasonable point to call it quits. Either the RAND code is broken or someone
- * is trying to open roughly very close to 2^128 (or 2^256) SSL sessions to our
- * server. How you might store that many sessions is perhaps a more interesting
- * question ... */
-static int def_generate_session_id(const SSL *ssl, uint8_t *id,
- unsigned int *id_len) {
- static const unsigned kMaxAttempts = 10;
- unsigned int retry = 0;
- do {
- if (!RAND_bytes(id, *id_len)) {
- return 0;
- }
- } while (SSL_has_matching_session_id(ssl, id, *id_len) &&
- (++retry < kMaxAttempts));
-
- if (retry < kMaxAttempts) {
- return 1;
- }
-
- /* else - woops a session_id match */
- /* XXX We should also check the external cache -- but the probability of a
- * collision is negligible, and we could not prevent the concurrent creation
- * of sessions with identical IDs since we currently don't have means to
- * atomically check whether a session ID already exists and make a
- * reservation for it if it does not (this problem applies to the internal
- * cache as well). */
- return 0;
-}
-
-int ssl_get_new_session(SSL *s, int session) {
- /* This gets used by clients and servers. */
-
- unsigned int tmp;
- SSL_SESSION *ss = NULL;
- GEN_SESSION_CB cb = def_generate_session_id;
-
- if (s->mode & SSL_MODE_NO_SESSION_CREATION) {
- OPENSSL_PUT_ERROR(SSL, ssl_get_new_session,
- SSL_R_SESSION_MAY_NOT_BE_CREATED);
- return 0;
- }
-
- ss = SSL_SESSION_new();
- if (ss == NULL) {
- return 0;
- }
-
- /* If the context has a default timeout, use it over the default. */
- if (s->initial_ctx->session_timeout != 0) {
- ss->timeout = s->initial_ctx->session_timeout;
- }
-
- SSL_SESSION_free(s->session);
- s->session = NULL;
-
- if (session) {
- if (s->version == SSL3_VERSION || s->version == TLS1_VERSION ||
- s->version == TLS1_1_VERSION || s->version == TLS1_2_VERSION ||
- s->version == DTLS1_VERSION || s->version == DTLS1_2_VERSION) {
- ss->ssl_version = s->version;
- ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
- } else {
- OPENSSL_PUT_ERROR(SSL, ssl_get_new_session,
- SSL_R_UNSUPPORTED_SSL_VERSION);
- SSL_SESSION_free(ss);
- return 0;
- }
-
- /* If RFC4507 ticket use empty session ID */
- if (s->tlsext_ticket_expected) {
- ss->session_id_length = 0;
- goto sess_id_done;
- }
-
- /* Choose which callback will set the session ID */
- if (s->generate_session_id) {
- cb = s->generate_session_id;
- } else if (s->initial_ctx->generate_session_id) {
- cb = s->initial_ctx->generate_session_id;
- }
-
- /* Choose a session ID */
- tmp = ss->session_id_length;
- if (!cb(s, ss->session_id, &tmp)) {
- /* The callback failed */
- OPENSSL_PUT_ERROR(SSL, ssl_get_new_session,
- SSL_R_SSL_SESSION_ID_CALLBACK_FAILED);
- SSL_SESSION_free(ss);
- return 0;
- }
-
- /* Don't allow the callback to set the session length to zero. nor set it
- * higher than it was. */
- if (!tmp || tmp > ss->session_id_length) {
- /* The callback set an illegal length */
- OPENSSL_PUT_ERROR(SSL, ssl_get_new_session,
- SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH);
- SSL_SESSION_free(ss);
- return 0;
- }
-
- ss->session_id_length = tmp;
- /* Finally, check for a conflict */
- if (SSL_has_matching_session_id(s, ss->session_id, ss->session_id_length)) {
- OPENSSL_PUT_ERROR(SSL, ssl_get_new_session,
- SSL_R_SSL_SESSION_ID_CONFLICT);
- SSL_SESSION_free(ss);
- return 0;
- }
-
- sess_id_done:
- if (s->tlsext_hostname) {
- ss->tlsext_hostname = BUF_strdup(s->tlsext_hostname);
- if (ss->tlsext_hostname == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_get_new_session, ERR_R_INTERNAL_ERROR);
- SSL_SESSION_free(ss);
- return 0;
- }
- }
- } else {
- ss->session_id_length = 0;
- }
-
- if (s->sid_ctx_length > sizeof(ss->sid_ctx)) {
- OPENSSL_PUT_ERROR(SSL, ssl_get_new_session, ERR_R_INTERNAL_ERROR);
- SSL_SESSION_free(ss);
- return 0;
- }
-
- memcpy(ss->sid_ctx, s->sid_ctx, s->sid_ctx_length);
- ss->sid_ctx_length = s->sid_ctx_length;
- s->session = ss;
- ss->ssl_version = s->version;
- ss->verify_result = X509_V_OK;
-
- return 1;
-}
-
-/* ssl_get_prev attempts to find an SSL_SESSION to be used to resume this
- * connection. It is only called by servers.
- *
- * ctx: contains the early callback context, which is the result of a
- * shallow parse of the ClientHello.
- *
- * Returns:
- * -1: error
- * 0: a session may have been found.
- *
- * Side effects:
- * - If a session is found then s->session is pointed at it (after freeing an
- * existing session if need be) and s->verify_result is set from the session.
- * - Both for new and resumed sessions, s->tlsext_ticket_expected is set to 1
- * if the server should issue a new session ticket (to 0 otherwise). */
-int ssl_get_prev_session(SSL *s, const struct ssl_early_callback_ctx *ctx) {
- /* This is used only by servers. */
- SSL_SESSION *ret = NULL;
- int fatal = 0;
- int try_session_cache = 1;
- int r;
-
- if (ctx->session_id_len > SSL_MAX_SSL_SESSION_ID_LENGTH) {
- goto err;
- }
-
- if (ctx->session_id_len == 0) {
- try_session_cache = 0;
- }
-
- r = tls1_process_ticket(s, ctx, &ret); /* sets s->tlsext_ticket_expected */
- switch (r) {
- case -1: /* Error during processing */
- fatal = 1;
- goto err;
-
- case 0: /* No ticket found */
- case 1: /* Zero length ticket found */
- break; /* Ok to carry on processing session id. */
-
- case 2: /* Ticket found but not decrypted. */
- case 3: /* Ticket decrypted, *ret has been set. */
- try_session_cache = 0;
- break;
-
- default:
- abort();
- }
-
- if (try_session_cache && ret == NULL &&
- !(s->initial_ctx->session_cache_mode &
- SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) {
- SSL_SESSION data;
- data.ssl_version = s->version;
- data.session_id_length = ctx->session_id_len;
- if (ctx->session_id_len == 0) {
- return 0;
- }
- memcpy(data.session_id, ctx->session_id, ctx->session_id_len);
-
- CRYPTO_MUTEX_lock_read(&s->initial_ctx->lock);
- ret = lh_SSL_SESSION_retrieve(s->initial_ctx->sessions, &data);
- CRYPTO_MUTEX_unlock(&s->initial_ctx->lock);
-
- if (ret != NULL) {
- SSL_SESSION_up_ref(ret);
- }
- }
-
- if (try_session_cache && ret == NULL &&
- s->initial_ctx->get_session_cb != NULL) {
- int copy = 1;
-
- ret = s->initial_ctx->get_session_cb(s, (uint8_t *)ctx->session_id,
- ctx->session_id_len, &copy);
- if (ret != NULL) {
- if (ret == SSL_magic_pending_session_ptr()) {
- /* This is a magic value which indicates that the callback needs to
- * unwind the stack and figure out the session asynchronously. */
- return PENDING_SESSION;
- }
-
- /* Increment reference count now if the session callback asks us to do so
- * (note that if the session structures returned by the callback are
- * shared between threads, it must handle the reference count itself
- * [i.e. copy == 0], or things won't be thread-safe). */
- if (copy) {
- SSL_SESSION_up_ref(ret);
- }
-
- /* Add the externally cached session to the internal cache as well if and
- * only if we are supposed to. */
- if (!(s->initial_ctx->session_cache_mode &
- SSL_SESS_CACHE_NO_INTERNAL_STORE)) {
- /* The following should not return 1, otherwise, things are very
- * strange */
- SSL_CTX_add_session(s->initial_ctx, ret);
- }
- }
- }
-
- if (ret == NULL) {
- goto err;
- }
-
- /* Now ret is non-NULL and we own one of its reference counts. */
-
- if (ret->sid_ctx_length != s->sid_ctx_length ||
- memcmp(ret->sid_ctx, s->sid_ctx, ret->sid_ctx_length)) {
- /* We have the session requested by the client, but we don't want to use it
- * in this context. */
- goto err; /* treat like cache miss */
- }
-
- if ((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0) {
- /* We can't be sure if this session is being used out of context, which is
- * especially important for SSL_VERIFY_PEER. The application should have
- * used SSL[_CTX]_set_session_id_context.
- *
- * For this error case, we generate an error instead of treating the event
- * like a cache miss (otherwise it would be easy for applications to
- * effectively disable the session cache by accident without anyone
- * noticing). */
- OPENSSL_PUT_ERROR(SSL, ssl_get_prev_session,
- SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);
- fatal = 1;
- goto err;
- }
-
- if (ret->timeout < (long)(time(NULL) - ret->time)) {
- /* timeout */
- if (try_session_cache) {
- /* session was from the cache, so remove it */
- SSL_CTX_remove_session(s->initial_ctx, ret);
- }
- goto err;
- }
-
- SSL_SESSION_free(s->session);
- s->session = ret;
- s->verify_result = s->session->verify_result;
- return 1;
-
-err:
- if (ret != NULL) {
- SSL_SESSION_free(ret);
- if (!try_session_cache) {
- /* The session was from a ticket, so we should
- * issue a ticket for the new session */
- s->tlsext_ticket_expected = 1;
- }
- }
- if (fatal) {
- return -1;
- }
- return 0;
-}
-
-int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c) {
- int ret = 0;
- SSL_SESSION *s;
-
- /* add just 1 reference count for the SSL_CTX's session cache even though it
- * has two ways of access: each session is in a doubly linked list and an
- * lhash */
- SSL_SESSION_up_ref(c);
- /* if session c is in already in cache, we take back the increment later */
-
- CRYPTO_MUTEX_lock_write(&ctx->lock);
- if (!lh_SSL_SESSION_insert(ctx->sessions, &s, c)) {
- CRYPTO_MUTEX_unlock(&ctx->lock);
- return 0;
- }
-
- /* s != NULL iff we already had a session with the given PID. In this case, s
- * == c should hold (then we did not really modify ctx->sessions), or we're
- * in trouble. */
- if (s != NULL && s != c) {
- /* We *are* in trouble ... */
- SSL_SESSION_list_remove(ctx, s);
- SSL_SESSION_free(s);
- /* ... so pretend the other session did not exist in cache (we cannot
- * handle two SSL_SESSION structures with identical session ID in the same
- * cache, which could happen e.g. when two threads concurrently obtain the
- * same session from an external cache) */
- s = NULL;
- }
-
- /* Put at the head of the queue unless it is already in the cache */
- if (s == NULL) {
- SSL_SESSION_list_add(ctx, c);
- }
-
- if (s != NULL) {
- /* existing cache entry -- decrement previously incremented reference count
- * because it already takes into account the cache */
- SSL_SESSION_free(s); /* s == c */
- ret = 0;
- } else {
- /* new cache entry -- remove old ones if cache has become too large */
- ret = 1;
-
- if (SSL_CTX_sess_get_cache_size(ctx) > 0) {
- while (SSL_CTX_sess_number(ctx) > SSL_CTX_sess_get_cache_size(ctx)) {
- if (!remove_session_lock(ctx, ctx->session_cache_tail, 0)) {
- break;
- }
- }
- }
- }
-
- CRYPTO_MUTEX_unlock(&ctx->lock);
- return ret;
-}
-
-int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c) {
- return remove_session_lock(ctx, c, 1);
-}
-
-static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lock) {
- SSL_SESSION *r;
- int ret = 0;
-
- if (c != NULL && c->session_id_length != 0) {
- if (lock) {
- CRYPTO_MUTEX_lock_write(&ctx->lock);
- }
- r = lh_SSL_SESSION_retrieve(ctx->sessions, c);
- if (r == c) {
- ret = 1;
- r = lh_SSL_SESSION_delete(ctx->sessions, c);
- SSL_SESSION_list_remove(ctx, c);
- }
-
- if (lock) {
- CRYPTO_MUTEX_unlock(&ctx->lock);
- }
-
- if (ret) {
- r->not_resumable = 1;
- if (ctx->remove_session_cb != NULL) {
- ctx->remove_session_cb(ctx, r);
- }
- SSL_SESSION_free(r);
- }
- }
-
- return ret;
-}
-
-SSL_SESSION *SSL_SESSION_up_ref(SSL_SESSION *session) {
- if (session) {
- CRYPTO_refcount_inc(&session->references);
- }
- return session;
-}
-
-void SSL_SESSION_free(SSL_SESSION *session) {
- if (session == NULL ||
- !CRYPTO_refcount_dec_and_test_zero(&session->references)) {
- return;
- }
-
- CRYPTO_free_ex_data(&g_ex_data_class, session, &session->ex_data);
-
- OPENSSL_cleanse(session->master_key, sizeof(session->master_key));
- OPENSSL_cleanse(session->session_id, sizeof(session->session_id));
- ssl_sess_cert_free(session->sess_cert);
- X509_free(session->peer);
- OPENSSL_free(session->tlsext_hostname);
- OPENSSL_free(session->tlsext_tick);
- OPENSSL_free(session->tlsext_signed_cert_timestamp_list);
- OPENSSL_free(session->ocsp_response);
- OPENSSL_free(session->psk_identity);
- OPENSSL_cleanse(session, sizeof(*session));
- OPENSSL_free(session);
-}
-
-int SSL_set_session(SSL *s, SSL_SESSION *session) {
- if (s->session == session) {
- return 1;
- }
-
- SSL_SESSION_free(s->session);
- s->session = session;
- if (session != NULL) {
- SSL_SESSION_up_ref(session);
- s->verify_result = session->verify_result;
- }
-
- return 1;
-}
-
-long SSL_SESSION_set_timeout(SSL_SESSION *s, long t) {
- if (s == NULL) {
- return 0;
- }
-
- s->timeout = t;
- return 1;
-}
-
-long SSL_SESSION_get_timeout(const SSL_SESSION *s) {
- if (s == NULL) {
- return 0;
- }
-
- return s->timeout;
-}
-
-long SSL_SESSION_get_time(const SSL_SESSION *s) {
- if (s == NULL) {
- return 0;
- }
-
- return s->time;
-}
-
-long SSL_SESSION_set_time(SSL_SESSION *s, long t) {
- if (s == NULL) {
- return 0;
- }
-
- s->time = t;
- return t;
-}
-
-X509 *SSL_SESSION_get0_peer(SSL_SESSION *s) { return s->peer; }
-
-int SSL_SESSION_set1_id_context(SSL_SESSION *s, const uint8_t *sid_ctx,
- unsigned int sid_ctx_len) {
- if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_set1_id_context,
- SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
- return 0;
- }
-
- s->sid_ctx_length = sid_ctx_len;
- memcpy(s->sid_ctx, sid_ctx, sid_ctx_len);
-
- return 1;
-}
-
-long SSL_CTX_set_timeout(SSL_CTX *s, long t) {
- long l;
- if (s == NULL) {
- return 0;
- }
-
- l = s->session_timeout;
- s->session_timeout = t;
- return l;
-}
-
-long SSL_CTX_get_timeout(const SSL_CTX *s) {
- if (s == NULL) {
- return 0;
- }
-
- return s->session_timeout;
-}
-
-typedef struct timeout_param_st {
- SSL_CTX *ctx;
- long time;
- LHASH_OF(SSL_SESSION) *cache;
-} TIMEOUT_PARAM;
-
-static void timeout_doall_arg(SSL_SESSION *sess, void *void_param) {
- TIMEOUT_PARAM *param = void_param;
-
- if (param->time == 0 ||
- param->time > (sess->time + sess->timeout)) {
- /* timeout */
- /* The reason we don't call SSL_CTX_remove_session() is to
- * save on locking overhead */
- (void) lh_SSL_SESSION_delete(param->cache, sess);
- SSL_SESSION_list_remove(param->ctx, sess);
- sess->not_resumable = 1;
- if (param->ctx->remove_session_cb != NULL) {
- param->ctx->remove_session_cb(param->ctx, sess);
- }
- SSL_SESSION_free(sess);
- }
-}
-
-void SSL_CTX_flush_sessions(SSL_CTX *ctx, long t) {
- TIMEOUT_PARAM tp;
-
- tp.ctx = ctx;
- tp.cache = ctx->sessions;
- if (tp.cache == NULL) {
- return;
- }
- tp.time = t;
- CRYPTO_MUTEX_lock_write(&ctx->lock);
- lh_SSL_SESSION_doall_arg(tp.cache, timeout_doall_arg, &tp);
- 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);
- return 1;
- }
-
- return 0;
-}
-
-/* locked by SSL_CTX in the calling function */
-static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s) {
- if (s->next == NULL || s->prev == NULL) {
- return;
- }
-
- if (s->next == (SSL_SESSION *)&ctx->session_cache_tail) {
- /* last element in list */
- if (s->prev == (SSL_SESSION *)&ctx->session_cache_head) {
- /* only one element in list */
- ctx->session_cache_head = NULL;
- ctx->session_cache_tail = NULL;
- } else {
- ctx->session_cache_tail = s->prev;
- s->prev->next = (SSL_SESSION *)&(ctx->session_cache_tail);
- }
- } else {
- if (s->prev == (SSL_SESSION *)&ctx->session_cache_head) {
- /* first element in list */
- ctx->session_cache_head = s->next;
- s->next->prev = (SSL_SESSION *)&(ctx->session_cache_head);
- } else { /* middle of list */
- s->next->prev = s->prev;
- s->prev->next = s->next;
- }
- }
- s->prev = s->next = NULL;
-}
-
-static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s) {
- if (s->next != NULL && s->prev != NULL) {
- SSL_SESSION_list_remove(ctx, s);
- }
-
- if (ctx->session_cache_head == NULL) {
- ctx->session_cache_head = s;
- ctx->session_cache_tail = s;
- s->prev = (SSL_SESSION *)&(ctx->session_cache_head);
- s->next = (SSL_SESSION *)&(ctx->session_cache_tail);
- } else {
- s->next = ctx->session_cache_head;
- s->next->prev = s;
- s->prev = (SSL_SESSION *)&(ctx->session_cache_head);
- ctx->session_cache_head = s;
- }
-}
-
-void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx,
- int (*cb)(struct ssl_st *ssl, SSL_SESSION *sess)) {
- ctx->new_session_cb = cb;
-}
-
-int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(SSL *ssl, SSL_SESSION *sess) {
- return ctx->new_session_cb;
-}
-
-void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx,
- void (*cb)(SSL_CTX *ctx, SSL_SESSION *sess)) {
- ctx->remove_session_cb = cb;
-}
-
-void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(SSL_CTX *ctx,
- SSL_SESSION *sess) {
- return ctx->remove_session_cb;
-}
-
-void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx,
- SSL_SESSION *(*cb)(struct ssl_st *ssl,
- uint8_t *data, int len,
- int *copy)) {
- ctx->get_session_cb = cb;
-}
-
-SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(SSL *ssl, uint8_t *data,
- int len, int *copy) {
- return ctx->get_session_cb;
-}
-
-void SSL_CTX_set_info_callback(SSL_CTX *ctx,
- void (*cb)(const SSL *ssl, int type, int val)) {
- ctx->info_callback = cb;
-}
-
-void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl, int type,
- int val) {
- return ctx->info_callback;
-}
-
-void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, X509 **x509,
- EVP_PKEY **pkey)) {
- ctx->client_cert_cb = cb;
-}
-
-int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **x509,
- EVP_PKEY **pkey) {
- return ctx->client_cert_cb;
-}
-
-void SSL_CTX_set_channel_id_cb(SSL_CTX *ctx,
- void (*cb)(SSL *ssl, EVP_PKEY **pkey)) {
- ctx->channel_id_cb = cb;
-}
-
-void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))(SSL *ssl, EVP_PKEY **pkey) {
- return ctx->channel_id_cb;
-}
-
-IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION)
diff --git a/src/ssl/ssl_session.c b/src/ssl/ssl_session.c
new file mode 100644
index 0000000..3d59bc3
--- /dev/null
+++ b/src/ssl/ssl_session.c
@@ -0,0 +1,764 @@
+/* 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.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE. */
+
+#include <openssl/ssl.h>
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <openssl/err.h>
+#include <openssl/lhash.h>
+#include <openssl/mem.h>
+#include <openssl/rand.h>
+
+#include "internal.h"
+#include "../crypto/internal.h"
+
+
+/* The address of this is a magic value, a pointer to which is returned by
+ * SSL_magic_pending_session_ptr(). It allows a session callback to indicate
+ * that it needs to asynchronously fetch session information. */
+static const char g_pending_session_magic = 0;
+
+static CRYPTO_EX_DATA_CLASS g_ex_data_class =
+ CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;
+
+static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *session);
+static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *session);
+static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *session, int lock);
+
+SSL_SESSION *SSL_SESSION_new(void) {
+ SSL_SESSION *session = (SSL_SESSION *)OPENSSL_malloc(sizeof(SSL_SESSION));
+ if (session == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ memset(session, 0, sizeof(SSL_SESSION));
+
+ session->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */
+ session->references = 1;
+ session->timeout = SSL_DEFAULT_SESSION_TIMEOUT;
+ session->time = (unsigned long)time(NULL);
+ CRYPTO_new_ex_data(&session->ex_data);
+ return session;
+}
+
+SSL_SESSION *SSL_SESSION_up_ref(SSL_SESSION *session) {
+ if (session != NULL) {
+ CRYPTO_refcount_inc(&session->references);
+ }
+ return session;
+}
+
+void SSL_SESSION_free(SSL_SESSION *session) {
+ if (session == NULL ||
+ !CRYPTO_refcount_dec_and_test_zero(&session->references)) {
+ return;
+ }
+
+ CRYPTO_free_ex_data(&g_ex_data_class, session, &session->ex_data);
+
+ OPENSSL_cleanse(session->master_key, sizeof(session->master_key));
+ OPENSSL_cleanse(session->session_id, sizeof(session->session_id));
+ X509_free(session->peer);
+ sk_X509_pop_free(session->cert_chain, X509_free);
+ OPENSSL_free(session->tlsext_hostname);
+ OPENSSL_free(session->tlsext_tick);
+ OPENSSL_free(session->tlsext_signed_cert_timestamp_list);
+ OPENSSL_free(session->ocsp_response);
+ OPENSSL_free(session->psk_identity);
+ OPENSSL_cleanse(session, sizeof(*session));
+ OPENSSL_free(session);
+}
+
+const uint8_t *SSL_SESSION_get_id(const SSL_SESSION *session,
+ unsigned *out_len) {
+ if (out_len != NULL) {
+ *out_len = session->session_id_length;
+ }
+ return session->session_id;
+}
+
+long SSL_SESSION_get_timeout(const SSL_SESSION *session) {
+ return session->timeout;
+}
+
+long SSL_SESSION_get_time(const SSL_SESSION *session) {
+ if (session == NULL) {
+ /* NULL should crash, but silently accept it here for compatibility. */
+ return 0;
+ }
+ return session->time;
+}
+
+uint32_t SSL_SESSION_get_key_exchange_info(const SSL_SESSION *session) {
+ return session->key_exchange_info;
+}
+
+X509 *SSL_SESSION_get0_peer(const SSL_SESSION *session) {
+ return session->peer;
+}
+
+long SSL_SESSION_set_time(SSL_SESSION *session, long time) {
+ if (session == NULL) {
+ return 0;
+ }
+
+ session->time = time;
+ return time;
+}
+
+long SSL_SESSION_set_timeout(SSL_SESSION *session, long timeout) {
+ if (session == NULL) {
+ return 0;
+ }
+
+ session->timeout = timeout;
+ return 1;
+}
+
+int SSL_SESSION_set1_id_context(SSL_SESSION *session, const uint8_t *sid_ctx,
+ unsigned sid_ctx_len) {
+ if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
+ return 0;
+ }
+
+ session->sid_ctx_length = sid_ctx_len;
+ memcpy(session->sid_ctx, sid_ctx, sid_ctx_len);
+
+ return 1;
+}
+
+SSL_SESSION *SSL_magic_pending_session_ptr(void) {
+ return (SSL_SESSION *)&g_pending_session_magic;
+}
+
+SSL_SESSION *SSL_get_session(const SSL *ssl)
+{
+ /* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */
+ return ssl->session;
+}
+
+SSL_SESSION *SSL_get1_session(SSL *ssl) {
+ /* variant of SSL_get_session: caller really gets something */
+ return SSL_SESSION_up_ref(ssl->session);
+}
+
+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, dup_func,
+ free_func)) {
+ return -1;
+ }
+ return index;
+}
+
+int SSL_SESSION_set_ex_data(SSL_SESSION *session, int idx, void *arg) {
+ return CRYPTO_set_ex_data(&session->ex_data, idx, arg);
+}
+
+void *SSL_SESSION_get_ex_data(const SSL_SESSION *session, int idx) {
+ return CRYPTO_get_ex_data(&session->ex_data, idx);
+}
+
+int ssl_get_new_session(SSL *ssl, int is_server) {
+ if (ssl->mode & SSL_MODE_NO_SESSION_CREATION) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SESSION_MAY_NOT_BE_CREATED);
+ return 0;
+ }
+
+ SSL_SESSION *session = SSL_SESSION_new();
+ if (session == NULL) {
+ return 0;
+ }
+
+ /* If the context has a default timeout, use it over the default. */
+ if (ssl->initial_ctx->session_timeout != 0) {
+ session->timeout = ssl->initial_ctx->session_timeout;
+ }
+
+ session->ssl_version = ssl->version;
+
+ if (is_server) {
+ if (ssl->tlsext_ticket_expected) {
+ /* Don't set session IDs for sessions resumed with tickets. This will keep
+ * them out of the session cache. */
+ session->session_id_length = 0;
+ } else {
+ session->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
+ if (!RAND_bytes(session->session_id, session->session_id_length)) {
+ goto err;
+ }
+ }
+
+ if (ssl->tlsext_hostname != NULL) {
+ session->tlsext_hostname = BUF_strdup(ssl->tlsext_hostname);
+ if (session->tlsext_hostname == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+ } else {
+ session->session_id_length = 0;
+ }
+
+ if (ssl->sid_ctx_length > sizeof(session->sid_ctx)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ memcpy(session->sid_ctx, ssl->sid_ctx, ssl->sid_ctx_length);
+ session->sid_ctx_length = ssl->sid_ctx_length;
+
+ session->verify_result = X509_V_OK;
+
+ SSL_SESSION_free(ssl->session);
+ ssl->session = session;
+ return 1;
+
+err:
+ SSL_SESSION_free(session);
+ return 0;
+}
+
+/* ssl_lookup_session looks up |session_id| in the session cache and sets
+ * |*out_session| to an |SSL_SESSION| object if found. The caller takes
+ * ownership of the result. */
+static enum ssl_session_result_t ssl_lookup_session(
+ SSL *ssl, SSL_SESSION **out_session, const uint8_t *session_id,
+ size_t session_id_len) {
+ *out_session = NULL;
+
+ if (session_id_len == 0 || session_id_len > SSL_MAX_SSL_SESSION_ID_LENGTH) {
+ return ssl_session_success;
+ }
+
+ SSL_SESSION *session;
+ /* Try the internal cache, if it exists. */
+ if (!(ssl->initial_ctx->session_cache_mode &
+ SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) {
+ SSL_SESSION data;
+ data.ssl_version = ssl->version;
+ data.session_id_length = session_id_len;
+ memcpy(data.session_id, session_id, session_id_len);
+
+ CRYPTO_MUTEX_lock_read(&ssl->initial_ctx->lock);
+ session = lh_SSL_SESSION_retrieve(ssl->initial_ctx->sessions, &data);
+ if (session != NULL) {
+ SSL_SESSION_up_ref(session);
+ }
+ /* TODO(davidben): This should probably move it to the front of the list. */
+ CRYPTO_MUTEX_unlock(&ssl->initial_ctx->lock);
+
+ if (session != NULL) {
+ *out_session = session;
+ return ssl_session_success;
+ }
+ }
+
+ /* Fall back to the external cache, if it exists. */
+ if (ssl->initial_ctx->get_session_cb == NULL) {
+ return ssl_session_success;
+ }
+ int copy = 1;
+ session = ssl->initial_ctx->get_session_cb(ssl, (uint8_t *)session_id,
+ session_id_len, &copy);
+ if (session == NULL) {
+ return ssl_session_success;
+ }
+ if (session == SSL_magic_pending_session_ptr()) {
+ return ssl_session_retry;
+ }
+
+ /* Increment reference count now if the session callback asks us to do so
+ * (note that if the session structures returned by the callback are shared
+ * between threads, it must handle the reference count itself [i.e. copy ==
+ * 0], or things won't be thread-safe). */
+ if (copy) {
+ SSL_SESSION_up_ref(session);
+ }
+
+ /* Add the externally cached session to the internal cache if necessary. */
+ if (!(ssl->initial_ctx->session_cache_mode &
+ SSL_SESS_CACHE_NO_INTERNAL_STORE)) {
+ SSL_CTX_add_session(ssl->initial_ctx, session);
+ }
+
+ *out_session = session;
+ return ssl_session_success;
+}
+
+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) {
+ /* This is used only by servers. */
+ assert(ssl->server);
+ SSL_SESSION *session = NULL;
+ int send_ticket = 0;
+
+ /* If tickets are disabled, always behave as if no tickets are present. */
+ const uint8_t *ticket = NULL;
+ size_t ticket_len = 0;
+ const int tickets_supported =
+ !(SSL_get_options(ssl) & SSL_OP_NO_TICKET) &&
+ ssl->version > SSL3_VERSION &&
+ SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_session_ticket,
+ &ticket, &ticket_len);
+ if (tickets_supported) {
+ if (!tls_process_ticket(ssl, &session, &send_ticket, ticket, ticket_len,
+ ctx->session_id, ctx->session_id_len)) {
+ return ssl_session_error;
+ }
+ } else {
+ /* The client does not support session tickets, so the session ID should be
+ * used instead. */
+ enum ssl_session_result_t lookup_ret = ssl_lookup_session(
+ ssl, &session, ctx->session_id, ctx->session_id_len);
+ if (lookup_ret != ssl_session_success) {
+ return lookup_ret;
+ }
+ }
+
+ if (session == NULL ||
+ session->sid_ctx_length != ssl->sid_ctx_length ||
+ memcmp(session->sid_ctx, ssl->sid_ctx, ssl->sid_ctx_length) != 0) {
+ goto no_session;
+ }
+
+ if ((ssl->verify_mode & SSL_VERIFY_PEER) && ssl->sid_ctx_length == 0) {
+ /* We can't be sure if this session is being used out of context, which is
+ * especially important for SSL_VERIFY_PEER. The application should have
+ * used SSL[_CTX]_set_session_id_context.
+ *
+ * For this error case, we generate an error instead of treating the event
+ * like a cache miss (otherwise it would be easy for applications to
+ * effectively disable the session cache by accident without anyone
+ * noticing). */
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);
+ goto fatal_error;
+ }
+
+ if (session->timeout < (long)(time(NULL) - session->time)) {
+ if (!tickets_supported) {
+ /* The session was from the cache, so remove it. */
+ SSL_CTX_remove_session(ssl->initial_ctx, session);
+ }
+ goto no_session;
+ }
+
+ *out_session = session;
+ *out_send_ticket = send_ticket;
+ return ssl_session_success;
+
+fatal_error:
+ SSL_SESSION_free(session);
+ return ssl_session_error;
+
+no_session:
+ *out_session = NULL;
+ *out_send_ticket = tickets_supported;
+ SSL_SESSION_free(session);
+ return ssl_session_success;
+}
+
+int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *session) {
+ /* Although |session| is inserted into two structures (a doubly-linked list
+ * and the hash table), |ctx| only takes one reference. */
+ SSL_SESSION_up_ref(session);
+
+ SSL_SESSION *old_session;
+ CRYPTO_MUTEX_lock_write(&ctx->lock);
+ if (!lh_SSL_SESSION_insert(ctx->sessions, &old_session, session)) {
+ CRYPTO_MUTEX_unlock(&ctx->lock);
+ SSL_SESSION_free(session);
+ return 0;
+ }
+
+ if (old_session != NULL) {
+ if (old_session == session) {
+ /* |session| was already in the cache. */
+ CRYPTO_MUTEX_unlock(&ctx->lock);
+ SSL_SESSION_free(old_session);
+ return 0;
+ }
+
+ /* There was a session ID collision. |old_session| must be removed from
+ * the linked list and released. */
+ SSL_SESSION_list_remove(ctx, old_session);
+ SSL_SESSION_free(old_session);
+ }
+
+ SSL_SESSION_list_add(ctx, session);
+
+ /* Enforce any cache size limits. */
+ if (SSL_CTX_sess_get_cache_size(ctx) > 0) {
+ while (SSL_CTX_sess_number(ctx) > SSL_CTX_sess_get_cache_size(ctx)) {
+ if (!remove_session_lock(ctx, ctx->session_cache_tail, 0)) {
+ break;
+ }
+ }
+ }
+
+ CRYPTO_MUTEX_unlock(&ctx->lock);
+ return 1;
+}
+
+int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *session) {
+ return remove_session_lock(ctx, session, 1);
+}
+
+static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *session, int lock) {
+ int ret = 0;
+
+ if (session != NULL && session->session_id_length != 0) {
+ if (lock) {
+ CRYPTO_MUTEX_lock_write(&ctx->lock);
+ }
+ SSL_SESSION *found_session = lh_SSL_SESSION_retrieve(ctx->sessions,
+ session);
+ if (found_session == session) {
+ ret = 1;
+ found_session = lh_SSL_SESSION_delete(ctx->sessions, session);
+ SSL_SESSION_list_remove(ctx, session);
+ }
+
+ if (lock) {
+ CRYPTO_MUTEX_unlock(&ctx->lock);
+ }
+
+ if (ret) {
+ found_session->not_resumable = 1;
+ if (ctx->remove_session_cb != NULL) {
+ ctx->remove_session_cb(ctx, found_session);
+ }
+ SSL_SESSION_free(found_session);
+ }
+ }
+
+ return ret;
+}
+
+int SSL_set_session(SSL *ssl, SSL_SESSION *session) {
+ if (ssl->session == session) {
+ return 1;
+ }
+
+ SSL_SESSION_free(ssl->session);
+ ssl->session = session;
+ if (session != NULL) {
+ SSL_SESSION_up_ref(session);
+ ssl->verify_result = session->verify_result;
+ }
+
+ return 1;
+}
+
+long SSL_CTX_set_timeout(SSL_CTX *ctx, long timeout) {
+ if (ctx == NULL) {
+ return 0;
+ }
+
+ long old_timeout = ctx->session_timeout;
+ ctx->session_timeout = timeout;
+ return old_timeout;
+}
+
+long SSL_CTX_get_timeout(const SSL_CTX *ctx) {
+ if (ctx == NULL) {
+ return 0;
+ }
+
+ return ctx->session_timeout;
+}
+
+typedef struct timeout_param_st {
+ SSL_CTX *ctx;
+ long time;
+ LHASH_OF(SSL_SESSION) *cache;
+} TIMEOUT_PARAM;
+
+static void timeout_doall_arg(SSL_SESSION *session, void *void_param) {
+ TIMEOUT_PARAM *param = void_param;
+
+ if (param->time == 0 ||
+ param->time > (session->time + session->timeout)) {
+ /* timeout */
+ /* The reason we don't call SSL_CTX_remove_session() is to
+ * save on locking overhead */
+ (void) lh_SSL_SESSION_delete(param->cache, session);
+ SSL_SESSION_list_remove(param->ctx, session);
+ session->not_resumable = 1;
+ if (param->ctx->remove_session_cb != NULL) {
+ param->ctx->remove_session_cb(param->ctx, session);
+ }
+ SSL_SESSION_free(session);
+ }
+}
+
+void SSL_CTX_flush_sessions(SSL_CTX *ctx, long time) {
+ TIMEOUT_PARAM tp;
+
+ tp.ctx = ctx;
+ tp.cache = ctx->sessions;
+ if (tp.cache == NULL) {
+ return;
+ }
+ tp.time = time;
+ CRYPTO_MUTEX_lock_write(&ctx->lock);
+ lh_SSL_SESSION_doall_arg(tp.cache, timeout_doall_arg, &tp);
+ CRYPTO_MUTEX_unlock(&ctx->lock);
+}
+
+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;
+ }
+
+ return 0;
+}
+
+/* locked by SSL_CTX in the calling function */
+static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *session) {
+ if (session->next == NULL || session->prev == NULL) {
+ return;
+ }
+
+ if (session->next == (SSL_SESSION *)&ctx->session_cache_tail) {
+ /* last element in list */
+ if (session->prev == (SSL_SESSION *)&ctx->session_cache_head) {
+ /* only one element in list */
+ ctx->session_cache_head = NULL;
+ ctx->session_cache_tail = NULL;
+ } else {
+ ctx->session_cache_tail = session->prev;
+ session->prev->next = (SSL_SESSION *)&(ctx->session_cache_tail);
+ }
+ } else {
+ if (session->prev == (SSL_SESSION *)&ctx->session_cache_head) {
+ /* first element in list */
+ ctx->session_cache_head = session->next;
+ session->next->prev = (SSL_SESSION *)&(ctx->session_cache_head);
+ } else { /* middle of list */
+ session->next->prev = session->prev;
+ session->prev->next = session->next;
+ }
+ }
+ session->prev = session->next = NULL;
+}
+
+static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *session) {
+ if (session->next != NULL && session->prev != NULL) {
+ SSL_SESSION_list_remove(ctx, session);
+ }
+
+ if (ctx->session_cache_head == NULL) {
+ ctx->session_cache_head = session;
+ ctx->session_cache_tail = session;
+ session->prev = (SSL_SESSION *)&(ctx->session_cache_head);
+ session->next = (SSL_SESSION *)&(ctx->session_cache_tail);
+ } else {
+ session->next = ctx->session_cache_head;
+ session->next->prev = session;
+ session->prev = (SSL_SESSION *)&(ctx->session_cache_head);
+ ctx->session_cache_head = session;
+ }
+}
+
+void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx,
+ int (*cb)(SSL *ssl, SSL_SESSION *session)) {
+ ctx->new_session_cb = cb;
+}
+
+int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(SSL *ssl, SSL_SESSION *session) {
+ return ctx->new_session_cb;
+}
+
+void SSL_CTX_sess_set_remove_cb(
+ SSL_CTX *ctx, void (*cb)(SSL_CTX *ctx, SSL_SESSION *session)) {
+ ctx->remove_session_cb = cb;
+}
+
+void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(SSL_CTX *ctx,
+ SSL_SESSION *session) {
+ return ctx->remove_session_cb;
+}
+
+void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx,
+ SSL_SESSION *(*cb)(SSL *ssl,
+ uint8_t *id, int id_len,
+ int *out_copy)) {
+ ctx->get_session_cb = cb;
+}
+
+SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(
+ SSL *ssl, uint8_t *id, int id_len, int *out_copy) {
+ return ctx->get_session_cb;
+}
+
+void SSL_CTX_set_info_callback(
+ SSL_CTX *ctx, void (*cb)(const SSL *ssl, int type, int value)) {
+ ctx->info_callback = cb;
+}
+
+void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl, int type,
+ int value) {
+ return ctx->info_callback;
+}
+
+void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl,
+ X509 **out_x509,
+ EVP_PKEY **out_pkey)) {
+ ctx->client_cert_cb = cb;
+}
+
+int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **out_x509,
+ EVP_PKEY **out_pkey) {
+ return ctx->client_cert_cb;
+}
+
+void SSL_CTX_set_channel_id_cb(SSL_CTX *ctx,
+ void (*cb)(SSL *ssl, EVP_PKEY **pkey)) {
+ ctx->channel_id_cb = cb;
+}
+
+void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))(SSL *ssl, EVP_PKEY **pkey) {
+ return ctx->channel_id_cb;
+}
diff --git a/src/ssl/ssl_stat.c b/src/ssl/ssl_stat.c
index fa5541b..8fa197d 100644
--- a/src/ssl/ssl_stat.c
+++ b/src/ssl/ssl_stat.c
@@ -1,4 +1,3 @@
-/* ssl/ssl_stat.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -82,605 +81,394 @@
* OTHERWISE.
*/
-#include <stdio.h>
+#include <openssl/ssl.h>
+
#include "internal.h"
-const char *SSL_state_string_long(const SSL *s) {
- const char *str;
- switch (s->state) {
+const char *SSL_state_string_long(const SSL *ssl) {
+ switch (ssl->state) {
case SSL_ST_ACCEPT:
- str = "before accept initialization";
- break;
+ return "before accept initialization";
case SSL_ST_CONNECT:
- str = "before connect initialization";
- break;
+ return "before connect initialization";
case SSL_ST_OK:
- str = "SSL negotiation finished successfully";
- break;
+ return "SSL negotiation finished successfully";
case SSL_ST_RENEGOTIATE:
- str = "SSL renegotiate ciphers";
- break;
+ return "SSL renegotiate ciphers";
/* SSLv3 additions */
case SSL3_ST_CW_CLNT_HELLO_A:
- str = "SSLv3 write client hello A";
- break;
+ return "SSLv3 write client hello A";
case SSL3_ST_CW_CLNT_HELLO_B:
- str = "SSLv3 write client hello B";
- break;
+ return "SSLv3 write client hello B";
case SSL3_ST_CR_SRVR_HELLO_A:
- str = "SSLv3 read server hello A";
- break;
+ return "SSLv3 read server hello A";
case SSL3_ST_CR_SRVR_HELLO_B:
- str = "SSLv3 read server hello B";
- break;
+ return "SSLv3 read server hello B";
case SSL3_ST_CR_CERT_A:
- str = "SSLv3 read server certificate A";
- break;
+ return "SSLv3 read server certificate A";
case SSL3_ST_CR_CERT_B:
- str = "SSLv3 read server certificate B";
- break;
+ return "SSLv3 read server certificate B";
case SSL3_ST_CR_KEY_EXCH_A:
- str = "SSLv3 read server key exchange A";
- break;
+ return "SSLv3 read server key exchange A";
case SSL3_ST_CR_KEY_EXCH_B:
- str = "SSLv3 read server key exchange B";
- break;
+ return "SSLv3 read server key exchange B";
case SSL3_ST_CR_CERT_REQ_A:
- str = "SSLv3 read server certificate request A";
- break;
+ return "SSLv3 read server certificate request A";
case SSL3_ST_CR_CERT_REQ_B:
- str = "SSLv3 read server certificate request B";
- break;
+ return "SSLv3 read server certificate request B";
case SSL3_ST_CR_SESSION_TICKET_A:
- str = "SSLv3 read server session ticket A";
- break;
+ return "SSLv3 read server session ticket A";
case SSL3_ST_CR_SESSION_TICKET_B:
- str = "SSLv3 read server session ticket B";
- break;
+ return "SSLv3 read server session ticket B";
case SSL3_ST_CR_SRVR_DONE_A:
- str = "SSLv3 read server done A";
- break;
+ return "SSLv3 read server done A";
case SSL3_ST_CR_SRVR_DONE_B:
- str = "SSLv3 read server done B";
- break;
+ return "SSLv3 read server done B";
case SSL3_ST_CW_CERT_A:
- str = "SSLv3 write client certificate A";
- break;
+ return "SSLv3 write client certificate A";
case SSL3_ST_CW_CERT_B:
- str = "SSLv3 write client certificate B";
- break;
+ return "SSLv3 write client certificate B";
case SSL3_ST_CW_CERT_C:
- str = "SSLv3 write client certificate C";
- break;
+ return "SSLv3 write client certificate C";
case SSL3_ST_CW_CERT_D:
- str = "SSLv3 write client certificate D";
- break;
+ return "SSLv3 write client certificate D";
case SSL3_ST_CW_KEY_EXCH_A:
- str = "SSLv3 write client key exchange A";
- break;
+ return "SSLv3 write client key exchange A";
case SSL3_ST_CW_KEY_EXCH_B:
- str = "SSLv3 write client key exchange B";
- break;
+ return "SSLv3 write client key exchange B";
case SSL3_ST_CW_CERT_VRFY_A:
- str = "SSLv3 write certificate verify A";
- break;
+ return "SSLv3 write certificate verify A";
case SSL3_ST_CW_CERT_VRFY_B:
- str = "SSLv3 write certificate verify B";
- break;
+ return "SSLv3 write certificate verify B";
case SSL3_ST_CW_CHANGE_A:
case SSL3_ST_SW_CHANGE_A:
- str = "SSLv3 write change cipher spec A";
- break;
+ return "SSLv3 write change cipher spec A";
case SSL3_ST_CW_CHANGE_B:
case SSL3_ST_SW_CHANGE_B:
- str = "SSLv3 write change cipher spec B";
- break;
+ return "SSLv3 write change cipher spec B";
case SSL3_ST_CW_FINISHED_A:
case SSL3_ST_SW_FINISHED_A:
- str = "SSLv3 write finished A";
- break;
+ return "SSLv3 write finished A";
case SSL3_ST_CW_FINISHED_B:
case SSL3_ST_SW_FINISHED_B:
- str = "SSLv3 write finished B";
- break;
+ return "SSLv3 write finished B";
case SSL3_ST_CR_CHANGE:
case SSL3_ST_SR_CHANGE:
- str = "SSLv3 read change cipher spec";
- break;
+ return "SSLv3 read change cipher spec";
case SSL3_ST_CR_FINISHED_A:
case SSL3_ST_SR_FINISHED_A:
- str = "SSLv3 read finished A";
- break;
+ return "SSLv3 read finished A";
case SSL3_ST_CR_FINISHED_B:
case SSL3_ST_SR_FINISHED_B:
- str = "SSLv3 read finished B";
- break;
+ return "SSLv3 read finished B";
case SSL3_ST_CW_FLUSH:
case SSL3_ST_SW_FLUSH:
- str = "SSLv3 flush data";
- break;
+ return "SSLv3 flush data";
case SSL3_ST_SR_CLNT_HELLO_A:
- str = "SSLv3 read client hello A";
- break;
+ return "SSLv3 read client hello A";
case SSL3_ST_SR_CLNT_HELLO_B:
- str = "SSLv3 read client hello B";
- break;
+ return "SSLv3 read client hello B";
case SSL3_ST_SR_CLNT_HELLO_C:
- str = "SSLv3 read client hello C";
- break;
+ return "SSLv3 read client hello C";
case SSL3_ST_SR_CLNT_HELLO_D:
- str = "SSLv3 read client hello D";
- break;
+ return "SSLv3 read client hello D";
case SSL3_ST_SW_HELLO_REQ_A:
- str = "SSLv3 write hello request A";
- break;
+ return "SSLv3 write hello request A";
case SSL3_ST_SW_HELLO_REQ_B:
- str = "SSLv3 write hello request B";
- break;
+ return "SSLv3 write hello request B";
case SSL3_ST_SW_HELLO_REQ_C:
- str = "SSLv3 write hello request C";
- break;
+ return "SSLv3 write hello request C";
case SSL3_ST_SW_SRVR_HELLO_A:
- str = "SSLv3 write server hello A";
- break;
+ return "SSLv3 write server hello A";
case SSL3_ST_SW_SRVR_HELLO_B:
- str = "SSLv3 write server hello B";
- break;
+ return "SSLv3 write server hello B";
case SSL3_ST_SW_CERT_A:
- str = "SSLv3 write certificate A";
- break;
+ return "SSLv3 write certificate A";
case SSL3_ST_SW_CERT_B:
- str = "SSLv3 write certificate B";
- break;
+ return "SSLv3 write certificate B";
case SSL3_ST_SW_KEY_EXCH_A:
- str = "SSLv3 write key exchange A";
- break;
+ return "SSLv3 write key exchange A";
case SSL3_ST_SW_KEY_EXCH_B:
- str = "SSLv3 write key exchange B";
- break;
+ return "SSLv3 write key exchange B";
case SSL3_ST_SW_CERT_REQ_A:
- str = "SSLv3 write certificate request A";
- break;
+ return "SSLv3 write certificate request A";
case SSL3_ST_SW_CERT_REQ_B:
- str = "SSLv3 write certificate request B";
- break;
+ return "SSLv3 write certificate request B";
case SSL3_ST_SW_SESSION_TICKET_A:
- str = "SSLv3 write session ticket A";
- break;
+ return "SSLv3 write session ticket A";
case SSL3_ST_SW_SESSION_TICKET_B:
- str = "SSLv3 write session ticket B";
- break;
+ return "SSLv3 write session ticket B";
case SSL3_ST_SW_SRVR_DONE_A:
- str = "SSLv3 write server done A";
- break;
+ return "SSLv3 write server done A";
case SSL3_ST_SW_SRVR_DONE_B:
- str = "SSLv3 write server done B";
- break;
+ return "SSLv3 write server done B";
case SSL3_ST_SR_CERT_A:
- str = "SSLv3 read client certificate A";
- break;
+ return "SSLv3 read client certificate A";
case SSL3_ST_SR_CERT_B:
- str = "SSLv3 read client certificate B";
- break;
+ return "SSLv3 read client certificate B";
case SSL3_ST_SR_KEY_EXCH_A:
- str = "SSLv3 read client key exchange A";
- break;
+ return "SSLv3 read client key exchange A";
case SSL3_ST_SR_KEY_EXCH_B:
- str = "SSLv3 read client key exchange B";
- break;
+ return "SSLv3 read client key exchange B";
case SSL3_ST_SR_CERT_VRFY_A:
- str = "SSLv3 read certificate verify A";
- break;
+ return "SSLv3 read certificate verify A";
case SSL3_ST_SR_CERT_VRFY_B:
- str = "SSLv3 read certificate verify B";
- break;
-
- /* SSLv2/v3 compatibility states */
- /* client */
- case SSL23_ST_CW_CLNT_HELLO_A:
- str = "SSLv2/v3 write client hello A";
- break;
-
- case SSL23_ST_CW_CLNT_HELLO_B:
- str = "SSLv2/v3 write client hello B";
- break;
-
- case SSL23_ST_CR_SRVR_HELLO_A:
- str = "SSLv2/v3 read server hello A";
- break;
-
- case SSL23_ST_CR_SRVR_HELLO_B:
- str = "SSLv2/v3 read server hello B";
- break;
-
- /* server */
- case SSL23_ST_SR_CLNT_HELLO:
- str = "SSLv2/v3 read client hello";
- break;
-
- case SSL23_ST_SR_V2_CLNT_HELLO:
- str = "SSLv2/v3 read v2 client hello";
- break;
-
- case SSL23_ST_SR_SWITCH_VERSION:
- str = "SSLv2/v3 switch version";
- break;
+ return "SSLv3 read certificate verify B";
/* DTLS */
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A:
- str = "DTLS1 read hello verify request A";
- break;
+ return "DTLS1 read hello verify request A";
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B:
- str = "DTLS1 read hello verify request B";
- break;
+ return "DTLS1 read hello verify request B";
default:
- str = "unknown state";
- break;
+ return "unknown state";
}
-
- return str;
}
-const char *SSL_rstate_string_long(const SSL *s) {
- const char *str;
-
- switch (s->rstate) {
- case SSL_ST_READ_HEADER:
- str = "read header";
- break;
-
- case SSL_ST_READ_BODY:
- str = "read body";
- break;
-
- case SSL_ST_READ_DONE:
- str = "read done";
- break;
-
- default:
- str = "unknown";
- break;
- }
-
- return str;
-}
-
-const char *SSL_state_string(const SSL *s) {
- const char *str;
-
- switch (s->state) {
+const char *SSL_state_string(const SSL *ssl) {
+ switch (ssl->state) {
case SSL_ST_ACCEPT:
- str = "AINIT ";
- break;
+ return "AINIT ";
case SSL_ST_CONNECT:
- str = "CINIT ";
- break;
+ return "CINIT ";
case SSL_ST_OK:
- str = "SSLOK ";
- break;
+ return "SSLOK ";
/* SSLv3 additions */
case SSL3_ST_SW_FLUSH:
case SSL3_ST_CW_FLUSH:
- str = "3FLUSH";
- break;
+ return "3FLUSH";
case SSL3_ST_CW_CLNT_HELLO_A:
- str = "3WCH_A";
- break;
+ return "3WCH_A";
case SSL3_ST_CW_CLNT_HELLO_B:
- str = "3WCH_B";
- break;
+ return "3WCH_B";
case SSL3_ST_CR_SRVR_HELLO_A:
- str = "3RSH_A";
- break;
+ return "3RSH_A";
case SSL3_ST_CR_SRVR_HELLO_B:
- str = "3RSH_B";
- break;
+ return "3RSH_B";
case SSL3_ST_CR_CERT_A:
- str = "3RSC_A";
- break;
+ return "3RSC_A";
case SSL3_ST_CR_CERT_B:
- str = "3RSC_B";
- break;
+ return "3RSC_B";
case SSL3_ST_CR_KEY_EXCH_A:
- str = "3RSKEA";
- break;
+ return "3RSKEA";
case SSL3_ST_CR_KEY_EXCH_B:
- str = "3RSKEB";
- break;
+ return "3RSKEB";
case SSL3_ST_CR_CERT_REQ_A:
- str = "3RCR_A";
- break;
+ return "3RCR_A";
case SSL3_ST_CR_CERT_REQ_B:
- str = "3RCR_B";
- break;
+ return "3RCR_B";
case SSL3_ST_CR_SRVR_DONE_A:
- str = "3RSD_A";
- break;
+ return "3RSD_A";
case SSL3_ST_CR_SRVR_DONE_B:
- str = "3RSD_B";
- break;
+ return "3RSD_B";
case SSL3_ST_CW_CERT_A:
- str = "3WCC_A";
- break;
+ return "3WCC_A";
case SSL3_ST_CW_CERT_B:
- str = "3WCC_B";
- break;
+ return "3WCC_B";
case SSL3_ST_CW_CERT_C:
- str = "3WCC_C";
- break;
+ return "3WCC_C";
case SSL3_ST_CW_CERT_D:
- str = "3WCC_D";
- break;
+ return "3WCC_D";
case SSL3_ST_CW_KEY_EXCH_A:
- str = "3WCKEA";
- break;
+ return "3WCKEA";
case SSL3_ST_CW_KEY_EXCH_B:
- str = "3WCKEB";
- break;
+ return "3WCKEB";
case SSL3_ST_CW_CERT_VRFY_A:
- str = "3WCV_A";
- break;
+ return "3WCV_A";
case SSL3_ST_CW_CERT_VRFY_B:
- str = "3WCV_B";
- break;
+ return "3WCV_B";
case SSL3_ST_SW_CHANGE_A:
case SSL3_ST_CW_CHANGE_A:
- str = "3WCCSA";
- break;
+ return "3WCCSA";
case SSL3_ST_SW_CHANGE_B:
case SSL3_ST_CW_CHANGE_B:
- str = "3WCCSB";
- break;
+ return "3WCCSB";
case SSL3_ST_SW_FINISHED_A:
case SSL3_ST_CW_FINISHED_A:
- str = "3WFINA";
- break;
+ return "3WFINA";
case SSL3_ST_SW_FINISHED_B:
case SSL3_ST_CW_FINISHED_B:
- str = "3WFINB";
- break;
+ return "3WFINB";
case SSL3_ST_CR_CHANGE:
case SSL3_ST_SR_CHANGE:
- str = "3RCCS_";
- break;
+ return "3RCCS_";
case SSL3_ST_SR_FINISHED_A:
case SSL3_ST_CR_FINISHED_A:
- str = "3RFINA";
- break;
+ return "3RFINA";
case SSL3_ST_SR_FINISHED_B:
case SSL3_ST_CR_FINISHED_B:
- str = "3RFINB";
- break;
+ return "3RFINB";
case SSL3_ST_SW_HELLO_REQ_A:
- str = "3WHR_A";
- break;
+ return "3WHR_A";
case SSL3_ST_SW_HELLO_REQ_B:
- str = "3WHR_B";
- break;
+ return "3WHR_B";
case SSL3_ST_SW_HELLO_REQ_C:
- str = "3WHR_C";
- break;
+ return "3WHR_C";
case SSL3_ST_SR_CLNT_HELLO_A:
- str = "3RCH_A";
- break;
+ return "3RCH_A";
case SSL3_ST_SR_CLNT_HELLO_B:
- str = "3RCH_B";
- break;
+ return "3RCH_B";
case SSL3_ST_SR_CLNT_HELLO_C:
- str = "3RCH_C";
- break;
+ return "3RCH_C";
case SSL3_ST_SR_CLNT_HELLO_D:
- str = "3RCH_D";
- break;
+ return "3RCH_D";
case SSL3_ST_SW_SRVR_HELLO_A:
- str = "3WSH_A";
- break;
+ return "3WSH_A";
case SSL3_ST_SW_SRVR_HELLO_B:
- str = "3WSH_B";
- break;
+ return "3WSH_B";
case SSL3_ST_SW_CERT_A:
- str = "3WSC_A";
- break;
+ return "3WSC_A";
case SSL3_ST_SW_CERT_B:
- str = "3WSC_B";
- break;
+ return "3WSC_B";
case SSL3_ST_SW_KEY_EXCH_A:
- str = "3WSKEA";
- break;
+ return "3WSKEA";
case SSL3_ST_SW_KEY_EXCH_B:
- str = "3WSKEB";
- break;
+ return "3WSKEB";
case SSL3_ST_SW_CERT_REQ_A:
- str = "3WCR_A";
- break;
+ return "3WCR_A";
case SSL3_ST_SW_CERT_REQ_B:
- str = "3WCR_B";
- break;
+ return "3WCR_B";
case SSL3_ST_SW_SRVR_DONE_A:
- str = "3WSD_A";
- break;
+ return "3WSD_A";
case SSL3_ST_SW_SRVR_DONE_B:
- str = "3WSD_B";
- break;
+ return "3WSD_B";
case SSL3_ST_SR_CERT_A:
- str = "3RCC_A";
- break;
+ return "3RCC_A";
case SSL3_ST_SR_CERT_B:
- str = "3RCC_B";
- break;
+ return "3RCC_B";
case SSL3_ST_SR_KEY_EXCH_A:
- str = "3RCKEA";
- break;
+ return "3RCKEA";
case SSL3_ST_SR_KEY_EXCH_B:
- str = "3RCKEB";
- break;
+ return "3RCKEB";
case SSL3_ST_SR_CERT_VRFY_A:
- str = "3RCV_A";
- break;
+ return "3RCV_A";
case SSL3_ST_SR_CERT_VRFY_B:
- str = "3RCV_B";
- break;
-
- /* SSLv2/v3 compatibility states */
- /* client */
- case SSL23_ST_CW_CLNT_HELLO_A:
- str = "23WCHA";
- break;
-
- case SSL23_ST_CW_CLNT_HELLO_B:
- str = "23WCHB";
- break;
-
- case SSL23_ST_CR_SRVR_HELLO_A:
- str = "23RSHA";
- break;
-
- case SSL23_ST_CR_SRVR_HELLO_B:
- str = "23RSHA";
- break;
-
- /* server */
- case SSL23_ST_SR_CLNT_HELLO:
- str = "23RCH_";
- break;
-
- case SSL23_ST_SR_V2_CLNT_HELLO:
- str = "23R2CH";
- break;
-
- case SSL23_ST_SR_SWITCH_VERSION:
- str = "23RSW_";
- break;
+ return "3RCV_B";
/* DTLS */
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A:
- str = "DRCHVA";
- break;
+ return "DRCHVA";
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B:
- str = "DRCHVB";
- break;
+ return "DRCHVB";
default:
- str = "UNKWN ";
- break;
+ return "UNKWN ";
}
-
- return str;
}
const char *SSL_alert_type_string_long(int value) {
@@ -695,300 +483,109 @@ const char *SSL_alert_type_string_long(int value) {
}
const char *SSL_alert_type_string(int value) {
- value >>= 8;
- if (value == SSL3_AL_WARNING) {
- return "W";
- } else if (value == SSL3_AL_FATAL) {
- return "F";
- }
-
- return "U";
+ return "!";
}
const char *SSL_alert_desc_string(int value) {
- const char *str;
-
- switch (value & 0xff) {
- case SSL3_AD_CLOSE_NOTIFY:
- str = "CN";
- break;
-
- case SSL3_AD_UNEXPECTED_MESSAGE:
- str = "UM";
- break;
-
- case SSL3_AD_BAD_RECORD_MAC:
- str = "BM";
- break;
-
- case SSL3_AD_DECOMPRESSION_FAILURE:
- str = "DF";
- break;
-
- case SSL3_AD_HANDSHAKE_FAILURE:
- str = "HF";
- break;
-
- case SSL3_AD_NO_CERTIFICATE:
- str = "NC";
- break;
-
- case SSL3_AD_BAD_CERTIFICATE:
- str = "BC";
- break;
-
- case SSL3_AD_UNSUPPORTED_CERTIFICATE:
- str = "UC";
- break;
-
- case SSL3_AD_CERTIFICATE_REVOKED:
- str = "CR";
- break;
-
- case SSL3_AD_CERTIFICATE_EXPIRED:
- str = "CE";
- break;
-
- case SSL3_AD_CERTIFICATE_UNKNOWN:
- str = "CU";
- break;
-
- case SSL3_AD_ILLEGAL_PARAMETER:
- str = "IP";
- break;
-
- case TLS1_AD_DECRYPTION_FAILED:
- str = "DC";
- break;
-
- case TLS1_AD_RECORD_OVERFLOW:
- str = "RO";
- break;
-
- case TLS1_AD_UNKNOWN_CA:
- str = "CA";
- break;
-
- case TLS1_AD_ACCESS_DENIED:
- str = "AD";
- break;
-
- case TLS1_AD_DECODE_ERROR:
- str = "DE";
- break;
-
- case TLS1_AD_DECRYPT_ERROR:
- str = "CY";
- break;
-
- case TLS1_AD_EXPORT_RESTRICTION:
- str = "ER";
- break;
-
- case TLS1_AD_PROTOCOL_VERSION:
- str = "PV";
- break;
-
- case TLS1_AD_INSUFFICIENT_SECURITY:
- str = "IS";
- break;
-
- case TLS1_AD_INTERNAL_ERROR:
- str = "IE";
- break;
-
- case TLS1_AD_USER_CANCELLED:
- str = "US";
- break;
-
- case TLS1_AD_NO_RENEGOTIATION:
- str = "NR";
- break;
-
- case TLS1_AD_UNSUPPORTED_EXTENSION:
- str = "UE";
- break;
-
- case TLS1_AD_CERTIFICATE_UNOBTAINABLE:
- str = "CO";
- break;
-
- case TLS1_AD_UNRECOGNIZED_NAME:
- str = "UN";
- break;
-
- case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
- str = "BR";
- break;
-
- case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE:
- str = "BH";
- break;
-
- case TLS1_AD_UNKNOWN_PSK_IDENTITY:
- str = "UP";
- break;
-
- default:
- str = "UK";
- break;
- }
-
- return str;
+ return "!!";
}
const char *SSL_alert_desc_string_long(int value) {
- const char *str;
-
switch (value & 0xff) {
case SSL3_AD_CLOSE_NOTIFY:
- str = "close notify";
- break;
+ return "close notify";
case SSL3_AD_UNEXPECTED_MESSAGE:
- str = "unexpected_message";
- break;
+ return "unexpected_message";
case SSL3_AD_BAD_RECORD_MAC:
- str = "bad record mac";
- break;
+ return "bad record mac";
case SSL3_AD_DECOMPRESSION_FAILURE:
- str = "decompression failure";
- break;
+ return "decompression failure";
case SSL3_AD_HANDSHAKE_FAILURE:
- str = "handshake failure";
- break;
+ return "handshake failure";
case SSL3_AD_NO_CERTIFICATE:
- str = "no certificate";
- break;
+ return "no certificate";
case SSL3_AD_BAD_CERTIFICATE:
- str = "bad certificate";
- break;
+ return "bad certificate";
case SSL3_AD_UNSUPPORTED_CERTIFICATE:
- str = "unsupported certificate";
- break;
+ return "unsupported certificate";
case SSL3_AD_CERTIFICATE_REVOKED:
- str = "certificate revoked";
- break;
+ return "certificate revoked";
case SSL3_AD_CERTIFICATE_EXPIRED:
- str = "certificate expired";
- break;
+ return "certificate expired";
case SSL3_AD_CERTIFICATE_UNKNOWN:
- str = "certificate unknown";
- break;
+ return "certificate unknown";
case SSL3_AD_ILLEGAL_PARAMETER:
- str = "illegal parameter";
- break;
+ return "illegal parameter";
case TLS1_AD_DECRYPTION_FAILED:
- str = "decryption failed";
- break;
+ return "decryption failed";
case TLS1_AD_RECORD_OVERFLOW:
- str = "record overflow";
- break;
+ return "record overflow";
case TLS1_AD_UNKNOWN_CA:
- str = "unknown CA";
- break;
+ return "unknown CA";
case TLS1_AD_ACCESS_DENIED:
- str = "access denied";
- break;
+ return "access denied";
case TLS1_AD_DECODE_ERROR:
- str = "decode error";
- break;
+ return "decode error";
case TLS1_AD_DECRYPT_ERROR:
- str = "decrypt error";
- break;
+ return "decrypt error";
case TLS1_AD_EXPORT_RESTRICTION:
- str = "export restriction";
- break;
+ return "export restriction";
case TLS1_AD_PROTOCOL_VERSION:
- str = "protocol version";
- break;
+ return "protocol version";
case TLS1_AD_INSUFFICIENT_SECURITY:
- str = "insufficient security";
- break;
+ return "insufficient security";
case TLS1_AD_INTERNAL_ERROR:
- str = "internal error";
- break;
+ return "internal error";
case TLS1_AD_USER_CANCELLED:
- str = "user canceled";
- break;
+ return "user canceled";
case TLS1_AD_NO_RENEGOTIATION:
- str = "no renegotiation";
- break;
+ return "no renegotiation";
case TLS1_AD_UNSUPPORTED_EXTENSION:
- str = "unsupported extension";
- break;
+ return "unsupported extension";
case TLS1_AD_CERTIFICATE_UNOBTAINABLE:
- str = "certificate unobtainable";
- break;
+ return "certificate unobtainable";
case TLS1_AD_UNRECOGNIZED_NAME:
- str = "unrecognized name";
- break;
+ return "unrecognized name";
case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
- str = "bad certificate status response";
- break;
+ return "bad certificate status response";
case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE:
- str = "bad certificate hash value";
- break;
+ return "bad certificate hash value";
case TLS1_AD_UNKNOWN_PSK_IDENTITY:
- str = "unknown PSK identity";
- break;
+ return "unknown PSK identity";
- default:
- str = "unknown";
- break;
- }
-
- return str;
-}
-
-const char *SSL_rstate_string(const SSL *s) {
- const char *str;
-
- switch (s->rstate) {
- case SSL_ST_READ_HEADER:
- str = "RH";
- break;
-
- case SSL_ST_READ_BODY:
- str = "RB";
- break;
-
- case SSL_ST_READ_DONE:
- str = "RD";
- break;
+ case SSL3_AD_INAPPROPRIATE_FALLBACK:
+ return "inappropriate fallback";
default:
- str = "unknown";
- break;
+ return "unknown";
}
-
- return str;
}
diff --git a/src/ssl/ssl_test.cc b/src/ssl/ssl_test.cc
index 1c6e24a..9558f1c 100644
--- a/src/ssl/ssl_test.cc
+++ b/src/ssl/ssl_test.cc
@@ -14,16 +14,21 @@
#include <stdio.h>
#include <string.h>
+#include <time.h>
+#include <algorithm>
#include <string>
#include <vector>
#include <openssl/base64.h>
#include <openssl/bio.h>
+#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
#include "test/scoped_types.h"
+#include "../crypto/test/test_util.h"
+
struct ExpectedCipher {
unsigned long id;
@@ -45,8 +50,10 @@ static const char kRule1[] =
"ECDHE-RSA-AES128-GCM-SHA256";
static const ExpectedCipher kExpected1[] = {
- { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, 0 },
- { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, 0 },
+ { 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 },
{ 0, 0 },
@@ -62,9 +69,11 @@ static const char kRule2[] =
"+aRSA";
static const ExpectedCipher kExpected2[] = {
- { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, 0 },
+ { 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_CHACHA20_POLY1305, 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 },
};
@@ -78,7 +87,8 @@ static const char kRule3[] =
"ECDHE-RSA-AES128-GCM-SHA256";
static const ExpectedCipher kExpected3[] = {
- { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, 0 },
+ { 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 },
};
@@ -114,8 +124,10 @@ static const char kRule6[] =
"BOGUS1:-BOGUS2:+BOGUS3:!BOGUS4";
static const ExpectedCipher kExpected6[] = {
- { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, 0 },
- { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, 0 },
+ { 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 },
{ 0, 0 },
@@ -128,9 +140,11 @@ static const char kRule7[] =
"ECDHE-RSA-AES128-GCM-SHA256";
static const ExpectedCipher kExpected7[] = {
- { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, 1 },
+ { 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_CHACHA20_POLY1305, 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 },
};
@@ -152,7 +166,8 @@ static const char kRule8[] =
static const ExpectedCipher kExpected8[] = {
{ TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0 },
- { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, 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 },
{ SSL3_CK_RSA_RC4_128_SHA, 0 },
@@ -164,14 +179,56 @@ 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[] = {
- { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, 0 },
- { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, 0 },
+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 },
};
@@ -185,6 +242,10 @@ static CipherTest kCipherTests[] = {
{ kRule7, kExpected7 },
{ kRule8, kExpected8 },
{ kRule9, kExpected9 },
+ { kRule10, kExpected10 },
+ { kRule11, kExpected11 },
+ { kRule12, kExpected12 },
+ { kRule13, kExpected13 },
{ NULL, NULL },
};
@@ -212,6 +273,23 @@ static const char *kBadRules[] = {
NULL,
};
+static const char *kMustNotIncludeNull[] = {
+ "ALL",
+ "DEFAULT",
+ "ALL:!eNULL",
+ "ALL:!NULL",
+ "MEDIUM",
+ "HIGH",
+ "FIPS",
+ "SHA",
+ "SHA1",
+ "RSA",
+ "SSLv3",
+ "TLSv1",
+ "TLSv1.2",
+ NULL
+};
+
static void PrintCipherPreferenceList(ssl_cipher_preference_list_st *list) {
bool in_group = false;
for (size_t i = 0; i < sk_SSL_CIPHER_num(list->ciphers); i++) {
@@ -265,6 +343,24 @@ static bool TestCipherRule(CipherTest *t) {
return true;
}
+static bool TestRuleDoesNotIncludeNull(const char *rule) {
+ ScopedSSL_CTX ctx(SSL_CTX_new(SSLv23_server_method()));
+ if (!ctx) {
+ return false;
+ }
+ if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
+ fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
+ return false;
+ }
+ for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
+ if (SSL_CIPHER_is_NULL(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
+ fprintf(stderr, "Error: cipher rule '%s' includes NULL\n",rule);
+ return false;
+ }
+ }
+ return true;
+}
+
static bool TestCipherRules() {
for (size_t i = 0; kCipherTests[i].rule != NULL; i++) {
if (!TestCipherRule(&kCipherTests[i])) {
@@ -284,6 +380,12 @@ static bool TestCipherRules() {
ERR_clear_error();
}
+ for (size_t i = 0; kMustNotIncludeNull[i] != NULL; i++) {
+ if (!TestRuleDoesNotIncludeNull(kMustNotIncludeNull[i])) {
+ return false;
+ }
+ }
+
return true;
}
@@ -335,6 +437,104 @@ static const char kCustomSession[] =
"q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
"BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
+// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
+static const char kBoringSSLSession[] =
+ "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
+ "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
+ "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
+ "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
+ "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
+ "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
+ "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
+ "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
+ "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
+ "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
+ "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
+ "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
+ "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
+ "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
+ "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
+ "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
+ "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
+ "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
+ "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
+ "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
+ "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
+ "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
+ "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
+ "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
+ "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
+ "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
+ "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
+ "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
+ "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
+ "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
+ "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
+ "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
+ "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
+ "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
+ "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
+ "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
+ "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
+ "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
+ "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
+ "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
+ "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
+ "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
+ "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
+ "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
+ "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
+ "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
+ "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
+ "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
+ "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
+ "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
+ "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
+ "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
+ "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
+ "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
+ "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
+ "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
+ "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
+ "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
+ "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
+ "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
+ "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
+ "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
+ "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
+ "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
+ "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
+ "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
+ "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
+ "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
+ "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
+ "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
+ "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
+ "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
+ "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
+ "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
+ "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
+ "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
+ "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
+ "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
+ "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
+ "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
+ "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
+ "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
+ "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
+ "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
+ "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
+ "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
+ "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
+ "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
+ "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
+ "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
+ "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
+ "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
+ "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
+ "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
+ "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
+
// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
// the final (optional) element of |kCustomSession| with tag number 30.
static const char kBadSessionExtraField[] =
@@ -359,6 +559,18 @@ static const char kBadSessionVersion[] =
"q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
"BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
+// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
+// appended.
+static const char kBadSessionTrailingData[] =
+ "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
+ "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
+ "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
+ "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
+ "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
+ "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
+ "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
+ "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
+
static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
size_t len;
if (!EVP_DecodedLength(&len, strlen(in))) {
@@ -367,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;
@@ -387,10 +599,9 @@ static bool TestSSL_SESSIONEncoding(const char *input_b64) {
}
// Verify the SSL_SESSION decodes.
- cptr = bssl::vector_data(&input);
- ScopedSSL_SESSION session(d2i_SSL_SESSION(NULL, &cptr, input.size()));
- if (!session || cptr != bssl::vector_data(&input) + input.size()) {
- fprintf(stderr, "d2i_SSL_SESSION failed\n");
+ ScopedSSL_SESSION session(SSL_SESSION_from_bytes(input.data(), input.size()));
+ if (!session) {
+ fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
return false;
}
@@ -404,8 +615,18 @@ 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);
+ return false;
+ }
+
+ // Verify the SSL_SESSION also decodes with the legacy API.
+ cptr = input.data();
+ session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
+ if (!session || cptr != input.data() + input.size()) {
+ fprintf(stderr, "d2i_SSL_SESSION failed\n");
return false;
}
@@ -432,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;
}
@@ -447,10 +668,9 @@ static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
}
// Verify that the SSL_SESSION fails to decode.
- const uint8_t *ptr = bssl::vector_data(&input);
- ScopedSSL_SESSION session(d2i_SSL_SESSION(NULL, &ptr, input.size()));
+ ScopedSSL_SESSION session(SSL_SESSION_from_bytes(input.data(), input.size()));
if (session) {
- fprintf(stderr, "d2i_SSL_SESSION unexpectedly succeeded\n");
+ fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
return false;
}
ERR_clear_error();
@@ -504,10 +724,12 @@ 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,
+ { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD,
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
- { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305,
+ { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD,
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" },
};
@@ -529,14 +751,297 @@ static bool TestCipherGetRFCName(void) {
return true;
}
-int main(void) {
- SSL_library_init();
+// CreateSessionWithTicket returns a sample |SSL_SESSION| with the ticket
+// replaced for one of length |ticket_len| or nullptr on failure.
+static ScopedSSL_SESSION CreateSessionWithTicket(size_t ticket_len) {
+ std::vector<uint8_t> der;
+ if (!DecodeBase64(&der, kOpenSSLSession)) {
+ return nullptr;
+ }
+ ScopedSSL_SESSION session(SSL_SESSION_from_bytes(der.data(), der.size()));
+ if (!session) {
+ return nullptr;
+ }
+
+ // Swap out the ticket for a garbage one.
+ OPENSSL_free(session->tlsext_tick);
+ session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
+ if (session->tlsext_tick == nullptr) {
+ return nullptr;
+ }
+ memset(session->tlsext_tick, 'a', ticket_len);
+ session->tlsext_ticklen = ticket_len;
+
+ // Fix up the timeout.
+ session->time = time(NULL);
+ return session;
+}
+
+// GetClientHelloLen creates a client SSL connection with a ticket of length
+// |ticket_len| and records the ClientHello. It returns the length of the
+// ClientHello, not including the record header, on success and zero on error.
+static size_t GetClientHelloLen(size_t ticket_len) {
+ ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+ ScopedSSL_SESSION session = CreateSessionWithTicket(ticket_len);
+ if (!ctx || !session) {
+ return 0;
+ }
+ ScopedSSL ssl(SSL_new(ctx.get()));
+ ScopedBIO bio(BIO_new(BIO_s_mem()));
+ if (!ssl || !bio || !SSL_set_session(ssl.get(), session.get())) {
+ return 0;
+ }
+ // Do not configure a reading BIO, but record what's written to a memory BIO.
+ SSL_set_bio(ssl.get(), nullptr /* rbio */, BIO_up_ref(bio.get()));
+ int ret = SSL_connect(ssl.get());
+ if (ret > 0) {
+ // SSL_connect should fail without a BIO to write to.
+ return 0;
+ }
+ ERR_clear_error();
+
+ const uint8_t *unused;
+ size_t client_hello_len;
+ if (!BIO_mem_contents(bio.get(), &unused, &client_hello_len) ||
+ client_hello_len <= SSL3_RT_HEADER_LENGTH) {
+ return 0;
+ }
+ return client_hello_len - SSL3_RT_HEADER_LENGTH;
+}
+
+struct PaddingTest {
+ size_t input_len, padded_len;
+};
+
+static const PaddingTest kPaddingTests[] = {
+ // ClientHellos of length below 0x100 do not require padding.
+ {0xfe, 0xfe},
+ {0xff, 0xff},
+ // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
+ {0x100, 0x200},
+ {0x123, 0x200},
+ {0x1fb, 0x200},
+ // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
+ // padding extension takes a minimum of four bytes plus one required content
+ // byte. (To work around yet more server bugs, we avoid empty final
+ // extensions.)
+ {0x1fc, 0x201},
+ {0x1fd, 0x202},
+ {0x1fe, 0x203},
+ {0x1ff, 0x204},
+ // Finally, larger ClientHellos need no padding.
+ {0x200, 0x200},
+ {0x201, 0x201},
+};
+
+static bool TestPaddingExtension() {
+ // Sample a baseline length.
+ size_t base_len = GetClientHelloLen(1);
+ if (base_len == 0) {
+ return false;
+ }
+
+ for (const PaddingTest &test : kPaddingTests) {
+ if (base_len > test.input_len) {
+ fprintf(stderr, "Baseline ClientHello too long.\n");
+ return false;
+ }
+
+ size_t padded_len = GetClientHelloLen(1 + test.input_len - base_len);
+ if (padded_len != test.padded_len) {
+ fprintf(stderr, "%u-byte ClientHello padded to %u bytes, not %u.\n",
+ static_cast<unsigned>(test.input_len),
+ static_cast<unsigned>(padded_len),
+ static_cast<unsigned>(test.padded_len));
+ return false;
+ }
+ }
+ return true;
+}
+
+// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
+// before configuring as a server.
+static bool TestClientCAList() {
+ ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+ if (!ctx) {
+ return false;
+ }
+ ScopedSSL ssl(SSL_new(ctx.get()));
+ if (!ssl) {
+ return false;
+ }
+
+ STACK_OF(X509_NAME) *stack = sk_X509_NAME_new_null();
+ if (stack == nullptr) {
+ return false;
+ }
+ // |SSL_set_client_CA_list| takes ownership.
+ SSL_set_client_CA_list(ssl.get(), stack);
+
+ return SSL_get_client_CA_list(ssl.get()) == stack;
+}
+
+static void AppendSession(SSL_SESSION *session, void *arg) {
+ std::vector<SSL_SESSION*> *out =
+ reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
+ out->push_back(session);
+}
+
+// ExpectCache returns true if |ctx|'s session cache consists of |expected|, in
+// order.
+static bool ExpectCache(SSL_CTX *ctx,
+ const std::vector<SSL_SESSION*> &expected) {
+ // Check the linked list.
+ SSL_SESSION *ptr = ctx->session_cache_head;
+ for (SSL_SESSION *session : expected) {
+ if (ptr != session) {
+ return false;
+ }
+ // TODO(davidben): This is an absurd way to denote the end of the list.
+ if (ptr->next ==
+ reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
+ ptr = nullptr;
+ } else {
+ ptr = ptr->next;
+ }
+ }
+ if (ptr != nullptr) {
+ return false;
+ }
+
+ // Check the hash table.
+ std::vector<SSL_SESSION*> actual, expected_copy;
+ lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual);
+ expected_copy = expected;
+
+ std::sort(actual.begin(), actual.end());
+ std::sort(expected_copy.begin(), expected_copy.end());
+
+ return actual == expected_copy;
+}
+
+static ScopedSSL_SESSION CreateTestSession(uint32_t number) {
+ ScopedSSL_SESSION ret(SSL_SESSION_new());
+ if (!ret) {
+ return nullptr;
+ }
+
+ ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
+ memset(ret->session_id, 0, ret->session_id_length);
+ memcpy(ret->session_id, &number, sizeof(number));
+ return ret;
+}
+
+// TODO(davidben): Switch this to a |std::vector<ScopedSSL_SESSION>| once we can
+// rely on a move-aware |std::vector|.
+class ScopedSessionVector {
+ public:
+ explicit ScopedSessionVector(std::vector<SSL_SESSION*> *sessions)
+ : sessions_(sessions) {}
+
+ ~ScopedSessionVector() {
+ for (SSL_SESSION *session : *sessions_) {
+ SSL_SESSION_free(session);
+ }
+ }
+
+ private:
+ std::vector<SSL_SESSION*> *const sessions_;
+};
+
+// Test that the internal session cache behaves as expected.
+static bool TestInternalSessionCache() {
+ ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+ if (!ctx) {
+ return false;
+ }
+
+ // Prepare 10 test sessions.
+ std::vector<SSL_SESSION*> sessions;
+ ScopedSessionVector cleanup(&sessions);
+ for (int i = 0; i < 10; i++) {
+ ScopedSSL_SESSION session = CreateTestSession(i);
+ if (!session) {
+ return false;
+ }
+ sessions.push_back(session.release());
+ }
+
+ SSL_CTX_sess_set_cache_size(ctx.get(), 5);
+
+ // Insert all the test sessions.
+ for (SSL_SESSION *session : sessions) {
+ if (!SSL_CTX_add_session(ctx.get(), session)) {
+ return false;
+ }
+ }
+
+ // Only the last five should be in the list.
+ std::vector<SSL_SESSION*> expected;
+ expected.push_back(sessions[9]);
+ expected.push_back(sessions[8]);
+ expected.push_back(sessions[7]);
+ expected.push_back(sessions[6]);
+ expected.push_back(sessions[5]);
+ if (!ExpectCache(ctx.get(), expected)) {
+ return false;
+ }
+
+ // Inserting an element already in the cache should fail.
+ if (SSL_CTX_add_session(ctx.get(), sessions[7]) ||
+ !ExpectCache(ctx.get(), expected)) {
+ return false;
+ }
+
+ // Although collisions should be impossible (256-bit session IDs), the cache
+ // must handle them gracefully.
+ ScopedSSL_SESSION collision(CreateTestSession(7));
+ if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
+ return false;
+ }
+ expected.clear();
+ expected.push_back(collision.get());
+ expected.push_back(sessions[9]);
+ expected.push_back(sessions[8]);
+ expected.push_back(sessions[6]);
+ expected.push_back(sessions[5]);
+ if (!ExpectCache(ctx.get(), expected)) {
+ return false;
+ }
+
+ // Removing sessions behaves correctly.
+ if (!SSL_CTX_remove_session(ctx.get(), sessions[6])) {
+ return false;
+ }
+ expected.clear();
+ expected.push_back(collision.get());
+ expected.push_back(sessions[9]);
+ expected.push_back(sessions[8]);
+ expected.push_back(sessions[5]);
+ if (!ExpectCache(ctx.get(), expected)) {
+ return false;
+ }
+
+ // Removing sessions requires an exact match.
+ if (SSL_CTX_remove_session(ctx.get(), sessions[0]) ||
+ SSL_CTX_remove_session(ctx.get(), sessions[7]) ||
+ !ExpectCache(ctx.get(), expected)) {
+ return false;
+ }
+
+ return true;
+}
+
+int main() {
+ CRYPTO_library_init();
if (!TestCipherRules() ||
!TestSSL_SESSIONEncoding(kOpenSSLSession) ||
!TestSSL_SESSIONEncoding(kCustomSession) ||
+ !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
!TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
!TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
+ !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
!TestDefaultVersion(0, &TLS_method) ||
!TestDefaultVersion(SSL3_VERSION, &SSLv3_method) ||
!TestDefaultVersion(TLS1_VERSION, &TLSv1_method) ||
@@ -545,7 +1050,10 @@ int main(void) {
!TestDefaultVersion(0, &DTLS_method) ||
!TestDefaultVersion(DTLS1_VERSION, &DTLSv1_method) ||
!TestDefaultVersion(DTLS1_2_VERSION, &DTLSv1_2_method) ||
- !TestCipherGetRFCName()) {
+ !TestCipherGetRFCName() ||
+ !TestPaddingExtension() ||
+ !TestClientCAList() ||
+ !TestInternalSessionCache()) {
ERR_print_errors_fp(stderr);
return 1;
}
diff --git a/src/ssl/ssl_txt.c b/src/ssl/ssl_txt.c
deleted file mode 100644
index 2275f16..0000000
--- a/src/ssl/ssl_txt.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/* 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.]
- */
-/* ====================================================================
- * Copyright 2005 Nokia. All rights reserved.
- *
- * The portions of the attached software ("Contribution") is developed by
- * Nokia Corporation and is licensed pursuant to the OpenSSL open source
- * license.
- *
- * The Contribution, originally written by Mika Kousa and Pasi Eronen of
- * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
- * support (see RFC 4279) to OpenSSL.
- *
- * No patent licenses or other rights except those expressly stated in
- * the OpenSSL open source license shall be deemed granted or received
- * expressly, by implication, estoppel, or otherwise.
- *
- * No assurances are provided by Nokia that the Contribution does not
- * infringe the patent or other intellectual property rights of any third
- * party or that the license provides you with all the necessary rights
- * to make use of the Contribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
- * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
- * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
- * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
- * OTHERWISE. */
-
-#include <inttypes.h>
-#include <stdio.h>
-
-#include <openssl/buf.h>
-#include <openssl/err.h>
-#include <openssl/mem.h>
-
-#include "internal.h"
-
-
-int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *x) {
- BIO *b;
- int ret;
-
- b = BIO_new(BIO_s_file());
- if (b == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_print_fp, ERR_R_BUF_LIB);
- return 0;
- }
-
- BIO_set_fp(b, fp, BIO_NOCLOSE);
- ret = SSL_SESSION_print(b, x);
- BIO_free(b);
- return ret;
-}
-
-int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x) {
- unsigned int i;
- const char *s;
-
- if (x == NULL ||
- BIO_puts(bp, "SSL-Session:\n") <= 0) {
- goto err;
- }
-
- if (x->ssl_version == SSL3_VERSION) {
- s = "SSLv3";
- } else if (x->ssl_version == TLS1_2_VERSION) {
- s = "TLSv1.2";
- } else if (x->ssl_version == TLS1_1_VERSION) {
- s = "TLSv1.1";
- } else if (x->ssl_version == TLS1_VERSION) {
- s = "TLSv1";
- } else if (x->ssl_version == DTLS1_VERSION) {
- s = "DTLSv1";
- } else if (x->ssl_version == DTLS1_2_VERSION) {
- s = "DTLSv1.2";
- } else {
- s = "unknown";
- }
-
- if (BIO_printf(bp, " Protocol : %s\n", s) <= 0) {
- goto err;
- }
-
- if (BIO_printf(bp, " Cipher : %s\n",
- ((x->cipher == NULL) ? "unknown" : x->cipher->name)) <= 0) {
- goto err;
- }
-
- if (BIO_puts(bp, " Session-ID: ") <= 0) {
- goto err;
- }
-
- for (i = 0; i < x->session_id_length; i++) {
- if (BIO_printf(bp, "%02X", x->session_id[i]) <= 0) {
- goto err;
- }
- }
-
- if (BIO_puts(bp, "\n Session-ID-ctx: ") <= 0) {
- goto err;
- }
-
- for (i = 0; i < x->sid_ctx_length; i++) {
- if (BIO_printf(bp, "%02X", x->sid_ctx[i]) <= 0) {
- goto err;
- }
- }
-
- if (BIO_puts(bp, "\n Master-Key: ") <= 0) {
- goto err;
- }
-
- for (i = 0; i < (unsigned int)x->master_key_length; i++) {
- if (BIO_printf(bp, "%02X", x->master_key[i]) <= 0) {
- goto err;
- }
- }
-
- if (BIO_puts(bp, "\n PSK identity: ") <= 0 ||
- BIO_printf(bp, "%s", x->psk_identity ? x->psk_identity : "None") <= 0) {
- goto err;
- }
-
- if (x->tlsext_tick_lifetime_hint &&
- BIO_printf(bp, "\n TLS session ticket lifetime hint: %" PRIu32
- " (seconds)",
- x->tlsext_tick_lifetime_hint) <= 0) {
- goto err;
- }
-
- if (x->tlsext_tick) {
- if (BIO_puts(bp, "\n TLS session ticket:\n") <= 0 ||
- BIO_hexdump(bp, x->tlsext_tick, x->tlsext_ticklen, 4) <= 0) {
- goto err;
- }
- }
-
- if (x->time != 0L && BIO_printf(bp, "\n Start Time: %ld", x->time) <= 0) {
- goto err;
- }
-
- if (x->timeout != 0L &&
- BIO_printf(bp, "\n Timeout : %ld (sec)", x->timeout) <= 0) {
- goto err;
- }
-
- if (BIO_puts(bp, "\n") <= 0 ||
- BIO_puts(bp, " Verify return code: ") <= 0 ||
- BIO_printf(bp, "%ld (%s)\n", x->verify_result,
- X509_verify_cert_error_string(x->verify_result)) <= 0) {
- goto err;
- }
-
- return 1;
-
-err:
- return 0;
-}
diff --git a/src/ssl/t1_enc.c b/src/ssl/t1_enc.c
index 6bd80c3..0f1d683 100644
--- a/src/ssl/t1_enc.c
+++ b/src/ssl/t1_enc.c
@@ -133,6 +133,8 @@
* OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
* OTHERWISE. */
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <stdio.h>
#include <string.h>
@@ -149,7 +151,7 @@
/* tls1_P_hash computes the TLS P_<hash> function as described in RFC 5246,
- * section 5. It writes |out_len| bytes to |out|, using |md| as the hash and
+ * section 5. It XORs |out_len| bytes to |out|, using |md| as the hash and
* |secret| as the secret. |seed1| through |seed3| are concatenated to form the
* seed parameter. It returns one on success and zero on failure. */
static int tls1_P_hash(uint8_t *out, size_t out_len, const EVP_MD *md,
@@ -157,57 +159,59 @@ 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))) {
+ !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);
- if (out_len > chunk) {
- unsigned len;
- if (!HMAC_Final(&ctx, out, &len)) {
- goto err;
- }
- assert(len == chunk);
- out += len;
- out_len -= len;
- /* Calculate the next A1 value. */
- if (!HMAC_Final(&ctx_tmp, A1, &A1_len)) {
- goto err;
- }
- } else {
- /* Last chunk. */
- if (!HMAC_Final(&ctx, A1, &A1_len)) {
- goto err;
- }
- memcpy(out, A1, out_len);
+ /* XOR the result into |out|. */
+ if (len > out_len) {
+ len = out_len;
+ }
+ unsigned i;
+ for (i = 0; i < len; i++) {
+ out[i] ^= hmac[i];
+ }
+ out += len;
+ out_len -= len;
+
+ if (out_len == 0) {
break;
}
+
+ /* Calculate the next A1 value. */
+ if (!HMAC_Final(&ctx_tmp, A1, &A1_len)) {
+ goto err;
+ }
}
ret = 1;
@@ -220,79 +224,51 @@ 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) {
- size_t idx, len, count, i;
- const uint8_t *S1;
- uint32_t m;
- const EVP_MD *md;
- int ret = 0;
- uint8_t *tmp;
if (out_len == 0) {
return 1;
}
- /* Allocate a temporary buffer. */
- tmp = OPENSSL_malloc(out_len);
- if (tmp == NULL) {
- OPENSSL_PUT_ERROR(SSL, tls1_prf, ERR_R_MALLOC_FAILURE);
- return 0;
- }
+ memset(out, 0, out_len);
- /* Count number of digests and partition |secret| evenly. */
- count = 0;
- for (idx = 0; ssl_get_handshake_digest(&m, &md, idx); idx++) {
- if (m & ssl_get_algorithm2(s)) {
- count++;
+ 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. */
+ size_t secret_half = secret_len - (secret_len / 2);
+ if (!tls1_P_hash(out, out_len, EVP_md5(), secret, secret_half,
+ (const uint8_t *)label, label_len, seed1, seed1_len, seed2,
+ seed2_len)) {
+ return 0;
}
+
+ /* Note that, if |secret_len| is odd, the two halves share a byte. */
+ secret = secret + (secret_len - secret_half);
+ secret_len = secret_half;
}
- /* TODO(davidben): The only case where count isn't 1 is the old MD5/SHA-1
- * combination. The logic around multiple handshake digests can probably be
- * simplified. */
- assert(count == 1 || count == 2);
- len = secret_len / count;
- if (count == 1) {
- secret_len = 0;
- }
- S1 = secret;
- memset(out, 0, out_len);
- for (idx = 0; ssl_get_handshake_digest(&m, &md, idx); idx++) {
- if (m & ssl_get_algorithm2(s)) {
- /* If |count| is 2 and |secret_len| is odd, |secret| is partitioned into
- * two halves with an overlapping byte. */
- if (!tls1_P_hash(tmp, out_len, md, S1, len + (secret_len & 1),
- (const uint8_t *)label, label_len, seed1, seed1_len,
- seed2, seed2_len)) {
- goto err;
- }
- S1 += len;
- for (i = 0; i < out_len; i++) {
- out[i] ^= tmp[i];
- }
- }
+
+ if (!tls1_P_hash(out, out_len, ssl_get_handshake_digest(algorithm_prf),
+ secret, secret_len, (const uint8_t *)label, label_len,
+ seed1, seed1_len, seed2, seed2_len)) {
+ return 0;
}
- ret = 1;
-err:
- OPENSSL_cleanse(tmp, out_len);
- OPENSSL_free(tmp);
- return ret;
+ 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;
@@ -304,20 +280,31 @@ 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, tls1_change_cipher_state, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return 0;
}
@@ -327,13 +314,13 @@ int tls1_change_cipher_state(SSL *s, int which) {
* suites) the key length reported by |EVP_AEAD_key_length| will
* include the MAC and IV key bytes. */
if (key_len < mac_secret_len + iv_len) {
- OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return 0;
}
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;
@@ -357,46 +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) {
- OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state, ERR_R_INTERNAL_ERROR);
+ 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,
- iv_len);
- return s->aead_read_ctx != NULL;
- } else {
- 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_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_write_ctx != NULL;
+ return ssl->aead_read_ctx != NULL;
}
+
+ 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);
+ 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);
@@ -406,14 +393,14 @@ int tls1_setup_key_block(SSL *s) {
* key length reported by |EVP_AEAD_key_length| will include the MAC key
* bytes and initial implicit IV. */
if (key_len < mac_secret_len + fixed_iv_len) {
- OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return 0;
}
key_len -= mac_secret_len + fixed_iv_len;
} else {
/* The nonce is split into a fixed portion and a variable portion. */
if (variable_iv_len < fixed_iv_len) {
- OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return 0;
}
variable_iv_len -= fixed_iv_len;
@@ -423,83 +410,84 @@ 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) {
- OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
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;
}
- if (!SSL_USE_EXPLICIT_IV(s) &&
- (s->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0) {
- /* enable vulnerability countermeasure for CBC ciphers with known-IV
- * problem (http://www.openssl.org/~bodo/tls-cbc.txt). */
- s->s3->need_record_splitting = 1;
-
- if (s->session->cipher != NULL &&
- s->session->cipher->algorithm_enc == SSL_RC4) {
- s->s3->need_record_splitting = 0;
- }
- }
-
ret = 1;
err:
return ret;
cipher_unavailable_err:
- OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block,
- SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
return 0;
}
-int tls1_cert_verify_mac(SSL *s, int md_nid, uint8_t *out) {
- unsigned int ret;
- EVP_MD_CTX ctx, *d = NULL;
- int i;
-
- if (s->s3->handshake_buffer &&
- !ssl3_digest_cached_records(s, free_handshake_buffer)) {
- return 0;
- }
-
- for (i = 0; i < SSL_MAX_DIGEST; i++) {
- if (s->s3->handshake_dgst[i] &&
- EVP_MD_CTX_type(s->s3->handshake_dgst[i]) == md_nid) {
- d = s->s3->handshake_dgst[i];
- break;
- }
- }
-
- if (!d) {
- OPENSSL_PUT_ERROR(SSL, tls1_cert_verify_mac, SSL_R_NO_REQUIRED_DIGEST);
+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 = &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;
}
+ EVP_MD_CTX ctx;
EVP_MD_CTX_init(&ctx);
- if (!EVP_MD_CTX_copy_ex(&ctx, d)) {
+ if (!EVP_MD_CTX_copy_ex(&ctx, ctx_template)) {
EVP_MD_CTX_cleanup(&ctx);
return 0;
}
+ unsigned ret;
EVP_DigestFinal_ex(&ctx, out, &ret);
EVP_MD_CTX_cleanup(&ctx);
+ return ret;
+}
+
+static int append_digest(const EVP_MD_CTX *ctx, uint8_t *out, size_t *out_len,
+ size_t max_out) {
+ int ret = 0;
+ EVP_MD_CTX ctx_copy;
+ EVP_MD_CTX_init(&ctx_copy);
+ if (EVP_MD_CTX_size(ctx) > max_out) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
+ goto err;
+ }
+ unsigned len;
+ if (!EVP_MD_CTX_copy_ex(&ctx_copy, ctx) ||
+ !EVP_DigestFinal_ex(&ctx_copy, out, &len)) {
+ goto err;
+ }
+ assert(len == EVP_MD_CTX_size(ctx));
+
+ *out_len = len;
+ ret = 1;
+
+err:
+ EVP_MD_CTX_cleanup(&ctx_copy);
return ret;
}
@@ -508,71 +496,40 @@ int tls1_cert_verify_mac(SSL *s, int md_nid, uint8_t *out) {
* 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) {
- const EVP_MD *md;
- EVP_MD_CTX ctx;
- int err = 0, len = 0;
- size_t i;
- uint32_t mask;
-
- EVP_MD_CTX_init(&ctx);
-
- for (i = 0; ssl_get_handshake_digest(&mask, &md, i); i++) {
- size_t hash_size;
- unsigned int digest_len;
- EVP_MD_CTX *hdgst = s->s3->handshake_dgst[i];
-
- if ((mask & ssl_get_algorithm2(s)) == 0) {
- continue;
- }
-
- hash_size = EVP_MD_size(md);
- if (!hdgst ||
- hash_size > out_len ||
- !EVP_MD_CTX_copy_ex(&ctx, hdgst) ||
- !EVP_DigestFinal_ex(&ctx, out, &digest_len) ||
- digest_len != hash_size /* internal error */) {
- err = 1;
- break;
- }
-
- out += digest_len;
- out_len -= digest_len;
- len += digest_len;
+int tls1_handshake_digest(SSL *ssl, uint8_t *out, size_t out_len) {
+ size_t md5_len = 0;
+ if (EVP_MD_CTX_md(&ssl->s3->handshake_md5) != NULL &&
+ !append_digest(&ssl->s3->handshake_md5, out, &md5_len, out_len)) {
+ return -1;
}
- EVP_MD_CTX_cleanup(&ctx);
-
- if (err != 0) {
+ size_t len;
+ if (!append_digest(&ssl->s3->handshake_hash, out + md5_len, &len,
+ out_len - md5_len)) {
return -1;
}
- return 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.
- * TODO(davidben): Apart from initialization, the handshake buffer should be
- * orthogonal to the handshake digest. https://crbug.com/492371 */
- assert(s->s3->handshake_buffer == NULL);
- if (s->s3->handshake_buffer &&
- !ssl3_digest_cached_records(s, free_handshake_buffer)) {
- return 0;
- }
+ * its own. */
+ 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;
}
@@ -583,41 +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;
-
- /* The master secret is based on the handshake hash just after sending the
- * ClientKeyExchange. However, we might have a client certificate to send,
- * in which case we might need different hashes for the verification and
- * thus still need the handshake buffer around. Keeping both a handshake
- * buffer *and* running hashes isn't yet supported so, when it comes to
- * calculating the Finished hash, we'll have to hash the handshake buffer
- * again. */
- if (s->s3->handshake_buffer &&
- !ssl3_digest_cached_records(s, dont_free_handshake_buffer)) {
- return 0;
- }
-
- 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;
}
}
@@ -625,41 +570,40 @@ 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) {
- OPENSSL_PUT_ERROR(SSL, tls1_export_keying_material,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ if (!ssl->s3->have_version || ssl->version == SSL3_VERSION) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
size_t seed_len = 2 * SSL3_RANDOM_SIZE;
if (use_context) {
if (context_len >= 1u << 16) {
- OPENSSL_PUT_ERROR(SSL, tls1_export_keying_material, ERR_R_OVERFLOW);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
return 0;
}
seed_len += 2 + context_len;
}
uint8_t *seed = OPENSSL_malloc(seed_len);
if (seed == NULL) {
- OPENSSL_PUT_ERROR(SSL, tls1_export_keying_material, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
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 9e5c011..5aea08b 100644
--- a/src/ssl/t1_lib.c
+++ b/src/ssl/t1_lib.c
@@ -106,27 +106,29 @@
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
+#include <openssl/ssl.h>
+
#include <assert.h>
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/bytestring.h>
+#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/rand.h>
+#include <openssl/type_check.h>
#include "internal.h"
-static int tls_decrypt_ticket(SSL *s, const uint8_t *tick, int ticklen,
- const uint8_t *sess_id, int sesslen,
- SSL_SESSION **psess);
-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,
@@ -167,8 +169,7 @@ const SSL3_ENC_METHOD TLSv1_2_enc_data = {
TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
tls1_alert_code,
tls1_export_keying_material,
- SSL_ENC_FLAG_EXPLICIT_IV|SSL_ENC_FLAG_SIGALGS|SSL_ENC_FLAG_SHA256_PRF
- |SSL_ENC_FLAG_TLS1_2_CIPHERS,
+ SSL_ENC_FLAG_EXPLICIT_IV|SSL_ENC_FLAG_SIGALGS|SSL_ENC_FLAG_SHA256_PRF,
};
static int compare_uint16_t(const void *p1, const void *p2) {
@@ -213,8 +214,7 @@ static int tls1_check_duplicate_extensions(const CBS *cbs) {
extension_types =
(uint16_t *)OPENSSL_malloc(sizeof(uint16_t) * num_extensions);
if (extension_types == NULL) {
- OPENSSL_PUT_ERROR(SSL, tls1_check_duplicate_extensions,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto done;
}
@@ -308,7 +308,7 @@ char ssl_early_callback_init(struct ssl_early_callback_ctx *ctx) {
return 1;
}
-char SSL_early_callback_ctx_extension_get(
+int SSL_early_callback_ctx_extension_get(
const struct ssl_early_callback_ctx *ctx, uint16_t extension_type,
const uint8_t **out_data, size_t *out_len) {
CBS extensions;
@@ -335,119 +335,61 @@ char SSL_early_callback_ctx_extension_get(
return 0;
}
-struct tls_curve {
- uint16_t curve_id;
- int nid;
-};
-
-/* ECC curves from RFC4492. */
-static const struct tls_curve tls_curves[] = {
- {21, NID_secp224r1},
- {23, NID_X9_62_prime256v1},
- {24, NID_secp384r1},
- {25, NID_secp521r1},
-};
-
-static const uint8_t ecformats_default[] = {
- TLSEXT_ECPOINTFORMAT_uncompressed,
-};
-
static const uint16_t eccurves_default[] = {
- 23, /* X9_62_prime256v1 */
- 24, /* secp384r1 */
-#if defined(ANDROID)
- 25, /* secp521r1 */
+ SSL_CURVE_SECP256R1,
+ SSL_CURVE_SECP384R1,
+#if defined(BORINGSSL_ANDROID_SYSTEM)
+ 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;
-}
-
/* 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;
@@ -462,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,
@@ -481,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;
}
@@ -514,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;
}
@@ -535,44 +478,22 @@ static int tls1_curve_params_from_ec_key(uint16_t *out_curve_id,
return 1;
}
-/* tls1_check_point_format returns one if |comp_id| is consistent with the
- * peer's point format preferences. */
-static int tls1_check_point_format(SSL *s, uint8_t comp_id) {
- uint8_t *p = s->s3->tmp.peer_ecpointformatlist;
- size_t plen = s->s3->tmp.peer_ecpointformatlist_length;
- size_t i;
-
- /* If point formats extension present check it, otherwise everything is
- * supported (see RFC4492). */
- if (p == NULL) {
- return 1;
- }
-
- for (i = 0; i < plen; i++) {
- if (comp_id == p[i]) {
- return 1;
- }
- }
-
- return 0;
-}
-
/* 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,
@@ -593,29 +514,20 @@ static int tls1_check_curve_id(SSL *s, uint16_t curve_id) {
return 1;
}
-static void tls1_get_formatlist(SSL *s, const uint8_t **pformats,
- size_t *pformatslen) {
- /* If we have a custom point format list use it otherwise use default */
- if (s->tlsext_ecpointformatlist) {
- *pformats = s->tlsext_ecpointformatlist;
- *pformatslen = s->tlsext_ecpointformatlist_length;
- } else {
- *pformats = ecformats_default;
- *pformatslen = sizeof(ecformats_default);
- }
-}
-
-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) ||
- !tls1_check_point_format(s, comp_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;
}
@@ -626,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. */
@@ -662,87 +555,48 @@ static const uint8_t tls12_sigalgs[] = {
tlsext_sigalg(TLSEXT_hash_sha1)
};
-size_t tls12_get_psigalgs(SSL *s, const uint8_t **psigs) {
- /* If server use client authentication sigalgs if not NULL */
- if (s->server && s->cert->client_sigalgs) {
- *psigs = s->cert->client_sigalgs;
- return s->cert->client_sigalgslen;
- } else if (s->cert->conf_sigalgs) {
- *psigs = s->cert->conf_sigalgs;
- return s->cert->conf_sigalgslen;
- } else {
- *psigs = tls12_sigalgs;
- return sizeof(tls12_sigalgs);
- }
+size_t tls12_get_psigalgs(SSL *ssl, const uint8_t **psigs) {
+ *psigs = tls12_sigalgs;
+ return sizeof(tls12_sigalgs);
}
-/* tls12_check_peer_sigalg parses a SignatureAndHashAlgorithm out of |cbs|. It
- * checks it is consistent with |s|'s sent supported signature algorithms and,
- * if so, writes the relevant digest into |*out_md| and returns 1. Otherwise it
- * returns 0 and writes an alert into |*out_alert|. */
-int tls12_check_peer_sigalg(const EVP_MD **out_md, int *out_alert, SSL *s,
- CBS *cbs, EVP_PKEY *pkey) {
+int tls12_check_peer_sigalg(SSL *ssl, const EVP_MD **out_md, int *out_alert,
+ uint8_t hash, uint8_t signature, EVP_PKEY *pkey) {
const uint8_t *sent_sigs;
size_t sent_sigslen, i;
- int sigalg = tls12_get_sigid(pkey);
- uint8_t hash, signature;
+ int sigalg = tls12_get_sigid(pkey->type);
/* Should never happen */
if (sigalg == -1) {
- OPENSSL_PUT_ERROR(SSL, tls12_check_peer_sigalg, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
*out_alert = SSL_AD_INTERNAL_ERROR;
return 0;
}
- if (!CBS_get_u8(cbs, &hash) ||
- !CBS_get_u8(cbs, &signature)) {
- OPENSSL_PUT_ERROR(SSL, tls12_check_peer_sigalg, SSL_R_DECODE_ERROR);
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
-
/* Check key type is consistent with signature */
if (sigalg != signature) {
- OPENSSL_PUT_ERROR(SSL, tls12_check_peer_sigalg, SSL_R_WRONG_SIGNATURE_TYPE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
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 (s->server && (!tls1_check_curve_id(s, curve_id) ||
- !tls1_check_point_format(s, comp_id))) {
- OPENSSL_PUT_ERROR(SSL, tls12_check_peer_sigalg, SSL_R_WRONG_CURVE);
- *out_alert = SSL_AD_ILLEGAL_PARAMETER;
- return 0;
- }
- }
-
/* Check signature matches a type we sent */
- sent_sigslen = tls12_get_psigalgs(s, &sent_sigs);
+ sent_sigslen = tls12_get_psigalgs(ssl, &sent_sigs);
for (i = 0; i < sent_sigslen; i += 2, sent_sigs += 2) {
if (hash == sent_sigs[0] && signature == sent_sigs[1]) {
break;
}
}
- /* Allow fallback to SHA-1. */
- if (i == sent_sigslen && hash != TLSEXT_hash_sha1) {
- OPENSSL_PUT_ERROR(SSL, tls12_check_peer_sigalg, SSL_R_WRONG_SIGNATURE_TYPE);
+ if (i == sent_sigslen) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
return 0;
}
*out_md = tls12_get_hash(hash);
if (*out_md == NULL) {
- OPENSSL_PUT_ERROR(SSL, tls12_check_peer_sigalg, SSL_R_UNKNOWN_DIGEST);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_DIGEST);
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
return 0;
}
@@ -754,24 +608,17 @@ int tls12_check_peer_sigalg(const EVP_MD **out_md, int *out_alert, SSL *s,
* 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;
c->mask_a = 0;
c->mask_k = 0;
- /* Don't allow TLS 1.2 only ciphers if we don't suppport them */
- if (!SSL_CLIENT_USE_TLS1_2_CIPHERS(s)) {
- c->mask_ssl = SSL_TLSV1_2;
- } else {
- c->mask_ssl = 0;
- }
-
/* 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:
@@ -793,1161 +640,1800 @@ 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;
}
}
-/* header_len is the length of the ClientHello header written so far, used to
- * compute padding. It does not include the record header. Pass 0 if no padding
- * is to be done. */
-uint8_t *ssl_add_clienthello_tlsext(SSL *s, uint8_t *buf, uint8_t *limit,
- size_t header_len) {
- int extdatalen = 0;
- uint8_t *ret = buf;
- uint8_t *orig = buf;
- /* See if we support any ECC ciphersuites */
- int using_ecc = 0;
+/* tls_extension represents a TLS extension that is handled internally. The
+ * |init| function is called for each handshake, before any other functions of
+ * the extension. Then the add and parse callbacks are called as needed.
+ *
+ * The parse callbacks receive a |CBS| that contains the contents of the
+ * extension (i.e. not including the type and length bytes). If an extension is
+ * not received then the parse callbacks will be called with a NULL CBS so that
+ * they can do any processing needed to handle the absence of an extension.
+ *
+ * The add callbacks receive a |CBB| to which the extension can be appended but
+ * the function is responsible for appending the type and length bytes too.
+ *
+ * All callbacks return one for success and zero for error. If a parse function
+ * returns zero then a fatal alert with value |*out_alert| will be sent. If
+ * |*out_alert| isn't set, then a |decode_error| alert will be sent. */
+struct tls_extension {
+ uint16_t value;
+ void (*init)(SSL *ssl);
+
+ int (*add_clienthello)(SSL *ssl, CBB *out);
+ int (*parse_serverhello)(SSL *ssl, uint8_t *out_alert, CBS *contents);
+
+ int (*parse_clienthello)(SSL *ssl, uint8_t *out_alert, CBS *contents);
+ int (*add_serverhello)(SSL *ssl, CBB *out);
+};
- if (s->version >= TLS1_VERSION || SSL_IS_DTLS(s)) {
- size_t i;
- uint32_t alg_k, alg_a;
- STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s);
- for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) {
- const SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
+/* Server name indication (SNI).
+ *
+ * https://tools.ietf.org/html/rfc6066#section-3. */
- alg_k = c->algorithm_mkey;
- alg_a = c->algorithm_auth;
- if ((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA)) {
- using_ecc = 1;
- break;
- }
- }
+static void ext_sni_init(SSL *ssl) {
+ ssl->s3->tmp.should_ack_sni = 0;
+}
+
+static int ext_sni_add_clienthello(SSL *ssl, CBB *out) {
+ if (ssl->tlsext_hostname == NULL) {
+ return 1;
}
- /* don't add extensions for SSLv3 unless doing secure renegotiation */
- if (s->client_version == SSL3_VERSION && !s->s3->send_connection_binding) {
- return orig;
+ CBB contents, server_name_list, name;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_server_name) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_u16_length_prefixed(&contents, &server_name_list) ||
+ !CBB_add_u8(&server_name_list, TLSEXT_NAMETYPE_host_name) ||
+ !CBB_add_u16_length_prefixed(&server_name_list, &name) ||
+ !CBB_add_bytes(&name, (const uint8_t *)ssl->tlsext_hostname,
+ strlen(ssl->tlsext_hostname)) ||
+ !CBB_flush(out)) {
+ return 0;
}
- ret += 2;
+ return 1;
+}
- if (ret >= limit) {
- return NULL; /* should never occur. */
+static int ext_sni_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return 1;
}
- if (s->tlsext_hostname != NULL) {
- /* Add TLS extension servername to the Client Hello message */
- unsigned long size_str;
- long lenmax;
+ if (CBS_len(contents) != 0) {
+ return 0;
+ }
- /* check for enough space.
- 4 for the servername type and entension length
- 2 for servernamelist length
- 1 for the hostname type
- 2 for hostname length
- + hostname length */
+ assert(ssl->tlsext_hostname != NULL);
- lenmax = limit - ret - 9;
- size_str = strlen(s->tlsext_hostname);
- if (lenmax < 0 || size_str > (unsigned long)lenmax) {
- return NULL;
+ if (!ssl->hit) {
+ assert(ssl->session->tlsext_hostname == NULL);
+ ssl->session->tlsext_hostname = BUF_strdup(ssl->tlsext_hostname);
+ if (!ssl->session->tlsext_hostname) {
+ *out_alert = SSL_AD_INTERNAL_ERROR;
+ return 0;
}
+ }
- /* extension type and length */
- s2n(TLSEXT_TYPE_server_name, ret);
- s2n(size_str + 5, ret);
+ return 1;
+}
- /* length of servername list */
- s2n(size_str + 3, ret);
+static int ext_sni_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return 1;
+ }
- /* hostname type, length and hostname */
- *(ret++) = (uint8_t)TLSEXT_NAMETYPE_host_name;
- s2n(size_str, ret);
- memcpy(ret, s->tlsext_hostname, size_str);
- ret += size_str;
+ /* The servername extension is treated as follows:
+ *
+ * - Only the hostname type is supported with a maximum length of 255.
+ * - The servername is rejected if too long or if it contains zeros, in
+ * which case an fatal alert is generated.
+ * - The servername field is maintained together with the session cache.
+ * - When a session is resumed, the servername callback is invoked in order
+ * to allow the application to position itself to the right context.
+ * - The servername is acknowledged if it is new for a session or when
+ * it is identical to a previously used for the same session.
+ * Applications can control the behaviour. They can at any time
+ * set a 'desirable' servername for a new SSL object. This can be the
+ * case for example with HTTPS when a Host: header field is received and
+ * a renegotiation is requested. In this case, a possible servername
+ * presented in the new client hello is only acknowledged if it matches
+ * the value of the Host: field.
+ * - Applications must use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
+ * if they provide for changing an explicit servername context for the
+ * session,
+ * i.e. when the session has been established with a servername extension.
+ */
+
+ CBS server_name_list;
+ char have_seen_host_name = 0;
+
+ if (!CBS_get_u16_length_prefixed(contents, &server_name_list) ||
+ CBS_len(&server_name_list) == 0 ||
+ CBS_len(contents) != 0) {
+ return 0;
}
- /* Add RI if renegotiating */
- if (s->s3->initial_handshake_complete) {
- int el;
+ /* Decode each ServerName in the extension. */
+ while (CBS_len(&server_name_list) > 0) {
+ uint8_t name_type;
+ CBS host_name;
- if (!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0)) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_tlsext, ERR_R_INTERNAL_ERROR);
- return NULL;
+ if (!CBS_get_u8(&server_name_list, &name_type) ||
+ !CBS_get_u16_length_prefixed(&server_name_list, &host_name)) {
+ return 0;
}
- if ((limit - ret - 4 - el) < 0) {
- return NULL;
+ /* Only host_name is supported. */
+ if (name_type != TLSEXT_NAMETYPE_host_name) {
+ continue;
}
- s2n(TLSEXT_TYPE_renegotiate, ret);
- s2n(el, ret);
-
- if (!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el)) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_tlsext, ERR_R_INTERNAL_ERROR);
- return NULL;
+ if (have_seen_host_name) {
+ /* The ServerNameList MUST NOT contain more than one name of the same
+ * name_type. */
+ return 0;
}
- ret += el;
- }
+ have_seen_host_name = 1;
- /* Add extended master secret. */
- if (s->version != SSL3_VERSION) {
- if (limit - ret - 4 < 0) {
- return NULL;
- }
- s2n(TLSEXT_TYPE_extended_master_secret, ret);
- s2n(0, ret);
- }
-
- if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) {
- int ticklen = 0;
- /* Renegotiation does not participate in session resumption. However, still
- * advertise the extension to avoid potentially breaking servers which carry
- * over the state from the previous handshake, such as OpenSSL servers
- * without upstream's 3c3f0259238594d77264a78944d409f2127642c4. */
- if (!s->s3->initial_handshake_complete && s->session != NULL &&
- s->session->tlsext_tick != NULL) {
- ticklen = s->session->tlsext_ticklen;
+ if (CBS_len(&host_name) == 0 ||
+ CBS_len(&host_name) > TLSEXT_MAXLEN_host_name ||
+ CBS_contains_zero_byte(&host_name)) {
+ *out_alert = SSL_AD_UNRECOGNIZED_NAME;
+ return 0;
}
- /* Check for enough room 2 for extension type, 2 for len rest for
- * ticket. */
- if ((long)(limit - ret - 4 - ticklen) < 0) {
- return NULL;
- }
- s2n(TLSEXT_TYPE_session_ticket, ret);
- s2n(ticklen, ret);
- if (ticklen) {
- memcpy(ret, s->session->tlsext_tick, ticklen);
- ret += ticklen;
+ if (!ssl->hit) {
+ assert(ssl->session->tlsext_hostname == NULL);
+ if (ssl->session->tlsext_hostname) {
+ /* This should be impossible. */
+ return 0;
+ }
+
+ /* Copy the hostname as a string. */
+ if (!CBS_strdup(&host_name, &ssl->session->tlsext_hostname)) {
+ *out_alert = SSL_AD_INTERNAL_ERROR;
+ return 0;
+ }
+
+ ssl->s3->tmp.should_ack_sni = 1;
}
}
- if (ssl3_version_from_wire(s, s->client_version) >= TLS1_2_VERSION) {
- size_t salglen;
- const uint8_t *salg;
- salglen = tls12_get_psigalgs(s, &salg);
- if ((size_t)(limit - ret) < salglen + 6) {
- return NULL;
- }
- s2n(TLSEXT_TYPE_signature_algorithms, ret);
- s2n(salglen + 2, ret);
- s2n(salglen, ret);
- memcpy(ret, salg, salglen);
- ret += salglen;
- }
-
- if (s->ocsp_stapling_enabled) {
- /* The status_request extension is excessively extensible at every layer.
- * On the client, only support requesting OCSP responses with an empty
- * responder_id_list and no extensions. */
- if (limit - ret - 4 - 1 - 2 - 2 < 0) {
- return NULL;
- }
+ return 1;
+}
- s2n(TLSEXT_TYPE_status_request, ret);
- s2n(1 + 2 + 2, ret);
- /* status_type */
- *(ret++) = TLSEXT_STATUSTYPE_ocsp;
- /* responder_id_list - empty */
- s2n(0, ret);
- /* request_extensions - empty */
- s2n(0, ret);
- }
-
- if (s->ctx->next_proto_select_cb && !s->s3->initial_handshake_complete &&
- !SSL_IS_DTLS(s)) {
- /* The client advertises an emtpy extension to indicate its support for
- * Next Protocol Negotiation */
- if (limit - ret - 4 < 0) {
- return NULL;
- }
- s2n(TLSEXT_TYPE_next_proto_neg, ret);
- s2n(0, ret);
+static int ext_sni_add_serverhello(SSL *ssl, CBB *out) {
+ if (ssl->hit ||
+ !ssl->s3->tmp.should_ack_sni ||
+ ssl->session->tlsext_hostname == NULL) {
+ return 1;
}
- if (s->signed_cert_timestamps_enabled) {
- /* The client advertises an empty extension to indicate its support for
- * certificate timestamps. */
- if (limit - ret - 4 < 0) {
- return NULL;
- }
- s2n(TLSEXT_TYPE_certificate_timestamp, ret);
- s2n(0, ret);
+ if (!CBB_add_u16(out, TLSEXT_TYPE_server_name) ||
+ !CBB_add_u16(out, 0 /* length */)) {
+ return 0;
}
- if (s->alpn_client_proto_list && !s->s3->initial_handshake_complete) {
- if ((size_t)(limit - ret) < 6 + s->alpn_client_proto_list_len) {
- return NULL;
- }
- s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);
- s2n(2 + s->alpn_client_proto_list_len, ret);
- s2n(s->alpn_client_proto_list_len, ret);
- memcpy(ret, s->alpn_client_proto_list, s->alpn_client_proto_list_len);
- ret += s->alpn_client_proto_list_len;
+ return 1;
+}
+
+
+/* Renegotiation indication.
+ *
+ * https://tools.ietf.org/html/rfc5746 */
+
+static int ext_ri_add_clienthello(SSL *ssl, CBB *out) {
+ CBB contents, prev_finished;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_renegotiate) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_u8_length_prefixed(&contents, &prev_finished) ||
+ !CBB_add_bytes(&prev_finished, ssl->s3->previous_client_finished,
+ ssl->s3->previous_client_finished_len) ||
+ !CBB_flush(out)) {
+ return 0;
}
- if (s->tlsext_channel_id_enabled && !SSL_IS_DTLS(s)) {
- /* The client advertises an emtpy extension to indicate its support for
- * Channel ID. */
- if (limit - ret - 4 < 0) {
- return NULL;
- }
- if (s->ctx->tlsext_channel_id_enabled_new) {
- s2n(TLSEXT_TYPE_channel_id_new, ret);
+ return 1;
+}
+
+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) {
+ /* 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.
+ *
+ * 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 +
+ ssl->s3->previous_server_finished_len;
+
+ /* Check for logic errors */
+ assert(!expected_len || ssl->s3->previous_client_finished_len);
+ assert(!expected_len || ssl->s3->previous_server_finished_len);
+
+ /* Parse out the extension contents. */
+ CBS renegotiated_connection;
+ if (!CBS_get_u8_length_prefixed(contents, &renegotiated_connection) ||
+ CBS_len(contents) != 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_ENCODING_ERR);
+ *out_alert = SSL_AD_ILLEGAL_PARAMETER;
+ return 0;
+ }
+
+ /* Check that the extension matches. */
+ if (CBS_len(&renegotiated_connection) != expected_len) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
+ *out_alert = SSL_AD_HANDSHAKE_FAILURE;
+ return 0;
+ }
+
+ const uint8_t *d = CBS_data(&renegotiated_connection);
+ if (CRYPTO_memcmp(d, 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;
+ return 0;
+ }
+ d += ssl->s3->previous_client_finished_len;
+
+ if (CRYPTO_memcmp(d, ssl->s3->previous_server_finished,
+ ssl->s3->previous_server_finished_len)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
+ *out_alert = SSL_AD_ILLEGAL_PARAMETER;
+ return 0;
+ }
+ ssl->s3->send_connection_binding = 1;
+
+ return 1;
+}
+
+static int ext_ri_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ /* Renegotiation isn't supported as a server so this function should never be
+ * called after the initial handshake. */
+ assert(!ssl->s3->initial_handshake_complete);
+
+ CBS fake_contents;
+ static const uint8_t kFakeExtension[] = {0};
+
+ if (contents == NULL) {
+ if (ssl->s3->send_connection_binding) {
+ /* The renegotiation SCSV was received so pretend that we received a
+ * renegotiation extension. */
+ CBS_init(&fake_contents, kFakeExtension, sizeof(kFakeExtension));
+ contents = &fake_contents;
+ /* We require that the renegotiation extension is at index zero of
+ * kExtensions. */
+ ssl->s3->tmp.extensions.received |= (1u << 0);
} else {
- s2n(TLSEXT_TYPE_channel_id, ret);
+ return 1;
}
- s2n(0, ret);
}
- if (SSL_get_srtp_profiles(s)) {
- int el;
+ CBS renegotiated_connection;
- ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0);
+ if (!CBS_get_u8_length_prefixed(contents, &renegotiated_connection) ||
+ CBS_len(contents) != 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_ENCODING_ERR);
+ return 0;
+ }
- if ((limit - ret - 4 - el) < 0) {
- return NULL;
- }
+ /* Check that the extension matches */
+ 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;
+ return 0;
+ }
- s2n(TLSEXT_TYPE_use_srtp, ret);
- s2n(el, ret);
+ ssl->s3->send_connection_binding = 1;
- if (!ssl_add_clienthello_use_srtp_ext(s, ret, &el, el)) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_tlsext, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
- ret += el;
+ return 1;
+}
+
+static int ext_ri_add_serverhello(SSL *ssl, CBB *out) {
+ CBB contents, prev_finished;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_renegotiate) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_u8_length_prefixed(&contents, &prev_finished) ||
+ !CBB_add_bytes(&prev_finished, ssl->s3->previous_client_finished,
+ ssl->s3->previous_client_finished_len) ||
+ !CBB_add_bytes(&prev_finished, ssl->s3->previous_server_finished,
+ ssl->s3->previous_server_finished_len) ||
+ !CBB_flush(out)) {
+ return 0;
}
- if (using_ecc) {
- /* Add TLS extension ECPointFormats to the ClientHello message */
- long lenmax;
- const uint8_t *formats;
- const uint16_t *curves;
- size_t formats_len, curves_len, i;
+ return 1;
+}
- tls1_get_formatlist(s, &formats, &formats_len);
- lenmax = limit - ret - 5;
- if (lenmax < 0) {
- return NULL;
- }
- if (formats_len > (size_t)lenmax) {
- return NULL;
- }
- if (formats_len > 255) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_tlsext, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
+/* Extended Master Secret.
+ *
+ * https://tools.ietf.org/html/draft-ietf-tls-session-hash-05 */
- s2n(TLSEXT_TYPE_ec_point_formats, ret);
- s2n(formats_len + 1, ret);
- *(ret++) = (uint8_t)formats_len;
- memcpy(ret, formats, formats_len);
- ret += formats_len;
+static void ext_ems_init(SSL *ssl) {
+ ssl->s3->tmp.extended_master_secret = 0;
+}
- /* Add TLS extension EllipticCurves to the ClientHello message */
- tls1_get_curvelist(s, 0, &curves, &curves_len);
+static int ext_ems_add_clienthello(SSL *ssl, CBB *out) {
+ if (ssl->version == SSL3_VERSION) {
+ return 1;
+ }
- lenmax = limit - ret - 6;
- if (lenmax < 0) {
- return NULL;
- }
- if (curves_len * 2 > (size_t)lenmax) {
- return NULL;
- }
- if (curves_len * 2 > 65532) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_tlsext, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
+ if (!CBB_add_u16(out, TLSEXT_TYPE_extended_master_secret) ||
+ !CBB_add_u16(out, 0 /* length */)) {
+ return 0;
+ }
- s2n(TLSEXT_TYPE_elliptic_curves, ret);
- s2n((curves_len * 2) + 2, ret);
+ return 1;
+}
- s2n(curves_len * 2, ret);
- for (i = 0; i < curves_len; i++) {
- s2n(curves[i], ret);
- }
+static int ext_ems_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return 1;
}
- if (header_len > 0) {
- size_t clienthello_minsize = 0;
- header_len += ret - orig;
- if (header_len > 0xff && header_len < 0x200) {
- /* Add padding to workaround bugs in F5 terminators. See
- * https://tools.ietf.org/html/draft-agl-tls-padding-03
- *
- * NB: because this code works out the length of all existing extensions
- * it MUST always appear last. */
- clienthello_minsize = 0x200;
- }
- if (s->fastradio_padding) {
- /* Pad the ClientHello record to 1024 bytes to fast forward the radio
- * into DCH (high data rate) state in 3G networks. Note that when
- * fastradio_padding is enabled, even if the header_len is less than 255
- * bytes, the padding will be applied regardless. This is slightly
- * different from the TLS padding extension suggested in
- * https://tools.ietf.org/html/draft-agl-tls-padding-03 */
- clienthello_minsize = 0x400;
- }
- if (header_len < clienthello_minsize) {
- size_t padding_len = clienthello_minsize - header_len;
- /* Extensions take at least four bytes to encode. Always include least
- * one byte of data if including the extension. WebSphere Application
- * Server 7.0 is intolerant to the last extension being zero-length. */
- if (padding_len >= 4 + 1) {
- padding_len -= 4;
- } else {
- padding_len = 1;
- }
+ if (ssl->version == SSL3_VERSION || CBS_len(contents) != 0) {
+ return 0;
+ }
- if (limit - ret - 4 - (long)padding_len < 0) {
- return NULL;
- }
+ ssl->s3->tmp.extended_master_secret = 1;
+ return 1;
+}
- s2n(TLSEXT_TYPE_padding, ret);
- s2n(padding_len, ret);
- memset(ret, 0, padding_len);
- ret += padding_len;
- }
+static int ext_ems_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (ssl->version == SSL3_VERSION || contents == NULL) {
+ return 1;
}
- extdatalen = ret - orig - 2;
- if (extdatalen == 0) {
- return orig;
+ if (CBS_len(contents) != 0) {
+ return 0;
}
- s2n(extdatalen, orig);
- return ret;
+ ssl->s3->tmp.extended_master_secret = 1;
+ return 1;
}
-uint8_t *ssl_add_serverhello_tlsext(SSL *s, uint8_t *buf, uint8_t *limit) {
- int extdatalen = 0;
- uint8_t *orig = buf;
- uint8_t *ret = buf;
- int next_proto_neg_seen;
- uint32_t alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
- uint32_t alg_a = s->s3->tmp.new_cipher->algorithm_auth;
- int using_ecc = (alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA);
- using_ecc = using_ecc && (s->s3->tmp.peer_ecpointformatlist != NULL);
+static int ext_ems_add_serverhello(SSL *ssl, CBB *out) {
+ if (!ssl->s3->tmp.extended_master_secret) {
+ return 1;
+ }
- /* don't add extensions for SSLv3, unless doing secure renegotiation */
- if (s->version == SSL3_VERSION && !s->s3->send_connection_binding) {
- return orig;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_extended_master_secret) ||
+ !CBB_add_u16(out, 0 /* length */)) {
+ return 0;
}
- ret += 2;
- if (ret >= limit) {
- return NULL; /* should never happen. */
+ return 1;
+}
+
+
+/* Session tickets.
+ *
+ * https://tools.ietf.org/html/rfc5077 */
+
+static int ext_ticket_add_clienthello(SSL *ssl, CBB *out) {
+ if (SSL_get_options(ssl) & SSL_OP_NO_TICKET) {
+ return 1;
}
- if (!s->hit && s->should_ack_sni && s->session->tlsext_hostname != NULL) {
- if ((long)(limit - ret - 4) < 0) {
- return NULL;
- }
+ const uint8_t *ticket_data = NULL;
+ int ticket_len = 0;
- s2n(TLSEXT_TYPE_server_name, ret);
- s2n(0, ret);
+ /* Renegotiation does not participate in session resumption. However, still
+ * advertise the extension to avoid potentially breaking servers which carry
+ * over the state from the previous handshake, such as OpenSSL servers
+ * without upstream's 3c3f0259238594d77264a78944d409f2127642c4. */
+ if (!ssl->s3->initial_handshake_complete &&
+ ssl->session != NULL &&
+ ssl->session->tlsext_tick != NULL) {
+ ticket_data = ssl->session->tlsext_tick;
+ ticket_len = ssl->session->tlsext_ticklen;
}
- if (s->s3->send_connection_binding) {
- int el;
+ CBB ticket;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_session_ticket) ||
+ !CBB_add_u16_length_prefixed(out, &ticket) ||
+ !CBB_add_bytes(&ticket, ticket_data, ticket_len) ||
+ !CBB_flush(out)) {
+ return 0;
+ }
- if (!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0)) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_tlsext, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
+ return 1;
+}
- if ((limit - ret - 4 - el) < 0) {
- return NULL;
- }
+static int ext_ticket_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ ssl->tlsext_ticket_expected = 0;
- s2n(TLSEXT_TYPE_renegotiate, ret);
- s2n(el, ret);
+ if (contents == NULL) {
+ return 1;
+ }
- if (!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el)) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_tlsext, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
+ /* If |SSL_OP_NO_TICKET| is set then no extension will have been sent and
+ * this function should never be called, even if the server tries to send the
+ * extension. */
+ assert((SSL_get_options(ssl) & SSL_OP_NO_TICKET) == 0);
- ret += el;
+ if (CBS_len(contents) != 0) {
+ return 0;
}
- if (s->s3->tmp.extended_master_secret) {
- if ((long)(limit - ret - 4) < 0) {
- return NULL;
- }
+ ssl->tlsext_ticket_expected = 1;
+ return 1;
+}
- s2n(TLSEXT_TYPE_extended_master_secret, ret);
- s2n(0, ret);
+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;
+}
+
+static int ext_ticket_add_serverhello(SSL *ssl, CBB *out) {
+ if (!ssl->tlsext_ticket_expected) {
+ return 1;
}
- if (using_ecc) {
- const uint8_t *plist;
- size_t plistlen;
- /* Add TLS extension ECPointFormats to the ServerHello message */
- long lenmax;
+ /* If |SSL_OP_NO_TICKET| is set, |tlsext_ticket_expected| should never be
+ * true. */
+ assert((SSL_get_options(ssl) & SSL_OP_NO_TICKET) == 0);
- tls1_get_formatlist(s, &plist, &plistlen);
+ if (!CBB_add_u16(out, TLSEXT_TYPE_session_ticket) ||
+ !CBB_add_u16(out, 0 /* length */)) {
+ return 0;
+ }
- lenmax = limit - ret - 5;
- if (lenmax < 0) {
- return NULL;
- }
- if (plistlen > (size_t)lenmax) {
- return NULL;
- }
- if (plistlen > 255) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_tlsext, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
+ return 1;
+}
+
+
+/* Signature Algorithms.
+ *
+ * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
- s2n(TLSEXT_TYPE_ec_point_formats, ret);
- s2n(plistlen + 1, ret);
- *(ret++) = (uint8_t)plistlen;
- memcpy(ret, plist, plistlen);
- ret += plistlen;
+static int ext_sigalgs_add_clienthello(SSL *ssl, CBB *out) {
+ if (ssl3_version_from_wire(ssl, ssl->client_version) < TLS1_2_VERSION) {
+ return 1;
}
- /* Currently the server should not respond with a SupportedCurves extension */
- if (s->tlsext_ticket_expected && !(SSL_get_options(s) & SSL_OP_NO_TICKET)) {
- if ((long)(limit - ret - 4) < 0) {
- return NULL;
- }
- s2n(TLSEXT_TYPE_session_ticket, ret);
- s2n(0, ret);
+ const uint8_t *sigalgs_data;
+ const size_t sigalgs_len = tls12_get_psigalgs(ssl, &sigalgs_data);
+
+ CBB contents, sigalgs;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_signature_algorithms) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_u16_length_prefixed(&contents, &sigalgs) ||
+ !CBB_add_bytes(&sigalgs, sigalgs_data, sigalgs_len) ||
+ !CBB_flush(out)) {
+ return 0;
}
- if (s->s3->tmp.certificate_status_expected) {
- if ((long)(limit - ret - 4) < 0) {
- return NULL;
- }
- s2n(TLSEXT_TYPE_status_request, ret);
- s2n(0, ret);
+ return 1;
+}
+
+static int ext_sigalgs_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents != NULL) {
+ /* Servers MUST NOT send this extension. */
+ *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER);
+ return 0;
}
- if (s->srtp_profile) {
- int el;
+ return 1;
+}
- ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0);
+static int ext_sigalgs_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ OPENSSL_free(ssl->cert->peer_sigalgs);
+ ssl->cert->peer_sigalgs = NULL;
+ ssl->cert->peer_sigalgslen = 0;
- if ((limit - ret - 4 - el) < 0) {
- return NULL;
- }
+ if (contents == NULL) {
+ return 1;
+ }
- s2n(TLSEXT_TYPE_use_srtp, ret);
- s2n(el, ret);
+ CBS supported_signature_algorithms;
+ if (!CBS_get_u16_length_prefixed(contents, &supported_signature_algorithms) ||
+ CBS_len(contents) != 0 ||
+ CBS_len(&supported_signature_algorithms) == 0 ||
+ !tls1_parse_peer_sigalgs(ssl, &supported_signature_algorithms)) {
+ return 0;
+ }
- if (!ssl_add_serverhello_use_srtp_ext(s, ret, &el, el)) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_tlsext, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
- ret += el;
+ return 1;
+}
+
+static int ext_sigalgs_add_serverhello(SSL *ssl, CBB *out) {
+ /* Servers MUST NOT send this extension. */
+ return 1;
+}
+
+
+/* OCSP Stapling.
+ *
+ * https://tools.ietf.org/html/rfc6066#section-8 */
+
+static void ext_ocsp_init(SSL *ssl) {
+ ssl->s3->tmp.certificate_status_expected = 0;
+}
+
+static int ext_ocsp_add_clienthello(SSL *ssl, CBB *out) {
+ if (!ssl->ocsp_stapling_enabled) {
+ return 1;
}
- next_proto_neg_seen = s->s3->next_proto_neg_seen;
- s->s3->next_proto_neg_seen = 0;
- if (next_proto_neg_seen && s->ctx->next_protos_advertised_cb) {
- const uint8_t *npa;
- unsigned int npalen;
- int r;
+ CBB contents;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_status_request) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_u8(&contents, TLSEXT_STATUSTYPE_ocsp) ||
+ !CBB_add_u16(&contents, 0 /* empty responder ID list */) ||
+ !CBB_add_u16(&contents, 0 /* empty request extensions */) ||
+ !CBB_flush(out)) {
+ return 0;
+ }
- r = s->ctx->next_protos_advertised_cb(
- s, &npa, &npalen, s->ctx->next_protos_advertised_cb_arg);
- if (r == SSL_TLSEXT_ERR_OK) {
- if ((long)(limit - ret - 4 - npalen) < 0) {
- return NULL;
- }
- s2n(TLSEXT_TYPE_next_proto_neg, ret);
- s2n(npalen, ret);
- memcpy(ret, npa, npalen);
- ret += npalen;
- s->s3->next_proto_neg_seen = 1;
- }
+ return 1;
+}
+
+static int ext_ocsp_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return 1;
}
- if (s->s3->alpn_selected) {
- const uint8_t *selected = s->s3->alpn_selected;
- size_t len = s->s3->alpn_selected_len;
+ if (CBS_len(contents) != 0) {
+ return 0;
+ }
- if ((long)(limit - ret - 4 - 2 - 1 - len) < 0) {
- return NULL;
- }
- s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);
- s2n(3 + len, ret);
- s2n(1 + len, ret);
- *ret++ = len;
- memcpy(ret, selected, len);
- ret += len;
- }
-
- /* If the client advertised support for Channel ID, and we have it
- * enabled, then we want to echo it back. */
- if (s->s3->tlsext_channel_id_valid) {
- if (limit - ret - 4 < 0) {
- return NULL;
- }
- if (s->s3->tlsext_channel_id_new) {
- s2n(TLSEXT_TYPE_channel_id_new, ret);
- } else {
- s2n(TLSEXT_TYPE_channel_id, ret);
- }
- s2n(0, ret);
+ ssl->s3->tmp.certificate_status_expected = 1;
+ return 1;
+}
+
+static int ext_ocsp_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return 1;
}
- extdatalen = ret - orig - 2;
- if (extdatalen == 0) {
- return orig;
+ uint8_t status_type;
+ if (!CBS_get_u8(contents, &status_type)) {
+ return 0;
}
- s2n(extdatalen, orig);
- return ret;
+ /* We cannot decide whether OCSP stapling will occur yet because the correct
+ * SSL_CTX might not have been selected. */
+ ssl->s3->tmp.ocsp_stapling_requested = status_type == TLSEXT_STATUSTYPE_ocsp;
+
+ return 1;
}
-/* tls1_alpn_handle_client_hello is called to process the ALPN extension in a
- * ClientHello.
- * cbs: the contents of the extension, not including the type and length.
- * out_alert: a pointer to the alert value to send in the event of a zero
- * return.
+static int ext_ocsp_add_serverhello(SSL *ssl, CBB *out) {
+ /* The extension shouldn't be sent when resuming sessions. */
+ if (ssl->hit ||
+ !ssl->s3->tmp.ocsp_stapling_requested ||
+ ssl->ctx->ocsp_response_length == 0) {
+ return 1;
+ }
+
+ ssl->s3->tmp.certificate_status_expected = 1;
+
+ return CBB_add_u16(out, TLSEXT_TYPE_status_request) &&
+ CBB_add_u16(out, 0 /* length */);
+}
+
+
+/* Next protocol negotiation.
*
- * returns: 1 on success. */
-static int tls1_alpn_handle_client_hello(SSL *s, CBS *cbs, int *out_alert) {
- CBS protocol_name_list, protocol_name_list_copy;
- const uint8_t *selected;
+ * https://htmlpreview.github.io/?https://github.com/agl/technotes/blob/master/nextprotoneg.html */
+
+static void ext_npn_init(SSL *ssl) {
+ ssl->s3->next_proto_neg_seen = 0;
+}
+
+static int ext_npn_add_clienthello(SSL *ssl, CBB *out) {
+ if (ssl->s3->initial_handshake_complete ||
+ ssl->ctx->next_proto_select_cb == NULL ||
+ (ssl->options & SSL_OP_DISABLE_NPN) ||
+ SSL_IS_DTLS(ssl)) {
+ return 1;
+ }
+
+ if (!CBB_add_u16(out, TLSEXT_TYPE_next_proto_neg) ||
+ !CBB_add_u16(out, 0 /* length */)) {
+ return 0;
+ }
+
+ return 1;
+}
+
+static int ext_npn_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return 1;
+ }
+
+ /* If any of these are false then we should never have sent the NPN
+ * extension in the ClientHello and thus this function should never have been
+ * called. */
+ assert(!ssl->s3->initial_handshake_complete);
+ assert(!SSL_IS_DTLS(ssl));
+ assert(ssl->ctx->next_proto_select_cb != NULL);
+ assert(!(ssl->options & SSL_OP_DISABLE_NPN));
+
+ if (ssl->s3->alpn_selected != NULL) {
+ /* NPN and ALPN may not be negotiated in the same connection. */
+ *out_alert = SSL_AD_ILLEGAL_PARAMETER;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN);
+ return 0;
+ }
+
+ const uint8_t *const orig_contents = CBS_data(contents);
+ const size_t orig_len = CBS_len(contents);
+
+ while (CBS_len(contents) != 0) {
+ CBS proto;
+ if (!CBS_get_u8_length_prefixed(contents, &proto) ||
+ CBS_len(&proto) == 0) {
+ return 0;
+ }
+ }
+
+ uint8_t *selected;
uint8_t selected_len;
- int r;
+ if (ssl->ctx->next_proto_select_cb(
+ ssl, &selected, &selected_len, orig_contents, orig_len,
+ ssl->ctx->next_proto_select_cb_arg) != SSL_TLSEXT_ERR_OK) {
+ *out_alert = SSL_AD_INTERNAL_ERROR;
+ return 0;
+ }
+
+ OPENSSL_free(ssl->next_proto_negotiated);
+ ssl->next_proto_negotiated = BUF_memdup(selected, selected_len);
+ if (ssl->next_proto_negotiated == NULL) {
+ *out_alert = SSL_AD_INTERNAL_ERROR;
+ return 0;
+ }
- if (s->ctx->alpn_select_cb == NULL) {
+ ssl->next_proto_negotiated_len = selected_len;
+ ssl->s3->next_proto_neg_seen = 1;
+
+ return 1;
+}
+
+static int ext_npn_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents != NULL && CBS_len(contents) != 0) {
+ return 0;
+ }
+
+ if (contents == NULL ||
+ ssl->s3->initial_handshake_complete ||
+ /* If the ALPN extension is seen before NPN, ignore it. (If ALPN is seen
+ * afterwards, parsing the ALPN extension will clear
+ * |next_proto_neg_seen|. */
+ ssl->s3->alpn_selected != NULL ||
+ ssl->ctx->next_protos_advertised_cb == NULL ||
+ SSL_IS_DTLS(ssl)) {
return 1;
}
- if (!CBS_get_u16_length_prefixed(cbs, &protocol_name_list) ||
- CBS_len(cbs) != 0 || CBS_len(&protocol_name_list) < 2) {
- goto parse_error;
+ ssl->s3->next_proto_neg_seen = 1;
+ return 1;
+}
+
+static int ext_npn_add_serverhello(SSL *ssl, CBB *out) {
+ /* |next_proto_neg_seen| might have been cleared when an ALPN extension was
+ * parsed. */
+ if (!ssl->s3->next_proto_neg_seen) {
+ return 1;
+ }
+
+ const uint8_t *npa;
+ unsigned npa_len;
+
+ if (ssl->ctx->next_protos_advertised_cb(
+ ssl, &npa, &npa_len, ssl->ctx->next_protos_advertised_cb_arg) !=
+ SSL_TLSEXT_ERR_OK) {
+ ssl->s3->next_proto_neg_seen = 0;
+ return 1;
+ }
+
+ CBB contents;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_next_proto_neg) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_bytes(&contents, npa, npa_len) ||
+ !CBB_flush(out)) {
+ return 0;
+ }
+
+ return 1;
+}
+
+
+/* Signed certificate timestamps.
+ *
+ * https://tools.ietf.org/html/rfc6962#section-3.3.1 */
+
+static int ext_sct_add_clienthello(SSL *ssl, CBB *out) {
+ if (!ssl->signed_cert_timestamps_enabled) {
+ return 1;
+ }
+
+ if (!CBB_add_u16(out, TLSEXT_TYPE_certificate_timestamp) ||
+ !CBB_add_u16(out, 0 /* length */)) {
+ return 0;
+ }
+
+ return 1;
+}
+
+static int ext_sct_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return 1;
+ }
+
+ /* If this is false then we should never have sent the SCT extension in the
+ * ClientHello and thus this function should never have been called. */
+ assert(ssl->signed_cert_timestamps_enabled);
+
+ if (CBS_len(contents) == 0) {
+ *out_alert = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+
+ /* Session resumption uses the original session information. */
+ if (!ssl->hit &&
+ !CBS_stow(contents, &ssl->session->tlsext_signed_cert_timestamp_list,
+ &ssl->session->tlsext_signed_cert_timestamp_list_length)) {
+ *out_alert = SSL_AD_INTERNAL_ERROR;
+ return 0;
+ }
+
+ return 1;
+}
+
+static int ext_sct_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ return contents == NULL || CBS_len(contents) == 0;
+}
+
+static int ext_sct_add_serverhello(SSL *ssl, CBB *out) {
+ /* The extension shouldn't be sent when resuming sessions. */
+ if (ssl->hit ||
+ ssl->ctx->signed_cert_timestamp_list_length == 0) {
+ return 1;
+ }
+
+ CBB contents;
+ return CBB_add_u16(out, TLSEXT_TYPE_certificate_timestamp) &&
+ CBB_add_u16_length_prefixed(out, &contents) &&
+ CBB_add_bytes(&contents, ssl->ctx->signed_cert_timestamp_list,
+ ssl->ctx->signed_cert_timestamp_list_length) &&
+ CBB_flush(out);
+}
+
+
+/* Application-level Protocol Negotiation.
+ *
+ * https://tools.ietf.org/html/rfc7301 */
+
+static void ext_alpn_init(SSL *ssl) {
+ OPENSSL_free(ssl->s3->alpn_selected);
+ ssl->s3->alpn_selected = NULL;
+}
+
+static int ext_alpn_add_clienthello(SSL *ssl, CBB *out) {
+ if (ssl->alpn_client_proto_list == NULL ||
+ ssl->s3->initial_handshake_complete) {
+ return 1;
+ }
+
+ CBB contents, proto_list;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_application_layer_protocol_negotiation) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_u16_length_prefixed(&contents, &proto_list) ||
+ !CBB_add_bytes(&proto_list, ssl->alpn_client_proto_list,
+ ssl->alpn_client_proto_list_len) ||
+ !CBB_flush(out)) {
+ return 0;
+ }
+
+ return 1;
+}
+
+static int ext_alpn_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return 1;
+ }
+
+ assert(!ssl->s3->initial_handshake_complete);
+ assert(ssl->alpn_client_proto_list != NULL);
+
+ if (ssl->s3->next_proto_neg_seen) {
+ /* NPN and ALPN may not be negotiated in the same connection. */
+ *out_alert = SSL_AD_ILLEGAL_PARAMETER;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN);
+ return 0;
+ }
+
+ /* The extension data consists of a ProtocolNameList which must have
+ * exactly one ProtocolName. Each of these is length-prefixed. */
+ CBS protocol_name_list, protocol_name;
+ if (!CBS_get_u16_length_prefixed(contents, &protocol_name_list) ||
+ CBS_len(contents) != 0 ||
+ !CBS_get_u8_length_prefixed(&protocol_name_list, &protocol_name) ||
+ /* Empty protocol names are forbidden. */
+ CBS_len(&protocol_name) == 0 ||
+ CBS_len(&protocol_name_list) != 0) {
+ return 0;
+ }
+
+ if (!CBS_stow(&protocol_name, &ssl->s3->alpn_selected,
+ &ssl->s3->alpn_selected_len)) {
+ *out_alert = SSL_AD_INTERNAL_ERROR;
+ return 0;
+ }
+
+ return 1;
+}
+
+static int ext_alpn_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return 1;
+ }
+
+ if (ssl->ctx->alpn_select_cb == NULL ||
+ ssl->s3->initial_handshake_complete) {
+ return 1;
+ }
+
+ /* ALPN takes precedence over NPN. */
+ ssl->s3->next_proto_neg_seen = 0;
+
+ CBS protocol_name_list;
+ if (!CBS_get_u16_length_prefixed(contents, &protocol_name_list) ||
+ CBS_len(contents) != 0 ||
+ CBS_len(&protocol_name_list) < 2) {
+ return 0;
}
/* Validate the protocol list. */
- protocol_name_list_copy = protocol_name_list;
+ CBS protocol_name_list_copy = protocol_name_list;
while (CBS_len(&protocol_name_list_copy) > 0) {
CBS protocol_name;
- if (!CBS_get_u8_length_prefixed(&protocol_name_list_copy, &protocol_name)) {
- goto parse_error;
+ if (!CBS_get_u8_length_prefixed(&protocol_name_list_copy, &protocol_name) ||
+ /* Empty protocol names are forbidden. */
+ CBS_len(&protocol_name) == 0) {
+ return 0;
}
}
- r = s->ctx->alpn_select_cb(
- s, &selected, &selected_len, CBS_data(&protocol_name_list),
- CBS_len(&protocol_name_list), s->ctx->alpn_select_cb_arg);
- if (r == SSL_TLSEXT_ERR_OK) {
- OPENSSL_free(s->s3->alpn_selected);
- s->s3->alpn_selected = BUF_memdup(selected, selected_len);
- if (!s->s3->alpn_selected) {
+ const uint8_t *selected;
+ uint8_t selected_len;
+ if (ssl->ctx->alpn_select_cb(
+ ssl, &selected, &selected_len, CBS_data(&protocol_name_list),
+ CBS_len(&protocol_name_list),
+ ssl->ctx->alpn_select_cb_arg) == SSL_TLSEXT_ERR_OK) {
+ OPENSSL_free(ssl->s3->alpn_selected);
+ ssl->s3->alpn_selected = BUF_memdup(selected, selected_len);
+ if (ssl->s3->alpn_selected == NULL) {
*out_alert = SSL_AD_INTERNAL_ERROR;
return 0;
}
- s->s3->alpn_selected_len = selected_len;
+ ssl->s3->alpn_selected_len = selected_len;
}
return 1;
+}
-parse_error:
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
+static int ext_alpn_add_serverhello(SSL *ssl, CBB *out) {
+ if (ssl->s3->alpn_selected == NULL) {
+ return 1;
+ }
+
+ CBB contents, proto_list, proto;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_application_layer_protocol_negotiation) ||
+ !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_flush(out)) {
+ return 0;
+ }
+
+ return 1;
}
-static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert) {
- int renegotiate_seen = 0;
- CBS extensions;
- s->should_ack_sni = 0;
- s->srtp_profile = NULL;
- s->s3->next_proto_neg_seen = 0;
- s->s3->tmp.certificate_status_expected = 0;
- s->s3->tmp.extended_master_secret = 0;
+/* Channel ID.
+ *
+ * https://tools.ietf.org/html/draft-balfanz-tls-channelid-01 */
+
+static void ext_channel_id_init(SSL *ssl) {
+ ssl->s3->tlsext_channel_id_valid = 0;
+}
- OPENSSL_free(s->s3->alpn_selected);
- s->s3->alpn_selected = NULL;
+static int ext_channel_id_add_clienthello(SSL *ssl, CBB *out) {
+ if (!ssl->tlsext_channel_id_enabled ||
+ SSL_IS_DTLS(ssl)) {
+ return 1;
+ }
- /* Clear any signature algorithms extension received */
- OPENSSL_free(s->cert->peer_sigalgs);
- s->cert->peer_sigalgs = NULL;
- s->cert->peer_sigalgslen = 0;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_channel_id) ||
+ !CBB_add_u16(out, 0 /* length */)) {
+ return 0;
+ }
- /* Clear any shared signature algorithms */
- OPENSSL_free(s->cert->shared_sigalgs);
- s->cert->shared_sigalgs = NULL;
- s->cert->shared_sigalgslen = 0;
+ return 1;
+}
- /* Clear ECC extensions */
- OPENSSL_free(s->s3->tmp.peer_ecpointformatlist);
- s->s3->tmp.peer_ecpointformatlist = NULL;
- s->s3->tmp.peer_ecpointformatlist_length = 0;
+static int ext_channel_id_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return 1;
+ }
- OPENSSL_free(s->s3->tmp.peer_ellipticcurvelist);
- s->s3->tmp.peer_ellipticcurvelist = NULL;
- s->s3->tmp.peer_ellipticcurvelist_length = 0;
+ assert(!SSL_IS_DTLS(ssl));
+ assert(ssl->tlsext_channel_id_enabled);
- /* There may be no extensions. */
- if (CBS_len(cbs) == 0) {
- goto ri_check;
+ if (CBS_len(contents) != 0) {
+ return 0;
}
- /* Decode the extensions block and check it is valid. */
- if (!CBS_get_u16_length_prefixed(cbs, &extensions) ||
- !tls1_check_duplicate_extensions(&extensions)) {
- *out_alert = SSL_AD_DECODE_ERROR;
+ ssl->s3->tlsext_channel_id_valid = 1;
+ return 1;
+}
+
+static int ext_channel_id_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL ||
+ !ssl->tlsext_channel_id_enabled ||
+ SSL_IS_DTLS(ssl)) {
+ return 1;
+ }
+
+ if (CBS_len(contents) != 0) {
return 0;
}
- while (CBS_len(&extensions) != 0) {
- uint16_t type;
- CBS extension;
+ ssl->s3->tlsext_channel_id_valid = 1;
+ return 1;
+}
- /* Decode the next extension. */
- if (!CBS_get_u16(&extensions, &type) ||
- !CBS_get_u16_length_prefixed(&extensions, &extension)) {
- *out_alert = SSL_AD_DECODE_ERROR;
+static int ext_channel_id_add_serverhello(SSL *ssl, CBB *out) {
+ if (!ssl->s3->tlsext_channel_id_valid) {
+ return 1;
+ }
+
+ if (!CBB_add_u16(out, TLSEXT_TYPE_channel_id) ||
+ !CBB_add_u16(out, 0 /* length */)) {
+ return 0;
+ }
+
+ return 1;
+}
+
+
+/* Secure Real-time Transport Protocol (SRTP) extension.
+ *
+ * https://tools.ietf.org/html/rfc5764 */
+
+
+static void ext_srtp_init(SSL *ssl) {
+ ssl->srtp_profile = NULL;
+}
+
+static int ext_srtp_add_clienthello(SSL *ssl, CBB *out) {
+ STACK_OF(SRTP_PROTECTION_PROFILE) *profiles = SSL_get_srtp_profiles(ssl);
+ if (profiles == NULL) {
+ return 1;
+ }
+ const size_t num_profiles = sk_SRTP_PROTECTION_PROFILE_num(profiles);
+ if (num_profiles == 0) {
+ return 1;
+ }
+
+ CBB contents, profile_ids;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_srtp) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_u16_length_prefixed(&contents, &profile_ids)) {
+ return 0;
+ }
+
+ size_t i;
+ for (i = 0; i < num_profiles; i++) {
+ if (!CBB_add_u16(&profile_ids,
+ sk_SRTP_PROTECTION_PROFILE_value(profiles, i)->id)) {
return 0;
}
+ }
- /* The servername extension is treated as follows:
-
- - Only the hostname type is supported with a maximum length of 255.
- - The servername is rejected if too long or if it contains zeros, in
- which case an fatal alert is generated.
- - The servername field is maintained together with the session cache.
- - When a session is resumed, the servername call back invoked in order
- to allow the application to position itself to the right context.
- - The servername is acknowledged if it is new for a session or when
- it is identical to a previously used for the same session.
- Applications can control the behaviour. They can at any time
- set a 'desirable' servername for a new SSL object. This can be the
- case for example with HTTPS when a Host: header field is received and
- a renegotiation is requested. In this case, a possible servername
- presented in the new client hello is only acknowledged if it matches
- the value of the Host: field.
- - Applications must use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
- if they provide for changing an explicit servername context for the
- session,
- i.e. when the session has been established with a servername extension.
- - On session reconnect, the servername extension may be absent. */
-
- if (type == TLSEXT_TYPE_server_name) {
- CBS server_name_list;
- char have_seen_host_name = 0;
-
- if (!CBS_get_u16_length_prefixed(&extension, &server_name_list) ||
- CBS_len(&server_name_list) < 1 || CBS_len(&extension) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ if (!CBB_add_u8(&contents, 0 /* empty use_mki value */) ||
+ !CBB_flush(out)) {
+ return 0;
+ }
- /* Decode each ServerName in the extension. */
- while (CBS_len(&server_name_list) > 0) {
- uint8_t name_type;
- CBS host_name;
+ return 1;
+}
- /* Decode the NameType. */
- if (!CBS_get_u8(&server_name_list, &name_type)) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
+static int ext_srtp_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return 1;
+ }
- /* Only host_name is supported. */
- if (name_type != TLSEXT_NAMETYPE_host_name) {
- continue;
- }
+ /* The extension consists of a u16-prefixed profile ID list containing a
+ * single uint16_t profile ID, then followed by a u8-prefixed srtp_mki field.
+ *
+ * See https://tools.ietf.org/html/rfc5764#section-4.1.1 */
+ CBS profile_ids, srtp_mki;
+ uint16_t profile_id;
+ if (!CBS_get_u16_length_prefixed(contents, &profile_ids) ||
+ !CBS_get_u16(&profile_ids, &profile_id) ||
+ CBS_len(&profile_ids) != 0 ||
+ !CBS_get_u8_length_prefixed(contents, &srtp_mki) ||
+ CBS_len(contents) != 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+ return 0;
+ }
- if (have_seen_host_name) {
- /* The ServerNameList MUST NOT contain more than one name of the same
- * name_type. */
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ if (CBS_len(&srtp_mki) != 0) {
+ /* Must be no MKI, since we never offer one. */
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_MKI_VALUE);
+ *out_alert = SSL_AD_ILLEGAL_PARAMETER;
+ return 0;
+ }
- have_seen_host_name = 1;
+ STACK_OF(SRTP_PROTECTION_PROFILE) *profiles = SSL_get_srtp_profiles(ssl);
- if (!CBS_get_u16_length_prefixed(&server_name_list, &host_name) ||
- CBS_len(&host_name) < 1) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ /* Check to see if the server gave us something we support (and presumably
+ * offered). */
+ size_t i;
+ for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(profiles); i++) {
+ const SRTP_PROTECTION_PROFILE *profile =
+ sk_SRTP_PROTECTION_PROFILE_value(profiles, i);
- if (CBS_len(&host_name) > TLSEXT_MAXLEN_host_name ||
- CBS_contains_zero_byte(&host_name)) {
- *out_alert = SSL_AD_UNRECOGNIZED_NAME;
- return 0;
- }
+ if (profile->id == profile_id) {
+ ssl->srtp_profile = profile;
+ return 1;
+ }
+ }
- if (!s->hit) {
- assert(s->session->tlsext_hostname == NULL);
- if (s->session->tlsext_hostname) {
- /* This should be impossible. */
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
-
- /* Copy the hostname as a string. */
- if (!CBS_strdup(&host_name, &s->session->tlsext_hostname)) {
- *out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
-
- s->should_ack_sni = 1;
- }
- }
- } else if (type == TLSEXT_TYPE_ec_point_formats) {
- CBS ec_point_format_list;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+ *out_alert = SSL_AD_ILLEGAL_PARAMETER;
+ return 0;
+}
- if (!CBS_get_u8_length_prefixed(&extension, &ec_point_format_list) ||
- CBS_len(&extension) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
+static int ext_srtp_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return 1;
+ }
- if (!CBS_stow(&ec_point_format_list, &s->s3->tmp.peer_ecpointformatlist,
- &s->s3->tmp.peer_ecpointformatlist_length)) {
- *out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
- } else if (type == TLSEXT_TYPE_elliptic_curves) {
- CBS elliptic_curve_list;
- size_t i, num_curves;
-
- if (!CBS_get_u16_length_prefixed(&extension, &elliptic_curve_list) ||
- CBS_len(&elliptic_curve_list) == 0 ||
- (CBS_len(&elliptic_curve_list) & 1) != 0 ||
- CBS_len(&extension) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ CBS profile_ids, srtp_mki;
+ if (!CBS_get_u16_length_prefixed(contents, &profile_ids) ||
+ CBS_len(&profile_ids) < 2 ||
+ !CBS_get_u8_length_prefixed(contents, &srtp_mki) ||
+ CBS_len(contents) != 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+ return 0;
+ }
+ /* Discard the MKI value for now. */
- OPENSSL_free(s->s3->tmp.peer_ellipticcurvelist);
- s->s3->tmp.peer_ellipticcurvelist_length = 0;
+ const STACK_OF(SRTP_PROTECTION_PROFILE) *server_profiles =
+ SSL_get_srtp_profiles(ssl);
- s->s3->tmp.peer_ellipticcurvelist =
- (uint16_t *)OPENSSL_malloc(CBS_len(&elliptic_curve_list));
+ /* Pick the server's most preferred profile. */
+ size_t i;
+ for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(server_profiles); i++) {
+ const SRTP_PROTECTION_PROFILE *server_profile =
+ sk_SRTP_PROTECTION_PROFILE_value(server_profiles, i);
- if (s->s3->tmp.peer_ellipticcurvelist == NULL) {
- *out_alert = SSL_AD_INTERNAL_ERROR;
+ CBS profile_ids_tmp;
+ CBS_init(&profile_ids_tmp, CBS_data(&profile_ids), CBS_len(&profile_ids));
+
+ while (CBS_len(&profile_ids_tmp) > 0) {
+ uint16_t profile_id;
+ if (!CBS_get_u16(&profile_ids_tmp, &profile_id)) {
return 0;
}
- num_curves = CBS_len(&elliptic_curve_list) / 2;
- for (i = 0; i < num_curves; i++) {
- if (!CBS_get_u16(&elliptic_curve_list,
- &s->s3->tmp.peer_ellipticcurvelist[i])) {
- *out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
+ if (server_profile->id == profile_id) {
+ ssl->srtp_profile = server_profile;
+ return 1;
}
+ }
+ }
- if (CBS_len(&elliptic_curve_list) != 0) {
- *out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
+ return 1;
+}
- s->s3->tmp.peer_ellipticcurvelist_length = num_curves;
- } else if (type == TLSEXT_TYPE_renegotiate) {
- if (!ssl_parse_clienthello_renegotiate_ext(s, &extension, out_alert)) {
- return 0;
- }
- renegotiate_seen = 1;
- } else if (type == TLSEXT_TYPE_signature_algorithms) {
- CBS supported_signature_algorithms;
+static int ext_srtp_add_serverhello(SSL *ssl, CBB *out) {
+ if (ssl->srtp_profile == NULL) {
+ return 1;
+ }
- if (!CBS_get_u16_length_prefixed(&extension,
- &supported_signature_algorithms) ||
- CBS_len(&extension) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ CBB contents, profile_ids;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_srtp) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_u16_length_prefixed(&contents, &profile_ids) ||
+ !CBB_add_u16(&profile_ids, ssl->srtp_profile->id) ||
+ !CBB_add_u8(&contents, 0 /* empty MKI */) ||
+ !CBB_flush(out)) {
+ return 0;
+ }
- /* Ensure the signature algorithms are non-empty. It contains a list of
- * SignatureAndHashAlgorithms which are two bytes each. */
- if (CBS_len(&supported_signature_algorithms) == 0 ||
- (CBS_len(&supported_signature_algorithms) % 2) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ return 1;
+}
- if (!tls1_process_sigalgs(s, &supported_signature_algorithms)) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
- /* If sigalgs received and no shared algorithms fatal error. */
- if (s->cert->peer_sigalgs && !s->cert->shared_sigalgs) {
- OPENSSL_PUT_ERROR(SSL, ssl_scan_clienthello_tlsext,
- SSL_R_NO_SHARED_SIGATURE_ALGORITHMS);
- *out_alert = SSL_AD_ILLEGAL_PARAMETER;
- return 0;
- }
- } else if (type == TLSEXT_TYPE_next_proto_neg &&
- !s->s3->initial_handshake_complete &&
- s->s3->alpn_selected == NULL && !SSL_IS_DTLS(s)) {
- /* The extension must be empty. */
- if (CBS_len(&extension) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
- s->s3->next_proto_neg_seen = 1;
- } else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation &&
- s->ctx->alpn_select_cb && !s->s3->initial_handshake_complete) {
- if (!tls1_alpn_handle_client_hello(s, &extension, out_alert)) {
- return 0;
- }
- /* ALPN takes precedence over NPN. */
- s->s3->next_proto_neg_seen = 0;
- } else if (type == TLSEXT_TYPE_channel_id && s->tlsext_channel_id_enabled &&
- !SSL_IS_DTLS(s)) {
- /* The extension must be empty. */
- if (CBS_len(&extension) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
- s->s3->tlsext_channel_id_valid = 1;
- } else if (type == TLSEXT_TYPE_channel_id_new &&
- s->tlsext_channel_id_enabled && !SSL_IS_DTLS(s)) {
- /* The extension must be empty. */
- if (CBS_len(&extension) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
+/* EC point formats.
+ *
+ * https://tools.ietf.org/html/rfc4492#section-5.1.2 */
- s->s3->tlsext_channel_id_valid = 1;
- s->s3->tlsext_channel_id_new = 1;
- } else if (type == TLSEXT_TYPE_use_srtp) {
- if (!ssl_parse_clienthello_use_srtp_ext(s, &extension, out_alert)) {
- return 0;
- }
- } else if (type == TLSEXT_TYPE_extended_master_secret &&
- s->version != SSL3_VERSION) {
- if (CBS_len(&extension) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
+static int ssl_any_ec_cipher_suites_enabled(const SSL *ssl) {
+ if (ssl->version < TLS1_VERSION && !SSL_IS_DTLS(ssl)) {
+ return 0;
+ }
+
+ const STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(ssl);
- s->s3->tmp.extended_master_secret = 1;
+ size_t i;
+ for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) {
+ const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(cipher_stack, i);
+
+ const uint32_t alg_k = cipher->algorithm_mkey;
+ const uint32_t alg_a = cipher->algorithm_auth;
+ if ((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA)) {
+ return 1;
}
}
-ri_check:
- /* Need RI if renegotiating */
+ return 0;
+}
- if (!renegotiate_seen && s->s3->initial_handshake_complete &&
- !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
- *out_alert = SSL_AD_HANDSHAKE_FAILURE;
- OPENSSL_PUT_ERROR(SSL, ssl_scan_clienthello_tlsext,
- SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
+static int ext_ec_point_add_extension(SSL *ssl, CBB *out) {
+ CBB contents, formats;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_ec_point_formats) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_u8_length_prefixed(&contents, &formats) ||
+ !CBB_add_u8(&formats, TLSEXT_ECPOINTFORMAT_uncompressed) ||
+ !CBB_flush(out)) {
return 0;
}
return 1;
}
-int ssl_parse_clienthello_tlsext(SSL *s, CBS *cbs) {
- int alert = -1;
- if (ssl_scan_clienthello_tlsext(s, cbs, &alert) <= 0) {
- ssl3_send_alert(s, SSL3_AL_FATAL, alert);
+static int ext_ec_point_add_clienthello(SSL *ssl, CBB *out) {
+ if (!ssl_any_ec_cipher_suites_enabled(ssl)) {
+ return 1;
+ }
+
+ return ext_ec_point_add_extension(ssl, out);
+}
+
+static int ext_ec_point_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return 1;
+ }
+
+ CBS ec_point_format_list;
+ if (!CBS_get_u8_length_prefixed(contents, &ec_point_format_list) ||
+ CBS_len(contents) != 0) {
return 0;
}
- if (ssl_check_clienthello_tlsext(s) <= 0) {
- OPENSSL_PUT_ERROR(SSL, ssl_parse_clienthello_tlsext,
- SSL_R_CLIENTHELLO_TLSEXT);
+ /* Per RFC 4492, section 5.1.2, implementations MUST support the uncompressed
+ * point format. */
+ if (memchr(CBS_data(&ec_point_format_list), TLSEXT_ECPOINTFORMAT_uncompressed,
+ CBS_len(&ec_point_format_list)) == NULL) {
+ *out_alert = SSL_AD_ILLEGAL_PARAMETER;
return 0;
}
return 1;
}
-/* ssl_next_proto_validate validates a Next Protocol Negotiation block. No
- * elements of zero length are allowed and the set of elements must exactly
- * fill the length of the block. */
-static char ssl_next_proto_validate(const CBS *cbs) {
- CBS copy = *cbs;
+static int ext_ec_point_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ return ext_ec_point_parse_serverhello(ssl, out_alert, contents);
+}
- while (CBS_len(&copy) != 0) {
- CBS proto;
- if (!CBS_get_u8_length_prefixed(&copy, &proto) || CBS_len(&proto) == 0) {
+static int ext_ec_point_add_serverhello(SSL *ssl, CBB *out) {
+ const uint32_t alg_k = ssl->s3->tmp.new_cipher->algorithm_mkey;
+ const uint32_t alg_a = ssl->s3->tmp.new_cipher->algorithm_auth;
+ const int using_ecc = (alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA);
+
+ if (!using_ecc) {
+ return 1;
+ }
+
+ return ext_ec_point_add_extension(ssl, out);
+}
+
+
+/* EC supported curves.
+ *
+ * https://tools.ietf.org/html/rfc4492#section-5.1.2 */
+
+static void ext_ec_curves_init(SSL *ssl) {
+ OPENSSL_free(ssl->s3->tmp.peer_ellipticcurvelist);
+ ssl->s3->tmp.peer_ellipticcurvelist = NULL;
+ ssl->s3->tmp.peer_ellipticcurvelist_length = 0;
+}
+
+static int ext_ec_curves_add_clienthello(SSL *ssl, CBB *out) {
+ if (!ssl_any_ec_cipher_suites_enabled(ssl)) {
+ return 1;
+ }
+
+ CBB contents, curves_bytes;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_elliptic_curves) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_u16_length_prefixed(&contents, &curves_bytes)) {
+ return 0;
+ }
+
+ const uint16_t *curves;
+ size_t curves_len;
+ tls1_get_curvelist(ssl, 0, &curves, &curves_len);
+
+ size_t i;
+ for (i = 0; i < curves_len; i++) {
+ if (!CBB_add_u16(&curves_bytes, curves[i])) {
return 0;
}
}
+ return CBB_flush(out);
+}
+
+static int ext_ec_curves_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ /* This extension is not expected to be echoed by servers and is ignored. */
return 1;
}
-static int ssl_scan_serverhello_tlsext(SSL *s, CBS *cbs, int *out_alert) {
- int tlsext_servername = 0;
- int renegotiate_seen = 0;
- CBS extensions;
+static int ext_ec_curves_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return 1;
+ }
- /* TODO(davidben): Move all of these to some per-handshake state that gets
- * systematically reset on a new handshake; perhaps allocate it fresh each
- * time so it's not even kept around post-handshake. */
- s->s3->next_proto_neg_seen = 0;
- s->tlsext_ticket_expected = 0;
- s->s3->tmp.certificate_status_expected = 0;
- s->s3->tmp.extended_master_secret = 0;
- s->srtp_profile = NULL;
+ CBS elliptic_curve_list;
+ if (!CBS_get_u16_length_prefixed(contents, &elliptic_curve_list) ||
+ CBS_len(&elliptic_curve_list) == 0 ||
+ (CBS_len(&elliptic_curve_list) & 1) != 0 ||
+ CBS_len(contents) != 0) {
+ return 0;
+ }
- OPENSSL_free(s->s3->alpn_selected);
- s->s3->alpn_selected = NULL;
+ ssl->s3->tmp.peer_ellipticcurvelist =
+ (uint16_t *)OPENSSL_malloc(CBS_len(&elliptic_curve_list));
- /* Clear ECC extensions */
- OPENSSL_free(s->s3->tmp.peer_ecpointformatlist);
- s->s3->tmp.peer_ecpointformatlist = NULL;
- s->s3->tmp.peer_ecpointformatlist_length = 0;
+ if (ssl->s3->tmp.peer_ellipticcurvelist == NULL) {
+ *out_alert = SSL_AD_INTERNAL_ERROR;
+ return 0;
+ }
- /* There may be no extensions. */
- if (CBS_len(cbs) == 0) {
- goto ri_check;
+ const size_t num_curves = CBS_len(&elliptic_curve_list) / 2;
+ size_t i;
+ for (i = 0; i < num_curves; i++) {
+ if (!CBS_get_u16(&elliptic_curve_list,
+ &ssl->s3->tmp.peer_ellipticcurvelist[i])) {
+ goto err;
+ }
}
- /* Decode the extensions block and check it is valid. */
- if (!CBS_get_u16_length_prefixed(cbs, &extensions) ||
- !tls1_check_duplicate_extensions(&extensions)) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
+ assert(CBS_len(&elliptic_curve_list) == 0);
+ ssl->s3->tmp.peer_ellipticcurvelist_length = num_curves;
+
+ return 1;
+
+err:
+ OPENSSL_free(ssl->s3->tmp.peer_ellipticcurvelist);
+ ssl->s3->tmp.peer_ellipticcurvelist = NULL;
+ *out_alert = SSL_AD_INTERNAL_ERROR;
+ return 0;
+}
+
+static int ext_ec_curves_add_serverhello(SSL *ssl, CBB *out) {
+ /* Servers don't echo this extension. */
+ return 1;
+}
+
+
+/* kExtensions contains all the supported extensions. */
+static const struct tls_extension kExtensions[] = {
+ {
+ /* 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. */
+ TLSEXT_TYPE_renegotiate,
+ NULL,
+ ext_ri_add_clienthello,
+ ext_ri_parse_serverhello,
+ ext_ri_parse_clienthello,
+ ext_ri_add_serverhello,
+ },
+ {
+ TLSEXT_TYPE_server_name,
+ ext_sni_init,
+ ext_sni_add_clienthello,
+ ext_sni_parse_serverhello,
+ ext_sni_parse_clienthello,
+ ext_sni_add_serverhello,
+ },
+ {
+ TLSEXT_TYPE_extended_master_secret,
+ ext_ems_init,
+ ext_ems_add_clienthello,
+ ext_ems_parse_serverhello,
+ ext_ems_parse_clienthello,
+ ext_ems_add_serverhello,
+ },
+ {
+ TLSEXT_TYPE_session_ticket,
+ NULL,
+ ext_ticket_add_clienthello,
+ ext_ticket_parse_serverhello,
+ ext_ticket_parse_clienthello,
+ ext_ticket_add_serverhello,
+ },
+ {
+ TLSEXT_TYPE_signature_algorithms,
+ NULL,
+ ext_sigalgs_add_clienthello,
+ ext_sigalgs_parse_serverhello,
+ ext_sigalgs_parse_clienthello,
+ ext_sigalgs_add_serverhello,
+ },
+ {
+ TLSEXT_TYPE_status_request,
+ ext_ocsp_init,
+ ext_ocsp_add_clienthello,
+ ext_ocsp_parse_serverhello,
+ ext_ocsp_parse_clienthello,
+ ext_ocsp_add_serverhello,
+ },
+ {
+ TLSEXT_TYPE_next_proto_neg,
+ ext_npn_init,
+ ext_npn_add_clienthello,
+ ext_npn_parse_serverhello,
+ ext_npn_parse_clienthello,
+ ext_npn_add_serverhello,
+ },
+ {
+ TLSEXT_TYPE_certificate_timestamp,
+ NULL,
+ ext_sct_add_clienthello,
+ ext_sct_parse_serverhello,
+ ext_sct_parse_clienthello,
+ ext_sct_add_serverhello,
+ },
+ {
+ TLSEXT_TYPE_application_layer_protocol_negotiation,
+ ext_alpn_init,
+ ext_alpn_add_clienthello,
+ ext_alpn_parse_serverhello,
+ ext_alpn_parse_clienthello,
+ ext_alpn_add_serverhello,
+ },
+ {
+ TLSEXT_TYPE_channel_id,
+ ext_channel_id_init,
+ ext_channel_id_add_clienthello,
+ ext_channel_id_parse_serverhello,
+ ext_channel_id_parse_clienthello,
+ ext_channel_id_add_serverhello,
+ },
+ {
+ TLSEXT_TYPE_srtp,
+ ext_srtp_init,
+ ext_srtp_add_clienthello,
+ ext_srtp_parse_serverhello,
+ ext_srtp_parse_clienthello,
+ ext_srtp_add_serverhello,
+ },
+ {
+ TLSEXT_TYPE_ec_point_formats,
+ NULL,
+ ext_ec_point_add_clienthello,
+ ext_ec_point_parse_serverhello,
+ ext_ec_point_parse_clienthello,
+ ext_ec_point_add_serverhello,
+ },
+ {
+ TLSEXT_TYPE_elliptic_curves,
+ ext_ec_curves_init,
+ ext_ec_curves_add_clienthello,
+ ext_ec_curves_parse_serverhello,
+ ext_ec_curves_parse_clienthello,
+ ext_ec_curves_add_serverhello,
+ },
+};
+
+#define kNumExtensions (sizeof(kExtensions) / sizeof(struct tls_extension))
+
+OPENSSL_COMPILE_ASSERT(kNumExtensions <=
+ sizeof(((SSL *)NULL)->s3->tmp.extensions.sent) * 8,
+ too_many_extensions_for_sent_bitset);
+OPENSSL_COMPILE_ASSERT(kNumExtensions <=
+ sizeof(((SSL *)NULL)->s3->tmp.extensions.received) *
+ 8,
+ too_many_extensions_for_received_bitset);
+
+static const struct tls_extension *tls_extension_find(uint32_t *out_index,
+ uint16_t value) {
+ unsigned i;
+ for (i = 0; i < kNumExtensions; i++) {
+ if (kExtensions[i].value == value) {
+ *out_index = i;
+ return &kExtensions[i];
+ }
}
- while (CBS_len(&extensions) != 0) {
- uint16_t type;
- CBS extension;
+ return NULL;
+}
- /* Decode the next extension. */
- if (!CBS_get_u16(&extensions, &type) ||
- !CBS_get_u16_length_prefixed(&extensions, &extension)) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
+int SSL_extension_supported(unsigned extension_value) {
+ uint32_t index;
+ return extension_value == TLSEXT_TYPE_padding ||
+ tls_extension_find(&index, extension_value) != NULL;
+}
+
+int ssl_add_clienthello_tlsext(SSL *ssl, CBB *out, size_t header_len) {
+ /* don't add extensions for SSLv3 unless doing secure renegotiation */
+ if (ssl->client_version == SSL3_VERSION &&
+ !ssl->s3->send_connection_binding) {
+ return 1;
+ }
+
+ CBB extensions;
+ if (!CBB_add_u16_length_prefixed(out, &extensions)) {
+ goto err;
+ }
+
+ ssl->s3->tmp.extensions.sent = 0;
+ ssl->s3->tmp.custom_extensions.sent = 0;
+
+ size_t i;
+ for (i = 0; i < kNumExtensions; i++) {
+ if (kExtensions[i].init != NULL) {
+ kExtensions[i].init(ssl);
}
+ }
- if (type == TLSEXT_TYPE_server_name) {
- /* The extension must be empty. */
- if (CBS_len(&extension) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ for (i = 0; i < kNumExtensions; i++) {
+ const size_t len_before = CBB_len(&extensions);
+ if (!kExtensions[i].add_clienthello(ssl, &extensions)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_ADDING_EXTENSION);
+ ERR_add_error_dataf("extension: %u", (unsigned)kExtensions[i].value);
+ goto err;
+ }
- /* We must have sent it in ClientHello. */
- if (s->tlsext_hostname == NULL) {
- *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
- return 0;
- }
+ if (CBB_len(&extensions) != len_before) {
+ ssl->s3->tmp.extensions.sent |= (1u << i);
+ }
+ }
- tlsext_servername = 1;
- } else if (type == TLSEXT_TYPE_ec_point_formats) {
- CBS ec_point_format_list;
+ if (!custom_ext_add_clienthello(ssl, &extensions)) {
+ goto err;
+ }
- if (!CBS_get_u8_length_prefixed(&extension, &ec_point_format_list) ||
- CBS_len(&extension) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
+ if (!SSL_IS_DTLS(ssl)) {
+ header_len += 2 + CBB_len(&extensions);
+ if (header_len > 0xff && header_len < 0x200) {
+ /* Add padding to workaround bugs in F5 terminators. See RFC 7685.
+ *
+ * NB: because this code works out the length of all existing extensions
+ * it MUST always appear last. */
+ size_t padding_len = 0x200 - header_len;
+ /* Extensions take at least four bytes to encode. Always include least
+ * one byte of data if including the extension. WebSphere Application
+ * Server 7.0 is intolerant to the last extension being zero-length. */
+ if (padding_len >= 4 + 1) {
+ padding_len -= 4;
+ } else {
+ padding_len = 1;
}
- if (!CBS_stow(&ec_point_format_list, &s->s3->tmp.peer_ecpointformatlist,
- &s->s3->tmp.peer_ecpointformatlist_length)) {
- *out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
- } else if (type == TLSEXT_TYPE_session_ticket) {
- if ((SSL_get_options(s) & SSL_OP_NO_TICKET) || CBS_len(&extension) > 0) {
- *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
- return 0;
+ uint8_t *padding_bytes;
+ if (!CBB_add_u16(&extensions, TLSEXT_TYPE_padding) ||
+ !CBB_add_u16(&extensions, padding_len) ||
+ !CBB_add_space(&extensions, &padding_bytes, padding_len)) {
+ goto err;
}
- s->tlsext_ticket_expected = 1;
- } else if (type == TLSEXT_TYPE_status_request) {
- /* The extension MUST be empty and may only sent if we've requested a
- * status request message. */
- if (CBS_len(&extension) != 0) {
+ memset(padding_bytes, 0, padding_len);
+ }
+ }
+
+ /* Discard empty extensions blocks. */
+ if (CBB_len(&extensions) == 0) {
+ CBB_discard_child(out);
+ }
+
+ return CBB_flush(out);
+
+err:
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return 0;
+}
+
+int ssl_add_serverhello_tlsext(SSL *ssl, CBB *out) {
+ CBB extensions;
+ if (!CBB_add_u16_length_prefixed(out, &extensions)) {
+ goto err;
+ }
+
+ unsigned i;
+ for (i = 0; i < kNumExtensions; i++) {
+ if (!(ssl->s3->tmp.extensions.received & (1u << i))) {
+ /* Don't send extensions that were not received. */
+ continue;
+ }
+
+ if (!kExtensions[i].add_serverhello(ssl, &extensions)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_ADDING_EXTENSION);
+ ERR_add_error_dataf("extension: %u", (unsigned)kExtensions[i].value);
+ goto err;
+ }
+ }
+
+ if (!custom_ext_add_serverhello(ssl, &extensions)) {
+ goto err;
+ }
+
+ /* Discard empty extensions blocks. */
+ if (CBB_len(&extensions) == 0) {
+ CBB_discard_child(out);
+ }
+
+ return CBB_flush(out);
+
+err:
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return 0;
+}
+
+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(ssl);
+ }
+ }
+
+ 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. */
+ assert(kExtensions[0].value == TLSEXT_TYPE_renegotiate);
+
+ /* There may be no extensions. */
+ if (CBS_len(cbs) != 0) {
+ /* Decode the extensions block and check it is valid. */
+ CBS extensions;
+ if (!CBS_get_u16_length_prefixed(cbs, &extensions) ||
+ !tls1_check_duplicate_extensions(&extensions)) {
+ *out_alert = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+
+ while (CBS_len(&extensions) != 0) {
+ uint16_t type;
+ CBS extension;
+
+ /* Decode the next extension. */
+ if (!CBS_get_u16(&extensions, &type) ||
+ !CBS_get_u16_length_prefixed(&extensions, &extension)) {
*out_alert = SSL_AD_DECODE_ERROR;
return 0;
}
- if (!s->ocsp_stapling_enabled) {
- *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
- return 0;
+ /* RFC 5746 made the existence of extensions in SSL 3.0 somewhat
+ * ambiguous. Ignore all but the renegotiation_info extension. */
+ if (ssl->version == SSL3_VERSION && type != TLSEXT_TYPE_renegotiate) {
+ continue;
}
- /* Set a flag to expect a CertificateStatus message */
- s->s3->tmp.certificate_status_expected = 1;
- } else if (type == TLSEXT_TYPE_next_proto_neg &&
- !s->s3->initial_handshake_complete && !SSL_IS_DTLS(s)) {
- uint8_t *selected;
- uint8_t selected_len;
+ unsigned ext_index;
+ const struct tls_extension *const ext =
+ tls_extension_find(&ext_index, type);
- /* We must have requested it. */
- if (s->ctx->next_proto_select_cb == NULL) {
- *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
- return 0;
+ if (ext == NULL) {
+ if (!custom_ext_parse_clienthello(ssl, out_alert, type, &extension)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
+ return 0;
+ }
+ continue;
}
- /* The data must be valid. */
- if (!ssl_next_proto_validate(&extension)) {
- *out_alert = SSL_AD_DECODE_ERROR;
+ ssl->s3->tmp.extensions.received |= (1u << ext_index);
+ uint8_t alert = SSL_AD_DECODE_ERROR;
+ 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);
return 0;
}
+ }
+ }
- if (s->ctx->next_proto_select_cb(
- s, &selected, &selected_len, CBS_data(&extension),
- CBS_len(&extension),
- s->ctx->next_proto_select_cb_arg) != SSL_TLSEXT_ERR_OK) {
- *out_alert = SSL_AD_INTERNAL_ERROR;
+ for (i = 0; i < kNumExtensions; 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(ssl, &alert, NULL)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION);
+ ERR_add_error_dataf("extension: %u", (unsigned)kExtensions[i].value);
+ *out_alert = alert;
return 0;
}
+ }
+ }
- s->next_proto_negotiated = BUF_memdup(selected, selected_len);
- if (s->next_proto_negotiated == NULL) {
- *out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
+ return 1;
+}
- s->next_proto_negotiated_len = selected_len;
- s->s3->next_proto_neg_seen = 1;
- } else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation &&
- !s->s3->initial_handshake_complete) {
- CBS protocol_name_list, protocol_name;
+int ssl_parse_clienthello_tlsext(SSL *ssl, CBS *cbs) {
+ int alert = -1;
+ if (ssl_scan_clienthello_tlsext(ssl, cbs, &alert) <= 0) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ return 0;
+ }
- /* We must have requested it. */
- if (s->alpn_client_proto_list == NULL) {
- *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
- return 0;
- }
+ if (ssl_check_clienthello_tlsext(ssl) <= 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_TLSEXT);
+ return 0;
+ }
- /* The extension data consists of a ProtocolNameList which must have
- * exactly one ProtocolName. Each of these is length-prefixed. */
- if (!CBS_get_u16_length_prefixed(&extension, &protocol_name_list) ||
- CBS_len(&extension) != 0 ||
- !CBS_get_u8_length_prefixed(&protocol_name_list, &protocol_name) ||
- CBS_len(&protocol_name_list) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ return 1;
+}
- if (!CBS_stow(&protocol_name, &s->s3->alpn_selected,
- &s->s3->alpn_selected_len)) {
- *out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
- } else if (type == TLSEXT_TYPE_channel_id && !SSL_IS_DTLS(s)) {
- if (CBS_len(&extension) != 0) {
+OPENSSL_COMPILE_ASSERT(kNumExtensions <= sizeof(uint32_t) * 8, too_many_bits);
+
+static int ssl_scan_serverhello_tlsext(SSL *ssl, CBS *cbs, int *out_alert) {
+ uint32_t received = 0;
+
+ if (CBS_len(cbs) != 0) {
+ /* Decode the extensions block and check it is valid. */
+ CBS extensions;
+ if (!CBS_get_u16_length_prefixed(cbs, &extensions) ||
+ !tls1_check_duplicate_extensions(&extensions)) {
+ *out_alert = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+
+
+ while (CBS_len(&extensions) != 0) {
+ uint16_t type;
+ CBS extension;
+
+ /* Decode the next extension. */
+ if (!CBS_get_u16(&extensions, &type) ||
+ !CBS_get_u16_length_prefixed(&extensions, &extension)) {
*out_alert = SSL_AD_DECODE_ERROR;
return 0;
}
- s->s3->tlsext_channel_id_valid = 1;
- } else if (type == TLSEXT_TYPE_channel_id_new && !SSL_IS_DTLS(s)) {
- if (CBS_len(&extension) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
+ unsigned ext_index;
+ const struct tls_extension *const ext =
+ tls_extension_find(&ext_index, type);
+
+ if (ext == NULL) {
+ if (!custom_ext_parse_serverhello(ssl, out_alert, type, &extension)) {
+ return 0;
+ }
+ continue;
}
- s->s3->tlsext_channel_id_valid = 1;
- s->s3->tlsext_channel_id_new = 1;
- } else if (type == TLSEXT_TYPE_certificate_timestamp) {
- if (CBS_len(&extension) == 0) {
+ 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);
*out_alert = SSL_AD_DECODE_ERROR;
return 0;
}
- /* Session resumption uses the original session information. */
- if (!s->hit &&
- !CBS_stow(&extension, &s->session->tlsext_signed_cert_timestamp_list,
- &s->session->tlsext_signed_cert_timestamp_list_length)) {
- *out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
- } else if (type == TLSEXT_TYPE_renegotiate) {
- if (!ssl_parse_serverhello_renegotiate_ext(s, &extension, out_alert)) {
- return 0;
- }
+ received |= (1u << ext_index);
- renegotiate_seen = 1;
- } else if (type == TLSEXT_TYPE_use_srtp) {
- if (!ssl_parse_serverhello_use_srtp_ext(s, &extension, out_alert)) {
+ uint8_t alert = SSL_AD_DECODE_ERROR;
+ 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;
return 0;
}
- } else if (type == TLSEXT_TYPE_extended_master_secret) {
- if (/* It is invalid for the server to select EMS and
- SSLv3. */
- s->version == SSL3_VERSION || CBS_len(&extension) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
-
- s->s3->tmp.extended_master_secret = 1;
}
}
- if (!s->hit && tlsext_servername == 1 && s->tlsext_hostname) {
- if (s->session->tlsext_hostname == NULL) {
- s->session->tlsext_hostname = BUF_strdup(s->tlsext_hostname);
- if (!s->session->tlsext_hostname) {
- *out_alert = SSL_AD_UNRECOGNIZED_NAME;
+ size_t i;
+ for (i = 0; i < kNumExtensions; i++) {
+ if (!(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_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;
return 0;
}
- } else {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
}
}
-ri_check:
- /* Determine if we need to see RI. Strictly speaking if we want to avoid an
- * attack we should *always* see RI even on initial server hello 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 so for
- * the immediate future tolerate RI absence on initial connect only. */
- if (!renegotiate_seen && !(s->options & SSL_OP_LEGACY_SERVER_CONNECT) &&
- !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
- *out_alert = SSL_AD_HANDSHAKE_FAILURE;
- OPENSSL_PUT_ERROR(SSL, ssl_scan_serverhello_tlsext,
- SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
- return 0;
- }
-
return 1;
}
-int ssl_prepare_clienthello_tlsext(SSL *s) { return 1; }
-
-int ssl_prepare_serverhello_tlsext(SSL *s) { 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->should_ack_sni = 0;
+ ssl->s3->tmp.should_ack_sni = 0;
return 1;
default:
@@ -1955,39 +2441,26 @@ static int ssl_check_clienthello_tlsext(SSL *s) {
}
}
-static int ssl_check_serverhello_tlsext(SSL *s) {
- int ret = SSL_TLSEXT_ERR_NOACK;
+static int ssl_check_serverhello_tlsext(SSL *ssl) {
+ int ret = SSL_TLSEXT_ERR_OK;
int al = SSL_AD_UNRECOGNIZED_NAME;
- /* If we are client and using an elliptic curve cryptography cipher suite,
- * then if server returns an EC point formats lists extension it must contain
- * uncompressed. */
- uint32_t alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
- uint32_t alg_a = s->s3->tmp.new_cipher->algorithm_auth;
- if (((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA)) &&
- !tls1_check_point_format(s, TLSEXT_ECPOINTFORMAT_uncompressed)) {
- OPENSSL_PUT_ERROR(SSL, ssl_check_serverhello_tlsext,
- SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST);
- return -1;
- }
- ret = SSL_TLSEXT_ERR_OK;
-
- 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:
@@ -1995,215 +2468,139 @@ 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 (s->version < SSL3_VERSION) {
- return 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) {
- OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_tlsext,
- SSL_R_SERVERHELLO_TLSEXT);
+ if (ssl_check_serverhello_tlsext(ssl) <= 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SERVERHELLO_TLSEXT);
return 0;
}
return 1;
}
-/* Since the server cache lookup is done early on in the processing of the
- * ClientHello, and other operations depend on the result, we need to handle
- * any TLS session ticket extension at the same time.
- *
- * ctx: contains the early callback context, which is the result of a
- * shallow parse of the ClientHello.
- * ret: (output) on return, if a ticket was decrypted, then this is set to
- * point to the resulting session.
- *
- * Returns:
- * -1: fatal error, either from parsing or decrypting the ticket.
- * 0: no ticket was found (or was ignored, based on settings).
- * 1: a zero length extension was found, indicating that the client supports
- * session tickets but doesn't currently have one to offer.
- * 2: a ticket was offered but couldn't be decrypted because of a non-fatal
- * error.
- * 3: a ticket was successfully decrypted and *ret was set.
- *
- * Side effects:
- * Sets s->tlsext_ticket_expected to 1 if the server will have to issue
- * a new session ticket to the client because the client indicated support
- * but the client either doesn't have a session ticket or we couldn't use
- * the one it gave us, or if s->ctx->tlsext_ticket_key_cb asked to renew
- * the client's ticket. Otherwise, s->tlsext_ticket_expected is set to 0.
- */
-int tls1_process_ticket(SSL *s, const struct ssl_early_callback_ctx *ctx,
- SSL_SESSION **ret) {
- *ret = NULL;
- s->tlsext_ticket_expected = 0;
- const uint8_t *data;
- size_t len;
- int r;
-
- /* If tickets disabled behave as if no ticket present to permit stateful
- * resumption. */
- if ((SSL_get_options(s) & SSL_OP_NO_TICKET) ||
- (s->version <= SSL3_VERSION && !ctx->extensions) ||
- !SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_session_ticket,
- &data, &len)) {
- return 0;
- }
-
- if (len == 0) {
- /* The client will accept a ticket but doesn't currently have one. */
- s->tlsext_ticket_expected = 1;
- return 1;
- }
-
- r = tls_decrypt_ticket(s, data, len, ctx->session_id, ctx->session_id_len,
- ret);
- switch (r) {
- case 2: /* ticket couldn't be decrypted */
- s->tlsext_ticket_expected = 1;
- return 2;
+int tls_process_ticket(SSL *ssl, SSL_SESSION **out_session,
+ int *out_send_ticket, const uint8_t *ticket,
+ size_t ticket_len, const uint8_t *session_id,
+ size_t session_id_len) {
+ int ret = 1; /* Most errors are non-fatal. */
+ SSL_CTX *ssl_ctx = ssl->initial_ctx;
+ uint8_t *plaintext = NULL;
- case 3: /* ticket was decrypted */
- return r;
+ HMAC_CTX hmac_ctx;
+ HMAC_CTX_init(&hmac_ctx);
+ EVP_CIPHER_CTX cipher_ctx;
+ EVP_CIPHER_CTX_init(&cipher_ctx);
- case 4: /* ticket decrypted but need to renew */
- s->tlsext_ticket_expected = 1;
- return 3;
+ *out_send_ticket = 0;
+ *out_session = NULL;
- default: /* fatal error */
- return -1;
+ if (session_id_len > SSL_MAX_SSL_SESSION_ID_LENGTH) {
+ goto done;
}
-}
-/* tls_decrypt_ticket attempts to decrypt a session ticket.
- *
- * etick: points to the body of the session ticket extension.
- * eticklen: the length of the session tickets extenion.
- * sess_id: points at the session ID.
- * sesslen: the length of the session ID.
- * psess: (output) on return, if a ticket was decrypted, then this is set to
- * point to the resulting session.
- *
- * Returns:
- * -1: fatal error, either from parsing or decrypting the ticket.
- * 2: the ticket couldn't be decrypted.
- * 3: a ticket was successfully decrypted and *psess was set.
- * 4: same as 3, but the ticket needs to be renewed. */
-static int tls_decrypt_ticket(SSL *s, const uint8_t *etick, int eticklen,
- const uint8_t *sess_id, int sesslen,
- SSL_SESSION **psess) {
- SSL_SESSION *sess;
- uint8_t *sdec;
- const uint8_t *p;
- int slen, mlen, renew_ticket = 0;
- uint8_t tick_hmac[EVP_MAX_MD_SIZE];
- HMAC_CTX hctx;
- EVP_CIPHER_CTX ctx;
- SSL_CTX *tctx = s->initial_ctx;
+ if (ticket_len == 0) {
+ /* The client will accept a ticket but doesn't currently have one. */
+ *out_send_ticket = 1;
+ goto done;
+ }
/* Ensure there is room for the key name and the largest IV
* |tlsext_ticket_key_cb| may try to consume. The real limit may be lower, but
* the maximum IV length should be well under the minimum size for the
* session material and HMAC. */
- if (eticklen < 16 + EVP_MAX_IV_LENGTH) {
- return 2;
- }
-
- /* Initialize session ticket encryption and HMAC contexts */
- HMAC_CTX_init(&hctx);
- EVP_CIPHER_CTX_init(&ctx);
- if (tctx->tlsext_ticket_key_cb) {
- uint8_t *nctick = (uint8_t *)etick;
- int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16, &ctx, &hctx,
- 0 /* decrypt */);
- if (rv < 0) {
- return -1;
+ if (ticket_len < SSL_TICKET_KEY_NAME_LEN + EVP_MAX_IV_LENGTH) {
+ goto done;
+ }
+ 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 */);
+ if (cb_ret < 0) {
+ ret = 0;
+ goto done;
}
- if (rv == 0) {
- return 2;
+ if (cb_ret == 0) {
+ goto done;
}
- if (rv == 2) {
- renew_ticket = 1;
+ if (cb_ret == 2) {
+ *out_send_ticket = 1;
}
} else {
- /* Check key name matches */
- if (memcmp(etick, tctx->tlsext_tick_key_name, 16)) {
- return 2;
+ /* Check the key name matches. */
+ if (memcmp(ticket, ssl_ctx->tlsext_tick_key_name,
+ SSL_TICKET_KEY_NAME_LEN) != 0) {
+ goto done;
}
- if (!HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, tlsext_tick_md(),
+ if (!HMAC_Init_ex(&hmac_ctx, ssl_ctx->tlsext_tick_hmac_key,
+ sizeof(ssl_ctx->tlsext_tick_hmac_key), tlsext_tick_md(),
NULL) ||
- !EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
- tctx->tlsext_tick_aes_key, etick + 16)) {
- HMAC_CTX_cleanup(&hctx);
- EVP_CIPHER_CTX_cleanup(&ctx);
- return -1;
+ !EVP_DecryptInit_ex(&cipher_ctx, EVP_aes_128_cbc(), NULL,
+ ssl_ctx->tlsext_tick_aes_key, iv)) {
+ ret = 0;
+ goto done;
}
}
+ size_t iv_len = EVP_CIPHER_CTX_iv_length(&cipher_ctx);
- /* First, check the MAC. The MAC is at the end of the ticket. */
- mlen = HMAC_size(&hctx);
- if ((size_t) eticklen < 16 + EVP_CIPHER_CTX_iv_length(&ctx) + 1 + mlen) {
+ /* Check the MAC at the end of the ticket. */
+ uint8_t mac[EVP_MAX_MD_SIZE];
+ size_t mac_len = HMAC_size(&hmac_ctx);
+ if (ticket_len < SSL_TICKET_KEY_NAME_LEN + iv_len + 1 + mac_len) {
/* The ticket must be large enough for key name, IV, data, and MAC. */
- HMAC_CTX_cleanup(&hctx);
- EVP_CIPHER_CTX_cleanup(&ctx);
- return 2;
- }
- eticklen -= mlen;
- /* Check HMAC of encrypted ticket */
- HMAC_Update(&hctx, etick, eticklen);
- HMAC_Final(&hctx, tick_hmac, NULL);
- HMAC_CTX_cleanup(&hctx);
- if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) {
- EVP_CIPHER_CTX_cleanup(&ctx);
- return 2;
- }
-
- /* Attempt to decrypt session data */
- /* Move p after IV to start of encrypted ticket, update length */
- p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx);
- eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx);
- sdec = OPENSSL_malloc(eticklen);
- if (!sdec) {
- EVP_CIPHER_CTX_cleanup(&ctx);
- return -1;
+ goto done;
}
- EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen);
- if (EVP_DecryptFinal_ex(&ctx, sdec + slen, &mlen) <= 0) {
- EVP_CIPHER_CTX_cleanup(&ctx);
- OPENSSL_free(sdec);
- return 2;
- }
- slen += mlen;
- EVP_CIPHER_CTX_cleanup(&ctx);
- p = sdec;
-
- sess = d2i_SSL_SESSION(NULL, &p, slen);
- OPENSSL_free(sdec);
- if (sess) {
- /* The session ID, if non-empty, is used by some clients to detect that the
- * ticket has been accepted. So we copy it to the session structure. If it
- * is empty set length to zero as required by standard. */
- if (sesslen) {
- memcpy(sess->session_id, sess_id, sesslen);
- }
- sess->session_id_length = sesslen;
- *psess = sess;
- if (renew_ticket) {
- return 4;
- }
- return 3;
+ HMAC_Update(&hmac_ctx, ticket, ticket_len - mac_len);
+ HMAC_Final(&hmac_ctx, mac, NULL);
+ if (CRYPTO_memcmp(mac, ticket + (ticket_len - mac_len), mac_len) != 0) {
+ goto done;
+ }
+
+ /* Decrypt the session data. */
+ const uint8_t *ciphertext = ticket + SSL_TICKET_KEY_NAME_LEN + iv_len;
+ size_t ciphertext_len = ticket_len - SSL_TICKET_KEY_NAME_LEN - iv_len -
+ mac_len;
+ plaintext = OPENSSL_malloc(ciphertext_len);
+ if (plaintext == NULL) {
+ ret = 0;
+ goto done;
+ }
+ if (ciphertext_len >= INT_MAX) {
+ goto done;
+ }
+ int len1, len2;
+ if (!EVP_DecryptUpdate(&cipher_ctx, plaintext, &len1, ciphertext,
+ (int)ciphertext_len) ||
+ !EVP_DecryptFinal_ex(&cipher_ctx, plaintext + len1, &len2)) {
+ ERR_clear_error(); /* Don't leave an error on the queue. */
+ goto done;
}
- ERR_clear_error();
- /* For session parse failure, indicate that we need to send a new ticket. */
- return 2;
+ /* Decode the session. */
+ SSL_SESSION *session = SSL_SESSION_from_bytes(plaintext, len1 + len2);
+ if (session == NULL) {
+ ERR_clear_error(); /* Don't leave an error on the queue. */
+ goto done;
+ }
+
+ /* Copy the client's session ID into the new session, to denote the ticket has
+ * been accepted. */
+ memcpy(session->session_id, session_id, session_id_len);
+ session->session_id_length = session_id_len;
+
+ *out_session = session;
+
+done:
+ OPENSSL_free(plaintext);
+ HMAC_CTX_cleanup(&hmac_ctx);
+ EVP_CIPHER_CTX_cleanup(&cipher_ctx);
+ return ret;
}
/* Tables to translate from NIDs to TLS v1.2 ids */
@@ -2233,43 +2630,20 @@ static int tls12_find_id(int nid, const tls12_lookup *table, size_t tlen) {
return -1;
}
-static int tls12_find_nid(int id, const tls12_lookup *table, size_t tlen) {
- size_t i;
- for (i = 0; i < tlen; i++) {
- if (table[i].id == id) {
- return table[i].nid;
- }
- }
-
- return NID_undef;
+int tls12_get_sigid(int pkey_type) {
+ return tls12_find_id(pkey_type, tls12_sig,
+ sizeof(tls12_sig) / sizeof(tls12_lookup));
}
-int tls12_get_sigandhash(uint8_t *p, const EVP_PKEY *pk, 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(pk);
- if (sig_id == -1) {
- return 0;
- }
-
- p[0] = (uint8_t)md_id;
- p[1] = (uint8_t)sig_id;
- return 1;
-}
-
-int tls12_get_sigid(const EVP_PKEY *pk) {
- return tls12_find_id(pk->type, tls12_sig,
- sizeof(tls12_sig) / sizeof(tls12_lookup));
+ 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) {
@@ -2312,328 +2686,151 @@ static int tls12_get_pkey_type(uint8_t sig_alg) {
}
}
-/* Convert TLS 1.2 signature algorithm extension values into NIDs */
-static void tls1_lookup_sigalg(int *phash_nid, int *psign_nid,
- int *psignhash_nid, const uint8_t *data) {
- int sign_nid = 0, hash_nid = 0;
- if (!phash_nid && !psign_nid && !psignhash_nid) {
- return;
- }
-
- if (phash_nid || psignhash_nid) {
- hash_nid = tls12_find_nid(data[0], tls12_md,
- sizeof(tls12_md) / sizeof(tls12_lookup));
- if (phash_nid) {
- *phash_nid = hash_nid;
- }
- }
-
- if (psign_nid || psignhash_nid) {
- sign_nid = tls12_find_nid(data[1], tls12_sig,
- sizeof(tls12_sig) / sizeof(tls12_lookup));
- if (psign_nid) {
- *psign_nid = sign_nid;
- }
- }
-
- if (psignhash_nid) {
- if (sign_nid && hash_nid) {
- OBJ_find_sigid_by_algs(psignhash_nid, hash_nid, sign_nid);
- } else {
- *psignhash_nid = NID_undef;
- }
- }
-}
-
-/* Given preference and allowed sigalgs set shared sigalgs */
-static int tls12_do_shared_sigalgs(TLS_SIGALGS *shsig, const uint8_t *pref,
- size_t preflen, const uint8_t *allow,
- size_t allowlen) {
- const uint8_t *ptmp, *atmp;
- size_t i, j, nmatch = 0;
-
- for (i = 0, ptmp = pref; i < preflen; i += 2, ptmp += 2) {
- /* Skip disabled hashes or signature algorithms */
- if (tls12_get_hash(ptmp[0]) == NULL ||
- tls12_get_pkey_type(ptmp[1]) == -1) {
- continue;
- }
-
- for (j = 0, atmp = allow; j < allowlen; j += 2, atmp += 2) {
- if (ptmp[0] == atmp[0] && ptmp[1] == atmp[1]) {
- nmatch++;
- if (shsig) {
- shsig->rhash = ptmp[0];
- shsig->rsign = ptmp[1];
- tls1_lookup_sigalg(&shsig->hash_nid, &shsig->sign_nid,
- &shsig->signandhash_nid, ptmp);
- shsig++;
- }
-
- break;
- }
- }
- }
-
- return nmatch;
-}
-
-/* Set shared signature algorithms for SSL structures */
-static int tls1_set_shared_sigalgs(SSL *s) {
- const uint8_t *pref, *allow, *conf;
- size_t preflen, allowlen, conflen;
- size_t nmatch;
- TLS_SIGALGS *salgs = NULL;
- CERT *c = s->cert;
-
- OPENSSL_free(c->shared_sigalgs);
- c->shared_sigalgs = NULL;
- c->shared_sigalgslen = 0;
+OPENSSL_COMPILE_ASSERT(sizeof(TLS_SIGALGS) == 2,
+ sizeof_tls_sigalgs_is_not_two);
- /* If client use client signature algorithms if not NULL */
- if (!s->server && c->client_sigalgs) {
- conf = c->client_sigalgs;
- conflen = c->client_sigalgslen;
- } else if (c->conf_sigalgs) {
- conf = c->conf_sigalgs;
- conflen = c->conf_sigalgslen;
- } else {
- conflen = tls12_get_psigalgs(s, &conf);
+int tls1_parse_peer_sigalgs(SSL *ssl, const CBS *in_sigalgs) {
+ /* Extension ignored for inappropriate versions */
+ if (!SSL_USE_SIGALGS(ssl)) {
+ return 1;
}
- if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) {
- pref = conf;
- preflen = conflen;
- allow = c->peer_sigalgs;
- allowlen = c->peer_sigalgslen;
- } else {
- allow = conf;
- allowlen = conflen;
- pref = c->peer_sigalgs;
- preflen = c->peer_sigalgslen;
- }
+ CERT *const cert = ssl->cert;
+ OPENSSL_free(cert->peer_sigalgs);
+ cert->peer_sigalgs = NULL;
+ cert->peer_sigalgslen = 0;
- nmatch = tls12_do_shared_sigalgs(NULL, pref, preflen, allow, allowlen);
- if (!nmatch) {
- return 1;
- }
+ size_t num_sigalgs = CBS_len(in_sigalgs);
- salgs = OPENSSL_malloc(nmatch * sizeof(TLS_SIGALGS));
- if (!salgs) {
+ if (num_sigalgs % 2 != 0) {
return 0;
}
+ num_sigalgs /= 2;
- nmatch = tls12_do_shared_sigalgs(salgs, pref, preflen, allow, allowlen);
- c->shared_sigalgs = salgs;
- c->shared_sigalgslen = nmatch;
- return 1;
-}
-
-/* Set preferred digest for each key type */
-int tls1_process_sigalgs(SSL *s, const CBS *sigalgs) {
- CERT *c = s->cert;
-
- /* Extension ignored for inappropriate versions */
- if (!SSL_USE_SIGALGS(s)) {
+ /* supported_signature_algorithms in the certificate request is
+ * allowed to be empty. */
+ if (num_sigalgs == 0) {
return 1;
}
- if (CBS_len(sigalgs) % 2 != 0 ||
- !CBS_stow(sigalgs, &c->peer_sigalgs, &c->peer_sigalgslen) ||
- !tls1_set_shared_sigalgs(s)) {
+ /* This multiplication doesn't overflow because sizeof(TLS_SIGALGS) is two
+ * (statically asserted above) and we just divided |num_sigalgs| by two. */
+ cert->peer_sigalgs = OPENSSL_malloc(num_sigalgs * sizeof(TLS_SIGALGS));
+ if (cert->peer_sigalgs == NULL) {
return 0;
}
+ cert->peer_sigalgslen = num_sigalgs;
- return 1;
-}
+ CBS sigalgs;
+ CBS_init(&sigalgs, CBS_data(in_sigalgs), CBS_len(in_sigalgs));
-const EVP_MD *tls1_choose_signing_digest(SSL *s, EVP_PKEY *pkey) {
- CERT *c = s->cert;
- int type = EVP_PKEY_id(pkey);
size_t i;
-
- /* Select the first shared digest supported by our key. */
- for (i = 0; i < c->shared_sigalgslen; i++) {
- const EVP_MD *md = tls12_get_hash(c->shared_sigalgs[i].rhash);
- if (md == NULL ||
- tls12_get_pkey_type(c->shared_sigalgs[i].rsign) != type ||
- !EVP_PKEY_supports_digest(pkey, md)) {
- continue;
- }
- return md;
- }
-
- /* If no suitable digest may be found, default to SHA-1. */
- return EVP_sha1();
-}
-
-int SSL_get_sigalgs(SSL *s, int idx, int *psign, int *phash, int *psignhash,
- uint8_t *rsig, uint8_t *rhash) {
- const uint8_t *psig = s->cert->peer_sigalgs;
-
- if (psig == NULL) {
- return 0;
- }
-
- if (idx >= 0) {
- idx <<= 1;
- if (idx >= (int)s->cert->peer_sigalgslen) {
+ for (i = 0; i < num_sigalgs; i++) {
+ TLS_SIGALGS *const sigalg = &cert->peer_sigalgs[i];
+ if (!CBS_get_u8(&sigalgs, &sigalg->rhash) ||
+ !CBS_get_u8(&sigalgs, &sigalg->rsign)) {
return 0;
}
- psig += idx;
- if (rhash) {
- *rhash = psig[0];
- }
- if (rsig) {
- *rsig = psig[1];
- }
- tls1_lookup_sigalg(phash, psign, psignhash, psig);
}
- return s->cert->peer_sigalgslen / 2;
+ return 1;
}
-int SSL_get_shared_sigalgs(SSL *s, int idx, int *psign, int *phash,
- int *psignhash, uint8_t *rsig, uint8_t *rhash) {
- TLS_SIGALGS *shsigalgs = s->cert->shared_sigalgs;
-
- if (!shsigalgs || idx >= (int)s->cert->shared_sigalgslen) {
- return 0;
- }
+const EVP_MD *tls1_choose_signing_digest(SSL *ssl) {
+ CERT *cert = ssl->cert;
+ int type = ssl_private_key_type(ssl);
+ size_t i, j;
+
+ static const int kDefaultDigestList[] = {NID_sha256, NID_sha384, NID_sha512,
+ NID_sha224, NID_sha1};
+
+ const int *digest_nids = kDefaultDigestList;
+ size_t num_digest_nids =
+ sizeof(kDefaultDigestList) / sizeof(kDefaultDigestList[0]);
+ if (cert->digest_nids != NULL) {
+ digest_nids = cert->digest_nids;
+ num_digest_nids = cert->num_digest_nids;
+ }
+
+ for (i = 0; i < num_digest_nids; i++) {
+ const int digest_nid = digest_nids[i];
+ for (j = 0; j < cert->peer_sigalgslen; j++) {
+ const EVP_MD *md = tls12_get_hash(cert->peer_sigalgs[j].rhash);
+ if (md == NULL ||
+ digest_nid != EVP_MD_type(md) ||
+ tls12_get_pkey_type(cert->peer_sigalgs[j].rsign) != type) {
+ continue;
+ }
- shsigalgs += idx;
- if (phash) {
- *phash = shsigalgs->hash_nid;
- }
- if (psign) {
- *psign = shsigalgs->sign_nid;
- }
- if (psignhash) {
- *psignhash = shsigalgs->signandhash_nid;
- }
- if (rsig) {
- *rsig = shsigalgs->rsign;
- }
- if (rhash) {
- *rhash = shsigalgs->rhash;
+ return md;
+ }
}
- return s->cert->shared_sigalgslen;
+ /* If no suitable digest may be found, default to SHA-1. */
+ return EVP_sha1();
}
-/* tls1_channel_id_hash calculates the signed data for a Channel ID on the
- * given SSL connection and writes it to |md|. */
-int tls1_channel_id_hash(EVP_MD_CTX *md, SSL *s) {
+int tls1_channel_id_hash(SSL *ssl, uint8_t *out, size_t *out_len) {
+ int ret = 0;
EVP_MD_CTX ctx;
- uint8_t temp_digest[EVP_MAX_MD_SIZE];
- unsigned temp_digest_len;
- int i;
- static const char kClientIDMagic[] = "TLS Channel ID signature";
- if (s->s3->handshake_buffer &&
- !ssl3_digest_cached_records(s, free_handshake_buffer)) {
- return 0;
+ EVP_MD_CTX_init(&ctx);
+ if (!EVP_DigestInit_ex(&ctx, EVP_sha256(), NULL)) {
+ goto err;
}
- EVP_DigestUpdate(md, kClientIDMagic, sizeof(kClientIDMagic));
+ static const char kClientIDMagic[] = "TLS Channel ID signature";
+ EVP_DigestUpdate(&ctx, kClientIDMagic, sizeof(kClientIDMagic));
- if (s->hit && s->s3->tlsext_channel_id_new) {
+ if (ssl->hit) {
static const char kResumptionMagic[] = "Resumption";
- EVP_DigestUpdate(md, kResumptionMagic, sizeof(kResumptionMagic));
- if (s->session->original_handshake_hash_len == 0) {
- return 0;
+ EVP_DigestUpdate(&ctx, kResumptionMagic, sizeof(kResumptionMagic));
+ if (ssl->session->original_handshake_hash_len == 0) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ goto err;
}
- EVP_DigestUpdate(md, s->session->original_handshake_hash,
- s->session->original_handshake_hash_len);
+ EVP_DigestUpdate(&ctx, ssl->session->original_handshake_hash,
+ ssl->session->original_handshake_hash_len);
}
- EVP_MD_CTX_init(&ctx);
- for (i = 0; i < SSL_MAX_DIGEST; i++) {
- if (s->s3->handshake_dgst[i] == NULL) {
- continue;
- }
- if (!EVP_MD_CTX_copy_ex(&ctx, s->s3->handshake_dgst[i])) {
- EVP_MD_CTX_cleanup(&ctx);
- return 0;
- }
- EVP_DigestFinal_ex(&ctx, temp_digest, &temp_digest_len);
- EVP_DigestUpdate(md, temp_digest, temp_digest_len);
+ uint8_t handshake_hash[EVP_MAX_MD_SIZE];
+ int handshake_hash_len = tls1_handshake_digest(ssl, handshake_hash,
+ sizeof(handshake_hash));
+ if (handshake_hash_len < 0) {
+ goto err;
}
- EVP_MD_CTX_cleanup(&ctx);
+ EVP_DigestUpdate(&ctx, handshake_hash, (size_t)handshake_hash_len);
+ unsigned len_u;
+ EVP_DigestFinal_ex(&ctx, out, &len_u);
+ *out_len = len_u;
- return 1;
+ ret = 1;
+
+err:
+ EVP_MD_CTX_cleanup(&ctx);
+ return ret;
}
/* 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) {
- return -1;
- }
-
- /* It only makes sense to call this function if Channel IDs have been
- * negotiated. */
- if (!s->s3->tlsext_channel_id_new) {
+ 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;
-
- return 1;
-}
-
-int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen,
- int client) {
- uint8_t *sigalgs, *sptr;
- int rhash, rsign;
- size_t i;
-
- if (salglen & 1) {
- return 0;
- }
-
- sigalgs = OPENSSL_malloc(salglen);
- if (sigalgs == NULL) {
- return 0;
- }
-
- for (i = 0, sptr = sigalgs; i < salglen; i += 2) {
- rhash = tls12_find_id(*psig_nids++, tls12_md,
- sizeof(tls12_md) / sizeof(tls12_lookup));
- rsign = tls12_find_id(*psig_nids++, tls12_sig,
- sizeof(tls12_sig) / sizeof(tls12_lookup));
-
- if (rhash == -1 || rsign == -1) {
- goto err;
- }
- *sptr++ = rhash;
- *sptr++ = rsign;
- }
-
- if (client) {
- OPENSSL_free(c->client_sigalgs);
- c->client_sigalgs = sigalgs;
- c->client_sigalgslen = salglen;
- } else {
- OPENSSL_free(c->conf_sigalgs);
- c->conf_sigalgs = sigalgs;
- c->conf_sigalgslen = salglen;
- }
+ ssl->session->original_handshake_hash_len = digest_len;
return 1;
-
-err:
- OPENSSL_free(sigalgs);
- return 0;
}
diff --git a/src/ssl/t1_reneg.c b/src/ssl/t1_reneg.c
deleted file mode 100644
index d0009c1..0000000
--- a/src/ssl/t1_reneg.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/* 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.]
- */
-/* ====================================================================
- * Copyright (c) 1998-2009 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com). */
-
-#include <assert.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <openssl/bytestring.h>
-#include <openssl/err.h>
-
-#include "internal.h"
-
-
-/* Add the client's renegotiation binding */
-int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
- int maxlen) {
- if (p) {
- if (s->s3->previous_client_finished_len + 1 > maxlen) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_renegotiate_ext,
- SSL_R_RENEGOTIATE_EXT_TOO_LONG);
- return 0;
- }
-
- /* Length byte */
- *p = s->s3->previous_client_finished_len;
- p++;
-
- memcpy(p, s->s3->previous_client_finished,
- s->s3->previous_client_finished_len);
- }
-
- *len = s->s3->previous_client_finished_len + 1;
-
- return 1;
-}
-
-/* Parse the client's renegotiation binding and abort if it's not right */
-int ssl_parse_clienthello_renegotiate_ext(SSL *s, CBS *cbs, int *out_alert) {
- CBS renegotiated_connection;
-
- if (!CBS_get_u8_length_prefixed(cbs, &renegotiated_connection) ||
- CBS_len(cbs) != 0) {
- OPENSSL_PUT_ERROR(SSL, ssl_parse_clienthello_renegotiate_ext,
- SSL_R_RENEGOTIATION_ENCODING_ERR);
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
-
- /* Check that the extension matches */
- if (!CBS_mem_equal(&renegotiated_connection, s->s3->previous_client_finished,
- s->s3->previous_client_finished_len)) {
- OPENSSL_PUT_ERROR(SSL, ssl_parse_clienthello_renegotiate_ext,
- SSL_R_RENEGOTIATION_MISMATCH);
- *out_alert = SSL_AD_HANDSHAKE_FAILURE;
- return 0;
- }
-
- s->s3->send_connection_binding = 1;
-
- return 1;
-}
-
-/* Add the server's renegotiation binding */
-int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
- int maxlen) {
- if (p) {
- if (s->s3->previous_client_finished_len +
- s->s3->previous_server_finished_len + 1 > maxlen) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_renegotiate_ext,
- SSL_R_RENEGOTIATE_EXT_TOO_LONG);
- return 0;
- }
-
- /* Length byte */
- *p = s->s3->previous_client_finished_len +
- s->s3->previous_server_finished_len;
- p++;
-
- memcpy(p, s->s3->previous_client_finished,
- s->s3->previous_client_finished_len);
- p += s->s3->previous_client_finished_len;
-
- memcpy(p, s->s3->previous_server_finished,
- s->s3->previous_server_finished_len);
- }
-
- *len = s->s3->previous_client_finished_len +
- s->s3->previous_server_finished_len + 1;
-
- return 1;
-}
-
-/* Parse the server's renegotiation binding and abort if it's not right */
-int ssl_parse_serverhello_renegotiate_ext(SSL *s, CBS *cbs, int *out_alert) {
- int expected_len =
- s->s3->previous_client_finished_len + s->s3->previous_server_finished_len;
- CBS renegotiated_connection;
- const uint8_t *d;
-
- /* Check for logic errors */
- assert(!expected_len || s->s3->previous_client_finished_len);
- assert(!expected_len || s->s3->previous_server_finished_len);
-
- /* Parse out the extension contents. */
- if (!CBS_get_u8_length_prefixed(cbs, &renegotiated_connection) ||
- CBS_len(cbs) != 0) {
- OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_renegotiate_ext,
- SSL_R_RENEGOTIATION_ENCODING_ERR);
- *out_alert = SSL_AD_ILLEGAL_PARAMETER;
- return 0;
- }
-
- /* Check that the extension matches. */
- if (CBS_len(&renegotiated_connection) != expected_len) {
- OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_renegotiate_ext,
- SSL_R_RENEGOTIATION_MISMATCH);
- *out_alert = SSL_AD_HANDSHAKE_FAILURE;
- return 0;
- }
-
- d = CBS_data(&renegotiated_connection);
- if (memcmp(d, s->s3->previous_client_finished,
- s->s3->previous_client_finished_len)) {
- OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_renegotiate_ext,
- SSL_R_RENEGOTIATION_MISMATCH);
- *out_alert = SSL_AD_HANDSHAKE_FAILURE;
- return 0;
- }
- d += s->s3->previous_client_finished_len;
-
- if (memcmp(d, s->s3->previous_server_finished,
- s->s3->previous_server_finished_len)) {
- OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_renegotiate_ext,
- SSL_R_RENEGOTIATION_MISMATCH);
- *out_alert = SSL_AD_ILLEGAL_PARAMETER;
- return 0;
- }
- s->s3->send_connection_binding = 1;
-
- return 1;
-}
diff --git a/src/ssl/test/async_bio.cc b/src/ssl/test/async_bio.cc
index 0534845..7a5737b 100644
--- a/src/ssl/test/async_bio.cc
+++ b/src/ssl/test/async_bio.cc
@@ -26,6 +26,7 @@ extern const BIO_METHOD g_async_bio_method;
struct AsyncBio {
bool datagram;
+ bool enforce_write_quota;
size_t read_quota;
size_t write_quota;
};
@@ -43,9 +44,7 @@ static int AsyncWrite(BIO *bio, const char *in, int inl) {
return 0;
}
- if (a->datagram) {
- // Perform writes synchronously; the DTLS implementation drops any packets
- // that failed to send.
+ if (!a->enforce_write_quota) {
return BIO_write(bio->next_bio, in, inl);
}
@@ -111,6 +110,7 @@ static int AsyncNew(BIO *bio) {
return 0;
}
memset(a, 0, sizeof(*a));
+ a->enforce_write_quota = true;
bio->init = 1;
bio->ptr = (char *)a;
return 1;
@@ -178,3 +178,11 @@ void AsyncBioAllowWrite(BIO *bio, size_t count) {
}
a->write_quota += count;
}
+
+void AsyncBioEnforceWriteQuota(BIO *bio, bool enforce) {
+ AsyncBio *a = GetData(bio);
+ if (a == NULL) {
+ return;
+ }
+ a->enforce_write_quota = enforce;
+}
diff --git a/src/ssl/test/async_bio.h b/src/ssl/test/async_bio.h
index 1ccdf9b..fbc4016 100644
--- a/src/ssl/test/async_bio.h
+++ b/src/ssl/test/async_bio.h
@@ -38,5 +38,8 @@ void AsyncBioAllowRead(BIO *bio, size_t count);
// AsyncBioAllowWrite increments |bio|'s write quota by |count|.
void AsyncBioAllowWrite(BIO *bio, size_t count);
+// AsyncBioEnforceWriteQuota configures where |bio| enforces its write quota.
+void AsyncBioEnforceWriteQuota(BIO *bio, bool enforce);
+
#endif // HEADER_ASYNC_BIO
diff --git a/src/ssl/test/bssl_shim.cc b/src/ssl/test/bssl_shim.cc
index 40cb149..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,16 +36,22 @@
#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>
#include <openssl/bytestring.h>
+#include <openssl/cipher.h>
+#include <openssl/crypto.h>
#include <openssl/err.h>
+#include <openssl/hmac.h>
+#include <openssl/obj.h>
+#include <openssl/rand.h>
#include <openssl/ssl.h>
#include <memory>
+#include <string>
#include <vector>
#include "../../crypto/test/scoped_types.h"
@@ -90,10 +100,17 @@ struct TestState {
ScopedSSL_SESSION pending_session;
bool early_callback_called = false;
bool handshake_done = false;
+ // private_key is the underlying private key used when testing custom keys.
+ ScopedEVP_PKEY private_key;
+ std::vector<uint8_t> private_key_result;
+ // private_key_retries is the number of times an asynchronous private key
+ // operation has been retried.
+ unsigned private_key_retries = 0;
+ bool got_new_session = false;
};
static void TestStateExFree(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
- int index, long argl, void *argp) {
+ int index, long argl, void *argp) {
delete ((TestState *)ptr);
}
@@ -108,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;
@@ -129,18 +147,198 @@ static ScopedEVP_PKEY LoadPrivateKey(const std::string &file) {
return pkey;
}
+static int AsyncPrivateKeyType(SSL *ssl) {
+ return EVP_PKEY_id(GetTestState(ssl)->private_key.get());
+}
+
+static size_t AsyncPrivateKeyMaxSignatureLen(SSL *ssl) {
+ return EVP_PKEY_size(GetTestState(ssl)->private_key.get());
+}
+
+static ssl_private_key_result_t AsyncPrivateKeySign(
+ SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
+ const EVP_MD *md, const uint8_t *in, size_t in_len) {
+ TestState *test_state = GetTestState(ssl);
+ if (!test_state->private_key_result.empty()) {
+ fprintf(stderr, "AsyncPrivateKeySign called with operation pending.\n");
+ abort();
+ }
+
+ ScopedEVP_PKEY_CTX ctx(EVP_PKEY_CTX_new(test_state->private_key.get(),
+ nullptr));
+ if (!ctx) {
+ return ssl_private_key_failure;
+ }
+
+ // Write the signature into |test_state|.
+ size_t len = 0;
+ if (!EVP_PKEY_sign_init(ctx.get()) ||
+ !EVP_PKEY_CTX_set_signature_md(ctx.get(), md) ||
+ !EVP_PKEY_sign(ctx.get(), nullptr, &len, in, in_len)) {
+ return ssl_private_key_failure;
+ }
+ test_state->private_key_result.resize(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);
+
+ // The signature will be released asynchronously in
+ // |AsyncPrivateKeySignComplete|.
+ return ssl_private_key_retry;
+}
+
+static ssl_private_key_result_t AsyncPrivateKeySignComplete(
+ SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out) {
+ TestState *test_state = GetTestState(ssl);
+ if (test_state->private_key_result.empty()) {
+ fprintf(stderr,
+ "AsyncPrivateKeySignComplete called without operation pending.\n");
+ abort();
+ }
+
+ if (test_state->private_key_retries < 2) {
+ // Only return the signature on the second attempt, to test both incomplete
+ // |sign| and |sign_complete|.
+ return ssl_private_key_retry;
+ }
+
+ if (max_out < test_state->private_key_result.size()) {
+ fprintf(stderr, "Output buffer too small.\n");
+ return ssl_private_key_failure;
+ }
+ memcpy(out, test_state->private_key_result.data(),
+ test_state->private_key_result.size());
+ *out_len = test_state->private_key_result.size();
+
+ test_state->private_key_result.clear();
+ test_state->private_key_retries = 0;
+ return ssl_private_key_success;
+}
+
+static ssl_private_key_result_t AsyncPrivateKeyDecrypt(
+ SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
+ const uint8_t *in, size_t in_len) {
+ TestState *test_state = GetTestState(ssl);
+ if (!test_state->private_key_result.empty()) {
+ fprintf(stderr,
+ "AsyncPrivateKeyDecrypt called with operation pending.\n");
+ abort();
+ }
+
+ RSA *rsa = EVP_PKEY_get0_RSA(test_state->private_key.get());
+ if (rsa == NULL) {
+ fprintf(stderr,
+ "AsyncPrivateKeyDecrypt called with incorrect key type.\n");
+ abort();
+ }
+ test_state->private_key_result.resize(RSA_size(rsa));
+ 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;
+ }
+
+ test_state->private_key_result.resize(*out_len);
+
+ // The decryption will be released asynchronously in
+ // |AsyncPrivateKeyDecryptComplete|.
+ return ssl_private_key_retry;
+}
+
+static ssl_private_key_result_t AsyncPrivateKeyDecryptComplete(
+ SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out) {
+ TestState *test_state = GetTestState(ssl);
+ if (test_state->private_key_result.empty()) {
+ fprintf(stderr,
+ "AsyncPrivateKeyDecryptComplete called without operation "
+ "pending.\n");
+ abort();
+ }
+
+ if (test_state->private_key_retries < 2) {
+ // Only return the decryption on the second attempt, to test both incomplete
+ // |decrypt| and |decrypt_complete|.
+ return ssl_private_key_retry;
+ }
+
+ if (max_out < test_state->private_key_result.size()) {
+ fprintf(stderr, "Output buffer too small.\n");
+ return ssl_private_key_failure;
+ }
+ memcpy(out, test_state->private_key_result.data(),
+ test_state->private_key_result.size());
+ *out_len = test_state->private_key_result.size();
+
+ test_state->private_key_result.clear();
+ test_state->private_key_retries = 0;
+ return ssl_private_key_success;
+}
+
+static const SSL_PRIVATE_KEY_METHOD g_async_private_key_method = {
+ AsyncPrivateKeyType,
+ AsyncPrivateKeyMaxSignatureLen,
+ AsyncPrivateKeySign,
+ AsyncPrivateKeySignComplete,
+ AsyncPrivateKeyDecrypt,
+ AsyncPrivateKeyDecryptComplete
+};
+
+template<typename T>
+struct Free {
+ void operator()(T *buf) {
+ free(buf);
+ }
+};
+
static bool InstallCertificate(SSL *ssl) {
const TestConfig *config = GetConfigPtr(ssl);
- if (!config->key_file.empty() &&
- !SSL_use_PrivateKey_file(ssl, config->key_file.c_str(),
- SSL_FILETYPE_PEM)) {
- return false;
+ TestState *test_state = GetTestState(ssl);
+
+ if (!config->digest_prefs.empty()) {
+ std::unique_ptr<char, Free<char>> digest_prefs(
+ strdup(config->digest_prefs.c_str()));
+ std::vector<int> digest_list;
+
+ for (;;) {
+ char *token =
+ strtok(digest_list.empty() ? digest_prefs.get() : nullptr, ",");
+ if (token == nullptr) {
+ break;
+ }
+
+ digest_list.push_back(EVP_MD_type(EVP_get_digestbyname(token)));
+ }
+
+ if (!SSL_set_private_key_digest_prefs(ssl, digest_list.data(),
+ digest_list.size())) {
+ return false;
+ }
+ }
+
+ if (!config->key_file.empty()) {
+ if (config->async) {
+ test_state->private_key = LoadPrivateKey(config->key_file.c_str());
+ if (!test_state->private_key) {
+ return false;
+ }
+ SSL_set_private_key_method(ssl, &g_async_private_key_method);
+ } else if (!SSL_use_PrivateKey_file(ssl, config->key_file.c_str(),
+ SSL_FILETYPE_PEM)) {
+ return false;
+ }
}
if (!config->cert_file.empty() &&
!SSL_use_certificate_file(ssl, config->cert_file.c_str(),
SSL_FILETYPE_PEM)) {
return false;
}
+ if (!config->ocsp_response.empty() &&
+ !SSL_CTX_set_ocsp_response(ssl->ctx,
+ (const uint8_t *)config->ocsp_response.data(),
+ config->ocsp_response.size())) {
+ return false;
+ }
return true;
}
@@ -196,10 +394,29 @@ static int SelectCertificateCallback(const struct ssl_early_callback_ctx *ctx) {
return 1;
}
-static int SkipVerify(int preverify_ok, X509_STORE_CTX *store_ctx) {
+static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) {
+ SSL* ssl = (SSL*)X509_STORE_CTX_get_ex_data(store_ctx,
+ SSL_get_ex_data_X509_STORE_CTX_idx());
+ const TestConfig *config = GetConfigPtr(ssl);
+
+ if (!config->expected_ocsp_response.empty()) {
+ const uint8_t *data;
+ size_t len;
+ SSL_get0_ocsp_response(ssl, &data, &len);
+ if (len == 0) {
+ fprintf(stderr, "OCSP response not available in verify callback\n");
+ return 0;
+ }
+ }
+
return 1;
}
+static int VerifyFail(X509_STORE_CTX *store_ctx, void *arg) {
+ store_ctx->error = X509_V_ERR_APPLICATION_VERIFICATION;
+ return 0;
+}
+
static int NextProtosAdvertisedCallback(SSL *ssl, const uint8_t **out,
unsigned int *out_len, void *arg) {
const TestConfig *config = GetConfigPtr(ssl);
@@ -341,6 +558,94 @@ static void InfoCallback(const SSL *ssl, int type, int val) {
}
}
+static int NewSessionCallback(SSL *ssl, SSL_SESSION *session) {
+ GetTestState(ssl)->got_new_session = true;
+ // BoringSSL passes a reference to |session|.
+ SSL_SESSION_free(session);
+ return 1;
+}
+
+static int TicketKeyCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
+ EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
+ int encrypt) {
+ // This is just test code, so use the all-zeros key.
+ static const uint8_t kZeros[16] = {0};
+
+ if (encrypt) {
+ memcpy(key_name, kZeros, sizeof(kZeros));
+ RAND_bytes(iv, 16);
+ } else if (memcmp(key_name, kZeros, 16) != 0) {
+ return 0;
+ }
+
+ if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
+ !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
+ return -1;
+ }
+
+ if (!encrypt) {
+ return GetConfigPtr(ssl)->renew_ticket ? 2 : 1;
+ }
+ return 1;
+}
+
+// kCustomExtensionValue is the extension value that the custom extension
+// callbacks will add.
+static const uint16_t kCustomExtensionValue = 1234;
+static void *const kCustomExtensionAddArg =
+ reinterpret_cast<void *>(kCustomExtensionValue);
+static void *const kCustomExtensionParseArg =
+ reinterpret_cast<void *>(kCustomExtensionValue + 1);
+static const char kCustomExtensionContents[] = "custom extension";
+
+static int CustomExtensionAddCallback(SSL *ssl, unsigned extension_value,
+ const uint8_t **out, size_t *out_len,
+ int *out_alert_value, void *add_arg) {
+ if (extension_value != kCustomExtensionValue ||
+ add_arg != kCustomExtensionAddArg) {
+ abort();
+ }
+
+ if (GetConfigPtr(ssl)->custom_extension_skip) {
+ return 0;
+ }
+ if (GetConfigPtr(ssl)->custom_extension_fail_add) {
+ return -1;
+ }
+
+ *out = reinterpret_cast<const uint8_t*>(kCustomExtensionContents);
+ *out_len = sizeof(kCustomExtensionContents) - 1;
+
+ return 1;
+}
+
+static void CustomExtensionFreeCallback(SSL *ssl, unsigned extension_value,
+ const uint8_t *out, void *add_arg) {
+ if (extension_value != kCustomExtensionValue ||
+ add_arg != kCustomExtensionAddArg ||
+ out != reinterpret_cast<const uint8_t *>(kCustomExtensionContents)) {
+ abort();
+ }
+}
+
+static int CustomExtensionParseCallback(SSL *ssl, unsigned extension_value,
+ const uint8_t *contents,
+ size_t contents_len,
+ int *out_alert_value, void *parse_arg) {
+ if (extension_value != kCustomExtensionValue ||
+ parse_arg != kCustomExtensionParseArg) {
+ abort();
+ }
+
+ if (contents_len != sizeof(kCustomExtensionContents) - 1 ||
+ memcmp(contents, kCustomExtensionContents, contents_len) != 0) {
+ *out_alert_value = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+
+ return 1;
+}
+
// Connect returns a new socket connected to localhost on |port| or -1 on
// error.
static int Connect(uint16_t port) {
@@ -406,11 +711,45 @@ static ScopedSSL_CTX SetupCtx(const TestConfig *config) {
return nullptr;
}
- if (!SSL_CTX_set_cipher_list(ssl_ctx.get(), "ALL")) {
+ std::string cipher_list = "ALL";
+ if (!config->cipher.empty()) {
+ cipher_list = config->cipher;
+ SSL_CTX_set_options(ssl_ctx.get(), SSL_OP_CIPHER_SERVER_PREFERENCE);
+ }
+ if (!SSL_CTX_set_cipher_list(ssl_ctx.get(), cipher_list.c_str())) {
+ return nullptr;
+ }
+
+ if (!config->cipher_tls10.empty() &&
+ !SSL_CTX_set_cipher_list_tls10(ssl_ctx.get(),
+ config->cipher_tls10.c_str())) {
+ return nullptr;
+ }
+ if (!config->cipher_tls11.empty() &&
+ !SSL_CTX_set_cipher_list_tls11(ssl_ctx.get(),
+ config->cipher_tls11.c_str())) {
return nullptr;
}
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;
}
@@ -425,7 +764,7 @@ static ScopedSSL_CTX SetupCtx(const TestConfig *config) {
SSL_CTX_set_session_cache_mode(ssl_ctx.get(), SSL_SESS_CACHE_BOTH);
}
- ssl_ctx->select_certificate_cb = SelectCertificateCallback;
+ SSL_CTX_set_select_certificate_cb(ssl_ctx.get(), SelectCertificateCallback);
SSL_CTX_set_next_protos_advertised_cb(
ssl_ctx.get(), NextProtosAdvertisedCallback, NULL);
@@ -438,12 +777,46 @@ static ScopedSSL_CTX SetupCtx(const TestConfig *config) {
SSL_CTX_set_alpn_select_cb(ssl_ctx.get(), AlpnSelectCallback, NULL);
}
- ssl_ctx->tlsext_channel_id_enabled_new = 1;
+ SSL_CTX_enable_tls_channel_id(ssl_ctx.get());
SSL_CTX_set_channel_id_cb(ssl_ctx.get(), ChannelIdCallback);
ssl_ctx->current_time_cb = CurrentTimeCallback;
SSL_CTX_set_info_callback(ssl_ctx.get(), InfoCallback);
+ SSL_CTX_sess_set_new_cb(ssl_ctx.get(), NewSessionCallback);
+
+ if (config->use_ticket_callback) {
+ SSL_CTX_set_tlsext_ticket_key_cb(ssl_ctx.get(), TicketKeyCallback);
+ }
+
+ if (config->enable_client_custom_extension &&
+ !SSL_CTX_add_client_custom_ext(
+ ssl_ctx.get(), kCustomExtensionValue, CustomExtensionAddCallback,
+ CustomExtensionFreeCallback, kCustomExtensionAddArg,
+ CustomExtensionParseCallback, kCustomExtensionParseArg)) {
+ return nullptr;
+ }
+
+ if (config->enable_server_custom_extension &&
+ !SSL_CTX_add_server_custom_ext(
+ ssl_ctx.get(), kCustomExtensionValue, CustomExtensionAddCallback,
+ CustomExtensionFreeCallback, kCustomExtensionAddArg,
+ CustomExtensionParseCallback, kCustomExtensionParseArg)) {
+ return nullptr;
+ }
+
+ if (config->verify_fail) {
+ SSL_CTX_set_cert_verify_callback(ssl_ctx.get(), VerifyFail, NULL);
+ } else {
+ SSL_CTX_set_cert_verify_callback(ssl_ctx.get(), VerifySucceed, NULL);
+ }
+
+ if (!config->signed_cert_timestamps.empty() &&
+ !SSL_CTX_set_signed_cert_timestamp_list(
+ ssl_ctx.get(), (const uint8_t *)config->signed_cert_timestamps.data(),
+ config->signed_cert_timestamps.size())) {
+ return nullptr;
+ }
return ssl_ctx;
}
@@ -457,6 +830,7 @@ static bool RetryAsync(SSL *ssl, int ret) {
return false;
}
+ const TestConfig *config = GetConfigPtr(ssl);
TestState *test_state = GetTestState(ssl);
if (test_state->clock_delta.tv_usec != 0 ||
test_state->clock_delta.tv_sec != 0) {
@@ -467,7 +841,17 @@ static bool RetryAsync(SSL *ssl, int ret) {
test_state->clock.tv_sec += test_state->clock_delta.tv_sec;
memset(&test_state->clock_delta, 0, sizeof(test_state->clock_delta));
- if (DTLSv1_handle_timeout(ssl) < 0) {
+ // The DTLS retransmit logic silently ignores write failures. So the test
+ // may progress, allow writes through synchronously.
+ if (config->async) {
+ AsyncBioEnforceWriteQuota(test_state->async_bio, false);
+ }
+ int timeout_ret = DTLSv1_handle_timeout(ssl);
+ if (config->async) {
+ AsyncBioEnforceWriteQuota(test_state->async_bio, true);
+ }
+
+ if (timeout_ret < 0) {
fprintf(stderr, "Error retransmitting.\n");
return false;
}
@@ -500,6 +884,9 @@ static bool RetryAsync(SSL *ssl, int ret) {
case SSL_ERROR_PENDING_CERTIFICATE:
// The handshake will resume without a second call to the early callback.
return InstallCertificate(ssl);
+ case SSL_ERROR_WANT_PRIVATE_KEY_OPERATION:
+ test_state->private_key_retries++;
+ return true;
default:
return false;
}
@@ -509,9 +896,19 @@ static bool RetryAsync(SSL *ssl, int ret) {
// the result value of the final |SSL_read| call.
static int DoRead(SSL *ssl, uint8_t *out, size_t max_out) {
const TestConfig *config = GetConfigPtr(ssl);
+ TestState *test_state = GetTestState(ssl);
int ret;
do {
+ if (config->async) {
+ // The DTLS retransmit logic silently ignores write failures. So the test
+ // may progress, allow writes through synchronously. |SSL_read| may
+ // trigger a retransmit, so disconnect the write quota.
+ AsyncBioEnforceWriteQuota(test_state->async_bio, false);
+ }
ret = SSL_read(ssl, out, max_out);
+ if (config->async) {
+ AsyncBioEnforceWriteQuota(test_state->async_bio, true);
+ }
} while (config->async && RetryAsync(ssl, ret));
return ret;
}
@@ -531,6 +928,195 @@ static int WriteAll(SSL *ssl, const uint8_t *in, size_t in_len) {
return ret;
}
+// DoShutdown calls |SSL_shutdown|, resolving any asynchronous operations. It
+// returns the result of the final |SSL_shutdown| call.
+static int DoShutdown(SSL *ssl) {
+ const TestConfig *config = GetConfigPtr(ssl);
+ int ret;
+ do {
+ ret = SSL_shutdown(ssl);
+ } while (config->async && RetryAsync(ssl, ret));
+ return ret;
+}
+
+// CheckHandshakeProperties checks, immediately after |ssl| completes its
+// initial handshake (or False Starts), whether all the properties are
+// consistent with the test configuration and invariants.
+static bool CheckHandshakeProperties(SSL *ssl, bool is_resume) {
+ const TestConfig *config = GetConfigPtr(ssl);
+
+ if (SSL_get_current_cipher(ssl) == nullptr) {
+ fprintf(stderr, "null cipher after handshake\n");
+ return false;
+ }
+
+ if (is_resume &&
+ (!!SSL_session_reused(ssl) == config->expect_session_miss)) {
+ fprintf(stderr, "session was%s reused\n",
+ SSL_session_reused(ssl) ? "" : " not");
+ return false;
+ }
+
+ bool expect_handshake_done = is_resume || !config->false_start;
+ if (expect_handshake_done != GetTestState(ssl)->handshake_done) {
+ fprintf(stderr, "handshake was%s completed\n",
+ GetTestState(ssl)->handshake_done ? "" : " not");
+ return false;
+ }
+
+ if (expect_handshake_done && !config->is_server) {
+ bool expect_new_session =
+ !config->expect_no_session &&
+ (!SSL_session_reused(ssl) || config->expect_ticket_renewal);
+ if (expect_new_session != GetTestState(ssl)->got_new_session) {
+ fprintf(stderr,
+ "new session was%s cached, but we expected the opposite\n",
+ GetTestState(ssl)->got_new_session ? "" : " not");
+ return false;
+ }
+ }
+
+ if (config->is_server && !GetTestState(ssl)->early_callback_called) {
+ fprintf(stderr, "early callback not called\n");
+ return false;
+ }
+
+ if (!config->expected_server_name.empty()) {
+ const char *server_name =
+ SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
+ if (server_name != config->expected_server_name) {
+ fprintf(stderr, "servername mismatch (got %s; want %s)\n",
+ server_name, config->expected_server_name.c_str());
+ return false;
+ }
+ }
+
+ if (!config->expected_certificate_types.empty()) {
+ const uint8_t *certificate_types;
+ size_t certificate_types_len =
+ SSL_get0_certificate_types(ssl, &certificate_types);
+ if (certificate_types_len != config->expected_certificate_types.size() ||
+ memcmp(certificate_types,
+ config->expected_certificate_types.data(),
+ certificate_types_len) != 0) {
+ fprintf(stderr, "certificate types mismatch\n");
+ return false;
+ }
+ }
+
+ if (!config->expected_next_proto.empty()) {
+ const uint8_t *next_proto;
+ unsigned next_proto_len;
+ SSL_get0_next_proto_negotiated(ssl, &next_proto, &next_proto_len);
+ if (next_proto_len != config->expected_next_proto.size() ||
+ memcmp(next_proto, config->expected_next_proto.data(),
+ next_proto_len) != 0) {
+ fprintf(stderr, "negotiated next proto mismatch\n");
+ return false;
+ }
+ }
+
+ if (!config->expected_alpn.empty()) {
+ const uint8_t *alpn_proto;
+ unsigned alpn_proto_len;
+ SSL_get0_alpn_selected(ssl, &alpn_proto, &alpn_proto_len);
+ if (alpn_proto_len != config->expected_alpn.size() ||
+ memcmp(alpn_proto, config->expected_alpn.data(),
+ alpn_proto_len) != 0) {
+ fprintf(stderr, "negotiated alpn proto mismatch\n");
+ return false;
+ }
+ }
+
+ if (!config->expected_channel_id.empty()) {
+ uint8_t channel_id[64];
+ if (!SSL_get_tls_channel_id(ssl, channel_id, sizeof(channel_id))) {
+ fprintf(stderr, "no channel id negotiated\n");
+ return false;
+ }
+ if (config->expected_channel_id.size() != 64 ||
+ memcmp(config->expected_channel_id.data(),
+ channel_id, 64) != 0) {
+ fprintf(stderr, "channel id mismatch\n");
+ return false;
+ }
+ }
+
+ if (config->expect_extended_master_secret) {
+ if (!ssl->session->extended_master_secret) {
+ fprintf(stderr, "No EMS for session when expected");
+ return false;
+ }
+ }
+
+ if (!config->expected_ocsp_response.empty()) {
+ const uint8_t *data;
+ size_t len;
+ SSL_get0_ocsp_response(ssl, &data, &len);
+ if (config->expected_ocsp_response.size() != len ||
+ memcmp(config->expected_ocsp_response.data(), data, len) != 0) {
+ fprintf(stderr, "OCSP response mismatch\n");
+ return false;
+ }
+ }
+
+ if (!config->expected_signed_cert_timestamps.empty()) {
+ const uint8_t *data;
+ size_t len;
+ SSL_get0_signed_cert_timestamp_list(ssl, &data, &len);
+ if (config->expected_signed_cert_timestamps.size() != len ||
+ memcmp(config->expected_signed_cert_timestamps.data(),
+ data, len) != 0) {
+ fprintf(stderr, "SCT list mismatch\n");
+ return false;
+ }
+ }
+
+ if (config->expect_verify_result) {
+ int expected_verify_result = config->verify_fail ?
+ X509_V_ERR_APPLICATION_VERIFICATION :
+ X509_V_OK;
+
+ if (SSL_get_verify_result(ssl) != expected_verify_result) {
+ fprintf(stderr, "Wrong certificate verification result\n");
+ return false;
+ }
+ }
+
+ if (config->expect_server_key_exchange_hash != 0 &&
+ config->expect_server_key_exchange_hash !=
+ SSL_get_server_key_exchange_hash(ssl)) {
+ fprintf(stderr, "ServerKeyExchange hash was %d, wanted %d.\n",
+ SSL_get_server_key_exchange_hash(ssl),
+ config->expect_server_key_exchange_hash);
+ 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. */
+ if (config->psk.empty()) {
+ if (SSL_get_peer_cert_chain(ssl) == nullptr) {
+ fprintf(stderr, "Missing peer certificate chain!\n");
+ return false;
+ }
+ } else if (SSL_get_peer_cert_chain(ssl) != nullptr) {
+ fprintf(stderr, "Unexpected peer certificate chain!\n");
+ return false;
+ }
+ }
+ return true;
+}
+
// DoExchange runs a test SSL exchange against the peer. On success, it returns
// true and sets |*out_session| to the negotiated SSL session. If the test is a
// resumption attempt, |is_resume| is true and |session| is the session from the
@@ -562,7 +1148,10 @@ static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx,
}
if (config->require_any_client_certificate) {
SSL_set_verify(ssl.get(), SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
- SkipVerify);
+ NULL);
+ }
+ if (config->verify_peer) {
+ SSL_set_verify(ssl.get(), SSL_VERIFY_PEER, NULL);
}
if (config->false_start) {
SSL_set_mode(ssl.get(), SSL_MODE_ENABLE_FALSE_START);
@@ -585,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->allow_unsafe_legacy_renegotiation) {
- SSL_set_options(ssl.get(), SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
- }
- 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());
}
@@ -637,7 +1217,6 @@ static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx,
!SSL_enable_signed_cert_timestamps(ssl.get())) {
return false;
}
- SSL_enable_fastradio_padding(ssl.get(), config->fastradio_padding);
if (config->min_version != 0) {
SSL_set_min_version(ssl.get(), (uint16_t)config->min_version);
}
@@ -651,13 +1230,35 @@ static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx,
if (config->install_ddos_callback) {
SSL_CTX_set_dos_protection_cb(ssl_ctx, DDoSCallback);
}
- if (!config->cipher.empty() &&
- !SSL_set_cipher_list(ssl.get(), config->cipher.c_str())) {
- return false;
+ if (config->renegotiate_once) {
+ SSL_set_renegotiate_mode(ssl.get(), ssl_renegotiate_once);
+ }
+ if (config->renegotiate_freely) {
+ SSL_set_renegotiate_mode(ssl.get(), ssl_renegotiate_freely);
}
- if (!config->reject_peer_renegotiations) {
- /* Renegotiations are disabled by default. */
- SSL_set_reject_peer_renegotiations(ssl.get(), 0);
+ if (config->renegotiate_ignore) {
+ SSL_set_renegotiate_mode(ssl.get(), ssl_renegotiate_ignore);
+ }
+ if (!config->check_close_notify) {
+ SSL_set_quiet_shutdown(ssl.get(), 1);
+ }
+ 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);
@@ -719,125 +1320,14 @@ static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx,
ret = SSL_connect(ssl.get());
}
} while (config->async && RetryAsync(ssl.get(), ret));
- if (ret != 1) {
- return false;
- }
-
- if (SSL_get_current_cipher(ssl.get()) == nullptr) {
- fprintf(stderr, "null cipher after handshake\n");
- return false;
- }
-
- if (is_resume &&
- (!!SSL_session_reused(ssl.get()) == config->expect_session_miss)) {
- fprintf(stderr, "session was%s reused\n",
- SSL_session_reused(ssl.get()) ? "" : " not");
- return false;
- }
-
- bool expect_handshake_done = is_resume || !config->false_start;
- if (expect_handshake_done != GetTestState(ssl.get())->handshake_done) {
- fprintf(stderr, "handshake was%s completed\n",
- GetTestState(ssl.get())->handshake_done ? "" : " not");
- return false;
- }
-
- if (config->is_server && !GetTestState(ssl.get())->early_callback_called) {
- fprintf(stderr, "early callback not called\n");
+ if (ret != 1 ||
+ !CheckHandshakeProperties(ssl.get(), is_resume)) {
return false;
}
- if (!config->expected_server_name.empty()) {
- const char *server_name =
- SSL_get_servername(ssl.get(), TLSEXT_NAMETYPE_host_name);
- if (server_name != config->expected_server_name) {
- fprintf(stderr, "servername mismatch (got %s; want %s)\n",
- server_name, config->expected_server_name.c_str());
- return false;
- }
- }
-
- if (!config->expected_certificate_types.empty()) {
- uint8_t *certificate_types;
- int num_certificate_types =
- SSL_get0_certificate_types(ssl.get(), &certificate_types);
- if (num_certificate_types !=
- (int)config->expected_certificate_types.size() ||
- memcmp(certificate_types,
- config->expected_certificate_types.data(),
- num_certificate_types) != 0) {
- fprintf(stderr, "certificate types mismatch\n");
- return false;
- }
- }
-
- if (!config->expected_next_proto.empty()) {
- const uint8_t *next_proto;
- unsigned next_proto_len;
- SSL_get0_next_proto_negotiated(ssl.get(), &next_proto, &next_proto_len);
- if (next_proto_len != config->expected_next_proto.size() ||
- memcmp(next_proto, config->expected_next_proto.data(),
- next_proto_len) != 0) {
- fprintf(stderr, "negotiated next proto mismatch\n");
- return false;
- }
- }
-
- if (!config->expected_alpn.empty()) {
- const uint8_t *alpn_proto;
- unsigned alpn_proto_len;
- SSL_get0_alpn_selected(ssl.get(), &alpn_proto, &alpn_proto_len);
- if (alpn_proto_len != config->expected_alpn.size() ||
- memcmp(alpn_proto, config->expected_alpn.data(),
- alpn_proto_len) != 0) {
- fprintf(stderr, "negotiated alpn proto mismatch\n");
- return false;
- }
- }
-
- if (!config->expected_channel_id.empty()) {
- uint8_t channel_id[64];
- if (!SSL_get_tls_channel_id(ssl.get(), channel_id, sizeof(channel_id))) {
- fprintf(stderr, "no channel id negotiated\n");
- return false;
- }
- if (config->expected_channel_id.size() != 64 ||
- memcmp(config->expected_channel_id.data(),
- channel_id, 64) != 0) {
- fprintf(stderr, "channel id mismatch\n");
- return false;
- }
- }
-
- if (config->expect_extended_master_secret) {
- if (!ssl->session->extended_master_secret) {
- fprintf(stderr, "No EMS for session when expected");
- return false;
- }
- }
-
- if (!config->expected_ocsp_response.empty()) {
- const uint8_t *data;
- size_t len;
- SSL_get0_ocsp_response(ssl.get(), &data, &len);
- if (config->expected_ocsp_response.size() != len ||
- memcmp(config->expected_ocsp_response.data(), data, len) != 0) {
- fprintf(stderr, "OCSP response mismatch\n");
- return false;
- }
- }
-
- if (!config->expected_signed_cert_timestamps.empty()) {
- const uint8_t *data;
- size_t len;
- SSL_get0_signed_cert_timestamp_list(ssl.get(), &data, &len);
- if (config->expected_signed_cert_timestamps.size() != len ||
- memcmp(config->expected_signed_cert_timestamps.data(),
- data, len) != 0) {
- fprintf(stderr, "SCT list mismatch\n");
- return false;
- }
- }
+ // Reset the state to assert later that the callback isn't called in
+ // renegotations.
+ GetTestState(ssl.get())->got_new_session = false;
}
if (config->export_keying_material > 0) {
@@ -883,18 +1373,19 @@ static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx,
}
// This mode writes a number of different record sizes in an attempt to
// trip up the CBC record splitting code.
- uint8_t buf[32769];
- memset(buf, 0x42, sizeof(buf));
+ static const size_t kBufLen = 32769;
+ std::unique_ptr<uint8_t[]> buf(new uint8_t[kBufLen]);
+ memset(buf.get(), 0x42, kBufLen);
static const size_t kRecordSizes[] = {
0, 1, 255, 256, 257, 16383, 16384, 16385, 32767, 32768, 32769};
for (size_t i = 0; i < sizeof(kRecordSizes) / sizeof(kRecordSizes[0]);
i++) {
const size_t len = kRecordSizes[i];
- if (len > sizeof(buf)) {
+ if (len > kBufLen) {
fprintf(stderr, "Bad kRecordSizes value.\n");
return false;
}
- if (WriteAll(ssl.get(), buf, len) < 0) {
+ if (WriteAll(ssl.get(), buf.get(), len) < 0) {
return false;
}
}
@@ -905,53 +1396,90 @@ static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx,
return false;
}
}
- for (;;) {
- uint8_t buf[512];
- int n = DoRead(ssl.get(), buf, sizeof(buf));
- int err = SSL_get_error(ssl.get(), n);
- if (err == SSL_ERROR_ZERO_RETURN ||
- (n == 0 && err == SSL_ERROR_SYSCALL)) {
- if (n != 0) {
- fprintf(stderr, "Invalid SSL_get_error output\n");
+ if (!config->shim_shuts_down) {
+ for (;;) {
+ static const size_t kBufLen = 16384;
+ std::unique_ptr<uint8_t[]> buf(new uint8_t[kBufLen]);
+
+ // Read only 512 bytes at a time in TLS to ensure records may be
+ // returned in multiple reads.
+ int n = DoRead(ssl.get(), buf.get(), config->is_dtls ? kBufLen : 512);
+ int err = SSL_get_error(ssl.get(), n);
+ if (err == SSL_ERROR_ZERO_RETURN ||
+ (n == 0 && err == SSL_ERROR_SYSCALL)) {
+ if (n != 0) {
+ fprintf(stderr, "Invalid SSL_get_error output\n");
+ return false;
+ }
+ // Stop on either clean or unclean shutdown.
+ break;
+ } else if (err != SSL_ERROR_NONE) {
+ if (n > 0) {
+ fprintf(stderr, "Invalid SSL_get_error output\n");
+ return false;
+ }
return false;
}
- // Accept shutdowns with or without close_notify.
- // TODO(davidben): Write tests which distinguish these two cases.
- break;
- } else if (err != SSL_ERROR_NONE) {
- if (n > 0) {
+ // Successfully read data.
+ if (n <= 0) {
fprintf(stderr, "Invalid SSL_get_error output\n");
return false;
}
- return false;
- }
- // Successfully read data.
- if (n <= 0) {
- fprintf(stderr, "Invalid SSL_get_error output\n");
- return false;
- }
- // After a successful read, with or without False Start, the handshake
- // must be complete.
- if (!GetTestState(ssl.get())->handshake_done) {
- fprintf(stderr, "handshake was not completed after SSL_read\n");
- return false;
- }
+ // After a successful read, with or without False Start, the handshake
+ // must be complete.
+ if (!GetTestState(ssl.get())->handshake_done) {
+ fprintf(stderr, "handshake was not completed after SSL_read\n");
+ return false;
+ }
- for (int i = 0; i < n; i++) {
- buf[i] ^= 0xff;
- }
- if (WriteAll(ssl.get(), buf, n) < 0) {
- return false;
+ for (int i = 0; i < n; i++) {
+ buf[i] ^= 0xff;
+ }
+ if (WriteAll(ssl.get(), buf.get(), n) < 0) {
+ return false;
+ }
}
}
}
+ if (!config->is_server && !config->false_start &&
+ !config->implicit_handshake &&
+ GetTestState(ssl.get())->got_new_session) {
+ fprintf(stderr, "new session was established after the handshake\n");
+ return false;
+ }
+
if (out_session) {
out_session->reset(SSL_get1_session(ssl.get()));
}
- SSL_shutdown(ssl.get());
+ ret = DoShutdown(ssl.get());
+
+ if (config->shim_shuts_down && config->check_close_notify) {
+ // We initiate shutdown, so |SSL_shutdown| will return in two stages. First
+ // it returns zero when our close_notify is sent, then one when the peer's
+ // is received.
+ if (ret != 0) {
+ fprintf(stderr, "Unexpected SSL_shutdown result: %d != 0\n", ret);
+ return false;
+ }
+ ret = DoShutdown(ssl.get());
+ }
+
+ if (ret != 1) {
+ fprintf(stderr, "Unexpected SSL_shutdown result: %d != 1\n", ret);
+ return false;
+ }
+
+ if (SSL_total_renegotiations(ssl.get()) !=
+ config->expect_total_renegotiations) {
+ fprintf(stderr, "Expected %d renegotiations, got %d\n",
+ config->expect_total_renegotiations,
+ SSL_total_renegotiations(ssl.get()));
+ return false;
+ }
+
return true;
}
@@ -973,9 +1501,7 @@ int main(int argc, char **argv) {
signal(SIGPIPE, SIG_IGN);
#endif
- if (!SSL_library_init()) {
- return 1;
- }
+ CRYPTO_library_init();
g_config_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
g_state_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, TestStateExFree);
if (g_config_index < 0 || g_state_index < 0) {
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/alert.go b/src/ssl/test/runner/alert.go
index b48ab2a..541216e 100644
--- a/src/ssl/test/runner/alert.go
+++ b/src/ssl/test/runner/alert.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package main
+package runner
import "strconv"
diff --git a/src/ssl/test/runner/chacha20_poly1305.go b/src/ssl/test/runner/chacha20_poly1305.go
index 42911d4..3c6ad82 100644
--- a/src/ssl/test/runner/chacha20_poly1305.go
+++ b/src/ssl/test/runner/chacha20_poly1305.go
@@ -1,15 +1,15 @@
-package main
+package runner
import (
"crypto/cipher"
"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 726f482..4d19b8c 100644
--- a/src/ssl/test/runner/chacha20_poly1305_test.go
+++ b/src/ssl/test/runner/chacha20_poly1305_test.go
@@ -1,4 +1,4 @@
-package main
+package runner
import (
"bytes"
@@ -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 70c7262..bfd31a5 100644
--- a/src/ssl/test/runner/cipher_suites.go
+++ b/src/ssl/test/runner/cipher_suites.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package main
+package runner
import (
"crypto/aes"
@@ -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},
@@ -102,7 +104,6 @@ var cipherSuites = []*cipherSuite{
{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, 32, 48, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12 | suiteSHA384, cipherAES, macSHA384, nil},
{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil},
- {TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 32, 0, 0, dheRSAKA, suiteTLS12, nil, nil, aeadCHACHA20POLY1305},
{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, dheRSAKA, suiteTLS12, nil, nil, aeadAESGCM},
{TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, dheRSAKA, suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
{TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, dheRSAKA, suiteTLS12, cipherAES, macSHA256, nil},
@@ -120,12 +121,19 @@ 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_AES_128_GCM_SHA256, 16, 0, 4, ecdhePSKKA, suiteECDHE | suiteTLS12 | suitePSK, nil, nil, aeadAESGCM},
+ {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},
+}
+
+type nullCipher struct{}
+
+func cipherNull(key, iv []byte, isRead bool) interface{} {
+ return nullCipher{}
}
func cipherRC4(key, iv []byte, isRead bool) interface{} {
@@ -243,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
@@ -370,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_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
- 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_PSK_WITH_AES_128_GCM_SHA256 uint16 = 0xcafe
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcc13
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcc14
- TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcc15
+ 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 edebba1..db3c675 100644
--- a/src/ssl/test/runner/common.go
+++ b/src/ssl/test/runner/common.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package main
+package runner
import (
"container/list"
@@ -82,6 +82,7 @@ const (
extensionSignedCertificateTimestamp uint16 = 18
extensionExtendedMasterSecret uint16 = 23
extensionSessionTicket uint16 = 35
+ extensionCustom uint16 = 1234 // not IANA assigned
extensionNextProtoNeg uint16 = 13172 // not IANA assigned
extensionRenegotiationInfo uint16 = 0xff01
extensionChannelID uint16 = 30032 // not IANA assigned
@@ -97,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
@@ -188,7 +190,9 @@ type ConnectionState struct {
VerifiedChains [][]*x509.Certificate // verified chains built from PeerCertificates
ChannelID *ecdsa.PublicKey // the channel ID for this connection
SRTPProtectionProfile uint16 // the negotiated DTLS-SRTP protection profile
- TLSUnique []byte
+ TLSUnique []byte // the tls-unique channel binding
+ SCTList []byte // signed certificate timestamp list
+ ClientCertSignatureHash uint8 // TLS id of the hash used by the client to sign the handshake
}
// ClientAuthType declares the policy the server will follow for
@@ -214,6 +218,8 @@ type ClientSessionState struct {
handshakeHash []byte // Handshake hash for Channel ID purposes.
serverCertificates []*x509.Certificate // Certificate chain presented by the server
extendedMasterSecret bool // Whether an extended master secret was used to generate the session
+ sctList []byte
+ ocspResponse []byte
}
// ClientSessionCache is a cache of ClientSessionState objects that can be used
@@ -394,11 +400,26 @@ 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.
InvalidSKXSignature bool
+ // InvalidCertVerifySignature specifies that the signature in a
+ // CertificateVerify message should be invalid.
+ InvalidCertVerifySignature bool
+
// InvalidSKXCurve causes the curve ID in the ServerKeyExchange message
// to be wrong.
InvalidSKXCurve bool
@@ -476,6 +497,10 @@ type ProtocolBugs struct {
// TLS_FALLBACK_SCSV in the ClientHello.
SendFallbackSCSV bool
+ // SendRenegotiationSCSV causes the client to include the renegotiation
+ // SCSV in the ClientHello.
+ SendRenegotiationSCSV bool
+
// MaxHandshakeRecordLength, if non-zero, is the maximum size of a
// handshake record. Handshake messages will be split into multiple
// records at the specified size, except that the client_version will
@@ -496,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.
@@ -522,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
@@ -535,11 +554,14 @@ type ProtocolBugs struct {
// must specify in the server_name extension.
ExpectServerName string
- // SwapNPNAndALPN switches the relative order between NPN and
- // ALPN on the server. This is to test that server preference
- // of ALPN works regardless of their relative order.
+ // SwapNPNAndALPN switches the relative order between NPN and ALPN in
+ // both ClientHello and ServerHello.
SwapNPNAndALPN bool
+ // ALPNProtocol, if not nil, sets the ALPN protocol that a server will
+ // return.
+ ALPNProtocol *string
+
// AllowSessionVersionMismatch causes the server to resume sessions
// regardless of the version associated with the session.
AllowSessionVersionMismatch bool
@@ -568,15 +590,27 @@ 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
- // SequenceNumberIncrement, if non-zero, causes outgoing sequence
- // numbers in DTLS to increment by that value rather by 1. This is to
- // stress the replay bitmap window by simulating extreme packet loss and
- // retransmit at the record layer.
- SequenceNumberIncrement uint64
+ // 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
+
+ // SequenceNumberMapping, if non-nil, is the mapping function to apply
+ // to the sequence number of outgoing packets. For both TLS and DTLS,
+ // the two most-significant bytes in the resulting sequence number are
+ // ignored so that the DTLS epoch cannot be changed.
+ SequenceNumberMapping func(uint64) uint64
// RSAEphemeralKey, if true, causes the server to send a
// ServerKeyExchange message containing an ephemeral key (as in
@@ -609,10 +643,6 @@ type ProtocolBugs struct {
// across a renego.
RequireSameRenegoClientVersion bool
- // RequireFastradioPadding, if true, requires that ClientHello messages
- // be at least 1000 bytes long.
- RequireFastradioPadding bool
-
// ExpectInitialRecordVersion, if non-zero, is the expected
// version of the records before the version is determined.
ExpectInitialRecordVersion uint16
@@ -626,7 +656,11 @@ type ProtocolBugs struct {
// the server believes it has actually negotiated.
SendCipherSuite uint16
- // AppDataAfterChangeCipherSpec, if not null, causes application data to
+ // AppDataBeforeHandshake, if not nil, causes application data to be
+ // sent immediately before the first handshake message.
+ AppDataBeforeHandshake []byte
+
+ // AppDataAfterChangeCipherSpec, if not nil, causes application data to
// be sent immediately after ChangeCipherSpec.
AppDataAfterChangeCipherSpec []byte
@@ -668,17 +702,10 @@ type ProtocolBugs struct {
// handshake fragments in DTLS to have the wrong message length.
FragmentMessageLengthMismatch bool
- // SplitFragmentHeader, if true, causes the handshake fragments in DTLS
- // to be split across two records.
- SplitFragmentHeader bool
-
- // SplitFragmentBody, if true, causes the handshake bodies in DTLS to be
- // split across two records.
- //
- // TODO(davidben): There's one final split to test: when the header and
- // body are split across two records. But those are (incorrectly)
- // accepted right now.
- SplitFragmentBody bool
+ // SplitFragments, if non-zero, causes the handshake fragments in DTLS
+ // to be split across two records. The value of |SplitFragments| is the
+ // number of bytes in the first fragment.
+ SplitFragments int
// SendEmptyFragments, if true, causes handshakes to include empty
// fragments in DTLS.
@@ -705,10 +732,6 @@ type ProtocolBugs struct {
// preferences to be ignored.
IgnorePeerCurvePreferences bool
- // SendWarningAlerts, if non-zero, causes every record to be prefaced by
- // a warning alert.
- SendWarningAlerts alert
-
// BadFinished, if true, causes the Finished hash to be broken.
BadFinished bool
@@ -727,6 +750,70 @@ type ProtocolBugs struct {
// EnableAllCiphersInDTLS, if true, causes RC4 to be enabled in DTLS.
EnableAllCiphersInDTLS bool
+
+ // EmptyCertificateList, if true, causes the server to send an empty
+ // certificate list in the Certificate message.
+ EmptyCertificateList bool
+
+ // ExpectNewTicket, if true, causes the client to abort if it does not
+ // receive a new ticket.
+ ExpectNewTicket bool
+
+ // RequireClientHelloSize, if not zero, is the required length in bytes
+ // of the ClientHello /record/. This is checked by the server.
+ RequireClientHelloSize int
+
+ // CustomExtension, if not empty, contains the contents of an extension
+ // that will be added to client/server hellos.
+ CustomExtension string
+
+ // ExpectedCustomExtension, if not nil, contains the expected contents
+ // of a custom extension.
+ ExpectedCustomExtension *string
+
+ // NoCloseNotify, if true, causes the close_notify alert to be skipped
+ // on connection shutdown.
+ NoCloseNotify bool
+
+ // ExpectCloseNotify, if true, requires a close_notify from the peer on
+ // shutdown. Records from the peer received after close_notify is sent
+ // are not discard.
+ ExpectCloseNotify bool
+
+ // SendLargeRecords, if true, allows outgoing records to be sent
+ // arbitrarily large.
+ SendLargeRecords bool
+
+ // NegotiateALPNAndNPN, if true, causes the server to negotiate both
+ // ALPN and NPN in the same connetion.
+ NegotiateALPNAndNPN bool
+
+ // SendEmptySessionTicket, if true, causes the server to send an empty
+ // session ticket.
+ SendEmptySessionTicket bool
+
+ // FailIfSessionOffered, if true, causes the server to fail any
+ // connections where the client offers a non-empty session ID or session
+ // ticket.
+ FailIfSessionOffered bool
+
+ // SendHelloRequestBeforeEveryAppDataRecord, if true, causes a
+ // 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() {
@@ -784,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 adbc1c3..cb60a92 100644
--- a/src/ssl/test/runner/conn.go
+++ b/src/ssl/test/runner/conn.go
@@ -4,7 +4,7 @@
// TLS low level connection and record layer
-package main
+package runner
import (
"bytes"
@@ -12,6 +12,7 @@ import (
"crypto/ecdsa"
"crypto/subtle"
"crypto/x509"
+ "encoding/binary"
"errors"
"fmt"
"io"
@@ -39,6 +40,7 @@ type Conn struct {
extendedMasterSecret bool // whether this session used an extended master secret
cipherSuite *cipherSuite
ocspResponse []byte // stapled OCSP response
+ sctList []byte // signed certificate timestamp list
peerCertificates []*x509.Certificate
// verifiedChains contains the certificate chains that we built, as
// opposed to the ones presented by the server.
@@ -48,6 +50,11 @@ type Conn struct {
// firstFinished contains the first Finished hash sent during the
// handshake. This is the "tls-unique" channel binding value.
firstFinished [12]byte
+ // clientCertSignatureHash contains the TLS hash id for the hash that
+ // was used by the client to sign the handshake with a client
+ // certificate. This is only set by a server and is zero if no client
+ // certificates were used.
+ clientCertSignatureHash uint8
clientRandom, serverRandom [32]byte
masterSecret [48]byte
@@ -87,6 +94,8 @@ func (c *Conn) init() {
c.out.isDTLS = c.isDTLS
c.in.config = c.config
c.out.config = c.config
+
+ c.out.updateOutSeq()
}
// Access to net.Conn methods.
@@ -134,6 +143,7 @@ type halfConn struct {
cipher interface{} // cipher algorithm
mac macFunction
seq [8]byte // 64-bit sequence number
+ outSeq [8]byte // Mapped sequence number
bfree *block // list of free blocks
nextCipher interface{} // next encryption state
@@ -189,10 +199,6 @@ func (hc *halfConn) incSeq(isOutgoing bool) {
if hc.isDTLS {
// Increment up to the epoch in DTLS.
limit = 2
-
- if isOutgoing && hc.config.Bugs.SequenceNumberIncrement != 0 {
- increment = hc.config.Bugs.SequenceNumberIncrement
- }
}
for i := 7; i >= limit; i-- {
increment += uint64(hc.seq[i])
@@ -206,6 +212,8 @@ func (hc *halfConn) incSeq(isOutgoing bool) {
if increment != 0 {
panic("TLS: sequence number wraparound")
}
+
+ hc.updateOutSeq()
}
// incNextSeq increments the starting sequence number for the next epoch.
@@ -241,6 +249,22 @@ func (hc *halfConn) incEpoch() {
hc.seq[i] = 0
}
}
+
+ hc.updateOutSeq()
+}
+
+func (hc *halfConn) updateOutSeq() {
+ if hc.config.Bugs.SequenceNumberMapping != nil {
+ seqU64 := binary.BigEndian.Uint64(hc.seq[:])
+ seqU64 = hc.config.Bugs.SequenceNumberMapping(seqU64)
+ binary.BigEndian.PutUint64(hc.outSeq[:], seqU64)
+
+ // The DTLS epoch cannot be changed.
+ copy(hc.outSeq[:2], hc.seq[:2])
+ return
+ }
+
+ copy(hc.outSeq[:], hc.seq[:])
}
func (hc *halfConn) recordHeaderLen() int {
@@ -397,6 +421,8 @@ func (hc *halfConn) decrypt(b *block) (ok bool, prefixLen int, alertValue alert)
//
// However, our behavior matches OpenSSL, so we leak
// only as much as they do.
+ case nullCipher:
+ break
default:
panic("unknown cipher type")
}
@@ -460,7 +486,7 @@ func (hc *halfConn) encrypt(b *block, explicitIVLen int) (bool, alert) {
// mac
if hc.mac != nil {
- mac := hc.mac.MAC(hc.outDigestBuf, hc.seq[0:], b.data[:3], b.data[recordHeaderLen-2:recordHeaderLen], b.data[recordHeaderLen+explicitIVLen:])
+ mac := hc.mac.MAC(hc.outDigestBuf, hc.outSeq[0:], b.data[:3], b.data[recordHeaderLen-2:recordHeaderLen], b.data[recordHeaderLen+explicitIVLen:])
n := len(b.data)
b.resize(n + len(mac))
@@ -478,7 +504,7 @@ func (hc *halfConn) encrypt(b *block, explicitIVLen int) (bool, alert) {
case *tlsAead:
payloadLen := len(b.data) - recordHeaderLen - explicitIVLen
b.resize(len(b.data) + c.Overhead())
- nonce := hc.seq[:]
+ nonce := hc.outSeq[:]
if c.explicitNonce {
nonce = b.data[recordHeaderLen : recordHeaderLen+explicitIVLen]
}
@@ -486,7 +512,7 @@ func (hc *halfConn) encrypt(b *block, explicitIVLen int) (bool, alert) {
payload = payload[:payloadLen]
var additionalData [13]byte
- copy(additionalData[:], hc.seq[:])
+ copy(additionalData[:], hc.outSeq[:])
copy(additionalData[8:], b.data[:3])
additionalData[11] = byte(payloadLen >> 8)
additionalData[12] = byte(payloadLen)
@@ -502,6 +528,8 @@ func (hc *halfConn) encrypt(b *block, explicitIVLen int) (bool, alert) {
b.resize(recordHeaderLen + explicitIVLen + len(prefix) + len(finalBlock))
c.CryptBlocks(b.data[recordHeaderLen+explicitIVLen:], prefix)
c.CryptBlocks(b.data[recordHeaderLen+explicitIVLen+len(prefix):], finalBlock)
+ case nullCipher:
+ break
default:
panic("unknown cipher type")
}
@@ -630,10 +658,10 @@ func (c *Conn) doReadRecord(want recordType) (recordType, *block, error) {
if err := b.readFromUntil(c.conn, recordHeaderLen); err != nil {
// RFC suggests that EOF without an alertCloseNotify is
// an error, but popular web sites seem to do this,
- // so we can't make it an error.
- // if err == io.EOF {
- // err = io.ErrUnexpectedEOF
- // }
+ // so we can't make it an error, outside of tests.
+ if err == io.EOF && c.config.Bugs.ExpectCloseNotify {
+ err = io.ErrUnexpectedEOF
+ }
if e, ok := err.(net.Error); !ok || !e.Temporary() {
c.in.setErrorLocked(err)
}
@@ -722,6 +750,10 @@ func (c *Conn) readRecord(want recordType) error {
c.sendAlert(alertInternalError)
return c.in.setErrorLocked(errors.New("tls: application data record requested before handshake complete"))
}
+ case recordTypeAlert:
+ // Looking for a close_notify. Note: unlike a real
+ // implementation, this is not tolerant of additional records.
+ // See the documentation for ExpectCloseNotify.
}
Again:
@@ -784,7 +816,7 @@ Again:
// A client might need to process a HelloRequest from
// the server, thus receiving a handshake message when
// application data is expected is ok.
- if !c.isClient {
+ if !c.isClient || want != recordTypeApplicationData {
return c.in.setErrorLocked(c.sendAlert(alertNoRenegotiation))
}
}
@@ -799,13 +831,8 @@ Again:
// sendAlert sends a TLS alert message.
// c.out.Mutex <= L.
-func (c *Conn) sendAlertLocked(err alert) error {
- switch err {
- case alertNoRenegotiation, alertCloseNotify:
- c.tmp[0] = alertLevelWarning
- default:
- c.tmp[0] = alertLevelError
- }
+func (c *Conn) sendAlertLocked(level byte, err alert) error {
+ c.tmp[0] = level
c.tmp[1] = byte(err)
if c.config.Bugs.FragmentAlert {
c.writeRecord(recordTypeAlert, c.tmp[0:1])
@@ -813,8 +840,8 @@ func (c *Conn) sendAlertLocked(err alert) error {
} else {
c.writeRecord(recordTypeAlert, c.tmp[0:2])
}
- // closeNotify is a special case in that it isn't an error:
- if err != alertCloseNotify {
+ // Error alerts are fatal to the connection.
+ if level == alertLevelError {
return c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err})
}
return nil
@@ -823,9 +850,17 @@ func (c *Conn) sendAlertLocked(err alert) error {
// sendAlert sends a TLS alert message.
// L < c.out.Mutex.
func (c *Conn) sendAlert(err alert) error {
+ level := byte(alertLevelError)
+ if err == alertNoRenegotiation || err == alertCloseNotify {
+ level = alertLevelWarning
+ }
+ return c.SendAlert(level, err)
+}
+
+func (c *Conn) SendAlert(level byte, err alert) error {
c.out.Lock()
defer c.out.Unlock()
- return c.sendAlertLocked(err)
+ return c.sendAlertLocked(level, err)
}
// writeV2Record writes a record for a V2ClientHello.
@@ -841,13 +876,6 @@ func (c *Conn) writeV2Record(data []byte) (n int, err error) {
// to the connection and updates the record layer state.
// c.out.Mutex <= L.
func (c *Conn) writeRecord(typ recordType, data []byte) (n int, err error) {
- if typ != recordTypeAlert && c.config.Bugs.SendWarningAlerts != 0 {
- alert := make([]byte, 2)
- alert[0] = alertLevelWarning
- alert[1] = byte(c.config.Bugs.SendWarningAlerts)
- c.writeRecord(recordTypeAlert, alert)
- }
-
if c.isDTLS {
return c.dtlsWriteRecord(typ, data)
}
@@ -856,9 +884,9 @@ func (c *Conn) writeRecord(typ recordType, data []byte) (n int, err error) {
b := c.out.newBlock()
first := true
isClientHello := typ == recordTypeHandshake && len(data) > 0 && data[0] == typeClientHello
- for len(data) > 0 {
+ for len(data) > 0 || first {
m := len(data)
- if m > maxPlaintext {
+ if m > maxPlaintext && !c.config.Bugs.SendLargeRecords {
m = maxPlaintext
}
if typ == recordTypeHandshake && c.config.Bugs.MaxHandshakeRecordLength > 0 && m > c.config.Bugs.MaxHandshakeRecordLength {
@@ -1038,6 +1066,9 @@ func (c *Conn) readHandshake() (interface{}, error) {
// sequence number expectations but otherwise ignores them.
func (c *Conn) skipPacket(packet []byte) error {
for len(packet) > 0 {
+ if len(packet) < 13 {
+ return errors.New("tls: bad packet")
+ }
// Dropped packets are completely ignored save to update
// expected sequence numbers for this and the next epoch. (We
// don't assert on the contents of the packets both for
@@ -1047,16 +1078,21 @@ func (c *Conn) skipPacket(packet []byte) error {
seq := packet[5:11]
length := uint16(packet[11])<<8 | uint16(packet[12])
if bytes.Equal(c.in.seq[:2], epoch) {
- if !bytes.Equal(c.in.seq[2:], seq) {
+ if bytes.Compare(seq, c.in.seq[2:]) < 0 {
return errors.New("tls: sequence mismatch")
}
+ copy(c.in.seq[2:], seq)
c.in.incSeq(false)
} else {
- if !bytes.Equal(c.in.nextSeq[:], seq) {
+ if bytes.Compare(seq, c.in.nextSeq[:]) < 0 {
return errors.New("tls: sequence mismatch")
}
+ copy(c.in.nextSeq[:], seq)
c.in.incNextSeq()
}
+ if len(packet) < 13+int(length) {
+ return errors.New("tls: bad packet")
+ }
packet = packet[13+length:]
}
return nil
@@ -1113,7 +1149,11 @@ func (c *Conn) Write(b []byte) (int, error) {
}
if c.config.Bugs.SendSpuriousAlert != 0 {
- c.sendAlertLocked(c.config.Bugs.SendSpuriousAlert)
+ c.sendAlertLocked(alertLevelError, c.config.Bugs.SendSpuriousAlert)
+ }
+
+ if c.config.Bugs.SendHelloRequestBeforeEveryAppDataRecord {
+ c.writeRecord(recordTypeHandshake, []byte{typeHelloRequest, 0, 0, 0})
}
// SSL 3.0 and TLS 1.0 are susceptible to a chosen-plaintext
@@ -1161,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
@@ -1240,10 +1283,22 @@ func (c *Conn) Close() error {
c.handshakeMutex.Lock()
defer c.handshakeMutex.Unlock()
- if c.handshakeComplete {
+ if c.handshakeComplete && !c.config.Bugs.NoCloseNotify {
alertErr = c.sendAlert(alertCloseNotify)
}
+ // Consume a close_notify from the peer if one hasn't been received
+ // already. This avoids the peer from failing |SSL_shutdown| due to a
+ // write failing.
+ if c.handshakeComplete && alertErr == nil && c.config.Bugs.ExpectCloseNotify {
+ for c.in.error() == nil {
+ c.readRecord(recordTypeAlert)
+ }
+ if c.in.error() != io.EOF {
+ alertErr = c.in.error()
+ }
+ }
+
if err := c.conn.Close(); err != nil {
return err
}
@@ -1273,6 +1328,9 @@ func (c *Conn) Handshake() error {
})
c.conn.Write([]byte{alertLevelError, byte(alertInternalError)})
}
+ if data := c.config.Bugs.AppDataBeforeHandshake; data != nil {
+ c.writeRecord(recordTypeApplicationData, data)
+ }
if c.isClient {
c.handshakeErr = c.clientHandshake()
} else {
@@ -1304,6 +1362,8 @@ func (c *Conn) ConnectionState() ConnectionState {
state.ChannelID = c.channelID
state.SRTPProtectionProfile = c.srtpProtectionProfile
state.TLSUnique = c.firstFinished[:]
+ state.SCTList = c.sctList
+ state.ClientCertSignatureHash = c.clientCertSignatureHash
}
return state
@@ -1357,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/dtls.go b/src/ssl/test/runner/dtls.go
index 50f7786..c3ee521 100644
--- a/src/ssl/test/runner/dtls.go
+++ b/src/ssl/test/runner/dtls.go
@@ -12,7 +12,7 @@
// with simulated loss, but there is no point in forcing the test
// driver to.
-package main
+package runner
import (
"bytes"
@@ -80,15 +80,21 @@ func (c *Conn) dtlsDoReadRecord(want recordType) (recordType, *block, error) {
return 0, nil, c.in.setErrorLocked(fmt.Errorf("dtls: received record with version %x when expecting version %x", vers, expect))
}
}
- seq := b.data[3:11]
- // For test purposes, we assume a reliable channel. Require
- // that the explicit sequence number matches the incrementing
- // one we maintain. A real implementation would maintain a
- // replay window and such.
- if !bytes.Equal(seq, c.in.seq[:]) {
+ epoch := b.data[3:5]
+ seq := b.data[5:11]
+ // For test purposes, require the sequence number be monotonically
+ // increasing, so c.in includes the minimum next sequence number. Gaps
+ // may occur if packets failed to be sent out. A real implementation
+ // would maintain a replay window and such.
+ if !bytes.Equal(epoch, c.in.seq[:2]) {
+ c.sendAlert(alertIllegalParameter)
+ return 0, nil, c.in.setErrorLocked(fmt.Errorf("dtls: bad epoch"))
+ }
+ if bytes.Compare(seq, c.in.seq[2:]) < 0 {
c.sendAlert(alertIllegalParameter)
return 0, nil, c.in.setErrorLocked(fmt.Errorf("dtls: bad sequence number"))
}
+ copy(c.in.seq[2:], seq)
n := int(b.data[11])<<8 | int(b.data[12])
if n > maxCiphertext || len(b.data) < recordHeaderLen+n {
c.sendAlert(alertRecordOverflow)
@@ -216,13 +222,10 @@ func (c *Conn) dtlsFlushHandshake() error {
// Pack handshake fragments into records.
var records [][]byte
for _, fragment := range fragments {
- if c.config.Bugs.SplitFragmentHeader {
- records = append(records, fragment[:2])
- records = append(records, fragment[2:])
- } else if c.config.Bugs.SplitFragmentBody {
- if len(fragment) > 12 {
- records = append(records, fragment[:13])
- records = append(records, fragment[13:])
+ if n := c.config.Bugs.SplitFragments; n > 0 {
+ if len(fragment) > n {
+ records = append(records, fragment[:n])
+ records = append(records, fragment[n:])
} else {
records = append(records, fragment)
}
@@ -301,13 +304,13 @@ func (c *Conn) dtlsSealRecord(typ recordType, data []byte) (b *block, err error)
b.data[1] = byte(vers >> 8)
b.data[2] = byte(vers)
// DTLS records include an explicit sequence number.
- copy(b.data[3:11], c.out.seq[0:])
+ copy(b.data[3:11], c.out.outSeq[0:])
b.data[11] = byte(len(data) >> 8)
b.data[12] = byte(len(data))
if explicitIVLen > 0 {
explicitIV := b.data[recordHeaderLen : recordHeaderLen+explicitIVLen]
if explicitIVIsSeq {
- copy(explicitIV, c.out.seq[:])
+ copy(explicitIV, c.out.outSeq[:])
} else {
if _, err = io.ReadFull(c.config.rand(), explicitIV); err != nil {
return
diff --git a/src/ssl/test/runner/handshake_client.go b/src/ssl/test/runner/handshake_client.go
index a950313..64630ba 100644
--- a/src/ssl/test/runner/handshake_client.go
+++ b/src/ssl/test/runner/handshake_client.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package main
+package runner
import (
"bytes"
@@ -45,7 +45,7 @@ func (c *Conn) clientHandshake() error {
nextProtosLength := 0
for _, proto := range c.config.NextProtos {
- if l := len(proto); l == 0 || l > 255 {
+ if l := len(proto); l > 255 {
return errors.New("tls: invalid NextProtos value")
} else {
nextProtosLength += 1 + l
@@ -61,6 +61,7 @@ func (c *Conn) clientHandshake() error {
compressionMethods: []uint8{compressionNone},
random: make([]byte, 32),
ocspStapling: true,
+ sctListSupported: true,
serverName: c.config.ServerName,
supportedCurves: c.config.curvePreferences(),
supportedPoints: []uint8{pointFormatUncompressed},
@@ -73,6 +74,7 @@ func (c *Conn) clientHandshake() error {
extendedMasterSecret: c.config.maxVersion() >= VersionTLS10,
srtpProtectionProfiles: c.config.SRTPProtectionProfiles,
srtpMasterKeyIdentifier: c.config.Bugs.SRTPMasterKeyIdentifer,
+ customExtension: c.config.Bugs.CustomExtension,
}
if c.config.Bugs.SendClientVersion != 0 {
@@ -96,7 +98,7 @@ func (c *Conn) clientHandshake() error {
}
}
- if c.config.Bugs.NoRenegotiationInfo {
+ if c.noRenegotiationInfo() {
hello.secureRenegotiation = nil
}
@@ -123,6 +125,10 @@ NextCipherSuite:
}
}
+ if c.config.Bugs.SendRenegotiationSCSV {
+ hello.cipherSuites = append(hello.cipherSuites, renegotiationSCSV)
+ }
+
if c.config.Bugs.SendFallbackSCSV {
hello.cipherSuites = append(hello.cipherSuites, fallbackSCSV)
}
@@ -272,7 +278,11 @@ NextCipherSuite:
return fmt.Errorf("tls: server selected an unsupported cipher suite")
}
- if len(c.clientVerify) > 0 && !c.config.Bugs.NoRenegotiationInfo {
+ if c.config.Bugs.RequireRenegotiationInfo && serverHello.secureRenegotiation == nil {
+ return errors.New("tls: renegotiation extension missing")
+ }
+
+ if len(c.clientVerify) > 0 && !c.noRenegotiationInfo() {
var expectedRenegInfo []byte
expectedRenegInfo = append(expectedRenegInfo, c.clientVerify...)
expectedRenegInfo = append(expectedRenegInfo, c.serverVerify...)
@@ -282,6 +292,12 @@ NextCipherSuite:
}
}
+ if expected := c.config.Bugs.ExpectedCustomExtension; expected != nil {
+ if serverHello.customExtension != *expected {
+ return fmt.Errorf("tls: bad custom extension contents %q", serverHello.customExtension)
+ }
+ }
+
hs := &clientHandshakeState{
c: c,
serverHello: serverHello,
@@ -356,6 +372,7 @@ NextCipherSuite:
copy(c.clientRandom[:], hs.hello.random)
copy(c.serverRandom[:], hs.serverHello.random)
copy(c.masterSecret[:], hs.masterSecret)
+
return nil
}
@@ -607,6 +624,9 @@ func (hs *clientHandshakeState) doFullHandshake() error {
c.sendAlert(alertInternalError)
return err
}
+ if c.config.Bugs.InvalidCertVerifySignature {
+ digest[0] ^= 0x80
+ }
switch key := c.config.Certificates[0].PrivateKey.(type) {
case *ecdsa.PrivateKey:
@@ -730,13 +750,28 @@ func (hs *clientHandshakeState) processServerHello() (bool, error) {
return false, errors.New("tls: server resumed session on renegotiation")
}
+ if hs.serverHello.sctList != nil {
+ return false, errors.New("tls: server sent SCT extension on session resumption")
+ }
+
+ if hs.serverHello.ocspStapling {
+ return false, errors.New("tls: server sent OCSP extension on session resumption")
+ }
+
// Restore masterSecret and peerCerts from previous state
hs.masterSecret = hs.session.masterSecret
c.peerCertificates = hs.session.serverCertificates
c.extendedMasterSecret = hs.session.extendedMasterSecret
+ c.sctList = hs.session.sctList
+ c.ocspResponse = hs.session.ocspResponse
hs.finishedHash.discardHandshakeBuffer()
return true, nil
}
+
+ if hs.serverHello.sctList != nil {
+ c.sctList = hs.serverHello.sctList
+ }
+
return false, nil
}
@@ -783,9 +818,14 @@ func (hs *clientHandshakeState) readSessionTicket() error {
masterSecret: hs.masterSecret,
handshakeHash: hs.finishedHash.server.Sum(nil),
serverCertificates: c.peerCertificates,
+ sctList: c.sctList,
+ ocspResponse: c.ocspResponse,
}
if !hs.serverHello.ticketSupported {
+ if c.config.Bugs.ExpectNewTicket {
+ return errors.New("tls: expected new ticket")
+ }
if hs.session == nil && len(hs.serverHello.sessionId) > 0 {
session.sessionId = hs.serverHello.sessionId
hs.session = session
@@ -793,6 +833,10 @@ func (hs *clientHandshakeState) readSessionTicket() error {
return nil
}
+ if c.vers == VersionSSL30 {
+ return errors.New("tls: negotiated session tickets in SSL 3.0")
+ }
+
msg, err := c.readHandshake()
if err != nil {
return err
@@ -880,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_messages.go b/src/ssl/test/runner/handshake_messages.go
index ce214fd..530ddbc 100644
--- a/src/ssl/test/runner/handshake_messages.go
+++ b/src/ssl/test/runner/handshake_messages.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package main
+package runner
import "bytes"
@@ -32,6 +32,7 @@ type clientHelloMsg struct {
srtpProtectionProfiles []uint16
srtpMasterKeyIdentifier string
sctListSupported bool
+ customExtension string
}
func (m *clientHelloMsg) equal(i interface{}) bool {
@@ -65,7 +66,8 @@ func (m *clientHelloMsg) equal(i interface{}) bool {
m.extendedMasterSecret == m1.extendedMasterSecret &&
eqUint16s(m.srtpProtectionProfiles, m1.srtpProtectionProfiles) &&
m.srtpMasterKeyIdentifier == m1.srtpMasterKeyIdentifier &&
- m.sctListSupported == m1.sctListSupported
+ m.sctListSupported == m1.sctListSupported &&
+ m.customExtension == m1.customExtension
}
func (m *clientHelloMsg) marshal() []byte {
@@ -119,7 +121,7 @@ func (m *clientHelloMsg) marshal() []byte {
if len(m.alpnProtocols) > 0 {
extensionsLength += 2
for _, s := range m.alpnProtocols {
- if l := len(s); l == 0 || l > 255 {
+ if l := len(s); l > 255 {
panic("invalid ALPN protocol")
}
extensionsLength++
@@ -138,6 +140,10 @@ func (m *clientHelloMsg) marshal() []byte {
if m.sctListSupported {
numExtensions++
}
+ if l := len(m.customExtension); l > 0 {
+ extensionsLength += l
+ numExtensions++
+ }
if numExtensions > 0 {
extensionsLength += 4 * numExtensions
length += 2 + extensionsLength
@@ -376,6 +382,14 @@ func (m *clientHelloMsg) marshal() []byte {
z[1] = byte(extensionSignedCertificateTimestamp & 0xff)
z = z[4:]
}
+ if l := len(m.customExtension); l > 0 {
+ z[0] = byte(extensionCustom >> 8)
+ z[1] = byte(extensionCustom & 0xff)
+ z[2] = byte(l >> 8)
+ z[3] = byte(l & 0xff)
+ copy(z[4:], []byte(m.customExtension))
+ z = z[4+l:]
+ }
m.raw = x
@@ -443,6 +457,7 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
m.signatureAndHashes = nil
m.alpnProtocols = nil
m.extendedMasterSecret = false
+ m.customExtension = ""
if len(data) == 0 {
// ClientHello is optionally followed by extension data
@@ -604,6 +619,8 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
return false
}
m.sctListSupported = true
+ case extensionCustom:
+ m.customExtension = string(data[:length])
}
data = data[length:]
}
@@ -625,40 +642,15 @@ type serverHelloMsg struct {
ticketSupported bool
secureRenegotiation []byte
alpnProtocol string
+ alpnProtocolEmpty bool
duplicateExtension bool
channelIDRequested bool
extendedMasterSecret bool
srtpProtectionProfile uint16
srtpMasterKeyIdentifier string
sctList []byte
-}
-
-func (m *serverHelloMsg) equal(i interface{}) bool {
- m1, ok := i.(*serverHelloMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- m.isDTLS == m1.isDTLS &&
- m.vers == m1.vers &&
- bytes.Equal(m.random, m1.random) &&
- bytes.Equal(m.sessionId, m1.sessionId) &&
- m.cipherSuite == m1.cipherSuite &&
- m.compressionMethod == m1.compressionMethod &&
- m.nextProtoNeg == m1.nextProtoNeg &&
- eqStrings(m.nextProtos, m1.nextProtos) &&
- m.ocspStapling == m1.ocspStapling &&
- m.ticketSupported == m1.ticketSupported &&
- bytes.Equal(m.secureRenegotiation, m1.secureRenegotiation) &&
- (m.secureRenegotiation == nil) == (m1.secureRenegotiation == nil) &&
- m.alpnProtocol == m1.alpnProtocol &&
- m.duplicateExtension == m1.duplicateExtension &&
- m.channelIDRequested == m1.channelIDRequested &&
- m.extendedMasterSecret == m1.extendedMasterSecret &&
- m.srtpProtectionProfile == m1.srtpProtectionProfile &&
- m.srtpMasterKeyIdentifier == m1.srtpMasterKeyIdentifier &&
- bytes.Equal(m.sctList, m1.sctList)
+ customExtension string
+ npnLast bool
}
func (m *serverHelloMsg) marshal() []byte {
@@ -695,7 +687,7 @@ func (m *serverHelloMsg) marshal() []byte {
if m.channelIDRequested {
numExtensions++
}
- if alpnLen := len(m.alpnProtocol); alpnLen > 0 {
+ if alpnLen := len(m.alpnProtocol); alpnLen > 0 || m.alpnProtocolEmpty {
if alpnLen >= 256 {
panic("invalid ALPN protocol")
}
@@ -713,6 +705,10 @@ func (m *serverHelloMsg) marshal() []byte {
extensionsLength += len(m.sctList)
numExtensions++
}
+ if l := len(m.customExtension); l > 0 {
+ extensionsLength += l
+ numExtensions++
+ }
if numExtensions > 0 {
extensionsLength += 4 * numExtensions
@@ -747,7 +743,7 @@ func (m *serverHelloMsg) marshal() []byte {
z[1] = 0xff
z = z[4:]
}
- if m.nextProtoNeg {
+ if m.nextProtoNeg && !m.npnLast {
z[0] = byte(extensionNextProtoNeg >> 8)
z[1] = byte(extensionNextProtoNeg & 0xff)
z[2] = byte(nextProtoLen >> 8)
@@ -784,7 +780,7 @@ func (m *serverHelloMsg) marshal() []byte {
copy(z, m.secureRenegotiation)
z = z[len(m.secureRenegotiation):]
}
- if alpnLen := len(m.alpnProtocol); alpnLen > 0 {
+ if alpnLen := len(m.alpnProtocol); alpnLen > 0 || m.alpnProtocolEmpty {
z[0] = byte(extensionALPN >> 8)
z[1] = byte(extensionALPN & 0xff)
l := 2 + 1 + alpnLen
@@ -838,6 +834,31 @@ func (m *serverHelloMsg) marshal() []byte {
copy(z[4:], m.sctList)
z = z[4+l:]
}
+ if l := len(m.customExtension); l > 0 {
+ z[0] = byte(extensionCustom >> 8)
+ z[1] = byte(extensionCustom & 0xff)
+ z[2] = byte(l >> 8)
+ z[3] = byte(l & 0xff)
+ copy(z[4:], []byte(m.customExtension))
+ z = z[4+l:]
+ }
+ if m.nextProtoNeg && m.npnLast {
+ z[0] = byte(extensionNextProtoNeg >> 8)
+ z[1] = byte(extensionNextProtoNeg & 0xff)
+ z[2] = byte(nextProtoLen >> 8)
+ z[3] = byte(nextProtoLen)
+ z = z[4:]
+
+ for _, v := range m.nextProtos {
+ l := len(v)
+ if l > 255 {
+ l = 255
+ }
+ z[0] = byte(l)
+ copy(z[1:], []byte(v[0:l]))
+ z = z[1+l:]
+ }
+ }
m.raw = x
@@ -869,7 +890,9 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool {
m.ocspStapling = false
m.ticketSupported = false
m.alpnProtocol = ""
+ m.alpnProtocolEmpty = false
m.extendedMasterSecret = false
+ m.customExtension = ""
if len(data) == 0 {
// ServerHello is optionally followed by extension data
@@ -940,6 +963,7 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool {
}
d = d[1:]
m.alpnProtocol = string(d)
+ m.alpnProtocolEmpty = len(d) == 0
case extensionChannelID:
if length > 0 {
return false
@@ -965,14 +989,9 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool {
}
m.srtpMasterKeyIdentifier = string(d[1:])
case extensionSignedCertificateTimestamp:
- if length < 2 {
- return false
- }
- l := int(data[0])<<8 | int(data[1])
- if l != len(data)-2 {
- return false
- }
- m.sctList = data[2:length]
+ m.sctList = data[:length]
+ case extensionCustom:
+ m.customExtension = string(data[:length])
}
data = data[length:]
}
@@ -985,16 +1004,6 @@ type certificateMsg struct {
certificates [][]byte
}
-func (m *certificateMsg) equal(i interface{}) bool {
- m1, ok := i.(*certificateMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- eqByteSlices(m.certificates, m1.certificates)
-}
-
func (m *certificateMsg) marshal() (x []byte) {
if m.raw != nil {
return m.raw
@@ -1072,16 +1081,6 @@ type serverKeyExchangeMsg struct {
key []byte
}
-func (m *serverKeyExchangeMsg) equal(i interface{}) bool {
- m1, ok := i.(*serverKeyExchangeMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- bytes.Equal(m.key, m1.key)
-}
-
func (m *serverKeyExchangeMsg) marshal() []byte {
if m.raw != nil {
return m.raw
@@ -1113,17 +1112,6 @@ type certificateStatusMsg struct {
response []byte
}
-func (m *certificateStatusMsg) equal(i interface{}) bool {
- m1, ok := i.(*certificateStatusMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- m.statusType == m1.statusType &&
- bytes.Equal(m.response, m1.response)
-}
-
func (m *certificateStatusMsg) marshal() []byte {
if m.raw != nil {
return m.raw
@@ -1175,11 +1163,6 @@ func (m *certificateStatusMsg) unmarshal(data []byte) bool {
type serverHelloDoneMsg struct{}
-func (m *serverHelloDoneMsg) equal(i interface{}) bool {
- _, ok := i.(*serverHelloDoneMsg)
- return ok
-}
-
func (m *serverHelloDoneMsg) marshal() []byte {
x := make([]byte, 4)
x[0] = typeServerHelloDone
@@ -1195,16 +1178,6 @@ type clientKeyExchangeMsg struct {
ciphertext []byte
}
-func (m *clientKeyExchangeMsg) equal(i interface{}) bool {
- m1, ok := i.(*clientKeyExchangeMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- bytes.Equal(m.ciphertext, m1.ciphertext)
-}
-
func (m *clientKeyExchangeMsg) marshal() []byte {
if m.raw != nil {
return m.raw
@@ -1239,16 +1212,6 @@ type finishedMsg struct {
verifyData []byte
}
-func (m *finishedMsg) equal(i interface{}) bool {
- m1, ok := i.(*finishedMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- bytes.Equal(m.verifyData, m1.verifyData)
-}
-
func (m *finishedMsg) marshal() (x []byte) {
if m.raw != nil {
return m.raw
@@ -1276,16 +1239,6 @@ type nextProtoMsg struct {
proto string
}
-func (m *nextProtoMsg) equal(i interface{}) bool {
- m1, ok := i.(*nextProtoMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- m.proto == m1.proto
-}
-
func (m *nextProtoMsg) marshal() []byte {
if m.raw != nil {
return m.raw
@@ -1353,18 +1306,6 @@ type certificateRequestMsg struct {
certificateAuthorities [][]byte
}
-func (m *certificateRequestMsg) equal(i interface{}) bool {
- m1, ok := i.(*certificateRequestMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- bytes.Equal(m.certificateTypes, m1.certificateTypes) &&
- eqByteSlices(m.certificateAuthorities, m1.certificateAuthorities) &&
- eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes)
-}
-
func (m *certificateRequestMsg) marshal() (x []byte) {
if m.raw != nil {
return m.raw
@@ -1507,19 +1448,6 @@ type certificateVerifyMsg struct {
signature []byte
}
-func (m *certificateVerifyMsg) equal(i interface{}) bool {
- m1, ok := i.(*certificateVerifyMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- m.hasSignatureAndHash == m1.hasSignatureAndHash &&
- m.signatureAndHash.hash == m1.signatureAndHash.hash &&
- m.signatureAndHash.signature == m1.signatureAndHash.signature &&
- bytes.Equal(m.signature, m1.signature)
-}
-
func (m *certificateVerifyMsg) marshal() (x []byte) {
if m.raw != nil {
return m.raw
@@ -1589,16 +1517,6 @@ type newSessionTicketMsg struct {
ticket []byte
}
-func (m *newSessionTicketMsg) equal(i interface{}) bool {
- m1, ok := i.(*newSessionTicketMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- bytes.Equal(m.ticket, m1.ticket)
-}
-
func (m *newSessionTicketMsg) marshal() (x []byte) {
if m.raw != nil {
return m.raw
@@ -1651,19 +1569,6 @@ type v2ClientHelloMsg struct {
challenge []byte
}
-func (m *v2ClientHelloMsg) equal(i interface{}) bool {
- m1, ok := i.(*v2ClientHelloMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- m.vers == m1.vers &&
- eqUint16s(m.cipherSuites, m1.cipherSuites) &&
- bytes.Equal(m.sessionId, m1.sessionId) &&
- bytes.Equal(m.challenge, m1.challenge)
-}
-
func (m *v2ClientHelloMsg) marshal() []byte {
if m.raw != nil {
return m.raw
@@ -1703,17 +1608,6 @@ type helloVerifyRequestMsg struct {
cookie []byte
}
-func (m *helloVerifyRequestMsg) equal(i interface{}) bool {
- m1, ok := i.(*helloVerifyRequestMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- m.vers == m1.vers &&
- bytes.Equal(m.cookie, m1.cookie)
-}
-
func (m *helloVerifyRequestMsg) marshal() []byte {
if m.raw != nil {
return m.raw
@@ -1755,16 +1649,6 @@ type encryptedExtensionsMsg struct {
channelID []byte
}
-func (m *encryptedExtensionsMsg) equal(i interface{}) bool {
- m1, ok := i.(*encryptedExtensionsMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- bytes.Equal(m.channelID, m1.channelID)
-}
-
func (m *encryptedExtensionsMsg) marshal() []byte {
if m.raw != nil {
return m.raw
diff --git a/src/ssl/test/runner/handshake_server.go b/src/ssl/test/runner/handshake_server.go
index 85cc0d2..0232772 100644
--- a/src/ssl/test/runner/handshake_server.go
+++ b/src/ssl/test/runner/handshake_server.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package main
+package runner
import (
"bytes"
@@ -139,8 +139,8 @@ func (hs *serverHandshakeState) readClientHello() (isResume bool, err error) {
c.sendAlert(alertUnexpectedMessage)
return false, unexpectedMessageError(hs.clientHello, msg)
}
- if config.Bugs.RequireFastradioPadding && len(hs.clientHello.raw) < 1000 {
- return false, errors.New("tls: ClientHello record size should be larger than 1000 bytes when padding enabled.")
+ if size := config.Bugs.RequireClientHelloSize; size != 0 && len(hs.clientHello.raw) != size {
+ return false, fmt.Errorf("tls: ClientHello record size is %d, but expected %d", len(hs.clientHello.raw), size)
}
if c.isDTLS && !config.Bugs.SkipHelloVerifyRequest {
@@ -203,6 +203,15 @@ func (hs *serverHandshakeState) readClientHello() (isResume bool, err error) {
hs.clientHello.signatureAndHashes = config.signatureAndHashesForServer()
}
+ // Check the client cipher list is consistent with the version.
+ if hs.clientHello.vers < VersionTLS12 {
+ for _, id := range hs.clientHello.cipherSuites {
+ if isTLS12Cipher(id) {
+ return false, fmt.Errorf("tls: client offered TLS 1.2 cipher before TLS 1.2")
+ }
+ }
+ }
+
c.vers, ok = config.mutualVersion(hs.clientHello.vers)
if !ok {
c.sendAlert(alertProtocolVersion)
@@ -210,8 +219,11 @@ func (hs *serverHandshakeState) readClientHello() (isResume bool, err error) {
}
c.haveVers = true
- hs.hello = new(serverHelloMsg)
- hs.hello.isDTLS = c.isDTLS
+ hs.hello = &serverHelloMsg{
+ isDTLS: c.isDTLS,
+ customExtension: config.Bugs.CustomExtension,
+ npnLast: config.Bugs.SwapNPNAndALPN,
+ }
supportedCurve := false
preferredCurves := config.curvePreferences()
@@ -274,7 +286,7 @@ Curves:
hs.hello.secureRenegotiation = hs.clientHello.secureRenegotiation
}
- if c.config.Bugs.NoRenegotiationInfo {
+ if c.noRenegotiationInfo() {
hs.hello.secureRenegotiation = nil
}
@@ -285,12 +297,18 @@ Curves:
}
if len(hs.clientHello.alpnProtocols) > 0 {
- if selectedProto, fallback := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos); !fallback {
+ if proto := c.config.Bugs.ALPNProtocol; proto != nil {
+ hs.hello.alpnProtocol = *proto
+ hs.hello.alpnProtocolEmpty = len(*proto) == 0
+ c.clientProtocol = *proto
+ c.usedALPN = true
+ } else if selectedProto, fallback := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos); !fallback {
hs.hello.alpnProtocol = selectedProto
c.clientProtocol = selectedProto
c.usedALPN = true
}
- } else {
+ }
+ if len(hs.clientHello.alpnProtocols) == 0 || c.config.Bugs.NegotiateALPNAndNPN {
// Although sending an empty NPN extension is reasonable, Firefox has
// had a bug around this. Best to send nothing at all if
// config.NextProtos is empty. See
@@ -335,6 +353,12 @@ Curves:
hs.hello.srtpProtectionProfile = c.config.Bugs.SendSRTPProtectionProfile
}
+ if expected := c.config.Bugs.ExpectedCustomExtension; expected != nil {
+ if hs.clientHello.customExtension != *expected {
+ return false, fmt.Errorf("tls: bad custom extension contents %q", hs.clientHello.customExtension)
+ }
+ }
+
_, hs.ecdsaOk = hs.cert.PrivateKey.(*ecdsa.PrivateKey)
// For test purposes, check that the peer never offers a session when
@@ -343,6 +367,10 @@ Curves:
return false, errors.New("tls: offered resumption on renegotiation")
}
+ if c.config.Bugs.FailIfSessionOffered && (len(hs.clientHello.sessionTicket) > 0 || len(hs.clientHello.sessionId) > 0) {
+ return false, errors.New("tls: client offered a session ticket or ID")
+ }
+
if hs.checkForResumption() {
return true, nil
}
@@ -516,7 +544,9 @@ func (hs *serverHandshakeState) doFullHandshake() error {
if !isPSK {
certMsg := new(certificateMsg)
- certMsg.certificates = hs.cert.Certificate
+ if !config.Bugs.EmptyCertificateList {
+ certMsg.certificates = hs.cert.Certificate
+ }
if !config.Bugs.UnauthenticatedECDH {
certMsgBytes := certMsg.marshal()
if config.Bugs.WrongCertificateMessageType {
@@ -668,6 +698,7 @@ func (hs *serverHandshakeState) doFullHandshake() error {
if !isSupportedSignatureAndHash(signatureAndHash, config.signatureAndHashesForServer()) {
return errors.New("tls: unsupported hash function for client certificate")
}
+ c.clientCertSignatureHash = signatureAndHash.hash
} else {
// Before TLS 1.2 the signature algorithm was implicit
// from the key type, and only one hash per signature
@@ -848,10 +879,12 @@ func (hs *serverHandshakeState) sendSessionTicket() error {
m := new(newSessionTicketMsg)
- var err error
- m.ticket, err = c.encryptTicket(&state)
- if err != nil {
- return err
+ if !c.config.Bugs.SendEmptySessionTicket {
+ var err error
+ m.ticket, err = c.encryptTicket(&state)
+ if err != nil {
+ return err
+ }
}
hs.writeServerHash(m.marshal())
@@ -881,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 {
@@ -1029,3 +1066,14 @@ func (c *Conn) tryCipherSuite(id uint16, supportedCipherSuites []uint16, version
return nil
}
+
+func isTLS12Cipher(id uint16) bool {
+ for _, cipher := range cipherSuites {
+ if cipher.id != id {
+ continue
+ }
+ return cipher.flags&suiteTLS12 != 0
+ }
+ // Unknown cipher.
+ return false
+}
diff --git a/src/ssl/test/runner/key_agreement.go b/src/ssl/test/runner/key_agreement.go
index 2ee0087..4f399d9 100644
--- a/src/ssl/test/runner/key_agreement.go
+++ b/src/ssl/test/runner/key_agreement.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package main
+package runner
import (
"crypto"
@@ -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 bbcd388..a8da311 100644
--- a/src/ssl/test/runner/packet_adapter.go
+++ b/src/ssl/test/runner/packet_adapter.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package main
+package runner
import (
"encoding/binary"
@@ -28,13 +28,22 @@ const opcodeTimeoutAck = byte('t')
type packetAdaptor struct {
net.Conn
+ debug *recordingConn
}
// newPacketAdaptor wraps a reliable streaming net.Conn into a reliable
// packet-based net.Conn. The stream contains packets and control commands,
// distinguished by a one byte opcode.
func newPacketAdaptor(conn net.Conn) *packetAdaptor {
- return &packetAdaptor{conn}
+ return &packetAdaptor{conn, nil}
+}
+
+func (p *packetAdaptor) log(message string, data []byte) {
+ if p.debug == nil {
+ return
+ }
+
+ p.debug.LogSpecial(message, data)
}
func (p *packetAdaptor) readOpcode() (byte, error) {
@@ -87,6 +96,8 @@ 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)
+
payload := make([]byte, 1+8)
payload[0] = opcodeTimeout
binary.BigEndian.PutUint64(payload[1:], uint64(d.Nanoseconds()))
@@ -102,6 +113,7 @@ func (p *packetAdaptor) SendReadTimeout(d time.Duration) ([][]byte, error) {
}
switch opcode {
case opcodeTimeoutAck:
+ p.log("Received timeout ACK", nil)
// Done! Return the packets buffered and continue.
return packets, nil
case opcodePacket:
@@ -110,6 +122,7 @@ func (p *packetAdaptor) SendReadTimeout(d time.Duration) ([][]byte, error) {
if err != nil {
return nil, err
}
+ p.log("Simulating dropped packet", packet)
packets = append(packets, packet)
default:
return nil, fmt.Errorf("unexpected opcode '%d'", opcode)
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 51a1009..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 main
+// +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/prf.go b/src/ssl/test/runner/prf.go
index d445e76..8521aba 100644
--- a/src/ssl/test/runner/prf.go
+++ b/src/ssl/test/runner/prf.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package main
+package runner
import (
"crypto"
diff --git a/src/ssl/test/runner/recordingconn.go b/src/ssl/test/runner/recordingconn.go
index a67fa48..39deb19 100644
--- a/src/ssl/test/runner/recordingconn.go
+++ b/src/ssl/test/runner/recordingconn.go
@@ -1,4 +1,4 @@
-package main
+package runner
import (
"bufio"
@@ -12,33 +12,49 @@ import (
"sync"
)
+type flowType int
+
+const (
+ readFlow flowType = iota
+ writeFlow
+ specialFlow
+)
+
+type flow struct {
+ flowType flowType
+ message string
+ data []byte
+}
+
// recordingConn is a net.Conn that records the traffic that passes through it.
// WriteTo can be used to produce output that can be later be loaded with
// ParseTestData.
type recordingConn struct {
net.Conn
sync.Mutex
- flows [][]byte
- reading bool
+ flows []flow
+ isDatagram bool
+ local, peer string
}
-func (r *recordingConn) Read(b []byte) (n int, err error) {
- if n, err = r.Conn.Read(b); n == 0 {
- return
- }
- b = b[:n]
-
+func (r *recordingConn) appendFlow(flowType flowType, message string, data []byte) {
r.Lock()
defer r.Unlock()
- if l := len(r.flows); l == 0 || !r.reading {
- buf := make([]byte, len(b))
- copy(buf, b)
- r.flows = append(r.flows, buf)
+ if l := len(r.flows); flowType == specialFlow || r.isDatagram || l == 0 || r.flows[l-1].flowType != flowType {
+ buf := make([]byte, len(data))
+ copy(buf, data)
+ r.flows = append(r.flows, flow{flowType, message, buf})
} else {
- r.flows[l-1] = append(r.flows[l-1], b[:n]...)
+ r.flows[l-1].data = append(r.flows[l-1].data, data...)
}
- r.reading = true
+}
+
+func (r *recordingConn) Read(b []byte) (n int, err error) {
+ if n, err = r.Conn.Read(b); n == 0 {
+ return
+ }
+ r.appendFlow(readFlow, "", b[:n])
return
}
@@ -46,37 +62,33 @@ func (r *recordingConn) Write(b []byte) (n int, err error) {
if n, err = r.Conn.Write(b); n == 0 {
return
}
- b = b[:n]
-
- r.Lock()
- defer r.Unlock()
-
- if l := len(r.flows); l == 0 || r.reading {
- buf := make([]byte, len(b))
- copy(buf, b)
- r.flows = append(r.flows, buf)
- } else {
- r.flows[l-1] = append(r.flows[l-1], b[:n]...)
- }
- r.reading = false
+ r.appendFlow(writeFlow, "", b[:n])
return
}
+// LogSpecial appends an entry to the record of type 'special'.
+func (r *recordingConn) LogSpecial(message string, data []byte) {
+ r.appendFlow(specialFlow, message, data)
+}
+
// WriteTo writes hex dumps to w that contains the recorded traffic.
func (r *recordingConn) WriteTo(w io.Writer) {
- // TLS always starts with a client to server flow.
- clientToServer := true
-
+ fmt.Fprintf(w, ">>> runner is %s, shim is %s\n", r.local, r.peer)
for i, flow := range r.flows {
- source, dest := "client", "server"
- if !clientToServer {
- source, dest = dest, source
+ switch flow.flowType {
+ case readFlow:
+ fmt.Fprintf(w, ">>> Flow %d (%s to %s)\n", i+1, r.peer, r.local)
+ case writeFlow:
+ fmt.Fprintf(w, ">>> Flow %d (%s to %s)\n", i+1, r.local, r.peer)
+ case specialFlow:
+ fmt.Fprintf(w, ">>> Flow %d %q\n", i+1, flow.message)
+ }
+
+ if flow.data != nil {
+ dumper := hex.Dumper(w)
+ dumper.Write(flow.data)
+ dumper.Close()
}
- fmt.Fprintf(w, ">>> Flow %d (%s to %s)\n", i+1, source, dest)
- dumper := hex.Dumper(w)
- dumper.Write(flow)
- dumper.Close()
- clientToServer = !clientToServer
}
}
diff --git a/src/ssl/test/runner/runner.go b/src/ssl/test/runner/runner.go
index 94c1d32..45bb0b7 100644
--- a/src/ssl/test/runner/runner.go
+++ b/src/ssl/test/runner/runner.go
@@ -1,4 +1,4 @@
-package main
+package runner
import (
"bytes"
@@ -27,11 +27,16 @@ 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.")
jsonOutput = flag.String("json-output", "", "The file to output JSON results to.")
pipe = flag.Bool("pipe", false, "If true, print status output suitable for piping into another program.")
+ testToRun = flag.String("test", "", "The name of a test to run, or empty to run all tests")
+ numWorkers = flag.Int("num-workers", runtime.NumCPU(), "The number of workers to run in parallel.")
+ shimPath = flag.String("shim-path", "../../../build/ssl/test/bssl_shim", "The location of the shim binary.")
+ resourceDir = flag.String("resource-dir", ".", "The directory in which to find certificate and key files.")
)
const (
@@ -54,21 +59,21 @@ var testSCTList = []byte{5, 6, 7, 8}
func initCertificates() {
var err error
- rsaCertificate, err = LoadX509KeyPair(rsaCertificateFile, rsaKeyFile)
+ rsaCertificate, err = LoadX509KeyPair(path.Join(*resourceDir, rsaCertificateFile), path.Join(*resourceDir, rsaKeyFile))
if err != nil {
panic(err)
}
rsaCertificate.OCSPStaple = testOCSPResponse
rsaCertificate.SignedCertificateTimestampList = testSCTList
- ecdsaCertificate, err = LoadX509KeyPair(ecdsaCertificateFile, ecdsaKeyFile)
+ ecdsaCertificate, err = LoadX509KeyPair(path.Join(*resourceDir, ecdsaCertificateFile), path.Join(*resourceDir, ecdsaKeyFile))
if err != nil {
panic(err)
}
ecdsaCertificate.OCSPStaple = testOCSPResponse
ecdsaCertificate.SignedCertificateTimestampList = testSCTList
- channelIDPEMBlock, err := ioutil.ReadFile(channelIDKeyFile)
+ channelIDPEMBlock, err := ioutil.ReadFile(path.Join(*resourceDir, channelIDKeyFile))
if err != nil {
panic(err)
}
@@ -145,15 +150,30 @@ type testCase struct {
// expectedNextProto controls whether the connection should
// negotiate a next protocol via NPN or ALPN.
expectedNextProto string
+ // expectNoNextProto, if true, means that no next protocol should be
+ // negotiated.
+ expectNoNextProto bool
// expectedNextProtoType, if non-zero, is the expected next
// protocol negotiation mechanism.
expectedNextProtoType int
// expectedSRTPProtectionProfile is the DTLS-SRTP profile that
// should be negotiated. If zero, none should be negotiated.
expectedSRTPProtectionProfile uint16
+ // expectedOCSPResponse, if not nil, is the expected OCSP response to be received.
+ expectedOCSPResponse []uint8
+ // expectedSCTList, if not nil, is the expected SCT list to be received.
+ expectedSCTList []uint8
+ // expectedClientCertSignatureHash, if not zero, is the TLS id of the
+ // hash function that the client should have used when signing the
+ // handshake with a client certificate.
+ expectedClientCertSignatureHash uint8
// messageLen is the length, in bytes, of the test message that will be
// sent.
messageLen int
+ // messageCount is the number of test messages that will be sent.
+ messageCount int
+ // digestPrefs is the list of digest preferences from the client.
+ digestPrefs string
// certFile is the path to the certificate to use for the server.
certFile string
// keyFile is the path to the private key to use for the server.
@@ -174,15 +194,22 @@ type testCase struct {
// newSessionsOnResume, if true, will cause resumeConfig to
// use a different session resumption context.
newSessionsOnResume bool
+ // noSessionCache, if true, will cause the server to run without a
+ // session cache.
+ noSessionCache bool
// sendPrefix sends a prefix on the socket before actually performing a
// handshake.
sendPrefix string
// shimWritesFirst controls whether the shim sends an initial "hello"
// message before doing a roundtrip with the runner.
shimWritesFirst bool
- // renegotiate indicates the the connection should be renegotiated
- // during the exchange.
- renegotiate bool
+ // shimShutsDown, if true, runs a test where the shim shuts down the
+ // connection immediately after the handshake rather than echoing
+ // messages from the runner.
+ shimShutsDown bool
+ // renegotiate indicates the number of times the connection should be
+ // renegotiated during the exchange.
+ renegotiate int
// renegotiateCiphers is a list of ciphersuite ids that will be
// switched in just before renegotiation.
renegotiateCiphers []uint16
@@ -204,959 +231,52 @@ type testCase struct {
// testTLSUnique, if true, causes the shim to send the tls-unique value
// which will be compared against the expected value.
testTLSUnique bool
+ // sendEmptyRecords is the number of consecutive empty records to send
+ // before and after the test message.
+ sendEmptyRecords int
+ // sendWarningAlerts is the number of consecutive warning alerts to send
+ // before and after the test message.
+ sendWarningAlerts int
+ // expectMessageDropped, if true, means the test message is expected to
+ // be dropped by the client rather than echoed back.
+ expectMessageDropped bool
}
-var testCases = []testCase{
- {
- name: "BadRSASignature",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- Bugs: ProtocolBugs{
- InvalidSKXSignature: true,
- },
- },
- shouldFail: true,
- expectedError: ":BAD_SIGNATURE:",
- },
- {
- name: "BadECDSASignature",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
- Bugs: ProtocolBugs{
- InvalidSKXSignature: true,
- },
- Certificates: []Certificate{getECDSACertificate()},
- },
- shouldFail: true,
- expectedError: ":BAD_SIGNATURE:",
- },
- {
- name: "BadECDSACurve",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
- Bugs: ProtocolBugs{
- InvalidSKXCurve: true,
- },
- Certificates: []Certificate{getECDSACertificate()},
- },
- shouldFail: true,
- 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{
- FailIfNotFallbackSCSV: true,
- },
- },
- shouldFail: true,
- expectedLocalError: "no fallback SCSV found",
- },
- {
- name: "SendFallbackSCSV",
- config: Config{
- Bugs: ProtocolBugs{
- FailIfNotFallbackSCSV: true,
- },
- },
- flags: []string{"-fallback-scsv"},
- },
- {
- name: "ClientCertificateTypes",
- config: Config{
- ClientAuth: RequestClientCert,
- ClientCertificateTypes: []byte{
- CertTypeDSSSign,
- CertTypeRSASign,
- CertTypeECDSASign,
- },
- },
- flags: []string{
- "-expect-certificate-types",
- base64.StdEncoding.EncodeToString([]byte{
- CertTypeDSSSign,
- CertTypeRSASign,
- CertTypeECDSASign,
- }),
- },
- },
- {
- name: "NoClientCertificate",
- config: Config{
- ClientAuth: RequireAnyClientCert,
- },
- shouldFail: true,
- expectedLocalError: "client didn't provide a certificate",
- },
- {
- name: "UnauthenticatedECDH",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- Bugs: ProtocolBugs{
- UnauthenticatedECDH: true,
- },
- },
- shouldFail: true,
- expectedError: ":UNEXPECTED_MESSAGE:",
- },
- {
- name: "SkipCertificateStatus",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- Bugs: ProtocolBugs{
- SkipCertificateStatus: true,
- },
- },
- flags: []string{
- "-enable-ocsp-stapling",
- },
- },
- {
- name: "SkipServerKeyExchange",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- Bugs: ProtocolBugs{
- SkipServerKeyExchange: true,
- },
- },
- shouldFail: true,
- expectedError: ":UNEXPECTED_MESSAGE:",
- },
- {
- name: "SkipChangeCipherSpec-Client",
- config: Config{
- Bugs: ProtocolBugs{
- SkipChangeCipherSpec: true,
- },
- },
- shouldFail: true,
- expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
- },
- {
- testType: serverTest,
- name: "SkipChangeCipherSpec-Server",
- config: Config{
- Bugs: ProtocolBugs{
- SkipChangeCipherSpec: true,
- },
- },
- shouldFail: true,
- expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
- },
- {
- testType: serverTest,
- name: "SkipChangeCipherSpec-Server-NPN",
- config: Config{
- NextProtos: []string{"bar"},
- Bugs: ProtocolBugs{
- SkipChangeCipherSpec: true,
- },
- },
- flags: []string{
- "-advertise-npn", "\x03foo\x03bar\x03baz",
- },
- shouldFail: true,
- expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
- },
- {
- name: "FragmentAcrossChangeCipherSpec-Client",
- config: Config{
- Bugs: ProtocolBugs{
- FragmentAcrossChangeCipherSpec: true,
- },
- },
- shouldFail: true,
- expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
- },
- {
- testType: serverTest,
- name: "FragmentAcrossChangeCipherSpec-Server",
- config: Config{
- Bugs: ProtocolBugs{
- FragmentAcrossChangeCipherSpec: true,
- },
- },
- shouldFail: true,
- expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
- },
- {
- testType: serverTest,
- name: "FragmentAcrossChangeCipherSpec-Server-NPN",
- config: Config{
- NextProtos: []string{"bar"},
- Bugs: ProtocolBugs{
- FragmentAcrossChangeCipherSpec: true,
- },
- },
- flags: []string{
- "-advertise-npn", "\x03foo\x03bar\x03baz",
- },
- shouldFail: true,
- expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
- },
- {
- testType: serverTest,
- name: "Alert",
- config: Config{
- Bugs: ProtocolBugs{
- SendSpuriousAlert: alertRecordOverflow,
- },
- },
- shouldFail: true,
- expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
- },
- {
- protocol: dtls,
- testType: serverTest,
- name: "Alert-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- SendSpuriousAlert: alertRecordOverflow,
- },
- },
- shouldFail: true,
- expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
- },
- {
- testType: serverTest,
- name: "FragmentAlert",
- config: Config{
- Bugs: ProtocolBugs{
- FragmentAlert: true,
- SendSpuriousAlert: alertRecordOverflow,
- },
- },
- shouldFail: true,
- expectedError: ":BAD_ALERT:",
- },
- {
- protocol: dtls,
- testType: serverTest,
- name: "FragmentAlert-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- FragmentAlert: true,
- SendSpuriousAlert: alertRecordOverflow,
- },
- },
- shouldFail: true,
- expectedError: ":BAD_ALERT:",
- },
- {
- testType: serverTest,
- name: "EarlyChangeCipherSpec-server-1",
- config: Config{
- Bugs: ProtocolBugs{
- EarlyChangeCipherSpec: 1,
- },
- },
- shouldFail: true,
- expectedError: ":CCS_RECEIVED_EARLY:",
- },
- {
- testType: serverTest,
- name: "EarlyChangeCipherSpec-server-2",
- config: Config{
- Bugs: ProtocolBugs{
- EarlyChangeCipherSpec: 2,
- },
- },
- shouldFail: true,
- expectedError: ":CCS_RECEIVED_EARLY:",
- },
- {
- name: "SkipNewSessionTicket",
- config: Config{
- Bugs: ProtocolBugs{
- SkipNewSessionTicket: true,
- },
- },
- shouldFail: true,
- expectedError: ":CCS_RECEIVED_EARLY:",
- },
- {
- testType: serverTest,
- name: "FallbackSCSV",
- config: Config{
- MaxVersion: VersionTLS11,
- Bugs: ProtocolBugs{
- SendFallbackSCSV: true,
- },
- },
- shouldFail: true,
- expectedError: ":INAPPROPRIATE_FALLBACK:",
- },
- {
- testType: serverTest,
- name: "FallbackSCSV-VersionMatch",
- config: Config{
- Bugs: ProtocolBugs{
- SendFallbackSCSV: true,
- },
- },
- },
- {
- testType: serverTest,
- name: "FragmentedClientVersion",
- config: Config{
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: 1,
- FragmentClientVersion: true,
- },
- },
- expectedVersion: VersionTLS12,
- },
- {
- testType: serverTest,
- name: "MinorVersionTolerance",
- config: Config{
- Bugs: ProtocolBugs{
- SendClientVersion: 0x03ff,
- },
- },
- expectedVersion: VersionTLS12,
- },
- {
- testType: serverTest,
- name: "MajorVersionTolerance",
- config: Config{
- Bugs: ProtocolBugs{
- SendClientVersion: 0x0400,
- },
- },
- expectedVersion: VersionTLS12,
- },
- {
- testType: serverTest,
- name: "VersionTooLow",
- config: Config{
- Bugs: ProtocolBugs{
- SendClientVersion: 0x0200,
- },
- },
- shouldFail: true,
- expectedError: ":UNSUPPORTED_PROTOCOL:",
- },
- {
- testType: serverTest,
- name: "HttpGET",
- sendPrefix: "GET / HTTP/1.0\n",
- shouldFail: true,
- expectedError: ":HTTP_REQUEST:",
- },
- {
- testType: serverTest,
- name: "HttpPOST",
- sendPrefix: "POST / HTTP/1.0\n",
- shouldFail: true,
- expectedError: ":HTTP_REQUEST:",
- },
- {
- testType: serverTest,
- name: "HttpHEAD",
- sendPrefix: "HEAD / HTTP/1.0\n",
- shouldFail: true,
- expectedError: ":HTTP_REQUEST:",
- },
- {
- testType: serverTest,
- name: "HttpPUT",
- sendPrefix: "PUT / HTTP/1.0\n",
- shouldFail: true,
- expectedError: ":HTTP_REQUEST:",
- },
- {
- testType: serverTest,
- name: "HttpCONNECT",
- sendPrefix: "CONNECT www.google.com:443 HTTP/1.0\n",
- shouldFail: true,
- expectedError: ":HTTPS_PROXY_REQUEST:",
- },
- {
- testType: serverTest,
- name: "Garbage",
- sendPrefix: "blah",
- shouldFail: true,
- expectedError: ":UNKNOWN_PROTOCOL:",
- },
- {
- name: "SkipCipherVersionCheck",
- config: Config{
- CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
- MaxVersion: VersionTLS11,
- Bugs: ProtocolBugs{
- SkipCipherVersionCheck: true,
- },
- },
- shouldFail: true,
- expectedError: ":WRONG_CIPHER_RETURNED:",
- },
- {
- name: "RSAEphemeralKey",
- config: Config{
- CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
- Bugs: ProtocolBugs{
- RSAEphemeralKey: true,
- },
- },
- shouldFail: true,
- expectedError: ":UNEXPECTED_MESSAGE:",
- },
- {
- name: "DisableEverything",
- flags: []string{"-no-tls12", "-no-tls11", "-no-tls1", "-no-ssl3"},
- shouldFail: true,
- expectedError: ":WRONG_SSL_VERSION:",
- },
- {
- protocol: dtls,
- name: "DisableEverything-DTLS",
- flags: []string{"-no-tls12", "-no-tls1"},
- shouldFail: true,
- expectedError: ":WRONG_SSL_VERSION:",
- },
- {
- name: "NoSharedCipher",
- config: Config{
- CipherSuites: []uint16{},
- },
- shouldFail: true,
- expectedError: ":HANDSHAKE_FAILURE_ON_CLIENT_HELLO:",
- },
- {
- protocol: dtls,
- testType: serverTest,
- name: "MTU",
- config: Config{
- Bugs: ProtocolBugs{
- MaxPacketLength: 256,
- },
- },
- flags: []string{"-mtu", "256"},
- },
- {
- protocol: dtls,
- testType: serverTest,
- name: "MTUExceeded",
- config: Config{
- Bugs: ProtocolBugs{
- MaxPacketLength: 255,
- },
- },
- flags: []string{"-mtu", "256"},
- shouldFail: true,
- expectedLocalError: "dtls: exceeded maximum packet length",
- },
- {
- name: "CertMismatchRSA",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
- Certificates: []Certificate{getECDSACertificate()},
- Bugs: ProtocolBugs{
- SendCipherSuite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
- },
- },
- shouldFail: true,
- expectedError: ":WRONG_CERTIFICATE_TYPE:",
- },
- {
- name: "CertMismatchECDSA",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- Certificates: []Certificate{getRSACertificate()},
- Bugs: ProtocolBugs{
- SendCipherSuite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
- },
- },
- shouldFail: true,
- expectedError: ":WRONG_CERTIFICATE_TYPE:",
- },
- {
- name: "TLSFatalBadPackets",
- damageFirstWrite: true,
- shouldFail: true,
- expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
- },
- {
- protocol: dtls,
- name: "DTLSIgnoreBadPackets",
- damageFirstWrite: true,
- },
- {
- protocol: dtls,
- name: "DTLSIgnoreBadPackets-Async",
- damageFirstWrite: true,
- flags: []string{"-async"},
- },
- {
- name: "AppDataAfterChangeCipherSpec",
- config: Config{
- Bugs: ProtocolBugs{
- AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"),
- },
- },
- shouldFail: true,
- expectedError: ":DATA_BETWEEN_CCS_AND_FINISHED:",
- },
- {
- protocol: dtls,
- name: "AppDataAfterChangeCipherSpec-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"),
- },
- },
- // BoringSSL's DTLS implementation will drop the out-of-order
- // application data.
- },
- {
- name: "AlertAfterChangeCipherSpec",
- config: Config{
- Bugs: ProtocolBugs{
- AlertAfterChangeCipherSpec: alertRecordOverflow,
- },
- },
- shouldFail: true,
- expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
- },
- {
- protocol: dtls,
- name: "AlertAfterChangeCipherSpec-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- AlertAfterChangeCipherSpec: alertRecordOverflow,
- },
- },
- shouldFail: true,
- expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
- },
- {
- protocol: dtls,
- name: "ReorderHandshakeFragments-Small-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- ReorderHandshakeFragments: true,
- // Small enough that every handshake message is
- // fragmented.
- MaxHandshakeRecordLength: 2,
- },
- },
- },
- {
- protocol: dtls,
- name: "ReorderHandshakeFragments-Large-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- ReorderHandshakeFragments: true,
- // Large enough that no handshake message is
- // fragmented.
- MaxHandshakeRecordLength: 2048,
- },
- },
- },
- {
- protocol: dtls,
- name: "MixCompleteMessageWithFragments-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- ReorderHandshakeFragments: true,
- MixCompleteMessageWithFragments: true,
- MaxHandshakeRecordLength: 2,
- },
- },
- },
- {
- name: "SendInvalidRecordType",
- config: Config{
- Bugs: ProtocolBugs{
- SendInvalidRecordType: true,
- },
- },
- shouldFail: true,
- expectedError: ":UNEXPECTED_RECORD:",
- },
- {
- protocol: dtls,
- name: "SendInvalidRecordType-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- SendInvalidRecordType: true,
- },
- },
- shouldFail: true,
- expectedError: ":UNEXPECTED_RECORD:",
- },
- {
- name: "FalseStart-SkipServerSecondLeg",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- NextProtos: []string{"foo"},
- Bugs: ProtocolBugs{
- SkipNewSessionTicket: true,
- SkipChangeCipherSpec: true,
- SkipFinished: true,
- ExpectFalseStart: true,
- },
- },
- flags: []string{
- "-false-start",
- "-handshake-never-done",
- "-advertise-alpn", "\x03foo",
- },
- shimWritesFirst: true,
- shouldFail: true,
- expectedError: ":UNEXPECTED_RECORD:",
- },
- {
- name: "FalseStart-SkipServerSecondLeg-Implicit",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- NextProtos: []string{"foo"},
- Bugs: ProtocolBugs{
- SkipNewSessionTicket: true,
- SkipChangeCipherSpec: true,
- SkipFinished: true,
- },
- },
- flags: []string{
- "-implicit-handshake",
- "-false-start",
- "-handshake-never-done",
- "-advertise-alpn", "\x03foo",
- },
- shouldFail: true,
- expectedError: ":UNEXPECTED_RECORD:",
- },
- {
- testType: serverTest,
- name: "FailEarlyCallback",
- flags: []string{"-fail-early-callback"},
- shouldFail: true,
- expectedError: ":CONNECTION_REJECTED:",
- expectedLocalError: "remote error: access denied",
- },
- {
- name: "WrongMessageType",
- config: Config{
- Bugs: ProtocolBugs{
- WrongCertificateMessageType: true,
- },
- },
- shouldFail: true,
- expectedError: ":UNEXPECTED_MESSAGE:",
- expectedLocalError: "remote error: unexpected message",
- },
- {
- protocol: dtls,
- name: "WrongMessageType-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- WrongCertificateMessageType: true,
- },
- },
- shouldFail: true,
- expectedError: ":UNEXPECTED_MESSAGE:",
- expectedLocalError: "remote error: unexpected message",
- },
- {
- protocol: dtls,
- name: "FragmentMessageTypeMismatch-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: 2,
- FragmentMessageTypeMismatch: true,
- },
- },
- shouldFail: true,
- expectedError: ":FRAGMENT_MISMATCH:",
- },
- {
- protocol: dtls,
- name: "FragmentMessageLengthMismatch-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: 2,
- FragmentMessageLengthMismatch: true,
- },
- },
- shouldFail: true,
- expectedError: ":FRAGMENT_MISMATCH:",
- },
- {
- protocol: dtls,
- name: "SplitFragmentHeader-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- SplitFragmentHeader: true,
- },
- },
- shouldFail: true,
- expectedError: ":UNEXPECTED_MESSAGE:",
- },
- {
- protocol: dtls,
- name: "SplitFragmentBody-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- SplitFragmentBody: true,
- },
- },
- shouldFail: true,
- expectedError: ":UNEXPECTED_MESSAGE:",
- },
- {
- protocol: dtls,
- name: "SendEmptyFragments-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- SendEmptyFragments: true,
- },
- },
- },
- {
- name: "UnsupportedCipherSuite",
- config: Config{
- CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
- Bugs: ProtocolBugs{
- IgnorePeerCipherPreferences: true,
- },
- },
- flags: []string{"-cipher", "DEFAULT:!RC4"},
- shouldFail: true,
- expectedError: ":WRONG_CIPHER_RETURNED:",
- },
- {
- 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},
- Bugs: ProtocolBugs{
- IgnorePeerCurvePreferences: true,
- },
- },
- shouldFail: true,
- expectedError: ":WRONG_CURVE:",
- },
- {
- name: "SendWarningAlerts",
- config: Config{
- Bugs: ProtocolBugs{
- SendWarningAlerts: alertAccessDenied,
- },
- },
- },
- {
- protocol: dtls,
- name: "SendWarningAlerts-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- SendWarningAlerts: alertAccessDenied,
- },
- },
- },
- {
- name: "BadFinished",
- config: Config{
- Bugs: ProtocolBugs{
- BadFinished: true,
- },
- },
- shouldFail: true,
- expectedError: ":DIGEST_CHECK_FAILED:",
- },
- {
- name: "FalseStart-BadFinished",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- NextProtos: []string{"foo"},
- Bugs: ProtocolBugs{
- BadFinished: true,
- ExpectFalseStart: true,
- },
- },
- flags: []string{
- "-false-start",
- "-handshake-never-done",
- "-advertise-alpn", "\x03foo",
- },
- shimWritesFirst: true,
- shouldFail: true,
- expectedError: ":DIGEST_CHECK_FAILED:",
- },
- {
- name: "NoFalseStart-NoALPN",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- Bugs: ProtocolBugs{
- ExpectFalseStart: true,
- AlertBeforeFalseStartTest: alertAccessDenied,
- },
- },
- flags: []string{
- "-false-start",
- },
- shimWritesFirst: true,
- shouldFail: true,
- expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
- expectedLocalError: "tls: peer did not false start: EOF",
- },
- {
- name: "NoFalseStart-NoAEAD",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
- NextProtos: []string{"foo"},
- Bugs: ProtocolBugs{
- ExpectFalseStart: true,
- AlertBeforeFalseStartTest: alertAccessDenied,
- },
- },
- flags: []string{
- "-false-start",
- "-advertise-alpn", "\x03foo",
- },
- shimWritesFirst: true,
- shouldFail: true,
- expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
- expectedLocalError: "tls: peer did not false start: EOF",
- },
- {
- name: "NoFalseStart-RSA",
- config: Config{
- CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
- NextProtos: []string{"foo"},
- Bugs: ProtocolBugs{
- ExpectFalseStart: true,
- AlertBeforeFalseStartTest: alertAccessDenied,
- },
- },
- flags: []string{
- "-false-start",
- "-advertise-alpn", "\x03foo",
- },
- shimWritesFirst: true,
- shouldFail: true,
- expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
- expectedLocalError: "tls: peer did not false start: EOF",
- },
- {
- name: "NoFalseStart-DHE_RSA",
- config: Config{
- CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
- NextProtos: []string{"foo"},
- Bugs: ProtocolBugs{
- ExpectFalseStart: true,
- AlertBeforeFalseStartTest: alertAccessDenied,
- },
- },
- flags: []string{
- "-false-start",
- "-advertise-alpn", "\x03foo",
- },
- shimWritesFirst: true,
- shouldFail: true,
- expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
- expectedLocalError: "tls: peer did not false start: EOF",
- },
- {
- testType: serverTest,
- name: "NoSupportedCurves",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- Bugs: ProtocolBugs{
- NoSupportedCurves: true,
- },
- },
- },
- {
- testType: serverTest,
- name: "NoCommonCurves",
- config: Config{
- CipherSuites: []uint16{
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
- TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
- },
- CurvePreferences: []CurveID{CurveP224},
- },
- expectedCipher: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
- },
- {
- protocol: dtls,
- name: "SendSplitAlert-Sync",
- config: Config{
- Bugs: ProtocolBugs{
- SendSplitAlert: true,
- },
- },
- },
- {
- protocol: dtls,
- name: "SendSplitAlert-Async",
- config: Config{
- Bugs: ProtocolBugs{
- SendSplitAlert: true,
- },
- },
- flags: []string{"-async"},
- },
- {
- protocol: dtls,
- name: "PackDTLSHandshake",
- config: Config{
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: 2,
- PackHandshakeFragments: 20,
- PackHandshakeRecords: 200,
- },
- },
- },
- {
- testType: serverTest,
- protocol: dtls,
- name: "NoRC4-DTLS",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_RC4_128_SHA},
- Bugs: ProtocolBugs{
- EnableAllCiphersInDTLS: true,
- },
- },
- shouldFail: true,
- expectedError: ":NO_SHARED_CIPHER:",
- },
-}
+var testCases []testCase
-func doExchange(test *testCase, config *Config, conn net.Conn, messageLen int, isResume bool) error {
- var connDebug *recordingConn
+func doExchange(test *testCase, config *Config, conn net.Conn, isResume bool) error {
var connDamage *damageAdaptor
+
+ if test.protocol == dtls {
+ config.Bugs.PacketAdaptor = newPacketAdaptor(conn)
+ conn = config.Bugs.PacketAdaptor
+ }
+
if *flagDebug {
- connDebug = &recordingConn{Conn: conn}
+ local, peer := "client", "server"
+ if test.testType == clientTest {
+ local, peer = peer, local
+ }
+ connDebug := &recordingConn{
+ Conn: conn,
+ isDatagram: test.protocol == dtls,
+ local: local,
+ peer: peer,
+ }
conn = connDebug
defer func() {
connDebug.WriteTo(os.Stdout)
}()
- }
- if test.protocol == dtls {
- config.Bugs.PacketAdaptor = newPacketAdaptor(conn)
- conn = config.Bugs.PacketAdaptor
- if test.replayWrites {
- conn = newReplayAdaptor(conn)
+ if config.Bugs.PacketAdaptor != nil {
+ config.Bugs.PacketAdaptor.debug = connDebug
}
}
+ if test.replayWrites {
+ conn = newReplayAdaptor(conn)
+ }
+
if test.damageFirstWrite {
connDamage = newDamageAdaptor(conn)
conn = connDamage
@@ -1183,6 +303,7 @@ func doExchange(test *testCase, config *Config, conn net.Conn, messageLen int, i
tlsConn = Client(conn, config)
}
}
+ defer tlsConn.Close()
if err := tlsConn.Handshake(); err != nil {
return err
@@ -1225,6 +346,12 @@ func doExchange(test *testCase, config *Config, conn net.Conn, messageLen int, i
}
}
+ if test.expectNoNextProto {
+ if actual := connState.NegotiatedProtocol; actual != "" {
+ return fmt.Errorf("got unexpected next proto %s", actual)
+ }
+ }
+
if test.expectedNextProtoType != 0 {
if (test.expectedNextProtoType == alpn) != connState.NegotiatedProtocolFromALPN {
return fmt.Errorf("next proto type mismatch")
@@ -1235,6 +362,18 @@ func doExchange(test *testCase, config *Config, conn net.Conn, messageLen int, i
return fmt.Errorf("SRTP profile mismatch: got %d, wanted %d", p, test.expectedSRTPProtectionProfile)
}
+ if test.expectedOCSPResponse != nil && !bytes.Equal(test.expectedOCSPResponse, tlsConn.OCSPResponse()) {
+ return fmt.Errorf("OCSP Response mismatch")
+ }
+
+ if test.expectedSCTList != nil && !bytes.Equal(test.expectedSCTList, connState.SCTList) {
+ return fmt.Errorf("SCT list mismatch")
+ }
+
+ if expected := test.expectedClientCertSignatureHash; expected != 0 && expected != connState.ClientCertSignatureHash {
+ return fmt.Errorf("expected client to sign handshake with hash %d, but got %d", expected, connState.ClientCertSignatureHash)
+ }
+
if test.exportKeyingMaterial > 0 {
actual := make([]byte, test.exportKeyingMaterial)
if _, err := io.ReadFull(tlsConn, actual); err != nil {
@@ -1271,12 +410,22 @@ func doExchange(test *testCase, config *Config, conn net.Conn, messageLen int, i
}
}
- if test.renegotiate {
+ for i := 0; i < test.sendEmptyRecords; i++ {
+ tlsConn.Write(nil)
+ }
+
+ for i := 0; i < test.sendWarningAlerts; i++ {
+ tlsConn.SendAlert(alertLevelWarning, alertUnexpectedMessage)
+ }
+
+ if test.renegotiate > 0 {
if test.renegotiateCiphers != nil {
config.CipherSuites = test.renegotiateCiphers
}
- if err := tlsConn.Renegotiate(); err != nil {
- return err
+ for i := 0; i < test.renegotiate; i++ {
+ if err := tlsConn.Renegotiate(); err != nil {
+ return err
+ }
}
} else if test.renegotiateCiphers != nil {
panic("renegotiateCiphers without renegotiate")
@@ -1288,6 +437,7 @@ func doExchange(test *testCase, config *Config, conn net.Conn, messageLen int, i
connDamage.setDamage(false)
}
+ messageLen := test.messageLen
if messageLen < 0 {
if test.protocol == dtls {
return fmt.Errorf("messageLen < 0 not supported for DTLS tests")
@@ -1296,37 +446,57 @@ func doExchange(test *testCase, config *Config, conn net.Conn, messageLen int, i
_, err := io.Copy(ioutil.Discard, tlsConn)
return err
}
-
if messageLen == 0 {
messageLen = 32
}
- testMessage := make([]byte, messageLen)
- for i := range testMessage {
- testMessage[i] = 0x42
+
+ messageCount := test.messageCount
+ if messageCount == 0 {
+ messageCount = 1
}
- tlsConn.Write(testMessage)
- buf := make([]byte, len(testMessage))
- if test.protocol == dtls {
- bufTmp := make([]byte, len(buf)+1)
- n, err := tlsConn.Read(bufTmp)
- if err != nil {
- return err
+ for j := 0; j < messageCount; j++ {
+ testMessage := make([]byte, messageLen)
+ for i := range testMessage {
+ testMessage[i] = 0x42 ^ byte(j)
}
- if n != len(buf) {
- return fmt.Errorf("bad reply; length mismatch (%d vs %d)", n, len(buf))
+ tlsConn.Write(testMessage)
+
+ for i := 0; i < test.sendEmptyRecords; i++ {
+ tlsConn.Write(nil)
}
- copy(buf, bufTmp)
- } else {
- _, err := io.ReadFull(tlsConn, buf)
- if err != nil {
- return err
+
+ for i := 0; i < test.sendWarningAlerts; i++ {
+ tlsConn.SendAlert(alertLevelWarning, alertUnexpectedMessage)
+ }
+
+ if test.shimShutsDown || test.expectMessageDropped {
+ // The shim will not respond.
+ continue
+ }
+
+ buf := make([]byte, len(testMessage))
+ if test.protocol == dtls {
+ bufTmp := make([]byte, len(buf)+1)
+ n, err := tlsConn.Read(bufTmp)
+ if err != nil {
+ return err
+ }
+ if n != len(buf) {
+ return fmt.Errorf("bad reply; length mismatch (%d vs %d)", n, len(buf))
+ }
+ copy(buf, bufTmp)
+ } else {
+ _, err := io.ReadFull(tlsConn, buf)
+ if err != nil {
+ return err
+ }
}
- }
- for i, v := range buf {
- if v != testMessage[i]^0xff {
- return fmt.Errorf("bad reply contents at byte %d", i)
+ for i, v := range buf {
+ if v != testMessage[i]^0xff {
+ return fmt.Errorf("bad reply contents at byte %d", i)
+ }
}
}
@@ -1352,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 {
@@ -1382,7 +560,7 @@ func acceptOrWait(listener net.Listener, waitChan chan error) (net.Conn, error)
}
}
-func runTest(test *testCase, buildDir string, mallocNumToFail int64) error {
+func runTest(test *testCase, shimPath string, mallocNumToFail int64) error {
if !test.shouldFail && (len(test.expectedError) > 0 || len(test.expectedLocalError) > 0) {
panic("Error expected without shouldFail in " + test.name)
}
@@ -1391,6 +569,10 @@ func runTest(test *testCase, buildDir string, mallocNumToFail int64) error {
panic("expectResumeRejected without resumeSession in " + test.name)
}
+ if test.testType != clientTest && test.expectedClientCertSignatureHash != 0 {
+ panic("expectedClientCertSignatureHash non-zero with serverTest in " + test.name)
+ }
+
listener, err := net.ListenTCP("tcp4", &net.TCPAddr{IP: net.IP{127, 0, 0, 1}})
if err != nil {
panic(err)
@@ -1401,26 +583,30 @@ func runTest(test *testCase, buildDir string, mallocNumToFail int64) error {
}
}()
- shim_path := path.Join(buildDir, "ssl/test/bssl_shim")
flags := []string{"-port", strconv.Itoa(listener.Addr().(*net.TCPAddr).Port)}
if test.testType == serverTest {
flags = append(flags, "-server")
flags = append(flags, "-key-file")
if test.keyFile == "" {
- flags = append(flags, rsaKeyFile)
+ flags = append(flags, path.Join(*resourceDir, rsaKeyFile))
} else {
- flags = append(flags, test.keyFile)
+ flags = append(flags, path.Join(*resourceDir, test.keyFile))
}
flags = append(flags, "-cert-file")
if test.certFile == "" {
- flags = append(flags, rsaCertificateFile)
+ flags = append(flags, path.Join(*resourceDir, rsaCertificateFile))
} else {
- flags = append(flags, test.certFile)
+ flags = append(flags, path.Join(*resourceDir, test.certFile))
}
}
+ if test.digestPrefs != "" {
+ flags = append(flags, "-digest-prefs")
+ flags = append(flags, test.digestPrefs)
+ }
+
if test.protocol == dtls {
flags = append(flags, "-dtls")
}
@@ -1433,6 +619,10 @@ func runTest(test *testCase, buildDir string, mallocNumToFail int64) error {
flags = append(flags, "-shim-writes-first")
}
+ if test.shimShutsDown {
+ flags = append(flags, "-shim-shuts-down")
+ }
+
if test.exportKeyingMaterial > 0 {
flags = append(flags, "-export-keying-material", strconv.Itoa(test.exportKeyingMaterial))
flags = append(flags, "-export-label", test.exportLabel)
@@ -1453,11 +643,13 @@ func runTest(test *testCase, buildDir string, mallocNumToFail int64) error {
var shim *exec.Cmd
if *useValgrind {
- shim = valgrindOf(false, shim_path, flags...)
+ shim = valgrindOf(false, shimPath, flags...)
} else if *useGDB {
- shim = gdbOf(shim_path, flags...)
+ shim = gdbOf(shimPath, flags...)
+ } else if *useLLDB {
+ shim = lldbOf(shimPath, flags...)
} else {
- shim = exec.Command(shim_path, flags...)
+ shim = exec.Command(shimPath, flags...)
}
shim.Stdin = os.Stdin
var stdoutBuf, stderrBuf bytes.Buffer
@@ -1467,7 +659,7 @@ func runTest(test *testCase, buildDir string, mallocNumToFail int64) error {
shim.Env = os.Environ()
shim.Env = append(shim.Env, "MALLOC_NUMBER_TO_FAIL="+strconv.FormatInt(mallocNumToFail, 10))
if *mallocTestDebug {
- shim.Env = append(shim.Env, "MALLOC_ABORT_ON_FAIL=1")
+ shim.Env = append(shim.Env, "MALLOC_BREAK_ON_FAIL=1")
}
shim.Env = append(shim.Env, "_MALLOC_CHECK=1")
}
@@ -1479,8 +671,10 @@ func runTest(test *testCase, buildDir string, mallocNumToFail int64) error {
go func() { waitChan <- shim.Wait() }()
config := test.config
- config.ClientSessionCache = NewLRUClientSessionCache(1)
- config.ServerSessionCache = NewLRUServerSessionCache(1)
+ if !test.noSessionCache {
+ config.ClientSessionCache = NewLRUClientSessionCache(1)
+ config.ServerSessionCache = NewLRUServerSessionCache(1)
+ }
if test.testType == clientTest {
if len(config.Certificates) == 0 {
config.Certificates = []Certificate{getRSACertificate()}
@@ -1495,7 +689,7 @@ func runTest(test *testCase, buildDir string, mallocNumToFail int64) error {
conn, err := acceptOrWait(listener, waitChan)
if err == nil {
- err = doExchange(test, &config, conn, test.messageLen, false /* not a resumption */)
+ err = doExchange(test, &config, conn, false /* not a resumption */)
conn.Close()
}
@@ -1509,7 +703,12 @@ func runTest(test *testCase, buildDir string, mallocNumToFail int64) error {
if len(resumeConfig.Certificates) == 0 {
resumeConfig.Certificates = []Certificate{getRSACertificate()}
}
- if !test.newSessionsOnResume {
+ if test.newSessionsOnResume {
+ if !test.noSessionCache {
+ resumeConfig.ClientSessionCache = NewLRUClientSessionCache(1)
+ resumeConfig.ServerSessionCache = NewLRUServerSessionCache(1)
+ }
+ } else {
resumeConfig.SessionTicketKey = config.SessionTicketKey
resumeConfig.ClientSessionCache = config.ClientSessionCache
resumeConfig.ServerSessionCache = config.ServerSessionCache
@@ -1520,7 +719,7 @@ func runTest(test *testCase, buildDir string, mallocNumToFail int64) error {
var connResume net.Conn
connResume, err = acceptOrWait(listener, waitChan)
if err == nil {
- err = doExchange(test, &resumeConfig, connResume, test.messageLen, true /* resumption */)
+ err = doExchange(test, &resumeConfig, connResume, true /* resumption */)
connResume.Close()
}
}
@@ -1606,7 +805,6 @@ var testCipherSuites = []struct {
{"DHE-RSA-AES256-GCM", TLS_DHE_RSA_WITH_AES_256_GCM_SHA384},
{"DHE-RSA-AES256-SHA", TLS_DHE_RSA_WITH_AES_256_CBC_SHA},
{"DHE-RSA-AES256-SHA256", TLS_DHE_RSA_WITH_AES_256_CBC_SHA256},
- {"DHE-RSA-CHACHA20-POLY1305", TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
{"ECDHE-ECDSA-AES128-GCM", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
{"ECDHE-ECDSA-AES128-SHA", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA},
{"ECDHE-ECDSA-AES128-SHA256", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256},
@@ -1614,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},
@@ -1622,20 +821,29 @@ 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},
+ {"NULL-SHA", TLS_RSA_WITH_NULL_SHA},
}
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") ||
@@ -1644,7 +852,7 @@ func isTLS12Only(suiteName string) bool {
}
func isDTLSCipher(suiteName string) bool {
- return !hasComponent(suiteName, "RC4")
+ return !hasComponent(suiteName, "RC4") && !hasComponent(suiteName, "NULL")
}
func bigFromHex(hex string) *big.Int {
@@ -1655,6 +863,1235 @@ func bigFromHex(hex string) *big.Int {
return ret
}
+func addBasicTests() {
+ basicTests := []testCase{
+ {
+ name: "BadRSASignature",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ Bugs: ProtocolBugs{
+ InvalidSKXSignature: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":BAD_SIGNATURE:",
+ },
+ {
+ name: "BadECDSASignature",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+ Bugs: ProtocolBugs{
+ InvalidSKXSignature: true,
+ },
+ Certificates: []Certificate{getECDSACertificate()},
+ },
+ shouldFail: true,
+ expectedError: ":BAD_SIGNATURE:",
+ },
+ {
+ testType: serverTest,
+ name: "BadRSASignature-ClientAuth",
+ config: Config{
+ Bugs: ProtocolBugs{
+ InvalidCertVerifySignature: true,
+ },
+ Certificates: []Certificate{getRSACertificate()},
+ },
+ shouldFail: true,
+ expectedError: ":BAD_SIGNATURE:",
+ flags: []string{"-require-any-client-certificate"},
+ },
+ {
+ testType: serverTest,
+ name: "BadECDSASignature-ClientAuth",
+ config: Config{
+ Bugs: ProtocolBugs{
+ InvalidCertVerifySignature: true,
+ },
+ Certificates: []Certificate{getECDSACertificate()},
+ },
+ shouldFail: true,
+ expectedError: ":BAD_SIGNATURE:",
+ flags: []string{"-require-any-client-certificate"},
+ },
+ {
+ name: "BadECDSACurve",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+ Bugs: ProtocolBugs{
+ InvalidSKXCurve: true,
+ },
+ Certificates: []Certificate{getECDSACertificate()},
+ },
+ shouldFail: true,
+ expectedError: ":WRONG_CURVE:",
+ },
+ {
+ name: "NoFallbackSCSV",
+ config: Config{
+ Bugs: ProtocolBugs{
+ FailIfNotFallbackSCSV: true,
+ },
+ },
+ shouldFail: true,
+ expectedLocalError: "no fallback SCSV found",
+ },
+ {
+ name: "SendFallbackSCSV",
+ config: Config{
+ Bugs: ProtocolBugs{
+ FailIfNotFallbackSCSV: true,
+ },
+ },
+ flags: []string{"-fallback-scsv"},
+ },
+ {
+ name: "ClientCertificateTypes",
+ config: Config{
+ ClientAuth: RequestClientCert,
+ ClientCertificateTypes: []byte{
+ CertTypeDSSSign,
+ CertTypeRSASign,
+ CertTypeECDSASign,
+ },
+ },
+ flags: []string{
+ "-expect-certificate-types",
+ base64.StdEncoding.EncodeToString([]byte{
+ CertTypeDSSSign,
+ CertTypeRSASign,
+ CertTypeECDSASign,
+ }),
+ },
+ },
+ {
+ name: "NoClientCertificate",
+ config: Config{
+ ClientAuth: RequireAnyClientCert,
+ },
+ shouldFail: true,
+ expectedLocalError: "client didn't provide a certificate",
+ },
+ {
+ name: "UnauthenticatedECDH",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ Bugs: ProtocolBugs{
+ UnauthenticatedECDH: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_MESSAGE:",
+ },
+ {
+ name: "SkipCertificateStatus",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ Bugs: ProtocolBugs{
+ SkipCertificateStatus: true,
+ },
+ },
+ flags: []string{
+ "-enable-ocsp-stapling",
+ },
+ },
+ {
+ name: "SkipServerKeyExchange",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ Bugs: ProtocolBugs{
+ SkipServerKeyExchange: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_MESSAGE:",
+ },
+ {
+ name: "SkipChangeCipherSpec-Client",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SkipChangeCipherSpec: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ testType: serverTest,
+ name: "SkipChangeCipherSpec-Server",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SkipChangeCipherSpec: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ testType: serverTest,
+ name: "SkipChangeCipherSpec-Server-NPN",
+ config: Config{
+ NextProtos: []string{"bar"},
+ Bugs: ProtocolBugs{
+ SkipChangeCipherSpec: true,
+ },
+ },
+ flags: []string{
+ "-advertise-npn", "\x03foo\x03bar\x03baz",
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ name: "FragmentAcrossChangeCipherSpec-Client",
+ config: Config{
+ Bugs: ProtocolBugs{
+ FragmentAcrossChangeCipherSpec: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ testType: serverTest,
+ name: "FragmentAcrossChangeCipherSpec-Server",
+ config: Config{
+ Bugs: ProtocolBugs{
+ FragmentAcrossChangeCipherSpec: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ testType: serverTest,
+ name: "FragmentAcrossChangeCipherSpec-Server-NPN",
+ config: Config{
+ NextProtos: []string{"bar"},
+ Bugs: ProtocolBugs{
+ FragmentAcrossChangeCipherSpec: true,
+ },
+ },
+ flags: []string{
+ "-advertise-npn", "\x03foo\x03bar\x03baz",
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ testType: serverTest,
+ name: "Alert",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendSpuriousAlert: alertRecordOverflow,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
+ },
+ {
+ protocol: dtls,
+ testType: serverTest,
+ name: "Alert-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendSpuriousAlert: alertRecordOverflow,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
+ },
+ {
+ testType: serverTest,
+ name: "FragmentAlert",
+ config: Config{
+ Bugs: ProtocolBugs{
+ FragmentAlert: true,
+ SendSpuriousAlert: alertRecordOverflow,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":BAD_ALERT:",
+ },
+ {
+ protocol: dtls,
+ testType: serverTest,
+ name: "FragmentAlert-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ FragmentAlert: true,
+ SendSpuriousAlert: alertRecordOverflow,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":BAD_ALERT:",
+ },
+ {
+ testType: serverTest,
+ name: "EarlyChangeCipherSpec-server-1",
+ config: Config{
+ Bugs: ProtocolBugs{
+ EarlyChangeCipherSpec: 1,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ testType: serverTest,
+ name: "EarlyChangeCipherSpec-server-2",
+ config: Config{
+ Bugs: ProtocolBugs{
+ EarlyChangeCipherSpec: 2,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ name: "SkipNewSessionTicket",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SkipNewSessionTicket: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ testType: serverTest,
+ name: "FallbackSCSV",
+ config: Config{
+ MaxVersion: VersionTLS11,
+ Bugs: ProtocolBugs{
+ SendFallbackSCSV: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":INAPPROPRIATE_FALLBACK:",
+ },
+ {
+ testType: serverTest,
+ name: "FallbackSCSV-VersionMatch",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendFallbackSCSV: true,
+ },
+ },
+ },
+ {
+ testType: serverTest,
+ name: "FragmentedClientVersion",
+ config: Config{
+ Bugs: ProtocolBugs{
+ MaxHandshakeRecordLength: 1,
+ FragmentClientVersion: true,
+ },
+ },
+ expectedVersion: VersionTLS12,
+ },
+ {
+ testType: serverTest,
+ name: "MinorVersionTolerance",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendClientVersion: 0x03ff,
+ },
+ },
+ expectedVersion: VersionTLS12,
+ },
+ {
+ testType: serverTest,
+ name: "MajorVersionTolerance",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendClientVersion: 0x0400,
+ },
+ },
+ expectedVersion: VersionTLS12,
+ },
+ {
+ testType: serverTest,
+ name: "VersionTooLow",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendClientVersion: 0x0200,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNSUPPORTED_PROTOCOL:",
+ },
+ {
+ testType: serverTest,
+ name: "HttpGET",
+ sendPrefix: "GET / HTTP/1.0\n",
+ shouldFail: true,
+ expectedError: ":HTTP_REQUEST:",
+ },
+ {
+ testType: serverTest,
+ name: "HttpPOST",
+ sendPrefix: "POST / HTTP/1.0\n",
+ shouldFail: true,
+ expectedError: ":HTTP_REQUEST:",
+ },
+ {
+ testType: serverTest,
+ name: "HttpHEAD",
+ sendPrefix: "HEAD / HTTP/1.0\n",
+ shouldFail: true,
+ expectedError: ":HTTP_REQUEST:",
+ },
+ {
+ testType: serverTest,
+ name: "HttpPUT",
+ sendPrefix: "PUT / HTTP/1.0\n",
+ shouldFail: true,
+ expectedError: ":HTTP_REQUEST:",
+ },
+ {
+ testType: serverTest,
+ name: "HttpCONNECT",
+ sendPrefix: "CONNECT www.google.com:443 HTTP/1.0\n",
+ shouldFail: true,
+ expectedError: ":HTTPS_PROXY_REQUEST:",
+ },
+ {
+ testType: serverTest,
+ name: "Garbage",
+ sendPrefix: "blah",
+ shouldFail: true,
+ expectedError: ":WRONG_VERSION_NUMBER:",
+ },
+ {
+ name: "SkipCipherVersionCheck",
+ config: Config{
+ CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
+ MaxVersion: VersionTLS11,
+ Bugs: ProtocolBugs{
+ SkipCipherVersionCheck: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":WRONG_CIPHER_RETURNED:",
+ },
+ {
+ name: "RSAEphemeralKey",
+ config: Config{
+ CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
+ Bugs: ProtocolBugs{
+ RSAEphemeralKey: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_MESSAGE:",
+ },
+ {
+ name: "DisableEverything",
+ flags: []string{"-no-tls12", "-no-tls11", "-no-tls1", "-no-ssl3"},
+ shouldFail: true,
+ expectedError: ":WRONG_SSL_VERSION:",
+ },
+ {
+ protocol: dtls,
+ name: "DisableEverything-DTLS",
+ flags: []string{"-no-tls12", "-no-tls1"},
+ shouldFail: true,
+ expectedError: ":WRONG_SSL_VERSION:",
+ },
+ {
+ name: "NoSharedCipher",
+ config: Config{
+ CipherSuites: []uint16{},
+ },
+ shouldFail: true,
+ expectedError: ":HANDSHAKE_FAILURE_ON_CLIENT_HELLO:",
+ },
+ {
+ protocol: dtls,
+ testType: serverTest,
+ name: "MTU",
+ config: Config{
+ Bugs: ProtocolBugs{
+ MaxPacketLength: 256,
+ },
+ },
+ flags: []string{"-mtu", "256"},
+ },
+ {
+ protocol: dtls,
+ testType: serverTest,
+ name: "MTUExceeded",
+ config: Config{
+ Bugs: ProtocolBugs{
+ MaxPacketLength: 255,
+ },
+ },
+ flags: []string{"-mtu", "256"},
+ shouldFail: true,
+ expectedLocalError: "dtls: exceeded maximum packet length",
+ },
+ {
+ name: "CertMismatchRSA",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+ Certificates: []Certificate{getECDSACertificate()},
+ Bugs: ProtocolBugs{
+ SendCipherSuite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":WRONG_CERTIFICATE_TYPE:",
+ },
+ {
+ name: "CertMismatchECDSA",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ Certificates: []Certificate{getRSACertificate()},
+ Bugs: ProtocolBugs{
+ SendCipherSuite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":WRONG_CERTIFICATE_TYPE:",
+ },
+ {
+ name: "EmptyCertificateList",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ Bugs: ProtocolBugs{
+ EmptyCertificateList: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":DECODE_ERROR:",
+ },
+ {
+ name: "TLSFatalBadPackets",
+ damageFirstWrite: true,
+ shouldFail: true,
+ expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
+ },
+ {
+ protocol: dtls,
+ name: "DTLSIgnoreBadPackets",
+ damageFirstWrite: true,
+ },
+ {
+ protocol: dtls,
+ name: "DTLSIgnoreBadPackets-Async",
+ damageFirstWrite: true,
+ flags: []string{"-async"},
+ },
+ {
+ name: "AppDataBeforeHandshake",
+ config: Config{
+ Bugs: ProtocolBugs{
+ AppDataBeforeHandshake: []byte("TEST MESSAGE"),
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ name: "AppDataBeforeHandshake-Empty",
+ config: Config{
+ Bugs: ProtocolBugs{
+ AppDataBeforeHandshake: []byte{},
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ protocol: dtls,
+ name: "AppDataBeforeHandshake-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ AppDataBeforeHandshake: []byte("TEST MESSAGE"),
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ protocol: dtls,
+ name: "AppDataBeforeHandshake-DTLS-Empty",
+ config: Config{
+ Bugs: ProtocolBugs{
+ AppDataBeforeHandshake: []byte{},
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ name: "AppDataAfterChangeCipherSpec",
+ config: Config{
+ Bugs: ProtocolBugs{
+ AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"),
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ name: "AppDataAfterChangeCipherSpec-Empty",
+ config: Config{
+ Bugs: ProtocolBugs{
+ AppDataAfterChangeCipherSpec: []byte{},
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ protocol: dtls,
+ name: "AppDataAfterChangeCipherSpec-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"),
+ },
+ },
+ // BoringSSL's DTLS implementation will drop the out-of-order
+ // application data.
+ },
+ {
+ protocol: dtls,
+ name: "AppDataAfterChangeCipherSpec-DTLS-Empty",
+ config: Config{
+ Bugs: ProtocolBugs{
+ AppDataAfterChangeCipherSpec: []byte{},
+ },
+ },
+ // BoringSSL's DTLS implementation will drop the out-of-order
+ // application data.
+ },
+ {
+ name: "AlertAfterChangeCipherSpec",
+ config: Config{
+ Bugs: ProtocolBugs{
+ AlertAfterChangeCipherSpec: alertRecordOverflow,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
+ },
+ {
+ protocol: dtls,
+ name: "AlertAfterChangeCipherSpec-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ AlertAfterChangeCipherSpec: alertRecordOverflow,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
+ },
+ {
+ protocol: dtls,
+ name: "ReorderHandshakeFragments-Small-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ ReorderHandshakeFragments: true,
+ // Small enough that every handshake message is
+ // fragmented.
+ MaxHandshakeRecordLength: 2,
+ },
+ },
+ },
+ {
+ protocol: dtls,
+ name: "ReorderHandshakeFragments-Large-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ ReorderHandshakeFragments: true,
+ // Large enough that no handshake message is
+ // fragmented.
+ MaxHandshakeRecordLength: 2048,
+ },
+ },
+ },
+ {
+ protocol: dtls,
+ name: "MixCompleteMessageWithFragments-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ ReorderHandshakeFragments: true,
+ MixCompleteMessageWithFragments: true,
+ MaxHandshakeRecordLength: 2,
+ },
+ },
+ },
+ {
+ name: "SendInvalidRecordType",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendInvalidRecordType: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ protocol: dtls,
+ name: "SendInvalidRecordType-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendInvalidRecordType: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ name: "FalseStart-SkipServerSecondLeg",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ NextProtos: []string{"foo"},
+ Bugs: ProtocolBugs{
+ SkipNewSessionTicket: true,
+ SkipChangeCipherSpec: true,
+ SkipFinished: true,
+ ExpectFalseStart: true,
+ },
+ },
+ flags: []string{
+ "-false-start",
+ "-handshake-never-done",
+ "-advertise-alpn", "\x03foo",
+ },
+ shimWritesFirst: true,
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ name: "FalseStart-SkipServerSecondLeg-Implicit",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ NextProtos: []string{"foo"},
+ Bugs: ProtocolBugs{
+ SkipNewSessionTicket: true,
+ SkipChangeCipherSpec: true,
+ SkipFinished: true,
+ },
+ },
+ flags: []string{
+ "-implicit-handshake",
+ "-false-start",
+ "-handshake-never-done",
+ "-advertise-alpn", "\x03foo",
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ testType: serverTest,
+ name: "FailEarlyCallback",
+ flags: []string{"-fail-early-callback"},
+ shouldFail: true,
+ expectedError: ":CONNECTION_REJECTED:",
+ expectedLocalError: "remote error: access denied",
+ },
+ {
+ name: "WrongMessageType",
+ config: Config{
+ Bugs: ProtocolBugs{
+ WrongCertificateMessageType: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_MESSAGE:",
+ expectedLocalError: "remote error: unexpected message",
+ },
+ {
+ protocol: dtls,
+ name: "WrongMessageType-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ WrongCertificateMessageType: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_MESSAGE:",
+ expectedLocalError: "remote error: unexpected message",
+ },
+ {
+ protocol: dtls,
+ name: "FragmentMessageTypeMismatch-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ MaxHandshakeRecordLength: 2,
+ FragmentMessageTypeMismatch: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":FRAGMENT_MISMATCH:",
+ },
+ {
+ protocol: dtls,
+ name: "FragmentMessageLengthMismatch-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ MaxHandshakeRecordLength: 2,
+ FragmentMessageLengthMismatch: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":FRAGMENT_MISMATCH:",
+ },
+ {
+ protocol: dtls,
+ name: "SplitFragments-Header-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SplitFragments: 2,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_MESSAGE:",
+ },
+ {
+ protocol: dtls,
+ name: "SplitFragments-Boundary-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SplitFragments: dtlsRecordHeaderLen,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":EXCESSIVE_MESSAGE_SIZE:",
+ },
+ {
+ protocol: dtls,
+ name: "SplitFragments-Body-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SplitFragments: dtlsRecordHeaderLen + 1,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":EXCESSIVE_MESSAGE_SIZE:",
+ },
+ {
+ protocol: dtls,
+ name: "SendEmptyFragments-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendEmptyFragments: true,
+ },
+ },
+ },
+ {
+ name: "UnsupportedCipherSuite",
+ config: Config{
+ CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ Bugs: ProtocolBugs{
+ IgnorePeerCipherPreferences: true,
+ },
+ },
+ flags: []string{"-cipher", "DEFAULT:!RC4"},
+ shouldFail: true,
+ expectedError: ":WRONG_CIPHER_RETURNED:",
+ },
+ {
+ name: "UnsupportedCurve",
+ config: Config{
+ 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:",
+ },
+ {
+ name: "BadFinished",
+ config: Config{
+ Bugs: ProtocolBugs{
+ BadFinished: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":DIGEST_CHECK_FAILED:",
+ },
+ {
+ name: "FalseStart-BadFinished",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ NextProtos: []string{"foo"},
+ Bugs: ProtocolBugs{
+ BadFinished: true,
+ ExpectFalseStart: true,
+ },
+ },
+ flags: []string{
+ "-false-start",
+ "-handshake-never-done",
+ "-advertise-alpn", "\x03foo",
+ },
+ shimWritesFirst: true,
+ shouldFail: true,
+ expectedError: ":DIGEST_CHECK_FAILED:",
+ },
+ {
+ name: "NoFalseStart-NoALPN",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ Bugs: ProtocolBugs{
+ ExpectFalseStart: true,
+ AlertBeforeFalseStartTest: alertAccessDenied,
+ },
+ },
+ flags: []string{
+ "-false-start",
+ },
+ shimWritesFirst: true,
+ shouldFail: true,
+ expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
+ expectedLocalError: "tls: peer did not false start: EOF",
+ },
+ {
+ name: "NoFalseStart-NoAEAD",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
+ NextProtos: []string{"foo"},
+ Bugs: ProtocolBugs{
+ ExpectFalseStart: true,
+ AlertBeforeFalseStartTest: alertAccessDenied,
+ },
+ },
+ flags: []string{
+ "-false-start",
+ "-advertise-alpn", "\x03foo",
+ },
+ shimWritesFirst: true,
+ shouldFail: true,
+ expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
+ expectedLocalError: "tls: peer did not false start: EOF",
+ },
+ {
+ name: "NoFalseStart-RSA",
+ config: Config{
+ CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
+ NextProtos: []string{"foo"},
+ Bugs: ProtocolBugs{
+ ExpectFalseStart: true,
+ AlertBeforeFalseStartTest: alertAccessDenied,
+ },
+ },
+ flags: []string{
+ "-false-start",
+ "-advertise-alpn", "\x03foo",
+ },
+ shimWritesFirst: true,
+ shouldFail: true,
+ expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
+ expectedLocalError: "tls: peer did not false start: EOF",
+ },
+ {
+ name: "NoFalseStart-DHE_RSA",
+ config: Config{
+ CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
+ NextProtos: []string{"foo"},
+ Bugs: ProtocolBugs{
+ ExpectFalseStart: true,
+ AlertBeforeFalseStartTest: alertAccessDenied,
+ },
+ },
+ flags: []string{
+ "-false-start",
+ "-advertise-alpn", "\x03foo",
+ },
+ shimWritesFirst: true,
+ shouldFail: true,
+ expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
+ expectedLocalError: "tls: peer did not false start: EOF",
+ },
+ {
+ testType: serverTest,
+ name: "NoSupportedCurves",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ Bugs: ProtocolBugs{
+ NoSupportedCurves: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":NO_SHARED_CIPHER:",
+ },
+ {
+ testType: serverTest,
+ name: "NoCommonCurves",
+ config: Config{
+ CipherSuites: []uint16{
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
+ },
+ CurvePreferences: []CurveID{CurveP224},
+ },
+ expectedCipher: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
+ },
+ {
+ protocol: dtls,
+ name: "SendSplitAlert-Sync",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendSplitAlert: true,
+ },
+ },
+ },
+ {
+ protocol: dtls,
+ name: "SendSplitAlert-Async",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendSplitAlert: true,
+ },
+ },
+ flags: []string{"-async"},
+ },
+ {
+ protocol: dtls,
+ name: "PackDTLSHandshake",
+ config: Config{
+ Bugs: ProtocolBugs{
+ MaxHandshakeRecordLength: 2,
+ PackHandshakeFragments: 20,
+ PackHandshakeRecords: 200,
+ },
+ },
+ },
+ {
+ testType: serverTest,
+ protocol: dtls,
+ name: "NoRC4-DTLS",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_RC4_128_SHA},
+ Bugs: ProtocolBugs{
+ EnableAllCiphersInDTLS: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":NO_SHARED_CIPHER:",
+ },
+ {
+ name: "SendEmptyRecords-Pass",
+ sendEmptyRecords: 32,
+ },
+ {
+ name: "SendEmptyRecords",
+ sendEmptyRecords: 33,
+ shouldFail: true,
+ expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:",
+ },
+ {
+ name: "SendEmptyRecords-Async",
+ sendEmptyRecords: 33,
+ flags: []string{"-async"},
+ shouldFail: true,
+ expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:",
+ },
+ {
+ name: "SendWarningAlerts-Pass",
+ sendWarningAlerts: 4,
+ },
+ {
+ protocol: dtls,
+ name: "SendWarningAlerts-DTLS-Pass",
+ sendWarningAlerts: 4,
+ },
+ {
+ name: "SendWarningAlerts",
+ sendWarningAlerts: 5,
+ shouldFail: true,
+ expectedError: ":TOO_MANY_WARNING_ALERTS:",
+ },
+ {
+ name: "SendWarningAlerts-Async",
+ sendWarningAlerts: 5,
+ flags: []string{"-async"},
+ shouldFail: true,
+ expectedError: ":TOO_MANY_WARNING_ALERTS:",
+ },
+ {
+ name: "EmptySessionID",
+ config: Config{
+ SessionTicketsDisabled: true,
+ },
+ noSessionCache: true,
+ flags: []string{"-expect-no-session"},
+ },
+ {
+ name: "Unclean-Shutdown",
+ config: Config{
+ Bugs: ProtocolBugs{
+ NoCloseNotify: true,
+ ExpectCloseNotify: true,
+ },
+ },
+ shimShutsDown: true,
+ flags: []string{"-check-close-notify"},
+ shouldFail: true,
+ expectedError: "Unexpected SSL_shutdown result: -1 != 1",
+ },
+ {
+ name: "Unclean-Shutdown-Ignored",
+ config: Config{
+ Bugs: ProtocolBugs{
+ NoCloseNotify: true,
+ },
+ },
+ shimShutsDown: true,
+ },
+ {
+ name: "LargePlaintext",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendLargeRecords: true,
+ },
+ },
+ messageLen: maxPlaintext + 1,
+ shouldFail: true,
+ expectedError: ":DATA_LENGTH_TOO_LONG:",
+ },
+ {
+ protocol: dtls,
+ name: "LargePlaintext-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendLargeRecords: true,
+ },
+ },
+ messageLen: maxPlaintext + 1,
+ shouldFail: true,
+ expectedError: ":DATA_LENGTH_TOO_LONG:",
+ },
+ {
+ name: "LargeCiphertext",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendLargeRecords: true,
+ },
+ },
+ messageLen: maxPlaintext * 2,
+ shouldFail: true,
+ expectedError: ":ENCRYPTED_LENGTH_TOO_LONG:",
+ },
+ {
+ protocol: dtls,
+ name: "LargeCiphertext-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendLargeRecords: true,
+ },
+ },
+ messageLen: maxPlaintext * 2,
+ // Unlike the other four cases, DTLS drops records which
+ // are invalid before authentication, so the connection
+ // does not fail.
+ expectMessageDropped: true,
+ },
+ {
+ name: "SendEmptySessionTicket",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendEmptySessionTicket: true,
+ FailIfSessionOffered: true,
+ },
+ },
+ flags: []string{"-expect-no-session"},
+ 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...)
+}
+
func addCipherSuiteTests() {
for _, suite := range testCipherSuites {
const psk = "12345"
@@ -1679,15 +2116,26 @@ func addCipherSuiteTests() {
"-psk", psk,
"-psk-identity", pskIdentity)
}
+ if hasComponent(suite.name, "NULL") {
+ // NULL ciphers must be explicitly enabled.
+ flags = append(flags, "-cipher", "DEFAULT:NULL-SHA")
+ }
for _, ver := range tlsVersions {
if ver.version < VersionTLS12 && isTLS12Only(suite.name) {
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,
@@ -1696,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,
@@ -1711,8 +2167,6 @@ func addCipherSuiteTests() {
PreSharedKey: []byte(psk),
PreSharedKeyIdentity: pskIdentity,
},
- certFile: certFile,
- keyFile: keyFile,
flags: flags,
resumeSession: true,
})
@@ -1752,6 +2206,33 @@ func addCipherSuiteTests() {
})
}
}
+
+ // Ensure both TLS and DTLS accept their maximum record sizes.
+ testCases = append(testCases, testCase{
+ name: suite.name + "-LargeRecord",
+ config: Config{
+ CipherSuites: []uint16{suite.id},
+ Certificates: []Certificate{cert},
+ PreSharedKey: []byte(psk),
+ PreSharedKeyIdentity: pskIdentity,
+ },
+ flags: flags,
+ messageLen: maxPlaintext,
+ })
+ if isDTLSCipher(suite.name) {
+ testCases = append(testCases, testCase{
+ protocol: dtls,
+ name: suite.name + "-LargeRecord-DTLS",
+ config: Config{
+ CipherSuites: []uint16{suite.id},
+ Certificates: []Certificate{cert},
+ PreSharedKey: []byte(psk),
+ PreSharedKeyIdentity: pskIdentity,
+ },
+ flags: flags,
+ messageLen: maxPlaintext,
+ })
+ }
}
testCases = append(testCases, testCase{
@@ -1766,8 +2247,126 @@ 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
+ // 1.1 specific cipher suite settings. A server is setup with the given
+ // cipher lists and then a connection is made for each member of
+ // expectations. The cipher suite that the server selects must match
+ // the specified one.
+ var versionSpecificCiphersTest = []struct {
+ ciphersDefault, ciphersTLS10, ciphersTLS11 string
+ // expectations is a map from TLS version to cipher suite id.
+ expectations map[uint16]uint16
+ }{
+ {
+ // Test that the null case (where no version-specific ciphers are set)
+ // works as expected.
+ "RC4-SHA:AES128-SHA", // default ciphers
+ "", // no ciphers specifically for TLS ≥ 1.0
+ "", // no ciphers specifically for TLS ≥ 1.1
+ map[uint16]uint16{
+ VersionSSL30: TLS_RSA_WITH_RC4_128_SHA,
+ VersionTLS10: TLS_RSA_WITH_RC4_128_SHA,
+ VersionTLS11: TLS_RSA_WITH_RC4_128_SHA,
+ VersionTLS12: TLS_RSA_WITH_RC4_128_SHA,
+ },
+ },
+ {
+ // With ciphers_tls10 set, TLS 1.0, 1.1 and 1.2 should get a different
+ // cipher.
+ "RC4-SHA:AES128-SHA", // default
+ "AES128-SHA", // these ciphers for TLS ≥ 1.0
+ "", // no ciphers specifically for TLS ≥ 1.1
+ map[uint16]uint16{
+ VersionSSL30: TLS_RSA_WITH_RC4_128_SHA,
+ VersionTLS10: TLS_RSA_WITH_AES_128_CBC_SHA,
+ VersionTLS11: TLS_RSA_WITH_AES_128_CBC_SHA,
+ VersionTLS12: TLS_RSA_WITH_AES_128_CBC_SHA,
+ },
+ },
+ {
+ // With ciphers_tls11 set, TLS 1.1 and 1.2 should get a different
+ // cipher.
+ "RC4-SHA:AES128-SHA", // default
+ "", // no ciphers specifically for TLS ≥ 1.0
+ "AES128-SHA", // these ciphers for TLS ≥ 1.1
+ map[uint16]uint16{
+ VersionSSL30: TLS_RSA_WITH_RC4_128_SHA,
+ VersionTLS10: TLS_RSA_WITH_RC4_128_SHA,
+ VersionTLS11: TLS_RSA_WITH_AES_128_CBC_SHA,
+ VersionTLS12: TLS_RSA_WITH_AES_128_CBC_SHA,
+ },
+ },
+ {
+ // With both ciphers_tls10 and ciphers_tls11 set, ciphers_tls11 should
+ // mask ciphers_tls10 for TLS 1.1 and 1.2.
+ "RC4-SHA:AES128-SHA", // default
+ "AES128-SHA", // these ciphers for TLS ≥ 1.0
+ "AES256-SHA", // these ciphers for TLS ≥ 1.1
+ map[uint16]uint16{
+ VersionSSL30: TLS_RSA_WITH_RC4_128_SHA,
+ VersionTLS10: TLS_RSA_WITH_AES_128_CBC_SHA,
+ VersionTLS11: TLS_RSA_WITH_AES_256_CBC_SHA,
+ VersionTLS12: TLS_RSA_WITH_AES_256_CBC_SHA,
+ },
+ },
+ }
+
+ for i, test := range versionSpecificCiphersTest {
+ for version, expectedCipherSuite := range test.expectations {
+ flags := []string{"-cipher", test.ciphersDefault}
+ if len(test.ciphersTLS10) > 0 {
+ flags = append(flags, "-cipher-tls10", test.ciphersTLS10)
+ }
+ if len(test.ciphersTLS11) > 0 {
+ flags = append(flags, "-cipher-tls11", test.ciphersTLS11)
+ }
+
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: fmt.Sprintf("VersionSpecificCiphersTest-%d-%x", i, version),
+ config: Config{
+ MaxVersion: version,
+ MinVersion: version,
+ CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA},
+ },
+ flags: flags,
+ expectedCipher: expectedCipherSuite,
+ })
+ }
+ }
}
func addBadECDSASignatureTests() {
@@ -1837,7 +2436,8 @@ func addCBCSplittingTests() {
MinVersion: VersionTLS10,
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
},
- messageLen: -1, // read until EOF
+ messageLen: -1, // read until EOF
+ resumeSession: true,
flags: []string{
"-async",
"-write-different-record-sizes",
@@ -1882,8 +2482,8 @@ func addClientAuthTests() {
ClientCAs: certPool,
},
flags: []string{
- "-cert-file", rsaCertificateFile,
- "-key-file", rsaKeyFile,
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
},
})
testCases = append(testCases, testCase{
@@ -1917,8 +2517,8 @@ func addClientAuthTests() {
ClientCAs: certPool,
},
flags: []string{
- "-cert-file", ecdsaCertificateFile,
- "-key-file", ecdsaKeyFile,
+ "-cert-file", path.Join(*resourceDir, ecdsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, ecdsaKeyFile),
},
})
}
@@ -2075,6 +2675,7 @@ func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol)
RenewTicketOnResume: true,
},
},
+ flags: []string{"-expect-ticket-renewal"},
resumeSession: true,
})
tests = append(tests, testCase{
@@ -2118,16 +2719,63 @@ func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol)
// TLS client auth.
tests = append(tests, testCase{
testType: clientTest,
- name: "ClientAuth-Client",
+ name: "ClientAuth-RSA-Client",
config: Config{
ClientAuth: RequireAnyClientCert,
},
flags: []string{
- "-cert-file", rsaCertificateFile,
- "-key-file", rsaKeyFile,
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
},
})
tests = append(tests, testCase{
+ testType: clientTest,
+ name: "ClientAuth-ECDSA-Client",
+ config: Config{
+ ClientAuth: RequireAnyClientCert,
+ },
+ flags: []string{
+ "-cert-file", path.Join(*resourceDir, ecdsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, ecdsaKeyFile),
+ },
+ })
+ if async {
+ // Test async keys against each key exchange.
+ tests = append(tests, testCase{
+ testType: serverTest,
+ name: "Basic-Server-RSA",
+ config: Config{
+ CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
+ },
+ flags: []string{
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
+ },
+ })
+ tests = append(tests, testCase{
+ testType: serverTest,
+ name: "Basic-Server-ECDHE-RSA",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ },
+ flags: []string{
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
+ },
+ })
+ tests = append(tests, testCase{
+ testType: serverTest,
+ name: "Basic-Server-ECDHE-ECDSA",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+ },
+ flags: []string{
+ "-cert-file", path.Join(*resourceDir, ecdsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, ecdsaKeyFile),
+ },
+ })
+ }
+ tests = append(tests, testCase{
testType: serverTest,
name: "ClientAuth-Server",
config: Config{
@@ -2171,10 +2819,65 @@ func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol)
flags: []string{"-psk", "secret"},
})
+ tests = append(tests, testCase{
+ testType: clientTest,
+ name: "OCSPStapling-Client",
+ flags: []string{
+ "-enable-ocsp-stapling",
+ "-expect-ocsp-response",
+ base64.StdEncoding.EncodeToString(testOCSPResponse),
+ "-verify-peer",
+ },
+ resumeSession: true,
+ })
+
+ tests = append(tests, testCase{
+ testType: serverTest,
+ name: "OCSPStapling-Server",
+ expectedOCSPResponse: testOCSPResponse,
+ flags: []string{
+ "-ocsp-response",
+ base64.StdEncoding.EncodeToString(testOCSPResponse),
+ },
+ resumeSession: true,
+ })
+
+ tests = append(tests, testCase{
+ testType: clientTest,
+ name: "CertificateVerificationSucceed",
+ flags: []string{
+ "-verify-peer",
+ },
+ })
+
+ tests = append(tests, testCase{
+ testType: clientTest,
+ name: "CertificateVerificationFail",
+ flags: []string{
+ "-verify-fail",
+ "-verify-peer",
+ },
+ shouldFail: true,
+ expectedError: ":CERTIFICATE_VERIFY_FAILED:",
+ })
+
+ tests = append(tests, testCase{
+ testType: clientTest,
+ name: "CertificateVerificationSoftFail",
+ flags: []string{
+ "-verify-fail",
+ "-expect-verify-result",
+ },
+ })
+
if protocol == tls {
tests = append(tests, testCase{
name: "Renegotiate-Client",
- renegotiate: true,
+ renegotiate: 1,
+ flags: []string{
+ "-renegotiate-freely",
+ "-expect-total-renegotiations", "1",
+ },
})
// NPN on client and server; results in post-handshake message.
tests = append(tests, testCase{
@@ -2292,7 +2995,7 @@ func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol)
config: Config{
RequestChannelID: true,
},
- flags: []string{"-send-channel-id", channelIDKeyFile},
+ flags: []string{"-send-channel-id", path.Join(*resourceDir, channelIDKeyFile)},
resumeSession: true,
expectChannelID: true,
})
@@ -2311,6 +3014,33 @@ func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol)
resumeSession: true,
expectChannelID: true,
})
+
+ // Bidirectional shutdown with the runner initiating.
+ tests = append(tests, testCase{
+ name: "Shutdown-Runner",
+ config: Config{
+ Bugs: ProtocolBugs{
+ ExpectCloseNotify: true,
+ },
+ },
+ flags: []string{"-check-close-notify"},
+ })
+
+ // Bidirectional shutdown with the shim initiating. The runner,
+ // in the meantime, sends garbage before the close_notify which
+ // the shim must ignore.
+ tests = append(tests, testCase{
+ name: "Shutdown-Shim",
+ config: Config{
+ Bugs: ProtocolBugs{
+ ExpectCloseNotify: true,
+ },
+ },
+ shimShutsDown: true,
+ sendEmptyRecords: 1,
+ sendWarningAlerts: 1,
+ flags: []string{"-check-close-notify"},
+ })
} else {
tests = append(tests, testCase{
name: "SkipHelloVerifyRequest",
@@ -2322,27 +3052,25 @@ func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol)
})
}
- var suffix string
- var flags []string
- var maxHandshakeRecordLength int
- if protocol == dtls {
- suffix = "-DTLS"
- }
- if async {
- suffix += "-Async"
- flags = append(flags, "-async")
- } else {
- suffix += "-Sync"
- }
- if splitHandshake {
- suffix += "-SplitHandshakeRecords"
- maxHandshakeRecordLength = 1
- }
for _, test := range tests {
test.protocol = protocol
- test.name += suffix
- test.config.Bugs.MaxHandshakeRecordLength = maxHandshakeRecordLength
- test.flags = append(test.flags, flags...)
+ if protocol == dtls {
+ test.name += "-DTLS"
+ }
+ if async {
+ test.name += "-Async"
+ test.flags = append(test.flags, "-async")
+ } else {
+ test.name += "-Sync"
+ }
+ if splitHandshake {
+ test.name += "-SplitHandshakeRecords"
+ test.config.Bugs.MaxHandshakeRecordLength = 1
+ if protocol == dtls {
+ test.config.Bugs.MaxPacketLength = 256
+ test.flags = append(test.flags, "-mtu", "256")
+ }
+ }
testCases = append(testCases, test)
}
}
@@ -2560,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,
@@ -2721,6 +3415,82 @@ func addExtensionTests() {
expectedNextProtoType: alpn,
resumeSession: true,
})
+ var emptyString string
+ testCases = append(testCases, testCase{
+ testType: clientTest,
+ name: "ALPNClient-EmptyProtocolName",
+ config: Config{
+ NextProtos: []string{""},
+ Bugs: ProtocolBugs{
+ // A server returning an empty ALPN protocol
+ // should be rejected.
+ ALPNProtocol: &emptyString,
+ },
+ },
+ flags: []string{
+ "-advertise-alpn", "\x03foo",
+ },
+ shouldFail: true,
+ expectedError: ":PARSE_TLSEXT:",
+ })
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "ALPNServer-EmptyProtocolName",
+ config: Config{
+ // A ClientHello containing an empty ALPN protocol
+ // should be rejected.
+ NextProtos: []string{"foo", "", "baz"},
+ },
+ flags: []string{
+ "-select-alpn", "foo",
+ },
+ shouldFail: true,
+ expectedError: ":PARSE_TLSEXT:",
+ })
+ // Test that negotiating both NPN and ALPN is forbidden.
+ testCases = append(testCases, testCase{
+ name: "NegotiateALPNAndNPN",
+ config: Config{
+ NextProtos: []string{"foo", "bar", "baz"},
+ Bugs: ProtocolBugs{
+ NegotiateALPNAndNPN: true,
+ },
+ },
+ flags: []string{
+ "-advertise-alpn", "\x03foo",
+ "-select-next-proto", "foo",
+ },
+ shouldFail: true,
+ expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:",
+ })
+ testCases = append(testCases, testCase{
+ name: "NegotiateALPNAndNPN-Swapped",
+ config: Config{
+ NextProtos: []string{"foo", "bar", "baz"},
+ Bugs: ProtocolBugs{
+ NegotiateALPNAndNPN: true,
+ SwapNPNAndALPN: true,
+ },
+ },
+ flags: []string{
+ "-advertise-alpn", "\x03foo",
+ "-select-next-proto", "foo",
+ },
+ shouldFail: true,
+ expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:",
+ })
+ // Test that NPN can be disabled with SSL_OP_DISABLE_NPN.
+ testCases = append(testCases, testCase{
+ name: "DisableNPN",
+ config: Config{
+ NextProtos: []string{"foo"},
+ },
+ flags: []string{
+ "-select-next-proto", "foo",
+ "-disable-npn",
+ },
+ expectNoNextProto: true,
+ })
// Resume with a corrupt ticket.
testCases = append(testCases, testCase{
testType: serverTest,
@@ -2733,6 +3503,24 @@ func addExtensionTests() {
resumeSession: true,
expectResumeRejected: true,
})
+ // Test the ticket callback, with and without renewal.
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "TicketCallback",
+ resumeSession: true,
+ flags: []string{"-use-ticket-callback"},
+ })
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "TicketCallback-Renew",
+ config: Config{
+ Bugs: ProtocolBugs{
+ ExpectNewTicket: true,
+ },
+ },
+ flags: []string{"-use-ticket-callback", "-renew-ticket"},
+ resumeSession: true,
+ })
// Resume with an oversized session id.
testCases = append(testCases, testCase{
testType: serverTest,
@@ -2822,22 +3610,101 @@ func addExtensionTests() {
shouldFail: true,
expectedError: ":BAD_SRTP_PROTECTION_PROFILE_LIST:",
})
- // Test OCSP stapling and SCT list.
+ // Test SCT list.
testCases = append(testCases, testCase{
- name: "OCSPStapling",
+ name: "SignedCertificateTimestampList-Client",
+ testType: clientTest,
flags: []string{
- "-enable-ocsp-stapling",
- "-expect-ocsp-response",
- base64.StdEncoding.EncodeToString(testOCSPResponse),
+ "-enable-signed-cert-timestamps",
+ "-expect-signed-cert-timestamps",
+ base64.StdEncoding.EncodeToString(testSCTList),
},
+ resumeSession: true,
})
testCases = append(testCases, testCase{
- name: "SignedCertificateTimestampList",
+ name: "SignedCertificateTimestampList-Server",
+ testType: serverTest,
flags: []string{
- "-enable-signed-cert-timestamps",
- "-expect-signed-cert-timestamps",
+ "-signed-cert-timestamps",
base64.StdEncoding.EncodeToString(testSCTList),
},
+ expectedSCTList: testSCTList,
+ resumeSession: true,
+ })
+ testCases = append(testCases, testCase{
+ testType: clientTest,
+ name: "ClientHelloPadding",
+ config: Config{
+ Bugs: ProtocolBugs{
+ RequireClientHelloSize: 512,
+ },
+ },
+ // This hostname just needs to be long enough to push the
+ // ClientHello into F5's danger zone between 256 and 511 bytes
+ // long.
+ flags: []string{"-host-name", "01234567890123456789012345678901234567890123456789012345678901234567890123456789.com"},
+ })
+
+ // Extensions should not function in SSL 3.0.
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "SSLv3Extensions-NoALPN",
+ config: Config{
+ MaxVersion: VersionSSL30,
+ NextProtos: []string{"foo", "bar", "baz"},
+ },
+ flags: []string{
+ "-select-alpn", "foo",
+ },
+ expectNoNextProto: true,
+ })
+
+ // Test session tickets separately as they follow a different codepath.
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "SSLv3Extensions-NoTickets",
+ config: Config{
+ MaxVersion: VersionSSL30,
+ Bugs: ProtocolBugs{
+ // Historically, session tickets in SSL 3.0
+ // failed in different ways depending on whether
+ // the client supported renegotiation_info.
+ NoRenegotiationInfo: true,
+ },
+ },
+ resumeSession: true,
+ })
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "SSLv3Extensions-NoTickets2",
+ config: Config{
+ MaxVersion: VersionSSL30,
+ },
+ resumeSession: true,
+ })
+
+ // But SSL 3.0 does send and process renegotiation_info.
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "SSLv3Extensions-RenegotiationInfo",
+ config: Config{
+ MaxVersion: VersionSSL30,
+ Bugs: ProtocolBugs{
+ RequireRenegotiationInfo: true,
+ },
+ },
+ })
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "SSLv3Extensions-RenegotiationInfo-SCSV",
+ config: Config{
+ MaxVersion: VersionSSL30,
+ Bugs: ProtocolBugs{
+ NoRenegotiationInfo: true,
+ SendRenegotiationSCSV: true,
+ RequireRenegotiationInfo: true,
+ },
+ },
})
}
@@ -2950,13 +3817,38 @@ func addRenegotiationTests() {
testCases = append(testCases, testCase{
testType: serverTest,
name: "Renegotiate-Server-Forbidden",
- renegotiate: true,
- flags: []string{"-reject-peer-renegotiations"},
+ renegotiate: 1,
shouldFail: true,
expectedError: ":NO_RENEGOTIATION:",
expectedLocalError: "remote error: no renegotiation",
})
- // TODO(agl): test the renegotiation info SCSV.
+ // The server shouldn't echo the renegotiation extension unless
+ // requested by the client.
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "Renegotiate-Server-NoExt",
+ config: Config{
+ Bugs: ProtocolBugs{
+ NoRenegotiationInfo: true,
+ RequireRenegotiationInfo: true,
+ },
+ },
+ shouldFail: true,
+ expectedLocalError: "renegotiation extension missing",
+ })
+ // The renegotiation SCSV should be sufficient for the server to echo
+ // the extension.
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "Renegotiate-Server-NoExt-SCSV",
+ config: Config{
+ Bugs: ProtocolBugs{
+ NoRenegotiationInfo: true,
+ SendRenegotiationSCSV: true,
+ RequireRenegotiationInfo: true,
+ },
+ },
+ })
testCases = append(testCases, testCase{
name: "Renegotiate-Client",
config: Config{
@@ -2964,84 +3856,188 @@ func addRenegotiationTests() {
FailIfResumeOnRenego: true,
},
},
- renegotiate: true,
+ renegotiate: 1,
+ flags: []string{
+ "-renegotiate-freely",
+ "-expect-total-renegotiations", "1",
+ },
})
testCases = append(testCases, testCase{
name: "Renegotiate-Client-EmptyExt",
- renegotiate: true,
+ renegotiate: 1,
config: Config{
Bugs: ProtocolBugs{
EmptyRenegotiationInfo: true,
},
},
+ flags: []string{"-renegotiate-freely"},
shouldFail: true,
expectedError: ":RENEGOTIATION_MISMATCH:",
})
testCases = append(testCases, testCase{
name: "Renegotiate-Client-BadExt",
- renegotiate: true,
+ renegotiate: 1,
config: Config{
Bugs: ProtocolBugs{
BadRenegotiationInfo: true,
},
},
+ flags: []string{"-renegotiate-freely"},
shouldFail: true,
expectedError: ":RENEGOTIATION_MISMATCH:",
})
testCases = append(testCases, testCase{
- name: "Renegotiate-Client-NoExt",
- renegotiate: true,
+ name: "Renegotiate-Client-Downgrade",
+ renegotiate: 1,
config: Config{
Bugs: ProtocolBugs{
- NoRenegotiationInfo: true,
+ 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{
+ 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",
- renegotiate: true,
+ renegotiate: 1,
config: Config{
Bugs: ProtocolBugs{
NoRenegotiationInfo: true,
},
},
+ flags: []string{
+ "-renegotiate-freely",
+ "-expect-total-renegotiations", "1",
+ },
})
testCases = append(testCases, testCase{
name: "Renegotiate-Client-SwitchCiphers",
- renegotiate: true,
+ renegotiate: 1,
config: Config{
CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
},
renegotiateCiphers: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ flags: []string{
+ "-renegotiate-freely",
+ "-expect-total-renegotiations", "1",
+ },
})
testCases = append(testCases, testCase{
name: "Renegotiate-Client-SwitchCiphers2",
- renegotiate: true,
+ renegotiate: 1,
config: Config{
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
},
renegotiateCiphers: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ flags: []string{
+ "-renegotiate-freely",
+ "-expect-total-renegotiations", "1",
+ },
+ })
+ testCases = append(testCases, testCase{
+ name: "Renegotiate-SameClientVersion",
+ renegotiate: 1,
+ config: Config{
+ MaxVersion: VersionTLS10,
+ Bugs: ProtocolBugs{
+ RequireSameRenegoClientVersion: true,
+ },
+ },
+ flags: []string{
+ "-renegotiate-freely",
+ "-expect-total-renegotiations", "1",
+ },
})
testCases = append(testCases, testCase{
- name: "Renegotiate-Client-Forbidden",
- renegotiate: true,
- flags: []string{"-reject-peer-renegotiations"},
+ name: "Renegotiate-FalseStart",
+ renegotiate: 1,
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ NextProtos: []string{"foo"},
+ },
+ flags: []string{
+ "-false-start",
+ "-select-next-proto", "foo",
+ "-renegotiate-freely",
+ "-expect-total-renegotiations", "1",
+ },
+ shimWritesFirst: true,
+ })
+
+ // Client-side renegotiation controls.
+ testCases = append(testCases, testCase{
+ name: "Renegotiate-Client-Forbidden-1",
+ renegotiate: 1,
shouldFail: true,
expectedError: ":NO_RENEGOTIATION:",
expectedLocalError: "remote error: no renegotiation",
})
testCases = append(testCases, testCase{
- name: "Renegotiate-SameClientVersion",
- renegotiate: true,
+ name: "Renegotiate-Client-Once-1",
+ renegotiate: 1,
+ flags: []string{
+ "-renegotiate-once",
+ "-expect-total-renegotiations", "1",
+ },
+ })
+ testCases = append(testCases, testCase{
+ name: "Renegotiate-Client-Freely-1",
+ renegotiate: 1,
+ flags: []string{
+ "-renegotiate-freely",
+ "-expect-total-renegotiations", "1",
+ },
+ })
+ testCases = append(testCases, testCase{
+ name: "Renegotiate-Client-Once-2",
+ renegotiate: 2,
+ flags: []string{"-renegotiate-once"},
+ shouldFail: true,
+ expectedError: ":NO_RENEGOTIATION:",
+ expectedLocalError: "remote error: no renegotiation",
+ })
+ testCases = append(testCases, testCase{
+ name: "Renegotiate-Client-Freely-2",
+ renegotiate: 2,
+ flags: []string{
+ "-renegotiate-freely",
+ "-expect-total-renegotiations", "2",
+ },
+ })
+ testCases = append(testCases, testCase{
+ name: "Renegotiate-Client-NoIgnore",
config: Config{
- MaxVersion: VersionTLS10,
Bugs: ProtocolBugs{
- RequireSameRenegoClientVersion: true,
+ SendHelloRequestBeforeEveryAppDataRecord: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":NO_RENEGOTIATION:",
+ })
+ testCases = append(testCases, testCase{
+ name: "Renegotiate-Client-Ignore",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendHelloRequestBeforeEveryAppDataRecord: true,
},
},
+ flags: []string{
+ "-renegotiate-ignore",
+ "-expect-total-renegotiations", "0",
+ },
})
}
@@ -3050,43 +4046,39 @@ func addDTLSReplayTests() {
testCases = append(testCases, testCase{
protocol: dtls,
name: "DTLS-Replay",
+ messageCount: 200,
replayWrites: true,
})
- // Test the outgoing sequence number skipping by values larger
+ // Test the incoming sequence number skipping by values larger
// than the retransmit window.
testCases = append(testCases, testCase{
protocol: dtls,
name: "DTLS-Replay-LargeGaps",
config: Config{
Bugs: ProtocolBugs{
- SequenceNumberIncrement: 127,
+ SequenceNumberMapping: func(in uint64) uint64 {
+ return in * 127
+ },
},
},
+ messageCount: 200,
replayWrites: true,
})
-}
-func addFastRadioPaddingTests() {
- testCases = append(testCases, testCase{
- protocol: tls,
- name: "FastRadio-Padding",
- config: Config{
- Bugs: ProtocolBugs{
- RequireFastradioPadding: true,
- },
- },
- flags: []string{"-fastradio-padding"},
- })
+ // Test the incoming sequence number changing non-monotonically.
testCases = append(testCases, testCase{
protocol: dtls,
- name: "FastRadio-Padding-DTLS",
+ name: "DTLS-Replay-NonMonotonic",
config: Config{
Bugs: ProtocolBugs{
- RequireFastradioPadding: true,
+ SequenceNumberMapping: func(in uint64) uint64 {
+ return in ^ 31
+ },
},
},
- flags: []string{"-fastradio-padding"},
+ messageCount: 200,
+ replayWrites: true,
})
}
@@ -3116,8 +4108,8 @@ func addSigningHashTests() {
},
},
flags: []string{
- "-cert-file", rsaCertificateFile,
- "-key-file", rsaKeyFile,
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
},
})
@@ -3133,6 +4125,19 @@ func addSigningHashTests() {
},
},
})
+
+ testCases = append(testCases, testCase{
+ name: "SigningHash-ServerKeyExchange-Verify-" + hash.name,
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ SignatureAndHashes: []signatureAndHash{
+ {signatureRSA, 42},
+ {signatureRSA, hash.id},
+ {signatureRSA, 255},
+ },
+ },
+ flags: []string{"-expect-server-key-exchange-hash", strconv.Itoa(int(hash.id))},
+ })
}
// Test that hash resolution takes the signature type into account.
@@ -3147,8 +4152,8 @@ func addSigningHashTests() {
},
},
flags: []string{
- "-cert-file", rsaCertificateFile,
- "-key-file", rsaKeyFile,
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
},
})
@@ -3178,8 +4183,8 @@ func addSigningHashTests() {
},
},
flags: []string{
- "-cert-file", rsaCertificateFile,
- "-key-file", rsaKeyFile,
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
},
})
@@ -3235,6 +4240,73 @@ func addSigningHashTests() {
shouldFail: true,
expectedError: ":WRONG_SIGNATURE_TYPE:",
})
+
+ // Test that the agreed upon digest respects the client preferences and
+ // the server digests.
+ testCases = append(testCases, testCase{
+ name: "Agree-Digest-Fallback",
+ config: Config{
+ ClientAuth: RequireAnyClientCert,
+ SignatureAndHashes: []signatureAndHash{
+ {signatureRSA, hashSHA512},
+ {signatureRSA, hashSHA1},
+ },
+ },
+ flags: []string{
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
+ },
+ digestPrefs: "SHA256",
+ expectedClientCertSignatureHash: hashSHA1,
+ })
+ testCases = append(testCases, testCase{
+ name: "Agree-Digest-SHA256",
+ config: Config{
+ ClientAuth: RequireAnyClientCert,
+ SignatureAndHashes: []signatureAndHash{
+ {signatureRSA, hashSHA1},
+ {signatureRSA, hashSHA256},
+ },
+ },
+ flags: []string{
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
+ },
+ digestPrefs: "SHA256,SHA1",
+ expectedClientCertSignatureHash: hashSHA256,
+ })
+ testCases = append(testCases, testCase{
+ name: "Agree-Digest-SHA1",
+ config: Config{
+ ClientAuth: RequireAnyClientCert,
+ SignatureAndHashes: []signatureAndHash{
+ {signatureRSA, hashSHA1},
+ },
+ },
+ flags: []string{
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
+ },
+ digestPrefs: "SHA512,SHA256,SHA1",
+ expectedClientCertSignatureHash: hashSHA1,
+ })
+ testCases = append(testCases, testCase{
+ name: "Agree-Digest-Default",
+ config: Config{
+ ClientAuth: RequireAnyClientCert,
+ SignatureAndHashes: []signatureAndHash{
+ {signatureRSA, hashSHA256},
+ {signatureECDSA, hashSHA256},
+ {signatureRSA, hashSHA1},
+ {signatureECDSA, hashSHA1},
+ },
+ },
+ flags: []string{
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
+ },
+ expectedClientCertSignatureHash: hashSHA256,
+ })
}
// timeouts is the retransmit schedule for BoringSSL. It doubles and
@@ -3441,7 +4513,219 @@ func addTLSUniqueTests() {
}
}
-func worker(statusChan chan statusMsg, c chan *testCase, buildDir string, wg *sync.WaitGroup) {
+func addCustomExtensionTests() {
+ expectedContents := "custom extension"
+ emptyString := ""
+
+ for _, isClient := range []bool{false, true} {
+ suffix := "Server"
+ flag := "-enable-server-custom-extension"
+ testType := serverTest
+ if isClient {
+ suffix = "Client"
+ flag = "-enable-client-custom-extension"
+ testType = clientTest
+ }
+
+ testCases = append(testCases, testCase{
+ testType: testType,
+ name: "CustomExtensions-" + suffix,
+ config: Config{
+ Bugs: ProtocolBugs{
+ CustomExtension: expectedContents,
+ ExpectedCustomExtension: &expectedContents,
+ },
+ },
+ flags: []string{flag},
+ })
+
+ // If the parse callback fails, the handshake should also fail.
+ testCases = append(testCases, testCase{
+ testType: testType,
+ name: "CustomExtensions-ParseError-" + suffix,
+ config: Config{
+ Bugs: ProtocolBugs{
+ CustomExtension: expectedContents + "foo",
+ ExpectedCustomExtension: &expectedContents,
+ },
+ },
+ flags: []string{flag},
+ shouldFail: true,
+ expectedError: ":CUSTOM_EXTENSION_ERROR:",
+ })
+
+ // If the add callback fails, the handshake should also fail.
+ testCases = append(testCases, testCase{
+ testType: testType,
+ name: "CustomExtensions-FailAdd-" + suffix,
+ config: Config{
+ Bugs: ProtocolBugs{
+ CustomExtension: expectedContents,
+ ExpectedCustomExtension: &expectedContents,
+ },
+ },
+ flags: []string{flag, "-custom-extension-fail-add"},
+ shouldFail: true,
+ expectedError: ":CUSTOM_EXTENSION_ERROR:",
+ })
+
+ // If the add callback returns zero, no extension should be
+ // added.
+ skipCustomExtension := expectedContents
+ if isClient {
+ // For the case where the client skips sending the
+ // custom extension, the server must not “echo†it.
+ skipCustomExtension = ""
+ }
+ testCases = append(testCases, testCase{
+ testType: testType,
+ name: "CustomExtensions-Skip-" + suffix,
+ config: Config{
+ Bugs: ProtocolBugs{
+ CustomExtension: skipCustomExtension,
+ ExpectedCustomExtension: &emptyString,
+ },
+ },
+ flags: []string{flag, "-custom-extension-skip"},
+ })
+ }
+
+ // The custom extension add callback should not be called if the client
+ // doesn't send the extension.
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "CustomExtensions-NotCalled-Server",
+ config: Config{
+ Bugs: ProtocolBugs{
+ ExpectedCustomExtension: &emptyString,
+ },
+ },
+ flags: []string{"-enable-server-custom-extension", "-custom-extension-fail-add"},
+ })
+
+ // Test an unknown extension from the server.
+ testCases = append(testCases, testCase{
+ testType: clientTest,
+ name: "UnknownExtension-Client",
+ config: Config{
+ Bugs: ProtocolBugs{
+ CustomExtension: expectedContents,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_EXTENSION:",
+ })
+}
+
+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()
for test := range c {
@@ -3449,11 +4733,11 @@ func worker(statusChan chan statusMsg, c chan *testCase, buildDir string, wg *sy
if *mallocTest < 0 {
statusChan <- statusMsg{test: test, started: true}
- err = runTest(test, buildDir, -1)
+ err = runTest(test, shimPath, -1)
} else {
for mallocNumToFail := int64(*mallocTest); ; mallocNumToFail++ {
statusChan <- statusMsg{test: test, started: true}
- if err = runTest(test, buildDir, mallocNumToFail); err != errMoreMallocs {
+ if err = runTest(test, shimPath, mallocNumToFail); err != errMoreMallocs {
if err != nil {
fmt.Printf("\n\nmalloc test failed at %d: %s\n", mallocNumToFail, err)
}
@@ -3515,12 +4799,10 @@ func statusPrinter(doneChan chan *testOutput, statusChan chan statusMsg, total i
}
func main() {
- var flagTest *string = flag.String("test", "", "The name of a test to run, or empty to run all tests")
- var flagNumWorkers *int = flag.Int("num-workers", runtime.NumCPU(), "The number of workers to run in parallel.")
- var flagBuildDir *string = flag.String("build-dir", "../../../build", "The build directory to run the shim from.")
-
flag.Parse()
+ *resourceDir = path.Clean(*resourceDir)
+ addBasicTests()
addCipherSuiteTests()
addBadECDSASignatureTests()
addCBCPaddingTests()
@@ -3529,17 +4811,19 @@ func main() {
addDDoSCallbackTests()
addVersionNegotiationTests()
addMinimumVersionTests()
- addD5BugTests()
addExtensionTests()
addResumptionVersionTests()
addExtendedMasterSecretTests()
addRenegotiationTests()
addDTLSReplayTests()
addSigningHashTests()
- addFastRadioPaddingTests()
addDTLSRetransmitTests()
addExportKeyingMaterialTests()
addTLSUniqueTests()
+ addCustomExtensionTests()
+ addRSAClientKeyExchangeTests()
+ addCurveTests()
+ addKeyExchangeInfoTests()
for _, async := range []bool{false, true} {
for _, splitHandshake := range []bool{false, true} {
for _, protocol := range []protocol{tls, dtls} {
@@ -3550,21 +4834,19 @@ func main() {
var wg sync.WaitGroup
- numWorkers := *flagNumWorkers
-
- statusChan := make(chan statusMsg, numWorkers)
- testChan := make(chan *testCase, numWorkers)
+ statusChan := make(chan statusMsg, *numWorkers)
+ testChan := make(chan *testCase, *numWorkers)
doneChan := make(chan *testOutput)
go statusPrinter(doneChan, statusChan, len(testCases))
- for i := 0; i < numWorkers; i++ {
+ for i := 0; i < *numWorkers; i++ {
wg.Add(1)
- go worker(statusChan, testChan, *flagBuildDir, &wg)
+ go worker(statusChan, testChan, *shimPath, &wg)
}
for i := range testCases {
- if len(*flagTest) == 0 || *flagTest == testCases[i].name {
+ if len(*testToRun) == 0 || *testToRun == testCases[i].name {
testChan <- &testCases[i]
}
}
diff --git a/src/ssl/test/runner/runner_test.go b/src/ssl/test/runner/runner_test.go
new file mode 100644
index 0000000..320ff52
--- /dev/null
+++ b/src/ssl/test/runner/runner_test.go
@@ -0,0 +1,7 @@
+package runner
+
+import "testing"
+
+func TestAll(t *testing.T) {
+ main()
+}
diff --git a/src/ssl/test/runner/test_output.go b/src/ssl/test/runner/test_output.go
index bcb7a93..2112092 100644
--- a/src/ssl/test/runner/test_output.go
+++ b/src/ssl/test/runner/test_output.go
@@ -12,7 +12,7 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
-package main
+package runner
import (
"encoding/json"
diff --git a/src/ssl/test/runner/ticket.go b/src/ssl/test/runner/ticket.go
index 8355822..e121c05 100644
--- a/src/ssl/test/runner/ticket.go
+++ b/src/ssl/test/runner/ticket.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package main
+package runner
import (
"bytes"
diff --git a/src/ssl/test/runner/tls.go b/src/ssl/test/runner/tls.go
index 6b637c8..24f9b1e 100644
--- a/src/ssl/test/runner/tls.go
+++ b/src/ssl/test/runner/tls.go
@@ -3,7 +3,7 @@
// license that can be found in the LICENSE file.
// Package tls partially implements TLS 1.2, as specified in RFC 5246.
-package main
+package runner
import (
"crypto"
diff --git a/src/ssl/test/test_config.cc b/src/ssl/test/test_config.cc
index 363b6f3..1cf316d 100644
--- a/src/ssl/test/test_config.cc
+++ b/src/ssl/test/test_config.cc
@@ -61,16 +61,12 @@ 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 },
- { "-allow-unsafe-legacy-renegotiation",
- &TestConfig::allow_unsafe_legacy_renegotiation },
{ "-enable-ocsp-stapling", &TestConfig::enable_ocsp_stapling },
{ "-enable-signed-cert-timestamps",
&TestConfig::enable_signed_cert_timestamps },
- { "-fastradio-padding", &TestConfig::fastradio_padding },
{ "-implicit-handshake", &TestConfig::implicit_handshake },
{ "-use-early-callback", &TestConfig::use_early_callback },
{ "-fail-early-callback", &TestConfig::fail_early_callback },
@@ -79,12 +75,33 @@ 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 },
- { "-reject-peer-renegotiations", &TestConfig::reject_peer_renegotiations },
- { "-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 },
+ { "-use-ticket-callback", &TestConfig::use_ticket_callback },
+ { "-renew-ticket", &TestConfig::renew_ticket },
+ { "-enable-client-custom-extension",
+ &TestConfig::enable_client_custom_extension },
+ { "-enable-server-custom-extension",
+ &TestConfig::enable_server_custom_extension },
+ { "-custom-extension-skip", &TestConfig::custom_extension_skip },
+ { "-custom-extension-fail-add", &TestConfig::custom_extension_fail_add },
+ { "-check-close-notify", &TestConfig::check_close_notify },
+ { "-shim-shuts-down", &TestConfig::shim_shuts_down },
+ { "-verify-fail", &TestConfig::verify_fail },
+ { "-verify-peer", &TestConfig::verify_peer },
+ { "-expect-verify-result", &TestConfig::expect_verify_result },
+ { "-renegotiate-once", &TestConfig::renegotiate_once },
+ { "-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[] = {
+ { "-digest-prefs", &TestConfig::digest_prefs },
{ "-key-file", &TestConfig::key_file },
{ "-cert-file", &TestConfig::cert_file },
{ "-expect-server-name", &TestConfig::expected_server_name },
@@ -101,6 +118,8 @@ const Flag<std::string> kStringFlags[] = {
{ "-psk-identity", &TestConfig::psk_identity },
{ "-srtp-profiles", &TestConfig::srtp_profiles },
{ "-cipher", &TestConfig::cipher },
+ { "-cipher-tls10", &TestConfig::cipher_tls10 },
+ { "-cipher-tls11", &TestConfig::cipher_tls11 },
{ "-export-label", &TestConfig::export_label },
{ "-export-context", &TestConfig::export_context },
};
@@ -111,6 +130,8 @@ const Flag<std::string> kBase64Flags[] = {
{ "-expect-ocsp-response", &TestConfig::expected_ocsp_response },
{ "-expect-signed-cert-timestamps",
&TestConfig::expected_signed_cert_timestamps },
+ { "-ocsp-response", &TestConfig::ocsp_response },
+ { "-signed-cert-timestamps", &TestConfig::signed_cert_timestamps },
};
const Flag<int> kIntFlags[] = {
@@ -119,6 +140,11 @@ const Flag<int> kIntFlags[] = {
{ "-max-version", &TestConfig::max_version },
{ "-mtu", &TestConfig::mtu },
{ "-export-keying-material", &TestConfig::export_keying_material },
+ { "-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 5d753c8..4e0a46a 100644
--- a/src/ssl/test/test_config.h
+++ b/src/ssl/test/test_config.h
@@ -24,6 +24,7 @@ struct TestConfig {
bool is_dtls = false;
bool resume = false;
bool fallback_scsv = false;
+ std::string digest_prefs;
std::string key_file;
std::string cert_file;
std::string expected_server_name;
@@ -44,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;
@@ -54,13 +54,11 @@ struct TestConfig {
bool expect_extended_master_secret = false;
std::string psk;
std::string psk_identity;
- bool allow_unsafe_legacy_renegotiation = false;
std::string srtp_profiles;
bool enable_ocsp_stapling = false;
std::string expected_ocsp_response;
bool enable_signed_cert_timestamps = false;
std::string expected_signed_cert_timestamps;
- bool fastradio_padding = false;
int min_version = 0;
int max_version = 0;
int mtu = 0;
@@ -71,14 +69,39 @@ struct TestConfig {
bool fail_ddos_callback = false;
bool fail_second_ddos_callback = false;
std::string cipher;
+ std::string cipher_tls10;
+ std::string cipher_tls11;
bool handshake_never_done = false;
int export_keying_material = 0;
std::string export_label;
std::string export_context;
bool use_export_context = false;
- bool reject_peer_renegotiations = false;
- bool no_legacy_server_connect = false;
bool tls_unique = false;
+ bool expect_ticket_renewal = false;
+ bool expect_no_session = false;
+ bool use_ticket_callback = false;
+ bool renew_ticket = false;
+ bool enable_client_custom_extension = false;
+ bool enable_server_custom_extension = false;
+ bool custom_extension_skip = false;
+ bool custom_extension_fail_add = false;
+ std::string ocsp_response;
+ bool check_close_notify = false;
+ bool shim_shuts_down = false;
+ bool verify_fail = false;
+ bool verify_peer = false;
+ bool expect_verify_result = false;
+ std::string signed_cert_timestamps;
+ int expect_total_renegotiations = 0;
+ bool renegotiate_once = false;
+ bool renegotiate_freely = false;
+ 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
new file mode 100644
index 0000000..3381eae
--- /dev/null
+++ b/src/ssl/tls_record.c
@@ -0,0 +1,342 @@
+/* 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.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com). */
+
+#include <openssl/ssl.h>
+
+#include <assert.h>
+
+#include <openssl/bytestring.h>
+#include <openssl/err.h>
+
+#include "internal.h"
+
+
+/* kMaxEmptyRecords is the number of consecutive, empty records that will be
+ * processed. Without this limit an attacker could send empty records at a
+ * faster rate than we can process and cause record processing to loop
+ * forever. */
+static const uint8_t kMaxEmptyRecords = 32;
+
+/* 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) {
+ if (SSL_IS_DTLS(ssl)) {
+ return DTLS1_RT_HEADER_LENGTH +
+ SSL_AEAD_CTX_explicit_nonce_len(ssl->aead_read_ctx);
+ } else {
+ return SSL3_RT_HEADER_LENGTH +
+ SSL_AEAD_CTX_explicit_nonce_len(ssl->aead_read_ctx);
+ }
+}
+
+size_t ssl_seal_prefix_len(const SSL *ssl) {
+ if (SSL_IS_DTLS(ssl)) {
+ return DTLS1_RT_HEADER_LENGTH +
+ SSL_AEAD_CTX_explicit_nonce_len(ssl->aead_write_ctx);
+ } else {
+ size_t ret = SSL3_RT_HEADER_LENGTH +
+ SSL_AEAD_CTX_explicit_nonce_len(ssl->aead_write_ctx);
+ if (ssl_needs_record_splitting(ssl)) {
+ ret += SSL3_RT_HEADER_LENGTH;
+ ret += ssl_cipher_get_record_split_len(ssl->aead_write_ctx->cipher);
+ }
+ return ret;
+ }
+}
+
+size_t ssl_max_seal_overhead(const SSL *ssl) {
+ if (SSL_IS_DTLS(ssl)) {
+ return DTLS1_RT_HEADER_LENGTH +
+ SSL_AEAD_CTX_max_overhead(ssl->aead_write_ctx);
+ } else {
+ size_t ret = SSL3_RT_HEADER_LENGTH +
+ SSL_AEAD_CTX_max_overhead(ssl->aead_write_ctx);
+ if (ssl_needs_record_splitting(ssl)) {
+ ret *= 2;
+ }
+ return ret;
+ }
+}
+
+enum ssl_open_record_t tls_open_record(
+ SSL *ssl, uint8_t *out_type, uint8_t *out, size_t *out_len,
+ size_t *out_consumed, uint8_t *out_alert, size_t max_out, const uint8_t *in,
+ size_t in_len) {
+ CBS cbs;
+ CBS_init(&cbs, in, in_len);
+
+ /* Decode the record header. */
+ uint8_t type;
+ uint16_t version, ciphertext_len;
+ if (!CBS_get_u8(&cbs, &type) ||
+ !CBS_get_u16(&cbs, &version) ||
+ !CBS_get_u16(&cbs, &ciphertext_len)) {
+ *out_consumed = SSL3_RT_HEADER_LENGTH;
+ return ssl_open_record_partial;
+ }
+
+ /* Check the version. */
+ if ((ssl->s3->have_version && version != ssl->version) ||
+ (version >> 8) != SSL3_VERSION_MAJOR) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_VERSION_NUMBER);
+ *out_alert = SSL_AD_PROTOCOL_VERSION;
+ return ssl_open_record_error;
+ }
+
+ /* Check the ciphertext length. */
+ 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;
+ }
+
+ /* Extract the body. */
+ CBS body;
+ if (!CBS_get_bytes(&cbs, &body, ciphertext_len)) {
+ *out_consumed = SSL3_RT_HEADER_LENGTH + (size_t)ciphertext_len;
+ return ssl_open_record_partial;
+ }
+
+ if (ssl->msg_callback != NULL) {
+ ssl->msg_callback(0 /* read */, 0, SSL3_RT_HEADER, in,
+ SSL3_RT_HEADER_LENGTH, ssl, ssl->msg_callback_arg);
+ }
+
+ /* Decrypt the body. */
+ size_t plaintext_len;
+ if (!SSL_AEAD_CTX_open(ssl->aead_read_ctx, out, &plaintext_len, max_out,
+ type, version, ssl->s3->read_sequence, CBS_data(&body),
+ CBS_len(&body))) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
+ *out_alert = SSL_AD_BAD_RECORD_MAC;
+ return ssl_open_record_error;
+ }
+ if (!ssl3_record_sequence_update(ssl->s3->read_sequence, 8)) {
+ *out_alert = SSL_AD_INTERNAL_ERROR;
+ return ssl_open_record_error;
+ }
+
+ /* Check the plaintext length. */
+ 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;
+ }
+
+ /* Limit the number of consecutive empty records. */
+ if (plaintext_len == 0) {
+ ssl->s3->empty_record_count++;
+ if (ssl->s3->empty_record_count > kMaxEmptyRecords) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_EMPTY_FRAGMENTS);
+ *out_alert = SSL_AD_UNEXPECTED_MESSAGE;
+ return ssl_open_record_error;
+ }
+ /* Apart from the limit, empty records are returned up to the caller. This
+ * allows the caller to reject records of the wrong type. */
+ } else {
+ ssl->s3->empty_record_count = 0;
+ }
+
+ *out_type = type;
+ *out_len = plaintext_len;
+ *out_consumed = in_len - CBS_len(&cbs);
+ return ssl_open_record_success;
+}
+
+static int do_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) {
+ if (max_out < SSL3_RT_HEADER_LENGTH) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+ /* Check the record header does not alias any part of the input.
+ * |SSL_AEAD_CTX_seal| will internally enforce other aliasing requirements. */
+ if (in < out + SSL3_RT_HEADER_LENGTH && out < in + in_len) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT);
+ return 0;
+ }
+
+ out[0] = type;
+
+ /* Some servers hang if initial ClientHello is larger than 256 bytes and
+ * record version number > TLS 1.0. */
+ uint16_t wire_version = ssl->version;
+ if (!ssl->s3->have_version && ssl->version > SSL3_VERSION) {
+ wire_version = TLS1_VERSION;
+ }
+ out[1] = wire_version >> 8;
+ out[2] = wire_version & 0xff;
+
+ size_t ciphertext_len;
+ if (!SSL_AEAD_CTX_seal(ssl->aead_write_ctx, out + SSL3_RT_HEADER_LENGTH,
+ &ciphertext_len, max_out - SSL3_RT_HEADER_LENGTH,
+ type, wire_version, ssl->s3->write_sequence, in,
+ in_len) ||
+ !ssl3_record_sequence_update(ssl->s3->write_sequence, 8)) {
+ return 0;
+ }
+
+ if (ciphertext_len >= 1 << 16) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ return 0;
+ }
+ out[3] = ciphertext_len >> 8;
+ out[4] = ciphertext_len & 0xff;
+
+ *out_len = SSL3_RT_HEADER_LENGTH + ciphertext_len;
+
+ if (ssl->msg_callback) {
+ ssl->msg_callback(1 /* write */, 0, SSL3_RT_HEADER, out,
+ SSL3_RT_HEADER_LENGTH, ssl, ssl->msg_callback_arg);
+ }
+
+ return 1;
+}
+
+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 (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) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT);
+ return 0;
+ }
+ /* Ensure |do_seal_record| does not write beyond |in[0]|. */
+ size_t frag_max_out = max_out;
+ if (out <= in + 1 && in + 1 < out + frag_max_out) {
+ frag_max_out = (size_t)(in + 1 - out);
+ }
+ if (!do_seal_record(ssl, out, &frag_len, frag_max_out, type, in, 1)) {
+ return 0;
+ }
+ in++;
+ in_len--;
+ out += frag_len;
+ max_out -= frag_len;
+
+ assert(SSL3_RT_HEADER_LENGTH +
+ ssl_cipher_get_record_split_len(ssl->aead_write_ctx->cipher) ==
+ frag_len);
+ }
+
+ if (!do_seal_record(ssl, out, out_len, max_out, type, in, in_len)) {
+ return 0;
+ }
+ *out_len += frag_len;
+ return 1;
+}
diff --git a/src/tool/CMakeLists.txt b/src/tool/CMakeLists.txt
index 74c1ac8..f0af283 100644
--- a/src/tool/CMakeLists.txt
+++ b/src/tool/CMakeLists.txt
@@ -4,9 +4,12 @@ add_executable(
bssl
args.cc
+ ciphers.cc
client.cc
const.cc
digest.cc
+ generate_ed25519.cc
+ genrsa.cc
pkcs12.cc
rand.cc
server.cc
@@ -18,5 +21,10 @@ add_executable(
if (APPLE OR WIN32 OR ANDROID)
target_link_libraries(bssl ssl crypto)
else()
- target_link_libraries(bssl ssl crypto -lrt)
+ find_library(FOUND_LIBRT rt)
+ if (FOUND_LIBRT)
+ target_link_libraries(bssl ssl crypto -lrt)
+ else()
+ target_link_libraries(bssl ssl crypto)
+ endif()
endif()
diff --git a/src/tool/args.cc b/src/tool/args.cc
index a164476..9ec18a3 100644
--- a/src/tool/args.cc
+++ b/src/tool/args.cc
@@ -15,7 +15,9 @@
#include <string>
#include <vector>
+#include <limits.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "internal.h"
@@ -75,3 +77,28 @@ void PrintUsage(const struct argument *templates) {
fprintf(stderr, "%s\t%s\n", templ->name, templ->description);
}
}
+
+bool GetUnsigned(unsigned *out, const std::string &arg_name,
+ unsigned default_value,
+ const std::map<std::string, std::string> &args) {
+ const auto &it = args.find(arg_name);
+ if (it == args.end()) {
+ *out = default_value;
+ return true;
+ }
+
+ const std::string &value = it->second;
+ if (value.empty()) {
+ return false;
+ }
+
+ char *endptr;
+ unsigned long int num = strtoul(value.c_str(), &endptr, 10);
+ if (*endptr ||
+ num > UINT_MAX) {
+ return false;
+ }
+
+ *out = num;
+ return true;
+}
diff --git a/src/tool/ciphers.cc b/src/tool/ciphers.cc
new file mode 100644
index 0000000..d7cc36b
--- /dev/null
+++ b/src/tool/ciphers.cc
@@ -0,0 +1,66 @@
+/* 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 <string>
+#include <vector>
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <openssl/ssl.h>
+
+#include "../crypto/test/scoped_types.h"
+#include "../ssl/test/scoped_types.h"
+#include "internal.h"
+
+
+bool Ciphers(const std::vector<std::string> &args) {
+ if (args.size() != 1) {
+ fprintf(stderr, "Usage: bssl ciphers <cipher suite string>\n");
+ return false;
+ }
+
+ const std::string &ciphers_string = args.back();
+
+ ScopedSSL_CTX ctx(SSL_CTX_new(SSLv23_client_method()));
+ if (!SSL_CTX_set_cipher_list(ctx.get(), ciphers_string.c_str())) {
+ fprintf(stderr, "Failed to parse cipher suite config.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ const struct ssl_cipher_preference_list_st *pref_list = ctx->cipher_list;
+ STACK_OF(SSL_CIPHER) *ciphers = pref_list->ciphers;
+
+ bool last_in_group = false;
+ for (size_t i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
+ bool in_group = pref_list->in_group_flags[i];
+ const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
+
+ if (in_group && !last_in_group) {
+ printf("[\n ");
+ } else if (last_in_group) {
+ printf(" ");
+ }
+
+ printf("%s\n", SSL_CIPHER_get_name(cipher));
+
+ if (!in_group && last_in_group) {
+ printf("]\n");
+ }
+ last_in_group = in_group;
+ }
+
+ return true;
+}
diff --git a/src/tool/client.cc b/src/tool/client.cc
index 1de0df2..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>
@@ -70,6 +72,20 @@ static const struct argument kArguments[] = {
"The key to use for signing a channel ID",
},
{
+ "-false-start", kBooleanArgument,
+ "Enable False Start",
+ },
+ { "-session-in", kOptionalArgument,
+ "A file containing a session to resume.",
+ },
+ { "-session-out", kOptionalArgument,
+ "A file to write the negotiated session to.",
+ },
+ {
+ "-key", kOptionalArgument,
+ "Private-key file to use (default is no client certificate)",
+ },
+ {
"", kOptionalArgument, "",
},
};
@@ -109,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;
@@ -125,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 &&
@@ -211,7 +234,22 @@ bool Client(const std::vector<std::string> &args) {
if (!pkey || !SSL_CTX_set1_tls_channel_id(ctx.get(), pkey.get())) {
return false;
}
- ctx->tlsext_channel_id_enabled_new = 1;
+ }
+
+ if (args_map.count("-false-start") != 0) {
+ 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;
@@ -226,6 +264,23 @@ bool Client(const std::vector<std::string> &args) {
SSL_set_tlsext_host_name(ssl.get(), args_map["-server-name"].c_str());
}
+ if (args_map.count("-session-in") != 0) {
+ ScopedBIO in(BIO_new_file(args_map["-session-in"].c_str(), "rb"));
+ if (!in) {
+ fprintf(stderr, "Error reading session\n");
+ ERR_print_errors_cb(PrintErrorCallback, stderr);
+ return false;
+ }
+ ScopedSSL_SESSION session(PEM_read_bio_SSL_SESSION(in.get(), nullptr,
+ nullptr, nullptr));
+ if (!session) {
+ fprintf(stderr, "Error reading session\n");
+ ERR_print_errors_cb(PrintErrorCallback, stderr);
+ return false;
+ }
+ SSL_set_session(ssl.get(), session.get());
+ }
+
SSL_set_bio(ssl.get(), bio.get(), bio.get());
bio.release();
@@ -240,6 +295,16 @@ bool Client(const std::vector<std::string> &args) {
fprintf(stderr, "Connected.\n");
PrintConnectionInfo(ssl.get());
+ if (args_map.count("-session-out") != 0) {
+ ScopedBIO out(BIO_new_file(args_map["-session-out"].c_str(), "wb"));
+ if (!out ||
+ !PEM_write_bio_SSL_SESSION(out.get(), SSL_get0_session(ssl.get()))) {
+ fprintf(stderr, "Error while saving session:\n");
+ ERR_print_errors_cb(PrintErrorCallback, stderr);
+ return false;
+ }
+ }
+
bool ok = TransferData(ssl.get(), sock);
return ok;
diff --git a/src/tool/const.cc b/src/tool/const.cc
index 5222667..7b7001e 100644
--- a/src/tool/const.cc
+++ b/src/tool/const.cc
@@ -15,9 +15,10 @@
#include <stddef.h>
#include <stdint.h>
-extern "C" {
+#include "internal.h"
-uint8_t kDERRSAPrivate2048[] = {
+
+const uint8_t kDERRSAPrivate2048[] = {
0x30, 0x82, 0x04, 0xa3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00,
0xd0, 0x02, 0xde, 0x5d, 0x19, 0x33, 0x48, 0x15, 0xc7, 0x86, 0xde, 0xa3,
0xec, 0x63, 0x89, 0x14, 0x63, 0x99, 0x30, 0x1f, 0x5d, 0x25, 0xb2, 0xfa,
@@ -120,9 +121,9 @@ uint8_t kDERRSAPrivate2048[] = {
0x77, 0xe6, 0xd3,
};
-size_t kDERRSAPrivate2048Len = sizeof(kDERRSAPrivate2048);
+const size_t kDERRSAPrivate2048Len = sizeof(kDERRSAPrivate2048);
-uint8_t kDERRSAPrivate4096[] = {
+const uint8_t kDERRSAPrivate4096[] = {
0x30, 0x82, 0x09, 0x28, 0x02, 0x01, 0x00, 0x02, 0x82, 0x02, 0x01, 0x00,
0xc3, 0x82, 0x01, 0xda, 0x03, 0xe1, 0x0d, 0x78, 0xf4, 0x86, 0xf1, 0x28,
0xf0, 0x4c, 0x34, 0xa6, 0x73, 0x0c, 0xfb, 0x22, 0xfa, 0x35, 0xc9, 0x3a,
@@ -321,6 +322,113 @@ uint8_t kDERRSAPrivate4096[] = {
0x59, 0x8e, 0xd7, 0x45, 0x87, 0x86, 0x05, 0x9d,
};
-size_t kDERRSAPrivate4096Len = sizeof(kDERRSAPrivate4096);
+const size_t kDERRSAPrivate4096Len = sizeof(kDERRSAPrivate4096);
+
+const uint8_t kDERRSAPrivate3Prime2048[] = {
+ 0x30, 0x82, 0x04, 0xd7, 0x02, 0x01, 0x01, 0x02, 0x82, 0x01, 0x00, 0x62,
+ 0x91, 0xe9, 0xea, 0xb3, 0x5d, 0x6c, 0x29, 0xae, 0x21, 0x83, 0xbb, 0xb5,
+ 0x82, 0xb1, 0x9e, 0xea, 0xe0, 0x64, 0x5b, 0x1e, 0x2f, 0x5e, 0x2c, 0x0a,
+ 0x80, 0x3d, 0x29, 0xd4, 0xfa, 0x9a, 0xe7, 0x44, 0xe6, 0x21, 0xbd, 0x98,
+ 0xc0, 0x3d, 0xe0, 0x53, 0x59, 0xae, 0xd3, 0x3e, 0xfe, 0xc4, 0xc2, 0xc4,
+ 0x5a, 0x5a, 0x89, 0x07, 0xf4, 0x4f, 0xdc, 0xb0, 0x6a, 0xd4, 0x3e, 0x99,
+ 0x7d, 0x7a, 0x97, 0x26, 0x4e, 0xe1, 0x93, 0xca, 0x6e, 0xed, 0x07, 0xfc,
+ 0xb4, 0xfa, 0x95, 0x1e, 0x73, 0x7b, 0x86, 0x08, 0x6a, 0xb9, 0xd4, 0x29,
+ 0xb0, 0x7e, 0x59, 0xb7, 0x9d, 0x7b, 0xeb, 0x67, 0x6e, 0xf0, 0xbb, 0x5e,
+ 0xcf, 0xb9, 0xcd, 0x58, 0x93, 0xf0, 0xe7, 0x88, 0x17, 0x6c, 0x0d, 0x76,
+ 0x1e, 0xb9, 0x27, 0x9a, 0x4d, 0x02, 0x16, 0xb6, 0x49, 0x6d, 0xa7, 0x83,
+ 0x23, 0x4d, 0x02, 0x48, 0x0c, 0x0c, 0x1f, 0x0e, 0x85, 0x21, 0xe3, 0x06,
+ 0x76, 0x0a, 0x73, 0xe6, 0xc1, 0x21, 0xfa, 0x30, 0x18, 0x78, 0x29, 0x5c,
+ 0x31, 0xd0, 0x29, 0xae, 0x6f, 0x7d, 0x87, 0xd8, 0x2f, 0x16, 0xfa, 0xbc,
+ 0x67, 0x8a, 0x94, 0x71, 0x59, 0x9b, 0xec, 0x22, 0x40, 0x55, 0x9f, 0xc2,
+ 0x94, 0xb5, 0xbd, 0x78, 0x01, 0xc9, 0xef, 0x18, 0xc8, 0x6d, 0x0d, 0xdc,
+ 0x53, 0x42, 0xb2, 0x5c, 0xab, 0x65, 0x05, 0xbd, 0x35, 0x08, 0x85, 0x1b,
+ 0xf8, 0xe9, 0x47, 0xbc, 0xfe, 0xc5, 0xae, 0x47, 0x29, 0x63, 0x44, 0x8e,
+ 0x4d, 0xb7, 0x47, 0xab, 0x0d, 0xd8, 0x76, 0x68, 0x4f, 0xc7, 0x07, 0x02,
+ 0xe4, 0x86, 0xb0, 0xcf, 0xd8, 0x19, 0xad, 0xf4, 0x85, 0x76, 0x8b, 0x3b,
+ 0x4e, 0x40, 0x8d, 0x29, 0x7a, 0x8a, 0x07, 0x36, 0xf3, 0x78, 0xae, 0x17,
+ 0xa6, 0x8f, 0x53, 0x58, 0x65, 0x4c, 0x86, 0x9e, 0xd7, 0x8b, 0xec, 0x38,
+ 0x4f, 0x99, 0xc7, 0x02, 0x01, 0x03, 0x02, 0x82, 0x01, 0x00, 0x41, 0xb6,
+ 0x9b, 0xf1, 0xcc, 0xe8, 0xf2, 0xc6, 0x74, 0x16, 0x57, 0xd2, 0x79, 0x01,
+ 0xcb, 0xbf, 0x47, 0x40, 0x42, 0xe7, 0x69, 0x74, 0xe9, 0x72, 0xb1, 0xaa,
+ 0xd3, 0x71, 0x38, 0xa7, 0x11, 0xef, 0x83, 0x44, 0x16, 0x7e, 0x65, 0xd5,
+ 0x7e, 0x95, 0x8c, 0xe6, 0x74, 0x8c, 0xd4, 0xa9, 0xd8, 0x81, 0xd8, 0x3c,
+ 0x3c, 0x5b, 0x5a, 0xa2, 0xdf, 0xe8, 0x75, 0x9c, 0x8d, 0x7f, 0x10, 0xfe,
+ 0x51, 0xba, 0x19, 0x89, 0xeb, 0xb7, 0xdc, 0x49, 0xf3, 0x5a, 0xa8, 0x78,
+ 0xa7, 0x0e, 0x14, 0x4c, 0xfd, 0x04, 0x05, 0x9c, 0x7b, 0xe2, 0xc5, 0xa3,
+ 0x04, 0xee, 0xd9, 0x4c, 0xfd, 0x7d, 0x47, 0xb0, 0x0d, 0x9b, 0x3d, 0x70,
+ 0x91, 0x81, 0x2c, 0xab, 0x2b, 0x87, 0xad, 0x11, 0x68, 0x24, 0xfc, 0x2b,
+ 0xd4, 0xee, 0x5e, 0x28, 0xeb, 0x6d, 0xab, 0xde, 0x0f, 0x77, 0x15, 0x58,
+ 0x76, 0x39, 0xc9, 0x59, 0x3a, 0x7f, 0x19, 0x9d, 0xc6, 0x7e, 0x86, 0xe4,
+ 0xd5, 0x38, 0x70, 0x9e, 0xae, 0xb9, 0xfb, 0x33, 0x33, 0xd1, 0x0c, 0x2d,
+ 0xab, 0x01, 0x20, 0xe1, 0x8b, 0x29, 0x99, 0xd3, 0xeb, 0x87, 0x05, 0x72,
+ 0xaa, 0x43, 0x58, 0x64, 0x8e, 0x9e, 0x31, 0xdb, 0x45, 0x9b, 0x2b, 0xac,
+ 0x58, 0x80, 0x5d, 0x33, 0xa2, 0x43, 0x05, 0x96, 0xcc, 0xca, 0x2d, 0x04,
+ 0x5f, 0xd6, 0xb7, 0x3d, 0x8b, 0x8f, 0x2d, 0xa3, 0xa5, 0xf8, 0x73, 0xf5,
+ 0xd7, 0xc0, 0x19, 0xff, 0x10, 0xe6, 0xee, 0x3a, 0x26, 0x2f, 0xe1, 0x64,
+ 0x3d, 0x11, 0xcd, 0x2d, 0xe4, 0x0a, 0x84, 0x27, 0xe3, 0xcb, 0x16, 0x62,
+ 0x19, 0xe7, 0xe3, 0x0d, 0x13, 0xe8, 0x09, 0x5a, 0x53, 0xd0, 0x20, 0x56,
+ 0x15, 0xf5, 0xb3, 0x67, 0xac, 0xa1, 0xb5, 0x94, 0x6b, 0xab, 0xdc, 0x71,
+ 0xc7, 0xbf, 0x0a, 0xde, 0x76, 0xf5, 0x03, 0xa0, 0x30, 0xd8, 0x27, 0x9d,
+ 0x00, 0x2b, 0x02, 0x57, 0x00, 0xf1, 0x4f, 0xc2, 0x86, 0x13, 0x06, 0x17,
+ 0xf7, 0x69, 0x7e, 0x37, 0xdf, 0x67, 0xc5, 0x32, 0xa0, 0x74, 0x1c, 0x32,
+ 0x69, 0x0f, 0x9f, 0x08, 0x88, 0x24, 0xb1, 0x51, 0xbc, 0xbc, 0x92, 0xba,
+ 0x73, 0x1f, 0x9c, 0x75, 0xc2, 0x14, 0x6d, 0x4f, 0xc4, 0x5a, 0xcf, 0xda,
+ 0x44, 0x35, 0x00, 0x6b, 0x42, 0x3b, 0x9f, 0x14, 0xf1, 0x05, 0xb3, 0x51,
+ 0x22, 0xb6, 0xbe, 0x9c, 0xe0, 0xc1, 0x5c, 0x48, 0x61, 0xdf, 0x4e, 0x4c,
+ 0x72, 0xb8, 0x05, 0x35, 0x7c, 0xac, 0xf1, 0xbb, 0xa0, 0x3b, 0x2a, 0xea,
+ 0xf7, 0x86, 0xe9, 0xd2, 0xff, 0x1e, 0x1d, 0x02, 0x56, 0x00, 0xca, 0xb1,
+ 0x39, 0xf6, 0xa2, 0xc6, 0x3b, 0x65, 0x45, 0x2f, 0x39, 0x00, 0xcd, 0x6e,
+ 0xd6, 0x55, 0xf7, 0x71, 0x37, 0x89, 0xc2, 0xe7, 0x7a, 0xc0, 0x1a, 0xa6,
+ 0x2f, 0xea, 0x17, 0x7c, 0xaa, 0x2a, 0x91, 0x8f, 0xd4, 0xc7, 0x50, 0x8b,
+ 0xab, 0x8e, 0x99, 0x3b, 0x33, 0x91, 0xbc, 0x02, 0x10, 0x58, 0x4b, 0x58,
+ 0x40, 0x9b, 0xc4, 0x8f, 0x48, 0x2b, 0xa7, 0x44, 0xfd, 0x07, 0x04, 0xf0,
+ 0x98, 0x67, 0x56, 0xea, 0x25, 0x92, 0x8b, 0x2e, 0x4b, 0x4a, 0xa1, 0xd3,
+ 0xc2, 0xa4, 0xb4, 0x9b, 0x59, 0x70, 0x32, 0xa6, 0xd8, 0x8b, 0xd9, 0x02,
+ 0x57, 0x00, 0xa0, 0xdf, 0xd7, 0x04, 0x0c, 0xae, 0xba, 0xa4, 0xf0, 0xfe,
+ 0xcf, 0xea, 0x45, 0x2e, 0x21, 0xc0, 0x4d, 0x68, 0x21, 0x9b, 0x5f, 0xbf,
+ 0x5b, 0x05, 0x6d, 0xcb, 0x8b, 0xd3, 0x28, 0x61, 0xd1, 0xa2, 0x15, 0x12,
+ 0xf9, 0x2c, 0x0d, 0x9e, 0x35, 0x2d, 0x91, 0xdf, 0xe6, 0xd8, 0x23, 0x55,
+ 0x9c, 0xd6, 0xd2, 0x6a, 0x0d, 0xf6, 0x03, 0xcc, 0xe0, 0xc1, 0xcf, 0x29,
+ 0xbd, 0xeb, 0x2b, 0x92, 0xda, 0xeb, 0xea, 0x34, 0x32, 0xf7, 0x25, 0x58,
+ 0xce, 0x53, 0x1d, 0xf6, 0x7d, 0x15, 0x7c, 0xc7, 0x47, 0x4f, 0xaf, 0x46,
+ 0x8c, 0xaa, 0x14, 0x13, 0x02, 0x56, 0x00, 0x87, 0x20, 0xd1, 0x4f, 0x17,
+ 0x2e, 0xd2, 0x43, 0x83, 0x74, 0xd0, 0xab, 0x33, 0x9f, 0x39, 0x8e, 0xa4,
+ 0xf6, 0x25, 0x06, 0x81, 0xef, 0xa7, 0x2a, 0xbc, 0x6e, 0xca, 0x9c, 0x0f,
+ 0xa8, 0x71, 0x71, 0xb6, 0x5f, 0xe3, 0x2f, 0x8b, 0x07, 0xc7, 0xb4, 0x66,
+ 0x27, 0x77, 0xb6, 0x7d, 0x56, 0xb5, 0x90, 0x32, 0x3a, 0xd5, 0xbd, 0x2d,
+ 0xb4, 0xda, 0xc7, 0xc4, 0xd8, 0xa8, 0xaf, 0x58, 0xa0, 0x65, 0x9a, 0x39,
+ 0xf1, 0x6e, 0x61, 0xb2, 0x1e, 0xdc, 0xdc, 0x6b, 0xe2, 0x81, 0xc3, 0x23,
+ 0x12, 0x3b, 0xa0, 0x21, 0xc4, 0x90, 0x5d, 0x3b, 0x02, 0x57, 0x00, 0xe6,
+ 0x8a, 0xaa, 0xb8, 0x6d, 0x2c, 0x81, 0x43, 0xb5, 0xd6, 0xa0, 0x2b, 0x42,
+ 0x49, 0xa9, 0x0a, 0x51, 0xfa, 0x18, 0xc8, 0x32, 0xea, 0x54, 0x18, 0xf3,
+ 0x60, 0xc2, 0xb5, 0x4a, 0x43, 0x05, 0x93, 0x9c, 0x01, 0xd9, 0x28, 0xed,
+ 0x73, 0xfa, 0x82, 0xbc, 0x12, 0x64, 0xcb, 0xc4, 0x24, 0xa9, 0x3e, 0xae,
+ 0x7c, 0x4b, 0x8f, 0x94, 0x57, 0x7b, 0x14, 0x10, 0x41, 0xdc, 0x62, 0x12,
+ 0x8c, 0xb2, 0x4a, 0x7c, 0xf6, 0x53, 0xd4, 0xc6, 0xe4, 0xda, 0xd1, 0xa2,
+ 0x00, 0x0e, 0x3d, 0x30, 0xf7, 0x05, 0x4f, 0x1d, 0x82, 0xbc, 0x52, 0xd9,
+ 0xb1, 0x30, 0x82, 0x01, 0x0a, 0x30, 0x82, 0x01, 0x06, 0x02, 0x56, 0x00,
+ 0x84, 0x12, 0x4f, 0xf7, 0x3b, 0x65, 0x53, 0x34, 0x6c, 0x6c, 0x4d, 0x77,
+ 0xdf, 0xfd, 0x1f, 0xb6, 0x16, 0xe2, 0x25, 0x15, 0xca, 0xc9, 0xc1, 0x41,
+ 0x9a, 0x50, 0xda, 0xeb, 0x88, 0x4f, 0x3d, 0xb3, 0x01, 0x00, 0x44, 0xc4,
+ 0xac, 0xe7, 0x14, 0x62, 0xa6, 0x56, 0xde, 0xc5, 0xb7, 0xc3, 0x1d, 0x07,
+ 0xbd, 0x7d, 0x64, 0xc5, 0x7e, 0x45, 0x25, 0x56, 0xed, 0x7a, 0xd2, 0x14,
+ 0xdb, 0x4e, 0x27, 0xd4, 0x1f, 0xf8, 0x94, 0xa7, 0xef, 0x07, 0xce, 0xdb,
+ 0x24, 0xb7, 0xdd, 0x71, 0x5c, 0x63, 0xc9, 0x33, 0xfe, 0xde, 0x40, 0x52,
+ 0xeb, 0x02, 0x55, 0x58, 0x0c, 0x35, 0x4f, 0x7c, 0xee, 0x37, 0x78, 0x48,
+ 0x48, 0x33, 0xa5, 0x3f, 0xfe, 0x15, 0x24, 0x0f, 0x41, 0x6e, 0x0e, 0x87,
+ 0x31, 0x2b, 0x81, 0x11, 0x8b, 0x3c, 0x9d, 0x05, 0x8a, 0x29, 0x22, 0x00,
+ 0xaa, 0xd8, 0x83, 0x1d, 0xef, 0x62, 0xec, 0x6e, 0xe4, 0x94, 0x83, 0xcf,
+ 0xd7, 0x68, 0xaf, 0xd3, 0xa8, 0xed, 0xd8, 0xfe, 0xd8, 0xc3, 0x8f, 0x48,
+ 0xfc, 0x8c, 0x0d, 0xe7, 0x89, 0x6f, 0xe2, 0xbf, 0xfb, 0x0d, 0xc5, 0x4a,
+ 0x05, 0x34, 0x92, 0x18, 0x7a, 0x93, 0xa0, 0xe8, 0x42, 0x86, 0x22, 0xa9,
+ 0xe9, 0x80, 0x37, 0x47, 0x02, 0x55, 0x60, 0x76, 0xab, 0xde, 0x2b, 0xf5,
+ 0xa2, 0x2c, 0xaa, 0x0c, 0x99, 0x81, 0xee, 0x72, 0x2c, 0x7d, 0x22, 0x59,
+ 0x2a, 0x35, 0xea, 0x50, 0x4e, 0x47, 0x6b, 0x92, 0x2d, 0x30, 0xa1, 0x01,
+ 0xa5, 0x9e, 0x26, 0x6e, 0x27, 0xca, 0xf5, 0xf2, 0x87, 0x5d, 0x31, 0xaf,
+ 0xe9, 0x32, 0xcd, 0x10, 0xfd, 0x4d, 0xdb, 0xf9, 0x86, 0x05, 0x12, 0x1b,
+ 0x01, 0x84, 0x55, 0x97, 0x5f, 0xe2, 0x78, 0x27, 0xd9, 0xe4, 0x26, 0x7d,
+ 0xab, 0x0e, 0xe0, 0x1b, 0x6f, 0xcb, 0x4b, 0x14, 0xdd, 0xdc, 0xdc, 0x8b,
+ 0xe8, 0x9f, 0xd0, 0x62, 0x96, 0xca, 0xcf,
+};
-}
+const size_t kDERRSAPrivate3Prime2048Len = sizeof(kDERRSAPrivate3Prime2048);
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/genrsa.cc b/src/tool/genrsa.cc
new file mode 100644
index 0000000..4b39401
--- /dev/null
+++ b/src/tool/genrsa.cc
@@ -0,0 +1,69 @@
+/* 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/bio.h>
+#include <openssl/bn.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/rsa.h>
+
+#include "../crypto/test/scoped_types.h"
+#include "internal.h"
+
+
+static const struct argument kArguments[] = {
+ {
+ "-nprimes", kOptionalArgument,
+ "The number of primes to generate (default: 2)",
+ },
+ {
+ "-bits", kOptionalArgument,
+ "The number of bits in the modulus (default: 2048)",
+ },
+ {
+ "", kOptionalArgument, "",
+ },
+};
+
+bool GenerateRSAKey(const std::vector<std::string> &args) {
+ std::map<std::string, std::string> args_map;
+
+ if (!ParseKeyValueArguments(&args_map, args, kArguments)) {
+ PrintUsage(kArguments);
+ return false;
+ }
+
+ unsigned bits, nprimes = 0;
+ if (!GetUnsigned(&bits, "-bits", 2048, args_map) ||
+ !GetUnsigned(&nprimes, "-nprimes", 2, args_map)) {
+ PrintUsage(kArguments);
+ return false;
+ }
+
+ ScopedRSA rsa(RSA_new());
+ ScopedBIGNUM e(BN_new());
+ ScopedBIO bio(BIO_new_fp(stdout, BIO_NOCLOSE));
+
+ if (!BN_set_word(e.get(), RSA_F4) ||
+ !RSA_generate_multi_prime_key(rsa.get(), bits, nprimes, e.get(), NULL) ||
+ !PEM_write_bio_RSAPrivateKey(bio.get(), rsa.get(), NULL /* cipher */,
+ NULL /* key */, 0 /* key len */,
+ NULL /* password callback */,
+ NULL /* callback arg */)) {
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/tool/internal.h b/src/tool/internal.h
index 277d099..84f8c4d 100644
--- a/src/tool/internal.h
+++ b/src/tool/internal.h
@@ -15,6 +15,8 @@
#ifndef OPENSSL_HEADER_TOOL_INTERNAL_H
#define OPENSSL_HEADER_TOOL_INTERNAL_H
+#include <openssl/base.h>
+
#include <string>
#include <vector>
@@ -49,5 +51,17 @@ bool ParseKeyValueArguments(std::map<std::string, std::string> *out_args, const
void PrintUsage(const struct argument *templates);
+bool GetUnsigned(unsigned *out, const std::string &arg_name,
+ unsigned default_value,
+ const std::map<std::string, std::string> &args);
+
+// These values are DER encoded, RSA private keys.
+extern const uint8_t kDERRSAPrivate2048[];
+extern const size_t kDERRSAPrivate2048Len;
+extern const uint8_t kDERRSAPrivate4096[];
+extern const size_t kDERRSAPrivate4096Len;
+extern const uint8_t kDERRSAPrivate3Prime2048[];
+extern const size_t kDERRSAPrivate3Prime2048Len;
+
#endif /* !OPENSSL_HEADER_TOOL_INTERNAL_H */
diff --git a/src/tool/pkcs12.cc b/src/tool/pkcs12.cc
index c191531..fe830d6 100644
--- a/src/tool/pkcs12.cc
+++ b/src/tool/pkcs12.cc
@@ -128,8 +128,10 @@ bool DoPKCS12(const std::vector<std::string> &args) {
return false;
}
- PEM_write_PrivateKey(stdout, key, NULL, NULL, 0, NULL, NULL);
- EVP_PKEY_free(key);
+ if (key != NULL) {
+ PEM_write_PrivateKey(stdout, key, NULL, NULL, 0, NULL, NULL);
+ EVP_PKEY_free(key);
+ }
for (size_t i = 0; i < sk_X509_num(certs); i++) {
PEM_write_X509(stdout, sk_X509_value(certs, i));
diff --git a/src/tool/server.cc b/src/tool/server.cc
index 164d6a5..14f37a4 100644
--- a/src/tool/server.cc
+++ b/src/tool/server.cc
@@ -35,10 +35,54 @@ static const struct argument kArguments[] = {
"Private-key file to use (default is server.pem)",
},
{
+ "-ocsp-response", kOptionalArgument,
+ "OCSP response file to send",
+ },
+ {
"", kOptionalArgument, "",
},
};
+static bool LoadOCSPResponse(SSL_CTX *ctx, const char *filename) {
+ void *data = NULL;
+ bool ret = false;
+ size_t bytes_read;
+ long length;
+
+ FILE *f = fopen(filename, "rb");
+
+ if (f == NULL ||
+ fseek(f, 0, SEEK_END) != 0) {
+ goto out;
+ }
+
+ length = ftell(f);
+ if (length < 0) {
+ goto out;
+ }
+
+ data = malloc(length);
+ if (data == NULL) {
+ goto out;
+ }
+ rewind(f);
+
+ bytes_read = fread(data, 1, length, f);
+ if (ferror(f) != 0 ||
+ bytes_read != (size_t)length ||
+ !SSL_CTX_set_ocsp_response(ctx, (uint8_t*)data, bytes_read)) {
+ goto out;
+ }
+
+ ret = true;
+out:
+ if (f != NULL) {
+ fclose(f);
+ }
+ free(data);
+ return ret;
+}
+
bool Server(const std::vector<std::string> &args) {
if (!InitSocketLibrary()) {
return false;
@@ -59,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;
}
@@ -74,6 +118,12 @@ bool Server(const std::vector<std::string> &args) {
return false;
}
+ if (args_map.count("-ocsp-response") != 0 &&
+ !LoadOCSPResponse(ctx, args_map["-ocsp-response"].c_str())) {
+ fprintf(stderr, "Failed to load OCSP response: %s\n", args_map["-ocsp-response"].c_str());
+ return false;
+ }
+
int sock = -1;
if (!Accept(&sock, args_map["-accept"])) {
return false;
diff --git a/src/tool/speed.cc b/src/tool/speed.cc
index ab17c2f..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>
@@ -36,16 +37,9 @@
#endif
#include "../crypto/test/scoped_types.h"
+#include "internal.h"
-extern "C" {
-// These values are DER encoded, RSA private keys.
-extern const uint8_t kDERRSAPrivate2048[];
-extern size_t kDERRSAPrivate2048Len;
-extern const uint8_t kDERRSAPrivate4096[];
-extern size_t kDERRSAPrivate4096Len;
-}
-
// TimeResults represents the results of benchmarking a function.
struct TimeResults {
// num_calls is the number of function calls done in the time period.
@@ -404,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) {
@@ -414,9 +477,9 @@ bool Speed(const std::vector<std::string> &args) {
selected = args[0];
}
- RSA *key = NULL;
- const uint8_t *inp = kDERRSAPrivate2048;
- if (NULL == d2i_RSAPrivateKey(&key, &inp, kDERRSAPrivate2048Len)) {
+ RSA *key = RSA_private_key_from_bytes(kDERRSAPrivate2048,
+ kDERRSAPrivate2048Len);
+ if (key == NULL) {
fprintf(stderr, "Failed to parse RSA key.\n");
ERR_print_errors_fp(stderr);
return false;
@@ -427,10 +490,22 @@ bool Speed(const std::vector<std::string> &args) {
}
RSA_free(key);
- key = NULL;
+ key = RSA_private_key_from_bytes(kDERRSAPrivate3Prime2048,
+ kDERRSAPrivate3Prime2048Len);
+ if (key == NULL) {
+ fprintf(stderr, "Failed to parse RSA key.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ if (!SpeedRSA("RSA 2048 (3 prime, e=3)", key, selected)) {
+ return false;
+ }
- inp = kDERRSAPrivate4096;
- if (NULL == d2i_RSAPrivateKey(&key, &inp, kDERRSAPrivate4096Len)) {
+ RSA_free(key);
+ key = RSA_private_key_from_bytes(kDERRSAPrivate4096,
+ kDERRSAPrivate4096Len);
+ if (key == NULL) {
fprintf(stderr, "Failed to parse 4096-bit RSA key.\n");
ERR_print_errors_fp(stderr);
return 1;
@@ -455,7 +530,12 @@ bool Speed(const std::vector<std::string> &args) {
!SpeedAEAD(EVP_aead_aes_256_gcm(), "AES-256-GCM", 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",
@@ -465,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 4bd7d1a..b825008 100644
--- a/src/tool/tool.cc
+++ b/src/tool/tool.cc
@@ -15,6 +15,7 @@
#include <string>
#include <vector>
+#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
@@ -26,56 +27,60 @@
#endif
+bool Ciphers(const std::vector<std::string> &args);
bool Client(const std::vector<std::string> &args);
-bool Server(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);
bool SHA1Sum(const std::vector<std::string> &args);
bool SHA224Sum(const std::vector<std::string> &args);
bool SHA256Sum(const std::vector<std::string> &args);
bool SHA384Sum(const std::vector<std::string> &args);
bool SHA512Sum(const std::vector<std::string> &args);
-bool DoPKCS12(const std::vector<std::string> &args);
+bool Server(const std::vector<std::string> &args);
bool Speed(const std::vector<std::string> &args);
-bool Rand(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[] = {
- { "speed", Speed },
- { "pkcs12", DoPKCS12 },
+ { "ciphers", Ciphers },
{ "client", Client },
+ { "generate-ed25519", GenerateEd25519Key },
+ { "genrsa", GenerateRSAKey },
+ { "md5sum", MD5Sum },
+ { "pkcs12", DoPKCS12 },
+ { "rand", Rand },
{ "s_client", Client },
- { "server", Server },
{ "s_server", Server },
- { "md5sum", MD5Sum },
+ { "server", Server },
{ "sha1sum", SHA1Sum },
{ "sha224sum", SHA224Sum },
{ "sha256sum", SHA256Sum },
{ "sha384sum", SHA384Sum },
{ "sha512sum", SHA512Sum },
- { "rand", Rand },
+ { "speed", Speed },
{ "", nullptr },
};
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) {
@@ -107,7 +112,7 @@ int main(int argc, char **argv) {
}
#endif
- SSL_library_init();
+ CRYPTO_library_init();
int starting_arg = 1;
tool_func_t tool = nullptr;
diff --git a/src/tool/transport_common.cc b/src/tool/transport_common.cc
index 3f5e631..2c15c00 100644
--- a/src/tool/transport_common.cc
+++ b/src/tool/transport_common.cc
@@ -133,19 +133,19 @@ out:
}
bool Accept(int *out_sock, const std::string &port) {
- struct sockaddr_in addr, cli_addr;
+ struct sockaddr_in6 addr, cli_addr;
socklen_t cli_addr_len = sizeof(cli_addr);
memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = INADDR_ANY;
- addr.sin_port = htons(atoi(port.c_str()));
+ addr.sin6_family = AF_INET6;
+ addr.sin6_addr = in6addr_any;
+ addr.sin6_port = htons(atoi(port.c_str()));
bool ok = false;
int server_sock = -1;
server_sock =
- socket(addr.sin_family, SOCK_STREAM, 0);
+ socket(addr.sin6_family, SOCK_STREAM, 0);
if (server_sock < 0) {
perror("socket");
goto out;
@@ -169,7 +169,14 @@ void PrintConnectionInfo(const SSL *ssl) {
const SSL_CIPHER *cipher = SSL_get_current_cipher(ssl);
fprintf(stderr, " Version: %s\n", SSL_get_version(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.go b/src/util/all_tests.go
index 49954df..566c3f7 100644
--- a/src/util/all_tests.go
+++ b/src/util/all_tests.go
@@ -41,63 +41,6 @@ var (
type test []string
-var tests = []test{
- {"crypto/base64/base64_test"},
- {"crypto/bio/bio_test"},
- {"crypto/bn/bn_test"},
- {"crypto/bytestring/bytestring_test"},
- {"crypto/cipher/aead_test", "aes-128-gcm", "crypto/cipher/test/aes_128_gcm_tests.txt"},
- {"crypto/cipher/aead_test", "aes-128-key-wrap", "crypto/cipher/test/aes_128_key_wrap_tests.txt"},
- {"crypto/cipher/aead_test", "aes-256-gcm", "crypto/cipher/test/aes_256_gcm_tests.txt"},
- {"crypto/cipher/aead_test", "aes-256-key-wrap", "crypto/cipher/test/aes_256_key_wrap_tests.txt"},
- {"crypto/cipher/aead_test", "chacha20-poly1305", "crypto/cipher/test/chacha20_poly1305_tests.txt"},
- {"crypto/cipher/aead_test", "rc4-md5-tls", "crypto/cipher/test/rc4_md5_tls_tests.txt"},
- {"crypto/cipher/aead_test", "rc4-sha1-tls", "crypto/cipher/test/rc4_sha1_tls_tests.txt"},
- {"crypto/cipher/aead_test", "aes-128-cbc-sha1-tls", "crypto/cipher/test/aes_128_cbc_sha1_tls_tests.txt"},
- {"crypto/cipher/aead_test", "aes-128-cbc-sha1-tls-implicit-iv", "crypto/cipher/test/aes_128_cbc_sha1_tls_implicit_iv_tests.txt"},
- {"crypto/cipher/aead_test", "aes-128-cbc-sha256-tls", "crypto/cipher/test/aes_128_cbc_sha256_tls_tests.txt"},
- {"crypto/cipher/aead_test", "aes-256-cbc-sha1-tls", "crypto/cipher/test/aes_256_cbc_sha1_tls_tests.txt"},
- {"crypto/cipher/aead_test", "aes-256-cbc-sha1-tls-implicit-iv", "crypto/cipher/test/aes_256_cbc_sha1_tls_implicit_iv_tests.txt"},
- {"crypto/cipher/aead_test", "aes-256-cbc-sha256-tls", "crypto/cipher/test/aes_256_cbc_sha256_tls_tests.txt"},
- {"crypto/cipher/aead_test", "aes-256-cbc-sha384-tls", "crypto/cipher/test/aes_256_cbc_sha384_tls_tests.txt"},
- {"crypto/cipher/aead_test", "des-ede3-cbc-sha1-tls", "crypto/cipher/test/des_ede3_cbc_sha1_tls_tests.txt"},
- {"crypto/cipher/aead_test", "des-ede3-cbc-sha1-tls-implicit-iv", "crypto/cipher/test/des_ede3_cbc_sha1_tls_implicit_iv_tests.txt"},
- {"crypto/cipher/aead_test", "rc4-md5-ssl3", "crypto/cipher/test/rc4_md5_ssl3_tests.txt"},
- {"crypto/cipher/aead_test", "rc4-sha1-ssl3", "crypto/cipher/test/rc4_sha1_ssl3_tests.txt"},
- {"crypto/cipher/aead_test", "aes-128-cbc-sha1-ssl3", "crypto/cipher/test/aes_128_cbc_sha1_ssl3_tests.txt"},
- {"crypto/cipher/aead_test", "aes-256-cbc-sha1-ssl3", "crypto/cipher/test/aes_256_cbc_sha1_ssl3_tests.txt"},
- {"crypto/cipher/aead_test", "des-ede3-cbc-sha1-ssl3", "crypto/cipher/test/des_ede3_cbc_sha1_ssl3_tests.txt"},
- {"crypto/cipher/aead_test", "aes-128-ctr-hmac-sha256", "crypto/cipher/test/aes_128_ctr_hmac_sha256.txt"},
- {"crypto/cipher/aead_test", "aes-256-ctr-hmac-sha256", "crypto/cipher/test/aes_256_ctr_hmac_sha256.txt"},
- {"crypto/cipher/cipher_test", "crypto/cipher/test/cipher_test.txt"},
- {"crypto/cmac/cmac_test"},
- {"crypto/constant_time_test"},
- {"crypto/dh/dh_test"},
- {"crypto/digest/digest_test"},
- {"crypto/dsa/dsa_test"},
- {"crypto/ec/ec_test"},
- {"crypto/ec/example_mul"},
- {"crypto/ecdsa/ecdsa_test"},
- {"crypto/err/err_test"},
- {"crypto/evp/evp_extra_test"},
- {"crypto/evp/evp_test", "crypto/evp/evp_tests.txt"},
- {"crypto/evp/evp_test", "crypto/hmac/hmac_tests.txt"},
- {"crypto/evp/pbkdf_test"},
- {"crypto/hkdf/hkdf_test"},
- {"crypto/hmac/hmac_test", "crypto/hmac/hmac_tests.txt"},
- {"crypto/lhash/lhash_test"},
- {"crypto/modes/gcm_test"},
- {"crypto/pkcs8/pkcs12_test"},
- {"crypto/refcount_test"},
- {"crypto/rsa/rsa_test"},
- {"crypto/thread_test"},
- {"crypto/x509/pkcs7_test"},
- {"crypto/x509v3/tab_test"},
- {"crypto/x509v3/v3name_test"},
- {"ssl/pqueue/pqueue_test"},
- {"ssl/ssl_test"},
-}
-
// testOutput is a representation of Chromium's JSON test result format. See
// https://www.chromium.org/developers/the-json-test-results-format
type testOutput struct {
@@ -254,8 +197,43 @@ func shortTestName(test test) string {
return strings.Join(args, " ")
}
+// setWorkingDirectory walks up directories as needed until the current working
+// directory is the top of a BoringSSL checkout.
+func setWorkingDirectory() {
+ for i := 0; i < 64; i++ {
+ if _, err := os.Stat("BUILDING.md"); err == nil {
+ return
+ }
+ os.Chdir("..")
+ }
+
+ panic("Couldn't find BUILDING.md in a parent directory!")
+}
+
+func parseTestConfig(filename string) ([]test, error) {
+ in, err := os.Open(filename)
+ if err != nil {
+ return nil, err
+ }
+ defer in.Close()
+
+ decoder := json.NewDecoder(in)
+ var result []test
+ if err := decoder.Decode(&result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
func main() {
flag.Parse()
+ setWorkingDirectory()
+
+ tests, err := parseTestConfig("util/all_tests.json")
+ if err != nil {
+ fmt.Printf("Failed to parse input: %s\n", err)
+ os.Exit(1)
+ }
testOutput := newTestOutput()
var failed []test
diff --git a/src/util/all_tests.json b/src/util/all_tests.json
new file mode 100644
index 0000000..c621799
--- /dev/null
+++ b/src/util/all_tests.json
@@ -0,0 +1,61 @@
+[
+ ["crypto/aes/aes_test"],
+ ["crypto/base64/base64_test"],
+ ["crypto/bio/bio_test"],
+ ["crypto/bn/bn_test"],
+ ["crypto/bytestring/bytestring_test"],
+ ["crypto/cipher/aead_test", "aes-128-gcm", "crypto/cipher/test/aes_128_gcm_tests.txt"],
+ ["crypto/cipher/aead_test", "aes-128-key-wrap", "crypto/cipher/test/aes_128_key_wrap_tests.txt"],
+ ["crypto/cipher/aead_test", "aes-256-gcm", "crypto/cipher/test/aes_256_gcm_tests.txt"],
+ ["crypto/cipher/aead_test", "aes-256-key-wrap", "crypto/cipher/test/aes_256_key_wrap_tests.txt"],
+ ["crypto/cipher/aead_test", "chacha20-poly1305", "crypto/cipher/test/chacha20_poly1305_tests.txt"],
+ ["crypto/cipher/aead_test", "chacha20-poly1305-old", "crypto/cipher/test/chacha20_poly1305_old_tests.txt"],
+ ["crypto/cipher/aead_test", "rc4-md5-tls", "crypto/cipher/test/rc4_md5_tls_tests.txt"],
+ ["crypto/cipher/aead_test", "rc4-sha1-tls", "crypto/cipher/test/rc4_sha1_tls_tests.txt"],
+ ["crypto/cipher/aead_test", "aes-128-cbc-sha1-tls", "crypto/cipher/test/aes_128_cbc_sha1_tls_tests.txt"],
+ ["crypto/cipher/aead_test", "aes-128-cbc-sha1-tls-implicit-iv", "crypto/cipher/test/aes_128_cbc_sha1_tls_implicit_iv_tests.txt"],
+ ["crypto/cipher/aead_test", "aes-128-cbc-sha256-tls", "crypto/cipher/test/aes_128_cbc_sha256_tls_tests.txt"],
+ ["crypto/cipher/aead_test", "aes-256-cbc-sha1-tls", "crypto/cipher/test/aes_256_cbc_sha1_tls_tests.txt"],
+ ["crypto/cipher/aead_test", "aes-256-cbc-sha1-tls-implicit-iv", "crypto/cipher/test/aes_256_cbc_sha1_tls_implicit_iv_tests.txt"],
+ ["crypto/cipher/aead_test", "aes-256-cbc-sha256-tls", "crypto/cipher/test/aes_256_cbc_sha256_tls_tests.txt"],
+ ["crypto/cipher/aead_test", "aes-256-cbc-sha384-tls", "crypto/cipher/test/aes_256_cbc_sha384_tls_tests.txt"],
+ ["crypto/cipher/aead_test", "des-ede3-cbc-sha1-tls", "crypto/cipher/test/des_ede3_cbc_sha1_tls_tests.txt"],
+ ["crypto/cipher/aead_test", "des-ede3-cbc-sha1-tls-implicit-iv", "crypto/cipher/test/des_ede3_cbc_sha1_tls_implicit_iv_tests.txt"],
+ ["crypto/cipher/aead_test", "rc4-md5-ssl3", "crypto/cipher/test/rc4_md5_ssl3_tests.txt"],
+ ["crypto/cipher/aead_test", "rc4-sha1-ssl3", "crypto/cipher/test/rc4_sha1_ssl3_tests.txt"],
+ ["crypto/cipher/aead_test", "aes-128-cbc-sha1-ssl3", "crypto/cipher/test/aes_128_cbc_sha1_ssl3_tests.txt"],
+ ["crypto/cipher/aead_test", "aes-256-cbc-sha1-ssl3", "crypto/cipher/test/aes_256_cbc_sha1_ssl3_tests.txt"],
+ ["crypto/cipher/aead_test", "des-ede3-cbc-sha1-ssl3", "crypto/cipher/test/des_ede3_cbc_sha1_ssl3_tests.txt"],
+ ["crypto/cipher/aead_test", "aes-128-ctr-hmac-sha256", "crypto/cipher/test/aes_128_ctr_hmac_sha256.txt"],
+ ["crypto/cipher/aead_test", "aes-256-ctr-hmac-sha256", "crypto/cipher/test/aes_256_ctr_hmac_sha256.txt"],
+ ["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"],
+ ["crypto/ec/ec_test"],
+ ["crypto/ec/example_mul"],
+ ["crypto/ecdsa/ecdsa_test"],
+ ["crypto/err/err_test"],
+ ["crypto/evp/evp_extra_test"],
+ ["crypto/evp/evp_test", "crypto/evp/evp_tests.txt"],
+ ["crypto/evp/pbkdf_test"],
+ ["crypto/hkdf/hkdf_test"],
+ ["crypto/hmac/hmac_test", "crypto/hmac/hmac_tests.txt"],
+ ["crypto/lhash/lhash_test"],
+ ["crypto/modes/gcm_test"],
+ ["crypto/pkcs8/pkcs8_test"],
+ ["crypto/pkcs8/pkcs12_test"],
+ ["crypto/poly1305/poly1305_test", "crypto/poly1305/poly1305_test.txt"],
+ ["crypto/refcount_test"],
+ ["crypto/rsa/rsa_test"],
+ ["crypto/thread_test"],
+ ["crypto/x509/pkcs7_test"],
+ ["crypto/x509v3/tab_test"],
+ ["crypto/x509v3/v3name_test"],
+ ["ssl/pqueue/pqueue_test"],
+ ["ssl/ssl_test"]
+]
diff --git a/src/util/bot/go/bootstrap.py b/src/util/bot/go/bootstrap.py
index 166ef3b..4a52d9e 100755
--- a/src/util/bot/go/bootstrap.py
+++ b/src/util/bot/go/bootstrap.py
@@ -45,12 +45,11 @@ WORKSPACE = os.path.join(ROOT, 'go')
EXE_SFX = '.exe' if sys.platform == 'win32' else ''
# Pinned version of Go toolset to download.
-TOOLSET_VERSION = 'go1.4'
+TOOLSET_VERSION = 'go1.5.1'
# Platform dependent portion of a download URL. See http://golang.org/dl/.
TOOLSET_VARIANTS = {
- ('darwin', 'x86-32'): 'darwin-386-osx10.8.tar.gz',
- ('darwin', 'x86-64'): 'darwin-amd64-osx10.8.tar.gz',
+ ('darwin', 'x86-64'): 'darwin-amd64.tar.gz',
('linux2', 'x86-32'): 'linux-386.tar.gz',
('linux2', 'x86-64'): 'linux-amd64.tar.gz',
('win32', 'x86-32'): 'windows-386.zip',
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 a427e04..cbee543 100644
--- a/src/util/doc.config
+++ b/src/util/doc.config
@@ -16,7 +16,6 @@
"include/openssl/obj.h",
"include/openssl/rand.h",
"include/openssl/stack.h",
- "include/openssl/thread.h",
"include/openssl/time_support.h"
]
},{
@@ -25,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",
@@ -35,7 +35,6 @@
"include/openssl/engine.h",
"include/openssl/hmac.h",
"include/openssl/md5.h",
- "include/openssl/modes.h",
"include/openssl/rc4.h",
"include/openssl/rsa.h",
"include/openssl/sha.h"
diff --git a/src/util/doc.go b/src/util/doc.go
index 540d6ca..7d15d9b 100644
--- a/src/util/doc.go
+++ b/src/util/doc.go
@@ -42,15 +42,16 @@ type HeaderFile struct {
// is a separate paragraph.
Preamble []string
Sections []HeaderSection
+ // AllDecls maps all decls to their URL fragments.
+ AllDecls map[string]string
}
type HeaderSection struct {
// Preamble contains a comment for a group of functions.
Preamble []string
Decls []HeaderDecl
- // Num is just the index of the section. It's included in order to help
- // text/template generate anchors.
- Num int
+ // Anchor, if non-empty, is the URL fragment to use in anchor tags.
+ Anchor string
// IsPrivate is true if the section contains private functions (as
// indicated by its name).
IsPrivate bool
@@ -65,10 +66,8 @@ type HeaderDecl struct {
Name string
// Decl contains the preformatted C declaration itself.
Decl string
- // Num is an index for the declaration, but the value is unique for all
- // declarations in a HeaderFile. It's included in order to help
- // text/template generate anchors.
- Num int
+ // Anchor, if non-empty, is the URL fragment to use in anchor tags.
+ Anchor string
}
const (
@@ -192,14 +191,6 @@ func extractDecl(lines []string, lineNo int) (decl string, rest []string, restLi
return
}
-func skipPast(s, skip string) string {
- i := strings.Index(s, skip)
- if i > 0 {
- return s[i:]
- }
- return s
-}
-
func skipLine(s string) string {
i := strings.Index(s, "\n")
if i > 0 {
@@ -227,8 +218,9 @@ func getNameFromDecl(decl string) (string, bool) {
}
return decl[:i], true
}
- decl = skipPast(decl, "STACK_OF(")
- decl = skipPast(decl, "LHASH_OF(")
+ decl = strings.TrimPrefix(decl, "OPENSSL_EXPORT ")
+ decl = strings.TrimPrefix(decl, "STACK_OF(")
+ decl = strings.TrimPrefix(decl, "LHASH_OF(")
i := strings.Index(decl, "(")
if i < 0 {
return "", false
@@ -243,6 +235,14 @@ func getNameFromDecl(decl string) (string, bool) {
return decl[j+1 : i], true
}
+func sanitizeAnchor(name string) string {
+ return strings.Replace(name, " ", "-", -1)
+}
+
+func isPrivateSection(name string) bool {
+ return strings.HasPrefix(name, "Private functions") || strings.HasPrefix(name, "Private structures") || strings.Contains(name, "(hidden)")
+}
+
func (config *Config) parseHeader(path string) (*HeaderFile, error) {
headerPath := filepath.Join(config.BaseDirectory, path)
@@ -284,7 +284,8 @@ func (config *Config) parseHeader(path string) (*HeaderFile, error) {
lines = lines[2:]
header := &HeaderFile{
- Name: filepath.Base(path),
+ Name: filepath.Base(path),
+ AllDecls: make(map[string]string),
}
for i, line := range lines {
@@ -314,7 +315,7 @@ func (config *Config) parseHeader(path string) (*HeaderFile, error) {
}
}
- var sectionNumber, declNumber int
+ allAnchors := make(map[string]struct{})
for {
// Start of a section.
@@ -330,10 +331,7 @@ func (config *Config) parseHeader(path string) (*HeaderFile, error) {
return nil, fmt.Errorf("blank line at start of section on line %d", lineNo)
}
- section := HeaderSection{
- Num: sectionNumber,
- }
- sectionNumber++
+ var section HeaderSection
if strings.HasPrefix(line, commentStart) {
comment, rest, restLineNo, err := extractComment(lines, lineNo)
@@ -341,8 +339,17 @@ func (config *Config) parseHeader(path string) (*HeaderFile, error) {
return nil, err
}
if len(rest) > 0 && len(rest[0]) == 0 {
+ anchor := sanitizeAnchor(firstSentence(comment))
+ if len(anchor) > 0 {
+ if _, ok := allAnchors[anchor]; ok {
+ return nil, fmt.Errorf("duplicate anchor: %s", anchor)
+ }
+ allAnchors[anchor] = struct{}{}
+ }
+
section.Preamble = comment
- section.IsPrivate = len(comment) > 0 && strings.HasPrefix(comment[0], "Private functions")
+ section.IsPrivate = len(comment) > 0 && isPrivateSection(comment[0])
+ section.Anchor = anchor
lines = rest[1:]
lineNo = restLineNo + 1
}
@@ -381,13 +388,33 @@ func (config *Config) parseHeader(path string) (*HeaderFile, error) {
if last := len(section.Decls) - 1; len(name) == 0 && len(comment) == 0 && last >= 0 {
section.Decls[last].Decl += "\n" + decl
} else {
+ // As a matter of style, comments should start
+ // with the name of the thing that they are
+ // commenting on. We make an exception here for
+ // #defines (because we often have blocks of
+ // them) and collective comments, which are
+ // detected by starting with “The†or “Theseâ€.
+ if len(comment) > 0 &&
+ !strings.HasPrefix(comment[0], name) &&
+ !strings.HasPrefix(decl, "#define ") &&
+ !strings.HasPrefix(comment[0], "The ") &&
+ !strings.HasPrefix(comment[0], "These ") {
+ return nil, fmt.Errorf("Comment for %q doesn't seem to match just above %s:%d\n", name, path, lineNo)
+ }
+ anchor := sanitizeAnchor(name)
+ // TODO(davidben): Enforce uniqueness. This is
+ // skipped because #ifdefs currently result in
+ // duplicate table-of-contents entries.
+ allAnchors[anchor] = struct{}{}
+
+ header.AllDecls[name] = anchor
+
section.Decls = append(section.Decls, HeaderDecl{
Comment: comment,
Name: name,
Decl: decl,
- Num: declNumber,
+ Anchor: anchor,
})
- declNumber++
}
if len(lines) > 0 && len(lines[0]) == 0 {
@@ -417,7 +444,7 @@ func firstSentence(paragraphs []string) string {
return s
}
-func markupPipeWords(s string) template.HTML {
+func markupPipeWords(allDecls map[string]string, s string) template.HTML {
ret := ""
for {
@@ -433,7 +460,14 @@ func markupPipeWords(s string) template.HTML {
j := strings.Index(s, " ")
if i > 0 && (j == -1 || j > i) {
ret += "<tt>"
+ anchor, isLink := allDecls[s[:i]]
+ if isLink {
+ ret += fmt.Sprintf("<a href=\"%s\">", template.HTMLEscapeString(anchor))
+ }
ret += s[:i]
+ if isLink {
+ ret += "</a>"
+ }
ret += "</tt>"
s = s[i+1:]
} else {
@@ -451,7 +485,12 @@ again:
if end > 0 {
end += start
w := strings.ToLower(string(s[start:end]))
- if w == "a" || w == "an" || w == "deprecated:" {
+ // The first word was already marked up as an HTML tag. Don't
+ // mark it up further.
+ if strings.ContainsRune(w, '<') {
+ return s
+ }
+ if w == "a" || w == "an" {
start = end + 1
goto again
}
@@ -471,10 +510,12 @@ func newlinesToBR(html template.HTML) template.HTML {
}
func generate(outPath string, config *Config) (map[string]string, error) {
+ allDecls := make(map[string]string)
+
headerTmpl := template.New("headerTmpl")
headerTmpl.Funcs(template.FuncMap{
"firstSentence": firstSentence,
- "markupPipeWords": markupPipeWords,
+ "markupPipeWords": func(s string) template.HTML { return markupPipeWords(allDecls, s) },
"markupFirstWord": markupFirstWord,
"newlinesToBR": newlinesToBR,
})
@@ -495,9 +536,9 @@ func generate(outPath string, config *Config) (map[string]string, error) {
<ol>
{{range .Sections}}
{{if not .IsPrivate}}
- {{if .Preamble}}<li class="header"><a href="#section-{{.Num}}">{{.Preamble | firstSentence | html | markupPipeWords}}</a></li>{{end}}
+ {{if .Anchor}}<li class="header"><a href="#{{.Anchor}}">{{.Preamble | firstSentence | html | markupPipeWords}}</a></li>{{end}}
{{range .Decls}}
- {{if .Name}}<li><a href="#decl-{{.Num}}"><tt>{{.Name}}</tt></a></li>{{end}}
+ {{if .Anchor}}<li><a href="#{{.Anchor}}"><tt>{{.Name}}</tt></a></li>{{end}}
{{end}}
{{end}}
{{end}}
@@ -505,23 +546,19 @@ func generate(outPath string, config *Config) (map[string]string, error) {
{{range .Sections}}
{{if not .IsPrivate}}
- <div class="section">
+ <div class="section" {{if .Anchor}}id="{{.Anchor}}"{{end}}>
{{if .Preamble}}
<div class="sectionpreamble">
- <a name="section-{{.Num}}">
{{range .Preamble}}<p>{{. | html | markupPipeWords}}</p>{{end}}
- </a>
</div>
{{end}}
{{range .Decls}}
- <div class="decl">
- <a name="decl-{{.Num}}">
+ <div class="decl" {{if .Anchor}}id="{{.Anchor}}"{{end}}>
{{range .Comment}}
<p>{{. | html | markupPipeWords | newlinesToBR | markupFirstWord}}</p>
{{end}}
<pre>{{.Decl}}</pre>
- </a>
</div>
{{end}}
</div>
@@ -535,6 +572,7 @@ func generate(outPath string, config *Config) (map[string]string, error) {
}
headerDescriptions := make(map[string]string)
+ var headers []*HeaderFile
for _, section := range config.Sections {
for _, headerPath := range section.Headers {
@@ -543,18 +581,26 @@ func generate(outPath string, config *Config) (map[string]string, error) {
return nil, errors.New("while parsing " + headerPath + ": " + err.Error())
}
headerDescriptions[header.Name] = firstSentence(header.Preamble)
- filename := filepath.Join(outPath, header.Name+".html")
- file, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
- if err != nil {
- panic(err)
- }
- defer file.Close()
- if err := headerTmpl.Execute(file, header); err != nil {
- return nil, err
+ headers = append(headers, header)
+
+ for name, anchor := range header.AllDecls {
+ allDecls[name] = fmt.Sprintf("%s#%s", header.Name+".html", anchor)
}
}
}
+ for _, header := range headers {
+ filename := filepath.Join(outPath, header.Name+".html")
+ file, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
+ if err != nil {
+ panic(err)
+ }
+ defer file.Close()
+ if err := headerTmpl.Execute(file, header); err != nil {
+ return nil, err
+ }
+ }
+
return headerDescriptions, nil
}
@@ -605,6 +651,14 @@ func generateIndex(outPath string, config *Config, headerDescriptions map[string
return nil
}
+func copyFile(outPath string, inFilePath string) error {
+ bytes, err := ioutil.ReadFile(inFilePath)
+ if err != nil {
+ return err
+ }
+ return ioutil.WriteFile(filepath.Join(outPath, filepath.Base(inFilePath)), bytes, 0666)
+}
+
func main() {
var (
configFlag *string = flag.String("config", "doc.config", "Location of config file")
@@ -645,4 +699,9 @@ func main() {
fmt.Printf("Failed to generate index: %s\n", err)
os.Exit(1)
}
+
+ if err := copyFile(*outputDir, "doc.css"); err != nil {
+ fmt.Printf("Failed to copy static file: %s\n", err)
+ os.Exit(1)
+ }
}
diff --git a/src/util/generate_build_files.py b/src/util/generate_build_files.py
index e534a56..6321c5c 100644
--- a/src/util/generate_build_files.py
+++ b/src/util/generate_build_files.py
@@ -19,6 +19,7 @@
import os
import subprocess
import sys
+import json
# OS_ARCH_COMBOS maps from OS and platform to the OpenSSL assembly "style" for
@@ -38,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',
],
}
@@ -68,7 +70,9 @@ class Chromium(object):
gypi.write(self.header + '{\n \'variables\': {\n')
self.PrintVariableSection(
- gypi, 'boringssl_lib_sources', files['crypto'] + files['ssl'])
+ gypi, 'boringssl_ssl_sources', files['ssl'])
+ self.PrintVariableSection(
+ gypi, 'boringssl_crypto_sources', files['crypto'])
for ((osname, arch), asm_files) in asm_outputs:
self.PrintVariableSection(gypi, 'boringssl_%s_%s_sources' %
@@ -133,6 +137,9 @@ class Android(object):
"""
+ def ExtraFiles(self):
+ return ['android_compat_hacks.c', 'android_compat_keywrap.c']
+
def PrintVariableSection(self, out, name, files):
out.write('%s := \\\n' % name)
for f in sorted(files):
@@ -143,9 +150,8 @@ class Android(object):
with open('sources.mk', 'w+') as makefile:
makefile.write(self.header)
- files['crypto'].append('android_compat_hacks.c')
- files['crypto'].append('android_compat_keywrap.c')
- 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'])
@@ -154,6 +160,129 @@ class Android(object):
makefile, '%s_%s_sources' % (osname, arch), asm_files)
+class AndroidStandalone(Android):
+ """AndroidStandalone is for Android builds outside of the Android-system, i.e.
+
+ for applications that wish wish to ship BoringSSL.
+ """
+
+ def ExtraFiles(self):
+ return []
+
+
+class Bazel(object):
+ """Bazel outputs files suitable for including in Bazel files."""
+
+ def __init__(self):
+ self.firstSection = True
+ self.header = \
+"""# This file is created by generate_build_files.py. Do not edit manually.
+
+"""
+
+ def PrintVariableSection(self, out, name, files):
+ if not self.firstSection:
+ out.write('\n')
+ self.firstSection = False
+
+ out.write('%s = [\n' % name)
+ for f in sorted(files):
+ out.write(' "%s",\n' % f)
+ out.write(']\n')
+
+ def WriteFiles(self, files, asm_outputs):
+ with open('BUILD.generated.bzl', 'w+') as out:
+ out.write(self.header)
+
+ self.PrintVariableSection(out, 'ssl_headers', files['ssl_headers'])
+ self.PrintVariableSection(
+ out, 'ssl_internal_headers', files['ssl_internal_headers'])
+ self.PrintVariableSection(out, 'ssl_sources', files['ssl'])
+ self.PrintVariableSection(out, 'crypto_headers', files['crypto_headers'])
+ self.PrintVariableSection(
+ out, 'crypto_internal_headers', files['crypto_internal_headers'])
+ self.PrintVariableSection(out, 'crypto_sources', files['crypto'])
+ self.PrintVariableSection(out, 'tool_sources', files['tool'])
+
+ for ((osname, arch), asm_files) in asm_outputs:
+ self.PrintVariableSection(
+ out, 'crypto_sources_%s_%s' % (osname, arch), asm_files)
+
+ with open('BUILD.generated_tests.bzl', 'w+') as out:
+ out.write(self.header)
+
+ out.write('test_support_sources = [\n')
+ for filename in files['test_support']:
+ if os.path.basename(filename) == 'malloc.cc':
+ continue
+ out.write(' "%s",\n' % filename)
+
+ out.write(']\n\n')
+
+ out.write('def create_tests(copts):\n')
+ out.write(' test_support_sources_complete = test_support_sources + \\\n')
+ out.write(' native.glob(["src/crypto/test/*.h"])\n')
+ name_counts = {}
+ for test in files['tests']:
+ name = os.path.basename(test[0])
+ name_counts[name] = name_counts.get(name, 0) + 1
+
+ first = True
+ for test in files['tests']:
+ name = os.path.basename(test[0])
+ if name_counts[name] > 1:
+ if '/' in test[1]:
+ name += '_' + os.path.splitext(os.path.basename(test[1]))[0]
+ else:
+ name += '_' + test[1].replace('-', '_')
+
+ if not first:
+ out.write('\n')
+ first = False
+
+ src_prefix = 'src/' + test[0]
+ for src in files['test']:
+ if src.startswith(src_prefix):
+ src = src
+ break
+ else:
+ raise ValueError("Can't find source for %s" % test[0])
+
+ out.write(' native.cc_test(\n')
+ out.write(' name = "%s",\n' % name)
+ out.write(' size = "small",\n')
+ out.write(' srcs = ["%s"] + test_support_sources_complete,\n' % src)
+
+ data_files = []
+ if len(test) > 1:
+
+ out.write(' args = [\n')
+ for arg in test[1:]:
+ if '/' in arg:
+ out.write(' "$(location src/%s)",\n' % arg)
+ data_files.append('src/%s' % arg)
+ else:
+ out.write(' "%s",\n' % arg)
+ out.write(' ],\n')
+
+ out.write(' copts = copts,\n')
+
+ if len(data_files) > 0:
+ out.write(' data = [\n')
+ for filename in data_files:
+ out.write(' "%s",\n' % filename)
+ out.write(' ],\n')
+
+ if 'ssl/' in test[0]:
+ out.write(' deps = [\n')
+ out.write(' ":crypto",\n')
+ out.write(' ":ssl",\n')
+ out.write(' ],\n')
+ else:
+ out.write(' deps = [":crypto"],\n')
+ out.write(' )\n')
+
+
def FindCMakeFiles(directory):
"""Returns list of all CMakeLists.txt files recursively in directory."""
cmakefiles = []
@@ -188,6 +317,10 @@ def AllFiles(dent, is_dir):
return True
+def SSLHeaderFiles(dent, is_dir):
+ return dent in ['ssl.h', 'tls1.h', 'ssl23.h', 'ssl3.h', 'dtls1.h']
+
+
def FindCFiles(directory, filter_func):
"""Recurses through directory and returns a list of paths to all the C source
files that pass filter_func."""
@@ -208,6 +341,21 @@ def FindCFiles(directory, filter_func):
return cfiles
+def FindHeaderFiles(directory, filter_func):
+ """Recurses through directory and returns a list of paths to all the header files that pass filter_func."""
+ hfiles = []
+
+ for (path, dirnames, filenames) in os.walk(directory):
+ for filename in filenames:
+ if not filename.endswith('.h'):
+ continue
+ if not filter_func(filename, False):
+ continue
+ hfiles.append(os.path.join(path, filename))
+
+ return hfiles
+
+
def ExtractPerlAsmFromCMakeFile(cmakefile):
"""Parses the contents of the CMakeLists.txt file passed as an argument and
returns a list of all the perlasm() directives found in the file."""
@@ -289,6 +437,9 @@ def WriteAsmFiles(perlasms):
if not output.startswith('src'):
raise ValueError('output missing src: %s' % output)
output = os.path.join(outDir, output[4:])
+ if output.endswith('-armx.${ASM_EXT}'):
+ output = output.replace('-armx',
+ '-armx64' if arch == 'aarch64' else '-armx32')
output = output.replace('${ASM_EXT}', asm_ext)
if arch in ArchForAsmFilename(filename):
@@ -302,7 +453,7 @@ def WriteAsmFiles(perlasms):
return asmfiles
-def main(platform):
+def main(platforms):
crypto_c_files = FindCFiles(os.path.join('src', 'crypto'), NoTests)
ssl_c_files = FindCFiles(os.path.join('src', 'ssl'), NoTests)
tool_cc_files = FindCFiles(os.path.join('src', 'tool'), NoTests)
@@ -320,36 +471,80 @@ def main(platform):
test_c_files = FindCFiles(os.path.join('src', 'crypto'), OnlyTests)
test_c_files += FindCFiles(os.path.join('src', 'ssl'), OnlyTests)
+ ssl_h_files = (
+ FindHeaderFiles(
+ os.path.join('src', 'include', 'openssl'),
+ SSLHeaderFiles))
+
+ def NotSSLHeaderFiles(filename, is_dir):
+ return not SSLHeaderFiles(filename, is_dir)
+ crypto_h_files = (
+ FindHeaderFiles(
+ os.path.join('src', 'include', 'openssl'),
+ NotSSLHeaderFiles))
+
+ ssl_internal_h_files = FindHeaderFiles(os.path.join('src', 'ssl'), NoTests)
+ crypto_internal_h_files = FindHeaderFiles(
+ os.path.join('src', 'crypto'), NoTests)
+
+ with open('src/util/all_tests.json', 'r') as f:
+ tests = json.load(f)
+ test_binaries = set([test[0] for test in tests])
+ test_sources = set([
+ test.replace('.cc', '').replace('.c', '').replace(
+ 'src/',
+ '')
+ for test in test_c_files])
+ if test_binaries != test_sources:
+ print 'Test sources and configured tests do not match'
+ a = test_binaries.difference(test_sources)
+ if len(a) > 0:
+ print 'These tests are configured without sources: ' + str(a)
+ b = test_sources.difference(test_binaries)
+ if len(b) > 0:
+ print 'These test sources are not configured: ' + str(b)
+
files = {
'crypto': crypto_c_files,
+ 'crypto_headers': crypto_h_files,
+ 'crypto_internal_headers': crypto_internal_h_files,
'ssl': ssl_c_files,
+ 'ssl_headers': ssl_h_files,
+ 'ssl_internal_headers': ssl_internal_h_files,
'tool': tool_cc_files,
'test': test_c_files,
'test_support': test_support_cc_files,
+ 'tests': tests,
}
asm_outputs = sorted(WriteAsmFiles(ReadPerlAsmOperations()).iteritems())
- platform.WriteFiles(files, asm_outputs)
+ for platform in platforms:
+ platform.WriteFiles(files, asm_outputs)
return 0
def Usage():
- print 'Usage: python %s [chromium|android]' % sys.argv[0]
+ print 'Usage: python %s [chromium|android|android-standalone|bazel]' % sys.argv[0]
sys.exit(1)
if __name__ == '__main__':
- if len(sys.argv) != 2:
- Usage()
-
- platform = None
- if sys.argv[1] == 'chromium':
- platform = Chromium()
- elif sys.argv[1] == 'android':
- platform = Android()
- else:
+ if len(sys.argv) < 2:
Usage()
- sys.exit(main(platform))
+ platforms = []
+ for s in sys.argv[1:]:
+ if s == 'chromium' or s == 'gyp':
+ platforms.append(Chromium())
+ elif s == 'android':
+ platforms.append(Android())
+ elif s == 'android-standalone':
+ platforms.append(AndroidStandalone())
+ elif s == 'bazel':
+ platforms.append(Bazel())
+ else:
+ Usage()
+
+ sys.exit(main(platforms))
diff --git a/src/util/make_errors.go b/src/util/make_errors.go
index dc8039a..cc35409 100644
--- a/src/util/make_errors.go
+++ b/src/util/make_errors.go
@@ -25,7 +25,6 @@ import (
"sort"
"strconv"
"strings"
- "unicode"
)
// ssl.h reserves values 1000 and above for error codes corresponding to
@@ -61,12 +60,11 @@ func makeErrors(reset bool) error {
}
prefix := strings.ToUpper(lib)
- functions, reasons, err := parseHeader(prefix, headerFile)
+ reasons, err := parseHeader(prefix, headerFile)
headerFile.Close()
if reset {
err = nil
- functions = make(map[string]int)
// Retain any reason codes above reservedReasonCode.
newReasons := make(map[string]int)
for key, value := range reasons {
@@ -97,12 +95,11 @@ func makeErrors(reset bool) error {
continue
}
- if err := addFunctionsAndReasons(functions, reasons, name, prefix); err != nil {
+ if err := addReasons(reasons, name, prefix); err != nil {
return err
}
}
- assignNewValues(functions, -1)
assignNewValues(reasons, reservedReasonCode)
headerFile, err = os.Open(headerPath)
@@ -117,7 +114,7 @@ func makeErrors(reset bool) error {
}
defer newHeaderFile.Close()
- if err := writeHeaderFile(newHeaderFile, headerFile, prefix, functions, reasons); err != nil {
+ if err := writeHeaderFile(newHeaderFile, headerFile, prefix, reasons); err != nil {
return err
}
os.Rename(headerPath+".tmp", headerPath)
@@ -127,8 +124,7 @@ func makeErrors(reset bool) error {
return err
}
- outputStrings(dataFile, lib, typeFunctions, functions)
- outputStrings(dataFile, lib, typeReasons, reasons)
+ outputStrings(dataFile, lib, reasons)
dataFile.Close()
return nil
@@ -136,16 +132,16 @@ func makeErrors(reset bool) error {
func findToplevel() (path string, err error) {
path = ".."
- buildingPath := filepath.Join(path, "BUILDING")
+ buildingPath := filepath.Join(path, "BUILDING.md")
_, err = os.Stat(buildingPath)
if err != nil && os.IsNotExist(err) {
path = filepath.Join("..", path)
- buildingPath = filepath.Join(path, "BUILDING")
+ buildingPath = filepath.Join(path, "BUILDING.md")
_, err = os.Stat(buildingPath)
}
if err != nil {
- return "", errors.New("Cannot find BUILDING file at the top-level")
+ return "", errors.New("Cannot find BUILDING.md file at the top-level")
}
return path, nil
}
@@ -183,7 +179,7 @@ func outputAssignments(w io.Writer, assignments map[string]int) {
}
}
-func parseDefineLine(line, lib string) (typ int, key string, value int, ok bool) {
+func parseDefineLine(line, lib string) (key string, value int, ok bool) {
if !strings.HasPrefix(line, "#define ") {
return
}
@@ -193,16 +189,8 @@ func parseDefineLine(line, lib string) (typ int, key string, value int, ok bool)
return
}
- funcPrefix := lib + "_F_"
- reasonPrefix := lib + "_R_"
-
key = fields[1]
- switch {
- case strings.HasPrefix(key, funcPrefix):
- typ = typeFunctions
- case strings.HasPrefix(key, reasonPrefix):
- typ = typeReasons
- default:
+ if !strings.HasPrefix(key, lib+"_R_") {
return
}
@@ -215,7 +203,7 @@ func parseDefineLine(line, lib string) (typ int, key string, value int, ok bool)
return
}
-func writeHeaderFile(w io.Writer, headerFile io.Reader, lib string, functions, reasons map[string]int) error {
+func writeHeaderFile(w io.Writer, headerFile io.Reader, lib string, reasons map[string]int) error {
var last []byte
var haveLast, sawDefine bool
newLine := []byte("\n")
@@ -223,7 +211,7 @@ func writeHeaderFile(w io.Writer, headerFile io.Reader, lib string, functions, r
scanner := bufio.NewScanner(headerFile)
for scanner.Scan() {
line := scanner.Text()
- _, _, _, ok := parseDefineLine(line, lib)
+ _, _, ok := parseDefineLine(line, lib)
if ok {
sawDefine = true
continue
@@ -247,7 +235,6 @@ func writeHeaderFile(w io.Writer, headerFile io.Reader, lib string, functions, r
return err
}
- outputAssignments(w, functions)
outputAssignments(w, reasons)
w.Write(newLine)
@@ -259,14 +246,9 @@ func writeHeaderFile(w io.Writer, headerFile io.Reader, lib string, functions, r
return nil
}
-const (
- typeFunctions = iota
- typeReasons
-)
-
-func outputStrings(w io.Writer, lib string, ty int, assignments map[string]int) {
+func outputStrings(w io.Writer, lib string, assignments map[string]int) {
lib = strings.ToUpper(lib)
- prefixLen := len(lib + "_F_")
+ prefixLen := len(lib + "_R_")
keys := make([]string, 0, len(assignments))
for key := range assignments {
@@ -275,11 +257,7 @@ func outputStrings(w io.Writer, lib string, ty int, assignments map[string]int)
sort.Strings(keys)
for _, key := range keys {
- typeString := "function"
- if ty == typeReasons {
- typeString = "reason"
- }
- fmt.Fprintf(w, "%s,%s,%d,%s\n", lib, typeString, assignments[key], key[prefixLen:])
+ fmt.Fprintf(w, "%s,%d,%s\n", lib, assignments[key], key[prefixLen:])
}
}
@@ -339,7 +317,7 @@ func handleDeclareMacro(line, join, macroName string, m map[string]int) {
}
}
-func addFunctionsAndReasons(functions, reasons map[string]int, filename, prefix string) error {
+func addReasons(reasons map[string]int, filename, prefix string) error {
file, err := os.Open(filename)
if err != nil {
return err
@@ -347,45 +325,15 @@ func addFunctionsAndReasons(functions, reasons map[string]int, filename, prefix
defer file.Close()
reasonPrefix := prefix + "_R_"
- var currentFunction string
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
- if len(line) > 0 && unicode.IsLetter(rune(line[0])) {
- /* Function start */
- fields := strings.Fields(line)
- for _, field := range fields {
- if i := strings.Index(field, "("); i != -1 {
- f := field[:i]
- // The return type of some functions is
- // a macro that contains a "(".
- if f == "STACK_OF" {
- continue
- }
- currentFunction = f
- for len(currentFunction) > 0 && currentFunction[0] == '*' {
- currentFunction = currentFunction[1:]
- }
- break
- }
- }
- }
-
- // Do not include cross-module error lines.
- if strings.Contains(line, "OPENSSL_PUT_ERROR(" + prefix + ",") {
- functionToken := prefix + "_F_" + currentFunction
- if _, ok := functions[functionToken]; !ok {
- functions[functionToken] = -1
- }
- }
-
handleDeclareMacro(line, "_R_", "OPENSSL_DECLARE_ERROR_REASON(", reasons)
- handleDeclareMacro(line, "_F_", "OPENSSL_DECLARE_ERROR_FUNCTION(", functions)
for len(line) > 0 {
- i := strings.Index(line, prefix + "_")
+ i := strings.Index(line, prefix+"_")
if i == -1 {
break
}
@@ -413,25 +361,17 @@ func addFunctionsAndReasons(functions, reasons map[string]int, filename, prefix
return scanner.Err()
}
-func parseHeader(lib string, file io.Reader) (functions, reasons map[string]int, err error) {
- functions = make(map[string]int)
+func parseHeader(lib string, file io.Reader) (reasons map[string]int, err error) {
reasons = make(map[string]int)
scanner := bufio.NewScanner(file)
for scanner.Scan() {
- typ, key, value, ok := parseDefineLine(scanner.Text(), lib)
+ key, value, ok := parseDefineLine(scanner.Text(), lib)
if !ok {
continue
}
- switch typ {
- case typeFunctions:
- functions[key] = value
- case typeReasons:
- reasons[key] = value
- default:
- panic("internal error")
- }
+ reasons[key] = value
}
err = scanner.Err()
diff --git a/ssl-sources.mk b/ssl-sources.mk
index 0d15bac..a4c8470 100644
--- a/ssl-sources.mk
+++ b/ssl-sources.mk
@@ -1,5 +1,5 @@
LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/sources.mk
include $(LOCAL_PATH)/sources.mk
-LOCAL_CFLAGS += -I$(LOCAL_PATH)/src/include -Wno-unused-parameter
+LOCAL_CFLAGS += -I$(LOCAL_PATH)/src/include -Wno-unused-parameter -DBORINGSSL_ANDROID_SYSTEM
LOCAL_SRC_FILES += $(ssl_sources)
diff --git a/win-x86/crypto/cpu-x86-asm.asm b/win-x86/crypto/cpu-x86-asm.asm
deleted file mode 100644
index 4317a73..0000000
--- a/win-x86/crypto/cpu-x86-asm.asm
+++ /dev/null
@@ -1,303 +0,0 @@
-%ifidn __OUTPUT_FORMAT__,obj
-section code use32 class=code align=64
-%elifidn __OUTPUT_FORMAT__,win32
-%ifdef __YASM_VERSION_ID__
-%if __YASM_VERSION_ID__ < 01010000h
-%error yasm version 1.1.0 or later needed.
-%endif
-; Yasm automatically includes .00 and complains about redefining it.
-; https://www.tortall.net/projects/yasm/manual/html/objfmt-win32-safeseh.html
-%else
-$@feat.00 equ 1
-%endif
-section .text code align=64
-%else
-section .text code
-%endif
-global _OPENSSL_ia32_cpuid
-align 16
-_OPENSSL_ia32_cpuid:
-L$_OPENSSL_ia32_cpuid_begin:
- push ebp
- push ebx
- push esi
- push edi
- xor edx,edx
- pushfd
- pop eax
- mov ecx,eax
- xor eax,2097152
- push eax
- popfd
- pushfd
- pop eax
- xor ecx,eax
- xor eax,eax
- bt ecx,21
- jnc NEAR L$000nocpuid
- mov esi,DWORD [20+esp]
- mov DWORD [8+esi],eax
- cpuid
- mov edi,eax
- xor eax,eax
- cmp ebx,1970169159
- setne al
- mov ebp,eax
- cmp edx,1231384169
- setne al
- or ebp,eax
- cmp ecx,1818588270
- setne al
- or ebp,eax
- jz NEAR L$001intel
- cmp ebx,1752462657
- setne al
- mov esi,eax
- cmp edx,1769238117
- setne al
- or esi,eax
- cmp ecx,1145913699
- setne al
- or esi,eax
- jnz NEAR L$001intel
- mov eax,2147483648
- cpuid
- cmp eax,2147483649
- jb NEAR L$001intel
- mov esi,eax
- mov eax,2147483649
- cpuid
- or ebp,ecx
- and ebp,2049
- cmp esi,2147483656
- jb NEAR L$001intel
- mov eax,2147483656
- cpuid
- movzx esi,cl
- inc esi
- mov eax,1
- xor ecx,ecx
- cpuid
- bt edx,28
- jnc NEAR L$002generic
- shr ebx,16
- and ebx,255
- cmp ebx,esi
- ja NEAR L$002generic
- and edx,4026531839
- jmp NEAR L$002generic
-L$001intel:
- cmp edi,7
- jb NEAR L$003cacheinfo
- mov esi,DWORD [20+esp]
- mov eax,7
- xor ecx,ecx
- cpuid
- mov DWORD [8+esi],ebx
-L$003cacheinfo:
- cmp edi,4
- mov edi,-1
- jb NEAR L$004nocacheinfo
- mov eax,4
- mov ecx,0
- cpuid
- mov edi,eax
- shr edi,14
- and edi,4095
-L$004nocacheinfo:
- mov eax,1
- xor ecx,ecx
- cpuid
- and edx,3220176895
- cmp ebp,0
- jne NEAR L$005notintel
- or edx,1073741824
-L$005notintel:
- bt edx,28
- jnc NEAR L$002generic
- and edx,4026531839
- cmp edi,0
- je NEAR L$002generic
- or edx,268435456
- shr ebx,16
- cmp bl,1
- ja NEAR L$002generic
- and edx,4026531839
-L$002generic:
- and ebp,2048
- and ecx,4294965247
- mov esi,edx
- or ebp,ecx
- bt ecx,27
- jnc NEAR L$006clear_avx
- xor ecx,ecx
-db 15,1,208
- and eax,6
- cmp eax,6
- je NEAR L$007done
- cmp eax,2
- je NEAR L$006clear_avx
-L$008clear_xmm:
- and ebp,4261412861
- and esi,4278190079
-L$006clear_avx:
- and ebp,4026525695
- mov edi,DWORD [20+esp]
- and DWORD [8+edi],4294967263
-L$007done:
- mov eax,esi
- mov edx,ebp
-L$000nocpuid:
- pop edi
- pop esi
- pop ebx
- pop ebp
- ret
-;extern _OPENSSL_ia32cap_P
-global _OPENSSL_rdtsc
-align 16
-_OPENSSL_rdtsc:
-L$_OPENSSL_rdtsc_begin:
- xor eax,eax
- xor edx,edx
- lea ecx,[_OPENSSL_ia32cap_P]
- bt DWORD [ecx],4
- jnc NEAR L$009notsc
- rdtsc
-L$009notsc:
- ret
-global _OPENSSL_instrument_halt
-align 16
-_OPENSSL_instrument_halt:
-L$_OPENSSL_instrument_halt_begin:
- lea ecx,[_OPENSSL_ia32cap_P]
- bt DWORD [ecx],4
- jnc NEAR L$010nohalt
-dd 2421723150
- and eax,3
- jnz NEAR L$010nohalt
- pushfd
- pop eax
- bt eax,9
- jnc NEAR L$010nohalt
- rdtsc
- push edx
- push eax
- hlt
- rdtsc
- sub eax,DWORD [esp]
- sbb edx,DWORD [4+esp]
- add esp,8
- ret
-L$010nohalt:
- xor eax,eax
- xor edx,edx
- ret
-global _OPENSSL_far_spin
-align 16
-_OPENSSL_far_spin:
-L$_OPENSSL_far_spin_begin:
- pushfd
- pop eax
- bt eax,9
- jnc NEAR L$011nospin
- mov eax,DWORD [4+esp]
- mov ecx,DWORD [8+esp]
-dd 2430111262
- xor eax,eax
- mov edx,DWORD [ecx]
- jmp NEAR L$012spin
-align 16
-L$012spin:
- inc eax
- cmp edx,DWORD [ecx]
- je NEAR L$012spin
-dd 529567888
- ret
-L$011nospin:
- xor eax,eax
- xor edx,edx
- ret
-global _OPENSSL_wipe_cpu
-align 16
-_OPENSSL_wipe_cpu:
-L$_OPENSSL_wipe_cpu_begin:
- xor eax,eax
- xor edx,edx
- lea ecx,[_OPENSSL_ia32cap_P]
- mov ecx,DWORD [ecx]
- bt DWORD [ecx],1
- jnc NEAR L$013no_x87
- and ecx,83886080
- cmp ecx,83886080
- jne NEAR L$014no_sse2
- pxor xmm0,xmm0
- pxor xmm1,xmm1
- pxor xmm2,xmm2
- pxor xmm3,xmm3
- pxor xmm4,xmm4
- pxor xmm5,xmm5
- pxor xmm6,xmm6
- pxor xmm7,xmm7
-L$014no_sse2:
-dd 4007259865,4007259865,4007259865,4007259865,2430851995
-L$013no_x87:
- lea eax,[4+esp]
- ret
-global _OPENSSL_atomic_add
-align 16
-_OPENSSL_atomic_add:
-L$_OPENSSL_atomic_add_begin:
- mov edx,DWORD [4+esp]
- mov ecx,DWORD [8+esp]
- push ebx
- nop
- mov eax,DWORD [edx]
-L$015spin:
- lea ebx,[ecx*1+eax]
- nop
-dd 447811568
- jne NEAR L$015spin
- mov eax,ebx
- pop ebx
- ret
-global _OPENSSL_indirect_call
-align 16
-_OPENSSL_indirect_call:
-L$_OPENSSL_indirect_call_begin:
- push ebp
- mov ebp,esp
- sub esp,28
- mov ecx,DWORD [12+ebp]
- mov DWORD [esp],ecx
- mov edx,DWORD [16+ebp]
- mov DWORD [4+esp],edx
- mov eax,DWORD [20+ebp]
- mov DWORD [8+esp],eax
- mov eax,DWORD [24+ebp]
- mov DWORD [12+esp],eax
- mov eax,DWORD [28+ebp]
- mov DWORD [16+esp],eax
- mov eax,DWORD [32+ebp]
- mov DWORD [20+esp],eax
- mov eax,DWORD [36+ebp]
- mov DWORD [24+esp],eax
- call DWORD [8+ebp]
- mov esp,ebp
- pop ebp
- ret
-global _OPENSSL_ia32_rdrand
-align 16
-_OPENSSL_ia32_rdrand:
-L$_OPENSSL_ia32_rdrand_begin:
- mov ecx,8
-L$016loop:
-db 15,199,240
- jc NEAR L$017break
- loop L$016loop
-L$017break:
- cmp eax,0
- cmove eax,ecx
- ret
-segment .bss
-common _OPENSSL_ia32cap_P 16
diff --git a/win-x86/crypto/sha/sha1-586.asm b/win-x86/crypto/sha/sha1-586.asm
index e24449d..cee8c62 100644
--- a/win-x86/crypto/sha/sha1-586.asm
+++ b/win-x86/crypto/sha/sha1-586.asm
@@ -35,8 +35,11 @@ L$000pic_point:
mov ecx,DWORD [8+esi]
test eax,16777216
jz NEAR L$001x86
- test ecx,536870912
- jnz NEAR L$shaext_shortcut
+ 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:
@@ -1405,7 +1408,7 @@ L$002loop:
pop ebp
ret
align 16
-__sha1_block_data_order_shaext:
+__sha1_block_data_order_ssse3:
push ebp
push ebx
push esi
@@ -1414,174 +1417,6 @@ __sha1_block_data_order_shaext:
L$003pic_point:
pop ebp
lea ebp,[(L$K_XX_XX-L$003pic_point)+ebp]
-L$shaext_shortcut:
- mov edi,DWORD [20+esp]
- mov ebx,esp
- mov esi,DWORD [24+esp]
- mov ecx,DWORD [28+esp]
- sub esp,32
- movdqu xmm0,[edi]
- movd xmm1,DWORD [16+edi]
- and esp,-32
- movdqa xmm3,[80+ebp]
- movdqu xmm4,[esi]
- pshufd xmm0,xmm0,27
- movdqu xmm5,[16+esi]
- pshufd xmm1,xmm1,27
- movdqu xmm6,[32+esi]
-db 102,15,56,0,227
- movdqu xmm7,[48+esi]
-db 102,15,56,0,235
-db 102,15,56,0,243
-db 102,15,56,0,251
- jmp NEAR L$004loop_shaext
-align 16
-L$004loop_shaext:
- dec ecx
- lea eax,[64+esi]
- movdqa [esp],xmm1
- paddd xmm1,xmm4
- cmovne esi,eax
- movdqa [16+esp],xmm0
-db 15,56,201,229
- movdqa xmm2,xmm0
-db 15,58,204,193,0
-db 15,56,200,213
- pxor xmm4,xmm6
-db 15,56,201,238
-db 15,56,202,231
- movdqa xmm1,xmm0
-db 15,58,204,194,0
-db 15,56,200,206
- pxor xmm5,xmm7
-db 15,56,202,236
-db 15,56,201,247
- movdqa xmm2,xmm0
-db 15,58,204,193,0
-db 15,56,200,215
- pxor xmm6,xmm4
-db 15,56,201,252
-db 15,56,202,245
- movdqa xmm1,xmm0
-db 15,58,204,194,0
-db 15,56,200,204
- pxor xmm7,xmm5
-db 15,56,202,254
-db 15,56,201,229
- movdqa xmm2,xmm0
-db 15,58,204,193,0
-db 15,56,200,213
- pxor xmm4,xmm6
-db 15,56,201,238
-db 15,56,202,231
- movdqa xmm1,xmm0
-db 15,58,204,194,1
-db 15,56,200,206
- pxor xmm5,xmm7
-db 15,56,202,236
-db 15,56,201,247
- movdqa xmm2,xmm0
-db 15,58,204,193,1
-db 15,56,200,215
- pxor xmm6,xmm4
-db 15,56,201,252
-db 15,56,202,245
- movdqa xmm1,xmm0
-db 15,58,204,194,1
-db 15,56,200,204
- pxor xmm7,xmm5
-db 15,56,202,254
-db 15,56,201,229
- movdqa xmm2,xmm0
-db 15,58,204,193,1
-db 15,56,200,213
- pxor xmm4,xmm6
-db 15,56,201,238
-db 15,56,202,231
- movdqa xmm1,xmm0
-db 15,58,204,194,1
-db 15,56,200,206
- pxor xmm5,xmm7
-db 15,56,202,236
-db 15,56,201,247
- movdqa xmm2,xmm0
-db 15,58,204,193,2
-db 15,56,200,215
- pxor xmm6,xmm4
-db 15,56,201,252
-db 15,56,202,245
- movdqa xmm1,xmm0
-db 15,58,204,194,2
-db 15,56,200,204
- pxor xmm7,xmm5
-db 15,56,202,254
-db 15,56,201,229
- movdqa xmm2,xmm0
-db 15,58,204,193,2
-db 15,56,200,213
- pxor xmm4,xmm6
-db 15,56,201,238
-db 15,56,202,231
- movdqa xmm1,xmm0
-db 15,58,204,194,2
-db 15,56,200,206
- pxor xmm5,xmm7
-db 15,56,202,236
-db 15,56,201,247
- movdqa xmm2,xmm0
-db 15,58,204,193,2
-db 15,56,200,215
- pxor xmm6,xmm4
-db 15,56,201,252
-db 15,56,202,245
- movdqa xmm1,xmm0
-db 15,58,204,194,3
-db 15,56,200,204
- pxor xmm7,xmm5
-db 15,56,202,254
- movdqu xmm4,[esi]
- movdqa xmm2,xmm0
-db 15,58,204,193,3
-db 15,56,200,213
- movdqu xmm5,[16+esi]
-db 102,15,56,0,227
- movdqa xmm1,xmm0
-db 15,58,204,194,3
-db 15,56,200,206
- movdqu xmm6,[32+esi]
-db 102,15,56,0,235
- movdqa xmm2,xmm0
-db 15,58,204,193,3
-db 15,56,200,215
- movdqu xmm7,[48+esi]
-db 102,15,56,0,243
- movdqa xmm1,xmm0
-db 15,58,204,194,3
- movdqa xmm2,[esp]
-db 102,15,56,0,251
-db 15,56,200,202
- paddd xmm0,[16+esp]
- jnz NEAR L$004loop_shaext
- pshufd xmm0,xmm0,27
- pshufd xmm1,xmm1,27
- movdqu [edi],xmm0
- movd DWORD [16+edi],xmm1
- mov esp,ebx
- pop edi
- pop esi
- pop ebx
- pop ebp
- ret
-align 16
-__sha1_block_data_order_ssse3:
- push ebp
- push ebx
- push esi
- push edi
- call L$005pic_point
-L$005pic_point:
- pop ebp
- lea ebp,[(L$K_XX_XX-L$005pic_point)+ebp]
L$ssse3_shortcut:
movdqa xmm7,[ebp]
movdqa xmm0,[16+ebp]
@@ -1634,9 +1469,9 @@ db 102,15,56,0,222
xor ebp,edx
pshufd xmm4,xmm0,238
and esi,ebp
- jmp NEAR L$006loop
+ jmp NEAR L$004loop
align 16
-L$006loop:
+L$004loop:
ror ebx,2
xor esi,edx
mov ebp,eax
@@ -2539,7 +2374,7 @@ L$006loop:
add ecx,edx
mov ebp,DWORD [196+esp]
cmp ebp,DWORD [200+esp]
- je NEAR L$007done
+ je NEAR L$005done
movdqa xmm7,[160+esp]
movdqa xmm6,[176+esp]
movdqu xmm0,[ebp]
@@ -2674,9 +2509,9 @@ db 102,15,56,0,222
pshufd xmm4,xmm0,238
and esi,ebx
mov ebx,ebp
- jmp NEAR L$006loop
+ jmp NEAR L$004loop
align 16
-L$007done:
+L$005done:
add ebx,DWORD [16+esp]
xor esi,edi
mov ebp,ecx
@@ -2789,6 +2624,1174 @@ L$007done:
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 fe36bc5..3e7cfcc 100644
--- a/win-x86/crypto/sha/sha256-586.asm
+++ b/win-x86/crypto/sha/sha256-586.asm
@@ -49,11 +49,10 @@ L$000pic_point:
jz NEAR L$003no_xmm
and ecx,1073741824
and ebx,268435968
- test edx,536870912
- jnz NEAR L$004shaext
or ecx,ebx
and ecx,1342177280
cmp ecx,1342177280
+ je NEAR L$004AVX
test ebx,512
jnz NEAR L$005SSSE3
L$003no_xmm:
@@ -3179,204 +3178,6 @@ L$009grand_loop:
pop ebp
ret
align 32
-L$004shaext:
- sub esp,32
- movdqu xmm1,[esi]
- lea ebp,[128+ebp]
- movdqu xmm2,[16+esi]
- movdqa xmm7,[128+ebp]
- pshufd xmm0,xmm1,27
- pshufd xmm1,xmm1,177
- pshufd xmm2,xmm2,27
-db 102,15,58,15,202,8
- punpcklqdq xmm2,xmm0
- jmp NEAR L$010loop_shaext
-align 16
-L$010loop_shaext:
- movdqu xmm3,[edi]
- movdqu xmm4,[16+edi]
- movdqu xmm5,[32+edi]
-db 102,15,56,0,223
- movdqu xmm6,[48+edi]
- movdqa [16+esp],xmm2
- movdqa xmm0,[ebp-128]
- paddd xmm0,xmm3
-db 102,15,56,0,231
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- nop
- movdqa [esp],xmm1
-db 15,56,203,202
- movdqa xmm0,[ebp-112]
- paddd xmm0,xmm4
-db 102,15,56,0,239
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- lea edi,[64+edi]
-db 15,56,204,220
-db 15,56,203,202
- movdqa xmm0,[ebp-96]
- paddd xmm0,xmm5
-db 102,15,56,0,247
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- movdqa xmm7,xmm6
-db 102,15,58,15,253,4
- nop
- paddd xmm3,xmm7
-db 15,56,204,229
-db 15,56,203,202
- movdqa xmm0,[ebp-80]
- paddd xmm0,xmm6
-db 15,56,205,222
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- movdqa xmm7,xmm3
-db 102,15,58,15,254,4
- nop
- paddd xmm4,xmm7
-db 15,56,204,238
-db 15,56,203,202
- movdqa xmm0,[ebp-64]
- paddd xmm0,xmm3
-db 15,56,205,227
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- movdqa xmm7,xmm4
-db 102,15,58,15,251,4
- nop
- paddd xmm5,xmm7
-db 15,56,204,243
-db 15,56,203,202
- movdqa xmm0,[ebp-48]
- paddd xmm0,xmm4
-db 15,56,205,236
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- movdqa xmm7,xmm5
-db 102,15,58,15,252,4
- nop
- paddd xmm6,xmm7
-db 15,56,204,220
-db 15,56,203,202
- movdqa xmm0,[ebp-32]
- paddd xmm0,xmm5
-db 15,56,205,245
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- movdqa xmm7,xmm6
-db 102,15,58,15,253,4
- nop
- paddd xmm3,xmm7
-db 15,56,204,229
-db 15,56,203,202
- movdqa xmm0,[ebp-16]
- paddd xmm0,xmm6
-db 15,56,205,222
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- movdqa xmm7,xmm3
-db 102,15,58,15,254,4
- nop
- paddd xmm4,xmm7
-db 15,56,204,238
-db 15,56,203,202
- movdqa xmm0,[ebp]
- paddd xmm0,xmm3
-db 15,56,205,227
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- movdqa xmm7,xmm4
-db 102,15,58,15,251,4
- nop
- paddd xmm5,xmm7
-db 15,56,204,243
-db 15,56,203,202
- movdqa xmm0,[16+ebp]
- paddd xmm0,xmm4
-db 15,56,205,236
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- movdqa xmm7,xmm5
-db 102,15,58,15,252,4
- nop
- paddd xmm6,xmm7
-db 15,56,204,220
-db 15,56,203,202
- movdqa xmm0,[32+ebp]
- paddd xmm0,xmm5
-db 15,56,205,245
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- movdqa xmm7,xmm6
-db 102,15,58,15,253,4
- nop
- paddd xmm3,xmm7
-db 15,56,204,229
-db 15,56,203,202
- movdqa xmm0,[48+ebp]
- paddd xmm0,xmm6
-db 15,56,205,222
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- movdqa xmm7,xmm3
-db 102,15,58,15,254,4
- nop
- paddd xmm4,xmm7
-db 15,56,204,238
-db 15,56,203,202
- movdqa xmm0,[64+ebp]
- paddd xmm0,xmm3
-db 15,56,205,227
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- movdqa xmm7,xmm4
-db 102,15,58,15,251,4
- nop
- paddd xmm5,xmm7
-db 15,56,204,243
-db 15,56,203,202
- movdqa xmm0,[80+ebp]
- paddd xmm0,xmm4
-db 15,56,205,236
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- movdqa xmm7,xmm5
-db 102,15,58,15,252,4
-db 15,56,203,202
- paddd xmm6,xmm7
- movdqa xmm0,[96+ebp]
- paddd xmm0,xmm5
-db 15,56,203,209
- pshufd xmm0,xmm0,14
-db 15,56,205,245
- movdqa xmm7,[128+ebp]
-db 15,56,203,202
- movdqa xmm0,[112+ebp]
- paddd xmm0,xmm6
- nop
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- cmp eax,edi
- nop
-db 15,56,203,202
- paddd xmm2,[16+esp]
- paddd xmm1,[esp]
- jnz NEAR L$010loop_shaext
- pshufd xmm2,xmm2,177
- pshufd xmm7,xmm1,27
- pshufd xmm1,xmm1,177
- punpckhqdq xmm1,xmm2
-db 102,15,58,15,215,8
- mov esp,DWORD [44+esp]
- movdqu [esi],xmm1
- movdqu [16+esi],xmm2
- pop edi
- pop esi
- pop ebx
- pop ebp
- ret
-align 32
L$005SSSE3:
lea esp,[esp-96]
mov eax,DWORD [esi]
@@ -3396,9 +3197,9 @@ L$005SSSE3:
mov DWORD [24+esp],ecx
mov DWORD [28+esp],esi
movdqa xmm7,[256+ebp]
- jmp NEAR L$011grand_ssse3
+ jmp NEAR L$010grand_ssse3
align 16
-L$011grand_ssse3:
+L$010grand_ssse3:
movdqu xmm0,[edi]
movdqu xmm1,[16+edi]
movdqu xmm2,[32+edi]
@@ -3421,9 +3222,9 @@ db 102,15,56,0,223
paddd xmm7,xmm3
movdqa [64+esp],xmm6
movdqa [80+esp],xmm7
- jmp NEAR L$012ssse3_00_47
+ jmp NEAR L$011ssse3_00_47
align 16
-L$012ssse3_00_47:
+L$011ssse3_00_47:
add ebp,64
mov ecx,edx
movdqa xmm4,xmm1
@@ -4066,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$012ssse3_00_47
+ jne NEAR L$011ssse3_00_47
mov ecx,edx
ror edx,14
mov esi,DWORD [20+esp]
@@ -4580,8 +4381,1189 @@ db 102,15,58,15,249,4
movdqa xmm7,[64+ebp]
sub ebp,192
cmp edi,DWORD [104+esp]
- jb NEAR L$011grand_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
diff --git a/win-x86_64/crypto/bn/modexp512-x86_64.asm b/win-x86_64/crypto/bn/modexp512-x86_64.asm
deleted file mode 100644
index d3e4a61..0000000
--- a/win-x86_64/crypto/bn/modexp512-x86_64.asm
+++ /dev/null
@@ -1,1887 +0,0 @@
-OPTION DOTNAME
-.text$ SEGMENT ALIGN(256) 'CODE'
-
-
-ALIGN 16
-MULADD_128x512 PROC PRIVATE
- mov rax,QWORD PTR[rsi]
- mul rbp
- add r8,rax
- adc rdx,0
- mov QWORD PTR[rcx],r8
- mov rbx,rdx
-
- mov rax,QWORD PTR[8+rsi]
- mul rbp
- add r9,rax
- adc rdx,0
- add r9,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[16+rsi]
- mul rbp
- add r10,rax
- adc rdx,0
- add r10,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[24+rsi]
- mul rbp
- add r11,rax
- adc rdx,0
- add r11,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[32+rsi]
- mul rbp
- add r12,rax
- adc rdx,0
- add r12,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[40+rsi]
- mul rbp
- add r13,rax
- adc rdx,0
- add r13,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[48+rsi]
- mul rbp
- add r14,rax
- adc rdx,0
- add r14,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[56+rsi]
- mul rbp
- add r15,rax
- adc rdx,0
- add r15,rbx
- adc rdx,0
- mov r8,rdx
- mov rbp,QWORD PTR[8+rdi]
- mov rax,QWORD PTR[rsi]
- mul rbp
- add r9,rax
- adc rdx,0
- mov QWORD PTR[8+rcx],r9
- mov rbx,rdx
-
- mov rax,QWORD PTR[8+rsi]
- mul rbp
- add r10,rax
- adc rdx,0
- add r10,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[16+rsi]
- mul rbp
- add r11,rax
- adc rdx,0
- add r11,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[24+rsi]
- mul rbp
- add r12,rax
- adc rdx,0
- add r12,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[32+rsi]
- mul rbp
- add r13,rax
- adc rdx,0
- add r13,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[40+rsi]
- mul rbp
- add r14,rax
- adc rdx,0
- add r14,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[48+rsi]
- mul rbp
- add r15,rax
- adc rdx,0
- add r15,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[56+rsi]
- mul rbp
- add r8,rax
- adc rdx,0
- add r8,rbx
- adc rdx,0
- mov r9,rdx
- DB 0F3h,0C3h ;repret
-MULADD_128x512 ENDP
-
-ALIGN 16
-mont_reduce PROC PRIVATE
- lea rdi,QWORD PTR[192+rsp]
- mov rsi,QWORD PTR[32+rsp]
- add rsi,576
- lea rcx,QWORD PTR[520+rsp]
-
- mov rbp,QWORD PTR[96+rcx]
- mov rax,QWORD PTR[rsi]
- mul rbp
- mov r8,QWORD PTR[rcx]
- add r8,rax
- adc rdx,0
- mov QWORD PTR[rdi],r8
- mov rbx,rdx
-
- mov rax,QWORD PTR[8+rsi]
- mul rbp
- mov r9,QWORD PTR[8+rcx]
- add r9,rax
- adc rdx,0
- add r9,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[16+rsi]
- mul rbp
- mov r10,QWORD PTR[16+rcx]
- add r10,rax
- adc rdx,0
- add r10,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[24+rsi]
- mul rbp
- mov r11,QWORD PTR[24+rcx]
- add r11,rax
- adc rdx,0
- add r11,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[32+rsi]
- mul rbp
- mov r12,QWORD PTR[32+rcx]
- add r12,rax
- adc rdx,0
- add r12,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[40+rsi]
- mul rbp
- mov r13,QWORD PTR[40+rcx]
- add r13,rax
- adc rdx,0
- add r13,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[48+rsi]
- mul rbp
- mov r14,QWORD PTR[48+rcx]
- add r14,rax
- adc rdx,0
- add r14,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[56+rsi]
- mul rbp
- mov r15,QWORD PTR[56+rcx]
- add r15,rax
- adc rdx,0
- add r15,rbx
- adc rdx,0
- mov r8,rdx
- mov rbp,QWORD PTR[104+rcx]
- mov rax,QWORD PTR[rsi]
- mul rbp
- add r9,rax
- adc rdx,0
- mov QWORD PTR[8+rdi],r9
- mov rbx,rdx
-
- mov rax,QWORD PTR[8+rsi]
- mul rbp
- add r10,rax
- adc rdx,0
- add r10,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[16+rsi]
- mul rbp
- add r11,rax
- adc rdx,0
- add r11,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[24+rsi]
- mul rbp
- add r12,rax
- adc rdx,0
- add r12,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[32+rsi]
- mul rbp
- add r13,rax
- adc rdx,0
- add r13,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[40+rsi]
- mul rbp
- add r14,rax
- adc rdx,0
- add r14,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[48+rsi]
- mul rbp
- add r15,rax
- adc rdx,0
- add r15,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[56+rsi]
- mul rbp
- add r8,rax
- adc rdx,0
- add r8,rbx
- adc rdx,0
- mov r9,rdx
- mov rbp,QWORD PTR[112+rcx]
- mov rax,QWORD PTR[rsi]
- mul rbp
- add r10,rax
- adc rdx,0
- mov QWORD PTR[16+rdi],r10
- mov rbx,rdx
-
- mov rax,QWORD PTR[8+rsi]
- mul rbp
- add r11,rax
- adc rdx,0
- add r11,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[16+rsi]
- mul rbp
- add r12,rax
- adc rdx,0
- add r12,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[24+rsi]
- mul rbp
- add r13,rax
- adc rdx,0
- add r13,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[32+rsi]
- mul rbp
- add r14,rax
- adc rdx,0
- add r14,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[40+rsi]
- mul rbp
- add r15,rax
- adc rdx,0
- add r15,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[48+rsi]
- mul rbp
- add r8,rax
- adc rdx,0
- add r8,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[56+rsi]
- mul rbp
- add r9,rax
- adc rdx,0
- add r9,rbx
- adc rdx,0
- mov r10,rdx
- mov rbp,QWORD PTR[120+rcx]
- mov rax,QWORD PTR[rsi]
- mul rbp
- add r11,rax
- adc rdx,0
- mov QWORD PTR[24+rdi],r11
- mov rbx,rdx
-
- mov rax,QWORD PTR[8+rsi]
- mul rbp
- add r12,rax
- adc rdx,0
- add r12,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[16+rsi]
- mul rbp
- add r13,rax
- adc rdx,0
- add r13,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[24+rsi]
- mul rbp
- add r14,rax
- adc rdx,0
- add r14,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[32+rsi]
- mul rbp
- add r15,rax
- adc rdx,0
- add r15,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[40+rsi]
- mul rbp
- add r8,rax
- adc rdx,0
- add r8,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[48+rsi]
- mul rbp
- add r9,rax
- adc rdx,0
- add r9,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[56+rsi]
- mul rbp
- add r10,rax
- adc rdx,0
- add r10,rbx
- adc rdx,0
- mov r11,rdx
- xor rax,rax
-
- add r8,QWORD PTR[64+rcx]
- adc r9,QWORD PTR[72+rcx]
- adc r10,QWORD PTR[80+rcx]
- adc r11,QWORD PTR[88+rcx]
- adc rax,0
-
-
-
-
- mov QWORD PTR[64+rdi],r8
- mov QWORD PTR[72+rdi],r9
- mov rbp,r10
- mov QWORD PTR[88+rdi],r11
-
- mov QWORD PTR[384+rsp],rax
-
- mov r8,QWORD PTR[rdi]
- mov r9,QWORD PTR[8+rdi]
- mov r10,QWORD PTR[16+rdi]
- mov r11,QWORD PTR[24+rdi]
-
-
-
-
-
-
-
-
- add rdi,8*10
-
- add rsi,64
- lea rcx,QWORD PTR[296+rsp]
-
- call MULADD_128x512
-
- mov rax,QWORD PTR[384+rsp]
-
-
- add r8,QWORD PTR[((-16))+rdi]
- adc r9,QWORD PTR[((-8))+rdi]
- mov QWORD PTR[64+rcx],r8
- mov QWORD PTR[72+rcx],r9
-
- adc rax,rax
- mov QWORD PTR[384+rsp],rax
-
- lea rdi,QWORD PTR[192+rsp]
- add rsi,64
-
-
-
-
-
- mov r8,QWORD PTR[rsi]
- mov rbx,QWORD PTR[8+rsi]
-
- mov rax,QWORD PTR[rcx]
- mul r8
- mov rbp,rax
- mov r9,rdx
-
- mov rax,QWORD PTR[8+rcx]
- mul r8
- add r9,rax
-
- mov rax,QWORD PTR[rcx]
- mul rbx
- add r9,rax
-
- mov QWORD PTR[8+rdi],r9
-
-
- sub rsi,192
-
- mov r8,QWORD PTR[rcx]
- mov r9,QWORD PTR[8+rcx]
-
- call MULADD_128x512
-
-
-
-
- mov rax,QWORD PTR[rsi]
- mov rbx,QWORD PTR[8+rsi]
- mov rdi,QWORD PTR[16+rsi]
- mov rdx,QWORD PTR[24+rsi]
-
-
- mov rbp,QWORD PTR[384+rsp]
-
- add r8,QWORD PTR[64+rcx]
- adc r9,QWORD PTR[72+rcx]
-
-
- adc rbp,rbp
-
-
-
- shl rbp,3
- mov rcx,QWORD PTR[32+rsp]
- add rbp,rcx
-
-
- xor rsi,rsi
-
- add r10,QWORD PTR[rbp]
- adc r11,QWORD PTR[64+rbp]
- adc r12,QWORD PTR[128+rbp]
- adc r13,QWORD PTR[192+rbp]
- adc r14,QWORD PTR[256+rbp]
- adc r15,QWORD PTR[320+rbp]
- adc r8,QWORD PTR[384+rbp]
- adc r9,QWORD PTR[448+rbp]
-
-
-
- sbb rsi,0
-
-
- and rax,rsi
- and rbx,rsi
- and rdi,rsi
- and rdx,rsi
-
- mov rbp,1
- sub r10,rax
- sbb r11,rbx
- sbb r12,rdi
- sbb r13,rdx
-
-
-
-
- sbb rbp,0
-
-
-
- add rcx,512
- mov rax,QWORD PTR[32+rcx]
- mov rbx,QWORD PTR[40+rcx]
- mov rdi,QWORD PTR[48+rcx]
- mov rdx,QWORD PTR[56+rcx]
-
-
-
- and rax,rsi
- and rbx,rsi
- and rdi,rsi
- and rdx,rsi
-
-
-
- sub rbp,1
-
- sbb r14,rax
- sbb r15,rbx
- sbb r8,rdi
- sbb r9,rdx
-
-
-
- mov rsi,QWORD PTR[144+rsp]
- mov QWORD PTR[rsi],r10
- mov QWORD PTR[8+rsi],r11
- mov QWORD PTR[16+rsi],r12
- mov QWORD PTR[24+rsi],r13
- mov QWORD PTR[32+rsi],r14
- mov QWORD PTR[40+rsi],r15
- mov QWORD PTR[48+rsi],r8
- mov QWORD PTR[56+rsi],r9
-
- DB 0F3h,0C3h ;repret
-mont_reduce ENDP
-
-ALIGN 16
-mont_mul_a3b PROC PRIVATE
-
-
-
-
- mov rbp,QWORD PTR[rdi]
-
- mov rax,r10
- mul rbp
- mov QWORD PTR[520+rsp],rax
- mov r10,rdx
- mov rax,r11
- mul rbp
- add r10,rax
- adc rdx,0
- mov r11,rdx
- mov rax,r12
- mul rbp
- add r11,rax
- adc rdx,0
- mov r12,rdx
- mov rax,r13
- mul rbp
- add r12,rax
- adc rdx,0
- mov r13,rdx
- mov rax,r14
- mul rbp
- add r13,rax
- adc rdx,0
- mov r14,rdx
- mov rax,r15
- mul rbp
- add r14,rax
- adc rdx,0
- mov r15,rdx
- mov rax,r8
- mul rbp
- add r15,rax
- adc rdx,0
- mov r8,rdx
- mov rax,r9
- mul rbp
- add r8,rax
- adc rdx,0
- mov r9,rdx
- mov rbp,QWORD PTR[8+rdi]
- mov rax,QWORD PTR[rsi]
- mul rbp
- add r10,rax
- adc rdx,0
- mov QWORD PTR[528+rsp],r10
- mov rbx,rdx
-
- mov rax,QWORD PTR[8+rsi]
- mul rbp
- add r11,rax
- adc rdx,0
- add r11,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[16+rsi]
- mul rbp
- add r12,rax
- adc rdx,0
- add r12,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[24+rsi]
- mul rbp
- add r13,rax
- adc rdx,0
- add r13,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[32+rsi]
- mul rbp
- add r14,rax
- adc rdx,0
- add r14,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[40+rsi]
- mul rbp
- add r15,rax
- adc rdx,0
- add r15,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[48+rsi]
- mul rbp
- add r8,rax
- adc rdx,0
- add r8,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[56+rsi]
- mul rbp
- add r9,rax
- adc rdx,0
- add r9,rbx
- adc rdx,0
- mov r10,rdx
- mov rbp,QWORD PTR[16+rdi]
- mov rax,QWORD PTR[rsi]
- mul rbp
- add r11,rax
- adc rdx,0
- mov QWORD PTR[536+rsp],r11
- mov rbx,rdx
-
- mov rax,QWORD PTR[8+rsi]
- mul rbp
- add r12,rax
- adc rdx,0
- add r12,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[16+rsi]
- mul rbp
- add r13,rax
- adc rdx,0
- add r13,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[24+rsi]
- mul rbp
- add r14,rax
- adc rdx,0
- add r14,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[32+rsi]
- mul rbp
- add r15,rax
- adc rdx,0
- add r15,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[40+rsi]
- mul rbp
- add r8,rax
- adc rdx,0
- add r8,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[48+rsi]
- mul rbp
- add r9,rax
- adc rdx,0
- add r9,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[56+rsi]
- mul rbp
- add r10,rax
- adc rdx,0
- add r10,rbx
- adc rdx,0
- mov r11,rdx
- mov rbp,QWORD PTR[24+rdi]
- mov rax,QWORD PTR[rsi]
- mul rbp
- add r12,rax
- adc rdx,0
- mov QWORD PTR[544+rsp],r12
- mov rbx,rdx
-
- mov rax,QWORD PTR[8+rsi]
- mul rbp
- add r13,rax
- adc rdx,0
- add r13,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[16+rsi]
- mul rbp
- add r14,rax
- adc rdx,0
- add r14,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[24+rsi]
- mul rbp
- add r15,rax
- adc rdx,0
- add r15,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[32+rsi]
- mul rbp
- add r8,rax
- adc rdx,0
- add r8,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[40+rsi]
- mul rbp
- add r9,rax
- adc rdx,0
- add r9,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[48+rsi]
- mul rbp
- add r10,rax
- adc rdx,0
- add r10,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[56+rsi]
- mul rbp
- add r11,rax
- adc rdx,0
- add r11,rbx
- adc rdx,0
- mov r12,rdx
- mov rbp,QWORD PTR[32+rdi]
- mov rax,QWORD PTR[rsi]
- mul rbp
- add r13,rax
- adc rdx,0
- mov QWORD PTR[552+rsp],r13
- mov rbx,rdx
-
- mov rax,QWORD PTR[8+rsi]
- mul rbp
- add r14,rax
- adc rdx,0
- add r14,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[16+rsi]
- mul rbp
- add r15,rax
- adc rdx,0
- add r15,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[24+rsi]
- mul rbp
- add r8,rax
- adc rdx,0
- add r8,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[32+rsi]
- mul rbp
- add r9,rax
- adc rdx,0
- add r9,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[40+rsi]
- mul rbp
- add r10,rax
- adc rdx,0
- add r10,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[48+rsi]
- mul rbp
- add r11,rax
- adc rdx,0
- add r11,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[56+rsi]
- mul rbp
- add r12,rax
- adc rdx,0
- add r12,rbx
- adc rdx,0
- mov r13,rdx
- mov rbp,QWORD PTR[40+rdi]
- mov rax,QWORD PTR[rsi]
- mul rbp
- add r14,rax
- adc rdx,0
- mov QWORD PTR[560+rsp],r14
- mov rbx,rdx
-
- mov rax,QWORD PTR[8+rsi]
- mul rbp
- add r15,rax
- adc rdx,0
- add r15,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[16+rsi]
- mul rbp
- add r8,rax
- adc rdx,0
- add r8,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[24+rsi]
- mul rbp
- add r9,rax
- adc rdx,0
- add r9,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[32+rsi]
- mul rbp
- add r10,rax
- adc rdx,0
- add r10,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[40+rsi]
- mul rbp
- add r11,rax
- adc rdx,0
- add r11,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[48+rsi]
- mul rbp
- add r12,rax
- adc rdx,0
- add r12,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[56+rsi]
- mul rbp
- add r13,rax
- adc rdx,0
- add r13,rbx
- adc rdx,0
- mov r14,rdx
- mov rbp,QWORD PTR[48+rdi]
- mov rax,QWORD PTR[rsi]
- mul rbp
- add r15,rax
- adc rdx,0
- mov QWORD PTR[568+rsp],r15
- mov rbx,rdx
-
- mov rax,QWORD PTR[8+rsi]
- mul rbp
- add r8,rax
- adc rdx,0
- add r8,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[16+rsi]
- mul rbp
- add r9,rax
- adc rdx,0
- add r9,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[24+rsi]
- mul rbp
- add r10,rax
- adc rdx,0
- add r10,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[32+rsi]
- mul rbp
- add r11,rax
- adc rdx,0
- add r11,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[40+rsi]
- mul rbp
- add r12,rax
- adc rdx,0
- add r12,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[48+rsi]
- mul rbp
- add r13,rax
- adc rdx,0
- add r13,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[56+rsi]
- mul rbp
- add r14,rax
- adc rdx,0
- add r14,rbx
- adc rdx,0
- mov r15,rdx
- mov rbp,QWORD PTR[56+rdi]
- mov rax,QWORD PTR[rsi]
- mul rbp
- add r8,rax
- adc rdx,0
- mov QWORD PTR[576+rsp],r8
- mov rbx,rdx
-
- mov rax,QWORD PTR[8+rsi]
- mul rbp
- add r9,rax
- adc rdx,0
- add r9,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[16+rsi]
- mul rbp
- add r10,rax
- adc rdx,0
- add r10,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[24+rsi]
- mul rbp
- add r11,rax
- adc rdx,0
- add r11,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[32+rsi]
- mul rbp
- add r12,rax
- adc rdx,0
- add r12,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[40+rsi]
- mul rbp
- add r13,rax
- adc rdx,0
- add r13,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[48+rsi]
- mul rbp
- add r14,rax
- adc rdx,0
- add r14,rbx
- adc rdx,0
- mov rbx,rdx
-
- mov rax,QWORD PTR[56+rsi]
- mul rbp
- add r15,rax
- adc rdx,0
- add r15,rbx
- adc rdx,0
- mov r8,rdx
- mov QWORD PTR[584+rsp],r9
- mov QWORD PTR[592+rsp],r10
- mov QWORD PTR[600+rsp],r11
- mov QWORD PTR[608+rsp],r12
- mov QWORD PTR[616+rsp],r13
- mov QWORD PTR[624+rsp],r14
- mov QWORD PTR[632+rsp],r15
- mov QWORD PTR[640+rsp],r8
-
-
-
-
-
- jmp mont_reduce
-
-
-mont_mul_a3b ENDP
-
-ALIGN 16
-sqr_reduce PROC PRIVATE
- mov rcx,QWORD PTR[16+rsp]
-
-
-
- mov rbx,r10
-
- mov rax,r11
- mul rbx
- mov QWORD PTR[528+rsp],rax
- mov r10,rdx
- mov rax,r12
- mul rbx
- add r10,rax
- adc rdx,0
- mov r11,rdx
- mov rax,r13
- mul rbx
- add r11,rax
- adc rdx,0
- mov r12,rdx
- mov rax,r14
- mul rbx
- add r12,rax
- adc rdx,0
- mov r13,rdx
- mov rax,r15
- mul rbx
- add r13,rax
- adc rdx,0
- mov r14,rdx
- mov rax,r8
- mul rbx
- add r14,rax
- adc rdx,0
- mov r15,rdx
- mov rax,r9
- mul rbx
- add r15,rax
- adc rdx,0
- mov rsi,rdx
-
- mov QWORD PTR[536+rsp],r10
-
-
-
-
-
- mov rbx,QWORD PTR[8+rcx]
-
- mov rax,QWORD PTR[16+rcx]
- mul rbx
- add r11,rax
- adc rdx,0
- mov QWORD PTR[544+rsp],r11
-
- mov r10,rdx
- mov rax,QWORD PTR[24+rcx]
- mul rbx
- add r12,rax
- adc rdx,0
- add r12,r10
- adc rdx,0
- mov QWORD PTR[552+rsp],r12
-
- mov r10,rdx
- mov rax,QWORD PTR[32+rcx]
- mul rbx
- add r13,rax
- adc rdx,0
- add r13,r10
- adc rdx,0
-
- mov r10,rdx
- mov rax,QWORD PTR[40+rcx]
- mul rbx
- add r14,rax
- adc rdx,0
- add r14,r10
- adc rdx,0
-
- mov r10,rdx
- mov rax,r8
- mul rbx
- add r15,rax
- adc rdx,0
- add r15,r10
- adc rdx,0
-
- mov r10,rdx
- mov rax,r9
- mul rbx
- add rsi,rax
- adc rdx,0
- add rsi,r10
- adc rdx,0
-
- mov r11,rdx
-
-
-
-
- mov rbx,QWORD PTR[16+rcx]
-
- mov rax,QWORD PTR[24+rcx]
- mul rbx
- add r13,rax
- adc rdx,0
- mov QWORD PTR[560+rsp],r13
-
- mov r10,rdx
- mov rax,QWORD PTR[32+rcx]
- mul rbx
- add r14,rax
- adc rdx,0
- add r14,r10
- adc rdx,0
- mov QWORD PTR[568+rsp],r14
-
- mov r10,rdx
- mov rax,QWORD PTR[40+rcx]
- mul rbx
- add r15,rax
- adc rdx,0
- add r15,r10
- adc rdx,0
-
- mov r10,rdx
- mov rax,r8
- mul rbx
- add rsi,rax
- adc rdx,0
- add rsi,r10
- adc rdx,0
-
- mov r10,rdx
- mov rax,r9
- mul rbx
- add r11,rax
- adc rdx,0
- add r11,r10
- adc rdx,0
-
- mov r12,rdx
-
-
-
-
-
- mov rbx,QWORD PTR[24+rcx]
-
- mov rax,QWORD PTR[32+rcx]
- mul rbx
- add r15,rax
- adc rdx,0
- mov QWORD PTR[576+rsp],r15
-
- mov r10,rdx
- mov rax,QWORD PTR[40+rcx]
- mul rbx
- add rsi,rax
- adc rdx,0
- add rsi,r10
- adc rdx,0
- mov QWORD PTR[584+rsp],rsi
-
- mov r10,rdx
- mov rax,r8
- mul rbx
- add r11,rax
- adc rdx,0
- add r11,r10
- adc rdx,0
-
- mov r10,rdx
- mov rax,r9
- mul rbx
- add r12,rax
- adc rdx,0
- add r12,r10
- adc rdx,0
-
- mov r15,rdx
-
-
-
-
- mov rbx,QWORD PTR[32+rcx]
-
- mov rax,QWORD PTR[40+rcx]
- mul rbx
- add r11,rax
- adc rdx,0
- mov QWORD PTR[592+rsp],r11
-
- mov r10,rdx
- mov rax,r8
- mul rbx
- add r12,rax
- adc rdx,0
- add r12,r10
- adc rdx,0
- mov QWORD PTR[600+rsp],r12
-
- mov r10,rdx
- mov rax,r9
- mul rbx
- add r15,rax
- adc rdx,0
- add r15,r10
- adc rdx,0
-
- mov r11,rdx
-
-
-
-
- mov rbx,QWORD PTR[40+rcx]
-
- mov rax,r8
- mul rbx
- add r15,rax
- adc rdx,0
- mov QWORD PTR[608+rsp],r15
-
- mov r10,rdx
- mov rax,r9
- mul rbx
- add r11,rax
- adc rdx,0
- add r11,r10
- adc rdx,0
- mov QWORD PTR[616+rsp],r11
-
- mov r12,rdx
-
-
-
-
- mov rbx,r8
-
- mov rax,r9
- mul rbx
- add r12,rax
- adc rdx,0
- mov QWORD PTR[624+rsp],r12
-
- mov QWORD PTR[632+rsp],rdx
-
-
- mov r10,QWORD PTR[528+rsp]
- mov r11,QWORD PTR[536+rsp]
- mov r12,QWORD PTR[544+rsp]
- mov r13,QWORD PTR[552+rsp]
- mov r14,QWORD PTR[560+rsp]
- mov r15,QWORD PTR[568+rsp]
-
- mov rax,QWORD PTR[24+rcx]
- mul rax
- mov rdi,rax
- mov r8,rdx
-
- add r10,r10
- adc r11,r11
- adc r12,r12
- adc r13,r13
- adc r14,r14
- adc r15,r15
- adc r8,0
-
- mov rax,QWORD PTR[rcx]
- mul rax
- mov QWORD PTR[520+rsp],rax
- mov rbx,rdx
-
- mov rax,QWORD PTR[8+rcx]
- mul rax
-
- add r10,rbx
- adc r11,rax
- adc rdx,0
-
- mov rbx,rdx
- mov QWORD PTR[528+rsp],r10
- mov QWORD PTR[536+rsp],r11
-
- mov rax,QWORD PTR[16+rcx]
- mul rax
-
- add r12,rbx
- adc r13,rax
- adc rdx,0
-
- mov rbx,rdx
-
- mov QWORD PTR[544+rsp],r12
- mov QWORD PTR[552+rsp],r13
-
- xor rbp,rbp
- add r14,rbx
- adc r15,rdi
- adc rbp,0
-
- mov QWORD PTR[560+rsp],r14
- mov QWORD PTR[568+rsp],r15
-
-
-
-
- mov r10,QWORD PTR[576+rsp]
- mov r11,QWORD PTR[584+rsp]
- mov r12,QWORD PTR[592+rsp]
- mov r13,QWORD PTR[600+rsp]
- mov r14,QWORD PTR[608+rsp]
- mov r15,QWORD PTR[616+rsp]
- mov rdi,QWORD PTR[624+rsp]
- mov rsi,QWORD PTR[632+rsp]
-
- mov rax,r9
- mul rax
- mov r9,rax
- mov rbx,rdx
-
- add r10,r10
- adc r11,r11
- adc r12,r12
- adc r13,r13
- adc r14,r14
- adc r15,r15
- adc rdi,rdi
- adc rsi,rsi
- adc rbx,0
-
- add r10,rbp
-
- mov rax,QWORD PTR[32+rcx]
- mul rax
-
- add r10,r8
- adc r11,rax
- adc rdx,0
-
- mov rbp,rdx
-
- mov QWORD PTR[576+rsp],r10
- mov QWORD PTR[584+rsp],r11
-
- mov rax,QWORD PTR[40+rcx]
- mul rax
-
- add r12,rbp
- adc r13,rax
- adc rdx,0
-
- mov rbp,rdx
-
- mov QWORD PTR[592+rsp],r12
- mov QWORD PTR[600+rsp],r13
-
- mov rax,QWORD PTR[48+rcx]
- mul rax
-
- add r14,rbp
- adc r15,rax
- adc rdx,0
-
- mov QWORD PTR[608+rsp],r14
- mov QWORD PTR[616+rsp],r15
-
- add rdi,rdx
- adc rsi,r9
- adc rbx,0
-
- mov QWORD PTR[624+rsp],rdi
- mov QWORD PTR[632+rsp],rsi
- mov QWORD PTR[640+rsp],rbx
-
- jmp mont_reduce
-
-
-sqr_reduce ENDP
-PUBLIC mod_exp_512
-
-mod_exp_512 PROC PUBLIC
- mov QWORD PTR[8+rsp],rdi ;WIN64 prologue
- mov QWORD PTR[16+rsp],rsi
- mov rax,rsp
-$L$SEH_begin_mod_exp_512::
- mov rdi,rcx
- mov rsi,rdx
- mov rdx,r8
- mov rcx,r9
-
-
- push rbp
- push rbx
- push r12
- push r13
- push r14
- push r15
-
-
- mov r8,rsp
- sub rsp,2688
- and rsp,-64
-
-
- mov QWORD PTR[rsp],r8
- mov QWORD PTR[8+rsp],rdi
- mov QWORD PTR[16+rsp],rsi
- mov QWORD PTR[24+rsp],rcx
-$L$body::
-
-
-
- pxor xmm4,xmm4
- movdqu xmm0,XMMWORD PTR[rsi]
- movdqu xmm1,XMMWORD PTR[16+rsi]
- movdqu xmm2,XMMWORD PTR[32+rsi]
- movdqu xmm3,XMMWORD PTR[48+rsi]
- movdqa XMMWORD PTR[512+rsp],xmm4
- movdqa XMMWORD PTR[528+rsp],xmm4
- movdqa XMMWORD PTR[608+rsp],xmm4
- movdqa XMMWORD PTR[624+rsp],xmm4
- movdqa XMMWORD PTR[544+rsp],xmm0
- movdqa XMMWORD PTR[560+rsp],xmm1
- movdqa XMMWORD PTR[576+rsp],xmm2
- movdqa XMMWORD PTR[592+rsp],xmm3
-
-
- movdqu xmm0,XMMWORD PTR[rdx]
- movdqu xmm1,XMMWORD PTR[16+rdx]
- movdqu xmm2,XMMWORD PTR[32+rdx]
- movdqu xmm3,XMMWORD PTR[48+rdx]
-
- lea rbx,QWORD PTR[384+rsp]
- mov QWORD PTR[136+rsp],rbx
- call mont_reduce
-
-
- lea rcx,QWORD PTR[448+rsp]
- xor rax,rax
- mov QWORD PTR[rcx],rax
- mov QWORD PTR[8+rcx],rax
- mov QWORD PTR[24+rcx],rax
- mov QWORD PTR[32+rcx],rax
- mov QWORD PTR[40+rcx],rax
- mov QWORD PTR[48+rcx],rax
- mov QWORD PTR[56+rcx],rax
- mov QWORD PTR[128+rsp],rax
- mov QWORD PTR[16+rcx],1
-
- lea rbp,QWORD PTR[640+rsp]
- mov rsi,rcx
- mov rdi,rbp
- mov rax,8
-loop_0::
- mov rbx,QWORD PTR[rcx]
- mov WORD PTR[rdi],bx
- shr rbx,16
- mov WORD PTR[64+rdi],bx
- shr rbx,16
- mov WORD PTR[128+rdi],bx
- shr rbx,16
- mov WORD PTR[192+rdi],bx
- lea rcx,QWORD PTR[8+rcx]
- lea rdi,QWORD PTR[256+rdi]
- dec rax
- jnz loop_0
- mov rax,31
- mov QWORD PTR[32+rsp],rax
- mov QWORD PTR[40+rsp],rbp
-
- mov QWORD PTR[136+rsp],rsi
- mov r10,QWORD PTR[rsi]
- mov r11,QWORD PTR[8+rsi]
- mov r12,QWORD PTR[16+rsi]
- mov r13,QWORD PTR[24+rsi]
- mov r14,QWORD PTR[32+rsi]
- mov r15,QWORD PTR[40+rsi]
- mov r8,QWORD PTR[48+rsi]
- mov r9,QWORD PTR[56+rsi]
-init_loop::
- lea rdi,QWORD PTR[384+rsp]
- call mont_mul_a3b
- lea rsi,QWORD PTR[448+rsp]
- mov rbp,QWORD PTR[40+rsp]
- add rbp,2
- mov QWORD PTR[40+rsp],rbp
- mov rcx,rsi
- mov rax,8
-loop_1::
- mov rbx,QWORD PTR[rcx]
- mov WORD PTR[rbp],bx
- shr rbx,16
- mov WORD PTR[64+rbp],bx
- shr rbx,16
- mov WORD PTR[128+rbp],bx
- shr rbx,16
- mov WORD PTR[192+rbp],bx
- lea rcx,QWORD PTR[8+rcx]
- lea rbp,QWORD PTR[256+rbp]
- dec rax
- jnz loop_1
- mov rax,QWORD PTR[32+rsp]
- sub rax,1
- mov QWORD PTR[32+rsp],rax
- jne init_loop
-
-
-
- movdqa XMMWORD PTR[64+rsp],xmm0
- movdqa XMMWORD PTR[80+rsp],xmm1
- movdqa XMMWORD PTR[96+rsp],xmm2
- movdqa XMMWORD PTR[112+rsp],xmm3
-
-
-
-
-
- mov eax,DWORD PTR[126+rsp]
- mov rdx,rax
- shr rax,11
- and edx,007FFh
- mov DWORD PTR[126+rsp],edx
- lea rsi,QWORD PTR[640+rax*2+rsp]
- mov rdx,QWORD PTR[8+rsp]
- mov rbp,4
-loop_2::
- movzx rbx,WORD PTR[192+rsi]
- movzx rax,WORD PTR[448+rsi]
- shl rbx,16
- shl rax,16
- mov bx,WORD PTR[128+rsi]
- mov ax,WORD PTR[384+rsi]
- shl rbx,16
- shl rax,16
- mov bx,WORD PTR[64+rsi]
- mov ax,WORD PTR[320+rsi]
- shl rbx,16
- shl rax,16
- mov bx,WORD PTR[rsi]
- mov ax,WORD PTR[256+rsi]
- mov QWORD PTR[rdx],rbx
- mov QWORD PTR[8+rdx],rax
- lea rsi,QWORD PTR[512+rsi]
- lea rdx,QWORD PTR[16+rdx]
- sub rbp,1
- jnz loop_2
- mov QWORD PTR[48+rsp],505
-
- mov rcx,QWORD PTR[8+rsp]
- mov QWORD PTR[136+rsp],rcx
- mov r10,QWORD PTR[rcx]
- mov r11,QWORD PTR[8+rcx]
- mov r12,QWORD PTR[16+rcx]
- mov r13,QWORD PTR[24+rcx]
- mov r14,QWORD PTR[32+rcx]
- mov r15,QWORD PTR[40+rcx]
- mov r8,QWORD PTR[48+rcx]
- mov r9,QWORD PTR[56+rcx]
- jmp sqr_2
-
-main_loop_a3b::
- call sqr_reduce
- call sqr_reduce
- call sqr_reduce
-sqr_2::
- call sqr_reduce
- call sqr_reduce
-
-
-
- mov rcx,QWORD PTR[48+rsp]
- mov rax,rcx
- shr rax,4
- mov edx,DWORD PTR[64+rax*2+rsp]
- and rcx,15
- shr rdx,cl
- and rdx,01Fh
-
- lea rsi,QWORD PTR[640+rdx*2+rsp]
- lea rdx,QWORD PTR[448+rsp]
- mov rdi,rdx
- mov rbp,4
-loop_3::
- movzx rbx,WORD PTR[192+rsi]
- movzx rax,WORD PTR[448+rsi]
- shl rbx,16
- shl rax,16
- mov bx,WORD PTR[128+rsi]
- mov ax,WORD PTR[384+rsi]
- shl rbx,16
- shl rax,16
- mov bx,WORD PTR[64+rsi]
- mov ax,WORD PTR[320+rsi]
- shl rbx,16
- shl rax,16
- mov bx,WORD PTR[rsi]
- mov ax,WORD PTR[256+rsi]
- mov QWORD PTR[rdx],rbx
- mov QWORD PTR[8+rdx],rax
- lea rsi,QWORD PTR[512+rsi]
- lea rdx,QWORD PTR[16+rdx]
- sub rbp,1
- jnz loop_3
- mov rsi,QWORD PTR[8+rsp]
- call mont_mul_a3b
-
-
-
- mov rcx,QWORD PTR[48+rsp]
- sub rcx,5
- mov QWORD PTR[48+rsp],rcx
- jge main_loop_a3b
-
-
-
-end_main_loop_a3b::
-
-
- mov rdx,QWORD PTR[8+rsp]
- pxor xmm4,xmm4
- movdqu xmm0,XMMWORD PTR[rdx]
- movdqu xmm1,XMMWORD PTR[16+rdx]
- movdqu xmm2,XMMWORD PTR[32+rdx]
- movdqu xmm3,XMMWORD PTR[48+rdx]
- movdqa XMMWORD PTR[576+rsp],xmm4
- movdqa XMMWORD PTR[592+rsp],xmm4
- movdqa XMMWORD PTR[608+rsp],xmm4
- movdqa XMMWORD PTR[624+rsp],xmm4
- movdqa XMMWORD PTR[512+rsp],xmm0
- movdqa XMMWORD PTR[528+rsp],xmm1
- movdqa XMMWORD PTR[544+rsp],xmm2
- movdqa XMMWORD PTR[560+rsp],xmm3
- call mont_reduce
-
-
-
- mov rax,QWORD PTR[8+rsp]
- mov r8,QWORD PTR[rax]
- mov r9,QWORD PTR[8+rax]
- mov r10,QWORD PTR[16+rax]
- mov r11,QWORD PTR[24+rax]
- mov r12,QWORD PTR[32+rax]
- mov r13,QWORD PTR[40+rax]
- mov r14,QWORD PTR[48+rax]
- mov r15,QWORD PTR[56+rax]
-
-
- mov rbx,QWORD PTR[24+rsp]
- add rbx,512
-
- sub r8,QWORD PTR[rbx]
- sbb r9,QWORD PTR[8+rbx]
- sbb r10,QWORD PTR[16+rbx]
- sbb r11,QWORD PTR[24+rbx]
- sbb r12,QWORD PTR[32+rbx]
- sbb r13,QWORD PTR[40+rbx]
- sbb r14,QWORD PTR[48+rbx]
- sbb r15,QWORD PTR[56+rbx]
-
-
- mov rsi,QWORD PTR[rax]
- mov rdi,QWORD PTR[8+rax]
- mov rcx,QWORD PTR[16+rax]
- mov rdx,QWORD PTR[24+rax]
- cmovnc rsi,r8
- cmovnc rdi,r9
- cmovnc rcx,r10
- cmovnc rdx,r11
- mov QWORD PTR[rax],rsi
- mov QWORD PTR[8+rax],rdi
- mov QWORD PTR[16+rax],rcx
- mov QWORD PTR[24+rax],rdx
-
- mov rsi,QWORD PTR[32+rax]
- mov rdi,QWORD PTR[40+rax]
- mov rcx,QWORD PTR[48+rax]
- mov rdx,QWORD PTR[56+rax]
- cmovnc rsi,r12
- cmovnc rdi,r13
- cmovnc rcx,r14
- cmovnc rdx,r15
- mov QWORD PTR[32+rax],rsi
- mov QWORD PTR[40+rax],rdi
- mov QWORD PTR[48+rax],rcx
- mov QWORD PTR[56+rax],rdx
-
- mov rsi,QWORD PTR[rsp]
- mov r15,QWORD PTR[rsi]
- mov r14,QWORD PTR[8+rsi]
- mov r13,QWORD PTR[16+rsi]
- mov r12,QWORD PTR[24+rsi]
- mov rbx,QWORD PTR[32+rsi]
- mov rbp,QWORD PTR[40+rsi]
- lea rsp,QWORD PTR[48+rsi]
-$L$epilogue::
- mov rdi,QWORD PTR[8+rsp] ;WIN64 epilogue
- mov rsi,QWORD PTR[16+rsp]
- DB 0F3h,0C3h ;repret
-$L$SEH_end_mod_exp_512::
-mod_exp_512 ENDP
-EXTERN __imp_RtlVirtualUnwind:NEAR
-
-ALIGN 16
-mod_exp_512_se_handler PROC PRIVATE
- push rsi
- push rdi
- push rbx
- push rbp
- push r12
- push r13
- push r14
- push r15
- pushfq
- sub rsp,64
-
- mov rax,QWORD PTR[120+r8]
- mov rbx,QWORD PTR[248+r8]
-
- lea r10,QWORD PTR[$L$body]
- cmp rbx,r10
- jb $L$in_prologue
-
- mov rax,QWORD PTR[152+r8]
-
- lea r10,QWORD PTR[$L$epilogue]
- cmp rbx,r10
- jae $L$in_prologue
-
- mov rax,QWORD PTR[rax]
-
- mov rbx,QWORD PTR[32+rax]
- mov rbp,QWORD PTR[40+rax]
- mov r12,QWORD PTR[24+rax]
- mov r13,QWORD PTR[16+rax]
- mov r14,QWORD PTR[8+rax]
- mov r15,QWORD PTR[rax]
- lea rax,QWORD PTR[48+rax]
- mov QWORD PTR[144+r8],rbx
- mov QWORD PTR[160+r8],rbp
- mov QWORD PTR[216+r8],r12
- mov QWORD PTR[224+r8],r13
- mov QWORD PTR[232+r8],r14
- mov QWORD PTR[240+r8],r15
-
-$L$in_prologue::
- mov rdi,QWORD PTR[8+rax]
- mov rsi,QWORD PTR[16+rax]
- mov QWORD PTR[152+r8],rax
- mov QWORD PTR[168+r8],rsi
- mov QWORD PTR[176+r8],rdi
-
- mov rdi,QWORD PTR[40+r9]
- mov rsi,r8
- mov ecx,154
- DD 0a548f3fch
-
- mov rsi,r9
- xor rcx,rcx
- mov rdx,QWORD PTR[8+rsi]
- mov r8,QWORD PTR[rsi]
- mov r9,QWORD PTR[16+rsi]
- mov r10,QWORD PTR[40+rsi]
- lea r11,QWORD PTR[56+rsi]
- lea r12,QWORD PTR[24+rsi]
- mov QWORD PTR[32+rsp],r10
- mov QWORD PTR[40+rsp],r11
- mov QWORD PTR[48+rsp],r12
- mov QWORD PTR[56+rsp],rcx
- call QWORD PTR[__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
-mod_exp_512_se_handler ENDP
-
-.text$ ENDS
-.pdata SEGMENT READONLY ALIGN(4)
-ALIGN 4
- DD imagerel $L$SEH_begin_mod_exp_512
- DD imagerel $L$SEH_end_mod_exp_512
- DD imagerel $L$SEH_info_mod_exp_512
-
-.pdata ENDS
-.xdata SEGMENT READONLY ALIGN(8)
-ALIGN 8
-$L$SEH_info_mod_exp_512::
-DB 9,0,0,0
- DD imagerel mod_exp_512_se_handler
-
-.xdata ENDS
-END
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/cpu-x86_64-asm.asm b/win-x86_64/crypto/cpu-x86_64-asm.asm
deleted file mode 100644
index c92d7bb..0000000
--- a/win-x86_64/crypto/cpu-x86_64-asm.asm
+++ /dev/null
@@ -1,154 +0,0 @@
-default rel
-%define XMMWORD
-%define YMMWORD
-%define ZMMWORD
-section .text code align=64
-
-
-global OPENSSL_ia32_cpuid
-
-ALIGN 16
-OPENSSL_ia32_cpuid:
- mov QWORD[8+rsp],rdi ;WIN64 prologue
- mov QWORD[16+rsp],rsi
- mov rax,rsp
-$L$SEH_begin_OPENSSL_ia32_cpuid:
- mov rdi,rcx
-
-
-
-
- mov rdi,rcx
- mov r8,rbx
-
- xor eax,eax
- mov DWORD[8+rdi],eax
- cpuid
- mov r11d,eax
-
- xor eax,eax
- cmp ebx,0x756e6547
- setne al
- mov r9d,eax
- cmp edx,0x49656e69
- setne al
- or r9d,eax
- cmp ecx,0x6c65746e
- setne al
- or r9d,eax
- jz NEAR $L$intel
-
- cmp ebx,0x68747541
- setne al
- mov r10d,eax
- cmp edx,0x69746E65
- setne al
- or r10d,eax
- cmp ecx,0x444D4163
- setne al
- or r10d,eax
- jnz NEAR $L$intel
-
-
-
-
- mov eax,0x80000000
- cpuid
-
-
- cmp eax,0x80000001
- jb NEAR $L$intel
- mov r10d,eax
- mov eax,0x80000001
- cpuid
-
-
- or r9d,ecx
- and r9d,0x00000801
-
- cmp r10d,0x80000008
- jb NEAR $L$intel
-
- mov eax,0x80000008
- cpuid
-
- movzx r10,cl
- inc r10
-
- mov eax,1
- cpuid
-
- bt edx,28
- jnc NEAR $L$generic
- shr ebx,16
- cmp bl,r10b
- ja NEAR $L$generic
- and edx,0xefffffff
- jmp NEAR $L$generic
-
-$L$intel:
- cmp r11d,4
- mov r10d,-1
- jb NEAR $L$nocacheinfo
-
- mov eax,4
- mov ecx,0
- cpuid
- mov r10d,eax
- shr r10d,14
- and r10d,0xfff
-
- cmp r11d,7
- jb NEAR $L$nocacheinfo
-
- mov eax,7
- xor ecx,ecx
- cpuid
- mov DWORD[8+rdi],ebx
-
-$L$nocacheinfo:
- mov eax,1
- cpuid
-
- and edx,0xbfefffff
- cmp r9d,0
- jne NEAR $L$notintel
- or edx,0x40000000
-$L$notintel:
- bt edx,28
- jnc NEAR $L$generic
- and edx,0xefffffff
- cmp r10d,0
- je NEAR $L$generic
-
- or edx,0x10000000
- shr ebx,16
- cmp bl,1
- ja NEAR $L$generic
- and edx,0xefffffff
-$L$generic:
- and r9d,0x00000800
- and ecx,0xfffff7ff
- or r9d,ecx
-
- mov r10d,edx
- bt r9d,27
- jnc NEAR $L$clear_avx
- xor ecx,ecx
-DB 0x0f,0x01,0xd0
- and eax,6
- cmp eax,6
- je NEAR $L$done
-$L$clear_avx:
- mov eax,0xefffe7ff
- and r9d,eax
- and DWORD[8+rdi],0xffffffdf
-$L$done:
- mov DWORD[4+rdi],r9d
- mov DWORD[rdi],r10d
- mov rbx,r8
- mov rdi,QWORD[8+rsp] ;WIN64 epilogue
- mov rsi,QWORD[16+rsp]
- DB 0F3h,0C3h ;repret
-$L$SEH_end_OPENSSL_ia32_cpuid:
-
diff --git a/win-x86_64/crypto/ec/p256-x86_64-asm.asm b/win-x86_64/crypto/ec/p256-x86_64-asm.asm
new file mode 100644
index 0000000..45ba686
--- /dev/null
+++ b/win-x86_64/crypto/ec/p256-x86_64-asm.asm
@@ -0,0 +1,1916 @@
+default rel
+%define XMMWORD
+%define YMMWORD
+%define ZMMWORD
+section .text code align=64
+
+EXTERN OPENSSL_ia32cap_P
+
+
+ALIGN 64
+$L$poly:
+ DQ 0xffffffffffffffff,0x00000000ffffffff,0x0000000000000000,0xffffffff00000001
+
+$L$One:
+ DD 1,1,1,1,1,1,1,1
+$L$Two:
+ DD 2,2,2,2,2,2,2,2
+$L$Three:
+ DD 3,3,3,3,3,3,3,3
+$L$ONE_mont:
+ DQ 0x0000000000000001,0xffffffff00000000,0xffffffffffffffff,0x00000000fffffffe
+
+
+ALIGN 64
+ecp_nistz256_mul_by_2:
+ mov QWORD[8+rsp],rdi ;WIN64 prologue
+ mov QWORD[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_ecp_nistz256_mul_by_2:
+ mov rdi,rcx
+ mov rsi,rdx
+
+
+ push r12
+ push r13
+
+ mov r8,QWORD[rsi]
+ mov r9,QWORD[8+rsi]
+ add r8,r8
+ mov r10,QWORD[16+rsi]
+ adc r9,r9
+ mov r11,QWORD[24+rsi]
+ lea rsi,[$L$poly]
+ mov rax,r8
+ adc r10,r10
+ adc r11,r11
+ mov rdx,r9
+ sbb r13,r13
+
+ 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_mul_by_2:
+
+
+
+global ecp_nistz256_neg
+
+ALIGN 32
+ecp_nistz256_neg:
+ mov QWORD[8+rsp],rdi ;WIN64 prologue
+ mov QWORD[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_ecp_nistz256_neg:
+ mov rdi,rcx
+ mov rsi,rdx
+
+
+ push r12
+ push r13
+
+ xor r8,r8
+ xor r9,r9
+ xor r10,r10
+ xor r11,r11
+ xor r13,r13
+
+ sub r8,QWORD[rsi]
+ sbb r9,QWORD[8+rsi]
+ sbb r10,QWORD[16+rsi]
+ mov rax,r8
+ sbb r11,QWORD[24+rsi]
+ lea rsi,[$L$poly]
+ 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_neg:
+
+
+
+
+
+
+global ecp_nistz256_mul_mont
+
+ALIGN 32
+ecp_nistz256_mul_mont:
+ mov QWORD[8+rsp],rdi ;WIN64 prologue
+ mov QWORD[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_ecp_nistz256_mul_mont:
+ mov rdi,rcx
+ mov rsi,rdx
+ mov rdx,r8
+
+
+$L$mul_mont:
+ push rbp
+ push rbx
+ push r12
+ push r13
+ push r14
+ push r15
+ mov rbx,rdx
+ mov rax,QWORD[rdx]
+ mov r9,QWORD[rsi]
+ mov r10,QWORD[8+rsi]
+ mov r11,QWORD[16+rsi]
+ mov r12,QWORD[24+rsi]
+
+ call __ecp_nistz256_mul_montq
+$L$mul_mont_done:
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop rbx
+ pop rbp
+ mov rdi,QWORD[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_ecp_nistz256_mul_mont:
+
+
+ALIGN 32
+__ecp_nistz256_mul_montq:
+
+
+ mov rbp,rax
+ mul r9
+ mov r14,QWORD[(($L$poly+8))]
+ mov r8,rax
+ mov rax,rbp
+ mov r9,rdx
+
+ mul r10
+ mov r15,QWORD[(($L$poly+24))]
+ add r9,rax
+ mov rax,rbp
+ adc rdx,0
+ mov r10,rdx
+
+ mul r11
+ add r10,rax
+ mov rax,rbp
+ adc rdx,0
+ mov r11,rdx
+
+ mul r12
+ add r11,rax
+ mov rax,r8
+ adc rdx,0
+ xor r13,r13
+ mov r12,rdx
+
+
+
+
+
+
+
+
+
+
+ mov rbp,r8
+ shl r8,32
+ mul r15
+ shr rbp,32
+ add r9,r8
+ adc r10,rbp
+ adc r11,rax
+ mov rax,QWORD[8+rbx]
+ adc r12,rdx
+ adc r13,0
+ xor r8,r8
+
+
+
+ mov rbp,rax
+ mul QWORD[rsi]
+ add r9,rax
+ mov rax,rbp
+ adc rdx,0
+ mov rcx,rdx
+
+ mul QWORD[8+rsi]
+ add r10,rcx
+ adc rdx,0
+ add r10,rax
+ mov rax,rbp
+ adc rdx,0
+ mov rcx,rdx
+
+ mul QWORD[16+rsi]
+ add r11,rcx
+ adc rdx,0
+ add r11,rax
+ mov rax,rbp
+ adc rdx,0
+ mov rcx,rdx
+
+ mul QWORD[24+rsi]
+ add r12,rcx
+ adc rdx,0
+ add r12,rax
+ mov rax,r9
+ adc r13,rdx
+ adc r8,0
+
+
+
+ mov rbp,r9
+ shl r9,32
+ mul r15
+ shr rbp,32
+ add r10,r9
+ adc r11,rbp
+ adc r12,rax
+ mov rax,QWORD[16+rbx]
+ adc r13,rdx
+ adc r8,0
+ xor r9,r9
+
+
+
+ mov rbp,rax
+ mul QWORD[rsi]
+ add r10,rax
+ mov rax,rbp
+ adc rdx,0
+ mov rcx,rdx
+
+ mul QWORD[8+rsi]
+ add r11,rcx
+ adc rdx,0
+ add r11,rax
+ mov rax,rbp
+ adc rdx,0
+ mov rcx,rdx
+
+ mul QWORD[16+rsi]
+ add r12,rcx
+ adc rdx,0
+ add r12,rax
+ mov rax,rbp
+ adc rdx,0
+ mov rcx,rdx
+
+ mul QWORD[24+rsi]
+ add r13,rcx
+ adc rdx,0
+ add r13,rax
+ mov rax,r10
+ adc r8,rdx
+ adc r9,0
+
+
+
+ mov rbp,r10
+ shl r10,32
+ mul r15
+ shr rbp,32
+ add r11,r10
+ adc r12,rbp
+ adc r13,rax
+ mov rax,QWORD[24+rbx]
+ adc r8,rdx
+ adc r9,0
+ xor r10,r10
+
+
+
+ mov rbp,rax
+ mul QWORD[rsi]
+ add r11,rax
+ mov rax,rbp
+ adc rdx,0
+ mov rcx,rdx
+
+ mul QWORD[8+rsi]
+ add r12,rcx
+ adc rdx,0
+ add r12,rax
+ mov rax,rbp
+ adc rdx,0
+ mov rcx,rdx
+
+ mul QWORD[16+rsi]
+ add r13,rcx
+ adc rdx,0
+ add r13,rax
+ mov rax,rbp
+ adc rdx,0
+ mov rcx,rdx
+
+ mul QWORD[24+rsi]
+ add r8,rcx
+ adc rdx,0
+ add r8,rax
+ mov rax,r11
+ adc r9,rdx
+ adc r10,0
+
+
+
+ mov rbp,r11
+ shl r11,32
+ mul r15
+ shr rbp,32
+ add r12,r11
+ adc r13,rbp
+ mov rcx,r12
+ adc r8,rax
+ adc r9,rdx
+ mov rbp,r13
+ adc r10,0
+
+
+
+ sub r12,-1
+ mov rbx,r8
+ sbb r13,r14
+ sbb r8,0
+ mov rdx,r9
+ sbb r9,r15
+ sbb r10,0
+
+ cmovc r12,rcx
+ cmovc r13,rbp
+ mov QWORD[rdi],r12
+ cmovc r8,rbx
+ mov QWORD[8+rdi],r13
+ cmovc r9,rdx
+ mov QWORD[16+rdi],r8
+ mov QWORD[24+rdi],r9
+
+ DB 0F3h,0C3h ;repret
+
+
+
+
+
+
+
+
+
+global ecp_nistz256_sqr_mont
+
+ALIGN 32
+ecp_nistz256_sqr_mont:
+ mov QWORD[8+rsp],rdi ;WIN64 prologue
+ mov QWORD[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_ecp_nistz256_sqr_mont:
+ mov rdi,rcx
+ mov rsi,rdx
+
+
+ push rbp
+ push rbx
+ push r12
+ push r13
+ push r14
+ push r15
+ mov rax,QWORD[rsi]
+ mov r14,QWORD[8+rsi]
+ mov r15,QWORD[16+rsi]
+ mov r8,QWORD[24+rsi]
+
+ call __ecp_nistz256_sqr_montq
+$L$sqr_mont_done:
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop rbx
+ pop rbp
+ mov rdi,QWORD[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_ecp_nistz256_sqr_mont:
+
+
+ALIGN 32
+__ecp_nistz256_sqr_montq:
+ mov r13,rax
+ mul r14
+ mov r9,rax
+ mov rax,r15
+ mov r10,rdx
+
+ mul r13
+ add r10,rax
+ mov rax,r8
+ adc rdx,0
+ mov r11,rdx
+
+ mul r13
+ add r11,rax
+ mov rax,r15
+ adc rdx,0
+ mov r12,rdx
+
+
+ mul r14
+ add r11,rax
+ mov rax,r8
+ adc rdx,0
+ mov rbp,rdx
+
+ mul r14
+ add r12,rax
+ mov rax,r8
+ adc rdx,0
+ add r12,rbp
+ mov r13,rdx
+ adc r13,0
+
+
+ mul r15
+ xor r15,r15
+ add r13,rax
+ mov rax,QWORD[rsi]
+ mov r14,rdx
+ adc r14,0
+
+ add r9,r9
+ adc r10,r10
+ adc r11,r11
+ adc r12,r12
+ adc r13,r13
+ adc r14,r14
+ adc r15,0
+
+ mul rax
+ mov r8,rax
+ mov rax,QWORD[8+rsi]
+ mov rcx,rdx
+
+ mul rax
+ add r9,rcx
+ adc r10,rax
+ mov rax,QWORD[16+rsi]
+ adc rdx,0
+ mov rcx,rdx
+
+ mul rax
+ add r11,rcx
+ adc r12,rax
+ mov rax,QWORD[24+rsi]
+ adc rdx,0
+ mov rcx,rdx
+
+ mul rax
+ add r13,rcx
+ adc r14,rax
+ mov rax,r8
+ adc r15,rdx
+
+ mov rsi,QWORD[(($L$poly+8))]
+ mov rbp,QWORD[(($L$poly+24))]
+
+
+
+
+ mov rcx,r8
+ shl r8,32
+ mul rbp
+ shr rcx,32
+ add r9,r8
+ adc r10,rcx
+ adc r11,rax
+ mov rax,r9
+ adc rdx,0
+
+
+
+ mov rcx,r9
+ shl r9,32
+ mov r8,rdx
+ mul rbp
+ shr rcx,32
+ add r10,r9
+ adc r11,rcx
+ adc r8,rax
+ mov rax,r10
+ adc rdx,0
+
+
+
+ mov rcx,r10
+ shl r10,32
+ mov r9,rdx
+ mul rbp
+ shr rcx,32
+ add r11,r10
+ adc r8,rcx
+ adc r9,rax
+ mov rax,r11
+ adc rdx,0
+
+
+
+ mov rcx,r11
+ shl r11,32
+ mov r10,rdx
+ mul rbp
+ shr rcx,32
+ add r8,r11
+ adc r9,rcx
+ adc r10,rax
+ adc rdx,0
+ xor r11,r11
+
+
+
+ add r12,r8
+ adc r13,r9
+ mov r8,r12
+ adc r14,r10
+ adc r15,rdx
+ mov r9,r13
+ adc r11,0
+
+ sub r12,-1
+ mov r10,r14
+ sbb r13,rsi
+ sbb r14,0
+ mov rcx,r15
+ sbb r15,rbp
+ sbb r11,0
+
+ cmovc r12,r8
+ cmovc r13,r9
+ mov QWORD[rdi],r12
+ cmovc r14,r10
+ mov QWORD[8+rdi],r13
+ cmovc r15,rcx
+ mov QWORD[16+rdi],r14
+ mov QWORD[24+rdi],r15
+
+ DB 0F3h,0C3h ;repret
+
+
+
+
+
+
+
+global ecp_nistz256_from_mont
+
+ALIGN 32
+ecp_nistz256_from_mont:
+ mov QWORD[8+rsp],rdi ;WIN64 prologue
+ mov QWORD[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_ecp_nistz256_from_mont:
+ mov rdi,rcx
+ mov rsi,rdx
+
+
+ push r12
+ push r13
+
+ mov rax,QWORD[rsi]
+ mov r13,QWORD[(($L$poly+24))]
+ mov r9,QWORD[8+rsi]
+ mov r10,QWORD[16+rsi]
+ mov r11,QWORD[24+rsi]
+ mov r8,rax
+ mov r12,QWORD[(($L$poly+8))]
+
+
+
+ mov rcx,rax
+ shl r8,32
+ mul r13
+ shr rcx,32
+ add r9,r8
+ adc r10,rcx
+ adc r11,rax
+ mov rax,r9
+ adc rdx,0
+
+
+
+ mov rcx,r9
+ shl r9,32
+ mov r8,rdx
+ mul r13
+ shr rcx,32
+ add r10,r9
+ adc r11,rcx
+ adc r8,rax
+ mov rax,r10
+ adc rdx,0
+
+
+
+ mov rcx,r10
+ shl r10,32
+ mov r9,rdx
+ mul r13
+ shr rcx,32
+ add r11,r10
+ adc r8,rcx
+ adc r9,rax
+ mov rax,r11
+ adc rdx,0
+
+
+
+ mov rcx,r11
+ shl r11,32
+ mov r10,rdx
+ mul r13
+ shr rcx,32
+ add r8,r11
+ adc r9,rcx
+ mov rcx,r8
+ adc r10,rax
+ mov rsi,r9
+ adc rdx,0
+
+ sub r8,-1
+ mov rax,r10
+ sbb r9,r12
+ sbb r10,0
+ mov r11,rdx
+ sbb rdx,r13
+ sbb r13,r13
+
+ cmovnz r8,rcx
+ cmovnz r9,rsi
+ mov QWORD[rdi],r8
+ cmovnz r10,rax
+ mov QWORD[8+rdi],r9
+ cmovz r11,rdx
+ 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_from_mont:
+
+
+global ecp_nistz256_select_w5
+
+ALIGN 32
+ecp_nistz256_select_w5:
+ lea rax,[((-136))+rsp]
+$L$SEH_begin_ecp_nistz256_select_w5:
+DB 0x48,0x8d,0x60,0xe0
+DB 0x0f,0x29,0x70,0xe0
+DB 0x0f,0x29,0x78,0xf0
+DB 0x44,0x0f,0x29,0x00
+DB 0x44,0x0f,0x29,0x48,0x10
+DB 0x44,0x0f,0x29,0x50,0x20
+DB 0x44,0x0f,0x29,0x58,0x30
+DB 0x44,0x0f,0x29,0x60,0x40
+DB 0x44,0x0f,0x29,0x68,0x50
+DB 0x44,0x0f,0x29,0x70,0x60
+DB 0x44,0x0f,0x29,0x78,0x70
+ movdqa xmm0,XMMWORD[$L$One]
+ movd xmm1,r8d
+
+ pxor xmm2,xmm2
+ pxor xmm3,xmm3
+ pxor xmm4,xmm4
+ pxor xmm5,xmm5
+ pxor xmm6,xmm6
+ pxor xmm7,xmm7
+
+ movdqa xmm8,xmm0
+ pshufd xmm1,xmm1,0
+
+ mov rax,16
+$L$select_loop_sse_w5:
+
+ movdqa xmm15,xmm8
+ paddd xmm8,xmm0
+ pcmpeqd xmm15,xmm1
+
+ movdqa xmm9,XMMWORD[rdx]
+ movdqa xmm10,XMMWORD[16+rdx]
+ movdqa xmm11,XMMWORD[32+rdx]
+ movdqa xmm12,XMMWORD[48+rdx]
+ movdqa xmm13,XMMWORD[64+rdx]
+ movdqa xmm14,XMMWORD[80+rdx]
+ lea rdx,[96+rdx]
+
+ pand xmm9,xmm15
+ pand xmm10,xmm15
+ por xmm2,xmm9
+ pand xmm11,xmm15
+ por xmm3,xmm10
+ pand xmm12,xmm15
+ por xmm4,xmm11
+ pand xmm13,xmm15
+ por xmm5,xmm12
+ pand xmm14,xmm15
+ por xmm6,xmm13
+ por xmm7,xmm14
+
+ dec rax
+ jnz NEAR $L$select_loop_sse_w5
+
+ movdqu XMMWORD[rcx],xmm2
+ movdqu XMMWORD[16+rcx],xmm3
+ movdqu XMMWORD[32+rcx],xmm4
+ movdqu XMMWORD[48+rcx],xmm5
+ movdqu XMMWORD[64+rcx],xmm6
+ movdqu XMMWORD[80+rcx],xmm7
+ movaps xmm6,XMMWORD[rsp]
+ movaps xmm7,XMMWORD[16+rsp]
+ movaps xmm8,XMMWORD[32+rsp]
+ movaps xmm9,XMMWORD[48+rsp]
+ movaps xmm10,XMMWORD[64+rsp]
+ movaps xmm11,XMMWORD[80+rsp]
+ movaps xmm12,XMMWORD[96+rsp]
+ movaps xmm13,XMMWORD[112+rsp]
+ movaps xmm14,XMMWORD[128+rsp]
+ movaps xmm15,XMMWORD[144+rsp]
+ lea rsp,[168+rsp]
+$L$SEH_end_ecp_nistz256_select_w5:
+ DB 0F3h,0C3h ;repret
+
+
+
+
+global ecp_nistz256_select_w7
+
+ALIGN 32
+ecp_nistz256_select_w7:
+ lea rax,[((-136))+rsp]
+$L$SEH_begin_ecp_nistz256_select_w7:
+DB 0x48,0x8d,0x60,0xe0
+DB 0x0f,0x29,0x70,0xe0
+DB 0x0f,0x29,0x78,0xf0
+DB 0x44,0x0f,0x29,0x00
+DB 0x44,0x0f,0x29,0x48,0x10
+DB 0x44,0x0f,0x29,0x50,0x20
+DB 0x44,0x0f,0x29,0x58,0x30
+DB 0x44,0x0f,0x29,0x60,0x40
+DB 0x44,0x0f,0x29,0x68,0x50
+DB 0x44,0x0f,0x29,0x70,0x60
+DB 0x44,0x0f,0x29,0x78,0x70
+ movdqa xmm8,XMMWORD[$L$One]
+ movd xmm1,r8d
+
+ pxor xmm2,xmm2
+ pxor xmm3,xmm3
+ pxor xmm4,xmm4
+ pxor xmm5,xmm5
+
+ movdqa xmm0,xmm8
+ pshufd xmm1,xmm1,0
+ mov rax,64
+
+$L$select_loop_sse_w7:
+ movdqa xmm15,xmm8
+ paddd xmm8,xmm0
+ movdqa xmm9,XMMWORD[rdx]
+ movdqa xmm10,XMMWORD[16+rdx]
+ pcmpeqd xmm15,xmm1
+ movdqa xmm11,XMMWORD[32+rdx]
+ movdqa xmm12,XMMWORD[48+rdx]
+ lea rdx,[64+rdx]
+
+ pand xmm9,xmm15
+ pand xmm10,xmm15
+ por xmm2,xmm9
+ pand xmm11,xmm15
+ por xmm3,xmm10
+ pand xmm12,xmm15
+ por xmm4,xmm11
+ prefetcht0 [255+rdx]
+ por xmm5,xmm12
+
+ dec rax
+ jnz NEAR $L$select_loop_sse_w7
+
+ movdqu XMMWORD[rcx],xmm2
+ movdqu XMMWORD[16+rcx],xmm3
+ movdqu XMMWORD[32+rcx],xmm4
+ movdqu XMMWORD[48+rcx],xmm5
+ movaps xmm6,XMMWORD[rsp]
+ movaps xmm7,XMMWORD[16+rsp]
+ movaps xmm8,XMMWORD[32+rsp]
+ movaps xmm9,XMMWORD[48+rsp]
+ movaps xmm10,XMMWORD[64+rsp]
+ movaps xmm11,XMMWORD[80+rsp]
+ movaps xmm12,XMMWORD[96+rsp]
+ movaps xmm13,XMMWORD[112+rsp]
+ movaps xmm14,XMMWORD[128+rsp]
+ movaps xmm15,XMMWORD[144+rsp]
+ lea rsp,[168+rsp]
+$L$SEH_end_ecp_nistz256_select_w7:
+ DB 0F3h,0C3h ;repret
+
+global ecp_nistz256_avx2_select_w7
+
+ALIGN 32
+ecp_nistz256_avx2_select_w7:
+ mov QWORD[8+rsp],rdi ;WIN64 prologue
+ mov QWORD[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_ecp_nistz256_avx2_select_w7:
+ mov rdi,rcx
+ mov rsi,rdx
+ mov rdx,r8
+
+
+DB 0x0f,0x0b
+ mov rdi,QWORD[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_ecp_nistz256_avx2_select_w7:
+
+ALIGN 32
+__ecp_nistz256_add_toq:
+ add r12,QWORD[rbx]
+ adc r13,QWORD[8+rbx]
+ mov rax,r12
+ adc r8,QWORD[16+rbx]
+ adc r9,QWORD[24+rbx]
+ mov rbp,r13
+ sbb r11,r11
+
+ sub r12,-1
+ mov rcx,r8
+ sbb r13,r14
+ sbb r8,0
+ mov r10,r9
+ sbb r9,r15
+ test r11,r11
+
+ cmovz r12,rax
+ cmovz r13,rbp
+ mov QWORD[rdi],r12
+ cmovz r8,rcx
+ mov QWORD[8+rdi],r13
+ cmovz r9,r10
+ mov QWORD[16+rdi],r8
+ mov QWORD[24+rdi],r9
+
+ DB 0F3h,0C3h ;repret
+
+
+
+ALIGN 32
+__ecp_nistz256_sub_fromq:
+ sub r12,QWORD[rbx]
+ sbb r13,QWORD[8+rbx]
+ mov rax,r12
+ sbb r8,QWORD[16+rbx]
+ sbb r9,QWORD[24+rbx]
+ mov rbp,r13
+ sbb r11,r11
+
+ add r12,-1
+ mov rcx,r8
+ adc r13,r14
+ adc r8,0
+ mov r10,r9
+ adc r9,r15
+ test r11,r11
+
+ cmovz r12,rax
+ cmovz r13,rbp
+ mov QWORD[rdi],r12
+ cmovz r8,rcx
+ mov QWORD[8+rdi],r13
+ cmovz r9,r10
+ mov QWORD[16+rdi],r8
+ mov QWORD[24+rdi],r9
+
+ DB 0F3h,0C3h ;repret
+
+
+
+ALIGN 32
+__ecp_nistz256_subq:
+ sub rax,r12
+ sbb rbp,r13
+ mov r12,rax
+ sbb rcx,r8
+ sbb r10,r9
+ mov r13,rbp
+ sbb r11,r11
+
+ add rax,-1
+ mov r8,rcx
+ adc rbp,r14
+ adc rcx,0
+ mov r9,r10
+ adc r10,r15
+ test r11,r11
+
+ cmovnz r12,rax
+ cmovnz r13,rbp
+ cmovnz r8,rcx
+ cmovnz r9,r10
+
+ DB 0F3h,0C3h ;repret
+
+
+
+ALIGN 32
+__ecp_nistz256_mul_by_2q:
+ add r12,r12
+ adc r13,r13
+ mov rax,r12
+ adc r8,r8
+ adc r9,r9
+ mov rbp,r13
+ sbb r11,r11
+
+ sub r12,-1
+ mov rcx,r8
+ sbb r13,r14
+ sbb r8,0
+ mov r10,r9
+ sbb r9,r15
+ test r11,r11
+
+ cmovz r12,rax
+ cmovz r13,rbp
+ mov QWORD[rdi],r12
+ cmovz r8,rcx
+ mov QWORD[8+rdi],r13
+ cmovz r9,r10
+ mov QWORD[16+rdi],r8
+ mov QWORD[24+rdi],r9
+
+ DB 0F3h,0C3h ;repret
+
+global ecp_nistz256_point_double
+
+ALIGN 32
+ecp_nistz256_point_double:
+ mov QWORD[8+rsp],rdi ;WIN64 prologue
+ mov QWORD[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_ecp_nistz256_point_double:
+ mov rdi,rcx
+ mov rsi,rdx
+
+
+ push rbp
+ push rbx
+ push r12
+ push r13
+ push r14
+ push r15
+ sub rsp,32*5+8
+
+ movdqu xmm0,XMMWORD[rsi]
+ mov rbx,rsi
+ movdqu xmm1,XMMWORD[16+rsi]
+ mov r12,QWORD[((32+0))+rsi]
+ mov r13,QWORD[((32+8))+rsi]
+ mov r8,QWORD[((32+16))+rsi]
+ mov r9,QWORD[((32+24))+rsi]
+ mov r14,QWORD[(($L$poly+8))]
+ mov r15,QWORD[(($L$poly+24))]
+ movdqa XMMWORD[96+rsp],xmm0
+ movdqa XMMWORD[(96+16)+rsp],xmm1
+ lea r10,[32+rdi]
+ lea r11,[64+rdi]
+DB 102,72,15,110,199
+DB 102,73,15,110,202
+DB 102,73,15,110,211
+
+ lea rdi,[rsp]
+ call __ecp_nistz256_mul_by_2q
+
+ mov rax,QWORD[((64+0))+rsi]
+ mov r14,QWORD[((64+8))+rsi]
+ mov r15,QWORD[((64+16))+rsi]
+ mov r8,QWORD[((64+24))+rsi]
+ lea rsi,[((64-0))+rsi]
+ lea rdi,[64+rsp]
+ call __ecp_nistz256_sqr_montq
+
+ mov rax,QWORD[((0+0))+rsp]
+ mov r14,QWORD[((8+0))+rsp]
+ lea rsi,[((0+0))+rsp]
+ mov r15,QWORD[((16+0))+rsp]
+ mov r8,QWORD[((24+0))+rsp]
+ lea rdi,[rsp]
+ call __ecp_nistz256_sqr_montq
+
+ mov rax,QWORD[32+rbx]
+ mov r9,QWORD[((64+0))+rbx]
+ mov r10,QWORD[((64+8))+rbx]
+ mov r11,QWORD[((64+16))+rbx]
+ mov r12,QWORD[((64+24))+rbx]
+ lea rsi,[((64-0))+rbx]
+ lea rbx,[32+rbx]
+DB 102,72,15,126,215
+ call __ecp_nistz256_mul_montq
+ call __ecp_nistz256_mul_by_2q
+
+ mov r12,QWORD[((96+0))+rsp]
+ mov r13,QWORD[((96+8))+rsp]
+ lea rbx,[64+rsp]
+ mov r8,QWORD[((96+16))+rsp]
+ mov r9,QWORD[((96+24))+rsp]
+ lea rdi,[32+rsp]
+ call __ecp_nistz256_add_toq
+
+ mov r12,QWORD[((96+0))+rsp]
+ mov r13,QWORD[((96+8))+rsp]
+ lea rbx,[64+rsp]
+ mov r8,QWORD[((96+16))+rsp]
+ mov r9,QWORD[((96+24))+rsp]
+ lea rdi,[64+rsp]
+ call __ecp_nistz256_sub_fromq
+
+ mov rax,QWORD[((0+0))+rsp]
+ mov r14,QWORD[((8+0))+rsp]
+ lea rsi,[((0+0))+rsp]
+ mov r15,QWORD[((16+0))+rsp]
+ mov r8,QWORD[((24+0))+rsp]
+DB 102,72,15,126,207
+ call __ecp_nistz256_sqr_montq
+ xor r9,r9
+ mov rax,r12
+ add r12,-1
+ mov r10,r13
+ adc r13,rsi
+ mov rcx,r14
+ adc r14,0
+ mov r8,r15
+ adc r15,rbp
+ adc r9,0
+ xor rsi,rsi
+ test rax,1
+
+ cmovz r12,rax
+ cmovz r13,r10
+ cmovz r14,rcx
+ cmovz r15,r8
+ cmovz r9,rsi
+
+ mov rax,r13
+ shr r12,1
+ shl rax,63
+ mov r10,r14
+ shr r13,1
+ or r12,rax
+ shl r10,63
+ mov rcx,r15
+ shr r14,1
+ or r13,r10
+ shl rcx,63
+ mov QWORD[rdi],r12
+ shr r15,1
+ mov QWORD[8+rdi],r13
+ shl r9,63
+ or r14,rcx
+ or r15,r9
+ mov QWORD[16+rdi],r14
+ mov QWORD[24+rdi],r15
+ mov rax,QWORD[64+rsp]
+ lea rbx,[64+rsp]
+ mov r9,QWORD[((0+32))+rsp]
+ mov r10,QWORD[((8+32))+rsp]
+ lea rsi,[((0+32))+rsp]
+ mov r11,QWORD[((16+32))+rsp]
+ mov r12,QWORD[((24+32))+rsp]
+ lea rdi,[32+rsp]
+ call __ecp_nistz256_mul_montq
+
+ lea rdi,[128+rsp]
+ call __ecp_nistz256_mul_by_2q
+
+ lea rbx,[32+rsp]
+ lea rdi,[32+rsp]
+ call __ecp_nistz256_add_toq
+
+ mov rax,QWORD[96+rsp]
+ lea rbx,[96+rsp]
+ mov r9,QWORD[((0+0))+rsp]
+ mov r10,QWORD[((8+0))+rsp]
+ lea rsi,[((0+0))+rsp]
+ mov r11,QWORD[((16+0))+rsp]
+ mov r12,QWORD[((24+0))+rsp]
+ lea rdi,[rsp]
+ call __ecp_nistz256_mul_montq
+
+ lea rdi,[128+rsp]
+ call __ecp_nistz256_mul_by_2q
+
+ mov rax,QWORD[((0+32))+rsp]
+ mov r14,QWORD[((8+32))+rsp]
+ lea rsi,[((0+32))+rsp]
+ mov r15,QWORD[((16+32))+rsp]
+ mov r8,QWORD[((24+32))+rsp]
+DB 102,72,15,126,199
+ call __ecp_nistz256_sqr_montq
+
+ lea rbx,[128+rsp]
+ mov r8,r14
+ mov r9,r15
+ mov r14,rsi
+ mov r15,rbp
+ call __ecp_nistz256_sub_fromq
+
+ mov rax,QWORD[((0+0))+rsp]
+ mov rbp,QWORD[((0+8))+rsp]
+ mov rcx,QWORD[((0+16))+rsp]
+ mov r10,QWORD[((0+24))+rsp]
+ lea rdi,[rsp]
+ call __ecp_nistz256_subq
+
+ mov rax,QWORD[32+rsp]
+ lea rbx,[32+rsp]
+ mov r14,r12
+ xor ecx,ecx
+ mov QWORD[((0+0))+rsp],r12
+ mov r10,r13
+ mov QWORD[((0+8))+rsp],r13
+ cmovz r11,r8
+ mov QWORD[((0+16))+rsp],r8
+ lea rsi,[((0-0))+rsp]
+ cmovz r12,r9
+ mov QWORD[((0+24))+rsp],r9
+ mov r9,r14
+ lea rdi,[rsp]
+ call __ecp_nistz256_mul_montq
+
+DB 102,72,15,126,203
+DB 102,72,15,126,207
+ call __ecp_nistz256_sub_fromq
+
+ add rsp,32*5+8
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop rbx
+ pop rbp
+ mov rdi,QWORD[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_ecp_nistz256_point_double:
+global ecp_nistz256_point_add
+
+ALIGN 32
+ecp_nistz256_point_add:
+ mov QWORD[8+rsp],rdi ;WIN64 prologue
+ mov QWORD[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_ecp_nistz256_point_add:
+ mov rdi,rcx
+ mov rsi,rdx
+ mov rdx,r8
+
+
+ push rbp
+ push rbx
+ push r12
+ push r13
+ push r14
+ push r15
+ sub rsp,32*18+8
+
+ movdqu xmm0,XMMWORD[rsi]
+ movdqu xmm1,XMMWORD[16+rsi]
+ movdqu xmm2,XMMWORD[32+rsi]
+ movdqu xmm3,XMMWORD[48+rsi]
+ movdqu xmm4,XMMWORD[64+rsi]
+ movdqu xmm5,XMMWORD[80+rsi]
+ mov rbx,rsi
+ mov rsi,rdx
+ movdqa XMMWORD[384+rsp],xmm0
+ movdqa XMMWORD[(384+16)+rsp],xmm1
+ por xmm1,xmm0
+ movdqa XMMWORD[416+rsp],xmm2
+ movdqa XMMWORD[(416+16)+rsp],xmm3
+ por xmm3,xmm2
+ movdqa XMMWORD[448+rsp],xmm4
+ movdqa XMMWORD[(448+16)+rsp],xmm5
+ por xmm3,xmm1
+
+ movdqu xmm0,XMMWORD[rsi]
+ pshufd xmm5,xmm3,0xb1
+ movdqu xmm1,XMMWORD[16+rsi]
+ movdqu xmm2,XMMWORD[32+rsi]
+ por xmm5,xmm3
+ movdqu xmm3,XMMWORD[48+rsi]
+ mov rax,QWORD[((64+0))+rsi]
+ mov r14,QWORD[((64+8))+rsi]
+ mov r15,QWORD[((64+16))+rsi]
+ mov r8,QWORD[((64+24))+rsi]
+ movdqa XMMWORD[480+rsp],xmm0
+ pshufd xmm4,xmm5,0x1e
+ movdqa XMMWORD[(480+16)+rsp],xmm1
+ por xmm1,xmm0
+DB 102,72,15,110,199
+ movdqa XMMWORD[512+rsp],xmm2
+ movdqa XMMWORD[(512+16)+rsp],xmm3
+ por xmm3,xmm2
+ por xmm5,xmm4
+ pxor xmm4,xmm4
+ por xmm3,xmm1
+
+ lea rsi,[((64-0))+rsi]
+ mov QWORD[((544+0))+rsp],rax
+ mov QWORD[((544+8))+rsp],r14
+ mov QWORD[((544+16))+rsp],r15
+ mov QWORD[((544+24))+rsp],r8
+ lea rdi,[96+rsp]
+ call __ecp_nistz256_sqr_montq
+
+ pcmpeqd xmm5,xmm4
+ pshufd xmm4,xmm3,0xb1
+ por xmm4,xmm3
+ pshufd xmm5,xmm5,0
+ pshufd xmm3,xmm4,0x1e
+ por xmm4,xmm3
+ pxor xmm3,xmm3
+ pcmpeqd xmm4,xmm3
+ pshufd xmm4,xmm4,0
+ mov rax,QWORD[((64+0))+rbx]
+ mov r14,QWORD[((64+8))+rbx]
+ mov r15,QWORD[((64+16))+rbx]
+ mov r8,QWORD[((64+24))+rbx]
+
+ lea rsi,[((64-0))+rbx]
+ lea rdi,[32+rsp]
+ call __ecp_nistz256_sqr_montq
+
+ mov rax,QWORD[544+rsp]
+ lea rbx,[544+rsp]
+ mov r9,QWORD[((0+96))+rsp]
+ mov r10,QWORD[((8+96))+rsp]
+ lea rsi,[((0+96))+rsp]
+ mov r11,QWORD[((16+96))+rsp]
+ mov r12,QWORD[((24+96))+rsp]
+ lea rdi,[224+rsp]
+ call __ecp_nistz256_mul_montq
+
+ mov rax,QWORD[448+rsp]
+ lea rbx,[448+rsp]
+ mov r9,QWORD[((0+32))+rsp]
+ mov r10,QWORD[((8+32))+rsp]
+ lea rsi,[((0+32))+rsp]
+ mov r11,QWORD[((16+32))+rsp]
+ mov r12,QWORD[((24+32))+rsp]
+ lea rdi,[256+rsp]
+ call __ecp_nistz256_mul_montq
+
+ mov rax,QWORD[416+rsp]
+ lea rbx,[416+rsp]
+ mov r9,QWORD[((0+224))+rsp]
+ mov r10,QWORD[((8+224))+rsp]
+ lea rsi,[((0+224))+rsp]
+ mov r11,QWORD[((16+224))+rsp]
+ mov r12,QWORD[((24+224))+rsp]
+ lea rdi,[224+rsp]
+ call __ecp_nistz256_mul_montq
+
+ mov rax,QWORD[512+rsp]
+ lea rbx,[512+rsp]
+ mov r9,QWORD[((0+256))+rsp]
+ mov r10,QWORD[((8+256))+rsp]
+ lea rsi,[((0+256))+rsp]
+ mov r11,QWORD[((16+256))+rsp]
+ mov r12,QWORD[((24+256))+rsp]
+ lea rdi,[256+rsp]
+ call __ecp_nistz256_mul_montq
+
+ lea rbx,[224+rsp]
+ lea rdi,[64+rsp]
+ call __ecp_nistz256_sub_fromq
+
+ or r12,r13
+ movdqa xmm2,xmm4
+ or r12,r8
+ or r12,r9
+ por xmm2,xmm5
+DB 102,73,15,110,220
+
+ mov rax,QWORD[384+rsp]
+ lea rbx,[384+rsp]
+ mov r9,QWORD[((0+96))+rsp]
+ mov r10,QWORD[((8+96))+rsp]
+ lea rsi,[((0+96))+rsp]
+ mov r11,QWORD[((16+96))+rsp]
+ mov r12,QWORD[((24+96))+rsp]
+ lea rdi,[160+rsp]
+ call __ecp_nistz256_mul_montq
+
+ mov rax,QWORD[480+rsp]
+ lea rbx,[480+rsp]
+ mov r9,QWORD[((0+32))+rsp]
+ mov r10,QWORD[((8+32))+rsp]
+ lea rsi,[((0+32))+rsp]
+ mov r11,QWORD[((16+32))+rsp]
+ mov r12,QWORD[((24+32))+rsp]
+ lea rdi,[192+rsp]
+ call __ecp_nistz256_mul_montq
+
+ lea rbx,[160+rsp]
+ lea rdi,[rsp]
+ call __ecp_nistz256_sub_fromq
+
+ or r12,r13
+ or r12,r8
+ or r12,r9
+
+DB 0x3e
+ jnz NEAR $L$add_proceedq
+DB 102,73,15,126,208
+DB 102,73,15,126,217
+ test r8,r8
+ jnz NEAR $L$add_proceedq
+ test r9,r9
+ jz NEAR $L$add_proceedq
+
+DB 102,72,15,126,199
+ pxor xmm0,xmm0
+ movdqu XMMWORD[rdi],xmm0
+ movdqu XMMWORD[16+rdi],xmm0
+ movdqu XMMWORD[32+rdi],xmm0
+ movdqu XMMWORD[48+rdi],xmm0
+ movdqu XMMWORD[64+rdi],xmm0
+ movdqu XMMWORD[80+rdi],xmm0
+ jmp NEAR $L$add_doneq
+
+ALIGN 32
+$L$add_proceedq:
+ mov rax,QWORD[((0+64))+rsp]
+ mov r14,QWORD[((8+64))+rsp]
+ lea rsi,[((0+64))+rsp]
+ mov r15,QWORD[((16+64))+rsp]
+ mov r8,QWORD[((24+64))+rsp]
+ lea rdi,[96+rsp]
+ call __ecp_nistz256_sqr_montq
+
+ mov rax,QWORD[448+rsp]
+ lea rbx,[448+rsp]
+ mov r9,QWORD[((0+0))+rsp]
+ mov r10,QWORD[((8+0))+rsp]
+ lea rsi,[((0+0))+rsp]
+ mov r11,QWORD[((16+0))+rsp]
+ mov r12,QWORD[((24+0))+rsp]
+ lea rdi,[352+rsp]
+ call __ecp_nistz256_mul_montq
+
+ mov rax,QWORD[((0+0))+rsp]
+ mov r14,QWORD[((8+0))+rsp]
+ lea rsi,[((0+0))+rsp]
+ mov r15,QWORD[((16+0))+rsp]
+ mov r8,QWORD[((24+0))+rsp]
+ lea rdi,[32+rsp]
+ call __ecp_nistz256_sqr_montq
+
+ mov rax,QWORD[544+rsp]
+ lea rbx,[544+rsp]
+ mov r9,QWORD[((0+352))+rsp]
+ mov r10,QWORD[((8+352))+rsp]
+ lea rsi,[((0+352))+rsp]
+ mov r11,QWORD[((16+352))+rsp]
+ mov r12,QWORD[((24+352))+rsp]
+ lea rdi,[352+rsp]
+ call __ecp_nistz256_mul_montq
+
+ mov rax,QWORD[rsp]
+ lea rbx,[rsp]
+ mov r9,QWORD[((0+32))+rsp]
+ mov r10,QWORD[((8+32))+rsp]
+ lea rsi,[((0+32))+rsp]
+ mov r11,QWORD[((16+32))+rsp]
+ mov r12,QWORD[((24+32))+rsp]
+ lea rdi,[128+rsp]
+ call __ecp_nistz256_mul_montq
+
+ mov rax,QWORD[160+rsp]
+ lea rbx,[160+rsp]
+ mov r9,QWORD[((0+32))+rsp]
+ mov r10,QWORD[((8+32))+rsp]
+ lea rsi,[((0+32))+rsp]
+ mov r11,QWORD[((16+32))+rsp]
+ mov r12,QWORD[((24+32))+rsp]
+ lea rdi,[192+rsp]
+ call __ecp_nistz256_mul_montq
+
+
+
+
+ add r12,r12
+ lea rsi,[96+rsp]
+ adc r13,r13
+ mov rax,r12
+ adc r8,r8
+ adc r9,r9
+ mov rbp,r13
+ sbb r11,r11
+
+ sub r12,-1
+ mov rcx,r8
+ sbb r13,r14
+ sbb r8,0
+ mov r10,r9
+ sbb r9,r15
+ test r11,r11
+
+ cmovz r12,rax
+ mov rax,QWORD[rsi]
+ cmovz r13,rbp
+ mov rbp,QWORD[8+rsi]
+ cmovz r8,rcx
+ mov rcx,QWORD[16+rsi]
+ cmovz r9,r10
+ mov r10,QWORD[24+rsi]
+
+ call __ecp_nistz256_subq
+
+ lea rbx,[128+rsp]
+ lea rdi,[288+rsp]
+ call __ecp_nistz256_sub_fromq
+
+ mov rax,QWORD[((192+0))+rsp]
+ mov rbp,QWORD[((192+8))+rsp]
+ mov rcx,QWORD[((192+16))+rsp]
+ mov r10,QWORD[((192+24))+rsp]
+ lea rdi,[320+rsp]
+
+ call __ecp_nistz256_subq
+
+ mov QWORD[rdi],r12
+ mov QWORD[8+rdi],r13
+ mov QWORD[16+rdi],r8
+ mov QWORD[24+rdi],r9
+ mov rax,QWORD[128+rsp]
+ lea rbx,[128+rsp]
+ mov r9,QWORD[((0+224))+rsp]
+ mov r10,QWORD[((8+224))+rsp]
+ lea rsi,[((0+224))+rsp]
+ mov r11,QWORD[((16+224))+rsp]
+ mov r12,QWORD[((24+224))+rsp]
+ lea rdi,[256+rsp]
+ call __ecp_nistz256_mul_montq
+
+ mov rax,QWORD[320+rsp]
+ lea rbx,[320+rsp]
+ mov r9,QWORD[((0+64))+rsp]
+ mov r10,QWORD[((8+64))+rsp]
+ lea rsi,[((0+64))+rsp]
+ mov r11,QWORD[((16+64))+rsp]
+ mov r12,QWORD[((24+64))+rsp]
+ lea rdi,[320+rsp]
+ call __ecp_nistz256_mul_montq
+
+ lea rbx,[256+rsp]
+ lea rdi,[320+rsp]
+ call __ecp_nistz256_sub_fromq
+
+DB 102,72,15,126,199
+
+ movdqa xmm0,xmm5
+ movdqa xmm1,xmm5
+ pandn xmm0,XMMWORD[352+rsp]
+ movdqa xmm2,xmm5
+ pandn xmm1,XMMWORD[((352+16))+rsp]
+ movdqa xmm3,xmm5
+ pand xmm2,XMMWORD[544+rsp]
+ pand xmm3,XMMWORD[((544+16))+rsp]
+ por xmm2,xmm0
+ por xmm3,xmm1
+
+ movdqa xmm0,xmm4
+ movdqa xmm1,xmm4
+ pandn xmm0,xmm2
+ movdqa xmm2,xmm4
+ pandn xmm1,xmm3
+ movdqa xmm3,xmm4
+ pand xmm2,XMMWORD[448+rsp]
+ pand xmm3,XMMWORD[((448+16))+rsp]
+ por xmm2,xmm0
+ por xmm3,xmm1
+ movdqu XMMWORD[64+rdi],xmm2
+ movdqu XMMWORD[80+rdi],xmm3
+
+ movdqa xmm0,xmm5
+ movdqa xmm1,xmm5
+ pandn xmm0,XMMWORD[288+rsp]
+ movdqa xmm2,xmm5
+ pandn xmm1,XMMWORD[((288+16))+rsp]
+ movdqa xmm3,xmm5
+ pand xmm2,XMMWORD[480+rsp]
+ pand xmm3,XMMWORD[((480+16))+rsp]
+ por xmm2,xmm0
+ por xmm3,xmm1
+
+ movdqa xmm0,xmm4
+ movdqa xmm1,xmm4
+ pandn xmm0,xmm2
+ movdqa xmm2,xmm4
+ pandn xmm1,xmm3
+ movdqa xmm3,xmm4
+ pand xmm2,XMMWORD[384+rsp]
+ pand xmm3,XMMWORD[((384+16))+rsp]
+ por xmm2,xmm0
+ por xmm3,xmm1
+ movdqu XMMWORD[rdi],xmm2
+ movdqu XMMWORD[16+rdi],xmm3
+
+ movdqa xmm0,xmm5
+ movdqa xmm1,xmm5
+ pandn xmm0,XMMWORD[320+rsp]
+ movdqa xmm2,xmm5
+ pandn xmm1,XMMWORD[((320+16))+rsp]
+ movdqa xmm3,xmm5
+ pand xmm2,XMMWORD[512+rsp]
+ pand xmm3,XMMWORD[((512+16))+rsp]
+ por xmm2,xmm0
+ por xmm3,xmm1
+
+ movdqa xmm0,xmm4
+ movdqa xmm1,xmm4
+ pandn xmm0,xmm2
+ movdqa xmm2,xmm4
+ pandn xmm1,xmm3
+ movdqa xmm3,xmm4
+ pand xmm2,XMMWORD[416+rsp]
+ pand xmm3,XMMWORD[((416+16))+rsp]
+ por xmm2,xmm0
+ por xmm3,xmm1
+ movdqu XMMWORD[32+rdi],xmm2
+ movdqu XMMWORD[48+rdi],xmm3
+
+$L$add_doneq:
+ add rsp,32*18+8
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop rbx
+ pop rbp
+ mov rdi,QWORD[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_ecp_nistz256_point_add:
+global ecp_nistz256_point_add_affine
+
+ALIGN 32
+ecp_nistz256_point_add_affine:
+ mov QWORD[8+rsp],rdi ;WIN64 prologue
+ mov QWORD[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_ecp_nistz256_point_add_affine:
+ mov rdi,rcx
+ mov rsi,rdx
+ mov rdx,r8
+
+
+ push rbp
+ push rbx
+ push r12
+ push r13
+ push r14
+ push r15
+ sub rsp,32*15+8
+
+ movdqu xmm0,XMMWORD[rsi]
+ mov rbx,rdx
+ movdqu xmm1,XMMWORD[16+rsi]
+ movdqu xmm2,XMMWORD[32+rsi]
+ movdqu xmm3,XMMWORD[48+rsi]
+ movdqu xmm4,XMMWORD[64+rsi]
+ movdqu xmm5,XMMWORD[80+rsi]
+ mov rax,QWORD[((64+0))+rsi]
+ mov r14,QWORD[((64+8))+rsi]
+ mov r15,QWORD[((64+16))+rsi]
+ mov r8,QWORD[((64+24))+rsi]
+ movdqa XMMWORD[320+rsp],xmm0
+ movdqa XMMWORD[(320+16)+rsp],xmm1
+ por xmm1,xmm0
+ movdqa XMMWORD[352+rsp],xmm2
+ movdqa XMMWORD[(352+16)+rsp],xmm3
+ por xmm3,xmm2
+ movdqa XMMWORD[384+rsp],xmm4
+ movdqa XMMWORD[(384+16)+rsp],xmm5
+ por xmm3,xmm1
+
+ movdqu xmm0,XMMWORD[rbx]
+ pshufd xmm5,xmm3,0xb1
+ movdqu xmm1,XMMWORD[16+rbx]
+ movdqu xmm2,XMMWORD[32+rbx]
+ por xmm5,xmm3
+ movdqu xmm3,XMMWORD[48+rbx]
+ movdqa XMMWORD[416+rsp],xmm0
+ pshufd xmm4,xmm5,0x1e
+ movdqa XMMWORD[(416+16)+rsp],xmm1
+ por xmm1,xmm0
+DB 102,72,15,110,199
+ movdqa XMMWORD[448+rsp],xmm2
+ movdqa XMMWORD[(448+16)+rsp],xmm3
+ por xmm3,xmm2
+ por xmm5,xmm4
+ pxor xmm4,xmm4
+ por xmm3,xmm1
+
+ lea rsi,[((64-0))+rsi]
+ lea rdi,[32+rsp]
+ call __ecp_nistz256_sqr_montq
+
+ pcmpeqd xmm5,xmm4
+ pshufd xmm4,xmm3,0xb1
+ mov rax,QWORD[rbx]
+
+ mov r9,r12
+ por xmm4,xmm3
+ pshufd xmm5,xmm5,0
+ pshufd xmm3,xmm4,0x1e
+ mov r10,r13
+ por xmm4,xmm3
+ pxor xmm3,xmm3
+ mov r11,r14
+ pcmpeqd xmm4,xmm3
+ pshufd xmm4,xmm4,0
+
+ lea rsi,[((32-0))+rsp]
+ mov r12,r15
+ lea rdi,[rsp]
+ call __ecp_nistz256_mul_montq
+
+ lea rbx,[320+rsp]
+ lea rdi,[64+rsp]
+ call __ecp_nistz256_sub_fromq
+
+ mov rax,QWORD[384+rsp]
+ lea rbx,[384+rsp]
+ mov r9,QWORD[((0+32))+rsp]
+ mov r10,QWORD[((8+32))+rsp]
+ lea rsi,[((0+32))+rsp]
+ mov r11,QWORD[((16+32))+rsp]
+ mov r12,QWORD[((24+32))+rsp]
+ lea rdi,[32+rsp]
+ call __ecp_nistz256_mul_montq
+
+ mov rax,QWORD[384+rsp]
+ lea rbx,[384+rsp]
+ mov r9,QWORD[((0+64))+rsp]
+ mov r10,QWORD[((8+64))+rsp]
+ lea rsi,[((0+64))+rsp]
+ mov r11,QWORD[((16+64))+rsp]
+ mov r12,QWORD[((24+64))+rsp]
+ lea rdi,[288+rsp]
+ call __ecp_nistz256_mul_montq
+
+ mov rax,QWORD[448+rsp]
+ lea rbx,[448+rsp]
+ mov r9,QWORD[((0+32))+rsp]
+ mov r10,QWORD[((8+32))+rsp]
+ lea rsi,[((0+32))+rsp]
+ mov r11,QWORD[((16+32))+rsp]
+ mov r12,QWORD[((24+32))+rsp]
+ lea rdi,[32+rsp]
+ call __ecp_nistz256_mul_montq
+
+ lea rbx,[352+rsp]
+ lea rdi,[96+rsp]
+ call __ecp_nistz256_sub_fromq
+
+ mov rax,QWORD[((0+64))+rsp]
+ mov r14,QWORD[((8+64))+rsp]
+ lea rsi,[((0+64))+rsp]
+ mov r15,QWORD[((16+64))+rsp]
+ mov r8,QWORD[((24+64))+rsp]
+ lea rdi,[128+rsp]
+ call __ecp_nistz256_sqr_montq
+
+ mov rax,QWORD[((0+96))+rsp]
+ mov r14,QWORD[((8+96))+rsp]
+ lea rsi,[((0+96))+rsp]
+ mov r15,QWORD[((16+96))+rsp]
+ mov r8,QWORD[((24+96))+rsp]
+ lea rdi,[192+rsp]
+ call __ecp_nistz256_sqr_montq
+
+ mov rax,QWORD[128+rsp]
+ lea rbx,[128+rsp]
+ mov r9,QWORD[((0+64))+rsp]
+ mov r10,QWORD[((8+64))+rsp]
+ lea rsi,[((0+64))+rsp]
+ mov r11,QWORD[((16+64))+rsp]
+ mov r12,QWORD[((24+64))+rsp]
+ lea rdi,[160+rsp]
+ call __ecp_nistz256_mul_montq
+
+ mov rax,QWORD[320+rsp]
+ lea rbx,[320+rsp]
+ mov r9,QWORD[((0+128))+rsp]
+ mov r10,QWORD[((8+128))+rsp]
+ lea rsi,[((0+128))+rsp]
+ mov r11,QWORD[((16+128))+rsp]
+ mov r12,QWORD[((24+128))+rsp]
+ lea rdi,[rsp]
+ call __ecp_nistz256_mul_montq
+
+
+
+
+ add r12,r12
+ lea rsi,[192+rsp]
+ adc r13,r13
+ mov rax,r12
+ adc r8,r8
+ adc r9,r9
+ mov rbp,r13
+ sbb r11,r11
+
+ sub r12,-1
+ mov rcx,r8
+ sbb r13,r14
+ sbb r8,0
+ mov r10,r9
+ sbb r9,r15
+ test r11,r11
+
+ cmovz r12,rax
+ mov rax,QWORD[rsi]
+ cmovz r13,rbp
+ mov rbp,QWORD[8+rsi]
+ cmovz r8,rcx
+ mov rcx,QWORD[16+rsi]
+ cmovz r9,r10
+ mov r10,QWORD[24+rsi]
+
+ call __ecp_nistz256_subq
+
+ lea rbx,[160+rsp]
+ lea rdi,[224+rsp]
+ call __ecp_nistz256_sub_fromq
+
+ mov rax,QWORD[((0+0))+rsp]
+ mov rbp,QWORD[((0+8))+rsp]
+ mov rcx,QWORD[((0+16))+rsp]
+ mov r10,QWORD[((0+24))+rsp]
+ lea rdi,[64+rsp]
+
+ call __ecp_nistz256_subq
+
+ mov QWORD[rdi],r12
+ mov QWORD[8+rdi],r13
+ mov QWORD[16+rdi],r8
+ mov QWORD[24+rdi],r9
+ mov rax,QWORD[352+rsp]
+ lea rbx,[352+rsp]
+ mov r9,QWORD[((0+160))+rsp]
+ mov r10,QWORD[((8+160))+rsp]
+ lea rsi,[((0+160))+rsp]
+ mov r11,QWORD[((16+160))+rsp]
+ mov r12,QWORD[((24+160))+rsp]
+ lea rdi,[32+rsp]
+ call __ecp_nistz256_mul_montq
+
+ mov rax,QWORD[96+rsp]
+ lea rbx,[96+rsp]
+ mov r9,QWORD[((0+64))+rsp]
+ mov r10,QWORD[((8+64))+rsp]
+ lea rsi,[((0+64))+rsp]
+ mov r11,QWORD[((16+64))+rsp]
+ mov r12,QWORD[((24+64))+rsp]
+ lea rdi,[64+rsp]
+ call __ecp_nistz256_mul_montq
+
+ lea rbx,[32+rsp]
+ lea rdi,[256+rsp]
+ call __ecp_nistz256_sub_fromq
+
+DB 102,72,15,126,199
+
+ movdqa xmm0,xmm5
+ movdqa xmm1,xmm5
+ pandn xmm0,XMMWORD[288+rsp]
+ movdqa xmm2,xmm5
+ pandn xmm1,XMMWORD[((288+16))+rsp]
+ movdqa xmm3,xmm5
+ pand xmm2,XMMWORD[$L$ONE_mont]
+ pand xmm3,XMMWORD[(($L$ONE_mont+16))]
+ por xmm2,xmm0
+ por xmm3,xmm1
+
+ movdqa xmm0,xmm4
+ movdqa xmm1,xmm4
+ pandn xmm0,xmm2
+ movdqa xmm2,xmm4
+ pandn xmm1,xmm3
+ movdqa xmm3,xmm4
+ pand xmm2,XMMWORD[384+rsp]
+ pand xmm3,XMMWORD[((384+16))+rsp]
+ por xmm2,xmm0
+ por xmm3,xmm1
+ movdqu XMMWORD[64+rdi],xmm2
+ movdqu XMMWORD[80+rdi],xmm3
+
+ movdqa xmm0,xmm5
+ movdqa xmm1,xmm5
+ pandn xmm0,XMMWORD[224+rsp]
+ movdqa xmm2,xmm5
+ pandn xmm1,XMMWORD[((224+16))+rsp]
+ movdqa xmm3,xmm5
+ pand xmm2,XMMWORD[416+rsp]
+ pand xmm3,XMMWORD[((416+16))+rsp]
+ por xmm2,xmm0
+ por xmm3,xmm1
+
+ movdqa xmm0,xmm4
+ movdqa xmm1,xmm4
+ pandn xmm0,xmm2
+ movdqa xmm2,xmm4
+ pandn xmm1,xmm3
+ movdqa xmm3,xmm4
+ pand xmm2,XMMWORD[320+rsp]
+ pand xmm3,XMMWORD[((320+16))+rsp]
+ por xmm2,xmm0
+ por xmm3,xmm1
+ movdqu XMMWORD[rdi],xmm2
+ movdqu XMMWORD[16+rdi],xmm3
+
+ movdqa xmm0,xmm5
+ movdqa xmm1,xmm5
+ pandn xmm0,XMMWORD[256+rsp]
+ movdqa xmm2,xmm5
+ pandn xmm1,XMMWORD[((256+16))+rsp]
+ movdqa xmm3,xmm5
+ pand xmm2,XMMWORD[448+rsp]
+ pand xmm3,XMMWORD[((448+16))+rsp]
+ por xmm2,xmm0
+ por xmm3,xmm1
+
+ movdqa xmm0,xmm4
+ movdqa xmm1,xmm4
+ pandn xmm0,xmm2
+ movdqa xmm2,xmm4
+ pandn xmm1,xmm3
+ movdqa xmm3,xmm4
+ pand xmm2,XMMWORD[352+rsp]
+ pand xmm3,XMMWORD[((352+16))+rsp]
+ por xmm2,xmm0
+ por xmm3,xmm1
+ movdqu XMMWORD[32+rdi],xmm2
+ movdqu XMMWORD[48+rdi],xmm3
+
+ add rsp,32*15+8
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop rbx
+ pop rbp
+ mov rdi,QWORD[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$SEH_end_ecp_nistz256_point_add_affine:
diff --git a/win-x86_64/crypto/rand/rdrand-x86_64.asm b/win-x86_64/crypto/rand/rdrand-x86_64.asm
index a63ea69..4c03791 100644
--- a/win-x86_64/crypto/rand/rdrand-x86_64.asm
+++ b/win-x86_64/crypto/rand/rdrand-x86_64.asm
@@ -5,6 +5,9 @@ default rel
section .text code align=64
+
+
+
global CRYPTO_rdrand
ALIGN 16
@@ -16,7 +19,52 @@ $L$SEH_begin_CRYPTO_rdrand:
mov rdi,rcx
-DB 0x48,0x0f,0xc7,0xf0
+ xor rax,rax
+
+
+DB 0x48,0x0f,0xc7,0xf1
+
+ adc rax,rax
+ mov QWORD[rdi],rcx
+ mov rdi,QWORD[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD[16+rsp]
+ DB 0F3h,0C3h ;repret
+
+
+
+
+
+global CRYPTO_rdrand_multiple8_buf
+
+ALIGN 16
+CRYPTO_rdrand_multiple8_buf:
+ mov QWORD[8+rsp],rdi ;WIN64 prologue
+ mov QWORD[16+rsp],rsi
+ mov rax,rsp
+$L$SEH_begin_CRYPTO_rdrand_multiple8_buf:
+ mov rdi,rcx
+ mov rsi,rdx
+
+
+ test rsi,rsi
+ jz NEAR $L$out
+ mov rdx,8
+$L$loop:
+
+
+DB 0x48,0x0f,0xc7,0xf1
+ jnc NEAR $L$err
+ mov QWORD[rdi],rcx
+ add rdi,rdx
+ sub rsi,rdx
+ jnz NEAR $L$loop
+$L$out:
+ mov rax,1
+ mov rdi,QWORD[8+rsp] ;WIN64 epilogue
+ mov rsi,QWORD[16+rsp]
+ DB 0F3h,0C3h ;repret
+$L$err:
+ xor rax,rax
mov rdi,QWORD[8+rsp] ;WIN64 epilogue
mov rsi,QWORD[16+rsp]
DB 0F3h,0C3h ;repret
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